const GROWTHICON = 'icons/magic/control/silhouette-grow-shrink-blue.webp' const SHRINKICON = 'icons/magic/control/silhouette-grow-shrink-tan.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 tokenList = tokens.map(t => t.name).join(", "); let menuOptions = { title: 'Growth/Shrink', defaultButton: "Cancel", options: {} }; let menuData = { inputs: [ { type: 'header', label: 'Growth/Shrink' }, { type: 'info', label: `Affected Tokens: ${tokenList}` }, { type: 'number', label: 'Number of steps (2pp ea)' }, { type: 'info', label: "Grow or Shrink" }, { type: 'radio', label: 'Growth', options: ['isspeed', true] }, { type: 'radio', label: 'Shrink', options: ['isspeed', false] }, ], buttons: [ { label: "Apply", value: "apply" }, { label: "Cancel", value: "cancel" } ] } let { buttons, inputs } = await warpgate.menu(menuData, menuOptions); if (buttons && buttons != "cancel") { let direction = inputs[4] || inputs[5]; let steps = inputs[2]; createEffect(tokens, steps, direction, buttons); } } async function createEffect(tokens, steps, direction, buttons) { const effectName = direction const effectId = direction const effectIcon = (direction == "Growth" ? GROWTHICON : SHRINKICON) for (const token of tokens) { let tokenDoc = token.document; let mode = foundry.CONST.ACTIVE_EFFECT_MODES.ADD; let effectData = { icon: effectIcon, id: effectId, label: effectName, duration: {rounds: 5}, flags: { swade: { expiration: 3, loseTurnOnHold: true } }, changes: [] }; let strDie = token.actor.data.data.attributes.strength.die.sides; let size = token.actor.data.data.stats.size; let strDieChange = 0; let strModChange = 0; let sizeChange = 0; if (direction == "Growth") { strDieChange = 2 * steps; sizeChange = steps; while (strDie + strDieChange > 12) { strDieChange -= 2; strModChange += 1; } } else { let stepCount = steps; while (size + sizeChange > -2 && stepCount > 0) { stepCount -= 1; strDieChange -= 2; sizeChange -= 1; } if (strDie + strDieChange < 4) { strDieChange = (4 - strDie); } } effectData.changes.push( { key: 'data.stats.size', mode: mode, value: sizeChange } ) effectData.changes.push( { key: 'data.attributes.strength.die.sides', mode: mode, value: strDieChange, } ) effectData.changes.push( { key: 'data.attributes.strength.die.modifier', mode: mode, value: strModChange } ) size += sizeChange; let scale = 0; let height = 1; let width = 1; switch (size) { case -2: scale = 0.6; break; case -1: scale = 0.8; break case 0: break; case 1: scale = 1.2; break; case 2: scale = 1.5; break; case 3: scale = 2; break; case 4: height = 2; width = 2; scale = 1; break; case 5: height = 2; width = 2; scale = 1.2; break; case 6: height = 2; width = 2; scale = 1.5; break; case 7: height = 2; width = 2; scale = 1.5; break; case 8: height = 3; width = 3; scale = 1; break; case 9: height = 3; width = 3; scale = 1.2; break; case 10: height = 3; width = 3; scale = 1.4; break; case 11: height = 3; width = 3; scale = 1.6; break; } if (size < -2) { scale = 0.5; } else if (size > 11) { scale = 1 height = 4 width = 4 } let tempMutate = { token: { scale: scale, height: height, width: width } } let mutate = { embedded: { ActiveEffect: { } } }; mutate.embedded.ActiveEffect[effectName] = effectData; let mutateOptions = { comparisonKeys: { 'ActiveEffect': 'label' }, name: effectName, description: effectName, } await warpgate.mutate(token.document, tempMutate, {}, mutateOptions); mutateOptions.permanent = true; await warpgate.mutate(token.document, mutate, {}, mutateOptions); } }