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

At a Dead End on this API script in my Character Sheet. Can I get an expert to take a looksee?

1514925067

Edited 1514938590
Pantsworth
Sheet Author
OK.  I have been beating my brains against this for the whole Christmas holiday, and it is now time to admit defeat.  Can someone tell me what I am doing wrong here?  What I am trying to do is get the attr_currDx to update when any of the attributes holding bonus or base values change.  (ie attr_mutationBonusDx) HTML Part <div> < div class="sheet-col-2-23 sheet-core-stat-label sheet-vert-middle sheet-right">DX:</div> <input type="hidden" name="attr_h_LeapMax" value="0"> <input type="hidden" name="attr_h_JumpMax" value="0"> <input type="hidden" name="attr_h_LeapMin" value="0"> <input type="hidden" name="attr_h_JumpMin" value="0"> <div><input type="text" name="attr_baseDx" /></div> <div><input type="text" name="attr_mutationBonusDx" /></div> <div><input type="text" name="attr_levelBonusDx" /></div> <div><input type="text" name="attr_otherBonusDx" /></div> <div><input type="text" name="attr_tempBonusDx" /></div> <input type="hidden" name="attr_h_CurrDx" value="0"> <div><input type="text" name="attr_CurrDx" value="3" placeholder="3" title="@{h_CurrDx}" /></div> <div> </div> <input type="hidden" name="attr_h_initMods" value="0"> <div><input type="number" name="attr_initMod" value="@{h_initMod}" disabled />INIT MOD</div> <!-- button type="roll" name="roll_initiative" value="@{wtype}&{template:simple} {{rname=^{init-u}}} {{mod=@{initiative_bonus}}} {{r1=[[@{initiative_style}+@{initiative_bonus}@{pbd_safe}[INIT] &{tracker}]]}} {{normal=1}} @{charname_output}" data-i18n="init-u">INITIATIVE</button --> <!--input type="number" name="attr_initMod" value="0" />INITIATIVE MOD</div --> <input type="hidden" name="attr_h_toHitMod" value="0"> <div><input type="number" name="attr_toHitMod" value="@{h_toHitMod}" disabled />TO-HIT BONUS</div> <div><input type="text" name="attr_Leap" value="@{h_leapMax}" />LEAP IN M</div> <!-- DX /3 --> <div><input type="text" name="attr_Jump" value="@{h_JumpMax}" />JUMP IN M</div> <!-- DX /10 --> <div> </div> <div> </div> </div> Script Part <script type="text/worker"> //State Change Handlers on("change:baseDx change:mutationBonusDx change:levelBonusDx change:otherBonusDx change:tempBonusDx", function() { console.log ("A Change was made"); update_currDex(); update_dexMods(); }); var update_currDex = function() { var update = {}; var attrsIn = ["baseDx", "mutationBonusDx", "levelBonusDx", "otherBonusDx", "tempBonusDx"]; var newCurrDx; getAttrs(attrsIn, function(values) { newCurrDx = Math.min(24, (values["baseDx"] + values["mutationBonusDx"] + values["levelBonusDx"] + values["otherBonusDx"] + values["tempBonusDx"])); update["h_currDx"] = newCurrDx; setAttrs(update); }); }; var update_dexMods = function() { var update = {}; var newCurrDx = 0; var bonusDex = 0 ; var modToInit = 0; var modToHit = 0; console.log('Starting'); getAttrs(["currDx"], function(values) { newCurrDx = values["currDex"] var MaxJump = (newCurrDx / 3 ); var MaxLeap = (newCurrDx / 10 ); update["h_jumpMax"] = MaxJump; update["h_jumpMin"] = (MaxJump / 2 ); update["h_leapMax"] = MaxLeap; update["h_leapMin"] = (MaxLeap / 2 ); if (newCurrDx > 15) { bonusDex = (newCurrDx - 15); modToHit = Math.min(3, bonusdex); modToInit = bonusdex; } else if (currDx < 6 ) { var bonusDex = (newCurrDx - 6); modToHit = Math.max(-3, bonusdex); } update["h_initMod"] = modToInit; update["h_toHitMod"] = modToHit; console.log(modToHit); }); console.log(update); setAttrs(update); };
1514932422

