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

Is it possible to read the value of a Token Statusmarker from a Macro?

I would like to be able to read the single value of a statusmarker using a macro. Say if I put the Value of statusmarker broken-shield at 3 on a Token and then wanted a player's character to be able to use a macro that would read that value and use it some way? 
1570690867
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
I think the new reporting option of token-mod can return the value, but I don't think such a macro can act on the returned value. It would probably require a custom script of some kind.
1570706820

Edited 1570745458
The Aaron
Roll20 Production Team
API Scripter
I have a script that creates attributes on characters that represents the status markers on their token.  Attributes are named sm_<NAME> and will have a value of 0-9 representing the number on the status marker.  A status marker that is present without a number will have the value 1.  A status marker with the number 0 will have the number zero, as will a status marker that isn't present. Some example attribute names: sm_blue sm_all-for-one sm_archery-target Here's the RealizeStatusmarkers script. on('ready',() => { const markerOnValue = 1; const markers=[ 'red', 'blue', 'green', 'brown', 'purple', 'pink', 'yellow', 'dead', 'skull', 'sleepy', 'half-heart', 'half-haze', 'interdiction', 'snail', 'lightning-helix', 'spanner', 'chained-heart', 'chemical-bolt', 'death-zone', 'drink-me', 'edge-crack', 'ninja-mask', 'stopwatch', 'fishing-net', 'overdrive', 'strong', 'fist', 'padlock', 'three-leaves', 'fluffy-wing', 'pummeled', 'tread', 'arrowed', 'aura', 'back-pain', 'black-flag', 'bleeding-eye', 'bolt-shield', 'broken-heart', 'cobweb', 'broken-shield', 'flying-flag', 'radioactive', 'trophy', 'broken-skull', 'frozen-orb', 'rolling-bomb', 'white-tower', 'grab', 'screaming', 'grenade', 'sentry-gun', 'all-for-one', 'angel-outfit', 'archery-target' ]; const markerAttrRegexp=/^sm_(?:red|blue|green|brown|purple|pink|yellow|dead|skull|sleepy|half-heart|half-haze|interdiction|snail|lightning-helix|spanner|chained-heart|chemical-bolt|death-zone|drink-me|edge-crack|ninja-mask|stopwatch|fishing-net|overdrive|strong|fist|padlock|three-leaves|fluffy-wing|pummeled|tread|arrowed|aura|back-pain|black-flag|bleeding-eye|bolt-shield|broken-heart|cobweb|broken-shield|flying-flag|radioactive|trophy|broken-skull|frozen-orb|rolling-bomb|white-tower|grab|screaming|grenade|sentry-gun|all-for-one|angel-outfit|archery-target)$/; const getOrCreateAttr = (()=>{ let cache = findObjs({ type: 'attribute'}) .filter( a => markerAttrRegexp.test(a.get('name'))) .reduce( (m,a) => { const cid=a.get('characterid'); m[cid]=m[cid]||{}; m[cid][a.get('name')]=a; return m; },{}); return (p)=>{ if(!cache.hasOwnProperty(p.characterid) || !cache[p.characterid].hasOwnProperty(p.name)){ cache[p.characterid]=cache[p.characterid]||{}; cache[p.characterid][p.name] = createObj('attribute',p); } return cache[p.characterid][p.name]; }; })(); const setStatus = (cid, s, v) => getOrCreateAttr({ type: 'attribute', name: `sm_${s}`, characterid: cid }).set('current',parseInt(v,10)||0); const handleStatusMarkerChange = _.debounce((obj,prev) => { if(obj.get('represents').length) { let character = getObj('character',obj.get('represents')); if(character && character.get('controlledby').length){ let sm = obj.get('statusmarkers'); if(sm!==prev.statusmarkers){ prev.statusmarkers.split(/,/) .map((s)=>s.split(/@/)) .forEach( s => setStatus(character.id,s[0])) ; sm.split(/,/) .filter(s=>s.length>0) .map((s)=>s.split(/@/)) .forEach( s => setStatus(character.id,s[0],parseInt(s[1],10)||markerOnValue)) ; } } } },10); const markersFor = (c) => markers.map( s => ({characterid: c.id, name: `sm_${s}`, current: 0}) ); const preCreateMarkersOn = (c) => { let queue = markersFor(c); const dequeue = () => { let prop = queue.shift(); if(prop){ getOrCreateAttr(prop); setTimeout(dequeue,0); } }; dequeue(); }; const handleControlledbyChange = (obj,prev) => { if( 0 === prev.controlledby.length) { preCreateMarkersOn(obj); } }; on('change:graphic',handleStatusMarkerChange); on('change:character:controlledby',handleControlledbyChange); /* global TokenMod */ if('undefined' !== typeof TokenMod && TokenMod.ObserveTokenChange){ TokenMod.ObserveTokenChange(handleStatusMarkerChange); } const workQueue = findObjs({ type: 'character' }) .filter( c => c.get('controlledby').length ) .reduce( (m,c) => [...m, ...markersFor(c)], []); log(`RealizeStatusmarkers: Initializing attributes: ${workQueue.length}`); const drainQueue = () => { let prop = workQueue.shift(); if(prop){ getOrCreateAttr(prop); setTimeout(drainQueue,0); } else { log(`RealizeStatusmarkers: Finished initializing attributes.`); } }; drainQueue(); });
1570739590

Edited 1570743528
Ajax
Pro
Not being that savvy with all this, here is a macro I am using: !power --name|@{selected|token_name} Attacks @{target|token_name} with a @{selected|MeleeWeapon} --The Roll|[[1d20+@{selected|Physical Prowess}]] **vs @{target|token_name}'s AC of [[10+@{target|bar2}]]** /w gm Damage Dealt On Hit [[@{selected|MeleeWeapon|max}-"In Here I would like the value of the broken-shield statusmarker On the Target Token to be deducted"]] Is this possible and if so how would I do it? I create all the NPCs and Monsters from just tokens and already use all the available token attributes, being able to access some other values from statusmarkers would be a real boon. Thanks for any help.
1570744808
The Aaron
Roll20 Production Team
API Scripter
It would be: !power --name|@{selected|token_name} Attacks @{target|token_name} with a @{selected|MeleeWeapon} --The Roll|[[1d20+@{selected|Physical Prowess}]] **vs @{target|token_name}'s AC of [[10+@{target|bar2}]]** /w gm Damage Dealt On Hit [[@{selected|MeleeWeapon|max}- @{selected|sm_broken-shield}] ] Note that this only works on characters that are controlled by someone.  If you need to do it for NPCs, you should set yourself as the controller on them. so that it will get the attributes created and maintained.
1570745487
The Aaron
Roll20 Production Team
API Scripter
I adjusted the above script to update the status markers on a character when it gains a controlled by, rather than waiting on an API restart.