If you want to streamline the sheet workers and remove some of the duplication, you could replace everything from line 1471 onwards with the code below (though it sounds like you've made your own changes to the weapon worker, so maybe the last worker needs tweaking). I had a couple hours spare, and couldn't help myself. If you don't want to use this, I won't be hurt *sniffle* There are some comments in the code to explain some things. feel free to ask questions. /* ability damage calcs */ const damages = { // an Object Literal: damages['stremgth'] returns 'damage', damages['empathy'] returns 'doubt', etc strength: 'damage', agility: 'fatigue', wits: 'confusion', empathy: 'doubt' }; Object.keys(damages).forEach(stat => { // creates a sheet worker for each stat in damages - first stat = 'strength', then stat = 'agility', etc // in each worker, stat = the stat (strength, agility, etc) and damages[stat] = the associated damage ('damage'. 'fatigue', etc) on(`change:${stat} change:${damages[stat]}`, function () { console.log(`${stat} or ${damages[stat]} has changed`); getAttrs([stat, damages[stat]], values => { const stat_score = parseInt(values[stat], 10)||0, damage_score = parseInt(values[damages[stat]], 10)||0; setAttrs({ [stat + '_total']: Math.max(0, stat_score - damage_score ) //Math.max returns the highest value from a comma separated list - it's just like roll20's kh1 dice function. // so you dont need the if( value > 0) test. With math.max, if the value is below 0, it becomes 0. }); }); }); });
/* skill total calcs */ const attributes = { // a javascript Object Literal, containing each skill, and its corresponding attribute 'Animal Handling': 'empathy_total', Crafting: 'strength_total', Endurance: 'strength_total', Healing: 'empathy_total', Insight: 'wits_total', Lore: 'wits_total', Manipulation: 'empathy_total', Marksmanship: 'agility_total', Melee: 'strength_total', Might: 'strength_total', Move: 'agility_total', Performance: 'empathy_total', Scouting: 'wits_total', 'Sleight Of Hand': 'agility_total', Stealth: 'agility_total', Survival: 'wits_total', }, getSkill = (label) => label.split(' ').join('_').toLowerCase(); // a function to change (for example) "Animal Handling" to "animal_handling" // needed for a couple of functions below
Object.keys(attributes).forEach(skill_name => { // creates a sheet worker for each skill in attributes - first skill = 'strength', then stat = 'agility', etc // in each worker, stat = the stat (strength, agility, etc) and damages[stat] = the associated damage ('damage'. 'fatigue', etc) const skill = getSkill(skill_name); on(`change:${skill} change:${attributes[skill_name]} sheet:opened`, function () { console.log(`${skill} or ${attributes[skill_name]} has changed`); getAttrs([skill, attributes[skill_name]], function(values) { const stat_score = parseInt(values[attributes[skill_name]], 10)||0, skill_score = parseInt(values[skill], 10)||0; setAttrs({ [skill + '_total']: stat_score + skill_score }); }); }); }); /* Wes's Dice Pool */ on("change:attribute", function () { getAttrs(['attribute'], function(values) { const pool = { //if you name the keys below to match the attributes on the character sheet, it makes setAttrs much simpler - see below. 0: {attribute_die_one: 0, attribute_die_two: 0, attribute_die_three: 0, attribute_die_four: 0, attribute_die_five: 0, attribute_die_six: 0}, 1: {attribute_die_one: 1, attribute_die_two: 0, attribute_die_three: 0, attribute_die_four: 0, attribute_die_five: 0, attribute_die_six: 0}, 2: {attribute_die_one: 1, attribute_die_two: 1, attribute_die_three: 0, attribute_die_four: 0, attribute_die_five: 0, attribute_die_six: 0}, 3: {attribute_die_one: 1, attribute_die_two: 1, attribute_die_three: 1, attribute_die_four: 0, attribute_die_five: 0, attribute_die_six: 0}, 4: {attribute_die_one: 1, attribute_die_two: 1, attribute_die_three: 1, attribute_die_four: 1, attribute_die_five: 0, attribute_die_six: 0}, 5: {attribute_die_one: 1, attribute_die_two: 1, attribute_die_three: 1, attribute_die_four: 1, attribute_die_five: 1, attribute_die_six: 0}, 6: {attribute_die_one: 1, attribute_die_two: 1, attribute_die_three: 1, attribute_die_four: 1, attribute_die_five: 1, attribute_die_six: 1} }; let attribute = values.attribute; if (!pool.hasOwnProperty( attribute )) { // I reversed the order from the example above for simplicity console.log("Error: The item " + pool + " is not found within the pool Object."); return; } setAttrs(pool[attribute]); }); });
on("change:skill", function () { getAttrs(['skill'], function(values) { const pool = { "-3": {negative_die_three: 1, negative_die_two: 1, negative_die_one: 1, skill_die_one: 0, skill_die_two: 0, skill_die_three: 0, skill_die_four: 0, skill_die_five: 0, skill_die_six: 0, skill_die_seven: 0}, "-2": {negative_die_three: 0, negative_die_two: 1, negative_die_one: 1, skill_die_one: 0, skill_die_two: 0, skill_die_three: 0, skill_die_four: 0, skill_die_five: 0, skill_die_six: 0, skill_die_seven: 0}, "-1": {negative_die_three: 0, negative_die_two: 0, negative_die_one: 1, skill_die_one: 0, skill_die_two: 0, skill_die_three: 0, skill_die_four: 0, skill_die_five: 0, skill_die_six: 0, skill_die_seven: 0}, 0: {negative_die_three: 0, negative_die_two: 0, negative_die_one: 0, skill_die_one: 0, skill_die_two: 0, skill_die_three: 0, skill_die_four: 0, skill_die_five: 0, skill_die_six: 0, skill_die_seven: 0}, 1: {negative_die_three: 0, negative_die_two: 0, negative_die_one: 0, skill_die_one: 1, skill_die_two: 0, skill_die_three: 0, skill_die_four: 0, skill_die_five: 0, skill_die_six: 0, skill_die_seven: 0}, 2: {negative_die_three: 0, negative_die_two: 0, negative_die_one: 0, skill_die_one: 1, skill_die_two: 1, skill_die_three: 0, skill_die_four: 0, skill_die_five: 0, skill_die_six: 0, skill_die_seven: 0}, 3: {negative_die_three: 0, negative_die_two: 0, negative_die_one: 0, skill_die_one: 1, skill_die_two: 1, skill_die_three: 1, skill_die_four: 0, skill_die_five: 0, skill_die_six: 0, skill_die_seven: 0}, 4: {negative_die_three: 0, negative_die_two: 0, negative_die_one: 0, skill_die_one: 1, skill_die_two: 1, skill_die_three: 1, skill_die_four: 1, skill_die_five: 0, skill_die_six: 0, skill_die_seven: 0}, 5: {negative_die_three: 0, negative_die_two: 0, negative_die_one: 0, skill_die_one: 1, skill_die_two: 1, skill_die_three: 1, skill_die_four: 1, skill_die_five: 1, skill_die_six: 0, skill_die_seven: 0}, 6: {negative_die_three: 0, negative_die_two: 0, negative_die_one: 0, skill_die_one: 1, skill_die_two: 1, skill_die_three: 1, skill_die_four: 1, skill_die_five: 1, skill_die_six: 1, skill_die_seven: 0}, 7: {negative_die_three: 0, negative_die_two: 0, negative_die_one: 0, skill_die_one: 1, skill_die_two: 1, skill_die_three: 1, skill_die_four: 1, skill_die_five: 1, skill_die_six: 1, skill_die_seven: 1} }; let skill = values.skill; if (!pool.hasOwnProperty( skill )) { // I reversed the order from the example above for simplicity console.log("Error: The item " + pool + " is not found within the pool Object."); return; } setAttrs(pool[skill]); }); });
on("change:gear", function () { getAttrs(['gear'], function(values) { const pool = { zero: {gear_die_one: 0, gear_die_two: 0, gear_die_three: 0, gear_die_four: 0, gear_die_five: 0, gear_die_six: 0, gear_die_seven: 0, gear_die_eight: 0, gear_die_nine: 0, gear_die_ten: 0, gear_die_eleven: 0, gear_die_twelve: 0}, one: {gear_die_one: 1, gear_die_two: 0, gear_die_three: 0, gear_die_four: 0, gear_die_five: 0, gear_die_six: 0, gear_die_seven: 0, gear_die_eight: 0, gear_die_nine: 0, gear_die_ten: 0, gear_die_eleven: 0, gear_die_twelve: 0}, two: {gear_die_one: 1, gear_die_two: 1, gear_die_three: 0, gear_die_four: 0, gear_die_five: 0, gear_die_six: 0, gear_die_seven: 0, gear_die_eight: 0, gear_die_nine: 0, gear_die_ten: 0, gear_die_eleven: 0, gear_die_twelve: 0}, three: {gear_die_one: 1, gear_die_two: 1, gear_die_three: 1, gear_die_four: 0, gear_die_five: 0, gear_die_six: 0, gear_die_seven: 0, gear_die_eight: 0, gear_die_nine: 0, gear_die_ten: 0, gear_die_eleven: 0, gear_die_twelve: 0}, four: {gear_die_one: 1, gear_die_two: 1, gear_die_three: 1, gear_die_four: 1, gear_die_five: 0, gear_die_six: 0, gear_die_seven: 0, gear_die_eight: 0, gear_die_nine: 0, gear_die_ten: 0, gear_die_eleven: 0, gear_die_twelve: 0}, five: {gear_die_one: 1, gear_die_two: 1, gear_die_three: 1, gear_die_four: 1, gear_die_five: 1, gear_die_six: 0, gear_die_seven: 0, gear_die_eight: 0, gear_die_nine: 0, gear_die_ten: 0, gear_die_eleven: 0, gear_die_twelve: 0}, six: {gear_die_one: 1, gear_die_two: 1, gear_die_three: 1, gear_die_four: 1, gear_die_five: 1, gear_die_six: 1, gear_die_seven: 0, gear_die_eight: 0, gear_die_nine: 0, gear_die_ten: 0, gear_die_eleven: 0, gear_die_twelve: 0}, seven: {gear_die_one: 1, gear_die_two: 1, gear_die_three: 1, gear_die_four: 1, gear_die_five: 1, gear_die_six: 1, gear_die_seven: 1, gear_die_eight: 0, gear_die_nine: 0, gear_die_ten: 0, gear_die_eleven: 0, gear_die_twelve: 0}, eight: {gear_die_one: 1, gear_die_two: 1, gear_die_three: 1, gear_die_four: 1, gear_die_five: 1, gear_die_six: 1, gear_die_seven: 1, gear_die_eight: 1, gear_die_nine: 0, gear_die_ten: 0, gear_die_eleven: 0, gear_die_twelve: 0}, nine: {gear_die_one: 1, gear_die_two: 1, gear_die_three: 1, gear_die_four: 1, gear_die_five: 1, gear_die_six: 1, gear_die_seven: 1, gear_die_eight: 1, gear_die_nine: 1, gear_die_ten: 0, gear_die_eleven: 0, gear_die_twelve: 0}, ten: {gear_die_one: 1, gear_die_two: 1, gear_die_three: 1, gear_die_four: 1, gear_die_five: 1, gear_die_six: 1, gear_die_seven: 1, gear_die_eight: 1, gear_die_nine: 1, gear_die_ten: 1, gear_die_eleven: 0, gear_die_twelve: 0}, eleven: {gear_die_one: 1, gear_die_two: 1, gear_die_three: 1, gear_die_four: 1, gear_die_five: 1, gear_die_six: 1, gear_die_seven: 1, gear_die_eight: 1, gear_die_nine: 1, gear_die_ten: 1, gear_die_eleven: 1, gear_die_twelve: 0}, twelve: {gear_die_one: 1, gear_die_two: 1, gear_die_three: 1, gear_die_four: 1, gear_die_five: 1, gear_die_six: 1, gear_die_seven: 1, gear_die_eight: 1, gear_die_nine: 1, gear_die_ten: 1, gear_die_eleven: 1, gear_die_twelve: 1} }; let gear = values.gear; if (!pool.hasOwnProperty( gear )) { // I reversed the order from the example above for simplicity console.log("Error: The item " + pool + " is not found within the pool Object."); return; } setAttrs(pool[gear]); }); });
on("clicked:dice_pool_crafting", () => dicePoolButtons('Crafting')); on("clicked:dice_pool_might", () => dicePoolButtons('Might')); on("clicked:dice_pool_endurance", () => dicePoolButtons('Endurance')); on("clicked:dice_pool_melee", () => dicePoolButtons('Melee')); on("clicked:dice_pool_stealth", () => dicePoolButtons('Stealth')); on("clicked:dice_pool_sleight_of_hand", () => dicePoolButtons('Sleight of Hand')); on("clicked:dice_pool_move", () => dicePoolButtons('Move')); on("clicked:dice_pool_marksmanship", () => dicePoolButtons('Marksmanship')); on("clicked:dice_pool_scouting", () => dicePoolButtons('Scouting')); on("clicked:dice_pool_lore", () => dicePoolButtons('Lore')); on("clicked:dice_pool_survival", () => dicePoolButtons('Survival')); on("clicked:dice_pool_insight", () => dicePoolButtons('Insight')); on("clicked:dice_pool_manipulation", () => dicePoolButtons('Manipulation')); on("clicked:dice_pool_performance", () => dicePoolButtons('Performance')); on("clicked:dice_pool_healing", () => dicePoolButtons('Healing')); on("clicked:dice_pool_animal_handling", () => dicePoolButtons('Animal Handling'));
const dicePoolButtons = (which) => { console.log(`Dice Pool ${which} - button clicked`); getAttrs([attributes[which], getSkill(which)], function (values) { // attributes[which] returns the attribute; e.g attributes['Stealth'] gives 'agility_total' // getSkill(which) converts the skill name to a valid attribute string: getSkill('Animal Handling') gives 'animal_handling' const stat = parseInt(values[attributes[which]], 10) || 0; // stat here first gets attributes['Stealth'] which will be, say, 'agility_total' and // then values['ability_total'] gives you the score from the character sheet. setAttrs({ attribute: stat > 0 ? stat : 0, // this is a Ternary Operator, it starts with a question (e.g. is stat > 0) // and if true, returns the bit after the ? and if false returns the bit after the : // you can often replace simple if/then expressions with a single line ternary operator. skill: parseInt(values[getSkill(which)], 10) || 0, current_preset: which }); }); }; /* end Dice Pool */
/* set weapon dice pool */ on("change:repeating_weapons:attack_roll", function() { console.log("Weapon - button clicked"); getAttrs(['attribute', 'skill', 'repeating_weapons_weapon_skill', 'repeating_weapons_weapon_name' ,'repeating_weapons_weapon_bonus', 'strength_total', 'agility_total', 'wits_total', 'empathy_total', 'marksmanship', 'melee'], function(values) { const weapon_skill = parseInt(values.repeating_weapons_weapon_skill,10)||0, weapon_bonus = parseInt(values.repeating_weapons_weapon_bonus,10)||0, weapon_name = values.repeating_weapons_weapon_name, attribute = (weapon_skill === 0 ? parseInt(values.strength_total,10)||0 : parseInt(values.agility_total,10)||0 ), skill = (weapon_skill === 0 ? parseInt(values.melee,10)||0 : parseInt(values.marksmanship,10)||0 ); setAttrs({ attribute: attribute, skill: skill, gear: weapon_bonus, current_preset: `Weapon Selected - ${weapon_name}` }); }); });