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 Request] [SheetWorkers] Trying to create a sheet workers to auto-calc ability scores, getting errors

1669288399
Toby
Pro
Hello, I'm trying to create a SheetWorkers to calculate ability scores for my customised DarkHeresy 1e character sheet (kinda based off the community one with some additional automation).  And I'm running into some problems with my ability score code.  My knowledge of javascript is honestly garbage and I'm just kinda copy/pasting the code and adapting it from another character sheet (one of the other pathfinder sheets, donno which one).  I am getting an error when trying to execute the sheet. I was hoping someone could look at my code and tell me where I'm going wrong: var SetAbil = function(abil){ "use strict"; console.log("=== Set Ability Scores ==="); console.log("Setting "+abil+" . . ."); getAttrs([abil+'-base'], [abil+'-unnatural'], function(v) { console.log("GET " + abil+"-base: [" + v[abil+"-base"] + "] " + abil+"-unnatural [" + v[abil+"-unnatural"] + "]"); var stat = parseInt(v[abil+"-base"]) + parseInt(v[abil+"-unnatural-mod"]); console.log("SET the value of " +abil+ ": " +stat); var statMod = Math.floor(stat / 2) - 5 // Auto-calculated variable found in @{XXX}.  This is not drawn from the character sheet. console.log("SET the value of " +abil+ "-mod: " +statMod); var unNatMod = Math.floor(parseInt(v[abil+"-unnatural-mod"]) * stat / 2); console.log("SET the value of " +unNatMod+ ": " +unNatMod); var finalMod = statMod + unNatMod; console.log("SET the value of " +finalMod+ ": " +finalMod); //console.log("Wounds Penalty: " +parseInt(v['condition-wounds'])+"."); ~RESERVED FOR FUTURE USE~ var update = {}; update[abil] = stat; update[abil+'-mod']= statMod; update[abil+'-unnatural-mod'] = unNatMod; update[abil+'-final-mod'] = chkCond1; /* ****************** CONDITIONALS ***************************************** */ /* ** WS (Weapon Skill)     : NONE                                        ** */ /* ** BS (Ballistics Skill) : NONE                                        ** */ /* ** STR (Strength)        : Fatigued/Exhausted                          ** */ /* ** TOU (Toughness)       : Entangled, Grappled, Fatigued/Exhausted     ** */ /* ** AGI (Agility)         : NONE                                        ** */ /* ** INT (Intelligence     : NONE                                        ** */ /* ** PER (Perception)      : NONE                                        ** */ /* ** WIL (Willpower)       : NONE                                        ** */ /* ** FEL (Fellowship)      : NONE                                        ** */ /* ** INF (Influence)       : NONE                                        ** */ /* ****************** CONDITIONALS ***************************************** */ setAttrs(update); });  //  }; on('change:ws-base ', _.bind(SetAbil,{},'ws')); on('change:bs-base ', _.bind(SetAbil,{},'bs')); on('change:tou-base ', _.bind(SetAbil,{},'tou')); on('change:agi-base ', _.bind(SetAbil,{},'agi')); on('change:int-base ', _.bind(SetAbil,{},'int')); on('change:wp-base ', _.bind(SetAbil,{},'wp')); on('change:fel-base ', _.bind(SetAbil,{},'fel')); on('change:inf-base ', _.bind(SetAbil,{},'inf')); with the html hidden fields: <input type="hidden" name="attr_ws-unnatural-mod" value="" title="Unnatural Weapon Skill Modifier" readonly /> <input type="hidden" name="attr_ws-mod" value="" title="Weapon Skill Modifier" readonly /> <input type="hidden" name="attr_ws-mod-final" value="" title="(@{ws-mod-final}) Final Modifier" readonly /> The console log output is: === Set Ability Scores === VM4:5 Setting ws . . . sheetsandboxworker.js:763 TypeError: workerGlobals.waitingAttrRequests[reqid] is not a function     at fullfillAttrReq (sheetsandboxworker.js:54:1)     at messageHandler (sheetsandboxworker.js:741:1) sheetsandboxworker.js:764 TypeError: workerGlobals.waitingAttrRequests[reqid] is not a function     at fullfillAttrReq (sheetsandboxworker.js:54:1)     at messageHandler (sheetsandboxworker.js:741:1) Thanks again in advance.
1669704371
GiGs
Pro
Sheet Author
API Scripter
I see a couple of possible places for errors. First this line: getAttrs([abil+'-base'], [abil+'-unnatural'], function(v) { The syntax here is wrong - you must only have one set of sequare brackets, so something like getAttrs([abil+'-base', abil+'-unnatural'], function(v) { I don't recommend having multiple calculations like this: var stat = parseInt(v[abil+"-base"]) + parseInt(v[abil+"-unnatural-mod"]); The issue is that parseInt might produce an error - if the html for these stats is type="number" it should be okay (I think...). But otherwise, you can easily get an error here and an error on either stat causes the calculation to fail. To avoid this, you'd need to do something like this: var stat = (parseInt(v[abil+"-base"]) || 0) + (parseInt(v[abil+"-unnatural-mod"]) || 0); This sets the default value to 0: if there is an error, the value is set to 0 instead. But when doing multiple stats you need the parentheses and the code is uggly. You could instead do something like this: var stat_base = parseInt(v[abil+"-base"]) || 0; var stat_mod = parseInt(v[abil+"-unnatural-mod"]) || 0; var stat = stat_base + stat_mod; here you don't need those outer brackets, and when an error occurs, it is easier to figure out which stat is causing problems with logging.
1669741552
Toby
Pro
Thank you very much for a replay I'm going to give this a try right now, but I do want to adress something quickly before I do and that is: ....and the code is uggly... *chuckle*  Yep, the code is very ugly.  Yet, I know something vaguely like this worked because I used it in the past with one of my character sheets where I had substantial help (for pathfinder 1e).  It might have even been you, actually.  I simply copied the code style as best I could and imported it into my character sheet.  Once I actually get it to function, I was going to ask a follow up question, and that was, making the code more... optimized, and therefore less... uggly. :D The reason I am in need to switch this over is because I'm using ScriptCards, and it doesn't really like autoCalc values.  It has some major issues parsing them.  So, I'm thinking if the calculations are handled behind the scene this will fix this issues.  Not to mention, it will make it easier to create automatic "buffs/debuffs" to the characters later down the line.
1669749450
GiGs
Pro
Sheet Author
API Scripter
I wasn't referring to your code as it is, but how "uggly" (hehe) it would become if you followed those instructions :) I hope that works. Generally speaking, it's better to use sheet workers than autocalcs. Sheet workers are a lot trickier to write, but work better with the rest of roll20.
1670523263
Toby
Pro
Alrighty... I think I have the code working.  I have redesigned the above code with the suggestions that you made.  Thank you for the help. var SetAbil = function(abil){ "use strict"; console.log("=== Set Ability Scores ==="); console.log("Setting "+abil+" . . ."); getAttrs([abil+'-base', abil+'-unnatural'], function(v) {     console.log("GET " + abil+"-base: [" + v[abil+"-base"] + "] " + abil+"-unnatural [" + v[abil+"-unnatural"] + "]"); var stat_unnat = parseInt(v[abil+"-unnatural"]) || 0; var stat_base  = parseInt(v[abil+"-base"]) || 0; var stat_unNat_base  = stat_base * stat_unnat;  // Unnatural Score is the base score, times the unnatural value. var base_mod  = Math.floor(stat_base / 10); var unNat_mod = Math.floor(stat_unNat_base / 10); console.log("SET the value of stat_unnat  = " +stat_unnat+ "."); console.log("SET the value of stat_base   = " +stat_base+ "."); console.log("SET the value of stat_unNat_base = " +stat_unNat_base+ "."); console.log("SET the value of base_mod    = " +base_mod+ "."); console.log("SET the value of unNat_mod   = " +unNat_mod+ "."); //console.log("Wounds Penalty: " +parseInt(v['condition-wounds'])+"."); ~RESERVED FOR FUTURE USE~ var update = {}; update[abil] = stat_base; update[abil+'-mod']= base_mod; update[abil+'-unnatural-mod'] = unNat_mod; // update[abil+'-final-mod'] = chkCond1; /* ****************** CONDITIONALS ***************************************** */ /* ** WS (Weapon Skill)     : NONE                                        ** */ /* ** BS (Ballistics Skill) : NONE                                        ** */ /* ** STR (Strength)        : Fatigued/Exhausted [SIZE]                   ** */ /* ** TOU (Toughness)       : Entangled, Grappled, Fatigued/Exhausted     ** */ /* ** AGI (Agility)         : NONE                                        ** */ /* ** INT (Intelligence     : NONE                                        ** */ /* ** PER (Perception)      : NONE                                        ** */ /* ** WIL (Willpower)       : NONE                                        ** */ /* ** FEL (Fellowship)      : NONE                                        ** */ /* ** INF (Influence)       : NONE                                        ** */ /* ****************** CONDITIONALS ***************************************** */ setAttrs(update); });  //  }; /* Update Code */ on('change:ws-base change:ws-unnatural ', _.bind(SetAbil,{},'ws')); on('change:bs-base ', _.bind(SetAbil,{},'bs')); on('change:tou-base ', _.bind(SetAbil,{},'tou')); on('change:agi-base ', _.bind(SetAbil,{},'agi')); on('change:int-base ', _.bind(SetAbil,{},'int')); on('change:wp-base ', _.bind(SetAbil,{},'wp')); on('change:fel-base ', _.bind(SetAbil,{},'fel')); on('change:inf-base ', _.bind(SetAbil,{},'inf')); There is still some work to be done to make adjustments and tweaks to this, such as the size bonus of the character affecting the STR TOU and AGI bonus.  Bonuses to STR and TOU from armor (some forms of power armor grant bonuses).  And as well as the eventual introduction as a repeating section for creating temporary buffs (I'd probably need to ask someone to create that for me, since... its probably beyond my knowledge of coding). I will now need to move on to the skills section to do this same thing with ability scores to essentially add the bonuses to skills from the various attributes.  I think the basic code would be the same.  And honestly, if thats the case it shouldn't be much more complcated to do. I do have two questions however.  First, Both WEAPON SKILL (WS) and BALLISTICS SKILL (BS) do not normally have unnatural ability scores.  If I simply disable those fields so people cannot enter a value into those fields (and as such the script will always have the default value for  stat_unnat   will that cause the sheet workers to have any... wonky side effects. Second, If I wanted to create a character sheet "reset" button, and have that reset button simply force the entirety of the sheet workers to take all the values in all the autocalc fields and execute the script again.  What would be the best way to go about that.  Would it be to simply have a checkbox button somewhere on the page and have an onChange element in the update code at the bottom like  change:reset  or would that cause undesireable results across the whole page and sheet workers?
1670547964

Edited 1670547988
GiGs
Pro
Sheet Author
API Scripter
If you have follow-up questions, I'd recommend mentioning they exist at the start of the post. I almost missed them from skimming the asnwer. Toby said: I do have two questions however.  First, Both WEAPON SKILL (WS) and BALLISTICS SKILL (BS) do not normally have unnatural ability scores .  If I simply disable those fields so people cannot enter a value into those fields (and as such the script will always have the default value for  stat_unnat   will that cause the sheet workers to have any... wonky side effects. Second, If I wanted to create a character sheet "reset" button, and have that reset button simply force the entirety of the sheet workers to take all the values in all the autocalc fields and execute the script again.  What would be the best way to go about that.  Would it be to simply have a checkbox button somewhere on the page and have an onChange element in the update code at the bottom like  change:reset  or would that cause undesireable results across the whole page and sheet workers? For your first question, I don't know what you mean by unnatural ability scores. That said, if the stat has a default vaklue (value="whataver") it will be used even if the player hasnt entered a manual value. For the reset button, the simplest way would be to have a list of all the default values, and set them again in setAttrs, and allow the effects of that to cascade out. You will have to do at least this. The sheet worker block has no inherent knowledge of anything in the sheet's html  - you have to tell te script block what to do.