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 with SheetWorker

1589692333

Edited 1589692376
hello, i am new to roll20, but i am trying to learn :) excellent platform ! now on topic,  ii have the bellow script. it will calculate the sum of 3 Strength variables and return the total. //<script type="text/worker">     on("change:strength_rank change:strength_item change:strength_special sheet:opened", function()      {          getAttrs(["strength_rank","strength_item","strength_special"], function(values)          {             let rank = parseInt(values.strength_rank,10)||0;             let item = parseInt(values.strength_item,10)||0;             let special = parseInt(values.strength_special,10)||0;             let total = rank + item + special;             setAttrs({strength_total: total});         });     }); </script> but i have 8 attributes and dont want to rewrite the same code over and over... so i thought to write something like the following (btw i am new to this scripts. i have var basic & good knowledge to programming languages (older)) <script type="text/worker"> const int = score => parseInt(score, 10) || 0; const stats = ["size", "strength","agility","stamina","perception","mental","personality","magic"]; stats.forEach(stat => {     on(`change:${stat}_rank,${stat}_item,${stat}_special sheet:opened`, () => {         getAttrs([stat], values => {                                     let rank = parseInt(values.`${stat}_rank`,10)||0;                                     let item = parseInt(values.`${stat}_item`,10)||0;                                     let special = parseInt(values.`${stat}_special`,10)||0;                                     let total = rank + item + special;                                     setAttrs({[`${stat}_bonus`]: total});         });     }); }); </script> but it does not work. can you help me correct the problem with the above script? i think the problem is where i am trying to attack the "values" with "${stat}" & "_rank" to take the value from thank you in advance!
1589696984

