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

Auto-calc fields going blank

Hi, I recently updated a character sheet I'm writing to calculate some modifiers using sheetworkers instead of auto-calc fields. It seems to have broken the auto-calc fields I'm still using elsewhere in the sheet, though: the affected fields are blank, and when I test them manually, they seem to be picking up incorrect values for some attributes. Example : I have the following auto-calc field: <input type="number" name="attr_will_abil" value="[[((@{wis_mod} + @{cha_mod}) + abs(@{wis_mod} - @{cha_mod}))]] / 2" disabled="true"/> After I made this update, it was miscalculated for exactly one of a half-dozen character sheets. In this instance, wis_mod is 2, and cha_mod is -1. The formula (a kludgy way of calculating the maximum of these two values) should produce a value of 2. Instead, the field is blank, and when I run @{will_abil} for this character, it spits out ((0 +0) + abs(0 - 0)) / 2, so it looks like it's getting the wrong inputs somewhere? Diagnostics: I've tried changing wis_mod and cha_mod. Nothing changes. I've tried using the inspect tool to enable the disabled input and re-enter the correct values. Afterward, if I change wis_mod or cha_mod, it goes back to being blank. It's also affecting downstream calculations: macros referencing will_abil are returning blank or incorrect values. Does anyone know what might be causing this? I can implement some extra sheetworkers, but I'd like to know what's responsible before I break anything else.
1595493053
GiGs
Pro
Sheet Author
API Scripter
Once you start using sheet workers, its very common to have to get rid of many more autocalcs and replace them with sheet workers. If your chain of calculations goes like this: sheet worker -> autocalc -> autocalc it should work fine, but if it goes like this at any point: autocalc -> sheetworker it will not work properly. Can you post all sheet workers you are currently using, and the html input code for the attributes they work with?
Sheet Workers:      on("change:str sheet:opened", function() { getAttrs(["str"], function(values) { setAttrs({ str_mod_hidden: Math.floor(values.str/2 - 5) }); }); }); on("change:con sheet:opened", function() { getAttrs(["con"], function(values) { setAttrs({ con_mod_hidden: Math.floor(values.con/2 - 5) }); }); }); on("change:dex sheet:opened", function() { getAttrs(["dex"], function(values) { setAttrs({ dex_mod_hidden: Math.floor(values.dex/2 - 5) }); }); }); on("change:int sheet:opened", function() { getAttrs(["int"], function(values) { setAttrs({ int_mod_hidden: Math.floor(values.int/2 - 5) }); }); }); on("change:wis sheet:opened", function() { getAttrs(["wis"], function(values) { setAttrs({ wis_mod_hidden: Math.floor(values.wis/2 - 5) }); }); }); on("change:cha sheet:opened", function() { getAttrs(["cha"], function(values) { setAttrs({ cha_mod_hidden: Math.floor(values.cha/2 - 5) }); }); }); on("change:str_mod change:con_mod sheet:opened", function() { getAttrs(["str_mod", "con_mod"], function(values) { let str_mod = parseInt(values.str_mod)||0; let con_mod = parseInt(values.con_mod)||0; let abil = Math.max(str_mod, con_mod); setAttrs({ fort_abil_hidden: abil }); }); }); on("change:dex_mod change:int_mod sheet:opened", function() { getAttrs(["dex_mod", "int_mod"], function(values) { let dex_mod = parseInt(values.dex_mod)||0; let int_mod = parseInt(values.int_mod)||0; let abil = Math.max(dex_mod, int_mod); setAttrs({ ref_abil_hidden: abil }); }); }); on("change:wis_mod change:cha_mod sheet:opened", function() { getAttrs(["wis_mod", "cha_mod"], function(values) { let wis_mod = parseInt(values.wis_mod)||0; let cha_mod = parseInt(values.cha_mod)||0; let abil = Math.max(wis_mod, cha_mod); setAttrs({ will_abil_hidden: abil }); }); }); const groups = ['basic', 'lesser', 'greater', 'feature', 'item', 'other']; groups.forEach(function (group) { const texts = ['attack_hit_', 'attack_crit_', 'attack_miss_', 'attack_effect_', 'attack_maintain_', 'attack_special_']; texts.forEach(function (text) { on("change:repeating_" + group + ":" + text + group + " sheet:opened", function () { usText = "repeating_" + group + "_" + text + group getAttrs([usText], function (values) { setAttrs({ [usText + '_noroll']: values[usText].split("[[").join("").split("]]").join("") }); }); }); }); }); The first six sheetworkers set an ability modifier based on an ability score. They are working as intended as far as I can tell. The next three are new, and pick the higher of two abilities to use in calculating the Fortitude, Reflex, and Will defenses. I've tried three different variations, listed below. That last one is something complicated and mostly unrelated: there can be text in 'repeating_basic_attack_hit_basic' which references the six ability modifiers above, but those are the only things that would feed into that sheetworker. HTML Input Code: <input type="number" name="attr_fort_abil" value="((@{str_mod} + @{con_mod}) + abs(@{str_mod} - @{con_mod})) / 2" disabled="true"/> <input type="number" name="attr_ref_abil" value="@{ref_abil_hidden}" disabled="true"/> <input type="hidden" name="attr_ref_abil_hidden" value="0"/> <input type="number" name="attr_will_abil" value="@{will_abil_hidden}" disabled="true"/> The Fortitude input doesn't use the sheetworker, it just does an auto-calc. It appears to be working fine. The Reflex input is disabled and takes the value of the hidden field updated by the sheetworker. It doesn't appear to work at all, now that I've tested it on other characters. The Will input is disabled and takes the value of the hidden attribute updated by the sheetworker, which does not have a field of its own. It also doesn't appear to work at all.
1595496585

