const version = 'v2.0'; const UPICON = "icons/magic/life/cross-embers-glow-yellow-purple.webp"; const DOWNICON = "icons/magic/movement/chevrons-down-yellow.webp"; if ( canvas.tokens.controlled[0]===undefined && Array.from(game.user.targets)[0]===undefined ) { ui.notifications.error("Please, select or target a token."); // No Token is Selected } else { main(); } async function main() { let tokens = []; tokens = tokens.concat(Array.from(game.user.targets)); tokens = tokens.concat(canvas.tokens.controlled); let groups = { "Attributes": [ "Agility", "Smarts", "Spirit", "Strength", "Vigor" ], "Skills": [], } let traits = { "Agility": { type: "attribute", name: "Agility", modkey: "data.attributes.agility.die.modifier", diekey: "data.attributes.agility.die.sides" }, "Smarts": { type: "attribute", name: "Smarts", modkey: "data.attributes.smarts.die.modifier", diekey: "data.attributes.smarts.die.sides" }, "Spirit": { type: "attribute", name: "Spirit", modkey: "data.attributes.spirit.die.modifier", diekey: "data.attributes.spirit.die.sides" }, "Strength": { type: "attribute", name: "Strength", modkey: "data.attributes.strength.die.modifier", diekey: "data.attributes.strength.die.sides" }, "Vigor": { type: "attribute", name: "Vigor", modkey: "data.attributes.vigor.die.modifier", diekey: "data.attributes.vigor.die.sides" } }; for (var token of tokens) { let skills = token.actor.items.filter(e => e.type == "skill"); for (const skill of skills) { let name = skill.data.name; traits[name] = { type: "skill", name: name, modkey: `@Skill{${name}}[data.die.modifier]`, diekey: `@Skill{${name}}[data.die.sides]` }; groups.Skills.push(name) } } var traitoptions = ``; var applyChanges = false; var raise = false; new Dialog({ title: `Boost/Lower Trait - ${version}`, content: `
Which Trait?
Boost or Lower?
${traitoptions}

`, buttons: { apply: { label: "Apply", callback: () => { applyChanges = true; raise } }, raise: { label: "Apply with raise", callback: () => { applyChanges = true; raise = true } }, cancel: { label: "Cancel" } }, default: "apply", close: html => { if (applyChanges) { let direction = html.find('[name="select-direction"]')[0].value; let trait = html.find('[name="select-trait"]')[0].value; createEffect(tokens, traits, direction, trait, raise); } } }).render(true); } // end main async function createEffect(tokens, traits, direction, trait, raise) { trait = traits[trait]; for (var tokenD of tokens) { let currentdie = 0; let currentmod = 0; if (trait["type"] == "attribute") { var part; let value = tokenD.actor.data; for (part of trait["diekey"].split(".")) { value = value[part]; } currentdie = value value = tokenD.actor.data for (part of trait["modkey"].split(".")) { value = value[part]; } currentmod = value; } else { let skill = tokenD.actor.items.filter(s => s.type == "skill").find(s => s.data.name == trait["name"]) if (skill) { currentdie = skill.data.data.die.sides; currentmod = skill.data.data.die.modifier; } } if (currentdie == 0) { continue; } if (currentdie == 4 && direction == "Lower") { continue; } let diemod = 2; let modmod = 0; if (direction == "Lower") { diemod = -2; } if (currentdie == 6 && direction == "Lower" && raise) { diemod = -1; } else if (currentdie == 12 && direction == "Boost") { diemod = 0; modmod = 1; } if (raise) { diemod *= 2; modmod *= 2; } if (currentdie == 10 && direction == "Boost" && raise) { diemod = 2; modmod = 1; } var effectData = { label: `${direction} ${trait.name}${raise ? " with raise" : ""}`, id: `${direction}${trait.name}${raise ? "raise" : ""}`, icon: direction == "Lower" ? DOWNICON : UPICON, changes: [{ "key": trait["diekey"], "mode": 2, "value": diemod, "priority": 0 },{ "key": trait["modkey"], "mode": 2, "value": modmod, "priority": 0 }] }; if (direction == "Boost") { effectData["duration"] = {rounds: 5} } let spellEffect = game.macros.getName("ApplySpellEffect"); spellEffect.execute(effectData, [tokenD]) } }