Edited 1589697069
GiGs
Pro
Sheet Author
API Scripter
The most likely issue is this section: let rank = parseInt(values.`${stat}_rank`,10)||0; let item = parseInt(values.`${stat}_item`,10)||0; let special = parseInt(values.`${stat}_special`,10)||0; There are two syntaxes you can use to get values from the getAttrs object: let rank = value.attribute; let rank = values['attribute']; Both of those work when the attribute name is explicit. But if the attribute is a variable, you have to use this syntax: let rank = values[variable_name]; So you can fix the above by using let rank = parseInt(values[`${stat}_rank`],10)||0; let item = parseInt(values[`${stat}_item`],10)||0; let special = parseInt(values[`${stat}_special`],10)||0; You also have this declared at the start of your script const int = score => parseInt(score, 10) || 0; so you might as well use it. That would make the script const int = score => parseInt(score) || 0; const stats = ["size", "strength", "agility", "stamina", "perception", "mental", "personality", "magic"]; stats.forEach(stat => {     on(`change:${stat}_rank,${stat}_item,${stat}_special sheet:opened`, () => {         getAttrs([stat], values => {             let rank = int(values[`${stat}_rank`]);             let item = int(values[`${stat}_item`]);             let special = int(values[`${stat}_special`]);             let total = rank + item + special;             setAttrs({                 [`${stat}_bonus`]: total             });         });     }); }); (note: i took the radix out of parseInt - the ,10 part: when you're working in base 10 you dont need it.)
thank you for the very fast reply. i did what you told me, but it seems that i do something not correct. this is my attributes:                      <tr>                         <td><button name="roll_size" type="roll" value="&{template:default} {{name=size}} {{Result=[[d20+(@{size_bonus})]]}}"></button></td>                         <td style="text-align: center;">Size</td>                         <td><input type="number" name="attr_size_rank" value="" /></td>                         <td><input type="number" name="attr_size_item" value="" /></td>                         <td><input type="number" name="attr_size_special" value="" /></td>                         <td><span name="attr_size_total"></span></td>                         <td><span name="attr_size_total_bonus"></span></td>                         <td style="text-align: center;font-size:50%;  font-style: italic"><input type="number" name="attr_size_Attribute_Cost" value="(2**@{size_rank})*256" disabled="true" style="width:100%;"/></td>                     </tr> and this is the script: <script type="text/worker"> const int = score => parseInt(score) || 0; const stats = ["size", "strength", "agility", "stamina", "perception", "mental", "personality", "magic"]; stats.forEach(stat => {     on(`change:${stat}_rank,${stat}_item,${stat}_special sheet:opened`, () => {         getAttrs([stat], values => {             let rank = int(values[`${stat}_rank`]);             let item = int(values[`${stat}_item`]);             let special = int(values[`${stat}_special`]);             let total = rank + item + special;             setAttrs({                 [`${stat}_total`]: total             });         });     }); }); </script> when i change any of the values ..."size_rank","size_item",..., it doesn't change the total.
1589700014
GiGs
Pro
Sheet Author
API Scripter
I didnt pay enough attention to the on(change) and getAttrs lines, which contained some errors. The corrected, working function is     const int = score => parseInt(score) || 0;          const stats = ["size", "strength", "agility", "stamina", "perception", "mental", "personality", "magic"];     stats.forEach(stat => {         on(`change:${stat}_rank change:${stat}_item change:${stat}_special sheet:opened`, () => {             getAttrs([`${stat}_rank`, `${stat}_item`, `${stat}_special`], values => {                 let rank = int(values[`${stat}_rank`]);                 let item = int(values[`${stat}_item`]);                 let special = int(values[`${stat}_special`]);                 let total = rank + item + special;                 setAttrs({                     [`${stat}_total`]: total                 });             });         });     }); Note that each attribute on the change line needs its own "change:" instruction, and they must be separated by spaces not commas. And on the getAttrs line, you also have to list every attribute, and this time they are separated by commas.
it worked!! thank you. can i trouble you for one more time please!!! i have now the Size attribute that gives me the "attr_size_total_bonus"> that was calculated from the script before. when i try to pass it to the bellow: <tr>                         <td><button name="roll_hp" type="roll" value="&{template:default} {{name=Strength}} {{Result=[[d20+(@{strength_bonus})]]}}"></button></td>                         <td><button name="roll_hp" type="roll" value="&{template:default} {{name=Strength}} {{Result=[[d20+(@{strength_bonus})]]}}"></button></td>                         <td style="text-align: center;">HP</td>                         <td><input type="number" name="attr_hprank" value="" /></td>                         <td><input type="number" name="attr_hpstat" value=" (@{size_total_bonus}) " disabled="true"/></td>                         <td><input type="number" name="attr_hpitem" value="" /></td>                         <td><input type="number" name="attr_hpspecial" value="" /></td>                         <td><span                name="attr_hp_total"></span></td>                             <span type="hidden"  name="attr_hp_total_max"></span>                         <td style="text-align: center;font-size:50%;  font-style: italic"><input type="number" name="attr_Size_Attribute_Cost" value="(2**@{Size_rank})*256" disabled="true" style="width:100%;"/></td>                     </tr> and use the next script : //HP <script type="text/worker">     on("change:hprank change:hpitem change:hpspecial change:hpstat sheet:opened", function()      {          getAttrs(["hprank","hpitem","hpspecial","hpstat"], function(values)          {             let rank = parseInt(values.hprank,10)||0;             let item = parseInt(values.hpitem,10)||0;             let special = parseInt(values.hpspecial,10)||0;             let stat = parseInt(values.hpstat,10)||0;                          let total = rank + stat + item + special;             setAttrs({hp_total: total});             setAttrs({hp_total_max: total});         });     }); </script> all is working except the stat. it seems that it does not recognize the stat value. thanks in advance !!!
1589701913

Edited 1589701952
GiGs
Pro
Sheet Author
API Scripter
Disabled attributes, aka autocalc attributes, are completely incompatible with sheet workers. the sheet worker doesnt get a umber, it gets string " @{size_total_bonus}) " and cant do anything with that. Instead of making hpstat a dsiabled attribute, set it to readonly and use a sheet worker to set its value whenever  size_total_bonus  changes. Also, just some advice: you should never do this:             setAttrs({hp_total: total});             setAttrs({hp_total_max: total}); Having more than one setAttrs statement in a worker is very bad for performance. You can do this instead:             setAttrs({                 hp_total: total,                 hp_total_max: total             }); You can include multiple stats there. Use a comma at the end of each assignment, except the last one. PS: you have two copies of the button at the start.
Thank you for all. i am new to this scripts. :)
1589706109
GiGs
Pro
Sheet Author
API Scripter
Welcome to the often confusing and frustrating, but ultimately rewarding, world of scripting :)