const ICON = 'icons/magic/symbols/circle-ouroboros.webp'; const ACTORFOLDER = "Summon Ally"; 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: "Summon Ally", defaultButton: "cancel", options: {} } let menuData = { inputs: [ { type: 'header', label: 'Summon Ally' }, { type: 'info', label: `${tokenList} is summoning an ally` }, { type: 'info', label: `
RankCostServant
Novice2Attendant
Seasoned4Bodyguard
Veteran6*Mirror Self*
Heroic8Sentinel
` }, { type: 'select', label: "Ally to summon", options: folder.contents.map(a => a.data.name) }, { type: 'number', label: 'Number to spawn (+half total cost per addtl.)', options: 1 }, { type: 'checkbox', label: 'Bite/Claw (+1)', options: false } ], buttons: [ { label: "Apply", value: "apply" }, { label: "Apply with Raise", value: "raise" }, { label: "Cancel", value: "cancel" } ] } let {buttons, inputs} = await warpgate.menu(menuData, menuOptions); let summonData = { raise: (buttons == "raise"), actorName: (inputs[3]), number: inputs[4], addBiteClaw: inputs[5], } summonData.actor = folder.contents.find(a => a.data.name == summonData.actorName); summonData.icon = summonData.actor.data.token.img; doWork(summonData, token); } async function doWork(summonData, token) { console.log("Summon Ally", token, summonData); let effectData = { icon: ICON, id: "summonally", label: "Summoned Ally", duration: { rounds: 5 }, flags: { swade: { expiration: 3, loseTurnOnHold: true } }, changes: [], }; let mutateOptions = { comparisonKeys: { 'ActiveEffect': 'label' }, name: "Summoned Ally", permanent: true, description: "Summoned Ally", } let mutate = { embedded: { ActiveEffect: { "Summoned Ally": effectData, } } }; await warpgate.mutate(token.document, mutate, {}, mutateOptions); let spawnOptions = { controllingActor: token.actor, duplicates: summonData.number, comparisonKeys: {'ActiveEffect': 'label'}, crosshairs: { size: 1, icon: summonData.icon, label: `Summon ${summonData.actorName}`, drawOutline: false, rememberControlled: true } } let mutateData = { token: { actorLink: false, name: `${token.name}'s ${summonData.actor.data.token.name}`, }, embedded: { Item: {} } } if (summonData.raise) { mutateData.embedded.Item.Resilient = { "name": "Resilient", "type": "ability", "img": "systems/swade/assets/icons/ability.svg", "data": { "description": "
\n

Some creatures, such as ogres or dire versions of common animals on Golarion, are tough to put down.

\n

Resilient Extras can take one @Compendium[swpf-core-rules.swpf-rules.Wounds]{Wound} before they’re @Compendium[swpf-core-rules.swpf-rules.Incapacitation]{Incapacitated}, Very Resilient Extras can take two. @Compendium[swpf-core-rules.swpf-rules.Wild Cards and Extras]{Wild Cards} can’t be Resilient or Very Resilient. The abilities exist to bring select Extras a little closer to the heroes and villains who lead them.

\n
", "notes": "", "additionalStats": {}, "subtype": "special", "grantsPowers": false }, "effects": {}, "flags": { "core": { "sourceId": "Compendium.swpf-core-rules.swpf-abilities.kiu5yk2aQkUGwlHN" }, } } } if (summonData.addBiteClaw) { mutateData.embedded.Item["Bite/Claw"] = { "name": "Bite/Claw", "type": "weapon", "img": "icons/creatures/claws/claw-hooked-curved.webp", "data": { "description": "", "notes": "", "additionalStats": {}, "quantity": 1, "weight": 0, "price": 0, "equippable": true, "equipped": true, "isVehicular": false, "actions": { "skill": "Fighting", "skillMod": "", "dmgMod": "", "additional": {} }, "bonusDamageDie": 6, "damage": "@str+d6", "range": "", "rof": "1", "ap": 0, "parry": 0, "minStr": "", "shots": 0, "currentShots": 0, "ammo": "", "autoReload": false }, "effects": {}, } } await warpgate.spawn(summonData.actorName, mutateData, {}, spawnOptions) }