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

AutoCalc error

1592784287

Edited 1592787951
Eli N.
Pro
Compendium Curator
I don't know what it is but I can't get any of my autocalcs to work. For example this one, there is no other attribute with these names <div class="sheet-col-1-8"><input type="checkbox" name="attr_skill_agriculture_checkbox" value="1"></div> <div class="sheet-col-1-16"><input type="number" name="attr_skill_agriculture_untrained" value="@{skill_agriculture_checkbox}" readonly/></div> Am I doing something stupid and simple? Whats going on?  I should say I can't get any NEW autocalcs to work. New sheetworkers still do their thing fine.  If this helps it seems like I can reference values outside of this skill section but if I try and do an autocalc inside the section it fails. For example if I set the value of cartography at @{strength} it works but @{skill_acting} it fails.  <div class="sheet-row sheet-skill-row"> <div class="sheet-col-15-24 sheet-vert-middle" style="color:red;">Cartography (Int)</div> <div class="sheet-col-1-6 sheet-vert-middle"><input type="number" name="attr_skill_cartography" value="0"/></div> <input type="hidden" name="attr_cartography_dice" value="[[d100]] Skill: [[@{skill_cartography}]]" /> <div class="sheet-col-5-24 sheet-vert-middle"><button class="sheet-skill-roll" type='roll' name='roll_skill_cartograpgy' value='@{character_name} makes a cartography skill check\n\nRoll :@{cartography_dice}'>Check</button></div> </div>
1592794337
GiGs
Pro
Sheet Author
API Scripter
Autocalc fields must use disabled , not readonly . If you are using sheet workers though, you dont want to be using autocalc fields, Sheet workers cant get the value of an autocalc field, they get the text of the expression. Regarding setting the value of cartography: what are the values of strength, and skill_action? Note that your button name has a typo: name='roll_skill_cartograp g y'
1592836244
Eli N.
Pro
Compendium Curator
Thanks that helped and so did the spelling error Quick follow up question.  I have so I have a sheetworker to set the base values of skills based on attributes. Then I have a checkbox to indicate if the skill is trained (aka if the attribute should be added or not). However in the example above with agriculture the sheet worker is putting a value in the  skill_agriculture_untrained  and when I check the checkbox it resets back to 1/0. 
1592837315
GiGs
Pro
Sheet Author
API Scripter
Post your current code for the above section, and the code for the sheet worker.
1592839279
Eli N.
Pro
Compendium Curator
Here is the code for the section  <div class="sheet-col-1-8"><input type="checkbox" name="attr_skill_agriculture_checkbox" value="1"></div> <div class="sheet-col-1-16"><input type="number" name="attr_skill_agriculture_untrained" value="@{skill_agriculture_checkbox}" disabled/></div> The Sheetworker autofills the 4 stats that are determined from wisdom (defense,mental save bonus, initiative, fatigue) and it sets the base value for each of the skills. For universal skills it just auto fills into the untrained bonus. But for non-universal I only want it to auto fill if the trained button is checked.   on("change:wisdom change:wisdom_fractional sheet:opened", function() { getAttrs(["wisdom","wisdom_fractional"], function(values) { const wis = int(values.wisdom); const wisfrac = int(values.wisdom_fractional); let wistot = wis + wisfrac*.01; console.log(wistot); const mods = [2, 4, 7,10, 12, 15, 18,20]; const getMod = score => (score> 20) ? 4 : mods.findIndex(check => check >= score) -4; const wisdom_defense_mod = getMod(wistot); const mods2 = [3,5,7,9, 13, 15, 18,20]; const getMod2 = score => (score> 20) ? 4 : mods2.findIndex(check => check >= score) -4; const mental_save_bonus = getMod2(wistot); const mods3 = [2,3,4,7,10,12,15,18,20]; const getMod3 = score => (score> 20) ? 2 : mods3.findIndex(check => check >= score) -7; const wisdom_initiative_mod = -1*getMod3(wistot); const mods4 = [3,6,9,12,15,18,21,22]; const getMod4= score => (score> 22) ? 4 : mods3.findIndex(check => check >= score) -3; const fatigue_wis = -1*getMod3(wistot); setAttrs({ wisdom_defense_mod:wisdom_defense_mod, mental_save_bonus:mental_save_bonus, wisdom_initiative_mod: wisdom_initiative_mod, fatigue_wis:fatigue_wis, skill_animal_husbandry_untrained: wis, skill_animal_mimicry_untrained: wis, skill_boating_untrained: wis, skill_current_affairs_untrained: wis, skill_fire_building_untrained: wis, skill_listening_untrained: wis, skill_observation_untrained: wis, skill_resist_persuasion_untrained: wis, skill_scrutiny_untrained: wis, skill_tracking_untrained: wis, skill_administraction_checkbox: wis, skill_agriculture_checkbox: wis, skill_animal_herding_checkbox: wis, skill_direction_sense_checkbox: wis, skill_divine_lore_checkbox: wis, skill_first_aid_checkbox: wis, skill_hunting_checkbox: wis, skill_identify_trap_checkbox: wis, skill_musician_checkbox: wis, skill_religion_checkbox: wis, skill_weather_sense_checkbox: wis }); }); });
1592846352

