I for the life of me cannot figure out the problem with this script. The error is quite strange and even the cause, while repeatable doesn't seem to make sense to me. Purpose: Allow incrementing/decrementing of attributes via chat for selected tokens that represent a character. format: !attr <attribute> <modifier> if <attribute> contains spaces then it should be in quotes. modifier is the amount to modify the current value by. examples: !attr Strength +1 // adds 1 to Strength attribute !attr "Str Mod" -1 // subtracts 1 to Str Mod attribute This works fine when an attribute already exists. However, in the case an attribute doesn't exist, I would like at add the attribute to the character with a starting value of 0, then modify as requested. Example: Someone finds 20 arrows !attr arrows +20 // the script would then add an arrows attribute with a 0 value and then add 20. The above occurs as expected. However, on a subsequent !attr arrows +1, the engine will crash with a very strange error. And here is the kicker, after restarting the engine, subsequent request will work fine. Even still after the initial request in which it adds the attribute, if the script is immediately saved before the second request it too will then work fine. Rundown to induce issue: Select A token that represents a character. send command: !attr arrows +1 // make sure it is an attribute the character doesn't already have. send command: !attr arrows +1 The script will then fail. String.prototype.contains = function(it) { return this.indexOf(it) != -1; };
if (!String.format) {
String.format = function(format) {
var args = Array.prototype.slice.call(arguments, 1);
return format.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
};
on('chat:message', function(msg) {
if (msg.type != "api") return;
// Get the API Chat Command
msg.who = msg.who.replace(" (GM)", "");
var command = msg.content.split(" ", 1);
if(command == "!attr")
{
log(msg);
if(!msg.selected) { // ensure at least 1 token is selected
SendChatTo(msg.playerid,"A token must be selected");
return;
}
var args = ParseCommand(msg.content); // parse message
log(args); // print attribute and mod
_.each(msg.selected,function(selected){ // perform request for each selected token
var charid = getObj("graphic", selected._id).get("represents");
var tokenName = getObj("graphic", selected._id).get("name");
if(!charid){
//var graphic = getObj("graphic")
SendChatToAs(msg.playerid, tokenName, " not a valid character. (skipping)");
}else{
var result = ModifyAttribute(charid, args[0], args[1], true);
//SendChatToAs(msg.playerid, tokenName, String.format("{0}: {1} -> {2}",result.attribute,result.from,result.to));
return;
//log(result);
//log(String.format("{0}: {1} -> {2}",result.attribute,result.from,result.to));
//SendChatToAs(msg.playerid, tokenName, String.format("{0}: {1} -> {2}",result.attribute,result.from,result.to));
}
});
return;
var cmd = '"Arrow"+1';
var args = ParseCommand(cmd);
log(args);
//log(cmd.contains('"'));
return;
log(msg.selected);
var charid = getObj("graphic", msg.selected[0]._id).get("represents");
log(charid);
var char = getObj("character", charid);
var attribs = findObjs({_type:"attribute", _characterid:charid});
log(char);
log(attribs);
}
});
function AddAttributeTo(charid, attr, current, max) {
return createObj("attribute", {
name: attr,
current: current,
max: max,
characterid: charid
});
};
function ModifyAttribute(charid, attribute, mod,addOnFail){
if(IsType("String", mod)) mod = parseInt(mod,10);
var attrib = findObjs({_type:"attribute", _characterid:charid, _name:attribute},{caseInsensitive: true})[0];
log(attrib);
//return {"id":charid,"attribute":attribute,"from":0,"to":0};
if(typeof attrib == "undefined") {
attrib = AddAttributeTo(charid, attribute,mod,0);
return {"id":charid,"attribute":attribute,"from":0,"to":mod};
};
var current = attrib.get("current");
if(IsType("String", current)) current = parseInt(current,10);
var now = current + mod;
log("now="+now);
attrib.set("current", now);
return {"id":charid,"attribute":attribute,"from":current,"to":now};
};
/// Expects the command arguement string
/// Returns an array of arguements
function ParseCommand(args){
args = args.trim();
if(args.contains('"')) return _.rest(/!attr "(.*)"\s*([^\s]+)/.exec(args));
else return _.rest(args.split(/[\s,]+/));
}
function IsType(type, obj){
var typeString = Object.prototype.toString.call(obj).slice(8, -1);
//log(typeString);
return obj !== undefined && obj !== null && typeString === type;
}