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

Sheetworker almost works...

1592968836

Edited 1592968859
Kraynic
Pro
Sheet Author
I am attempting to alter a sheetworker from my Palladium Fantasy sheet for use in the Heroes Unlimited sheet I am working on.  It uses the character's speed attribute, their number of attacks per melee, and calculates how far they can move for each melee action.  The wrinkle is that the characters in the sheet I am working on can have more than 1 hand to hand skill, and must choose which one they are using.  I already have a toggle to switch back and forth between the (currently) 2 hand to hand skill sections of the sheet for macro usage.  I am attempting to get this sheetworker to also adjust to the attacks/actions per round as the hand to hand skill is changed.  My current attempt looks like this: on("change:spd change:combatskill sheet:opened", function () { getAttrs(['spd','hth1_numberattacks', 'hth2_numberattacks', 'combatskill'], function (values) { const spd = parseInt(values['spd'])||0; const hth1_numberattacks = parseInt(values['hth1_numberattacks'])||0; const hth2_numberattacks = parseInt(values['hth2_numberattacks'])||0; let numberattacks = 1 if (combatskill = 1) numberattacks = hth1_numberattacks; else if (combatskill = 2) numberattacks = hth2_numberattacks; const modifier = Math.round((spd/numberattacks)*15); setAttrs({ run_attack: modifier }); }); }); spd = speed stat combatskill = radio button toggle which has a value of 1 or 2 corresponding to the hth number hth1_numberattacks = number of attacks/actions from Combat Skill 1 hth2_numberattacks = number of attacks/actions from Combat Skill 2 I'm sure there is some error in how I am structuring this because as it is, it will correctly display the correct calculation using hth1_numberattacks, but it doesn't change with the toggle.  On my first attempt, I left out the "else" and it always calculated based on hth2_numberattacks.  So I know it has all the attributes it needs and will calculate both ways, but I am doing something wrong in how I am asking it to change when the combatskill value changes. What am I doing wrong?
This may just be how you entered it into your post, but 1. You never retrieve 'combatskill' from the 'values' collection. You use undefined variable 'combatskill' instead. 2. To check for equality, you should use == or ===. The "if (combatskill = 1)" doesn't check if the value is equal to one, it sets the value to one.
1592970214
Finderski
Pro
Sheet Author
Compendium Curator
To add on to Primal Zed's first point, when you check values[combatskill] in the if statements, you may want to put quotes around them. It's been my experience that getAttrs always returns strings, so if you're checking equality you want to check against a string.  You might be able to get away with == without the quotes around the 1 and 2, but...I'd do it like this, just to be sure: if (values[combatskill] === "1") numberattacks = hth1_numberattacks; Not sure if curly braces are needed or not (I don't believe so--at least in this case, but I always use them).
1592970764
GiGs
Pro
Sheet Author
API Scripter
Finderski said: To add on to Primal Zed's first point, when you check values[combatskill] in the if statements, you may want to put quotes around them. It's been my experience that getAttrs always returns strings, so if you're checking equality you want to check against a string.  You might be able to get away with == without the quotes around the 1 and 2, but...I'd do it like this, just to be sure: if (values[combatskill] === "1") numberattacks = hth1_numberattacks; Not sure if curly braces are needed or not (I don't believe so--at least in this case, but I always use them). Using curly braces isnt needed if you're doing a single thing like above. But it's perfectly fine to always use them - some prefer to do that for consistency and readability. You're right, getAttrs does always return strings. I wouldnt put values in there though, I'd put in a variable first, and use parseInt to make sure its a number. For example: const combatskill = values[combatskill] || 1; if (combatskill === 1) numberattacks = hth1_numberattacks;
1592971217

Edited 1592971376
Kraynic
Pro
Sheet Author
Let me paste in what I have at the moment after removing combatskill from the values line and adding the structure around combatskill in the if lines.  I also realized I needed it to watch for changes in the 2 numberattack fields. on("change:spd change:combatskill sheet:opened change:hth1_numberattacks change:hth2_numberattacks", function () { getAttrs(['spd','hth1_numberattacks', 'hth2_numberattacks'], function (values) { const spd = parseInt(values['spd'])||0; const hth1_numberattacks = parseInt(values['hth1_numberattacks'])||0; const hth2_numberattacks = parseInt(values['hth2_numberattacks'])||0; let numberattacks = 1 if (values[combatskill] === "1") numberattacks = hth1_numberattacks; else if (values[combatskill] === "2") numberattacks = hth2_numberattacks; const modifier = Math.round((spd/numberattacks)*15); setAttrs({ run_attack: modifier }); }); }); It no longer calculates in this version, so I must be misunderstanding something you are trying to tell me.  Edit: And I'm off to bed.  I'll hopefully have time to tinker some more on this tomorrow after work.
1592971354
GiGs
Pro
Sheet Author
API Scripter
Primal Zed has pointed out the reasons the worker isnt working. But I'd also add a couple of events to the on(change) line. If numberofattacks 1 or 2 change, it might be enough to an increase in the modifier - but you wont see that on the sheet, because the worker wont detect the change.   on("change:spd change:combatskill change: hth1_numberattacks change:hth2_numberattacks sheet:opened", function () { getAttrs(['spd','hth1_numberattacks', 'hth2_numberattacks', 'combatskill'], function (values) { const spd = parseInt(values['spd'])||0; const hth1_numberattacks = parseInt(values['hth1_numberattacks'])||0; const hth2_numberattacks = parseInt(values['hth2_numberattacks'])||0;         const combatskill = parseInt(values[combatskill]) || 1; let numberattacks = 1; if (combatskill === 1) numberattacks = hth1_numberattacks; else if (combatskill === 2) numberattacks = hth2_numberattacks; const modifier = Math.round((spd/numberattacks)*15); setAttrs({ run_attack: modifier }); }); }); If your combatskill attribite is set up so that it always has one of 2 values, 1 or 2, you can streamline the above code: on("change:spd change:combatskill change:hth1_numberattacks change:hth2_numberattacks sheet:opened", function () { getAttrs(['spd','hth1_numberattacks', 'hth2_numberattacks', 'combatskill'], function (values) { const spd = parseInt(values['spd'])||0;         const combatskill = parseInt(values[combatskill]) || 1; const numberattacks = parseInt(values['hth' + combatskill + '_numberattacks']) || 1; const modifier = Math.round((spd/numberattacks)*15); setAttrs({ run_attack: modifier }); }); });
1592971454
Kraynic
Pro
Sheet Author
I didn't even think of trying to make it like the other snippet you wrote.  It is using the same toggle...  I'll give that a try tomorrow.
1592971773

Edited 1592971845
GiGs
Pro
Sheet Author
API Scripter
I didnt see your earlier post. The reason that one wasnt working is most likely because you forgot to include combatskill in getAttrs.
1593043586
Kraynic
Pro
Sheet Author
It isn't working for me, and I am getting the following error in the console: ReferenceError: can't access lexical declaration `combatskill' before initialization There are a couple other lines that I'm not sure are worth posting, but I can if need be.  I get this error with either one of those versions of the sheetworker.
1593044013
GiGs
Pro
Sheet Author
API Scripter
Oops, its missing quotes. This  const combatskill = parseInt(values[combatskill]) || 1; should be either  const combatskill = parseInt(values['combatskill']) || 1; or  const combatskill = parseInt(values.combatskill) || 1; Either one is fine.
1593046143
Kraynic
Pro
Sheet Author
I used the first option, since it matches how everything else is set up (now that I notice the quotes). It works!  Thanks for the help.
1593046526
GiGs
Pro
Sheet Author
API Scripter
You're welcome :) For reference the difference between the two methods: The second is the default usage. It's the simpler syntax and is most common. But the other is necessary when the name is being constructed within the worker, or contains characters not allowed in javascript variable names (like a dash). Take this line: const numberattacks = parseInt(values['hth' + combatskill + '_numberattacks']) || 1; You can't do that with the dot syntax, you need the brackets to enclose the construction of the name. Likewise if we'd built that into a variable like this: const attackname = 'hth' + combatskill + '_numberattacks'; const numberattacks = parseInt(values[attackname]) || 1; You need to use the brackets there.