The Aaron said:
I'd have to look at the CFX script, but probably it does something like checks if a player is a gm, which would fail if it gets called from a script.
Here is the script I have installed:
on('ready',()=>{
const isBuiltinFx = (name) => /(beam|bomb|breath|bubbling|burn|burst|explode|glow|missile|nova|splatter)-(acid|blood|charm|death|fire|frost|holy|magic|slime|smoke|water)/.test(name);
const getPageForPlayer = (playerid) => {
let player = getObj('player',playerid);
if(playerIsGM(playerid)){
return player.get('lastpage');
}
let psp = Campaign().get('playerspecificpages');
if(psp[playerid]){
return psp[playerid];
}
return Campaign().get('playerpageid');
};
on('chat:message',(msg)=>{
if('api' !== msg.type ) {
return;
}
let args = msg.content.split(/\s+/);
switch(args.shift().toLowerCase()){
case '!cfx': {
if (args.length < 3){
sendChat("CFX", `/w "${who}" Use <code>!cfx [effect] [source id] [destination id ...]</code><br><code>id</code>s can be token or character ids. You can specify as many destination ids as you like to target multiple tokens or creatures.`);
return;
}
let who = (getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname');
let srcToken = getObj('graphic',args[1]);
let pageid = getPageForPlayer(msg.playerid);
if(!srcToken) {
let character = getObj('character',args[1]);
if(character){
let ts = findObjs({
type: 'graphic',
represents: character.id,
pageid: pageid
});
if(ts.length){
srcToken = ts[0];
}
}
}
let destTokens = args.slice(2)
.map((id)=>getObj('graphic',id) || findObjs({type:'graphic', represents:id, pageid}))
.reduce((m,o)=>[...m,...(Array.isArray(o) ? o : [o])],[])
;
if(!srcToken){
sendChat("CFX", `/w "${who}" No matching tokens source character or token ID on your current page.`);
return;
}
if(0 === destTokens.length){
sendChat("CFX", `/w "${who}" No destination tokens found for supplied IDs.`);
return;
}
let srcPt = {
x: srcToken.get('left'),
y: srcToken.get('top')
};
let targeted = false;
let effect = args[0];
if(!isBuiltinFx(effect)){
let custfx = findObjs({type: 'custfx', name: effect}, {caseInsensitive: true})[0];
if(!custfx){
sendChat("CFX", `/w "${who}" Not a built in or custom effect: <code>${effect}</code>`);
return;
}
targeted = (-1 === parseInt((custfx.get('definition')||{}).angle));
effect = custfx.id;
} else {
targeted = /^(beam|breath|splatter)-/.test(effect);
}
let spawner = targeted
? (s,d,e,p) => spawnFxBetweenPoints(s,d,e,p)
: (s,d,e,p) => spawnFx(d.x,d.y,e,p)
;
destTokens.forEach((t)=>{
let destPt = {
x: t.get('left'),
y: t.get('top')
};
spawner(srcPt,destPt,effect,t.get('pageid'));
});
}
break;
}
});
log("-=> CFX command loaded (!cfx) <=-");
});