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

Calculating Total Encumberance

Trying to get a total encumberance based on character strength/weight plus total weight of coinage / other items. I have the following setup: input fields used on char sheet attr_char_str_total (total strength bonus) attr_character_weight (character weight) attr_platimun1 attr_gold1 attr_silver1 attr_bronze1 attr_copper1 attr_tin1 attr_iron1 (coinage) fieldset repeating_inventory: attr_itemcount (number of inventory item) repeating_inventory: attr_itemweight (weight of single inventory item) return field: attr_enc_total I then have the following scripts written: <script type="text/worker"> on("change:char_str_total change:character_weight change:repeating_inventory:itemweight change:repeating_inventory:itemcount change:platimun1 change gold1 change:silver1 change:bronze1 change:copper1 change:tin1 change:iron1 sheet:opened", function() { update_weight(); }); var update_weight = function() { var update = {}; var wtotal = 0; var weightratio = 0; var enc_penalty = 0; var final_penalty = 0; var weight_attrs = ["platimun1","gold1","silver1","bronze1","copper1","tin1","iron1","character_weight","char_str_total"]; getSectionIDs("repeating_inventory", function(idarray) { _.each(idarray, function(currentID, i) { weight_attrs.push("repeating_inventory_" + currentID + "_itemweight"); weight_attrs.push("repeating_inventory_" + currentID + "_itemcount"); }); getAttrs(weight_attrs, function(v) { platimun1 = isNaN(parseInt(v.platimun1, 10)) === false ? parseInt(v.platimun1, 10) : 0; gold1 = isNaN(parseInt(v.gold1, 10)) === false ? parseInt(v.gold1, 10) : 0; silver1 = isNaN(parseInt(v.silver1, 10)) === false ? parseInt(v.silver1, 10) : 0; bronze1 = isNaN(parseInt(v.bronze1, 10)) === false ? parseInt(v.bronze1, 10) : 0; copper1 = isNaN(parseInt(v.copper1, 10)) === false ? parseInt(v.copper1, 10) : 0; tin1 = isNaN(parseInt(v.tin1, 10)) === false ? parseInt(v.tin1, 10) : 0; iron1 = isNaN(parseInt(v.iron1, 10)) === false ? parseInt(v.iron1, 10) : 0; wtotal = wtotal + ((platimun1 + gold1 + silver1 + bronze1 + copper1 + tin1 + iron1) / 50); _.each(idarray, function(currentID, i) { if(v["repeating_inventory_" + currentID + "_itemweight"] && isNaN(parseInt(v["repeating_inventory_" + currentID + "_itemweight"], 10)) === false) { count = v["repeating_inventory_" + currentID + "_itemcount"] && isNaN(parseFloat(v["repeating_inventory_" + currentID + "_itemcount"])) === false ? parseFloat(v["repeating_inventory_" + currentID + "_itemcount"]) : 1; wtotal = wtotal + (parseFloat(v["repeating_inventory_" + currentID + "_itemweight"]) * count); } }); weightratio = wtotal / v.character_weight; if (weightratio < 10) {penalty = 0;} else if (weightratio < 20) {penalty = 10;} else if (weightratio < 30) {penalty = 20;} else if (weightratio < 40) {penalty = 30;} else if (weightratio < 50) {penalty = 40;} else if (weightratio < 60) {penalty = 50;} else if (weightratio < 70) {penalty = 60;} else if (weightratio < 80) {penalty = 70;} else if (weightratio < 90) {penalty = 80;} else if (weightratio < 100) {penalty = 90;} enc_penalty = v.char_str_total - penalty; if (enc_penalty < 0) {final_penalty = enc_penalty;} else {final_penalty = 0;} setAttrs({ enc_total: final_penalty; }); }); }); }; </script> When I make the changes to the fields listed in the on:change  section the enc_total field is not updating. Please can you advise where I have gone wrong?
It appears to be an issue with the way I am interacting with the repeating fieldset. I have written another function which should set 2 parameters in the repeating fieldset based on the chosen weapon and this also does not work. The code block is as follows: on("change:repeating_weapons sheet:opened", function () { var weight_attrs = ["cat_1hedge_totalbonus","cat_1hconc_totalbonus","cat_2hand_totalbonus","cat_thrown_totalbonus","cat_missle_totalbonus","cat_polearm_totalbonus"]; getAttrs("weight_attrs", function(values) { let 1hedge=values.cat_1hedge_totalbonus; let 1hconc=values.cat_1hconc_totalbonus; let 2hand=values.cat_2hand_totalbonus; let thrown=values.cat_thrown_totalbonus; let missile=values.cat_missile_totalbonus; let polearm=values.cat_polearm_totalbonus; getSectionIDs("repeating_weapons", function(idArray) { _.each(idarray, function(currentID, i) { getAttrs("repeating_weapons_" + currentID + "_weapon_name", function(repeatval) { let weaponid=repeatval["repeating_weapons_" + currentID + "_weapon_name"]; if (weapon_name < 6) { weapon_type = "1"; attack_bonus = 1hedge; } else if (weapon_name < 12) { weapon_type = "2"; attack_bonus = 1hconc; } else if (weapon_name < 14) { weapon_type = "3"; attack_bonus = 2hand; } else if (weapon_name < 16) { weapon_type = "4"; attack_bonus = thrown; } else if (weapon_name < 20) { weapon_type = "5"; attack_bonus = missile; } else { weapon_type = "6"; attack_bonus = polearm; } setAttrs ({ "repeating_weapons_" + currentID + "_weapon_type":weapon_type; "repeating_weapons_" + currentID + "_weapon_skill":attack_bonus; }); }); }); }); }); }); btw when the character sheet runs is there is a debug log somewhere? I am trying to resolve these issues on a trial basis which is not ideal. Cheers
Just for in case I am defining my fieldset incorrectly I am using the following code: <fieldset class="repeating_weapons"> <table style="width: 203px;" class="sheet-table-row"> <tr> <td class="sheet-table-data-left"> <select name="attr_weapon_name"> <option value="1">Broadsword</option> <option value="2">Dagger</option> <option value="3">Hand-Axe</option> <option value="4">Scimitar</option> <option value="5">Short-Sword</option> <option value="6">Club</option> <option value="7">Mace</option> <option value="8">Morning Star</option> <option value="9">Net</option> <option value="10">War-Hammer</option> <option value="11">Whip</option> <option value="12">Javelin</option> <option value="13">Spear</option> <option value="14">Mounted Lance</option> <option value="15">Halberd</option> <option value="16">Battle-Axe</option> <option value="17">Flail</option> <option value="18">Quarterstaff</option> <option value="19">2-Handed Sword</option> <option value="20">Bola</option> <option value="21">Composite Bow</option> <option value="22">Crossbow</option> <option value="23">Long Bow</option> <option value="24">Short Bow</option> <option value="25">Sling</option> </select></td> <td class="sheet-table-data-left" style="width: 100px"><input type="text" name="attr_weapon_type" value="0" disabled="true"></td> <td class="sheet-table-data-center style="width: 40px"><input type="text" name="attr_weapon_skill" value="0" disabled="true"></td> <td class="sheet-table-data-center></td> <td class="sheet-table-data-center></td> <td class="sheet-table-data-center></td> <td class="sheet-table-data-center></td> </tr> </table> </fieldset> Thanks
1542510451
GiGs
Pro
Sheet Author
API Scripter
The error is likely due to running getAttrs and setAttrs in a loop. It's always best to have a single getAttrs and single setAtrs in your script. I'm feeling sick at the moment, so can't really concentrate on it. To give you a pointer: in your getsectionIds, the way to go is to use a loop to build a list of IDs, and an array of all the completed attributes, before you enter the getAttrs. If you search through my previous posts you'll find I've answered this specific problem a couple of times.
1542523439
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Heading to bed, but with a quick glance, you've got a syntaxerror in addition to GG's advice which is excellent best practice. The syntax error is that elements of an object are separated by commas, not semicolons. Your code most likely isn't even compiling; it's always a good idea to run your code through something like google's closure compiler or a local compiler when you aren't getting any response to stimulus.
1542523838
GiGs
Pro
Sheet Author
API Scripter
Scott is specifically referring to the setAttrs section, which should be setAttrs ({ "repeating_weapons_" + currentID + "_weapon_type":weapon_type, "repeating_weapons_" + currentID + "_weapon_skill":attack_bonus }); You should end each line with a comma, and the last entry should have no comma (if there's only one item, it's the last entry and should have no comma).
1542524239
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Thanks GG, on mobile which makes copying code a pain. Woody, just noticed your question about the log. Yes, you'll use your browser's console log (cmd alt i on Mac chrome/Ctrl shift I on PC chrome/inspect an html element and then switch to the console from there)
1542524787
GiGs
Pro
Sheet Author
API Scripter
You can call the log like this: console.log("enter a label here: " + name_of_variable_to_check); I like to put something like this at the start of my console.log statements: console.log("=============================================="); the browser console has a lot of stuff in it, and it's easy to miss your log statements without something to make them stand out. Scott mentioned some ways to get to the console. Another method, at least on chrome, is just pressing F12.
1542525087

