swade-mb-shared/macros/warpgate_spells/boost-lower-warpgate.js
2022-04-20 23:43:00 -05:00

224 lines
7.4 KiB
JavaScript

const UPICON = 'icons/magic/life/cross-embers-glow-yellow-purple.webp'
const DOWNICON = 'icons/magic/movement/chevrons-down-yellow.webp'
let tokens = [];
let targets = Array.from(game.user.targets);
if (targets.length > 0) {
tokens = targets;
} else if (canvas.tokens.controlled.length > 0) {
tokens = canvas.tokens.controlled;
}
if (tokens.length > 0) {
main(tokens);
} else {
ui.notifications.error("Please select or target a token");
}
async function main(tokens) {
let traitOptions = [
"Agility",
"Smarts",
"Spirit",
"Strength",
"Vigor"
];
let allSkills = [];
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"
}
};
let tokenList = tokens.map(t => t.name).join(", ");
for (const 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]`
};
if (name != 'Unskilled' && !allSkills.find(v => v == name)) {
allSkills.push(name);
}
}
}
traitOptions = traitOptions.concat(allSkills.sort());
let menuOptions = {
title: 'Boost/Lower Trait',
defaultButton: "Cancel",
options: {}
};
let menuData = {
inputs: [
{type: 'header', label: 'Boost/Lower Trait'},
{type: 'info', label: `Affected Tokens: ${tokenList}`},
{type: 'select', label: 'Trait', options: traitOptions},
{type: 'info', label: "Boost or Lower?"},
{type: 'radio', label: 'Boost', options: ['boostlower', true]},
{type: 'radio', label: 'Lower', options: ['boostlower', false]},
],
buttons: [
{label: "Apply", value: "apply"},
{label: "Apply with raise", value: "raise"},
{label: "Cancel", value: "cancel"}
]
}
let {buttons, inputs} = await warpgate.menu(menuData, menuOptions);
if (buttons != "cancel") {
let trait = inputs[2];
let direction = inputs[4] || inputs[5];
createEffect(tokens, traits[trait], direction, buttons);
}
}
function getDottedPart(obj, key) {
let value = obj;
for (const part of key.split(".")) {
value = value[part];
}
return value;
}
async function createEffect(tokens, trait, direction, buttons) {
const raise = buttons;
const effectName = `${raise == 'raise' ? "Major" : "Minor"} ${direction} ${trait.name}`;
const effectId = `${raise == 'raise' ? "Major" : "Minor"}${direction}${trait.name}`;
const effectIcon = (direction == 'Boost' ? UPICON : DOWNICON)
for (const token of tokens) {
let tokenDoc = token.document;
let currentDie = 0;
let currentMod = 0;
if (trait.type == 'attribute') {
currentDie = getDottedPart(token.actor.data, trait.diekey);
currentMod = getDottedPart(token.actor.data, trait.modkey);
} else {
let skill = token.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;
} else {
currentDie = 4;
currentMod = -2;
}
}
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;
}
if (currentDie == 4 && currentMod == -2 && direction == "Boost") {
diemod = (raise ? 2 : 0);
modmod = 2;
}
let effectData = {
icon: effectIcon,
id: effectId,
label: effectName,
flags: {
swade: {
expiration: 3,
loseTurnOnHold: true
}
},
changes: []
};
let mode = foundry.CONST.ACTIVE_EFFECT_MODES.ADD;
if (diemod != 0) {
effectData.changes.push({key: trait.diekey, mode: mode, value: diemod, priority: 0});
}
if (modmod != 0) {
effectData.changes.push({key: trait.modkey, mode: mode, value: modmod, priority: 0});
}
if (direction == "Boost") {
effectData.duration = {rounds: 5};
}
let mutate = {
embedded: {
ActiveEffect: {
}
}
};
mutate.embedded.ActiveEffect[effectName] = effectData;
let mutateOptions = {
comparisonKeys: {'ActiveEffect': 'label'},
name: effectName,
permanent: false,
description: effectName,
}
if (trait.type == 'skill' && direction == 'Boost' && !token.actor.items.getName(trait.name)) {
let itemmutate = { embedded: { Item: {} } }
itemmutate.embedded.Item[trait.name] = {
"name": trait.name,
"type": "skill",
"img": "systems/swade/assets/icons/skills/uncertainty.svg",
"data": {
"description": "See SWADE. Auto added as untrained for Boost Trait.",
"notes": "",
"additionalStats": {},
"attribute": trait.attribute,
"isCoreSkill": false,
"die": {
"sides": 4,
"modifier": -2
},
"wild-die": {
"sides": 6
}
}
}
await warpgate.mutate(token.document, itemmutate, {}, mutateOptions);
}
mutateOptions.permanent = true;
await warpgate.mutate(token.document, mutate, {}, mutateOptions);
}
}