const ICON = 'icons/creatures/magical/humanoid-silhouette-glowing-pink.webp'; const ACTORFOLDER = "Shape Change"; const PHYSICAL_SKILLS = [ "Athletics", "Boating", "Driving", "Fighting", "Piloting", "Riding", "Shooting", "Stealth", "Thievery" ] 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[0]); } else { ui.notifications.error("Please select or target a token"); } async function main(token) { let tokenList = token.name; let folder = game.folders.find(f => f.data.type == 'Actor' && f.data.name == ACTORFOLDER) let menuOptions = { title: "Shape Change", defaultButton: "cancel", options: {} } let menuData = { inputs: [ { type: 'header', label: 'Shape Change' }, { type: 'info', label: `pick a new form for ${tokenList}` }, { type: 'select', label: "Form", options: folder.contents.map(a => a.data.name) }, ], buttons: [ { label: "Apply", value: "apply" }, { label: "Apply with Raise", value: "raise" }, { label: "Cancel", value: "cancel" } ] } let {buttons, inputs} = await warpgate.menu(menuData, menuOptions); let shapeData = { raise: (buttons == "raise"), actorName: (inputs[2]), } shapeData.actor = folder.contents.find(a => a.data.name == shapeData.actorName); shapeData.icon = shapeData.actor.data.token.img; if (buttons && buttons != 'cancel') { doWork(shapeData, token); } } async function doWork(shapeData, token) { let effectData = { icon: ICON, id: "shapechange", label: "Shape Change", duration: { rounds: 5 }, flags: { swade: { expiration: 3, loseTurnOnHold: true } }, changes: [ { key: 'data.attributes.strength.die.sides', mode: foundry.CONST.ACTIVE_EFFECT_MODES.UPGRADE, value: 0, priority: 0 }, { key: 'data.attributes.strength.die.modifier', mode: foundry.CONST.ACTIVE_EFFECT_MODES.UPGRADE, value: 0, priority: 0 }, { key: 'data.attributes.vigor.die.sides', mode: foundry.CONST.ACTIVE_EFFECT_MODES.UPGRADE, value: 0, priority: 0 }, { key: 'data.attributes.vigor.die.modifier', mode: foundry.CONST.ACTIVE_EFFECT_MODES.UPGRADE, value: 0, priority: 0 }, ] }; if (shapeData.raise) { effectData.label = "Hardier Shape Change" let str = shapeData.actor.data.data.attributes.strength.die; let vig = shapeData.actor.data.data.attributes.vigor.die; if (str == 12) { effectData.changes[1].value = 1 } else { effectData.changes[0].value = 2 } if (vig == 12) { effectData.changes[3].value = 1 } else { effectData.changes[2].value = 2 } } let mutateOptions = { comparisonKeys: { 'ActiveEffect': 'label' }, name: `Shape Change (${shapeData.actor.data.name})`, permanent: false, description: "Shape Change", } let shapeActor = shapeData.actor; let shapeToken = shapeActor.data.token; let mutate = { actor: { data: { attributes: { agility: {die: {...shapeActor.data.data.attributes.agility.die}}, strength: {die: {...shapeActor.data.data.attributes.strength.die}}, vigor: {die: {...shapeActor.data.data.attributes.vigor.die}}, }, stats: { speed: shapeActor.data.data.stats.speed, size: shapeActor.data.data.stats.size, scale: shapeActor.data.data.stats.scale, } } }, token: { width: shapeToken.width, height: shapeToken.height, scale: shapeToken.scale, img: shapeToken.img, }, embedded: { ActiveEffect: { [effectData.label]: effectData }, Item: { } } } for (let item of token.actor.items.filter(i => ['weapon', 'armor'].indexOf(i.data.type) > -1)) { mutate.embedded.Item[item.data.name] = warpgate.CONST.DELETE } for (let item of token.actor.items.filter(i => i.data.type == 'ability')) { if (!shapeData.actor.items.find(i => i.data.name == item.data.name && i.data.type == item.data.type)) { mutate.embedded.Item[item.data.name] = warpgate.CONST.DELETE } } for (let item of shapeData.actor.items.filter( i => i.data.type == 'skill' && PHYSICAL_SKILLS.indexOf(i.data.name > -1)) ) { mutate.embedded.Item[item.data.name] = { img: item.data.img, name: item.data.name, type: item.data.type, data: { description: item.data.data.description, die: item.data.data.die, notes: item.data.data.notes, "wild-die": item.data.data["wild-die"], } } } for (let item of shapeData.actor.items.filter(i => i.data.type == 'ability')) { mutate.embedded.Item[item.data.name] = item.data; } shapeData.actor.effects.forEach(effect => { mutate.embedded.ActiveEffect[effect.data.label] = effect.data }) console.log(mutate) await warpgate.mutate(token.document, mutate, {}, mutateOptions); }