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 adding TokenMod observation to existing script

Hi folks! I came across keithcurtis' simple concentration script and I've simplified it a bit more to suit my group's needs. We usually use TokenMod to make hp bar changes though, and I'd like to adjust this further to recognize changes via TokenMod. Here's the script as I'm currently using it: on('ready', () => { const TOKEN_CONCENTRATING_STATUS_MARKER = "status_" + "concentration::4718809"; on("change:graphic:bar1_value", function(obj, prev) { if (obj.get(TOKEN_CONCENTRATING_STATUS_MARKER)) { log ("status marker is " + obj.get(TOKEN_CONCENTRATING_STATUS_MARKER)); //let playerPage = Campaign().get("playerpageid"); //let tokenPage = obj.get("_pageid"); if (prev["bar1_value"] > obj.get("bar1_value")) { let final_conc_DC = 10; let calc_conc_DC = (prev["bar1_value"] - obj.get("bar1_value")) / 2; if (calc_conc_DC > final_conc_DC) { final_conc_DC = Math.floor(calc_conc_DC); } let tokenName = obj.get("name"); let theMessage = "/w gm &{template:npcaction} {{rname=Concentration Check}} {{name="+tokenName+"}} {{description=[DC " +final_conc_DC + " Constitution](~selected|constitution_save)}}"; sendChat("Concentration",theMessage ); } } }); }); And I know I'll need to add something along the lines of this (pulled from another script so I know it won't be this exactly): on('change:graphic', handleTokenChange); if('undefined' !== typeof TokenMod && TokenMod.ObserveTokenChange){ TokenMod.ObserveTokenChange(handleTokenChange); } But I'm not sure which part of the script to change to a constant to use in place of handleTokenChange, let alone how exactly I'd go about that. If anyone's familiar with how to do this your help will be greatly appreciated!
1681324233
timmaugh
Pro
API Scripter
Hey, P... That's close.  You want the registration with TokenMod to happen in a 'ready' handler (which it probably was in the script you pulled this from): on('ready',function(){   on('change:graphic', handleTokenChange);   if('undefined' !== typeof TokenMod && TokenMod.ObserveTokenChange){     TokenMod.ObserveTokenChange(handleTokenChange);   } }; Then, somewhere in your script, you would declare the handleTokenChange function, setting it to accept two parameters ( obj , and prev ): const handleTokenChange = (obj, prev) => { ... }; That would then get the code from what you have currently written into the graphic change handler. Altogether, it would look something more like (air-coded, so apologies for errors): on('ready', () => {   const TOKEN_CONCENTRATING_STATUS_MARKER = "status_" + "concentration::4718809";   const handleTokenChange = (obj, prev) => {     if (obj.get(TOKEN_CONCENTRATING_STATUS_MARKER)) {         log ("status marker is " + obj.get(TOKEN_CONCENTRATING_STATUS_MARKER));         //let playerPage = Campaign().get("playerpageid");         //let tokenPage = obj.get("_pageid");         if (prev["bar1_value"] > obj.get("bar1_value")) {             let final_conc_DC = 10;             let calc_conc_DC = (prev["bar1_value"] - obj.get("bar1_value")) / 2;             if (calc_conc_DC > final_conc_DC) {                 final_conc_DC = Math.floor(calc_conc_DC);             }             let tokenName = obj.get("name");             let theMessage = "/w gm &{template:npcaction} {{rname=Concentration Check}} {{name="+tokenName+"}} {{description=[DC " +final_conc_DC + " Constitution](~selected|constitution_save)}}"; sendChat("Concentration",theMessage );                 }     }   };   on('change:graphic', handleTokenChange);   if('undefined' !== typeof TokenMod && TokenMod.ObserveTokenChange){     TokenMod.ObserveTokenChange(handleTokenChange);   } }); The thing to look at would be that previously the listener was set up specifically for the bar1 value changing... now it's registering for all graphic changes. I would just make sure that whatever you put in the handleTokenChange function is testing to make sure it is a change it should be reacting to (currently that is what it does: testing if the old value is greater than the new value).
Thanks timmaugh! I think that's just what I needed. I knew I would need to alter line 3 to define handleTokenChange as that whole section there, but I was struggling to understand which parts to keep and which ones to move. If I'm understanding how the observer works, I think I can narrow it by altering on('change:graphic', handleTokenChange); to this instead? on('change:graphic:bar1_value', handleTokenChange); Or is that redundant since handleTokenChange already specifies bar1_value within its function?
1681330882

Edited 1681331068
timmaugh
Pro
API Scripter
I'd have to look at TokenMod to know how it handles emitting events. Roll20 will emit both a 'change:graphic' and a 'change:graphic:bar1_value', but I don't know whether TokenMod follows that pattern, or if Aaron has consolidated the events down to just a single sort of "token-mod took action" event. I'll poke him and see if he can weigh in. EDIT: Until Aaron weighs in, I think you're OK... no matter what TokenMod emits, your function is already making sure that it only acts when it needs to... so, to your question: yes. You should be fine to put that back.
1681331200
The Aaron
Roll20 Production Team
API Scripter
TokenMod doesn't provide refinement based on events.  If you supply a function to ObserveTokenChange, it will call it for each token it changes with a new state (obj, a Roll20 Graphic Object), and previous state (prev, a POD JS Object). In the case of the on(<EVENT>,<FUNCTION>), you are correct.  The second method will result in handleTokenChange only being called by Roll20 if a user changes the value of bar1 on a token.  This will reduce the number of times it is called for user interactions.  You would want to still leave the check against bar1 being changed in the function since you are passing it to TokenMod, but there's no harm in reducing the number of times it's called.
I tested it out with your adjustments (observing 'change:graphic') and so far it's doing just what I wanted it to :) Thanks again!
The Aaron said: You would want to still leave the check against bar1 being changed in the function since you are passing it to TokenMod, but there's no harm in reducing the number of times it's called. That makes sense! I appreciate the clarification :)