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

[Sheet Workers] Help

I am having a hard time with math and sheet workers.  I know I have done something simular in the past, but the solution eludes me.   I want a sheet worker that does the same thing as this disabled field.  Any help would be appreciated. floor((@{navigation1}+0.5)*@{int_total}+@{navigation2}+@{navigation3}+@{navigation4})
1544777624

Edited 1544777693
GiGs
Pro
Sheet Author
API Scripter
Assuming none of those stats are in a repeating section: on("change:navigation1 change:navigation 2  change:navigation 3  change:navigation 4 change:int_total", function() { getAttrs(["navigation1", "navigation2", "navigation3", "navigation4", "int_total"], function(v) {     let n1 = parseInt(v.navigation1,10)||0,         n2 = parseInt(v.navigation2,10)||0,         n3 = parseInt(v.navigation3,10)||0,                 n4 = parseInt(v.navigation4,10)||0,                 int = parseInt(v.int_total,10)||0;     let result = Math.floor((n1+0.5)* int + n2 + n3 + n4);     setAttrs({ wherever: result     }); }); }); Are you sure that calculation does what you think it does? It looks to me it should be more like this:     let result = Math.floor(n1* (int + n2 + n3 + n4) +0.5); Or just     let result = Math.round(n1* (int + n2 + n3 + n4)); Unless of course navigation1 is a fractional stat whose lowest value is 0.5 - I don't know, I'm just guessing.
Well...what you gave me- which is based off the information provided- works perfectly...I just gave you incomplete data for what I am looking for. Okay, so..."Whatever" is a skill based off an attribute.  If you are not trained, the rating is whatever /2.  If you are trained, the value is equal to whatever .  Each additional level adds +10.  Say the int_total is equal to 40.  Untrained (first box not checked) value would be 20, and 40 if the first box is checked.  If the second box is also checked, whatever has a value of 50, and so on.   Does this new information help at all?  Am I making sense or am I confusing folks more?  With this information, should there be changes to the code?
1544817823

Edited 1544819048
GiGs
Pro
Sheet Author
API Scripter
aha, that makes a bit more sense. So in this case, each navigation box is a level. One thing: have you set a "value=1" or "value=10" in your skill checkboxes, and what is the value? Assuming you have Value = 1, the calculation would be: let n1 = parseInt(v.navigation1,10)||0, n2 = parseInt(v.navigation2,10)||0, n3 = parseInt(v.navigation3,10)||0,     n4 = parseInt(v.navigation4,10)||0,     int = parseInt(v.int_total,10)||0, result; if(n1 === 0) result = Math.floor(int/2); else result = (n1 + n2 + n3 + n4 -1) * 10 + int; If each navigation box has value = 10, just remive the *10 above.
1544818547

Edited 1544829759
GiGs
Pro
Sheet Author
API Scripter
Also, you might consider using a radio input in place of multiple checkboxes for this. In that case you could have the 5 radio boxes with -1, 0, 10, 20, 30 And replace the calculation with just two attributes, int_total, and navigation, and the code would look like on("change:navigation_levels change:int_total sheet:opened", function() { getAttrs(["navigation_levels", "int_total"], function(v) { let n = parseInt(v.navigation,10)||0, int = parseInt(v.int_total,10)||0, result; if(n < 0) result = Math.floor(int/2); else result = int + n; setAttrs({ navigation: result }); }); }); The inputs would simply be: <input type="radio" name="attr_navigation_levels" value="-1" checked = "checked" >Untrained   <input type="radio" name="attr_navigation_levels" value="0">Trained   <input type="radio" name="attr_navigation_levels" value="10">+1   <input type="radio" name="attr_navigation_levels" value="20">+2   <input type="radio" name="attr_navigation_levels" value="30">+3 Replace the untrained/trained/+1 etc with whatever you need, or maybe the inputs are just in a row under headings (in which case, remove Untrained/Trained/+1 etc). The checked tag makes sure the untrained value is set by default for each of them. Adding sheet:opened  to the sheet worker makes sure those defaults get taken into account without you having to manually check them all. Note that I assumed the skill name is navigation, and the radio button is called navigation_levels. This simplifies making this worker universal later, so with one sheetworker you can update all  skills, rather than having to create a separate sheet worker for each skill. If this worker is what you need, I'll add how to update it for that later.
1544823870

Edited 1544828981
GiGs
Pro
Sheet Author
API Scripter
Edit: corrected a typo in the script in the last post. Here's how you make it universal. First in your script section, make a list of all the skills in your game with matching stat bonuses in this format: const skills = { "navigation": "int",  "anotherskill": "an_attribute",  "yet another skill": "an_attribute",  }; This is an object  called skills . You dont need to put them on separate lines, it just looks neater. Dont put int_total, just put int. I assume all the stat bonuses are named the same (stat_total). Then add this worker immediately after it: Object.keys(skills).forEach(skill => {     on("change:" +skill + "_levels change:" +skills[skill] + "_total sheet:opened", function() { getAttrs([skill + "_levels", skills[skill] + "_total"], function(v) { const level = parseInt(v[skill + "_levels"],10)||0, stat = parseInt(v[skills[skill] + "_total"],10)||0; let result = level < 0 ? Math.floor(stat/2) : stat + level; setAttrs({ [skill]: result }); }); }); }); In case you;re interested in how it works: The first line  Object.keys(skills).forEach(skill  sets up a loop, going through the skills object one row at a time. Each row has a pair of values - the key , and the value . Navigation is a key , and int is that key's value . The script can then access these values:  skill  gives the current key, and skills[skill]  gives that key's value, the stat. So you carefully substitute each reference to a skill with skill , and each reference to the stat with  skills[skill] . Notice this line (with parseInt removed for clarity):: const level = v[skill + "_levels"]; Normally when you are getting an attributes value you would use const level = v.navigation_levels; but when you are building the attribute name with a string in the previous example, that format wont work and you have to use the [ ] format. You also need to do that on the setAttrs row [skill]: instead of navigation: So there you have it. I hope is useful for you. To recap, add this to your sheet worker and fill in the skills object, and you're good to go. const skills = { "navigation": "int",  "anotherskill": "its_attribute",  "yet another skill": "its attribute",  }; Object.keys(skills).forEach(skill => {     on("change:" +skill + "_levels change:" +skills[skill] + "_total sheet:opened", function() { getAttrs([skill + "_levels", skills[skill] + "_total"], function(v) { const level = parseInt(v[skill + "_levels"],10)||0, stat = parseInt(v[skills[skill] + "_total"],10)||0; let result = level < 0 ? Math.floor(stat/2) : stat + level; setAttrs({ [skill]: result }); }); }); });
Damn, dude.  Thank you for all your help.
1544829054
GiGs
Pro
Sheet Author
API Scripter
You're welcome! I just noticed the second copy of the script had an error in it (not sure how I managed that, must have copied an earlier testing version), I've corrected it.