Created
May 21, 2021 19:37
-
-
Save palikhov/81b221d01505156bc5e8e3d452ac743e to your computer and use it in GitHub Desktop.
Foundry Animate objects attack macro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Animate Object Attacks. | |
| * Initial version stolen from somewhere but I forgot from where | |
| */ | |
| const details = { | |
| "e-blast" : { "size": 1, "atk": 11, "dmg": "1d10 + 5" }, | |
| }; | |
| // Use select token or some defaults if nothing is selected. | |
| const actorData = actor || canvas.tokens.controlled[0] || game.user.character; | |
| if (!actorData) { | |
| ui.notifications.warn("No actor selected"); | |
| } | |
| const targetId = game.user.targets.ids[0]; | |
| const targetToken = canvas.tokens.get(targetId); | |
| const targetName = targetToken?.actor.name || "Enemy"; | |
| const count = parseInt(game.brMacro?.animate_objects_count, 4) || 4; | |
| const rollState = BetterRolls.getRollState(); | |
| const content = ` | |
| <p><em>Your animated objects attack ${targetName}!</em></p> | |
| <p>Enter the details for the Animated Objects...</p> | |
| <form> | |
| <div class="form-group"> | |
| <label for="size">Size:</label> | |
| <select id="size" name="size"> | |
| <option value="e-blast">E-Blast</option> | |
| </select> | |
| </div> | |
| <div class="form-group"> | |
| <label for="count">Number of Objects:</label> | |
| <input id="count" name="count" type="number" min="0" value="${count}"></input> | |
| </div> | |
| <div class="form-group"> | |
| <label for="size">Roll Type:</label> | |
| <select id="roll" name="roll"> | |
| <option value="first">Normal</option> | |
| <option value="highest" ${rollState === "highest" ? "selected" : null}>Advantage</option> | |
| <option value="lowest" ${rollState === "lowest" ? "selected" : null}>Disadvantage</option> | |
| </select> | |
| </div> | |
| </form> | |
| `; | |
| const attackAction = async (html) => { | |
| let size = html.find("#size")[0].value; | |
| let count = html.find("#count")[0].value; | |
| let rollState = html.find("#roll")[0].value; | |
| const { atk, dmg } = details[size]; | |
| const rollTypes = { | |
| "highest": "Advantage", | |
| "lowest": "Disadvantage" | |
| }; | |
| let rollExpr = `1d20 + ${atk}`; | |
| const card = BetterRolls.rollItem(actorData); | |
| card.addField(["header", {img: this.data.img, title: "E-Blast"}]); | |
| for (let i = 0; i < count; i++) { | |
| const rollTypeStr = rollState in rollTypes ? `(${rollTypes[rollState]})` : ''; | |
| const title = `Object Attacks #${i+1} (+${atk}) ${rollTypeStr}`; | |
| card.addField(["attack", { formula: rollExpr, rollState, title}]); | |
| card.addField(["damage", { formula: dmg }]); | |
| } | |
| await card.toMessage(); | |
| // Remember setting for next run | |
| game.brMacro = game.brMacro ?? {}; | |
| game.brMacro.animate_objects_count = count; | |
| }; | |
| new Dialog({ | |
| title: "Animated Object Attacks", | |
| content: content, | |
| buttons: { | |
| attack: { | |
| icon: '<i class="fas fa-check"></i>', | |
| label: "Attack!", | |
| callback: attackAction | |
| }, | |
| cancel: { label: "Cancel" } | |
| }, | |
| default: "attack", | |
| }).render(true); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment