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

Help with Custom Status Markers

1587197907
StéphaneD
Pro
Sheet Author
API Scripter
Hi there Need some help understanding custom status markers. Either I mis-read or mis-understood the API help page regarding custom status markers, or it is unclear, so here is my question : when changing the token object's statusmarkers property, are the markers supposed to visually appear automagically on the token, or should the API script create a graphic object for the marker itself ?  I understand that the standard/legacy markers (the colored dots and the 'dead' red X) can still be shown or hidden using the 'status_xxxx' virtual properties on the token object, but I still don't understand how to interact with custom ones... Thanks for any help
1587240241

Edited 1587247806
The Aaron
Roll20 Production Team
API Scripter
I created this library to simply getting the available status markers:&nbsp; <a href="https://app.roll20.net/forum/post/8061179/script-library-libtokenmarkers-a-resource-for-scripts-which-simplifies-using-the-new-token-markers" rel="nofollow">https://app.roll20.net/forum/post/8061179/script-library-libtokenmarkers-a-resource-for-scripts-which-simplifies-using-the-new-token-markers</a> As for setting them, you have to add them to the comma separated string in the statusmarkers property.&nbsp; You can use these functions to simplify applying TokenMarkers: const unpackSM = (stats) =&gt; stats.split(/,/).reduce((m,v) =&gt; { let p = v.split(/@/); let n = (undefined === p[1] ? true : parseInt(p[1] || '0', 10)); if(p[0].length) { m[p[0]] = n; } return m; },{}); const packSM = (o) =&gt; Object.keys(o) .reduce( (m,k)=&gt; (false===o[k] ? m : [...m,( ('dead'===k || true === o[k]) ? k : `${k}@${Math.max(Math.min(parseInt(o[k]),9),0)}` )] ) ,[]) .join(','); Here is an example script that uses those functions, as well as libTokenMarkers to toggle a token marker on and off by name on all selected tokens.&nbsp; Just select some tokens and run: !set-sm blue To toggle the blue marker on and off.&nbsp; You can sub in whatever token marker name you want. Code: /* global libTokenMarkers */ on('ready', ()=&gt;{ // Make sure libTokenMarkers exists, and has the functions that are expected if('undefined' === typeof libTokenMarkers || (['getStatus','getStatuses','getOrderedList'].find(k=&gt; !libTokenMarkers.hasOwnProperty(k) || 'function' !== typeof libTokenMarkers[k] )) ) { // notify of the missing library sendChat('',`/w gm &lt;div style="color:red;font-weight:bold;border:2px solid red;background-color:black;border-radius:1em;padding:1em;"&gt;Missing dependency: libTokenMarkers&lt;/div&gt;`); } else { const unpackSM = (stats) =&gt; stats.split(/,/).reduce((m,v) =&gt; { let p = v.split(/@/); let n = (undefined === p[1] ? true : parseInt(p[1] || '0', 10)); if(p[0].length) { m[p[0]] = n; } return m; },{}); const packSM = (o) =&gt; Object.keys(o) .reduce( (m,k)=&gt; (false===o[k] ? m : [...m,( ('dead'===k || true === o[k]) ? k : `${k}@${Math.max(Math.min(parseInt(o[k]),9),0)}` )] ) ,[]) .join(','); // Watch for chat messages on('chat:message',(msg) =&gt; { // when `!set-sm` occurs, do something if('api'===msg.type &amp;&amp; /^!set-sm/i.test(msg.content)){ let who = (getObj('player',msg.playerid)||{get:()=&gt;'API'}).get('_displayname'); let args = msg.content.split(/\s+/).slice(1); // get all the markers that match the first argument let marker = libTokenMarkers.getStatuses(args[0]); // if there aren't any, give an error if(!marker.length){ sendChat('',`/w "${who}" Cannot find status matching: &lt;code&gt;${args[0]}&lt;/code&gt;.`); return; } // take just the first match (if you had blue, blue-dragon, blue-la-la-la, it would just be blue) marker = marker[0]; // Find all the selected tokens (msg.selected || []) .map(o=&gt;getObj('graphic',o._id)) .filter(g=&gt;undefined !== g) .forEach(t=&gt;{ // get a representation of the current markers for the token let sm = unpackSM(t.get('statusmarkers')); // if it's set, unset it, else set it sm[marker.getTag()] = (sm.hasOwnProperty(marker.getTag()) ? false : true); // store them back on the token. t.set({statusmarkers: packSM(sm)}); }); } }); } });
1587247820
The Aaron
Roll20 Production Team
API Scripter
(Made some minor updates to the code)
1587286557
StéphaneD
Pro
Sheet Author
API Scripter
Hey Aaron Okay, the missing part in the documentation was that the statusmarkers property must be loaded with status markers tags, not status markers names when setting custom markers Thanks a ton for the help !