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

Text/worker help again

so can someone help me understand what i have done wrong? im trying to set the script to change a value when one of two values change, thought i was setting it up right but i guess not. i want it to change it the armor type changes and if the dex mod (dex_ac) changes. But it will only change when the armor changes. Any help would be welcome. <script type="text/worker"><!-- Armor Value --> on('change:Armor change:dex_ac' function() { getAttrs(['Armor','dex_ac','con_ac','int_ac','wis_ac'], function(values) { const Armor = parseInt(values.Armor) || 00; const dex = parseInt(values.dex_ac); const con = parseInt(values.con_ac); const wis = parseInt(values.wis_ac); const ini = parseInt(values.int_ac); let ac1 = 10; if (Armor == 00) {ac1 = 10 + dex;} else if (Armor == 01) {ac1 = 11 + dex;} else if (Armor == 02) {ac1 = 12 + dex;} else if (Armor == 03) {ac1 = 13 + dex;} else if (Armor == 04) {ac1 = 14 + dex;} else if (Armor == 05) {ac1 = 15 + dex;} else if (Armor == 06) {ac1 = 16;} else if (Armor == 07) {ac1 = 17;} else if (Armor == 08) {ac1 = 18;} else if (Armor == 09) {ac1 = 13 + ini;} else if (Armor == 10) {ac1 = 10+ dex + con;} else if (Armor == 11) {ac1 = 13 + wis;} setAttrs({ ac1: ac1 }); }); }); </script>
1691678602
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
A couple things. The listener (the on() ) requires that everything be in lowercase. This is one reason why using an all lowercase casing system like snake_case is recommended. There's also a syntax error in your listener. You are missing the comma between the listener strong and the callback function. It should be this: on('change:Armor change:dex_ac' , function() { In JavaScript, numbers do not have a leading zero. I'm not actually sure how that'd be parsed, but I'd recommend changing things like 00 to just 0.
1691682264

Edited 1691684142
GiGs
Pro
Sheet Author
API Scripter
A thing about attribute case in roll20: it's a mess. You always have to use lower case on that first line (that starts with on( ). But the case you must use for the rest of the worker is set by whatever you declare in the getAttrs. So let's say you have an input like this: <input type="number" name="attr_aRmOuR" value="0"> Now roll20 macros don't care about case, you you could use @{Armour}, @{armour}, @{ARMOUR}. As long as the spelling is correct. it will find that attribute. However in sheet workers, there are two different situations. The on( line must be all lower case, so you must use on('change:armour , not on('change:aRmOuR , or on('change:AMOUR , even though they'll work with macros. The complication (and this really causes a lot of confusion, it has to be a bug)  is that if you use a case that matches the original attribute (here aRmOr), it might appear to work at first. But it won't work consistentely. At some point, it will stop working. If you use all lower case, it will always work . And then in the getAttrs, you can use any case, but you must use that consistently from then on. So with the same attribute, so you could do getAttrs(['ARMOUR' , getAttrs(['armour' , or even getAttrs(['aRmOuR' . But once you use that you have committed it. You have essentially set the attribute to have that spelling. If you use getAttrs(['armour' ,then these will all fail: const Armor = parseInt(values.Armour) || 0; const Armor = parseInt(values.ARMOUR) || 0; const Armor = parseInt(values.ArMoUr) || 0; These will all fail, even though that last one is the case you used when creating that attribute. The only one that will work is the one you defined in the getAttrs: const Armor = parseInt(values.armour) || 0; There are explanations why it works this way, but it is still irritating.
1691696908

Edited 1691696984
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Agreed with everything GiGs said, except I'd simplify it down to just "use lower case everywhere". And, now that I'm back at my computere, I can also post a code critique I noticed this morning while I was on my phone. While your if chain will certainly work, it's a lot extra code and logic for your sheetworker to go through. A more streamlined approach would be to use an array to look up the value: on('change:Armor change:dex_ac' function () { getAttrs(['Armor', 'dex_ac', 'con_ac', 'int_ac', 'wis_ac'], function (values) { const Armor = parseInt(values.Armor) || 0; const dex = parseInt(values.dex_ac) || 0; const con = parseInt(values.con_ac) || 0; const wis = parseInt(values.wis_ac) || 0; const ini = parseInt(values.int_ac) || 0; // I also added some additional type and parse guarding into your code const modArray = [ 10 + dex, 11 + dex, 12 + dex, 13 + dex, 14 + dex, 15 + dex, 16, 17, 18, 13 + ini, 10 + dex + con, 13 + wis ]; // An empty object for us to store our changes in // overkill in this instance, but a good habit to get into const setObj = {}; setObj.ac1 = modArray[Armor] || 10; // While this doesn't seem like less code, // it is less logic for the computer to process // this means it will be faster // additionally, this is a little easier to maintain than a long chain of ifs, or a switch // with lots of cases setAttrs(setObj); }); });
1691699822

Edited 1691706033
GiGs
Pro
Sheet Author
API Scripter
Scott C. said: Agreed with everything GiGs said, except I'd simplify it down to just "use lower case everywhere". I think that's good edvice.all lower-case is just so much more convenient and solves problems without ever having to think about them. I was also going to talk about that if statement, but got distracted and ran out of time :) (see my last post for the distraction!) I'm very happy you came back to it.