Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[Script Modification Request] Aura/Tint HealthColors

1609055232

Edited 1609131663
So I've managed to kludge around a bit with the Aura/Tint Healthcolors script to get tokens to use a light red tint upon death (instead of the giant X), turn off the name from showing to players, and move it to the back if it's in the same space as another token; and reverse that if the token regains any hit points. The last bit that I'd like to do is have it send a message to the GM: "{token_name} is Dead", and "{token name} is Alive". The issue is that the tokens are updated upon all  change:token  events, so I get a message every time a token is moved or updated in any way, instead of simply when it reaches 0 hp or is healed from 0 hp.  Can anyone help with some code to modify this section? //SHOW DEAD---------- if(ShowDead === true) { var tokenName = (obj.get('name')); if(curValue > 0) { obj.set({'tint_color': "transparent", 'showplayers_name': "on",}); toFront(obj); sendChat('HealthColors',`/w gm ` + tokenName + ' is Alive'); } else if(curValue < 1) { var DeadSounds = state.HealthColors.auraDeadFX; if(DeadSounds !== "None" && curValue != prevValue) PlayDeath(DeadSounds); obj.set({'tint_color': "#ffaaaa",}); obj.set('showplayers_name', false); toBack(obj); sendChat('HealthColors',`/w gm ` + tokenName + ' is Dead'); SetAuraNone(obj); } }     } Edit: here's the completed code for anyone else who may want it:             //SHOW DEAD----------                 if(curValue != prevValue && ShowDead === true) {                         var tokenName = (obj.get('name'));                         if(curValue !== prevValue && curValue > 0) {                             obj.set({'tint_color': "transparent", 'showplayers_name': "on",'showname': "on",});                             toFront(obj);                             sendChat('HealthColors',`/w gm ` + tokenName + ' is Alive.');                         }                             else if(curValue !== prevValue && curValue < 1) {                             var DeadSounds = state.HealthColors.auraDeadFX;                             if(DeadSounds !== "None" && curValue != prevValue) PlayDeath(DeadSounds);                             obj.set({'tint_color': "#ffaaaa",});                             obj.set('showplayers_name', false);                             obj.set('showname', false);                             toBack(obj);                             SetAuraNone(obj);                             sendChat('HealthColors',`/w gm ` + tokenName + ' is Dead.');                         }     }                 }
1609055595
GiGs
Pro
Sheet Author
API Scripter
You could check if the value has changed, using the prev property, and only sendChat if the value has changed. I'm not sure exactly the details as I dont have the script code open.
1609063928