Edited 1514933056
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
It is helpful to use the code formatting available from the paragraph formatting drop down at the top left of the text editor (Unfortunately markdown and html tags don't work in the forum editor): HTML <div>     <div class="sheet-col-2-23 sheet-core-stat-label sheet-vert-middle sheet-right">DX:</div>     <input type="hidden" name="attr_h_LeapMax" value="0">     <input type="hidden" name="attr_h_JumpMax" value="0">     <input type="hidden" name="attr_h_LeapMin" value="0">     <input type="hidden" name="attr_h_JumpMin" value="0">     <div><input type="text" name="attr_baseDx" /></div>     <div><input type="text" name="attr_mutationBonusDx" /></div>     <div><input type="text" name="attr_levelBonusDx" /></div>     <div><input type="text" name="attr_otherBonusDx" /></div>     <div><input type="text" name="attr_tempBonusDx" /></div>     <input type="hidden" name="attr_h_CurrDx" value="0">     <div><input type="text" name="attr_CurrDx" value="3" placeholder="3" title="@{h_CurrDx}" /></div>     <div> </div>     <input type="hidden" name="attr_h_initMods" value="0">     <div><input type="number" name="attr_initMod" value="@{h_initMod}" disabled />INIT MOD</div>     <!-- button type="roll" name="roll_initiative" value="@{wtype}&{template:simple} {{rname=^{init-u}}} {{mod=@{initiative_bonus}}} {{r1=[[@{initiative_style}+@{initiative_bonus}@{pbd_safe}[INIT] &{tracker}]]}} {{normal=1}} @{charname_output}" data-i18n="init-u">INITIATIVE</button -->     <!--input type="number" name="attr_initMod" value="0" />INITIATIVE MOD</div -->     <input type="hidden" name="attr_h_toHitMod" value="0">     <div><input type="number" name="attr_toHitMod" value="@{h_toHitMod}" disabled />TO-HIT BONUS</div>     <div><input type="text" name="attr_Leap" value="@{h_leapMax}" />LEAP IN M</div> <!-- DX /3 -->     <div><input type="text" name="attr_Jump" value="@{h_JumpMax}" />JUMP IN M</div> <!-- DX /10 -->     <div>              </div>     <div>     </div> </div> Script <script type="text/worker">     //State Change Handlers     on("change:baseDx change:mutationBonusDx change:levelBonusDx change:otherBonusDx change:tempBonusDx", function() {         console.log ("A Change was made");         update_currDex();         update_dexMods();     });     var update_currDex = function() {         var update = {};         var attrsIn = ["baseDx", "mutationBonusDx", "levelBonusDx", "otherBonusDx", "tempBonusDx"];         var newCurrDx;         getAttrs(attrsIn, function(values) {             newCurrDx = Math.min(24, (values["baseDx"] + values["mutationBonusDx"] + values["levelBonusDx"] + values["otherBonusDx"] + values["tempBonusDx"]));             update["h_currDx"] = newCurrDx;             setAttrs(update);         });     };     var update_dexMods = function() {         var update = {};         var newCurrDx = 0;         var bonusDex = 0 ;         var modToInit = 0;         var modToHit = 0;         console.log('Starting');         getAttrs(["currDx"], function(values) {             newCurrDx = values["currDex"]             var MaxJump = (newCurrDx / 3 );             var MaxLeap = (newCurrDx / 10 );             update["h_jumpMax"] = MaxJump;             update["h_jumpMin"] = (MaxJump / 2 );             update["h_leapMax"] = MaxLeap;             update["h_leapMin"] = (MaxLeap / 2 );             if (newCurrDx > 15) {                 bonusDex = (newCurrDx - 15);                 modToHit = Math.min(3, bonusdex);                 modToInit = bonusdex;             }else             if (currDx < 6 ) {                 var bonusDex = (newCurrDx - 6);                 modToHit = Math.max(-3, bonusdex);             }             update["h_initMod"] = modToInit;             update["h_toHitMod"] = modToHit;             console.log(modToHit);         });         console.log(update);         setAttrs(update);     }; </script> Ok, so I notice several things here: You are calling your update for currdx and dexmods at the same time. Both of these functions are asynchronous (due to the fact that all the meat of them is done in getAttrs/setAttrs. This means that changes made in the first one won't necessarily propagate to the second function, since it might run before or after the first function, or even in between the asynchronous sections of the first function. Your update_currDex function looks to be setting an attribute called H_currDx, while your dexmods function is getting an attribute called currDx. I don't see any method for synchronizing these two (if they are supposed to be) the setAttrs call in your dexmods function is outside the getAttrs call. See problem 1 for why this doesn't work. I'm sure you had it in your actual code, but you missed the </script> closer in your post These are just some quick notes on the code while I take a break from work and without really knowing what problems you are having, or what your desired behavior is. If you can let us know what is happening that is not intended and what you want to happen instead, it would make debugging easier. EDIT: One recommendation I can make regardless of what you are trying to do is fold all your functions into a single getAttrs - setAttrs pair. This is much more performant than having many different getAttrs/setAttrs pathways that each have to run independently, and getting/setting one attribute takes about the same amount of time as getting/setting a couple hundred of them, whereas getting/setting a couple hundred a few at a time will take much longer as the next getAttrs can't start till all the calculations in the first one to trigger are done, and then each setAttrs has to wait for each process ahead of it in the queue to trigger as well.
1514938432

Edited 1514938626
GiGs
Pro
Sheet Author
API Scripter
There's a missing semicolon on the line "newCurrDx = values["currDex"]" In one of your functions you seem to be setting h_currdex, but in the other you are calling currdex, which is a different stat.  In the html you are setting the "title" of currdex, and i spect you hsould be setting the "value" But in any case, if h_currdex and currdex are supposed to be equal, you are better off removing the hidden one and just using the visible one, stting it through your sheet worker. My suggestion would be to break them up something like this: on("change:baseDx change:mutationBonusDx change:levelBonusDx change:otherBonusDx change:tempBonusDx", function() {    console.log ("A Change was made");    getAttrs(["baseDx", "mutationBonusDx", "levelBonusDx", "otherBonusDx", "tempBonusDx"], function(values) { newCurrDx = Math.min(24, (values["baseDx"] + values["mutationBonusDx"] + values["levelBonusDx"] + values["otherBonusDx"] + values["tempBonusDx"])); // I'd actually break the above line up into several, assigning each value to a separate variable, like // var baseDEX = parseInt(values["baseDx"])||0; // so i could use log statements to check their values are accurate. setAttrs({ "currDx"= newCurrDx }); }); }); on("change:currDx", function() { getAttrs(["currDx"], function(values) { var update = {}; var newCurrDx = parseInt(values["currDex"])||0; // put all your calculations here setAttrs(update); }); }); So when the DEX score is changed, the change event for that stat runs. Also, in the htm you have lines like this: <div><input type="text" name="attr_Leap" value="@{h_leapMax}" />LEAP IN M</div> <!-- DX /3 --> If you are setting these values in sheet workers, you don't need autocalc fields, and its often a bad idea to mix them up. Either calculate the derived values with autocalc fields and dont touch them with sheet workers, or use sheetworkers and remove the autocalc fields. Don't try to alter the same attribute with both autocalc and sheetworkers.
Thanks all.  I am going to put these recommendations into action.  I will report back soon.  I think I was just not getting how to make an effective async call, but both your posts are a big help. G G said: Also, in the htm you have lines like this: <div><input type="text" name="attr_Leap" value="@{h_leapMax}" />LEAP IN M</div> <!-- DX /3 --> If you are setting these values in sheet workers, you don't need autocalc fields, and its often a bad idea to mix them up. Either calculate the derived values with autocalc fields and dont touch them with sheet workers, or use sheetworkers and remove the autocalc fields. Don't try to alter the same attribute with both autocalc and sheetworkers. Yeah.  I was planning on making those input fields disable="true" as soon as I got the API calls right.  But I never got to that point.  :-)  
1514946267

