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

Sheetworker not seeing new values - sync issue?

I have a series of basic characteristics (strength, agility, etc) in a point-buy character system where the stat values are set as the total of points directly spent on the stats themselves plus any adjustments from a repeating section of powers.&nbsp; The meat of the html is a repeating section (removing some formatting for clarity and using just Endurance as an example): &lt; input &nbsp; type = "number" &nbsp; name = "attr_en_adj" &nbsp; title = "en_adj" &nbsp; /&gt; ... and the main stat section is: &lt; input &nbsp; type = "number" &nbsp; name = "attr_endurance_cost" &nbsp; title = "endurance_cost" &nbsp; value = "0" /&gt; &lt; input &nbsp; type = "text" &nbsp; name = "attr_endurance_score" &nbsp; title = "endurance_score" &nbsp; &nbsp;&nbsp;&nbsp;&nbsp; disabled &nbsp; value = "(@{endurance_cost}+@{en_adj_total})" /&gt; &lt; input &nbsp; type = "text" &nbsp; name = "attr_endurance_save" &nbsp; title = "endurance_save" disabled &nbsp; value = "@{hid_en_save}" /&gt;&lt; input &nbsp; type = "hidden" &nbsp; name = "attr_hid_en_save" &nbsp; title = "hid_en_save" &gt; An sheet worker fires when the repeating section is changed (there will be one added to the change on the _cost fields as well after I get the logic working) to get the _adj-total value for the _score calculation. &nbsp;&nbsp;&nbsp;&nbsp;on('change:repeating_powers&nbsp;remove:repeating_powers',&nbsp;function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; repeatingSum("en_adj_total",&nbsp;"powers",&nbsp;"en_adj"); &nbsp;&nbsp;&nbsp; }); This is all working fine; a change to any of the adjustment fields in the repeater will correctly update the appropriate _score field values. From these base scores a number of other stats get calculated, many of them by doing lookups against a table containing stat ranges and related values - the _save field above being an example.&nbsp; After the repeatingSum above I've added a call to this function: &nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;updateFromBCs()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getAttrs([ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"strength_score", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"endurance_score", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"agility_score", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"intelligence_score", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"cool_score" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;],&nbsp;function(v)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;statTable&nbsp;=&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{min:&nbsp;0,&nbsp;max:&nbsp;0,&nbsp;carry:&nbsp;8,&nbsp;hth_init:&nbsp;'d2-1',&nbsp;save:&nbsp;6,&nbsp;hits_st:&nbsp;-3,&nbsp;hits_en:&nbsp;-5,&nbsp;hits_ag:&nbsp;-2,&nbsp;hits_cl:&nbsp;-1,&nbsp;heal:&nbsp;.2}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{min:&nbsp;1,&nbsp;max:&nbsp;1,&nbsp;carry:&nbsp;10,&nbsp;hth_init:&nbsp;'d2-1',&nbsp;save:&nbsp;7,&nbsp;hits_st:&nbsp;-3,&nbsp;hits_en:&nbsp;-5,&nbsp;hits_ag:&nbsp;-2,&nbsp;hits_cl:&nbsp;-1,&nbsp;heal:&nbsp;.3}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{min:&nbsp;2,&nbsp;max:&nbsp;2,&nbsp;carry:&nbsp;12,&nbsp;hth_init:&nbsp;'d2-1',&nbsp;save:&nbsp;7,&nbsp;hits_st:&nbsp;-3,&nbsp;hits_en:&nbsp;-5,&nbsp;hits_ag:&nbsp;-2,&nbsp;hits_cl:&nbsp;-1,&nbsp;heal:&nbsp;.3}, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;etc&gt;.... &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {min:&nbsp;96,&nbsp;max:&nbsp;98,&nbsp;carry:&nbsp;32212254720,&nbsp;hth_init:&nbsp;'3d10+2d12',&nbsp;save:&nbsp;25,&nbsp;hits_st:&nbsp;54,&nbsp;hits_en:&nbsp;69,&nbsp;hits_ag:&nbsp;35,&nbsp;hits_cl:&nbsp;18,&nbsp;heal:&nbsp;18.1} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;stResult&nbsp;=&nbsp;statTable.filter(tableRow&nbsp;=&gt;&nbsp;(tableRow.min&nbsp;&lt;=&nbsp;v.strength_score&nbsp;&amp;&amp;&nbsp;tableRow.max&nbsp;&gt;=&nbsp;v.strength_score)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;enResult&nbsp;=&nbsp;statTable.filter(tableRow&nbsp;=&gt;&nbsp;(tableRow.min&nbsp;&lt;=&nbsp;v.endurance_score&nbsp;&amp;&amp;&nbsp;tableRow.max&nbsp;&gt;=&nbsp;v.endurance_score)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;agResult&nbsp;=&nbsp;statTable.filter(tableRow&nbsp;=&gt;&nbsp;(tableRow.min&nbsp;&lt;=&nbsp;v.agility_score&nbsp;&amp;&amp;&nbsp;tableRow.max&nbsp;&gt;=&nbsp;v.agility_score)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;inResult&nbsp;=&nbsp;statTable.filter(tableRow&nbsp;=&gt;&nbsp;(tableRow.min&nbsp;&lt;=&nbsp;v.intelligence_score&nbsp;&amp;&amp;&nbsp;tableRow.max&nbsp;&gt;=&nbsp;v.intelligence_score)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;clResult&nbsp;=&nbsp;statTable.filter(tableRow&nbsp;=&gt;&nbsp;(tableRow.min&nbsp;&lt;=&nbsp;v.cool_score&nbsp;&amp;&amp;&nbsp;tableRow.max&nbsp;&gt;=&nbsp;v.cool_score)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log('EN&nbsp;score&nbsp;'&nbsp;+&nbsp;v.endurance_score&nbsp;+&nbsp;'&nbsp;save&nbsp;'&nbsp;+&nbsp;enResult[0].save); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setAttrs({ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hid_en_save:&nbsp;enResult[0].save &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;}; I've tested the lookup function with some hard-coded numbers and it works fine.&nbsp; The problem is that, as shown by the console.log statement, the value of the _score in the update function always 10... which is a placeholder value I dropped in early in the build.&nbsp; The actual field on the form is displaying the correct value, but the function doesn't see it. Current full code is at <a href="https://github.com/drl2/roll20-character-sheets/blob/mighty_protectors/Villains%20and%20Vigilantes/VandVMightyProtectors.html" rel="nofollow">https://github.com/drl2/roll20-character-sheets/blob/mighty_protectors/Villains%20and%20Vigilantes/VandVMightyProtectors.html</a> if it's useful. (Side question - why did I have to move statTable into the function itself rather than leaving it outside as a global?&nbsp; Any attempts to access it were failing until I made it local.)
1591939566