Edited 1542525116
GiGs
Pro
Sheet Author
API Scripter
By the way, a simpler version of this silver1 = isNaN(parseInt(v.silver1, 10)) === false ? parseInt(v.silver1, 10) : 0; would be let silver1 = parseInt(v.silver1, 10) || 0; (dont forget to declare the variable on first appearance with var or let or const .)
Thanks Guys - GG - get yourself better!!!! I'll go through the suggestions, looking to implement.
1542526731

Edited 1542526940
GiGs
Pro
Sheet Author
API Scripter
Thanks Woody :) For that first encumbrance script, it seems to be built properly - a loop to build the attrs in getsectionIds before entering getAttrs. I wouldn't be surprised if the reason it isn't working is the semicolon in setAttrs, as Scott spotted, I did notice the wtotal each loop seems unnecessarily convoluted. This one: _.each(idarray, function(currentID, i) { if(v["repeating_inventory_" + currentID + "_itemweight"] && isNaN(parseInt(v["repeating_inventory_" + currentID + "_itemweight"], 10)) === false) { count = v["repeating_inventory_" + currentID + "_itemcount"] && isNaN(parseFloat(v["repeating_inventory_" + currentID + "_itemcount"])) === false ? parseFloat(v["repeating_inventory_" + currentID + "_itemcount"]) : 1; wtotal = wtotal + (parseFloat(v["repeating_inventory_" + currentID + "_itemweight"]) * count); } }); I think it can be streamlined to to: _.each(idarray, function(currentID) {         let weight = parseFloat(v["repeating_inventory_" + currentID + "_itemweight"], 10) || 0;         let count = parseInt(v["repeating_inventory_" + currentID + "_itemcount"], 10) || 1; wtotal = wtotal + weight * count; }); You shouldnt need to check each attribute exists, because the idarray list and matching attributes contain only valid values. The || 0 and || 1 at the end of the statements above set default values, if the items are not found, or aren't numbers.
1542530313

