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

Linking statusmarkers to checkbox attributes; issue with new tokens

Bit of a newb here, but been fiddling with an api script to update status markers on a token if the linked character's attributes change.  With the sheet I've been creating the attributes in question are all checkboxes which return "0" if unchecked or "on" or a value (like "4") if checked. Basic code has been working in many cases and runs something like this: on("change:attribute", function(attr) { var aName = attr.get("name"); var aCurrent = attr.get("current"); var charid = attr.get("_characterid"); // get MATCHING token(s) on current map var tokens = findObjs({ _pageid: Campaign().get("playerpageid"), _type: "graphic", represents: charid, }); // for each token for (i = 0; i < tokens.length; i++) { // case switch based on which attr was updated switch (aName) {             // examples -- sometimes using extended if / else for certain attribs, but most work with the ternary operator case "wounded": if (aCurrent == "0") { tokens[i].set("status_red", false); } else { tokens[i].set("status_red", true); } break; case "shaken": aCurrent == "on" ? tokens[i].set("status_green", true) : tokens[i].set("status_green", false); break; default : break; } } }); This all seems to work fine if I've opened that character and toggled through the respective attribute buttons.  But if I add a brand new token (linked to a character sheet) onto the map and go toggle an attribute I get nothing until I toggle that attribute again. I tried writing some kind of "initialize" function to see if setting all the attributes to non-zero and then setting them back to zero would do something, but it hasn't changed the behavior. I'm aware that this may already be done in another script, but (a) I like learning by doing and (b) all the _chains and _maps ya'll seem to like make my head spin, so trying to do it the simple way for now. Not sure what I'm missing, any tips appreciated.  Thank you!
1588280388
The Aaron
Roll20 Production Team
API Scripter
You might want to pull your handler function out to a named function, then register it for both the 'change:attribute' and 'add:attribute' events.  Probably when you check it the first time it's not getting changed, it's getting created. Writing an initialize function that creates them if they don't exist would not trigger events (API changes don't result in events.. mostly), but you could call your extracted function for each of the attributes you create.  You might run into an issue with heartbeat failures/infinite loop detection, which would necessitate rewriting that operation as a deferred processing queue. You don't need the leading _ on properties, btw.  I find it cleaner without them, and if the property becomes read-write, you don't have to change any code. The 'status_X' property setters are deprecated and don't work on the Custom Token Markers (and may not work on status markers outside the colored dots).  You might want to look into using the 'statusmarkers' property.  I have some functions that can help with that, if you're interested. Speaking of helper functions, I have a library script called libTokenMarkers that can help if you want to work with Custom Token Markers.  Currently it provides handy lists, names, etc.  I'm going to add some setting functions to it next.
1588280492
The Aaron
Roll20 Production Team
API Scripter
Also, if you want to get to a less-head-explody place with chains, maps, reduces, etc., I'm happy to talk about the ad nauseam. =D
Thank you for the suggestions.  Might take me a while to try them out.
Thank you for the pointers so far.  I've done a rudimentary job of separating the functions with something like: const foo = function(attr) {     // all my funky code to find and set the markers }; // listen for changes to attributes on("change:attribute", function(obj){ foo(obj); }); // listen for new attributes on("add:attribute", function(obj){ foo(obj); }); Still running in to the same issue where it works fine once I've touched the attributes.  But on the initial load of the game or the first time I touch an attribute it doesn't work.  I'm a little lost with your following suggestion.  Are there any examples you could point me to? The Aaron said: [y]ou could call your extracted function for each of the attributes you create.  You might run into an issue with heartbeat failures/infinite loop detection, which would necessitate rewriting that operation as a deferred processing queue.