Edited 1595496636
It honestly looks to me like certain fields and/or attributes are coming "unmoored" and no longer accepting auto-calc updates. It seems to be happening at random; I've checked a dozen different characters and some of them are unaffected, and some of them have one or two fields affected.
1595496617
GiGs
Pro
Sheet Author
API Scripter
If youre building the dex_mod, cha_mod the same way as your saves, with a hidden value, and a visible value using a disabled attribute, that's your issue. You dont need the hidden attribute, just use <input type="number" name="attr_ref_abil" value="0" readonly/> and have the sheet worker update the visible stat              setAttrs({ ref_abil: abil }); So, you need to change each of the stats, str, dex, etc, so that the mod updates the visible attribute directly. Dont use hidden attributes, and then an autocalc to display it. You can set them as readonly so players cant tweak them. Here's a method to calculate all 6 stats, and all 3 saves (untested). But remember - change all inputs to use readonly not disabled. const stats = ['cha', 'wis', 'dex', 'int', 'con', 'str']; stats.forEach(stat => {     on(`change:${stat} sheet:opened`, function() {         getAttrs([stat], function(values) {             const score = parseInt(score) ||0;             setAttrs({                 [`${score}_mod`]: Math.floor(score/2 - 5)             });         });     }); }); const saves = {     ref: ['dex', 'int'],     fort: ['str', 'con'],     will: ['wis', 'cha'] }; Object.keys(saves).forEach(save => {     on(`change:${saves[save][0]}_mod change:${saves[save][1]}_mod sheet:opened`, function() {         getAttrs([`${saves[save][0]}_mod`, `${saves[save][1]}_mod`], function(values) {             let mod0 = parseInt(values[`${saves[save][0]}`])||0;             let mod1 = parseInt(values[`${saves[save][1]}`])||0;             let abil = Math.max(mod0, mod1);             setAttrs({                 [`${saves[save]}_abil`]: abil             });         });     }); });
Thanks for the code! Javascript is not my forte, but I was able to parse what the intent was and debug it. Tested, probably bug-free revision: const stats = ['cha', 'wis', 'dex', 'int', 'con', 'str']; stats.forEach(stat => { on(`change:${stat} sheet:opened`, function() { getAttrs([stat], function(values) { const score = parseInt(values[stat]) ||0; setAttrs({ [`${stat}_mod`]: Math.floor(score/2 - 5) }); }); }); }); const saves = { ref: ['dex', 'int'], fort: ['str', 'con'], will: ['wis', 'cha'] }; Object.keys(saves).forEach(save => { on(`change:${saves[save][0]}_mod change:${saves[save][1]}_mod sheet:opened`, function() { getAttrs([`${saves[save][0]}_mod`, `${saves[save][1]}_mod`], function(values) { let mod0 = parseInt(values[`${saves[save][0]}_mod`])||0; let mod1 = parseInt(values[`${saves[save][1]}_mod`])||0; let abil = Math.max(mod0, mod1); setAttrs({ [`${save}_abil`]: abil }); }); }); });
1595499956
GiGs
Pro
Sheet Author
API Scripter
Nice work on fixing it.