Edited 1591939893
GiGs
Pro
Sheet Author
API Scripter
This sounds like a classic problem: sheet workers cant do anything with disabled values. As far as the sheet worker is concerned, your endurance_score attribute has a value of "(@{endurance_cost}+@{en_adj_total})" Note the quotes: this is a text value. Sheet workers have no way to interpret this:&nbsp; @{endurance_cost} , it's just text to a sheet worker. The way to handle this is to replace the score calculation for the stats with sheet workers. Change those _score s from disabled to readonly, and use a sheet worker like this: ["strength",&nbsp;&nbsp;"endurance",&nbsp;&nbsp;&nbsp;"agility",&nbsp;&nbsp;"intelligence",&nbsp;&nbsp;"cool"].forEach(stat&nbsp;=&gt;&nbsp;{ &nbsp;&nbsp;let&nbsp;stat_cost&nbsp;=&nbsp;`${stat}_cost`,&nbsp;stat_adj&nbsp;=&nbsp;`${stat.slice(0,2)}_adj_total`; &nbsp;&nbsp;on(`change:${stat_cost}&nbsp;change:${stat_adj}`,&nbsp;function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;getAttrs([stat_cost,&nbsp;stat_adj],&nbsp;function(v)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;cost&nbsp;=&nbsp;+v[stat_cost]&nbsp;||0; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;adj&nbsp;=&nbsp;&nbsp;+v[stat_adj]&nbsp;||0; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;score&nbsp;=&nbsp;cost&nbsp;+&nbsp;adj; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setAttrs({ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`${stat}_score`]:&nbsp;score &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}) &nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;}); }); assuming ever adj_total stat uses only the first 2 letters of its governing attribute, this should calculate the scores of all 5 stats.
OK, I had accounted for the disabled fields in the updates from the repeatingSum values but hadn't considered it from the other direction in terms of reading from those values later.&nbsp; I'll try to rework it as suggested above &amp; see how it goes. Thanks again!
1591980056
GiGs
Pro
Sheet Author
API Scripter
Good luck :)
Looking at the suggested code above I'm a little fuzzy on the scope of the &lt;stat name&gt;_adj_total values.&nbsp; Do I need to leave the repeatingSum calls under the change event for the repeating area?&nbsp; Will their values be available to this new event?
1592179630
GiGs
Pro
Sheet Author
API Scripter
Yes, you dont need to change any of the existing sheet worker code, just add that new function in as well.&nbsp; For efficiency purposes it would be better to combine them all into one big worker. I wrote repeatingSum, so I'm always happy to see it in use, but having six uses of it for the same repeating section is pretty inefficient. I may tweak it so it can be better for this kind of situation. But that's not essential - the above should work with your current code fine. Just remember to remove the disabled &nbsp;part from those inputs. (Replacing with readonly &nbsp;works pretty well.)
Finally scraped out time to try it out and it's working!&nbsp; On to the next challenge :)
1592561749
GiGs
Pro
Sheet Author
API Scripter
Incidentally, I've just added an upgrade to repeatingSum (several in fact). On your sheet you have this: on('change:repeating_powers&nbsp;remove:repeating_powers',&nbsp;function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;repeatingSum("abilityip_total","powers","ip_cost"); &nbsp;&nbsp;&nbsp;&nbsp;repeatingSum("st_adj_total",&nbsp;"powers",&nbsp;"st_adj"); &nbsp;&nbsp;&nbsp;&nbsp;repeatingSum("en_adj_total",&nbsp;"powers",&nbsp;"en_adj"); &nbsp;&nbsp;&nbsp;&nbsp;repeatingSum("ag_adj_total",&nbsp;"powers",&nbsp;"ag_adj"); &nbsp;&nbsp;&nbsp;&nbsp;repeatingSum("in_adj_total",&nbsp;"powers",&nbsp;"in_adj"); &nbsp;&nbsp;&nbsp;&nbsp;repeatingSum("cl_adj_total",&nbsp;"powers",&nbsp;"cl_adj"); &nbsp;&nbsp;&nbsp;&nbsp;updateFromBCs(); }); You can now combine all those repeatingSums into one, which is a lot more efficient: on('change:repeating_powers&nbsp;remove:repeating_powers',&nbsp;function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;repeatingSum(["abilityip_total",&nbsp;"st_adj_total",&nbsp;"en_adj_total",&nbsp;"ag_adj_total",&nbsp;"in_adj_total",&nbsp;"cl_adj_total"], &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"powers",["ip_cost",&nbsp;"st_adj",&nbsp;"en_adj",&nbsp;"ag_adj",&nbsp;"in_adj",&nbsp;"cl_adj"]); &nbsp;&nbsp;&nbsp;&nbsp;updateFromBCs(); }); Just grab the new code from&nbsp; <a href="https://wiki.roll20.net/RepeatingSum" rel="nofollow">https://wiki.roll20.net/RepeatingSum</a> There are now two functions on the page - either one will do what you need.
Nice, thanks!