Edited 1542530548
GiGs
Pro
Sheet Author
API Scripter
I noticed a couple of errors in the weapon script. You have some variable names that start with a number (1hedge, 2handed, etc), which will cause an error. Variable names must start with a letter (some symbols are fine, but never use a number). Also you had a getAttrs/setAttrs inside a loop, which was inside a getSectionIDs, which was inside another gettAttrs. that will never work. You also had a weapon_name and weapon_id variable. I have assumed they are supposed to be the same variable in the code below, since one of them was never used, and the other was never declared. I had a stab at restructuring the function. on("change:repeating_weapons sheet:opened", function () { let weight_attrs = ["cat_1hedge_totalbonus", "cat_1hconc_totalbonus", "cat_2hand_totalbonus", "cat_thrown_totalbonus", "cat_missle_totalbonus", "cat_polearm_totalbonus"]; getSectionIDs("repeating_weapons", function (idArray) { _.each(idarray, function (currentID) { weight_attrs.push("repeating_weapons_" + currentID + "_weapon_name"); }); getAttrs("weight_attrs", function (values) { let edge1h = values.cat_1hedge_totalbonus; let conc1h = values.cat_1hconc_totalbonus; let hand2 = values.cat_2hand_totalbonus; let thrown = values.cat_thrown_totalbonus; let missile = values.cat_missile_totalbonus; let polearm = values.cat_polearm_totalbonus; let weapons = {}; _.each(idarray, function (currentID) { let weapon_name = values["repeating_weapons_" + currentID + "_weapon_name"]; if (weapon_name < 6) { weapon_type = "1"; attack_bonus = edge1h; } else if (weapon_name < 12) { weapon_type = "2"; attack_bonus = conc1h; } else if (weapon_name < 14) { weapon_type = "3"; attack_bonus = hand2; } else if (weapon_name < 16) { weapon_type = "4"; attack_bonus = thrown; } else if (weapon_name < 20) { weapon_type = "5"; attack_bonus = missile; } else { weapon_type = "6"; attack_bonus = polearm; } weapons["repeating_weapons_" + currentID + "_weapon_type"] = weapon_type; weapons["repeating_weapons_" + currentID + "_weapon_skill"] = attack_bonus; }); setAttrs(weapons); }); }); }); The setAttrs format might be different to what you are used to. Look up javascript object literals if you need to know more.  This is untested, but the basic structure is sound.
Thanks GG - there are actually a number of reasons why the script was failing to produce the results I wanted - probably mainly the fact that I don't understand javascript I also didn't fully understand how the attributes were populating the character sheet. I had an assumption that if I set name=attr_value3 value=" @{param1} + @{param2} " would create an attribute field value3. This was not the case - so when I went to retrieve the data from my script it was failing - the parameter was coming back as UNDEFINED (Thanks Scott - being able to console.log helped me massively in confirming this). Therefore I am going through setting all of the calculated values using javascript on the character sheet - hence forcing attributes to be created. Once this is done - I will grab what you have written (Thanks GG), make sure it does what I want and then update for the repeating group.
1542635394
GiGs
Pro
Sheet Author
API Scripter
It is possible to calculate attributes that way, you have to set the input to disabled. That creates an autocalc field. But the attributes created that way are incompatible with sheet workers, so you are better off doing what you are doing and switching to sheet workers for calculating stats.
Linked to this ticket as its around the use of repeating sections. I have the following code: on("change:repeating_skills sheet:opened", function () { var skill_attrs=[] getSectionIDs("repeating_skills", function(idArray) { _.each(idArray, function (currentID) { skill_attrs.push("repeating_skills_" + currentID + "_skill_second_ranks"); }); console.log("======================================================================="); console.log("skill_attrs=" + skill_attrs); getAttrs("skill_attrs", function(values) { let skills = []; _.each(idArray, function(currentID) { let skill_second_rank = values["repeating_skills_" + currentID + "_skill_second_ranks"]; skills["repeating_skills_" + currentID + "_skill_second_rankbonus"] = skill_second_rank; console.log("skill_second_rank =" + skill_second_rank); console.log("skills =" + skills); }); setAttrs(skills); }); }); }); When this runs the first pair of console commands return: ======================================================================= VM17:1389 skill_attrs=repeating_skills_-lroezrb3hguqgubfetf_skill_second_ranks,repeating_skills_-lrokdtnz8yzvkciz8dh_skill_second_ranks However I then get the following error: Uncaught TypeError: Cannot use 'in' operator to search for '0' in skill_attrs at Function.k.each.k.forEach (base.js?1530633549:6) at Worker.<anonymous> (app.js?1542653517:360) Looking at other posts this seems to be saying I am trying to search in a larger field for an object. However I'm not sure that this is the case on this function. Google Compiler states that the code is sound - however obviously roll20 has issues with it. The section of the repeating section that is being used in this code is as follows: <fieldset class="repeating_skills"> <table style="width: 800px;" class="sheet-table-row"> <tr> <td class="sheet-table-data-skills-cat-name"><input type="text" name="attr_skill_second_skillname"/></td> <td class="sheet-table-data-skills-cat"><select name="attr_skill_second_ranks" value="0"> <option value="-25">0</option> <option value="5">1</option> <option value="10">2</option> <option value="15">3</option> <option value="20">4</option> <option value="25">5</option> <option value="30">6</option> <option value="35">7</option> <option value="40">8</option> <option value="45">9</option> <option value="50">10</option> <option value="52">11</option> <option value="54">12</option> <option value="56">13</option> <option value="58">14</option> <option value="60">15</option> </select></td> <td class="sheet-table-data-skills-cat"><input type="text" name="attr_skill_second_rankbonus"value="0" readonly></td> As always any assistance will be appreciated.
1542673385
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
GetAttrs takes an array. You're passing it a string with the name of your array rather than the array itself.
1542680690
GiGs
Pro
Sheet Author
API Scripter
getAttrs("skill_attrs", function(values) { should be getAttrs(skill_attrs, function(values) {
Thanks Scott and GG ... worked.