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

Can the API act on a change:graphic, but not on add:graphic?

I stumble through understanding basic API scripts, so this may seem like a dumb question with an obvious answer. I have a script that monitors for changes to a tokenbar (watching for change:graphic:bar1_value events) and it always fires off when I drag new tokens to the tabletop, which spams my chat with whispers. This makes sense, as the token is created and the barvalue has technically changed, and the script notifies me, exactly as I have asked it to do. So I assume there is no way to avoid this happening.  There is no way to monitor the tokens only after they have been created and their initial tokenbar value set, right?
1532840487
The Aaron
Pro
API Scripter
That is a terribly annoying bug that I have reported in the past. I feel like it’s a broken contract between the event system  and the api. The add:graphic  occurs and is followed up with 1-4 change graphic events depending on some other factors.  Amyway, I digress. You can trap for this occurence and hade it appropriately.  The basic process is this: 1) catch add:graphic  and store the create time by token id.  2) catch. change:graphic  when you get the event, check the create time is older than a few seconds ago. And quit if it isn’t. 
Thanks for the tip, Aaron! Are there any scripts (yours or others) that store and/or compare times/dates? I tried working with some js date/time functions (getSeconds(), getMilliseconds(), etc.), but it looks like they are not supported in Roll20 (or maybe I am using them incorrectly?). It looks like creation date is not a property of graphics or tokens that I can query. When graphics already exist on the tabletop, they won't have a creation date to compare to, so I guess I should account for that. If a creation date does not exist, the graphic should be monitored for changes. I assume that stored creation dates would persist through my session, but would be cleared on a reload of the tabletop (unless I store them in the state?). I don't think I will need them to persist beyond the session; as you indicate, after a few seconds, I consider them to be placed tokens.
1532884216

Edited 1532893331
The Aaron
Pro
API Scripter
You can copy this function and just call it: on('ready',()=>{ const isAddChange = (()=>{ const THRESHOLD = 300; const createRegistry = {}; on('add:graphic',(obj)=>{ createRegistry[obj.id]= new Date() * 1; }); return (id) => ( (new Date()*1) - (createRegistry[id]||0) ) < THRESHOLD; })(); on('change:graphic',(obj)=>{ if( isAddChange(obj.id)) { log('Add Change'); } else { log('Real Change'); } }); }); The bold part is the function you need, the rest is a small script demonstrating it's use. If you only want something to happen when it's not an add, it might look like: /* ... */ on('change:graphic',(obj,prev)=>{ if(!isAddChange(obj.id)){ // do your thing } }); /* ... */ Cheers!
1532911959

Edited 1532912009
Many thanks, Aaron. It works great! I was achieving some success with the prev value on the token. This helped with my Mooks, as the token's speed went from Null to their speed and I was able to ignore any tokens that started with Null as the prev value, but it was not helping for any NPC who was encumbered. It looks like when a token is dragged out, it pulls the initial value from the sheet, then executes the sheetworkers on the value. This seems weird. Do sheetworkers for linked attributes run for every token I drag out? Anyway, can you explain a little bit more what is happening here? I am guessing that the THRESHHOLD of 300 is 300 seconds (milliseconds?). createRegistry is an array of object IDs and the date you capture. Why do you multiply it by 1? Then you get the date again and subtract the object's "created date" from it. If the difference is less than 300, then it was just recently created and you know it was an "add change." Thanks again!
1532916436
The Aaron
Pro
API Scripter
Pretty much. :) The add:graphic  event often provides an object with only an id, and then subsequent change events occur as the token gets set up to represent a character, and another to apply game settings defaults. I found this out working on TokenNameNumber over the years.  The createRegistry variable is an object, but you can think of it as an associative array or key/value dictionary  I’m using it to store the time that a graphic was created under it’s id. JavaScript Date objects store the time at a millisecond resolution, I multiply by 1 to force it to convert from a Date object to a number which I can later do some math on. In practice, I was getting 100ms to 140ms between the add event and the two change events, so I figured anything after 300ms was probably a real change  if you start getting false positives, you could bump that number up a bit. 1000 would be a second.