Edited 1609064027
Oosh
Sheet Author
Are you already inside a change:token event for other functions? Or is it your own event just for HP? I think this is what GiGs is suggesting: on('ready', () => { on('change:token:bar1_value', (obj, prev) => { let curValue = parseInt(obj.get('bar1_value')); let oldValue = parseInt(prev['bar1_value']) if (oldValue < 1 && curValue > 0) { // token is back on their feet } if (curValue < 1 && oldValue > 0) { // token just died } }); }); If it's already inside a change:token event that looks for other changes as well (not just bar1), you could just use: let curValue = parseInt(obj.get('bar1_value')); let oldValue = parseInt(prev['bar1_value']) if (oldValue === curValue) return; to exit the code at the top. No idea if it was just because my game was pretty empty and that was the whole code I was running, but the event was firing twice for any token that had its HP linked to a character sheet, and sending two messages to chat. Just in case it's relevant, ._debounce() fixed that: on('ready', () => { on('change:token:bar1_value', _.debounce((obj, prev) => { let curValue = parseInt(obj.get('bar1_value')); let oldValue = parseInt(prev['bar1_value']) if (oldValue < 1 && curValue > 0) sendChat('', 'Did you miss me?'); if (curValue < 1 && oldValue > 0) sendChat('', 'Down I go...') },1000, true)); });
1609093306
It's the Aura/Tint HealthColors script from the one-click (v1.6.1). In the REGISTER EVENTS section, there's a change:token &nbsp;event calling handle:token &nbsp;which uses a prev property. I see there's a 'prev' property being used in the CHECK BARS section that's referenced several times as prevValue... but that's as far as my limited coding skills (very basic HTML and CSS) gets me.&nbsp; Here's the full unedited code: /* global createObj TokenMod spawnFxWithDefinition getObj state playerIsGM sendChat _ findObjs log on*/ /* My Profile link: <a href="https://app.roll20.net/users/262130/dxwarlock" rel="nofollow">https://app.roll20.net/users/262130/dxwarlock</a> GIT link: <a href="https://github.com/dxwarlock/Roll20/blob/master/Public/HeathColors" rel="nofollow">https://github.com/dxwarlock/Roll20/blob/master/Public/HeathColors</a> Roll20Link: <a href="https://app.roll20.net/forum/post/4630083/script-aura-slash-tint-healthcolor" rel="nofollow">https://app.roll20.net/forum/post/4630083/script-aura-slash-tint-healthcolor</a> */ /*jshint bitwise: false*/ var HealthColors = HealthColors || (function () { &nbsp; &nbsp; 'use strict'; &nbsp; &nbsp; var version = '1.6.1', &nbsp; &nbsp; &nbsp; &nbsp; ScriptName = "HealthColors", &nbsp; &nbsp; &nbsp; &nbsp; schemaVersion = '1.0.3', &nbsp; &nbsp; &nbsp; &nbsp; Updated = "Aug 20 2020", /*------------------------ ON TOKEN CHANGE/CREATE ------------------------*/ &nbsp; &nbsp; &nbsp; &nbsp; handleToken = function (obj, prev, update) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Check existance of state and create default if needed. Needed because when copying games state is not copied and handleToken is called before CheckInstall &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(state.HealthColors === undefined) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log(ScriptName + " " + version + " state is missing, reverting to default state"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HealthColors.CheckInstall(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //CHECK IF TRIGGERED------------ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(state.HealthColors.auraColorOn !== true || obj.get("layer") !== "objects") return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(obj.get("represents") !== "" || (obj.get("represents") === "" &amp;&amp; state.HealthColors.OneOff === true)) { &nbsp; &nbsp; //**CHECK BARS------------// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var barUsed = state.HealthColors.auraBar; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var maxValue, curValue, prevValue; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(obj.get(barUsed + "_max") !== "" || obj.get(barUsed + "_value") !== "") { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; maxValue = parseInt(obj.get(barUsed + "_max"), 10); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curValue = parseInt(obj.get(barUsed + "_value"), 10); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prevValue = prev[barUsed + "_value"]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(isNaN(maxValue) || isNaN(curValue) || isNaN(prevValue)) return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //CALC PERCENTAGE------------ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var percReal = Math.round((curValue / maxValue) * 100); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var markerColor = PercentToHEX(percReal); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //DEFINE VARIABLES--- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var pColor = '#ffffff'; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var GM = '',PC = ''; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var IsTypeOn, PercentOn, ShowDead, UseAura; &nbsp; &nbsp; &nbsp; &nbsp; //**CHECK MONSTER OR PLAYER------------// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var oCharacter = getObj('character', obj.get("_represents")); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var type = (oCharacter === undefined || oCharacter.get("controlledby") === "") ? 'Monster' : 'Player'; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var colortype = (state.HealthColors.auraTint) ? 'tint' : 'aura1'; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //IF PLAYER------------ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(type == 'Player') { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM = state.HealthColors.GM_PCNames; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PC = state.HealthColors.PCNames; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IsTypeOn =state.HealthColors.PCAura; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PercentOn = state.HealthColors.auraPercPC; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShowDead = state.HealthColors.auraDeadPC; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var cBy = oCharacter.get('controlledby'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var player = getObj('player', cBy); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pColor = '#000000'; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(player !== undefined) pColor = player.get('color'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //IF MONSTER------------ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if(type == 'Monster') { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM = state.HealthColors.GM_NPCNames; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PC = state.HealthColors.NPCNames; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IsTypeOn =state.HealthColors.NPCAura; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PercentOn = state.HealthColors.auraPerc; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShowDead = state.HealthColors.auraDead; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else return; &nbsp; &nbsp; &nbsp; &nbsp; //CHECK DISABLED AURA/TINT ATTRIB------------ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(oCharacter !== undefined) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UseAura = lookupUseColor(oCharacter); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //SET HEALTH COLOR---------- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(IsTypeOn &amp;&amp; UseAura !== "NO") { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; percReal = Math.min(percReal, 100); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(percReal &gt; PercentOn || curValue === 0) SetAuraNone(obj); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else TokenSet(obj, state.HealthColors.AuraSize, markerColor, pColor, update); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //SHOW DEAD---------- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(ShowDead === true) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(curValue &gt; 0) obj.set("status_dead", false); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if(curValue &lt; 1) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var DeadSounds = state.HealthColors.auraDeadFX; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(DeadSounds !== "None" &amp;&amp; curValue != prevValue) PlayDeath(DeadSounds); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj.set("status_dead", true); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetAuraNone(obj); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if((!IsTypeOn || UseAura === "NO") &amp;&amp; obj.get(colortype + '_color') === markerColor) SetAuraNone(obj); &nbsp; &nbsp; &nbsp; &nbsp; //SET SHOW NAMES------------ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetShowNames(GM,PC,obj); //**SPURT FX------------// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(curValue != prevValue &amp;&amp; prevValue != "" &amp;&amp; update !== "YES") { &nbsp; &nbsp; &nbsp; &nbsp; //CHECK BLOOD ATTRIB------------ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var UseBlood; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(oCharacter !== undefined) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UseBlood = lookupUseBlood(oCharacter); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(state.HealthColors.FX === true &amp;&amp; obj.get("layer") == "objects" &amp;&amp; (UseBlood !== "OFF" || UseBlood !== "NO")) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var HurtColor, HealColor, FX, aFX, FXArray = []; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var amount = Math.abs(curValue - prevValue); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var HitSizeCalc = Math.min((amount / maxValue) * 4, 1); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var Scale = obj.get("height") / 70; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var HitSize = Math.max(HitSizeCalc, 0.2) * (_.random(60, 100) / 100); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //IF HEALED------------ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(curValue &gt; prevValue) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; aFX = findObjs({_type: "custfx",name: '-DefaultHeal'}, {caseInsensitive: true})[0]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FX = aFX.get("definition"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HealColor = HEXtoRGB(state.HealthColors.HealFX); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FX.startColour = HealColor; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FXArray.push(FX); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //IF HURT------------ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if(curValue &lt; prevValue) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; aFX = findObjs({_type: "custfx",name: '-DefaultHurt'}, {caseInsensitive: true})[0]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(aFX) FX = aFX.get("definition"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //CHECK DEFAULT COLOR-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(UseBlood === "DEFAULT" || UseBlood === undefined) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HurtColor = HEXtoRGB(state.HealthColors.HurtFX); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FX.startColour = HurtColor; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FXArray.push(FX); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //ELSE CHECK CUSTOM COLOR/FX-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if(UseBlood !== "DEFAULT" &amp;&amp; UseBlood !== undefined) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HurtColor = HEXtoRGB(UseBlood); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //IF CUSTOM COLOR-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.difference(HurtColor, [0, 0, 0, 0]).length !== 0) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FX.startColour = HurtColor; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FXArray.push(FX); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //ELSE ASSUME CUSTOM FX-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var i = UseBlood.split(/,/); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.each(i, function (FXname) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; aFX = findObjs({_type: "custfx",name: FXname}, {caseInsensitive: true})[0]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(aFX) FXArray.push(aFX.get("definition")); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else GMW("No FX with name " + FXname); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //SPAWN FX------------ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.each(FXArray, function (FX) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SpawnFX(Scale, HitSize, obj.get("left"), obj.get("top"), FX, obj.get("_pageid")); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; /*------------------------ &nbsp; &nbsp; CHAT MESSAGES &nbsp; &nbsp; ------------------------*/ &nbsp; &nbsp; &nbsp; &nbsp; handleInput = function (msg) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var msgFormula = msg.content.split(/\s+/); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var command = msgFormula[0].toUpperCase(), UPPER =""; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(msg.type == "api" &amp;&amp; command.indexOf("!AURA") !== -1) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var OPTION = msgFormula[1] || "MENU"; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!playerIsGM(msg.playerid)) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('HealthColors', "/w " + msg.who + " you must be a GM to use this command!"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(OPTION !== "MENU") GMW("UPDATING TOKENS..."); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch(OPTION.toUpperCase()) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "MENU": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "ON": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.auraColorOn = !state.HealthColors.auraColorOn; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "BAR": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.auraBar = "bar" + msgFormula[2]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "TINT": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.auraTint = !state.HealthColors.auraTint; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "PERC": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.auraPercPC = parseInt(msgFormula[2], 10); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.auraPerc = parseInt(msgFormula[3], 10); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "PC": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.PCAura = !state.HealthColors.PCAura; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "NPC": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.NPCAura = !state.HealthColors.NPCAura; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "GMNPC": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.GM_NPCNames = msgFormula[2]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "GMPC": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.GM_PCNames = msgFormula[2]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "PCNPC": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.NPCNames = msgFormula[2]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "PCPC": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.PCNames = msgFormula[2]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "DEAD": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.auraDead = !state.HealthColors.auraDead; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "DEADPC": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.auraDeadPC = !state.HealthColors.auraDeadPC; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "DEADFX": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.auraDeadFX = msgFormula[2]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "SIZE": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.AuraSize = parseFloat(msgFormula[2]); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "ONEOFF": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.OneOff = !state.HealthColors.OneOff; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "FX": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.FX = !state.HealthColors.FX; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "HEAL": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UPPER = msgFormula[2]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UPPER = UPPER.toUpperCase(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.HealFX = UPPER; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "HURT": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UPPER = msgFormula[2]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UPPER = UPPER.toUpperCase(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.HurtFX = UPPER; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "RESET": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; delete state.HealthColors; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GMW("STATE RESET"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; checkInstall(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "UPDATE": &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; manUpdate(msg); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; aurahelp(OPTION); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, /*------------------------ "FUNCTIONS" ------------------------*/ &nbsp; &nbsp; //SET TOKEN COLORS------------ &nbsp; &nbsp; &nbsp; &nbsp; TokenSet = function (obj, sizeSet, markerColor, pColor, update) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var Pageon = getObj("page", obj.get("_pageid")); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var scale = Pageon.get("scale_number") / 10; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(state.HealthColors.auraTint === true) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(obj.get('aura1_color') == markerColor &amp;&amp; update === "YES") { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj.set({'aura1_color': "transparent",'aura2_color': "transparent",}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj.set({'tint_color': markerColor,}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(obj.get('tint_color') == markerColor &amp;&amp; update === "YES") { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj.set({'tint_color': "transparent",}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj.set({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'aura1_radius': sizeSet * scale * 1.8, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'aura2_radius': sizeSet * scale * 0.1, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'aura1_color': markerColor, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'aura2_color': pColor, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'showplayers_aura1': true, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'showplayers_aura2': true, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //REMOVE ALL------------ &nbsp; &nbsp; &nbsp; &nbsp; SetAuraNone = function (obj) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(state.HealthColors.auraTint === true) obj.set({'tint_color': "transparent",}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else obj.set({'aura1_color': "transparent",'aura2_color': "transparent",}); &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //FORCE ALL TOKEN UPDATE------------ &nbsp; &nbsp; &nbsp; &nbsp; MenuForceUpdate = function(){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let i = 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const start = new Date().getTime(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const barUsed = state.HealthColors.auraBar; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const workQueue = findObjs({type: 'graphic',subtype: 'token',layer: 'objects'}) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter((o)=&gt;o.get(barUsed + "_max") !== "" &amp;&amp; o.get(barUsed + "_value") !== ""); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const drainQueue = ()=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let t = workQueue.shift(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(t){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const prev = JSON.parse(JSON.stringify(t)); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handleToken( t, prev, 'YES'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setTimeout(drainQueue,0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('Fixing Tokens',`/w gm Finished Fixing Tokens`); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('Fixing Tokens',`/w gm Fixing ${workQueue.length} Tokens`); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; drainQueue(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var end = new Date().getTime(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return "Tokens Processed: " + workQueue.length + "&lt;br&gt;Run time in ms: " + (end - start); &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; SetShowNames = function(GM,PC,obj) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(GM != 'Off' &amp;&amp; GM != '') { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GM = (GM == "Yes") ? true : false; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj.set({'showname': GM}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(PC != 'Off' &amp;&amp; PC != '') { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PC = (PC == "Yes") ? true : false; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj.set({'showplayers_name': PC}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //MANUAL UPDATE------------ &nbsp; &nbsp; &nbsp; &nbsp; manUpdate = function(msg){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var selected = msg.selected; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var allNames = ''; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.each(selected, function(obj) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var token = getObj('graphic', obj._id); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var tName = token.get("name"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; allNames = allNames.concat(tName+'&lt;br&gt;'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var prev = JSON.parse(JSON.stringify(token)); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handleToken(token, prev, "YES"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GMW(allNames); &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //ATTRIBUTE CACHE------------ &nbsp; &nbsp; &nbsp; &nbsp; makeSmartAttrCache = function (attribute, options) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let cache = {}, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;defaultValue = options.default || 'YES', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;validator = options.validation || _.constant(true); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; on('change:attribute', function (attr) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(attr.get('name') === attribute) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(!validator(attr.get('current'))) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;attr.set('current', defaultValue); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cache[attr.get('characterid')] = attr.get('current'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var tokens = findObjs({type: 'graphic'}).filter((o) =&gt; o.get('represents') === attr.get("characterid")); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_.each(tokens, function (obj) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var prev = JSON.parse(JSON.stringify(obj)); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;handleToken(obj, prev, "YES"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; on('destroy:attribute', function (attr) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(attr.get('name') === attribute) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;delete cache[attr.get('characterid')]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return function(character){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let attr = findObjs({type: 'attribute',name: attribute,characterid: character.id},{caseInsensitive:true})[0] || &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; createObj('attribute',{name: attribute,characterid: character.id, current: defaultValue}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!cache[character.id] || cache[character.id] !== attr.get('current')){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(!validator(attr.get('current'))){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;attr.set('current',defaultValue); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cache[character.id]=attr.get('current'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return cache[character.id]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; lookupUseBlood = makeSmartAttrCache('USEBLOOD',{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default: 'DEFAULT' &nbsp; &nbsp; &nbsp; &nbsp; }), &nbsp; &nbsp; &nbsp; &nbsp; lookupUseColor = makeSmartAttrCache('USECOLOR',{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default: 'YES', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; validation: (o)=&gt;o.match(/YES|NO/) &nbsp; &nbsp; &nbsp; &nbsp; }), &nbsp; &nbsp; //DEATH SOUND------------ &nbsp; &nbsp; &nbsp; &nbsp; PlayDeath = function (trackname) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var RandTrackName; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(trackname.indexOf(",") &gt; 0) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var tracklist = trackname.split(","); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RandTrackName = tracklist[Math.floor(Math.random() * tracklist.length)]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else RandTrackName = trackname; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var track = findObjs({type: 'jukeboxtrack',title: RandTrackName})[0]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(track) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; track.set('playing', false); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; track.set('softstop', false); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; track.set('volume', 50); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; track.set('playing', true); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log(ScriptName + ": No track found named " + RandTrackName); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //PERC TO RGB------------ &nbsp; &nbsp; &nbsp; &nbsp; PercentToHEX = function (percent) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var HEX; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(percent &gt; 100) HEX = "#0000FF"; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(percent === 100) percent = 99; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var r, g, b = 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(percent &lt; 50) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g = Math.floor(255 * (percent / 50)); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r = 255; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g = 255; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r = Math.floor(255 * ((50 - percent % 50) / 50)); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HEX = "#" + ((1 &lt;&lt; 24) + (r &lt;&lt; 16) + (g &lt;&lt; 8) + b).toString(16).slice(1); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return HEX; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //HEX TO RGB------------ &nbsp; &nbsp; &nbsp; &nbsp; HEXtoRGB = function (hex) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let parts = (hex || '').match(/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(parts) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let rgb = _.chain(parts).rest().map((d) =&gt; parseInt(d, 16)).value(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rgb.push(1.0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return rgb; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return [0, 0, 0, 0.0]; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //SPAWN FX------------ &nbsp; &nbsp; &nbsp; &nbsp; SpawnFX = function (Scale,HitSize,left,top,FX,pageid) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.defaults(FX, { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "maxParticles": 100, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "duration": 100, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "size": 100, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "sizeRandom": 100, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "lifeSpan": 100, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "lifeSpanRandom": 100, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "speed": 0, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "speedRandom": 0, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "angle": 0, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "angleRandom": 0, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "emissionRate": 100, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "startColour": [255,255,255,1], &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "endColour": [0,0,0,1], &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "gravity": {"x": 0,"y": 0.0}, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var newFX = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "maxParticles": FX.maxParticles * HitSize, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "duration": FX.duration * HitSize, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "size": FX.size * Scale / 2, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "sizeRandom": FX.sizeRandom * Scale / 2, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "lifeSpan": FX.lifeSpan, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "lifeSpanRandom": FX.lifeSpanRandom, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "speed": FX.speed * Scale, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "speedRandom": FX.speedRandom * Scale, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "angle": FX.angle, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "angleRandom": FX.angleRandom, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "emissionRate": FX.emissionRate * HitSize * 2, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "startColour": FX.startColour, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "endColour": FX.endColour, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "gravity": {"x": FX.gravity.x * Scale,"y": FX.gravity.y * Scale}, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spawnFxWithDefinition(left,top,newFX,pageid); &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //HELP MENU------------ &nbsp; &nbsp; &nbsp; &nbsp; aurahelp = function (OPTION) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var Update = ''; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(OPTION !== "MENU") Update = MenuForceUpdate(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var img = "background-image: -webkit-linear-gradient(left, #76ADD6 0%, #a7c7dc 100%);"; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var tshadow = "-1px -1px #222, 1px -1px #222, -1px 1px #222, 1px 1px #222 , 2px 2px #222;"; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var style = 'style="padding-top: 1px; text-align:center; font-size: 9pt; width: 48px; height: 14px; border: 1px solid black; margin: 1px; background-color: #6FAEC7;border-radius: 4px;&nbsp; box-shadow: 1px 1px 1px #707070;'; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var off = "#A84D4D"; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var disable = "#D6D6D6"; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var HR = "&lt;hr style='background-color: #000000; margin: 5px; border-width:0;color: #000000;height: 1px;'/&gt;"; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var FX = state.HealthColors.auraDeadFX.substring(0, 4); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('HealthColors', "/w GM &lt;b&gt;&lt;br&gt;" + '&lt;div style="border-radius: 8px 8px 8px 8px; padding: 5px; font-size: 9pt; text-shadow: ' + tshadow + '; box-shadow: 3px 3px 1px #707070; ' + img + ' color:#FFF; border:2px solid black; text-align:right; vertical-align:middle;"&gt;' + '&lt;u&gt;&lt;big&gt;HealthColors Version: ' + version + '&lt;/u&gt;&lt;/big&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HR + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Is On: &lt;a ' + style + 'background-color:' + (state.HealthColors.auraColorOn !== true ? off : "") + ';" href="!aura on"&gt;' + (state.HealthColors.auraColorOn !== true ? "No" : "Yes") + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Bar: &lt;a ' + style + '" href="!aura bar ?{Bar|1|2|3}"&gt;' + state.HealthColors.auraBar + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Use Tint: &lt;a ' + style + 'background-color:' + (state.HealthColors.auraTint !== true ? off : "") + ';" href="!aura tint"&gt;' + (state.HealthColors.auraTint !== true ? "No" : "Yes") + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Percentage(PC/NPC): &lt;a ' + style + '" href="!aura perc ?{PCPercent?|100} ?{NPCPercent?|100}"&gt;' + state.HealthColors.auraPercPC + '/'+ state.HealthColors.auraPerc +'&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HR + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Show PC Health: &lt;a ' + style + 'background-color:' + (state.HealthColors.PCAura !== true ? off : "") + ';" href="!aura pc"&gt;' + (state.HealthColors.PCAura !== true ? "No" : "Yes") + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Show NPC Health: &lt;a ' + style + 'background-color:' + (state.HealthColors.NPCAura !== true ? off : "") + ';" href="!aura npc"&gt;' + (state.HealthColors.NPCAura !== true ? "No" : "Yes") + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Show Dead PC: &lt;a ' + style + 'background-color:' + (state.HealthColors.auraDeadPC !== true ? off : "") + ';" href="!aura deadPC"&gt;' + (state.HealthColors.auraDeadPC !== true ? "No" : "Yes") + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Show Dead NPC: &lt;a ' + style + 'background-color:' + (state.HealthColors.auraDead !== true ? off : "") + ';" href="!aura dead"&gt;' + (state.HealthColors.auraDead !== true ? "No" : "Yes") + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HR + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'GM Sees all PC Names: &lt;a ' + style + 'background-color:' + ButtonColor(state.HealthColors.GM_PCNames, off, disable) + ';" href="!aura gmpc ?{Setting|Yes|No|Off}"&gt;' + state.HealthColors.GM_PCNames + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'GM Sees all NPC Names: &lt;a ' + style + 'background-color:' + ButtonColor(state.HealthColors.GM_NPCNames, off, disable) + ';" href="!aura gmnpc ?{Setting|Yes|No|Off}"&gt;' + state.HealthColors.GM_NPCNames + '&lt;/a&gt;&lt;br&gt;' + //--- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HR + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'PC Sees all PC Names: &lt;a ' + style + 'background-color:' + ButtonColor(state.HealthColors.PCNames, off, disable) + ';" href="!aura pcpc ?{Setting|Yes|No|Off}"&gt;' + state.HealthColors.PCNames + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'PC Sees all NPC Names: &lt;a ' + style + 'background-color:' + ButtonColor(state.HealthColors.NPCNames, off, disable) + ';" href="!aura pcnpc ?{Setting|Yes|No|Off}"&gt;' + state.HealthColors.NPCNames + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HR + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Aura Size: &lt;a ' + style + '" href="!aura size ?{Size?|0.7}"&gt;' + state.HealthColors.AuraSize + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'One Offs: &lt;a ' + style + 'background-color:' + (state.HealthColors.OneOff !== true ? off : "") + ';" href="!aura ONEOFF"&gt;' + (state.HealthColors.OneOff !== true ? "No" : "Yes") + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'FX: &lt;a ' + style + 'background-color:' + (state.HealthColors.FX !== true ? off : "") + ';" href="!aura FX"&gt;' + (state.HealthColors.FX !== true ? "No" : "Yes") + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'HealFX Color: &lt;a ' + style + 'background-color:#' + state.HealthColors.HealFX + ';""href="!aura HEAL ?{Color?|00FF00}"&gt;' + state.HealthColors.HealFX + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'HurtFX Color: &lt;a ' + style + 'background-color:#' + state.HealthColors.HurtFX + ';""href="!aura HURT ?{Color?|FF0000}"&gt;' + state.HealthColors.HurtFX + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'DeathSFX: &lt;a ' + style + '" href="!aura deadfx ?{Sound Name?|' + state.HealthColors.auraDeadFX + '}"&gt;' + FX + '&lt;/a&gt;&lt;br&gt;' + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HR + //-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Update +//-- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'); &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //OFF BUTTON COLORS------------ &nbsp; &nbsp; &nbsp; &nbsp; ButtonColor = function (state, off, disable) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var color; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(state == "No") color = off; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(state == "Off") color = disable; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return color; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //CHECK INSTALL &amp; SET STATE------------ &nbsp; &nbsp; &nbsp; &nbsp; checkInstall = function () { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log('-=&gt;' + ScriptName + ' v' + version + ' [Updated: ' + Updated + ']&lt;=-'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!_.has(state, 'HealthColors') || state.HealthColors.schemaVersion !== schemaVersion) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log('&lt;' + ScriptName + ' Updating Schema to v' + schemaVersion + '&gt;'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors = {schemaVersion: schemaVersion}; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.HealthColors.version = version; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //CHECK STATE VALUES &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.auraColorOn)) state.HealthColors.auraColorOn = true; //global on or off &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.auraBar)) state.HealthColors.auraBar = "bar1"; //bar to use &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.auraTint)) state.HealthColors.auraTint = false; //use tint instead? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.auraPercPC)) state.HealthColors.auraPercPC = 100; //precent to start showing PC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.auraPerc)) state.HealthColors.auraPerc = 100; //precent to start showing NPC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //----------------- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.PCAura)) state.HealthColors.PCAura = true; //show players Health? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.NPCAura)) state.HealthColors.NPCAura = true; //show NPC Health? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.auraDeadPC)) state.HealthColors.auraDeadPC = true; //show dead X status PC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.auraDead)) state.HealthColors.auraDead = true; //show dead X status NPC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //----------------- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.GM_PCNames)) state.HealthColors.GM_PCNames = "Yes"; //show GM PC names? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.PCNames)) state.HealthColors.PCNames = "Yes"; //show players PC Names? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //----------------- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.GM_NPCNames)) state.HealthColors.GM_NPCNames = "Yes"; //show GM NPC names? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.NPCNames)) state.HealthColors.NPCNames = "Yes"; //show players NPC Names? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //----------------- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.AuraSize)) state.HealthColors.AuraSize = 0.7; //set aura size? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.FX)) state.HealthColors.FX = true; //set FX ON/OFF? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.HealFX)) state.HealthColors.HealFX = "00FF00"; //set FX HEAL COLOR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.HurtFX)) state.HealthColors.HurtFX = "FF0000"; //set FX HURT COLOR? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.isUndefined(state.HealthColors.auraDeadFX)) state.HealthColors.auraDeadFX = 'None'; //Sound FX Name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //TokenMod CHECK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if('undefined' !== typeof TokenMod &amp;&amp; TokenMod.ObserveTokenChange) TokenMod.ObserveTokenChange(handleToken); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var FXHurt = findObjs({_type: "custfx",name: "-DefaultHurt"}, {caseInsensitive: true})[0]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var FXHeal = findObjs({_type: "custfx",name: "-DefaultHeal"}, {caseInsensitive: true})[0]; &nbsp; &nbsp; &nbsp; &nbsp; //DEFAULT FX CHECK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!FXHurt) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GMW("Creating Default Hurt FX"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var Hurt = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "maxParticles": 150, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "duration": 50, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "size": 10, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "sizeRandom": 3, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "lifeSpan": 25, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "lifeSpanRandom": 5, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "speed": 8, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "speedRandom": 3, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "gravity": {"x": 0.01,"y": 0.65}, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "angle": 270, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "angleRandom": 25, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "emissionRate": 100, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "startColour": [0, 0, 0, 0], &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "endColour": [0, 0, 0, 0], &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; createObj('custfx', {name: "-DefaultHurt",definition: Hurt}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!FXHeal) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GMW("Creating Default Heal FX"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var Heal = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "maxParticles": 150, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "duration": 50, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "size": 10, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "sizeRandom": 15, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "lifeSpan": 50, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "lifeSpanRandom": 30, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "speed": 0.5, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "speedRandom": 2, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "angle": 0, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "angleRandom": 180, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "emissionRate": 1000, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "startColour": [0, 0, 0, 0], &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "endColour": [0, 0, 0, 0], &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; createObj('custfx', {name: "-DefaultHeal",definition: Heal}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //WHISPER GM------------ &nbsp; &nbsp; &nbsp; &nbsp; GMW = function (text) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var DIV = "&lt;div style='width: 100%; border-radius: 4px;&nbsp; box-shadow: 1px 1px 1px #707070; text-align: center; vertical-align: middle; padding: 3px 0px; margin: 0px auto; border: 1px solid #000; color: #000; background-image: -webkit-linear-gradient(-45deg, #a7c7dc 0%,#85b2d3 100%);"; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var MSG = DIV + "'&gt;&lt;b&gt;"+text+"&lt;/b&gt;&lt;/div"; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('HealthColors', "/w GM "+MSG); &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //OUTSIDE CALL------------ &nbsp; &nbsp; &nbsp; &nbsp; UpdateToken = function (obj, prev) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (obj.get("type") === "graphic") handleToken(obj, prev); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else GMW("Script sent non-Token to be updated!"); &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; //REGISTER TRIGGERS------------ &nbsp; &nbsp; &nbsp; &nbsp; registerEventHandlers = function () { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; on('chat:message', handleInput); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; on("change:token", handleToken); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; on('add:token', function (t) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.delay(() =&gt; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let token = getObj('graphic', t.id), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prev = JSON.parse(JSON.stringify(token)); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handleToken(token, prev, "YES"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 400); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; //RETURN OUTSIDE FUNCTIONS------------ &nbsp; &nbsp; return { &nbsp; &nbsp; &nbsp; &nbsp; GMW: GMW, &nbsp; &nbsp; &nbsp; &nbsp; Update: UpdateToken, &nbsp; &nbsp; &nbsp; &nbsp; CheckInstall: checkInstall, &nbsp; &nbsp; &nbsp; &nbsp; RegisterEventHandlers: registerEventHandlers &nbsp; &nbsp; }; }()); //On Ready on('ready', function () { &nbsp; &nbsp; 'use strict'; &nbsp; &nbsp; HealthColors.GMW("API READY"); &nbsp; &nbsp; HealthColors.CheckInstall(); &nbsp; &nbsp; HealthColors.RegisterEventHandlers(); });
1609106157
GiGs
Pro
Sheet Author
API Scripter
the handleToken function starts like this handleToken = function (obj, prev, update) { So you can use obj.get('propertyname') to get token properties as they are now, after the change event, and use prev.propertyname to get the value of propertyname before the change event fired. So you'll know which tokenbar is used to track hit points (that's saved in the script somewhere), so you can query that property with obj.get and prev., and then move some of the script code inside an if statement, which only runs those two are different. Honestly I'm surprised it doesnt do that already, but havent studied the code- maybe there's a good reason.
1609108292

Edited 1609108336
In fact the script does just that, but not in the place where you would expect it if you interpret the code as 'this handles a health change'. But the script does so much at the same time: The same code that handles health changes also handles new tokens. And the same code also set/unsets the name, set/unsets the aura,crosses/uncrosses a token upon Death&nbsp; and&nbsp; plays FX. And all aspects of this are configurable.&nbsp; Checks are cheaps, changes are expensive... so it does a lot of checks first and than executes the changes.&nbsp;
1609119086
Martijn S. said: In fact the script does just that, but not in the place where you would expect it if you interpret the code as 'this handles a health change'. But the script does so much at the same time: The same code that handles health changes also handles new tokens. And the same code also set/unsets the name, set/unsets the aura,crosses/uncrosses a token upon Death&nbsp; and&nbsp; plays FX. And all aspects of this are configurable.&nbsp; Checks are cheaps, changes are expensive... so it does a lot of checks first and than executes the changes.&nbsp; There's a setting to not show the name to players only upon reaching 0 hp, and reset it if it goes above 0 hp? There's a setting to have tint applied to a token only at 0hp, but use an aura for any time above 0 hp? There's a setting to not use the large red X cross upon death, but use something else instead (red tint)? There's a setting to whisper to the GM when a token reaches 0 hp, and again when it goes above 0 hp? If those settings are already built into the script, I would love to know where, and how to set them!
1609124979
Oosh
Sheet Author
I think all you need is to change the first conditional - the script already has the two values you need: //SHOW DEAD---------- if(ShowDead === true &amp;&amp; prevValue !== curValue) { The entire block will only run if an HP change triggered the event.
1609131547

Edited 1609131714
Oosh said: I think all you need is to change the first conditional - the script already has the two values you need: //SHOW DEAD---------- if(ShowDead === true &amp;&amp; prevValue !== curValue) { The entire block will only run if an HP change triggered the event. I got it to work! Thank you Oosh! I had a feeling there was some simple little snippet of code that would trigger only on changes to hp. For some reason your code didn't work at first, and it was still triggering on token movement.&nbsp; I also threw the&nbsp; curValue != prevValue &nbsp;into the&nbsp; curValue &gt; 0 &nbsp;and&nbsp; curValue &lt; 1 &nbsp;sections, just to be sure.&nbsp; &nbsp;&nbsp; But then I switched the two arguments: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(curValue != prevValue &amp;&amp; ShowDead === true) { And then it worked. So maybe I somehow missed something when I cut and pasted it (I don't know how that could happen... and I wasn't getting an error message on the API page).&nbsp; Who knows? But it's working now. So for anyone else like me who wants to have these settings, I've added the code to the end of my first post in this thread.
1609132215

Edited 1609132243
Oosh
Sheet Author
Ah... it might be the triple equals, perhaps? Right up at the top where the variables are defined, prevValue doesn't get the parseInt treatment, for some reason. Probably a good idea to chuck it in there: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; maxValue = parseInt(obj.get(barUsed + "_max"), 10); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curValue = parseInt(obj.get(barUsed + "_value"), 10); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prevValue = prev[barUsed + "_value"]; It looks like the prev object mostly stores actual integers, though from a quick look it does have some strings in there as well. Won't hurt to make sure.