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

Having issue with simplest Sheetworker script

1483063267
GiGs
Pro
Sheet Author
API Scripter
I have the following script that is not doing anything as far as I can see: <script type="text/worker"> on("change:merciful", function() {    getAttrs(["Merciful"], function(values) {       setAttrs({           Cruel: 20-Merciful;       });    }); }); </script> For explanation, Merciful and Cruel are two attributes defined in the html like this: <input class='sheet-traits sheet-carac2' type="number" name="attr_Merciful" value="10" /> <input class='sheet-traits-right sheet-carac2' type="number" name="attr_Cruel" value="10"  /> I am totally stumped. i have tried copying sheetworkers from roll20 character sheets that manipulate numbers, and I just cant get them to do anything. Where am I going wrong?
1483064642

Edited 1483064678
Corin S.
Sheet Author
Well, there are two things I can see off of the bat: While it might not actually be breaking the code, the semi-colon after 20-Merciful isn't necessary, and Probably more importantly, getAttrs returns one object, in your case called "values", which has the requested attributes as properties. In other words, the variable isn't "Merciful", but "values.Merciful". So I'd write the script as: <script type="text/worker"> on("change:merciful", function() {    getAttrs(["Merciful"], function(values) {       setAttrs({           Cruel: 20-values.Merciful       });    }); }); </script>
1483068797

Edited 1483069380
GiGs
Pro
Sheet Author
API Scripter
Thank you, that was it! I'm going to have 26 separate identical macros like the one above. How do I change it to a single macro with variables? There are 26 traits in 13 pairs, and each pair adds up to 20. Chaste / Lustful, Forgiving / Vengeful, Merciful / Modest, and so on. How do i define these pairs, so that if a change in one trait occurs, the above macro runs and applies to the other trait in the pair? I have tried variations of this. I think where I'm going wrong is inside the setAttrs fucntion, I'm not sure how to access the attribute by a variable name. function adjustTraits(virtue,vice) {    getAttrs([virtue,vice], function(v) {        var curVirtue = parseInt(v.virtue);        if (curVirtue > 0) {             var newVice = Math.max(20-v.virtue,0);             setAttrs( {                v.vice: newVice              });         }    });  } on("change:merciful", adjustTraits("Merciful","Cruel")); on("change:cruel", adjustTraits("Cruel","Merciful")); on("change:chaste", adjustTraits("Chaste","Lustful")); on("change:lustful", adjustTraits("Lustful","Chaste"));
1483077311
Lithl
Pro
Sheet Author
API Scripter
The second parameter to on() needs to be a function reference. In your code above, you're calling  adjustTraits(), meaning the value given to on() is the return value of adjustTraits(), which is currently undefined. You can, of course, use a function reference as the return value of a function in JavaScript, which is what you'd need to do for a construction like this. Also important, v.virtue  will look for the property "virtue", while v[virtue]  will look for the property with the value of the virtue  variable (eg, "Merciful"). Similarly, you cannot use "v.vice" as a property in an object literal (and in this case you don't want to, because v[vice] would be a number, and you want the name of the vice attribute, not the value of the vice attribute). Here's an example: function adjustTraits(virtue, vice) { return function() { getAttrs([virtue, vice], function(values) { var curVirtue = parseInt(values[virtue]), attrs = {}; if (curVirtue > 0) { attrs[vice] = Math.max(20 - curVirtue, 0); setAttrs(attrs); } }); }; } on('change:merciful', adjustTraits('Mericful', 'Cruel')); on('change:cruel', adjustTraits('Cruel', 'Merciful')); on('change:chaste', adjustTraits('Chaste', 'Lustful')); // etc. Notice the attrs object instead of the object literal in setAttrs; this lets you use variables for the property names of the attributes object.
1483078445
GiGs
Pro
Sheet Author
API Scripter
Thank you! I was at my wits end. It works perfectly. Thanks for the explanation too, I'm getting a bit closer to understanding how these things work.