It's not the command. It works fine via macro and direct entry in chat, copied and pasted from the script arg.
I must be missing something in the arg or opt that is preventing it from firing. I have the same problem with the remove token option as well. The output runs correctly, but the argument is not applied in either the <delstatus> or <concen> arguments.
Here is the entire altered script as I have it running now:
/* global log, _, getObj, HealthColors, playerIsGM, sendChat, on, libTokenMarkers */
const ApplyDamage = (() => {
const version = "1.2";
const observers = {
"change": []
};
let boundedBar = false;
const defaultOpts = {
type: "half",
ids: "",
saves: "",
DC: "-1",
dmg: "0",
bar: "1"
};
const checkInstall = () => {
log(`-=> ApplyDamage v${version} <=-`);
if('undefined' === typeof libTokenMarkers
|| (['getStatus','getStatuses','getOrderedList'].find(k=>
!libTokenMarkers.hasOwnProperty(k) || 'function' !== typeof libTokenMarkers[k]
))
) {
// notify of the missing library
sendChat('',`/w gm <div style="color:red;font-weight:bold;border:2px solid red;background-color:black;border-radius:1em;padding:1em;">Missing dependency: libTokenMarkers</div>`);
}
};
const getWhisperPrefix = (playerid) => {
const player = getObj("player", playerid);
if (player && player.get("_displayname")) {
return `/w "${player.get("_displayname")}" `;
}
else {
return "/w GM ";
}
};
const parseOpts = (content, hasValue) => {
return content
.replace(/<br\/>\n/g, " ")
.replace(/({{(.*?)\s*}}\s*$)/g, "$2")
.split(/\s+--/)
.slice(1)
.reduce((opts, arg) => {
const kv = arg.split(/\s(.+)/);
if (hasValue.includes(kv[0])) {
opts[kv[0]] = (kv[1] || "");
} else {
opts[arg] = true;
}
return opts;
}, {});
};
const processInlinerolls = function (msg) {
if (msg.inlinerolls && msg.inlinerolls.length) {
return msg.inlinerolls.map(v => {
const ti = v.results.rolls.filter(v2 => v2.table)
.map(v2 => v2.results.map(v3 => v3.tableItem.name).join(", "))
.join(", ");
return (ti.length && ti) || v.results.total || 0;
}).reduce((m, v, k) => m.replace(`$[[${k}]]`, v), msg.content);
} else {
return msg.content;
}
};
const handleError = (whisper, errorMsg) => {
const output = `${whisper}<div style="border:1px solid black;background:#FFBABA;padding:3px">` +
`<h4>Error</h4><p>${errorMsg}</p></div>`;
sendChat("ApplyDamage", output);
};
const finalApply = (results, dmg, type, bar, status, delstatus, concen,) => {
const barCur = `bar${bar}_value`,
barMax = `bar${bar}_max`;
Object.entries(results).forEach(([id, saved]) => {
const token = getObj("graphic", id),
prev = JSON.parse(JSON.stringify(token || {}));
let newValue;
if (token && !saved) {
if (boundedBar) {
newValue = Math.min(Math.max(parseInt(token.get(barCur)) - dmg, 0), parseInt(token.get(barMax)));
} else {
newValue = parseInt(token.get(barCur)) - dmg;
}
if (status) {
let tm = libTokenMarkers.getStatus(status);
token.set(`status_${tm.getTag()}`, true);
}
if (delstatus) {
let tm = libTokenMarkers.getStatus(status);
token.set(`status_${tm.getTag()}`, false);
}
if (concen) {
sendChat('',"!cmaster --remove,condition=concentration");
return};
}
else if (token && type === "half") {
if (boundedBar) {
newValue = Math.min(Math.max(parseInt(token.get(barCur)) - Math.floor(dmg / 2), 0), parseInt(token.get(barMax)));
} else {
newValue = parseInt(token.get(barCur)) - Math.floor(dmg / 2);
}
}
if (!_.isUndefined(newValue)) {
if (Number.isNaN(newValue)) newValue = token.get(barCur);
token.set(barCur, newValue);
notifyObservers("change", token, prev);
}
});
};
const handleInput = (msg) => {
if (msg.type === "api" && msg.content.search(/^!apply-damage\b/) !== -1) {
const hasValue = ["ids", "saves", "DC", "type", "dmg", "bar", "status","delstatus"],
opts = Object.assign({}, defaultOpts, parseOpts(processInlinerolls(msg), hasValue));
opts.ids = opts.ids.split(/,\s*/g);
opts.saves = opts.saves.split(/,\s*/g);
opts.DC = parseInt(opts.DC);
opts.dmg = parseInt(opts.dmg);
if (!playerIsGM(msg.playerid) && getObj("player", msg.playerid)) {
handleError(getWhisperPrefix(msg.playerid), "Permission denied.");
return;
}
if (!["1", "2", "3"].includes(opts.bar)) {
handleError(getWhisperPrefix(msg.playerid), "Invalid bar.");
return;
}
if (opts.status === "none") {
delete opts.status;
}
if (opts.delstatus === "none") {
delete opts.delstatus;
}
if (opts.concen === "none") {
delete opts.concen;
}
if (opts.status && 0 === libTokenMarkers.getStatuses(opts.status).length) {
handleError(getWhisperPrefix(msg.playerid), "Invalid status.");
return;
}
if (opts.delstatus && 0 === libTokenMarkers.getStatuses(opts.delstatus).length) {
handleError(getWhisperPrefix(msg.playerid), "Invalid status.");
return;
}
const results = _.reduce(opts.ids, function (m, id, k) {
m[id] = parseInt(opts.saves[k] || "0") >= opts.DC;
return m;
}, {});
finalApply(results, opts.dmg, opts.type, opts.bar, opts.status, opts.delstatus);
const output = `${
getWhisperPrefix(msg.playerid)
}<div style="border:1px solid black;background:#FFF;padding:3px"><p>${
(opts.dmg ? `${opts.dmg} damage applied to tokens, with ${
(opts.type === "half" ? "half" : "no")
} damage on a successful saving throw.` : "")}${
(opts.status ? ` ${opts.status} status marker applied to tokens that failed the save.` : "")}${
(opts.delstatus ? ` ${opts.delstatus} status marker removed from tokens that failed the save.` : "")}${
(opts.concen ? ` Concentration status marker removed from tokens that failed the save.` : "")
}</p></div>`;
sendChat("ApplyDamage", output, null, { noarchive: true });
}
return;
};
const notifyObservers = (event, obj, prev) => {
observers[event].forEach(observer => observer(obj, prev));
};
const registerObserver = (event, observer) => {
if (observer && _.isFunction(observer) && observers.hasOwnProperty(event)) {
observers[event].push(observer);
} else {
log("ApplyDamage event registration unsuccessful.");
}
};
const registerEventHandlers = () => {
on("chat:message", handleInput);
};
on("ready", () => {
checkInstall();
registerEventHandlers();
if ("undefined" !== typeof HealthColors) {
ApplyDamage.registerObserver("change", HealthColors.Update);
}
});
return {
registerObserver
};
})();