Edited 1592846975
GiGs
Pro
Sheet Author
API Scripter
First thing: your agriculture skill is disabled, so the sheet worker cant change its value. You need to change the readonly. Second, unrelated: you can reduce all those getmods to one function:         const getMod = (set, score, mod) => (score> 20) ? 4 : set.findIndex(check => check >= score) - mod;         const mods_def = [2, 4, 7,10, 12, 15, 18,20]; const wisdom_defense_mod = getMod(mods_def, wistot, 4); const mods_save = [3,5,7,9, 13, 15, 18,20]; const mental_save_bonus = getMod(mods_save, wistot, 4); const mods_init = [2,3,4,7,10,12,15,18,20]; const wisdom_initiative_mod = -1 * getMod(mods_init, wistot, 7); const mods_ft = [3,6,9,12,15,18,21,22];         const fatigue_wis = -1 * getMod(mods_ft, wistot, 3); or even better         const getMod = (set, score, mod) => (score> 20) ? 4 : set.findIndex(check => check >= score) - mod;         const mods = {             def: [2, 4, 7,10, 12, 15, 18,20],             save: [3,5,7,9, 13, 15, 18,20],              init: [2,3,4,7,10,12,15,18,20],              ft: [3,6,9,12,15,18,21,22]         }; const wisdom_defense_mod = getMod(mods.def, wistot, 4); const mental_save_bonus = getMod(mods.save, wistot, 4); const wisdom_initiative_mod = -1 * getMod(mods.init, wistot, 7);         const fatigue_wis = -1 * getMod(mods.ft, wistot, 3); Okay on to your issue. You seem to be saving wis to the checkbox values. You shouldnt be doing that. You shouldnt be altering that through the sheet worker at all. But also, you need to check the value of each skill's checkbox. To do that you must  get those values into the sheet worker, by adding them to getAttrs. You should probably also have them in the on(change) line, so that the value can be updated when a player checks or unchecks the box.  To achieve this, I would recommend creating two arrays inside an object before the sheet worker that looks like: const skills = {     wisdom_universal: ['animal_husbandry', 'etc'],     wisdom_checkbox: ['agriculture', 'more here'] }; Just add the rest of the skills - each in quotes, and separated by a comma. You need two arrays: one for all the wisdom skills that are universal, and one for all those that need the checkbox checked. side note: i assume administra c tion is a typo. Now we have those, we can loop through them in various ways. For instance, to add the checkbox values to the on(changes) line you can build a string of them all with one line of code: const wisChanges = skills.wisdom_checkbox.map(skill => `change:skill_${skill}_checkbox`).join(' '); map is a function that takes an array and does something to every item in that array. In the above, we are taking each skill in the checkboxes list, and adding "change:skill_" and "_checkbox" to its value. Then joining it into a string separated by spaces. We can use that like so: on(`change:wisdom change:wisdom_fractional ${wisChanges} sheet:opened`, function() { You can do a similar process for the getAtrrs line. Here we keep it as an array, so we dont need the join at the end: const wisAttrs = skills.wisdom_checkbox.map(skill => `skill_${skill}_checkbox`); This allows use to use: getAttrs(['wisdom','wisdom_fractional', ...wisAttrs], function(values) { The ... before the name of wisAttrs array is called the spread  operate. It spreads out an array into its items, so that drops each skill full name into getAttrs where we need it. So now the values  object contains all the checkbox values for wisdom skills. And this sheet worker will update whenever any checkbox is clicked, or the wisdom value changes. To set the scores inside the sheet worker, we are going to loop through both the wisdom skills arrays above. First we create an object to hold the final values like so: const output = {}; Then we loop through the universal array like so     skills.wisdom_universal.forEach(skill => {             output[`skill_${skill}_untrained`] = wis;     });         This takes the wisdom_universal array, and gets every skill name, adds "skill_" and "_untrained" to it, thus building a proper attribute named. It then adds an entry with that name to output , and sets its value to wis. Once that loop runs, we have avariable that contains all the universal skills and their new values.  We are going to do the same for the checkbox array. But this time we need to check if the checkbox is checked, and only enter the wis value if it is. But  we also need to handle what happens if it is not checked. Imagine a player checks the box - that skill gains a value equal to wis. Then they uncheck it. If the worker does nothing, the skill will still have the value. So we need to reset the value when unchecked. here's a loop that does exactly that.        skills.wisdom_checkbox.forEach(skill => {             const check = int(values[`skill_${skill}_checkbox`]);             if(check) {                 output[`skill_${skill}_untrained`] = wis;             } else {                 output[`skill_${skill}_untrained`] = 0;             }         });         I assume the value you want when unchecked is 0. You can change that to whatever it should be. And then we have to save the new values, which is simple enough: setAttrs(output); Putting all that together (with a few name changes for clarity): const getStatMod = (set, score, mod) => (score> 20) ? 4 : set.findIndex(check => check >= score) - mod; const stat_mods = {     def: [2, 4, 7,10, 12, 15, 18,20],     save: [3,5,7,9, 13, 15, 18,20],     init: [2,3,4,7,10,12,15,18,20],     ft: [3,6,9,12,15,18,21,22] }; const skills = {     wisdom_universal: ['animal_husbandry', 'etc'],     wisdom_checkbox: ['agriculture', 'more here'] }; const wisChanges = skills.wisdom_checkbox.map(skill => `change:skill_${skill}_checkbox`).join(' '); const wisAttrs = skills.wisdom_checkbox.map(skill => `skill_${skill}_checkbox`); on(`change:wisdom change:wisdom_fractional ${wisChanges} sheet:opened`, function() {     getAttrs(['wisdom','wisdom_fractional', ...wisAttrs], function(values) {         const wis = int(values.wisdom);         const wisfrac = int(values.wisdom_fractional);         let wistot  = wis + wisfrac*.01;         console.log(wistot);         const output = {};         output.wisdom_defense_mod =  getStatMod(stat_mods.def, wistot, 4);         output.mental_save_bonus =  getStatMod(stat_mods.save, wistot, 4);         output.wisdom_initiative_mod = -1 * getStatMod(stat_mods.init, wistot, 7);         output.fatigue_wis = -1 * getStatMod(stat_mods.ft, wistot, 3);         skills.wisdom_universal.forEach(skill => {             output[`skill_${skill}_untrained`] = wis;         });         skills.wisdom_checkbox.forEach(skill => {             const check = int(values[`skill_${skill}_checkbox`]);             if(check) {                 output[`skill_${skill}_untrained`] = wis;             } else {                 output[`skill_${skill}_untrained`] = 0;             }         });                  setAttrs(output);     }); }); A few things to note: I moved the getMod function and the stat_mods outside the sheet worker. I am assuming to will also have a similar sheet worker for the other stats, and this allows you to use the same code for each. No need to write it again in each worker. I also named the skills variable the way I did so you can just put the arrays for the other stats in there as well, and then use basically the same sheet worker code for the other stats. I also put the four special stats in a different format: no need to individually define them, when we can just add them directly to the output object. Hope this helps!
1592850368
Eli N.
Pro
Compendium Curator
This does help, I'll make these edits later and let you know.  If that works, I'll do the same process for the other skills.
1592851041
GiGs
Pro
Sheet Author
API Scripter
i just noticed the getStatMod has a bit of an error in it. It doesnt account for all the variation in your comparisons, so change it to this  const getMod = (set, score, mod, max = 4) => (score> Math.max(set)) ? max : set.findIndex(check => check >= score) - mod; And for those four wisdom stats, change to (only the initiative one actually changed)         output.wisdom_defense_mod =  getStatMod(stat_mods.def, wistot, 4);         output.mental_save_bonus =  getStatMod(stat_mods.save, wistot, 4);         output.wisdom_initiative_mod = -1 * getStatMod(stat_mods.init, wistot, 7, 2);         output.fatigue_wis = -1 * getStatMod(stat_mods.ft, wistot, 3);
1592860500
Eli N.
Pro
Compendium Curator
Alrighty, so I tried this, and no dice it didn't auto fill abilities or skills const getMod = (set, score, mod, max = 4) => (score> Math.max(set)) ? max : set.findIndex(check => check >= score) - mod; const stat_mods = {     def: [2, 4, 7,10, 12, 15, 18,20],     save: [3,5,7,9, 13, 15, 18,20],     init: [2,3,4,7,10,12,15,18,20],     ft: [3,6,9,12,15,18,21,22] }; const skills = {     wisdom_universal: ['animal_husbandry', 'animal_mimicry','current_affairs','fire_building','listening','observation','resist_persuasion','scrutiny','tracking'],     wisdom_checkbox: ['agriculture', 'administration','animal_herding','direction_sense','divine_lore','first_aid','hunting','identify_trap','musician','religion','weather_sense'] }; const wisChanges = skills.wisdom_checkbox.map(skill => `change:skill_${skill}_checkbox`).join(' '); const wisAttrs = skills.wisdom_checkbox.map(skill => `skill_${skill}_checkbox`); on(`change:wisdom change:wisdom_fractional ${wisChanges} sheet:opened`, function() {     getAttrs(['wisdom','wisdom_fractional', ...wisAttrs], function(values) {         const wis = int(values.wisdom);         const wisfrac = int(values.wisdom_fractional);         let wistot  = wis + wisfrac*.01;         console.log(wistot);         const output = {};         output.wisdom_defense_mod =  getStatMod(stat_mods.def, wistot, 4);         output.mental_save_bonus =  getStatMod(stat_mods.save, wistot, 4);         output.wisdom_initiative_mod = -1 * getStatMod(stat_mods.init, wistot, 7, 2);         output.fatigue_wis = -1 * getStatMod(stat_mods.ft, wistot, 3);         skills.wisdom_universal.forEach(skill => {             output[`skill_${skill}_untrained`] = wis;         });         skills.wisdom_checkbox.forEach(skill => {             const check = int(values[`skill_${skill}_checkbox`]);             if(check) {                 output[`skill_${skill}_untrained`] = wis;             } else {                 output[`skill_${skill}_untrained`] = 0;             }         });                  setAttrs(output);     }); });
1592861160

