I created this library to simply getting the available status markers: <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. You can use these functions to simplify applying TokenMarkers: const unpackSM = (stats) => stats.split(/,/).reduce((m,v) => {
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) => Object.keys(o)
.reduce(
(m,k)=> (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. Just select some tokens and run: !set-sm blue To toggle the blue marker on and off. You can sub in whatever token marker name you want. Code: /* global libTokenMarkers */
on('ready', ()=>{
// Make sure libTokenMarkers exists, and has the functions that are expected
if('undefined' === typeof libTokenMarkers
|| (['getStatus','getStatuses','getOrderedList'].find(k=>
!libTokenMarkers.hasOwnProperty(k) || 'function' !== typeof libTokenMarkers[k]
))
) {
// notify of the missing library
sendChat('',`/w gm <div style="color:red;font-weight:bold;border:2px solid red;background-color:black;border-radius:1em;padding:1em;">Missing dependency: libTokenMarkers</div>`);
} else {
const unpackSM = (stats) => stats.split(/,/).reduce((m,v) => {
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) => Object.keys(o)
.reduce(
(m,k)=> (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) => {
// when `!set-sm` occurs, do something
if('api'===msg.type && /^!set-sm/i.test(msg.content)){
let who = (getObj('player',msg.playerid)||{get:()=>'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: <code>${args[0]}</code>.`);
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=>getObj('graphic',o._id))
.filter(g=>undefined !== g)
.forEach(t=>{
// 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)});
});
}
});
}
});