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 Mod Help] Changing script to affect NPCs only

Hey all. Awhile back, a user here made a small script for me that swaps out tokens for "chalk outline" images when they reach 0 HP, and if they're NPCs, removes them from initiative (healing the chalk outline re-swaps and puts the token back into initiative). I love the script, but want to make one modification: I don't want it to affect player tokens at all. The problem is that I have zero script expertise, and the user who made the script for me hasn't responded to my queries. So I was wondering if anyone else could show me how to mod this script so that it only targets NPCs and my players don't have their tokens turned into chalk outlines whenever they drop to 0. Here's the code: /* InitiativeCleaner script: Author: Scott C. Contact: <a href="https://app.roll20.net/users/459831/scott-c" rel="nofollow">https://app.roll20.net/users/459831/scott-c</a> */ var cleaner = cleaner || (function() { &nbsp; &nbsp; 'use strict'; &nbsp; &nbsp; var version = '0.02', &nbsp; &nbsp; &nbsp; &nbsp; lastUpdate = 1555799069, &nbsp; &nbsp; &nbsp; &nbsp; schemaVersion = 0.02, &nbsp; &nbsp; &nbsp; &nbsp; hpBar = 3, &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ch = function (c) { &nbsp; &nbsp; &nbsp; &nbsp; var entities = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;' : 'lt', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&gt;' : 'gt', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "'" : '#39', &nbsp; &nbsp; '@' : '#64', '{' : '#123', '|' : '#124', '}' : '#125', '[' : '#91', ']' : '#93', '"' : 'quot', '-' : 'mdash', ' ' : 'nbsp' }; if(_.has(entities,c) ){ return ('&amp;'+entities[c]+';'); } return ''; }, esRE = function (s) { &nbsp; &nbsp; &nbsp; &nbsp; var escapeForRegexp = /(\\|\/|\[|\]|\(|\)|\{|\}|\?|\+|\*|\||\.|\^|\$)/g; &nbsp; &nbsp; &nbsp; &nbsp; return s.replace(escapeForRegexp,"\\$1"); &nbsp; &nbsp; }, &nbsp; &nbsp; HE = (function(){ &nbsp; &nbsp; &nbsp; &nbsp; var entities={ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //' ' : '&amp;'+'nbsp'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&amp;' : '&amp;'+'amp'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;' : '&amp;'+'lt'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&gt;' : '&amp;'+'gt'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "'" : '&amp;'+'#39'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '@' : '&amp;'+'#64'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //'{' : '&amp;'+'#123'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '|' : '&amp;'+'#124'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '}' : '&amp;'+'#125'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ',' : '&amp;'+'#44'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '[' : '&amp;'+'#91'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ']' : '&amp;'+'#93'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '"' : '&amp;'+'quot'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ':' : '&amp;'+'#58'+';', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //'-' : '&amp;'+'mdash'+';' &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; re=new RegExp('('+_.map(_.keys(entities),esRE).join('|')+')','g'); &nbsp; &nbsp; &nbsp; &nbsp; return function(s){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return s.replace(re, function(c){ return entities[c] || c; }); &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; }()), &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; checkInstall = function() { &nbsp; &nbsp; &nbsp; &nbsp; log('-=&gt; cleaner v'+version+' &lt;=- &nbsp; ['+(new Date(lastUpdate*1000))+']'); &nbsp; &nbsp; &nbsp; &nbsp; if( ! _.has(state,'cleaner') || state.cleaner.version !== schemaVersion) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.cleaner=state.cleaner || {}; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log(' &nbsp; &gt; Updating Schema to v'+schemaVersion+' &lt;'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.cleaner.version = schemaVersion; } &nbsp; &nbsp; }, &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; cleanImgSrc = function(img){ &nbsp; &nbsp; &nbsp; &nbsp; var parts = img.match(/(.*\/images\/.*)(thumb|med|original|max)(.*)$/); &nbsp; &nbsp; &nbsp; &nbsp; if(parts) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return parts[1]+'thumb'+parts[3]; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; }, &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; cleanField = function(token,prev){ &nbsp; &nbsp; &nbsp; &nbsp; log(`Reacting to change of ${token.get('name')}`); &nbsp; &nbsp; &nbsp; &nbsp; let turnTracker =Campaign().get('initiativepage'), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; turnOrder = Campaign().get('turnorder'), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; initiative,character,cleanHistory; &nbsp; &nbsp; &nbsp; &nbsp; try{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; turnOrder = JSON.parse(turnOrder); &nbsp; &nbsp; &nbsp; &nbsp; }catch (err){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; turnOrder = false; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; if(token.get('represents')!=='' &amp;&amp; token.get(`bar${hpBar}_value`)*1!==prev[`bar${hpBar}_value`]*1 &amp;&amp; turnTracker &amp;&amp; turnOrder){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; character = getObj('character',token.get('represents')); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log(`cleaning battlefield`); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const tokenID = token.id; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; token = getObj('graphic',tokenID); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cleanHistory = token.get('gmnotes').replace(/.*?({.*}).*/,'$1').replace(/\n/,''); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cleanHistory = JSON.parse(cleanHistory); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }catch (err){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cleanHistory = false; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(token.get(`bar${hpBar}_value`)*1&lt;=0){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; createCorpse(token,character,turnOrder); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else if(token.get(`bar${hpBar}_value`)*1&gt;0 &amp;&amp; cleanHistory){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reviveToken(token,character,turnOrder); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log(`applying changes to battlefield`); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; }, &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; createCorpse = function(token,character,turnOrder){ &nbsp; &nbsp; &nbsp; &nbsp; let deadImage = findObjs({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; type:'rollabletable', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name:'deadTable' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },{caseinsensitive:true})[0], &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; creationObj,tokenTurn; &nbsp; &nbsp; &nbsp; &nbsp; const setObj = {}; &nbsp; &nbsp; &nbsp; &nbsp; deadImage = findObjs({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; type:'tableitem', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _rollabletableid:deadImage.id &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; deadImage = _.reduce(deadImage,(memo,item)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.each(_.range(item.get('weight')*1),(n)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memo.push(cleanImgSrc(item.get('avatar'))); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return memo; &nbsp; &nbsp; &nbsp; &nbsp; },[]); &nbsp; &nbsp; &nbsp; &nbsp; deadImage = deadImage[randomInteger(deadImage.length) - 1]; &nbsp; &nbsp; &nbsp; &nbsp; log(`${token.get('name')} is dead, their corpse looks like ${deadImage}`); &nbsp; &nbsp; &nbsp; &nbsp; creationObj = _.reduce([ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'represents','name','left','top','width','height','_pageid','layer','barN_value','barN_link','barN_max','auraN_radius','auraN_color','auraN_square', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'tintcolor','statusmarkers','showname','showplayers_name','showplayers_barN','showplayers_auraN','playersedit_name','playersedit_barN', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'playersedit_auraN','light_radius','light_dimradius','light_otherplayers','light_hassight','light_angle','light_losangle', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'lastmove','light_multiplier','adv_fow_view_distance' &nbsp; &nbsp; &nbsp; &nbsp; ],(memo,attr)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(/N/.test(attr)){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; attr.replace(/(.*)N(.*)/,(match,pre,post)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.each(/aura/.test(pre) ? [1,2] : [1,2,3],(n)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memo[`${pre}${n}${post}`]=token.get(`${pre}${n}${post}`); &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{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memo[attr]=token.get(attr); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return memo; &nbsp; &nbsp; &nbsp; &nbsp; },{}); &nbsp; &nbsp; &nbsp; &nbsp; creationObj.rotation = randomInteger(361) - 1; &nbsp; &nbsp; &nbsp; &nbsp; creationObj.imgsrc = deadImage; &nbsp; &nbsp; &nbsp; &nbsp; let newToken = createObj('graphic',creationObj); &nbsp; &nbsp; &nbsp; &nbsp; turnOrder = _.reject(turnOrder,(turn)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(turn.id === token.id){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tokenTurn = _.clone(turn); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(character.get('controlledby')===''){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; turn.id = newToken.id; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; newToken.set({gmnotes: `{"originalToken":"${token.id}","deathInitiative":${JSON.stringify(tokenTurn)}}\n${token.get('gmnotes')}`.replace(/undefined/,'"$&amp;"')}); &nbsp; &nbsp; &nbsp; &nbsp; setObj.layer = 'walls'; &nbsp; &nbsp; &nbsp; &nbsp; token.set(setObj); &nbsp; &nbsp; &nbsp; &nbsp; if(turnOrder){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Campaign().set('turnorder',JSON.stringify(turnOrder)); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; }, &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; reviveToken = function(token,character,turnOrder){ &nbsp; &nbsp; &nbsp; &nbsp; let initiative; &nbsp; &nbsp; &nbsp; &nbsp; log(`${token.get('name')} is being revived`); &nbsp; &nbsp; &nbsp; &nbsp; token.get('gmnotes').replace(/{"originalToken":"(.+?)","deathInitiative":("undefined"|.*?})}\n?(.*)/,(match,tokenID,init,originalText)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let origToken = getObj('graphic',tokenID); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log(`origToken: ${JSON.stringify(origToken)}`); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const setObj = _.reduce([ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'left','top','width','height','layer','barN_value','barN_link','barN_max','auraN_radius','auraN_color','auraN_square', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'tintcolor','statusmarkers','showname','showplayers_name','showplayers_barN','showplayers_auraN','playersedit_name','playersedit_barN', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'playersedit_auraN','light_radius','light_dimradius','light_otherplayers','light_hassight','light_angle','light_losangle', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'lastmove','light_multiplier','adv_fow_view_distance' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ],(memo,attr)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(/N/.test(attr)){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; attr.replace(/(.*)N(.*)/,(match,pre,post)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.each(/aura/.test(pre) ? [1,2] : [1,2,3],(n)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memo[`${pre}${n}${post}`]=token.get(`${pre}${n}${post}`); &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{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; memo[attr]=token.get(attr); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return memo; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },{layer:token.get('layer')}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; origToken.set(setObj); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; initiative = JSON.parse(init); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }catch (err){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; initiative = false; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return originalText; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; log(`initial turnOrder: ${JSON.stringify(turnOrder)}`); &nbsp; &nbsp; &nbsp; &nbsp; if(initiative){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; turnOrder = sortInitiative(turnOrder,initiative,token.id); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; log(`final turnOrder: ${JSON.stringify(turnOrder)}`); &nbsp; &nbsp; &nbsp; &nbsp; if(turnOrder){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Campaign().set('turnorder',JSON.stringify(turnOrder)); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; token.remove(); &nbsp; &nbsp; }, &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; sortInitiative = function(order,init,deadID){ &nbsp; &nbsp; &nbsp; &nbsp; const newOrder = []; &nbsp; &nbsp; &nbsp; &nbsp; let initAdded = false; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.some(order,(turn)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(turn.id === deadID){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; turn.id = init.id; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; initAdded = true; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return initAdded; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; if(initAdded){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return order; &nbsp; &nbsp; &nbsp; &nbsp; }else{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.each(order,(turn)=&gt;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(turn.pr*1&lt;init.pr*1 &amp;&amp; !_.isEmpty(newOrder)&amp;&amp;!initAdded){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newOrder.push(init); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newOrder.push(turn); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; initAdded = true; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else if(turn.pr*1===init.pr*1){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newOrder.push(turn); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newOrder.push(init); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; initAdded = true; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }else{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newOrder.push(turn); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; if(!initAdded){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newOrder.push(init); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; return newOrder; &nbsp; &nbsp; }, &nbsp; &nbsp; RegisterEventHandlers = function() { &nbsp; &nbsp; &nbsp; &nbsp; on('change:graphic', cleanField); &nbsp; &nbsp; }; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; return { &nbsp; &nbsp; &nbsp; &nbsp; CheckInstall: checkInstall, &nbsp; &nbsp; RegisterEventHandlers: RegisterEventHandlers }; &nbsp;&nbsp; &nbsp; }()); on("ready",function(){ &nbsp; &nbsp; 'use strict'; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; cleaner.CheckInstall(); &nbsp; &nbsp; cleaner.RegisterEventHandlers(); });
1611234129
GiGs
Pro
Sheet Author
API Scripter
It looks like its supposed to ignore your player tokens already, due to this line: if(token.get('represents')!=='' &amp;&amp; token.get(`bar${hpBar}_value`)*1!==prev[`bar${hpBar}_value`]*1 &amp;&amp; turnTracker &amp;&amp; turnOrder){ Do your players tokens have their represents field set properly?
GiGs said: It looks like its supposed to ignore your player tokens already, due to this line: if(token.get('represents')!=='' &amp;&amp; token.get(`bar${hpBar}_value`)*1!==prev[`bar${hpBar}_value`]*1 &amp;&amp; turnTracker &amp;&amp; turnOrder){ Do your players tokens have their represents field set properly? Yep, their tokens are set correctly. Right now, the script ignores the "remove token from initiative" part of the script for player tokens but still converts every token, player or NPC, to a chalk outline.&nbsp;
1611235644
Kurt J.
Pro
API Scripter
Jay R. said: GiGs said: It looks like its supposed to ignore your player tokens already, due to this line: if(token.get('represents')!=='' &amp;&amp; token.get(`bar${hpBar}_value`)*1!==prev[`bar${hpBar}_value`]*1 &amp;&amp; turnTracker &amp;&amp; turnOrder){ Do your players tokens have their represents field set properly? Yep, their tokens are set correctly. Right now, the script ignores the "remove token from initiative" part of the script for player tokens but still converts every token, player or NPC, to a chalk outline.&nbsp; Represents just means a token represents a character in the characters list (PC or NPC). The "controlledby" attribute will start with "-" (an object ID) if it is controlled by one or more (but not all) players, "all" if controlled by all players, or "" if not controlled by anyone (an NPC).
Kurt J. said: Jay R. said: GiGs said: It looks like its supposed to ignore your player tokens already, due to this line: if(token.get('represents')!=='' &amp;&amp; token.get(`bar${hpBar}_value`)*1!==prev[`bar${hpBar}_value`]*1 &amp;&amp; turnTracker &amp;&amp; turnOrder){ Do your players tokens have their represents field set properly? Yep, their tokens are set correctly. Right now, the script ignores the "remove token from initiative" part of the script for player tokens but still converts every token, player or NPC, to a chalk outline.&nbsp; Represents just means a token represents a character in the characters list (PC or NPC). The "controlledby" attribute will start with "-" (an object ID) if it is controlled by one or more (but not all) players, "all" if controlled by all players, or "" if not controlled by anyone (an NPC). Thanks for this clarification, Kurt. So then I'm puzzled as to why the script still targets PCs for the chalk outline part, since this part --&nbsp;if(token.get('represents')!=='' -- would seem to include only NPCs. Each of my player tokens is controlled by one player.
1611237317

Edited 1611248384
The Aaron
Roll20 Production Team
API Scripter
Try this: /* InitiativeCleaner script: Author: Scott C. Contact: <a href="https://app.roll20.net/users/459831/scott-c" rel="nofollow">https://app.roll20.net/users/459831/scott-c</a> */ /* global TokenMod */ var cleaner = cleaner || (function() { 'use strict'; var version = '0.02', lastUpdate = 1611241695, schemaVersion = 0.02, hpBar = 3, ch = function (c) { var entities = { '&lt;' : 'lt', '&gt;' : 'gt', "'" : '#39', '@' : '#64', '{' : '#123', '|' : '#124', '}' : '#125', '[' : '#91', ']' : '#93', '"' : 'quot', '-' : 'mdash', ' ' : 'nbsp' }; if(_.has(entities,c) ){ return ('&amp;'+entities[c]+';'); } return ''; }, esRE = function (s) { var escapeForRegexp = /(\\|\/|\[|\]|\(|\)|\{|\}|\?|\+|\*|\||\.|\^|\$)/g; return s.replace(escapeForRegexp,"\\$1"); }, HE = (function(){ var entities={ //' ' : '&amp;'+'nbsp'+';', '&amp;' : '&amp;'+'amp'+';', '&lt;' : '&amp;'+'lt'+';', '&gt;' : '&amp;'+'gt'+';', "'" : '&amp;'+'#39'+';', '@' : '&amp;'+'#64'+';', //'{' : '&amp;'+'#123'+';', '|' : '&amp;'+'#124'+';', '}' : '&amp;'+'#125'+';', ',' : '&amp;'+'#44'+';', '[' : '&amp;'+'#91'+';', ']' : '&amp;'+'#93'+';', '"' : '&amp;'+'quot'+';', ':' : '&amp;'+'#58'+';', //'-' : '&amp;'+'mdash'+';' }, re=new RegExp('('+_.map(_.keys(entities),esRE).join('|')+')','g'); return function(s){ return s.replace(re, function(c){ return entities[c] || c; }); }; }()), checkInstall = function() { log('-=&gt; cleaner v'+version+' &lt;=- ['+(new Date(lastUpdate*1000))+']'); if( ! _.has(state,'cleaner') || state.cleaner.version !== schemaVersion) { state.cleaner=state.cleaner || {}; log(' &gt; Updating Schema to v'+schemaVersion+' &lt;'); state.cleaner.version = schemaVersion; } }, cleanImgSrc = function(img){ var parts = img.match(/(.*\/images\/.*)(thumb|med|original|max)(.*)$/); if(parts) { return parts[1]+'thumb'+parts[3]; } return; }, playerCanControl = (obj, playerid='any') =&gt; { const playerInControlledByList = (list, playerid) =&gt; list.includes('all') || list.includes(playerid) || ('any'===playerid &amp;&amp; list.length); let players = obj.get('controlledby') .split(/,/) .filter(s=&gt;s.length); if(playerInControlledByList(players,playerid)){ return true; } if('' !== obj.get('represents') ) { players = (getObj('character',obj.get('represents')) || {get: function(){return '';} } ) .get('controlledby').split(/,/) .filter(s=&gt;s.length); return playerInControlledByList(players,playerid); } return false; }, cleanField = function(token,prev){ log(`Reacting to change of ${token.get('name')}`); let turnTracker =Campaign().get('initiativepage'), turnOrder = Campaign().get('turnorder'), initiative,character,cleanHistory; try{ turnOrder = JSON.parse(turnOrder); }catch (err){ turnOrder = false; } if(!playerCanControl(token) &amp;&amp; token.get('represents')!=='' &amp;&amp; token.get(`bar${hpBar}_value`)*1!==prev[`bar${hpBar}_value`]*1 &amp;&amp; turnTracker &amp;&amp; turnOrder){ character = getObj('character',token.get('represents')); log(`cleaning battlefield`); const tokenID = token.id; token = getObj('graphic',tokenID); try{ cleanHistory = token.get('gmnotes').replace(/.*?({.*}).*/,'$1').replace(/\n/,''); cleanHistory = JSON.parse(cleanHistory); }catch (err){ cleanHistory = false; } if(token.get(`bar${hpBar}_value`)*1&lt;=0){ createCorpse(token,character,turnOrder); }else if(token.get(`bar${hpBar}_value`)*1&gt;0 &amp;&amp; cleanHistory){ reviveToken(token,character,turnOrder); } log(`applying changes to battlefield`); } }, createCorpse = function(token,character,turnOrder){ let deadImage = findObjs({ type:'rollabletable', name:'deadTable' },{caseinsensitive:true})[0], creationObj,tokenTurn; const setObj = {}; deadImage = findObjs({ type:'tableitem', _rollabletableid:deadImage.id }); deadImage = _.reduce(deadImage,(memo,item)=&gt;{ _.each(_.range(item.get('weight')*1),(n)=&gt;{ memo.push(cleanImgSrc(item.get('avatar'))); }); return memo; },[]); deadImage = deadImage[randomInteger(deadImage.length) - 1]; log(`${token.get('name')} is dead, their corpse looks like ${deadImage}`); creationObj = _.reduce([ 'represents','name','left','top','width','height','_pageid','layer','barN_value','barN_link','barN_max','auraN_radius','auraN_color','auraN_square', 'tintcolor','statusmarkers','showname','showplayers_name','showplayers_barN','showplayers_auraN','playersedit_name','playersedit_barN', 'playersedit_auraN','light_radius','light_dimradius','light_otherplayers','light_hassight','light_angle','light_losangle', 'lastmove','light_multiplier','adv_fow_view_distance' ],(memo,attr)=&gt;{ if(/N/.test(attr)){ attr.replace(/(.*)N(.*)/,(match,pre,post)=&gt;{ _.each(/aura/.test(pre) ? [1,2] : [1,2,3],(n)=&gt;{ memo[`${pre}${n}${post}`]=token.get(`${pre}${n}${post}`); }); }); }else{ memo[attr]=token.get(attr); } return memo; },{}); creationObj.rotation = randomInteger(361) - 1; creationObj.imgsrc = deadImage; let newToken = createObj('graphic',creationObj); turnOrder = _.reject(turnOrder,(turn)=&gt;{ if(turn.id === token.id){ tokenTurn = _.clone(turn); if(character.get('controlledby')===''){ return true; }else{ turn.id = newToken.id; } } return false; }); newToken.set({gmnotes: `{"originalToken":"${token.id}","deathInitiative":${JSON.stringify(tokenTurn)}}\n${token.get('gmnotes')}`.replace(/undefined/,'"$&amp;"')}); setObj.layer = 'walls'; token.set(setObj); if(turnOrder){ Campaign().set('turnorder',JSON.stringify(turnOrder)); } }, reviveToken = function(token,character,turnOrder){ let initiative; log(`${token.get('name')} is being revived`); token.get('gmnotes').replace(/{"originalToken":"(.+?)","deathInitiative":("undefined"|.*?})}\n?(.*)/,(match,tokenID,init,originalText)=&gt;{ let origToken = getObj('graphic',tokenID); log(`origToken: ${JSON.stringify(origToken)}`); const setObj = _.reduce([ 'left','top','width','height','layer','barN_value','barN_link','barN_max','auraN_radius','auraN_color','auraN_square', 'tintcolor','statusmarkers','showname','showplayers_name','showplayers_barN','showplayers_auraN','playersedit_name','playersedit_barN', 'playersedit_auraN','light_radius','light_dimradius','light_otherplayers','light_hassight','light_angle','light_losangle', 'lastmove','light_multiplier','adv_fow_view_distance' ],(memo,attr)=&gt;{ if(/N/.test(attr)){ attr.replace(/(.*)N(.*)/,(match,pre,post)=&gt;{ _.each(/aura/.test(pre) ? [1,2] : [1,2,3],(n)=&gt;{ memo[`${pre}${n}${post}`]=token.get(`${pre}${n}${post}`); }); }); }else{ memo[attr]=token.get(attr); } return memo; },{layer:token.get('layer')}); origToken.set(setObj); try{ initiative = JSON.parse(init); }catch (err){ initiative = false; } return originalText; }); log(`initial turnOrder: ${JSON.stringify(turnOrder)}`); if(initiative){ turnOrder = sortInitiative(turnOrder,initiative,token.id); } log(`final turnOrder: ${JSON.stringify(turnOrder)}`); if(turnOrder){ Campaign().set('turnorder',JSON.stringify(turnOrder)); } token.remove(); }, sortInitiative = function(order,init,deadID){ const newOrder = []; let initAdded = false; _.some(order,(turn)=&gt;{ if(turn.id === deadID){ turn.id = init.id; initAdded = true; } return initAdded; }); if(initAdded){ return order; }else{ _.each(order,(turn)=&gt;{ if(turn.pr*1&lt;init.pr*1 &amp;&amp; !_.isEmpty(newOrder)&amp;&amp;!initAdded){ newOrder.push(init); newOrder.push(turn); initAdded = true; }else if(turn.pr*1===init.pr*1){ newOrder.push(turn); newOrder.push(init); initAdded = true; }else{ newOrder.push(turn); } }); } if(!initAdded){ newOrder.push(init); } return newOrder; }, RegisterEventHandlers = function() { on('change:graphic', cleanField); if('undefined' !== typeof TokenMod &amp;&amp; TokenMod.ObserveTokenChange){ TokenMod.ObserveTokenChange(cleanField); } }; return { CheckInstall: checkInstall, RegisterEventHandlers: RegisterEventHandlers }; }()); on("ready",function(){ 'use strict'; cleaner.CheckInstall(); cleaner.RegisterEventHandlers(); });
1611237872
GiGs
Pro
Sheet Author
API Scripter
Kurt J. said: Jay R. said: GiGs said: It looks like its supposed to ignore your player tokens already, due to this line: if(token.get('represents')!=='' &amp;&amp; token.get(`bar${hpBar}_value`)*1!==prev[`bar${hpBar}_value`]*1 &amp;&amp; turnTracker &amp;&amp; turnOrder){ Do your players tokens have their represents field set properly? Yep, their tokens are set correctly. Right now, the script ignores the "remove token from initiative" part of the script for player tokens but still converts every token, player or NPC, to a chalk outline.&nbsp; Represents just means a token represents a character in the characters list (PC or NPC). The "controlledby" attribute will start with "-" (an object ID) if it is controlled by one or more (but not all) players, "all" if controlled by all players, or "" if not controlled by anyone (an NPC). Oh yeah, little brain wonkiness there.
1611240053
Kurt J.
Pro
API Scripter
Jay R. said: Kurt J. said: Jay R. said: GiGs said: It looks like its supposed to ignore your player tokens already, due to this line: if(token.get('represents')!=='' &amp;&amp; token.get(`bar${hpBar}_value`)*1!==prev[`bar${hpBar}_value`]*1 &amp;&amp; turnTracker &amp;&amp; turnOrder){ Do your players tokens have their represents field set properly? Yep, their tokens are set correctly. Right now, the script ignores the "remove token from initiative" part of the script for player tokens but still converts every token, player or NPC, to a chalk outline.&nbsp; Represents just means a token represents a character in the characters list (PC or NPC). The "controlledby" attribute will start with "-" (an object ID) if it is controlled by one or more (but not all) players, "all" if controlled by all players, or "" if not controlled by anyone (an NPC). Thanks for this clarification, Kurt. So then I'm puzzled as to why the script still targets PCs for the chalk outline part, since this part --&nbsp;if(token.get('represents')!=='' -- would seem to include only NPCs. Each of my player tokens is controlled by one player. It should be an axiom to "always go with what The Aaron says..." :) But for clarification, get('represents') would need to be get('controlledby') to prevent it from impacting PCs (totally untested) :)
Will try, Aaron, and thank you as always! While I have you here, question: is there a way to make this Initiative Cleaner script work with my Tokenmod damage macro? Currently, the script only triggers if I reduce or add HP by modifying bar1 directly, and not through Tokenmod. This is my current damage macro: /fx glow-blood @{selected|token_id} !token-mod {{ --set bar1_value|-[[?{Enter Damage Amount|0}]]! --report all|"/em {name} takes {bar1_value:abschange} damage." player|"**{name}** now has **{bar1_value}/{bar1_max}** hp." }} The Aaron said: Try this: /* InitiativeCleaner script: Author: Scott C. Contact: <a href="https://app.roll20.net/users/459831/scott-c" rel="nofollow">https://app.roll20.net/users/459831/scott-c</a> */ var cleaner = cleaner || (function() { 'use strict'; var version = '0.02', lastUpdate = 1555799069, schemaVersion = 0.02, hpBar = 3, ch = function (c) { var entities = { '&lt;' : 'lt', '&gt;' : 'gt', "'" : '#39', '@' : '#64', '{' : '#123', '|' : '#124', '}' : '#125', '[' : '#91', ']' : '#93', '"' : 'quot', '-' : 'mdash', ' ' : 'nbsp' }; if(_.has(entities,c) ){ return ('&amp;'+entities[c]+';'); } return ''; }, esRE = function (s) { var escapeForRegexp = /(\\|\/|\[|\]|\(|\)|\{|\}|\?|\+|\*|\||\.|\^|\$)/g; return s.replace(escapeForRegexp,"\\$1"); }, HE = (function(){ var entities={ //' ' : '&amp;'+'nbsp'+';', '&amp;' : '&amp;'+'amp'+';', '&lt;' : '&amp;'+'lt'+';', '&gt;' : '&amp;'+'gt'+';', "'" : '&amp;'+'#39'+';', '@' : '&amp;'+'#64'+';', //'{' : '&amp;'+'#123'+';', '|' : '&amp;'+'#124'+';', '}' : '&amp;'+'#125'+';', ',' : '&amp;'+'#44'+';', '[' : '&amp;'+'#91'+';', ']' : '&amp;'+'#93'+';', '"' : '&amp;'+'quot'+';', ':' : '&amp;'+'#58'+';', //'-' : '&amp;'+'mdash'+';' }, re=new RegExp('('+_.map(_.keys(entities),esRE).join('|')+')','g'); return function(s){ return s.replace(re, function(c){ return entities[c] || c; }); }; }()), checkInstall = function() { log('-=&gt; cleaner v'+version+' &lt;=- ['+(new Date(lastUpdate*1000))+']'); if( ! _.has(state,'cleaner') || state.cleaner.version !== schemaVersion) { state.cleaner=state.cleaner || {}; log(' &gt; Updating Schema to v'+schemaVersion+' &lt;'); state.cleaner.version = schemaVersion; } }, cleanImgSrc = function(img){ var parts = img.match(/(.*\/images\/.*)(thumb|med|original|max)(.*)$/); if(parts) { return parts[1]+'thumb'+parts[3]; } return; }, playerCanControl = (obj, playerid='any') =&gt; { const playerInControlledByList = (list, playerid) =&gt; list.includes('all') || list.includes(playerid) || ('any'===playerid &amp;&amp; list.length); let players = obj.get('controlledby') .split(/,/) .filter(s=&gt;s.length); if(playerInControlledByList(players,playerid)){ return true; } if('' !== obj.get('represents') ) { players = (getObj('character',obj.get('represents')) || {get: function(){return '';} } ) .get('controlledby').split(/,/) .filter(s=&gt;s.length); return playerInControlledByList(players,playerid); } return false; }, cleanField = function(token,prev){ log(`Reacting to change of ${token.get('name')}`); let turnTracker =Campaign().get('initiativepage'), turnOrder = Campaign().get('turnorder'), initiative,character,cleanHistory; try{ turnOrder = JSON.parse(turnOrder); }catch (err){ turnOrder = false; } if(!playerCanConbtrol(token) &amp;&amp; token.get('represents')!=='' &amp;&amp; token.get(`bar${hpBar}_value`)*1!==prev[`bar${hpBar}_value`]*1 &amp;&amp; turnTracker &amp;&amp; turnOrder){ character = getObj('character',token.get('represents')); log(`cleaning battlefield`); const tokenID = token.id; token = getObj('graphic',tokenID); try{ cleanHistory = token.get('gmnotes').replace(/.*?({.*}).*/,'$1').replace(/\n/,''); cleanHistory = JSON.parse(cleanHistory); }catch (err){ cleanHistory = false; } if(token.get(`bar${hpBar}_value`)*1&lt;=0){ createCorpse(token,character,turnOrder); }else if(token.get(`bar${hpBar}_value`)*1&gt;0 &amp;&amp; cleanHistory){ reviveToken(token,character,turnOrder); } log(`applying changes to battlefield`); } }, createCorpse = function(token,character,turnOrder){ let deadImage = findObjs({ type:'rollabletable', name:'deadTable' },{caseinsensitive:true})[0], creationObj,tokenTurn; const setObj = {}; deadImage = findObjs({ type:'tableitem', _rollabletableid:deadImage.id }); deadImage = _.reduce(deadImage,(memo,item)=&gt;{ _.each(_.range(item.get('weight')*1),(n)=&gt;{ memo.push(cleanImgSrc(item.get('avatar'))); }); return memo; },[]); deadImage = deadImage[randomInteger(deadImage.length) - 1]; log(`${token.get('name')} is dead, their corpse looks like ${deadImage}`); creationObj = _.reduce([ 'represents','name','left','top','width','height','_pageid','layer','barN_value','barN_link','barN_max','auraN_radius','auraN_color','auraN_square', 'tintcolor','statusmarkers','showname','showplayers_name','showplayers_barN','showplayers_auraN','playersedit_name','playersedit_barN', 'playersedit_auraN','light_radius','light_dimradius','light_otherplayers','light_hassight','light_angle','light_losangle', 'lastmove','light_multiplier','adv_fow_view_distance' ],(memo,attr)=&gt;{ if(/N/.test(attr)){ attr.replace(/(.*)N(.*)/,(match,pre,post)=&gt;{ _.each(/aura/.test(pre) ? [1,2] : [1,2,3],(n)=&gt;{ memo[`${pre}${n}${post}`]=token.get(`${pre}${n}${post}`); }); }); }else{ memo[attr]=token.get(attr); } return memo; },{}); creationObj.rotation = randomInteger(361) - 1; creationObj.imgsrc = deadImage; let newToken = createObj('graphic',creationObj); turnOrder = _.reject(turnOrder,(turn)=&gt;{ if(turn.id === token.id){ tokenTurn = _.clone(turn); if(character.get('controlledby')===''){ return true; }else{ turn.id = newToken.id; } } return false; }); newToken.set({gmnotes: `{"originalToken":"${token.id}","deathInitiative":${JSON.stringify(tokenTurn)}}\n${token.get('gmnotes')}`.replace(/undefined/,'"$&amp;"')}); setObj.layer = 'walls'; token.set(setObj); if(turnOrder){ Campaign().set('turnorder',JSON.stringify(turnOrder)); } }, reviveToken = function(token,character,turnOrder){ let initiative; log(`${token.get('name')} is being revived`); token.get('gmnotes').replace(/{"originalToken":"(.+?)","deathInitiative":("undefined"|.*?})}\n?(.*)/,(match,tokenID,init,originalText)=&gt;{ let origToken = getObj('graphic',tokenID); log(`origToken: ${JSON.stringify(origToken)}`); const setObj = _.reduce([ 'left','top','width','height','layer','barN_value','barN_link','barN_max','auraN_radius','auraN_color','auraN_square', 'tintcolor','statusmarkers','showname','showplayers_name','showplayers_barN','showplayers_auraN','playersedit_name','playersedit_barN', 'playersedit_auraN','light_radius','light_dimradius','light_otherplayers','light_hassight','light_angle','light_losangle', 'lastmove','light_multiplier','adv_fow_view_distance' ],(memo,attr)=&gt;{ if(/N/.test(attr)){ attr.replace(/(.*)N(.*)/,(match,pre,post)=&gt;{ _.each(/aura/.test(pre) ? [1,2] : [1,2,3],(n)=&gt;{ memo[`${pre}${n}${post}`]=token.get(`${pre}${n}${post}`); }); }); }else{ memo[attr]=token.get(attr); } return memo; },{layer:token.get('layer')}); origToken.set(setObj); try{ initiative = JSON.parse(init); }catch (err){ initiative = false; } return originalText; }); log(`initial turnOrder: ${JSON.stringify(turnOrder)}`); if(initiative){ turnOrder = sortInitiative(turnOrder,initiative,token.id); } log(`final turnOrder: ${JSON.stringify(turnOrder)}`); if(turnOrder){ Campaign().set('turnorder',JSON.stringify(turnOrder)); } token.remove(); }, sortInitiative = function(order,init,deadID){ const newOrder = []; let initAdded = false; _.some(order,(turn)=&gt;{ if(turn.id === deadID){ turn.id = init.id; initAdded = true; } return initAdded; }); if(initAdded){ return order; }else{ _.each(order,(turn)=&gt;{ if(turn.pr*1&lt;init.pr*1 &amp;&amp; !_.isEmpty(newOrder)&amp;&amp;!initAdded){ newOrder.push(init); newOrder.push(turn); initAdded = true; }else if(turn.pr*1===init.pr*1){ newOrder.push(turn); newOrder.push(init); initAdded = true; }else{ newOrder.push(turn); } }); } if(!initAdded){ newOrder.push(init); } return newOrder; }, RegisterEventHandlers = function() { on('change:graphic', cleanField); }; return { CheckInstall: checkInstall, RegisterEventHandlers: RegisterEventHandlers }; }()); on("ready",function(){ 'use strict'; cleaner.CheckInstall(); cleaner.RegisterEventHandlers(); });
1611241773
The Aaron
Roll20 Production Team
API Scripter
I adjusted the above posted script to observe TokenMod changes, that should let it trigger when you use TokenMod to adjust the token.
The Aaron said: I adjusted the above posted script to observe TokenMod changes, that should let it trigger when you use TokenMod to adjust the token. Thank you!!
It wont work... it has a typo&nbsp; playerCanConbtrol
Martijn S. said: It wont work... it has a typo&nbsp; playerCanConbtrol I know, already spotted and fixed.
The joy of interpreted languages. Typos can go unremarked for a very long time.
1611248408
The Aaron
Roll20 Production Team
API Scripter
Good catch!&nbsp; Fixed it above as well. =D
Martijn S. said: The joy of interpreted languages. Typos can go unremarked for a very long time. Agreed! :)&nbsp;