Finderski said: Here's a "simple" example for calculating things... Coal Powered Puppet said: So I have a single characteristic box with several inputs in it (say strength, dexterity, etc). I am setting up several other characteristic boxes with modifiers. When checkbox "A" is checked (and no others), only the modifiers of box "A" are used. But I also want to be able to add boxes "B" and "C". Activating an entire suite of modifiers with a single click, or turning them off. I was shown how to do this on another sheet, I think, but I can't remember which that was. Anyone got a clue how to do this? It would be easier if you used the actual names of attributes, it makes writing the code and giving explanations so much easier. When you use vague concepts, we have to guess what they might be, write code based on that guess work, then you have to look at the code and figure out how to adapt it back to what you need. Whereas if you used the actual attribute names and details, we could write the final code (while still explaining what it does), and you can just go and use it. Anyway, the basic principle is as follows: Before i start explaining, let me say that I use const and let in place of var , but if you aren't comfortable with those, just replace them both with var . They do the same job. Step 1: Create the Data Start by creating a data variable which contains all the attributes (their actual names on their sheet) and their values. For example, here's a hypothetical set of race modifiers: const modsbyrace = {
none: {strength_race_mod: 0, dexterity_race_mod: 0, intelligence_race_mod: 0, wisdom_race_mod: 0, charisma_race_mod: 0}, human: {strength_race_mod: 0, dexterity_race_mod: 0, intelligence_race_mod: 0, wisdom_race_mod: 0, charisma_race_mod: 0},
elf: {strength_race_mod: -1, dexterity_race_mod: 2, intelligence_race_mod: 2, wisdom_race_mod: -2, charisma_race_mod: 2},
halfling: {strength_race_mod: -4, dexterity_race_mod: 4, intelligence_race_mod: 0, wisdom_race_mod: 0, charisma_race_mod: 2},
}; Notice the structure here. You have a set of outer { } brackets. Then you have a name for each set of modifiers, a colon, then another set of { } inside of which you have all that attribute names you want to assign, with their values. Each of the inner {} sets ends with a comma. For best effects, the names for each data set (human, elf, halfling) should perfectly match the values in dropdown or whatever you are getting them from. Notice I have a "none" entry - it's a good idea with this approach to set up an entry for when the value isnt set. Also note that strength_race_mod, dexterity_race_mod , etc are the attribute names exactly as they appear on the sheet. You dont have to do this (sometimes you can't, like in a repeating section), but it makes the code much, much easier when you can, and that's what this example focuses on. Step 2: Set up the Input So lets say in the sheet we have a race selection dropdown that looks like this: <select name="attr_race"> <option value="none" selected>Choose a Race</option> <option value="human" >Human</option> <option value="elf">Elf</option> <option value="halfling">Halfling</option> </select> Notice one of the entries is selected : that makes the process easier. It doesnt matter which is selected, just make sure one is. With that set, you can avoid having to handle certain errors in the sheet worker. Step 3: The Magic Happens Now the part of the sheet worker that does the magic. on('change:race', function() { getAttrs(['race'], function(values) { const race = values.race; const updatemods = modsbyrace[race]; setattrs(updatemods); }); }); and there you have it. It's that simple. A Brief Aside to Explain How it Works The modsbyrace[race] part does the magic. You are looking in the modsbyrace data set, and picking the line that matches the race you want. You get a value like {strength_race_mod: 0, dexterity_race_mod: 0, intelligence_race_mod: 0, wisdom_race_mod: 0, charisma_race_mod: 0} Now I want you to think about what happens when use setAttrs with multiple attributes. You do something like this: setAttrs( { strength_race_mod: 0, dexterity_race_mod: 0, intelligence_race_mod: 0, wisdom_race_mod: 0, charisma_race_mod: 0 }); Now compare to the object you got from the modsbyrace object: they are identical if you ignore the linebreaks. And in javascript, linebreaks are optional. So the modsbyrace holds the data you need, in the perfect format to just send to setAttrs without further work. Thats why this technique is so powerful and simple. Using an Input instead of a Select Now, the version above is one you can use with a select , because you can make sure every option value in the select matches a name in the modsbyrace data. If you are using an input , where players might enter any words at all and you have to handle the possibility of data not matching, or you forget to include a selected option, you need to tweak it a bit. Something like: on('change:race', function() { getAttrs(['race'], function(values) { const race = values.race;
let updatemods = modsbyrace[race]' // set a default value first
if(modsbyrace.hasOwnProperty(race) {
// check if the race value actually exists in the data, and only if it does set the variable
updatemods = modsbyrace[race];
setattrs(updatemods);
}
});
}); And there you have it. Where to put the Data Final note: You can include the modsbyrace data set in the sheet worker, or before it. I left it out of the sheet worker just for clarity of explaining the worker itself. If its data you might use in different sheet workers, keep it outside the sheet worker. Otherwise, put it inside the sheet worker after the getAttrs line but before the rest of the code. I hope this is a decent explanation and you can adapt it to your purpose. If you need more help, post the code you are working with and I'll show you how to make it work.