diff --git a/macros/warpgate_spells/summon-ally-warpgate.js b/macros/warpgate_spells/summon-ally-warpgate.js new file mode 100644 index 0000000..6052582 --- /dev/null +++ b/macros/warpgate_spells/summon-ally-warpgate.js @@ -0,0 +1,181 @@ +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, mutateOptions, {}, spawnOptions) + console.log(position); +} \ No newline at end of file diff --git a/packs/macros.db b/packs/macros.db index 1957f80..b895a5e 100644 --- a/packs/macros.db +++ b/packs/macros.db @@ -4,10 +4,11 @@ {"_id":"79YiKPX3WcmBeMzm","name":"Intangibility","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"icons/magic/control/debuff-energy-hold-levitate-blue-yellow.webp","scope":"global","command":"const powerEffectApply = game.macros.getName(\"Power Effect\");\n\nreturn await powerEffectApply.execute(\"Intangibility\");","folder":null,"sort":0,"permission":{"default":0,"HXnQ3GTDyHZ7E1ev":3},"flags":{"advanced-macros":{"runAsGM":false},"combat-utility-belt":{"macroTrigger":""},"core":{"sourceId":"Macro.01dTmSPBq0xJQJcm"},"scene-packer":{"sourceId":"Macro.79YiKPX3WcmBeMzm","hash":"48cfba28bf13ab364cef9bdc7953f64c23d9c5e4"},"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000"}}} {"_id":"92LxuCERE2PKwgWn","name":"CancelSpellEffect","type":"script","author":"ygiRButlaf23fX9p","img":"icons/svg/cancel.svg","scope":"global","command":"const effect = args[0];\nconst targetIds = args[1];\nconst extra = args[2];\n\nasync function main() {\n for (const tokenId of targetIds) {\n let token = game.canvas.tokens.get(tokenId);\n let actor = token?.actor;\n if (!actor) continue;\n const active = actor.effects.find(e => e.data.label === effect.label);\n if (active) {\n await token.toggleEffect(effect, { active: false });\n console.log(\"Removed active effect\", effect.label, \"from\", token.name);\n }\n }\n}\nmain();","folder":null,"sort":0,"permission":{"default":0,"ygiRButlaf23fX9p":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"scene-packer":{"sourceId":"Macro.LHPOj1ppx03VgI1R"},"cf":{"id":"temp_p20tzfcm449","path":"Spell Effect Macros","color":"#000000"}}} {"_id":"9KVvOhKLlyZHrQ76","name":"Fly","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"systems/swade/assets/icons/status/status_flying.svg","scope":"global","command":"const powerEffectApply = game.macros.getName(\"Power Effect\");\n\nreturn await powerEffectApply.execute(\"Fly\");","folder":null,"sort":0,"permission":{"default":0,"HXnQ3GTDyHZ7E1ev":3},"flags":{"advanced-macros":{"runAsGM":false},"combat-utility-belt":{"macroTrigger":""},"core":{"sourceId":"Macro.01dTmSPBq0xJQJcm"},"scene-packer":{"sourceId":"Macro.9KVvOhKLlyZHrQ76","hash":"48cfba28bf13ab364cef9bdc7953f64c23d9c5e4"},"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000"}}} +{"_id":"9RQzK3bB1im4N0Lw","name":"Summon Ally","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"icons/magic/symbols/circle-ouroboros.webp","scope":"global","command":"const ICON = 'icons/magic/symbols/circle-ouroboros.webp';\nconst ACTORFOLDER = \"Summon Ally\";\n\nlet tokens = [];\nlet targets = Array.from(game.user.targets);\nif (targets.length > 0) {\n tokens = targets;\n} else if (canvas.tokens.controlled.length > 0) {\n tokens = canvas.tokens.controlled;\n}\nif (tokens.length > 0) {\n main(tokens[0]);\n} else {\n ui.notifications.error(\"Please select or target a token\");\n}\n\nasync function main(token) {\n let tokenList = token.name;\n let folder = game.folders.find(f => f.data.type == 'Actor' && f.data.name == ACTORFOLDER)\n let menuOptions = {\n title: \"Summon Ally\",\n defaultButton: \"cancel\",\n options: {}\n }\n let menuData = {\n inputs: [\n { type: 'header', label: 'Summon Ally' },\n { type: 'info', label: `${tokenList} is summoning an ally` },\n {\n type: 'info',\n label: `\n \n \n \n \n \n \n
RankCostServant
Novice2Attendant
Seasoned4Bodyguard
Veteran6*Mirror Self*
Heroic8Sentinel
\n `\n },\n {\n type: 'select',\n label: \"Ally to summon\",\n options: folder.contents.map(a => a.data.name)\n },\n {\n type: 'number',\n label: 'Number to spawn (+half total cost per addtl.)',\n options: 1\n },\n { type: 'checkbox', label: 'Bite/Claw (+1)', options: false }\n ],\n buttons: [\n { label: \"Apply\", value: \"apply\" },\n { label: \"Apply with Raise\", value: \"raise\" },\n { label: \"Cancel\", value: \"cancel\" }\n ]\n }\n\n let {buttons, inputs} = await warpgate.menu(menuData, menuOptions);\n let summonData = {\n raise: (buttons == \"raise\"), \n actorName: (inputs[3]),\n number: inputs[4],\n addBiteClaw: inputs[5],\n }\n summonData.actor = folder.contents.find(a => a.data.name == summonData.actorName);\n summonData.icon = summonData.actor.data.token.img;\n doWork(summonData, token);\n}\n\nasync function doWork(summonData, token) {\n console.log(\"Summon Ally\", token, summonData);\n let effectData = {\n icon: ICON,\n id: \"summonally\",\n label: \"Summoned Ally\",\n duration: { rounds: 5 },\n flags: {\n swade: {\n expiration: 3,\n loseTurnOnHold: true\n }\n },\n changes: [],\n };\n let mutateOptions = {\n comparisonKeys: { 'ActiveEffect': 'label' },\n name: \"Summoned Ally\",\n permanent: true,\n description: \"Summoned Ally\",\n }\n let mutate = {\n embedded: {\n ActiveEffect: {\n \"Summoned Ally\": effectData,\n }\n }\n };\n await warpgate.mutate(token.document, mutate, {}, mutateOptions);\n let spawnOptions = {\n controllingActor: token.actor,\n duplicates: summonData.number,\n comparisonKeys: {'ActiveEffect': 'label'},\n crosshairs: {\n size: 1,\n icon: summonData.icon,\n label: `Summon ${summonData.actorName}`,\n drawOutline: false,\n rememberControlled: true\n }\n }\n let mutateData = {\n token: {\n actorLink: false,\n name: `${token.name}'s ${summonData.actor.data.token.name}`,\n },\n embedded: {\n Item: {}\n }\n }\n if (summonData.raise) {\n mutateData.embedded.Item.Resilient = {\n \"name\": \"Resilient\",\n \"type\": \"ability\",\n \"img\": \"systems/swade/assets/icons/ability.svg\",\n \"data\": {\n \"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
\",\n \"notes\": \"\",\n \"additionalStats\": {},\n \"subtype\": \"special\",\n \"grantsPowers\": false\n },\n \"effects\": {},\n \"flags\": {\n \"core\": {\n \"sourceId\": \"Compendium.swpf-core-rules.swpf-abilities.kiu5yk2aQkUGwlHN\"\n },\n }\n }\n }\n \n if (summonData.addBiteClaw) {\n mutateData.embedded.Item[\"Bite/Claw\"] = {\n \"name\": \"Bite/Claw\",\n \"type\": \"weapon\",\n \"img\": \"icons/creatures/claws/claw-hooked-curved.webp\",\n \"data\": {\n \"description\": \"\",\n \"notes\": \"\",\n \"additionalStats\": {},\n \"quantity\": 1,\n \"weight\": 0,\n \"price\": 0,\n \"equippable\": true,\n \"equipped\": true,\n \"isVehicular\": false,\n \"actions\": {\n \"skill\": \"Fighting\",\n \"skillMod\": \"\",\n \"dmgMod\": \"\",\n \"additional\": {}\n },\n \"bonusDamageDie\": 6,\n \"damage\": \"@str+d6\",\n \"range\": \"\",\n \"rof\": \"1\",\n \"ap\": 0,\n \"parry\": 0,\n \"minStr\": \"\",\n \"shots\": 0,\n \"currentShots\": 0,\n \"ammo\": \"\",\n \"autoReload\": false\n },\n \"effects\": {},\n }\n }\n await warpgate.spawn(summonData.actorName, mutateData, {}, spawnOptions)\n}","folder":null,"sort":0,"permission":{"default":0,"HXnQ3GTDyHZ7E1ev":3},"flags":{"scene-packer":{"hash":"2330aea2aee15edc2f08b0bc010a12096b472242","sourceId":"Macro.9RQzK3bB1im4N0Lw"},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.9RQzK3bB1im4N0Lw"},"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000"}}} {"_id":"AVI34dUpDYCEm9w5","name":"AE_Companion_Macro(NAMEOFFORMACTOR)","type":"script","author":"ygiRButlaf23fX9p","img":"icons/svg/dice-target.svg","scope":"global","command":"const macro = game.macros.getName(\"shapeshift_AE_form\");\nlet value = await macro.execute(args[0]);\nreturn value;","folder":null,"sort":0,"permission":{"default":0,"ygiRButlaf23fX9p":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.BEcVfWAVnXW0QKTR"},"scene-packer":{"sourceId":"Macro.BEcVfWAVnXW0QKTR"},"cf":{"id":"temp_ocr9zgcmo7","color":"#000000"}}} {"_id":"B07BTxFEkIpxWK3p","name":"Adventure Card","permission":{"default":0,"mrhsZpAiXth4sLah":3},"type":"script","flags":{"core":{"sourceId":"Compendium.swade-macros-simple.SWADE-Macros.dj9ISCPKpZRu43ud"},"cf":{"id":"temp_natl1zonf8"}},"scope":"global","command":"/* Mini Tutorial\r\n1 - Import the cards to a rollable table (i recommend Card Deck Importer - follow the instructions there). Name the rollable table AdventureDeck or change below.\r\n2 - Create an item (gear) named Adventure Card. Give it to the characters that will use it.\r\n3 - Run the macro.\r\n*/\r\n\r\nvar rollTableName = \"AdventureDeck\"; /// name of the rolltable with adventure cards\r\nvar itemCard = \"Adventure Card\"; /// name of the item holding the adventure card\r\n\r\nlet chars = game.actors.entities.filter((t) => t.data.type === \"character\"); /// all the chars\r\nlet optionchars = \"\";\r\nvar allchars = [];\r\n\r\nfor (const char of chars) {\r\n let myitem = char.items.find((i) => i.name === itemCard);\r\n if (myitem !== null) {\r\n /// filters the ones that has the item\r\n optionchars += ``;\r\n allchars.push(char._id);\r\n }\r\n}\r\n\r\nif (!optionchars) {\r\n /// no chars\r\n ui.notifications.warn(`No character has the item ` + itemCard + `.`, {});\r\n}\r\n\r\nlet template =\r\n `

How many cards?

\r\n

For wich character?

`;\r\nnew Dialog({\r\n title: \"Give Adventure Cards\",\r\n content: template,\r\n buttons: {\r\n ok: {\r\n label: \"Give\",\r\n callback: function (html) {\r\n applyFormOptions(html);\r\n },\r\n },\r\n cancel: {\r\n label: \"Cancel\",\r\n },\r\n },\r\n}).render(true);\r\n\r\nfunction drawFromTable(tableName) {\r\n /// thanks to Forien for this. Check his modules https://foundryvtt.com/community/forien\r\n const table = game.tables.getName(tableName);\r\n if (!table) {\r\n ui.notifications.warn(`Table ${tableName} not found.`, {});\r\n return;\r\n }\r\n let results = table.roll().results;\r\n\r\n // if table is without replacemenets, mark results as drawn\r\n if (table.data.replacement === false) {\r\n results = results.map((r) => {\r\n r.drawn = true;\r\n return r;\r\n });\r\n\r\n table.updateEmbeddedEntity(\"TableResult\", results);\r\n }\r\n\r\n return results;\r\n}\r\n\r\nfunction applyFormOptions(html) {\r\n let qtde = html.find(\"#qtde\")[0].value;\r\n let selchar = html.find(\"#jogs\")[0].value;\r\n\r\n if (selchar === \"todos\") {\r\n for (let i = 0; i < allchars.length; i++) {\r\n giveCards(qtde, allchars[i]);\r\n }\r\n } else {\r\n giveCards(qtde, selchar);\r\n }\r\n\r\n let chatData = {\r\n user: game.user._id,\r\n speaker: ChatMessage.getSpeaker(),\r\n content: \"Adventure Cards given\",\r\n };\r\n ChatMessage.create(chatData, {});\r\n}\r\n\r\nfunction giveCards(howmany, actorId) {\r\n let char = game.actors.get(actorId);\r\n let myitem = char.items.find((i) => i.name === itemCard);\r\n let updatedesc = \"\";\r\n\r\n for (let i = 1; i <= howmany; i++) {\r\n let results = drawFromTable(rollTableName);\r\n updatedesc +=\r\n \"

@Compendium[\" + results[0].collection + \".\" + results[0].resultId + \"]{\" + results[0].text + \"}

\";\r\n }\r\n\r\n myitem.update({ [\"data.description\"]: updatedesc });\r\n}\r\n","author":"mrhsZpAiXth4sLah","img":"icons/svg/chest.svg","actorIds":[]} {"_id":"CZvzvDhyY6oUHdKN","name":"Toggle Flying","permission":{"default":0,"goVuB7uyVDPjAwfj":3},"type":"script","flags":{"combat-utility-belt":{"macroTrigger":""},"core":{"sourceId":"Macro.dsr95SKSNCDX70VO"},"cf":{"id":"temp_pswasgs6ygg"}},"scope":"global","command":"main ()\n\nasync function main() {\n\nconst effect = \"systems/swade/assets/icons/status/status_flying.svg\";\nconst effectName = \"Flying\";\n\n //Is a token selected\n if (canvas.tokens.controlled.length == 0) {\n ui.notifications.error(\"No tokens selected\");\n return;\n }\n\n let tokens = canvas.tokens.controlled.map(token => {return token});\n\n for (let token of tokens) {\n await token.toggleEffect(effect);\n } // end for\n} //End main","author":"goVuB7uyVDPjAwfj","img":"systems/swade/assets/icons/status/status_flying.svg","actorIds":[]} -{"_id":"EMnNSHCl45UMUnJu","name":"Warrior's Gift","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"icons/magic/control/modfiy-luck-fortune-gray.webp","scope":"global","command":"const ICON = 'icons/magic/control/modfiy-luck-fortune-gray.webp'\n\nconst PACKNAMES = [\n 'swade-core-rules.swade-edges',\n 'swpf-core-rules.swpf-edges',\n]\n\nconst EDGENAMES = [\n 'Block',\n 'Improved Block',\n 'Brawler',\n 'Bruiser',\n 'Calculating',\n 'Combat Reflexes',\n 'Counterattack',\n 'Improved Counterattack',\n 'Dead Shot',\n 'Dodge',\n 'Extraction',\n 'Improved Extraction',\n 'Feint',\n 'First Strike',\n 'Improved First Strike',\n 'Formation Fighter',\n 'Free Runner',\n 'Frenzy',\n 'Improved Frenzy',\n 'Giant Killer',\n 'Hard to Kill',\n 'Harder to Kill',\n 'Improvisational Fighter',\n 'Iron Jaw',\n 'Killer Instinct',\n 'Level Headed',\n 'Improved Level Headed',\n 'Marksman',\n 'Mighty Blow',\n 'Nerves of Steel',\n 'Improved Nerves of Steel',\n 'No Mercy',\n 'Rapid Reload',\n 'Rapid Shot',\n 'Improved Rapid Shot',\n 'Steady Hands',\n 'Sweep',\n 'Improved Sweep',\n 'Trademark Weapon',\n 'Improved Trademark Weapon',\n 'Two-Weapon Fighting',\n]\n\nlet EDGES = new Map()\nfor (let edgeName of EDGENAMES) {\n for (let packName of PACKNAMES) {\n let edge = game.packs.get(packName)?.index?.find(i => i.name == edgeName);\n if (edge) {\n EDGES.set(edgeName, {pack: packName, edge: edge._id});\n break;\n }\n }\n}\n\nlet tokens = [];\nlet targets = Array.from(game.user.targets);\nif (targets.length > 0) {\n tokens = targets;\n} else if (canvas.tokens.controlled.length > 0) {\n tokens = canvas.tokens.controlled;\n}\nif (tokens.length > 0) {\n main(tokens);\n} else {\n ui.notifications.error(\"Please select or target a token\");\n}\n\nasync function main(tokens) {\n let tokenList = tokens.map(t => t.name).join(\", \");\n let menuOptions = {\n title: \"Warrior's Gift\",\n defaultButton: \"cancel\",\n options: {}\n }\n let edgeNames = Array.from(EDGES.keys()).sort();\n let menuData = {\n inputs: [\n {type: 'header', label: \"Warrior's Gift\"},\n {type: 'info', label: `Apply Warrior's Gift to ${tokenList}`},\n {type: 'select', label: \"Edge\", options: edgeNames},\n ],\n buttons: [\n {label: \"Apply\", value: \"apply\"},\n {label: \"Cancel\", value: \"cancel\"}\n ]\n }\n let {buttons, inputs} = await warpgate.menu(menuData, menuOptions);\n if (buttons && buttons != \"cancel\") {\n await createEffect(tokens, inputs[2]);\n }\n}\n\nasync function createEffect(tokens, edgeName) {\n const effectIcon = ICON;\n for (const token of tokens) {\n const effectName = `Warrior's Gift (${edgeName})`;\n const effectId = `warriorsgift${edgeName}`;\n const edgeId = EDGES.get(edgeName).edge;\n const pack = EDGES.get(edgeName).pack;\n const edge = await game.packs.get(pack).getDocument(edgeId);\n let effectData = {\n icon: effectIcon,\n id: effectId,\n label: effectName,\n duration: {rounds: 5},\n flags: {\n swade: {\n expiration: 3,\n loseTurnOnHold: true\n }\n },\n changes: [],\n };\n let edgeData = {...edge.data};\n let mutate = {\n embedded: {\n Item: {\n [edgeName]: edgeData,\n },\n ActiveEffect: {\n [effectName]: effectData,\n }\n }\n };\n edgeData.effects.forEach(edgeEffect => {\n mutate.embedded.ActiveEffect[edgeEffect.data.label] = edgeEffect.data\n })\n \n let mutateOptions = {\n comparisonKeys: {'ActiveEffect': 'label'},\n name: effectName,\n permanent: false,\n description: effectName,\n }\n await warpgate.mutate(token.document, mutate, {}, mutateOptions);\n }\n}","folder":null,"sort":0,"permission":{"default":0,"HXnQ3GTDyHZ7E1ev":3},"flags":{"scene-packer":{"hash":"9c18182e7fa4fbe8154f7842129c6b227d83cea0","sourceId":"Macro.EMnNSHCl45UMUnJu"},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.EMnNSHCl45UMUnJu"},"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000"}}} +{"_id":"EMnNSHCl45UMUnJu","name":"Warrior's Gift","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"icons/magic/control/modfiy-luck-fortune-gray.webp","scope":"global","command":"const ICON = 'icons/magic/control/modfiy-luck-fortune-gray.webp'\n\nconst PACKNAMES = [\n 'swade-core-rules.swade-edges',\n 'swpf-core-rules.swpf-edges',\n]\n\nconst EDGENAMES = [\n 'Block',\n 'Improved Block',\n 'Brawler',\n 'Bruiser',\n 'Calculating',\n 'Combat Reflexes',\n 'Counterattack',\n 'Improved Counterattack',\n 'Dead Shot',\n 'Dodge',\n 'Extraction',\n 'Improved Extraction',\n 'Feint',\n 'First Strike',\n 'Improved First Strike',\n 'Formation Fighter',\n 'Free Runner',\n 'Frenzy',\n 'Improved Frenzy',\n 'Giant Killer',\n 'Hard to Kill',\n 'Harder to Kill',\n 'Improvisational Fighter',\n 'Iron Jaw',\n 'Killer Instinct',\n 'Level Headed',\n 'Improved Level Headed',\n 'Marksman',\n 'Mighty Blow',\n 'Nerves of Steel',\n 'Improved Nerves of Steel',\n 'No Mercy',\n 'Rapid Reload',\n 'Rapid Shot',\n 'Improved Rapid Shot',\n 'Steady Hands',\n 'Sweep',\n 'Improved Sweep',\n 'Trademark Weapon',\n 'Improved Trademark Weapon',\n 'Two-Weapon Fighting',\n]\n\nlet EDGES = new Map()\nfor (let edgeName of EDGENAMES) {\n for (let packName of PACKNAMES) {\n let edge = game.packs.get(packName)?.index?.find(i => i.name == edgeName);\n if (edge) {\n EDGES.set(edgeName, {pack: packName, edge: edge._id});\n break;\n }\n }\n}\n\nlet tokens = [];\nlet targets = Array.from(game.user.targets);\nif (targets.length > 0) {\n tokens = targets;\n} else if (canvas.tokens.controlled.length > 0) {\n tokens = canvas.tokens.controlled;\n}\nif (tokens.length > 0) {\n main(tokens);\n} else {\n ui.notifications.error(\"Please select or target a token\");\n}\n\nasync function main(tokens) {\n let tokenList = tokens.map(t => t.name).join(\", \");\n let menuOptions = {\n title: \"Warrior's Gift\",\n defaultButton: \"cancel\",\n options: {}\n }\n let edgeNames = Array.from(EDGES.keys()).sort();\n let menuData = {\n inputs: [\n {type: 'header', label: \"Warrior's Gift\"},\n {type: 'info', label: `Apply Warrior's Gift to ${tokenList}`},\n {type: 'select', label: \"Edge\", options: edgeNames},\n ],\n buttons: [\n {label: \"Apply\", value: \"apply\"},\n {label: \"Cancel\", value: \"cancel\"}\n ]\n }\n let {buttons, inputs} = await warpgate.menu(menuData, menuOptions);\n if (buttons && buttons != \"cancel\") {\n await createEffect(tokens, inputs[2]);\n }\n}\n\nasync function createEffect(tokens, edgeName) {\n const effectIcon = ICON;\n for (const token of tokens) {\n const effectName = `Warrior's Gift (${edgeName})`;\n const effectId = `warriorsgift${edgeName}`;\n const edgeId = EDGES.get(edgeName).edge;\n const pack = EDGES.get(edgeName).pack;\n const edge = await game.packs.get(pack).getDocument(edgeId);\n let effectData = {\n icon: effectIcon,\n id: effectId,\n label: effectName,\n duration: {rounds: 5},\n flags: {\n swade: {\n expiration: 3,\n loseTurnOnHold: true\n }\n },\n changes: [],\n };\n let edgeData = {...edge.data};\n let mutate = {\n embedded: {\n Item: {\n [edgeName]: edgeData,\n },\n ActiveEffect: {\n [effectName]: effectData,\n }\n }\n };\n edgeData.effects.forEach(edgeEffect => {\n mutate.embedded.ActiveEffect[edgeEffect.data.label] = edgeEffect.data\n })\n \n let mutateOptions = {\n comparisonKeys: {'ActiveEffect': 'label'},\n name: effectName,\n permanent: false,\n description: effectName,\n }\n await warpgate.mutate(token.document, mutate, {}, mutateOptions);\n }\n}","folder":null,"sort":0,"permission":{"default":0,"HXnQ3GTDyHZ7E1ev":3},"flags":{"scene-packer":{"hash":"1f36d4f0d8aab97fdee83a6c5c4b128f1a25d323","sourceId":"Macro.EMnNSHCl45UMUnJu"},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.EMnNSHCl45UMUnJu"},"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000"}}} {"_id":"Elp8657828AQ5fUL","name":"Card Draw","permission":{"default":0,"mrhsZpAiXth4sLah":3},"type":"script","flags":{"core":{"sourceId":"Compendium.swade-macros-simple.SWADE-Macros.RhmF9WWSB93bXUeF"},"cf":{"id":"temp_natl1zonf8"}},"scope":"global","command":"/*\r\nFeatures\r\n- Draw n cards placing them in the scene\r\n- This macro can reset the table preventing from the error\r\n- This macro can line up the cards\r\n*/\r\n\r\ngetRequirements();\r\n\r\nfunction getRequirements() {\r\n //How Many Cards to Draw\r\n //Width/Height\r\n //Which Table to Draw From\r\n let cardsList = \"\";\r\n Array.from(game.tables).map((el) => {\r\n cardsList += ``;\r\n });\r\n\r\n let template = `\r\n

Table to Draw From:

\r\n

\r\n Cards to Draw (Lines x Columns): x \r\n

\r\n

\r\n Height: \r\n Width: \r\n

\r\n
\r\n

\r\n \r\n Reset Table?\r\n

\r\n

\r\n \r\n Just stack up all cards\r\n

\r\n
\r\n

\r\n

Horizontal spacing between cards

\r\n \r\n

\r\n

\r\n

Vertical spacing between cards (dogfight only)

\r\n \r\n

\r\n `;\r\n new Dialog({\r\n title: \"Draw Cards To Table\",\r\n content: template,\r\n buttons: {\r\n ok: {\r\n label: \"Draw\",\r\n callback: async (html) => {\r\n makeTiles(html);\r\n },\r\n },\r\n cancel: {\r\n label: \"Cancel\",\r\n },\r\n },\r\n }).render(true);\r\n}\r\n\r\nasync function makeTiles(html) { \r\n let spacingx = html.find(\"#spacingx\")[0].value/100;\r\n let spacingy = html.find(\"#spacingy\")[0].value/100;\r\n let dogFightLines = html.find(\"#dogFightLines\")[0].value;\r\n let dogFightColumns = html.find(\"#dogFightColumns\")[0].value; \r\n let resetTable = html.find(\"#reset\")[0].value;\r\n const stackupcards = html.find(\"#stackupcards\")[0].checked;\r\n let tableName = html.find(\"#tableName\")[0].value;\r\n let cardsToDraw = dogFightLines*dogFightColumns;\r\n let _height = html.find(\"#height\")[0].value;\r\n let _width = html.find(\"#width\")[0].value;\r\n\r\n if (resetTable=='on') {\r\n await game.tables.find((el) => el.data.name == tableName).reset();\r\n }\r\n\r\n let cardDraws = (\r\n await game.tables\r\n .find((el) => el.data.name == tableName)\r\n .drawMany(cardsToDraw)\r\n ).results;\r\n\r\n let centerX = game.scenes.active.data.width / 3;\r\n let centerY = game.scenes.active.data.height / 2;\r\n \r\n let deltaX = 0;\r\n let deltaY = 0;\r\n let counter = 0;\r\n \r\n //console.log(spacingx + '/' + spacingy + ' stackupcards:' + (stackupcards!='on'));\r\n for (let y = 0; y < dogFightLines; y++) {\r\n deltaY = ( _height*y + _height*spacingy*y );\r\n for (let x = 0; x < dogFightColumns; x++) { \r\n deltaX = ( _width*x + _width*spacingx*x ); \r\n if (stackupcards) {\r\n deltaX = 0;\r\n deltaY = 0; \r\n }\r\n await Tile.create({\r\n img: cardDraws[counter].img,\r\n width: _width,\r\n height: _height,\r\n x: centerX + deltaX,\r\n y: centerY + deltaY\r\n }); \r\n //console.log('x:' + x + ' y:' + y + ' counter:' + counter + ' deltaX:' + deltaX + ' deltaY:' + deltaY);\r\n counter = counter + 1;\r\n //console.log('centerX: ' + centerX + ' / deltaX: ' + deltaX + ' / centerX+deltaX:' + (centerX+deltaX) ); \r\n } \r\n }\r\n}","author":"mrhsZpAiXth4sLah","img":"icons/svg/thrust.svg","actorIds":[]} {"_id":"FngiDIs9HR2p0eY1","name":"Sloth/Speed","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"icons/skills/movement/feet-winged-boots-glowing-yellow.webp","scope":"global","command":"const SPEEDICON = 'icons/skills/movement/feet-winged-boots-glowing-yellow.webp'\nconst SLOTHICON = 'icons/magic/control/encase-creature-spider-hold.webp'\n\nlet tokens = [];\nlet targets = Array.from(game.user.targets);\nif (targets.length > 0) {\n tokens = targets;\n} else if (canvas.tokens.controlled.length > 0) {\n tokens = canvas.tokens.controlled;\n}\nif (tokens.length > 0) {\n main(tokens);\n} else {\n ui.notifications.error(\"Please select or target a token\");\n}\n\nasync function main(tokens) {\n let tokenList = tokens.map(t => t.name).join(\", \");\n let menuOptions = {\n title: 'Sloth/Speed',\n defaultButton: \"Cancel\",\n options: {}\n };\n let menuData = {\n inputs: [\n { type: 'header', label: 'Sloth/Speed' },\n { type: 'info', label: `Affected Tokens: ${tokenList}` },\n { type: 'info', label: \"Speed or Sloth\" },\n { type: 'radio', label: 'Speed', options: ['isspeed', true] },\n { type: 'radio', label: 'Sloth', options: ['isspeed', false] },\n ],\n buttons: [\n { label: \"Apply\", value: \"apply\" },\n { label: \"Apply with raise\", value: \"raise\" },\n { label: \"Cancel\", value: \"cancel\" }\n ]\n }\n let { buttons, inputs } = await warpgate.menu(menuData, menuOptions);\n if (buttons != \"cancel\") {\n let direction = inputs[3] || inputs[4];\n createEffect(tokens, direction, buttons);\n }\n}\n\nasync function createEffect(tokens, direction, buttons) {\n const raise = (buttons == 'raise');\n const effectName = `${raise ? \"Major\" : \"Minor\"} ${direction}`;\n const effectId = `${raise ? \"Major\" : \"Minor\"}${direction}`;\n const effectIcon = (direction == \"Speed\" ? SPEEDICON : SLOTHICON)\n for (const token of tokens) {\n let tokenDoc = token.document;\n let effectData = {\n icon: effectIcon,\n id: effectId,\n label: effectName,\n flags: {\n swade: {\n expiration: 3,\n loseTurnOnHold: true\n }\n },\n changes: []\n };\n let mode = foundry.CONST.ACTIVE_EFFECT_MODES.MULTIPLY;\n if (direction == \"Speed\") {\n effectData.duration = { rounds: 5 };\n effectData.changes.push({\n key: 'data.stats.speed.value',\n mode: mode,\n value: 2\n })\n } else {\n effectData.changes.push({\n key: 'data.stats.speed.value',\n mode: mode,\n value: 0.5\n })\n }\n let mutate = {\n embedded: {\n ActiveEffect: {\n }\n }\n };\n mutate.embedded.ActiveEffect[effectName] = effectData;\n let mutateOptions = {\n comparisonKeys: { 'ActiveEffect': 'label' },\n name: effectName,\n permanent: true,\n description: effectName,\n }\n await warpgate.mutate(token.document, mutate, {}, mutateOptions);\n }\n}","folder":null,"sort":0,"permission":{"default":0,"HXnQ3GTDyHZ7E1ev":3},"flags":{"scene-packer":{"hash":"0318a6a5650fcdfffa0a670ca22c559c503bc575","sourceId":"Macro.FngiDIs9HR2p0eY1"},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.FngiDIs9HR2p0eY1"},"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000"}}} {"_id":"FntCnwyd0hrKppdd","name":"Protection","type":"script","author":"ygiRButlaf23fX9p","img":"systems/swade/assets/icons/status/status_protection.svg","scope":"global","command":"const targets = canvas.tokens.controlled;\nconst extra = { flavor: \"Magic Shield\" }\nconst spellEffect = game.macros.getName(\"ApplySpellEffect\");\nconst label = \"Protection\";\nconst id = \"protection\";\nconst icon = \"systems/swade/assets/icons/status/status_protection.svg\";\nconst duration = 5;\n\nmain();\n\nasync function main() {\n let effect = {\n changes: [\n { key: \"data.stats.toughness.armor\", value: 2, mode: 2 }\n ],\n duration: { rounds: duration },\n icon: icon,\n label: label,\n id: id\n }\n\n let applyChanges = false;\n let d = new Dialog({\n title: `Applying ${label} effects`,\n content: `Apply ${label} with raise?`,\n buttons: {\n raise: {\n icon: '',\n label: 'With raise',\n callback: () => {\n applyChanges = true;\n effect.label = effect.label + \" with raise\";\n effect.changes[0].key = 'data.stats.toughness.value';\n }\n },\n noraise: {\n icon: '',\n label: 'Normal Success',\n callback: () => { applyChanges = true }\n }\n },\n default: \"noraise\",\n close: html => {\n if (applyChanges) {\n spellEffect.execute(effect, targets, extra);\n }\n }\n });\n d.render(true);\n}","folder":null,"sort":0,"permission":{"default":0,"ygiRButlaf23fX9p":3},"flags":{"advanced-macros":{"runAsGM":false},"combat-utility-belt":{"macroTrigger":""},"scene-packer":{"sourceId":"Macro.aIbfmIoI2JVsbg9D"},"cf":{"id":"temp_p20tzfcm449","path":"Spell Effect Macros","color":"#000000"},"core":{"sourceId":"Macro.aIbfmIoI2JVsbg9D"}}} @@ -35,6 +36,6 @@ {"_id":"p94dkSmOgfuoC28K","name":"Deflection (SWPF)","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"icons/magic/defensive/shield-barrier-deflect-teal.webp","scope":"global","command":"const ICON = 'icons/magic/defensive/shield-barrier-deflect-teal.webp'\n\nlet tokens = [];\nlet targets = Array.from(game.user.targets);\nif (targets.length > 0) {\n tokens = targets;\n} else if (canvas.tokens.controlled.length > 0) {\n tokens = canvas.tokens.controlled;\n}\nif (tokens.length > 0) {\n main(tokens);\n} else {\n ui.notifications.error(\"Please select or target a token\");\n}\n\nasync function main(tokens) {\n let tokenList = tokens.map(t => t.name).join(\", \");\n let dialogOptions = {\n title: \"Deflection\",\n content: `Apply Deflection to ${tokenList}`,\n default: \"cancel\",\n buttons: [\n {label: \"Apply (melee)\", value: \"melee\"},\n {label: \"Apply (ranged)\", value: \"ranged\"},\n {label: \"Apply with raise (both)\", value: \"raise\"},\n {label: \"Cancel\", value: \"cancel\"}\n ]\n }\n let choice = await warpgate.buttonDialog(dialogOptions);\n if (choice != \"cancel\") {\n createEffect(tokens, choice);\n }\n}\n\nasync function createEffect(tokens, choice) {\n let effectName = 'Deflection';\n let effectId = `deflection${choice}`;\n let changes = []\n switch (choice) {\n case 'melee':\n effectName = \"Melee \" + effectName;\n break\n case 'ranged':\n effectName = \"Ranged \" + effectName;\n break \n }\n const effectIcon = ICON;\n for (const token of tokens) {\n let effectData = {\n icon: effectIcon,\n id: effectId,\n label: effectName,\n duration: {rounds: 5},\n flags: {\n swade: {\n expiration: 3,\n loseTurnOnHold: true\n }\n },\n changes: [\n {key: 'data.stats.parry.modifier', mode: foundry.CONST.ACTIVE_EFFECT_MODES.UPGRADE, value: 0, priority: 0}\n ],\n };\n let mutate = {\n embedded: {\n ActiveEffect: {\n }\n }\n };\n mutate.embedded.ActiveEffect[effectName] = effectData;\n let mutateOptions = {\n comparisonKeys: {'ActiveEffect': 'label'},\n name: effectName,\n permanent: true,\n description: effectName,\n }\n await warpgate.mutate(token.document, mutate, {}, mutateOptions);\n }\n}","folder":null,"sort":0,"permission":{"default":0,"HXnQ3GTDyHZ7E1ev":3},"flags":{"scene-packer":{"hash":"9fef11ff303f385dcc039b421c26212cdee832c2","sourceId":"Macro.p94dkSmOgfuoC28K"},"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000"},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Compendium.swade-mb-shared.macros.p94dkSmOgfuoC28K"}}} {"_id":"tjaqN9gedJpYFgbu","name":"Smite","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"systems/swade/assets/icons/status/status_smite.svg","scope":"global","command":"const ICON = 'systems/swade/assets/icons/status/status_smite.svg'\n\nlet tokens = [];\nlet targets = Array.from(game.user.targets);\nif (targets.length > 0) {\n tokens = targets;\n} else if (canvas.tokens.controlled.length > 0) {\n tokens = canvas.tokens.controlled;\n}\nif (tokens.length > 0) {\n main(tokens);\n} else {\n ui.notifications.error(\"Please select or target a token\");\n}\n\nasync function main(tokens) {\n let tokenList = tokens.map(t => t.name).join(\", \");\n let menuOptions = {\n title: 'Smite',\n defaultButton: \"cancel\",\n options: {}\n }\n let menuData = {\n inputs: [\n {type: 'header', label: 'Smite'},\n {type: 'info', label: `Apply Smite to ${tokenList}`},\n ],\n buttons: [\n {label: \"Apply\", value: \"apply\"},\n {label: \"Apply with Raise\", value: \"raise\"},\n {label: \"Cancel\", value: \"cancel\"}\n ]\n }\n let tokenWeapons = {};\n let index = 1;\n for (const token of tokens) {\n index += 2;\n tokenWeapons[token.id] = index;\n menuData.inputs.push({type: 'info', label: `

${token.name}

`});\n let weapons = token.actor.items.filter(i => i.type == 'weapon').map(i => i.name);\n weapons.unshift(\"\");\n menuData.inputs.push({type: 'select', label: token.name, options: weapons});\n }\n let {buttons, inputs} = await warpgate.menu(menuData, menuOptions);\n for (let tokenid in tokenWeapons) {\n tokenWeapons[tokenid] = inputs[tokenWeapons[tokenid]];\n }\n if (buttons != \"cancel\") {\n await createEffect(tokens, tokenWeapons, buttons);\n }\n console.log(buttons, tokenWeapons);\n}\n\nasync function createEffect(tokens, tokenWeapons, choice) {\n const effectIcon = ICON;\n const changeValue = (choice == 'raise' ? \"+4\" : \"+2\");\n for (const token of tokens) {\n const weaponName = tokenWeapons[token.id];\n const weaponId = token.actor.items.getName(weaponName)?.id\n const changeKey = `@Weapon{${weaponName}}[data.damage]`\n if (!weaponId) {\n continue\n }\n const effectName = `Smite (${weaponName})`;\n const effectId = `smite${choice}_${weaponId}`;\n let effectData = {\n icon: effectIcon,\n id: effectId,\n label: effectName,\n duration: {rounds: 5},\n flags: {\n swade: {\n expiration: 3,\n loseTurnOnHold: true\n }\n },\n changes: [\n {\n key: changeKey,\n mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD,\n value: changeValue,\n priority: 0\n }\n ],\n };\n let mutate = {\n embedded: {\n ActiveEffect: {\n }\n }\n };\n mutate.embedded.ActiveEffect[effectName] = effectData;\n let mutateOptions = {\n comparisonKeys: {'ActiveEffect': 'label'},\n name: effectName,\n permanent: true,\n description: effectName,\n }\n await warpgate.mutate(token.document, mutate, {}, mutateOptions);\n }\n}","folder":null,"sort":0,"permission":{"default":0,"ygiRButlaf23fX9p":3},"flags":{"advanced-macros":{"runAsGM":false},"combat-utility-belt":{"macroTrigger":""},"core":{"sourceId":"Macro.MXSe0F5osRtleDV4"},"scene-packer":{"sourceId":"Macro.MXSe0F5osRtleDV4","hash":"a74182d3f48775895d7f8e9b4b0af22194eaa82c"},"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000"}}} {"_id":"uB67GR2V90kmvyVs","name":"Deflection (SWADE)","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"icons/magic/defensive/shield-barrier-deflect-teal.webp","scope":"global","command":"const ICON = 'icons/magic/defensive/shield-barrier-deflect-teal.webp'\n\nlet tokens = [];\nlet targets = Array.from(game.user.targets);\nif (targets.length > 0) {\n tokens = targets;\n} else if (canvas.tokens.controlled.length > 0) {\n tokens = canvas.tokens.controlled;\n}\nif (tokens.length > 0) {\n main(tokens);\n} else {\n ui.notifications.error(\"Please select or target a token\");\n}\n\nasync function main(tokens) {\n let tokenList = tokens.map(t => t.name).join(\", \");\n let dialogOptions = {\n title: \"Deflection\",\n content: `Apply Deflection to ${tokenList}`,\n default: \"cancel\",\n buttons: [\n {label: \"Apply (-2)\", value: \"apply\"},\n {label: \"Apply with raise (-4)\", value: \"raise\"},\n {label: \"Cancel\", value: \"cancel\"}\n ]\n }\n let choice = await warpgate.buttonDialog(dialogOptions);\n if (choice != \"cancel\") {\n createEffect(tokens, choice);\n }\n}\n\nasync function createEffect(tokens, choice) {\n let effectName = 'Deflection';\n let effectId = `deflection${choice}`;\n let changes = []\n if (choice == \"raise\") {\n effectName = \"Major \" + effectName;\n }\n const effectIcon = ICON;\n for (const token of tokens) {\n let effectData = {\n icon: effectIcon,\n id: effectId,\n label: effectName,\n duration: {rounds: 5},\n flags: {\n swade: {\n expiration: 3,\n loseTurnOnHold: true\n }\n },\n changes: [\n {key: 'data.stats.parry.modifier', mode: foundry.CONST.ACTIVE_EFFECT_MODES.UPGRADE, value: 0, priority: 0}\n ],\n };\n let mutate = {\n embedded: {\n ActiveEffect: {\n }\n }\n };\n mutate.embedded.ActiveEffect[effectName] = effectData;\n let mutateOptions = {\n comparisonKeys: {'ActiveEffect': 'label'},\n name: effectName,\n permanent: true,\n description: effectName,\n }\n await warpgate.mutate(token.document, mutate, {}, mutateOptions);\n }\n}","folder":null,"sort":0,"permission":{"default":0,"HXnQ3GTDyHZ7E1ev":3},"flags":{"scene-packer":{"hash":"5aaf1e3ca287022321b0e6c7b610e1a42175d2b2","sourceId":"Macro.uB67GR2V90kmvyVs"},"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000"},"core":{"sourceId":"Compendium.swade-mb-shared.macros.uB67GR2V90kmvyVs"}}} -{"_id":"wa7ZoYUhNcjrNEmN","name":"#[CF_tempEntity]","type":"chat","author":"HXnQ3GTDyHZ7E1ev","img":"icons/svg/dice-target.svg","scope":"global","command":"","folder":null,"sort":0,"permission":{"default":0,"HXnQ3GTDyHZ7E1ev":3},"flags":{"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000","name":"SWADE Spell Effects (WarpGate)","children":["ye1BuJD7kKGAyReU","fzkUWlTKCJ68nEzL","uB67GR2V90kmvyVs","p94dkSmOgfuoC28K","K51dscyigZyR1Kma","c8lz4DUmw6afCYRC","9KVvOhKLlyZHrQ76","OAC1Ofm7iEjU9KAm","79YiKPX3WcmBeMzm","4SRoZduQrF2o3MZK","VzTYSKRXvpOTquUO","ZMWoKCwGTBTufQaF","U6ysKunxzRsvhnR6","yV3XNCfgHpGrREt0","FngiDIs9HR2p0eY1","tjaqN9gedJpYFgbu",null],"folderPath":[]},"scene-packer":{"hash":"3d9a8396d815dcef72c41f01fa0318a9a20c0bb4"}}} +{"_id":"wa7ZoYUhNcjrNEmN","name":"#[CF_tempEntity]","type":"chat","author":"HXnQ3GTDyHZ7E1ev","img":"icons/svg/dice-target.svg","scope":"global","command":"","folder":null,"sort":0,"permission":{"default":0,"HXnQ3GTDyHZ7E1ev":3},"flags":{"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000","name":"SWADE Spell Effects (WarpGate)","children":["ye1BuJD7kKGAyReU","fzkUWlTKCJ68nEzL","uB67GR2V90kmvyVs","p94dkSmOgfuoC28K","K51dscyigZyR1Kma","c8lz4DUmw6afCYRC","9KVvOhKLlyZHrQ76","OAC1Ofm7iEjU9KAm","79YiKPX3WcmBeMzm","4SRoZduQrF2o3MZK","VzTYSKRXvpOTquUO","ZMWoKCwGTBTufQaF","U6ysKunxzRsvhnR6","yV3XNCfgHpGrREt0","FngiDIs9HR2p0eY1","tjaqN9gedJpYFgbu",null,"EMnNSHCl45UMUnJu"],"folderPath":[]},"scene-packer":{"hash":"3d9a8396d815dcef72c41f01fa0318a9a20c0bb4"}}} {"_id":"yV3XNCfgHpGrREt0","name":"Sanctuary","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"icons/magic/defensive/shield-barrier-flaming-diamond-blue-yellow.webp","scope":"global","command":"const powerEffectApply = game.macros.getName(\"Power Effect\");\n\nreturn await powerEffectApply.execute(\"Sanctuary\");","folder":null,"sort":0,"permission":{"default":0,"ygiRButlaf23fX9p":3},"flags":{"advanced-macros":{"runAsGM":false},"combat-utility-belt":{"macroTrigger":""},"core":{"sourceId":"Macro.01dTmSPBq0xJQJcm"},"scene-packer":{"sourceId":"Macro.fzA6qQ1PyNgV8FqE","hash":"a45f562cc1f65a09386c3a6f9006b1fad3650f78"},"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000"}}} {"_id":"ye1BuJD7kKGAyReU","name":"Arcane Protection","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"icons/magic/defensive/shield-barrier-deflect-gold.webp","scope":"global","command":"const powerEffectApply = game.macros.getName(\"Power Effect\");\n\nreturn await powerEffectApply.execute(\"Arcane Protection\");","folder":null,"sort":0,"permission":{"default":0,"HXnQ3GTDyHZ7E1ev":3},"flags":{"advanced-macros":{"runAsGM":false},"combat-utility-belt":{"macroTrigger":""},"core":{"sourceId":"Macro.01dTmSPBq0xJQJcm"},"scene-packer":{"sourceId":"Macro.ye1BuJD7kKGAyReU","hash":"0d06d7cc1e1d6d1b9767648e0519e61253496a1c"},"cf":{"id":"temp_g9ptj9b0b4s","path":"SWADE Spell Effects (WarpGate)","color":"#000000"}}}