The easiest way is the sheetworker approach, though it'll look very confusing at first. At the very bottom of the html sheet, add the following: <script type="text/worker">
</script>
Any scripts you add, like the one I'm about to suggest go between that script block. If your sheet already has a script block like this, don't create a new one, add any scripts inside the same block. So, for a sheetworker to work, it needs several things: First it needs a block like this: on("change:myattribute", function() {
}); This tells roll20: on a change to this attribute, perform this function. So we need to fill in the function. One of the complications of working with roll20, is that the script engine doesnt know the attribute values automatically, It may detect that an attribute has changed , but it doesnt know what the attribute value is , so we need to set that up. on("change:myattribute", function() {
getAttrs(["MyAttribute"], function(values) {
let myStat = values.MyAttribute;
});
});
Now things look a bit more complicated, but if you use sheet workers a lot, this basic framework will start to look very familiar. getAttrs is a function that creates the named attribute as an object. Then the let myStat statement extracts the value of that object in a form you can actually use. You don't need to worry about why it works like this, just follow this pattern and it works. If you're eagle-eyed, you may notice the on(change) line and the others are not using the same case. I wanted to point out that event calls (like the on(change) must always use lower case, even if the attribute name is not in lower case. But for the rest of the function ,you use the case of the attribute as defined in the character sheet. You can avoid having to worry about this, by always making your attribute names lower case! So, imagine you have a dropdown attribute named affinity , which has the entries "Fire", "Water", etc. When the user changes the affinity, you want several stats to be updated, lets call them hitmod , damagemod , critmod . on("change:affinity", function () {
getAttrs(["affinity"], function (values) {
//initialize variables
let affinity = values.affinity;
let critmod = 0;
let hitmod = 0;
let damagemod = 0;
// depending on affinity value, change other stats values.
switch (affinity) {
case "Fire":
critmod = 1;
hitmod = 1;
damagemod = 1;
break;
case "Earth":
critmod = 2;
hitmod = 2;
damagemod = 2;
break;
case "Ice":
critmod = 3;
hitmod = 3;
damagemod = 3;
break;
case "Wind":
critmod = 4;
hitmod = 4;
damagemod = 4;
break;
}
});
});
There's a lot going on in this, but to explain the new elements: since you want to have several stats affected, you need to create a new variable to hold each one's value. Then the switch statement allows you to modify the various stats, based on the value of the affinity. It basically says, "When affinity is Wind, do this", etc. When affinity is Wind, everything between the Case "Wind" and the break statement is carried out. (break tells the script to leave the switch block). Note that I havent looked at the table to get those values, you should be able to enter the correct values yourself. You should be able to add the extra blocks, too, for the other affinities. So at this point you have code which will detect when the affinity attribute changes, and set up variables for the stats you want altered. You now need to save them to the character sheet. This is the final step - see the setAttrs block in the following on("change:affinity", function () {
getAttrs(["affinity"], function (values) {
let affinity = values.affinity;
let critmod = 0,
hitmod = 0,
damagemod = 0;
switch (affinity) {
case "Fire":
critmod = 1;
hitmod = 1;
damagemod = 1;
break;
case "Earth":
critmod = 2;
hitmod = 2;
damagemod = 2;
break;
case "ice":
critmod = 3;
hitmod = 3;
damagemod = 3;
break;
case "Wind":
critmod = 4;
hitmod = 4;
damagemod = 4;
break;
}
setAttrs({
"critMod": critmod,
"damageMod": damagemod,
"hitMod": hitmod
})
});
});
I've made a couple of assumptions here: first, your character sheet has three attributes: hitMod, damageMod, and critMod. setAttrs saves the variables we created earlier into those stats. Note: in the setAttrs function, each line must end with a comma, except the last one which must not. Now, when you make an attack macro, you can use those stats in then normal way (e.g. @{attackMod}), can use autocalc fields to add them to attributes on the sheet, or add extra sheet workers to use them in various ways. Hopefully this gets you started.