Edited 1514946405
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Yep, but the point is that if you're using sheetworkers, you don't need,and shouldn't use the autocalc. Just set leap directly, don't bother with the h_ intermediate. Disabled fields resolve to the formula of their value when their values are gotten through sheetworkers, not the calculated value.
1514974597
Jakob
Sheet Author
API Scripter
In addition to what Scott said, if you set fields via sheet workers and want the result to be non-editable, add the readonly  attribute to the field ( not   disabled ).
1514998769

Edited 1514999186
Pantsworth
Sheet Author
OK - I have implemented some changes.&nbsp; Still not getting it to work.&nbsp; Could it be something in the CSS?&nbsp; Should I include that as well? I have narrowed the scope here - for ease of debugging.&nbsp; I am trying to capture the events of changes in any of the following attributes: attr_baseDx,&nbsp;attr_mutationBonusDx,&nbsp;attr_levelBonusDx,&nbsp;attr_otherBonusDx,&nbsp;attr_tempBonusDx .&nbsp; When any of those change I want to calculate a sum of all those numbers and place that value in&nbsp;attr_CurrDx.&nbsp;&nbsp; This is all in a character sheet that I am (trying to) devloping. HTML portion (non relevant bits cut out): &lt;div class="sheet-row"&gt; &lt;div class="sheet-col-2-23 sheet-core-stat-label sheet-vert-middle sheet-right"&gt;DX:&lt;/div&gt; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_baseDx"&nbsp; value="3"/&gt;&lt;/div&gt; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_mutationBonusDx"&nbsp; value="0"/&gt;&lt;/div&gt; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_levelBonusDx"&nbsp; value="0" /&gt;&lt;/div&gt; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_otherBonusDx"&nbsp; value="0"/&gt;&lt;/div&gt; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_tempBonusDx"&nbsp; value="0"/&gt;&lt;/div&gt; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_CurrDx"&nbsp; readonly="true" /&gt;&lt;/div&gt; &lt;/div&gt; &nbsp;Javascript portion &lt;!--Sheet Workers --&gt; &lt;script type="text/worker"&gt; on("change:baseDx change:mutationBonusDx change:levelBonusDx change:otherBonusDx change:tempBonusDx", function() { &nbsp; &nbsp; console.log ("A Change was made"); &nbsp; &nbsp; getAttrs(["baseDx", "mutationBonusDx", "levelBonusDx", "otherBonusDx", "tempBonusDx"], function(values) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // I'd actually break the above line up into several, assigning each value to a separate variable, like&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var baseDx&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = parseInt(values["baseDx"])||0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log (baseDx); &nbsp; &nbsp; &nbsp; &nbsp; var mutationBonusDx&nbsp; &nbsp;= parseInt(values["mutationBonusDx"] )||0; &nbsp; &nbsp; &nbsp; &nbsp; var levelBonusDx&nbsp; &nbsp; &nbsp; = parseInt(values["levelBonusDx"] )||0; &nbsp; &nbsp; &nbsp; &nbsp; var otherBonusDx&nbsp; &nbsp; &nbsp; = parseInt(values["otherBonusDx"] )||0; &nbsp; &nbsp; &nbsp; &nbsp; var tempBonusDx&nbsp; &nbsp; &nbsp; &nbsp;= parseInt(values["tempBonusDx"])||0; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Add them all together and set the value. &nbsp; &nbsp; &nbsp; &nbsp; newCurrDx = Math.min(24, (baseDx&nbsp; + mutationBonusDx + levelBonusDx + otherBonusDx + tempBonusDx )); &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(newCurrDx) &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAttrs({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "currDx" = newCurrDx &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; }); }); . . other scripts . . &lt;/script&gt; As an FYI, I have tried the attribute fields with and without a value="" assignment.&nbsp;&nbsp; I also tried the following in the setAttrs portion.&nbsp; Per this page in the wiki:&nbsp;&nbsp; <a href="https://wiki.roll20.net/Sheet_Worker_Scripts#setAttrs.28values.2Coptions.2Ccallback.29_.5BAsynchronous.5D" rel="nofollow">https://wiki.roll20.net/Sheet_Worker_Scripts#setAttrs.28values.2Coptions.2Ccallback.29_.5BAsynchronous.5D</a> &nbsp; &nbsp; &nbsp; &nbsp; setAttrs({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currDx: newCurrDx &nbsp; &nbsp; &nbsp; &nbsp; }); If I had to guess, the issue is in the on change: event.&nbsp; In debugging, I never see the&nbsp; console.log ("A Change was made"); in the console.
1515002016

Edited 1515005883
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Ah, change events are all lowercase. So there is no change event for baseDx, there is a change for basedx. Similarly, the values of the getAttrs array are all lower case for the attribute names. I would also suggest changing your parseint declarations: &lt;!--Sheet Workers --&gt; &lt;script type="text/worker"&gt; on(" change:basedx change:mutationbonusdx change:levelbonusdx change:otherbonusdx change:tempbonusdx ", function() { &nbsp; &nbsp; console.log ("A Change was made"); var setObj = {}; &nbsp; &nbsp; getAttrs([ "basedx", "mutationbonusdx", "levelbonusdx", "otherbonusdx", "tempbonusdx" ], function(values) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // I'd actually break the above line up into several, assigning each value to a separate variable, like&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var baseDx&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = values[" basedx "] *1 ||0, &nbsp; &nbsp; &nbsp; &nbsp; mutationBonusDx&nbsp; &nbsp;= values[" mutationbonusdx "] *1 ||0, // I find this method to be more performant than the parseX functions &nbsp; &nbsp; &nbsp; &nbsp; levelBonusDx&nbsp; &nbsp; &nbsp; = values[" levelbonusdx "] *1 ||0, &nbsp; &nbsp; &nbsp; &nbsp; otherBonusDx&nbsp; &nbsp; &nbsp; = values[" otherbonusdx "] *1 ||0, &nbsp; &nbsp; &nbsp; &nbsp; tempBonusDx&nbsp; &nbsp; &nbsp; &nbsp;= values[" tempbonusdx "] *1 ||0; &nbsp; &nbsp; &nbsp; &nbsp; console.log (baseDx); &nbsp; &nbsp; &nbsp; &nbsp; //Add them all together and set the value. &nbsp; &nbsp; &nbsp; &nbsp; setObj.newcurrdx = Math.min(24, (baseDx&nbsp; + mutationBonusDx + levelBonusDx + otherBonusDx + tempBonusDx )); &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log("setObj: "+JSON.stringify(setObj)); &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAttrs( setObj ); &nbsp; &nbsp; }); }); . . other scripts . . &lt;/script&gt;
1515002091
Jakob
Sheet Author
API Scripter
1. Lowercase attributes in your event string: "change:basedx change:mutationbonusdx change:levelbonusdx change:otherbonusdx change:tempbonusdx" BTW this is why I would recommend not camelCasing your attribute names, but separating words via underscores and lowercasing all attribute names. 2. This &nbsp; &nbsp; &nbsp; &nbsp; setAttrs({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currDx: newCurrDx &nbsp; &nbsp; &nbsp; &nbsp; }); is correct syntax for object literals, the version with "=" is not. You do not see anything because this code has a syntax error (the setAttrs part). In general, it's a good idea to run your sheet workers code through a syntax checker before testing in Roll20. P.S.: It's not actually an error in non-strict Javascript, but you ought to declare variables before you use them, newCurrDex in this example.
1515002394
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
I second Jakob's suggestion about attribute naming conventions as well. I'd also add to avoid using dashes in your names to avoid the problems of working with property keys with a dash in them in javascript.
1515002758

Edited 1515003141
Pantsworth
Sheet Author
Excellent.&nbsp; Old habits die hard with the Camel Case stuff.&nbsp; I come from the SQL world, and underscores are typically frowned upon. Alright - let me go and make these changes.&nbsp; Thanks again for everyone's help.&nbsp; I knew it was probably something simple that I just couldn't see. BTW: on the Parseint changes, what are you doing there?&nbsp; Are you multiplying by 1 because any non-int will cause that operation to fail and then return a 0 when it does fail?
1515005440

Edited 1515005918
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Pantsworth said: BTW: on the Parseint changes, what are you doing there?&nbsp; Are you multiplying by 1 because any non-int will cause that operation to fail and then return a 0 when it does fail? In Javascript, multiplying/dividing/or subtracting attempts to convert both arguments in the equation to numbers. If one or more of the arguments in the equation cannot be converted to a number, it returns NaN (which is a falsy value in javascript). So you get the following: var someString,someResult; someString = "5"; someResult = someString *1; =&gt; 5 someString = "Hello World"; someResult = someString *1; =&gt; NaN //This even works with floats, and avoids the pit falls of parseFloat causing incorrect rounding someString = "2.65"; someResult = someString *1; =&gt; 2.65 //You can also use this to quickly multiply values together someString = "4"; anothString = "5"; someResult = somestring * anothString; =&gt; 20 The "|| 0" part of the code is simply there in case the attribute value is not a number (and therefore returns NaN from the multiplication) so that you don't wind up attempting to add say 5 + 10 + NaN + NaN. Note that you cannot use "+" because that is shorthand for concatenation of a string, and converts all arguments to strings if all arguments are not numbers.
Thanks Scott. OK - v3.0 is not working either. HTML: &lt;div class="sheet-row"&gt; &lt;div class="sheet-col-2-23 sheet-core-stat-label sheet-vert-middle sheet-right"&gt;DX:&lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_base_dx"&nbsp; value="3"/&gt;&lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_mutation_bonus_dx"&nbsp; value="0"/&gt;&lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_level_bonus_dx"&nbsp; value="0" /&gt;&lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_other_bonus_dx"&nbsp; value="0"/&gt;&lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_temp_bonus_dx"&nbsp; value="0"/&gt;&lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="sheet-ability-num"&gt;&lt;input class="sheet-ability-num" type="text" name="attr_curr_dx"&nbsp; /&gt;&lt;/div&gt; &lt;/div&gt; JavaScript:&nbsp; &nbsp; &nbsp;&nbsp; on("change:base_dx change:mutation_bonus_dx change:level_bonus_dx change:other_bonus_dx change:temp_bonus_dx", function() { &nbsp; &nbsp; console.log ("A Change was made"); &nbsp; &nbsp; getAttrs(["base_dx", "mutation_bonus_dx", "level_bonus_dx", "other_bonus_dx", "temp_bonus_dx"], function(values) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //variable assignments&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var setObj = {}; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var new_curr_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_base_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_mutation_bonus_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_level_bonus_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_other_bonus_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_temp_bonus_dx = 0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // parse and assign get attrs values &nbsp; &nbsp; &nbsp; &nbsp; new_base_dx&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = values["base_dx"]*1||0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log (new_base_dx); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log (values["base_dx"]); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log (values.base_dx); &nbsp; &nbsp; &nbsp; &nbsp; new_mutation_bonus_dx&nbsp; &nbsp;= values["mutation_bonus_dx"]*1||0; &nbsp; &nbsp; &nbsp; &nbsp; new_level_bonus_dx&nbsp; &nbsp; &nbsp; = values["level_bonus_dx"] *1||0; &nbsp; &nbsp; &nbsp; &nbsp; new_other_bonus_dx&nbsp; &nbsp; &nbsp; = values["other_bonus_dx"] *1||0; &nbsp; &nbsp; &nbsp; &nbsp; new_temp_bonus_dx&nbsp; &nbsp; &nbsp; &nbsp;= values["temp_bonus_dx"]*1||0; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Add them all together and set the value. &nbsp; &nbsp; &nbsp; &nbsp; new_curr_dx = Math.min(24, (new_base_dx + new_mutation_bonus_dx + new_level_bonus_dx + new_other_bonus_dx + new_temp_bonus_dx )); &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setObj.curr_dx = new_curr_dx;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(new_curr_dx); &nbsp; &nbsp; &nbsp; &nbsp; console.log("setObj: "+JSON.stringify(setObj)); &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAttrs(setObj); &nbsp; &nbsp; }); }); as a note I also tried: &lt;!--Sheet Workers --&gt; &lt;script type="text/worker"&gt; &nbsp; &nbsp; //State Change Handlers &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; on("change:base_dx change:mutation_bonus_dx change:level_bonus_dx change:other_bonus_dx change:temp_bonus_dx", function() { &nbsp; &nbsp; console.log ("A Change was made"); &nbsp; &nbsp; getAttrs(["base_dx", "mutation_bonus_dx", "level_bonus_dx", "other_bonus_dx", "temp_bonus_dx"], function(values) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //variable assignments&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //var setObj = {}; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var new_curr_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_base_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_mutation_bonus_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_level_bonus_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_other_bonus_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_temp_bonus_dx = 0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // parse and assign get attrs values &nbsp; &nbsp; &nbsp; &nbsp; new_base_dx&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = values["base_dx"]*1||0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log (new_base_dx); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log (values["base_dx"]); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log (values.base_dx); &nbsp; &nbsp; &nbsp; &nbsp; new_mutation_bonus_dx&nbsp; &nbsp;= values["mutation_bonus_dx"]*1||0; &nbsp; &nbsp; &nbsp; &nbsp; new_level_bonus_dx&nbsp; &nbsp; &nbsp; = values["level_bonus_dx"] *1||0; &nbsp; &nbsp; &nbsp; &nbsp; new_other_bonus_dx&nbsp; &nbsp; &nbsp; = values["other_bonus_dx"] *1||0; &nbsp; &nbsp; &nbsp; &nbsp; new_temp_bonus_dx&nbsp; &nbsp; &nbsp; &nbsp;= values["temp_bonus_dx"]*1||0; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Add them all together and set the value. &nbsp; &nbsp; &nbsp; &nbsp; new_curr_dx = Math.min(24, (new_base_dx + new_mutation_bonus_dx + new_level_bonus_dx + new_other_bonus_dx + new_temp_bonus_dx )); &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //setObj.curr_dx = new_curr_dx;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(new_curr_dx); &nbsp; &nbsp; &nbsp; &nbsp; //console.log("setObj: "+JSON.stringify(setObj)); &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //setAttrs(setObj); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAttrs({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "curr_dx" = new_curr_dx &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; }); }); &lt;/script&gt; Other things I tried: Removing all other scripts I was working in Google Chrome, but I tried Firefox, Edge and ie10 Turning off my VPN. None of those worked either. HOWEVER: stripping it down to only one change did work. &lt;script type="text/worker"&gt; &nbsp; &nbsp; //State Change Handlers &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; //on("change:base_dx change:mutation_bonus_dx change:level_bonus_dx change:other_bonus_dx change:temp_bonus_dx", function() { on("change:base_dx", function() { &nbsp; &nbsp; //console.log ("A Change was made"); &nbsp; &nbsp; //getAttrs(["base_dx", "mutation_bonus_dx", "level_bonus_dx", "other_bonus_dx", "temp_bonus_dx"], function(values) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getAttrs(["base_dx"], function(values) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //variable assignments&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var setObj = {}; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var new_curr_dx = 0; &nbsp; &nbsp; &nbsp; &nbsp; var new_base_dx = -5; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //var new_curr_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //new_base_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //new_mutation_bonus_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //new_level_bonus_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //new_other_bonus_dx = 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //new_temp_bonus_dx = 0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // parse and assign get attrs values &nbsp; &nbsp; &nbsp; &nbsp; new_base_dx&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = values["base_dx"]*1||0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //console.log (new_base_dx); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //console.log (values["base_dx"]); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //console.log (values.base_dx); &nbsp; &nbsp; &nbsp; &nbsp; //new_mutation_bonus_dx&nbsp; &nbsp;= values["mutation_bonus_dx"]*1||0; &nbsp; &nbsp; &nbsp; &nbsp; //new_level_bonus_dx&nbsp; &nbsp; &nbsp; = values["level_bonus_dx"] *1||0; &nbsp; &nbsp; &nbsp; &nbsp; //new_other_bonus_dx&nbsp; &nbsp; &nbsp; = values["other_bonus_dx"] *1||0; &nbsp; &nbsp; &nbsp; &nbsp; //new_temp_bonus_dx&nbsp; &nbsp; &nbsp; &nbsp;= values["temp_bonus_dx"]*1||0; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Add them all together and set the value. &nbsp; &nbsp; &nbsp; &nbsp; //new_curr_dx = Math.min(24, (new_base_dx + new_mutation_bonus_dx + new_level_bonus_dx + new_other_bonus_dx + new_temp_bonus_dx )); &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //new_curr_dx = new_base_dx;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setObj.curr_dx = new_base_dx;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //console.log(new_curr_dx); &nbsp; &nbsp; &nbsp; &nbsp; //console.log("setObj: "+JSON.stringify(setObj)); &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAttrs(setObj); &nbsp; &nbsp; }); }); &lt;/script&gt; It still seems to me that it is not getting to the all of the On("change:foo_bar") events.&nbsp; So I am going to start adding them back in one at a time.&nbsp; See if I can't pinpoint what is causing the issue that way. Thanks for all your help so far.
Looks like it was a space that did me in. new_level_bonus_dx&nbsp; &nbsp; &nbsp; = values["level_bonus_dx" ] * 1||0; Should read. new_level_bonus_dx&nbsp; &nbsp; &nbsp; = values["level_bonus_dx"]*1||0; IE no space between the "]" and the "*". Whew.&nbsp; Thanks for all your help folks.&nbsp; I learned a lot, and am closer to having my Character Sheet all done!
1515019637
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Congratulations.
One more question.&nbsp; If I were to refactor this to handle any of the 6 attributes in Gamma World, how would I do the setObj assignment? Would something like&nbsp; setObj."curr_" & attribute work?&nbsp; If not, is there a way to do this?
1515038096
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
you'd do this: setObj["curr_"+attribute] = ...
Perfect.&nbsp; Thx