Edited 1592861399
GiGs
Pro
Sheet Author
API Scripter
Did you remove the disabled tag on the attributes? Also change the first line to const getStatMod = (set, score, mod, max = 4) => (score> Math.max(set)) ? max : set.findIndex(check => check >= score) - mod; Sorry for changing the name on you. I made it more specific in case you need a similar function later.
1592862168
Eli N.
Pro
Compendium Curator
Skills are readonly and the stats don't have readonly or disabled
1592862349
Eli N.
Pro
Compendium Curator
Okay so it's working now, but when I initially load up the sheet it has set all the values to wis, as opposed to 0, 
1592864203
GiGs
Pro
Sheet Author
API Scripter
The values are being set because you set sheet:opened  in the sheet worker. It runs when the sheet is opened. Should the sheet worker hold off till a specific value is set before setting the skills? 
1592864340
Eli N.
Pro
Compendium Curator
I meant all the skills with checkboxes already have the wisdom score in it
1592864490
GiGs
Pro
Sheet Author
API Scripter
If I'm understanding you correctly, your previous code set the checkboxes to wis. Just click and unclick each checkbox to restore them to the values they should have. 
1592866966
Eli N.
Pro
Compendium Curator
Ah so thats more of an issue of pre-existing values being in those spots. Thanks
1592867370
GiGs
Pro
Sheet Author
API Scripter
I think so. Let me know if that doesnt fix it.