From 3dcfcf9616101ca9d79e4ee99cf5f51b3bfeb606 Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sun, 1 May 2022 17:09:15 -0500 Subject: [PATCH] add deflection macro for swade --- packs/macros.db | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packs/macros.db b/packs/macros.db index b9a6abc..545174d 100644 --- a/packs/macros.db +++ b/packs/macros.db @@ -21,7 +21,8 @@ {"name":"#[CF_tempEntity]","permission":{"default":0,"mrhsZpAiXth4sLah":3},"type":"chat","flags":{"cf":{"id":"temp_natl1zonf8","folderPath":[],"color":"#000000","fontColor":"#FFFFFF","name":"Cards","children":[],"icon":""}},"scope":"global","command":"","author":"mrhsZpAiXth4sLah","img":"icons/svg/dice-target.svg","actorIds":[],"_id":"hnicuEhZlfMF2upA"} {"name":"Sanctuary CUB","type":"script","author":"g5E84yQWEXKWBl9L","img":"icons/svg/holy-shield.svg","scope":"global","command":"const CONDITION = \"Sanctuary\";\n\n\nasync function tokenEffect(token) {\n console.log(token);\n let message = \"\" + token.data.name;\n if (game.cub.hasCondition(CONDITION, token)) {\n message += \" is no longer under Sanctuary.\";\n game.cub.removeCondition(CONDITION, token);\n } else {\n game.cub.addCondition(CONDITION, token);\n message += \" is under @Compendium[swpf-core-rules.swpf-powers.H82NWO4VNEYTqciG]{Sanctuary}.\";\n }\n ChatMessage.create({\n user: game.user._id,\n emote: true,\n flavor: \"Sanctuary!\",\n speaker: ChatMessage.getSpeaker({token: token}),\n content: message});\n}\n\nasync function main() {\n if (canvas.tokens.controlled.length == 0) {\n ui.notifications.error(\"No tokens selected\");\n return;\n }\n canvas.tokens.controlled.forEach(token => tokenEffect(token));\n}\n\nmain()","folder":null,"sort":0,"permission":{"default":0,"g5E84yQWEXKWBl9L":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"core":{"sourceId":"Macro.T7GXMuVq2JNMne2g"}},"_id":"jAPMvsQemX2LnSWp"} {"_id":"lm51dm7e9yhTx4os","name":"ApplySpellEffect","type":"script","author":"ygiRButlaf23fX9p","img":"icons/svg/sun.svg","scope":"global","command":"let effect = args[0];\nlet targets = args[1];\nlet extra = args[2];\nif (!extra) {\n extra = {};\n}\nif (!extra.name) { extra.name = effect.label }\nif (!extra.duration) { extra.duration = effect.duration?.rounds }\nif (!extra.startMessage) {\n extra.startMessage = `${effect.label}'s effects start`\n}\nif (!extra.endMessage) {\n extra.endMessage = `${effect.label}'s effects end`\n}\nif (!extra.fadeMessage) {\n extra.fadeMessage = `${effect.label}'s effects start to fade`\n}\n\nif (canvas.tokens.controlled.length == 0) {\n ui.notifications.error(\"No tokens selected\");\n return;\n}\nfor (let tgt of targets) {\n let actor = tgt.actor;\n let active = actor.effects.find(i => i.data.label === effect.label);\n let chatData = {\n speaker: ChatMessage.getSpeaker(tgt),\n type: CONST.CHAT_MESSAGE_TYPES.OTHER,\n emote: true\n }\n if (extra.flavor) {\n chatData.flavor = extra.flavor;\n }\n if (active) {\n await tgt.toggleEffect(effect, { active: false })\n chatData.content = extra.endMessage;\n } else {\n await tgt.toggleEffect(effect, { active: true })\n chatData.content = extra.startMessage;\n }\n if (chatData.content) {\n ChatMessage.create(chatData);\n }\n}\nif (game.modules.get(\"turnAlert\")?.active) {\n if (game.combat && extra.duration) {\n let alertData = {\n round: extra.duration - 1,\n roundAbsolute: false,\n turnId: game.combat.combatant._id,\n message: extra.fadeMessage\n }\n await TurnAlert.create(alertData);\n\n const targetIds = targets.map(t => t.id);\n alertData = {\n round: extra.duration - 1,\n roundAbsolute: false,\n turnId: game.combat.combatant._id,\n endOfTurn: true,\n message: extra.endMessage,\n macro: \"CancelSpellEffect\",\n args: [effect, targetIds]\n }\n await TurnAlert.create(alertData);\n }\n} else if (game.modules.get(\"about-time\")?.active && extra.duration) {\n let duration = extra.duration * 6;\n let preDuration = duration - 6;\n console.log(\"effects end in duration:\", duration, preDuration)\n Gametime.doIn({ seconds: preDuration }, () => {\n let chatData = {\n type: CONST.CHAT_MESSAGE_TYPES.OTHER,\n emote: true,\n content: extra.fadeMessage\n }\n if (extra.flavor) {\n chatData.flavor = extra.flavor;\n }\n ChatMessage.create(chatData);\n });\n const targetIds = targets.map(t => t.id);\n Gametime.doIn({ seconds: duration }, () => {\n let macro = game.macros.getName(\"CancelSpellEffect\")\n macro.execute(effect, targetIds)\n })\n}","folder":null,"sort":0,"permission":{"default":0,"ygiRButlaf23fX9p":3},"flags":{"combat-utility-belt":{"macroTrigger":""},"advanced-macros":{"runAsGM":false},"scene-packer":{"sourceId":"Macro.OB9FF0mpgWSYEryu"},"cf":{"id":"temp_p20tzfcm449","path":"Spell Effect Macros","color":"#000000"}}} -{"_id":"p94dkSmOgfuoC28K","name":"Deflection","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"}}} +{"_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"}}} {"_id":"tjaqN9gedJpYFgbu","name":"Smite","type":"script","author":"HXnQ3GTDyHZ7E1ev","img":"icons/weapons/swords/sword-flanged-lightning.webp","scope":"global","command":"const ICON = 'icons/weapons/swords/sword-flanged-lightning.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: '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 (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":"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":["fzkUWlTKCJ68nEzL","p94dkSmOgfuoC28K","tjaqN9gedJpYFgbu"],"folderPath":[]},"scene-packer":{"hash":"3d9a8396d815dcef72c41f01fa0318a9a20c0bb4"}}} +{"_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"}}} +{"_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":["fzkUWlTKCJ68nEzL","uB67GR2V90kmvyVs","p94dkSmOgfuoC28K","tjaqN9gedJpYFgbu"],"folderPath":[]},"scene-packer":{"hash":"3d9a8396d815dcef72c41f01fa0318a9a20c0bb4"}}} {"_id":"yV3XNCfgHpGrREt0","name":"Sanctuary","type":"script","author":"ygiRButlaf23fX9p","img":"icons/svg/holy-shield.svg","scope":"global","command":"let effect = {\n changes: [\n ],\n duration: {rounds: 5},\n icon: 'icons/svg/holy-shield.svg',\n label: 'Sanctuary',\n id: 'sanctuary'\n}\nconst targets = canvas.tokens.controlled;\nconst extra = { flavor: \"Sanctuary!\" }\nconst spellEffect = game.macros.getName(\"ApplySpellEffect\");\nlet value = await spellEffect.execute(effect, targets, extra);\nreturn value;","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.01dTmSPBq0xJQJcm"},"cf":{"id":"temp_p20tzfcm449","path":"Spell Effect Macros","color":"#000000"}}}