From 60377a2393cf72fe9a61fe80de5773be124535c8 Mon Sep 17 00:00:00 2001 From: U~man Date: Tue, 7 Jul 2020 00:22:21 +0200 Subject: [PATCH] WIP: Macros --- src/lang/en.json | 6 +++ src/module/config.js | 5 +++ src/module/dice.js | 19 ++++++-- src/module/item/entity.js | 3 +- src/module/macros.js | 61 ++++++++++++++++++++++++++ src/ose.js | 7 ++- src/template.json | 2 + src/templates/chat/item-card.html | 2 +- src/templates/items/ability-sheet.html | 6 +++ src/templates/items/armor-sheet.html | 13 ++++++ 10 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 src/module/macros.js diff --git a/src/lang/en.json b/src/lang/en.json index 7ec9660..51ad8c8 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -143,12 +143,18 @@ "OSE.items.Cost": "Cost", "OSE.items.Quantity": "Qt.", "OSE.items.Roll": "Roll", + "OSE.items.BlindRoll": "Blind", "OSE.items.Damage": "Damage", "OSE.items.Melee": "Melee", "OSE.items.Missile": "Missile", "OSE.items.Slow": "Slow", "OSE.items.ArmorAC": "AC", "OSE.items.ArmorAAC": "AAC", + + "OSE.armor.type": "Armor Type", + "OSE.armor.unarmored": "Unarmored", + "OSE.armor.light": "Light", + "OSE.armor.heavy": "Heavy", "OSE.spells.Memorized": "Memorized", "OSE.spells.Cast": "Cast", diff --git a/src/module/config.js b/src/module/config.js index 8332845..8765dac 100644 --- a/src/module/config.js +++ b/src/module/config.js @@ -21,4 +21,9 @@ export const OSE = { breath: "OSE.saves.breath.long", spell: "OSE.saves.spell.long", }, + armor : { + unarmored: "OSE.armor.unarmored", + light: "OSE.armor.light", + heavy: "OSE.armor.heavy", + } }; diff --git a/src/module/dice.js b/src/module/dice.js index e6d7166..96eda66 100644 --- a/src/module/dice.js +++ b/src/module/dice.js @@ -47,6 +47,7 @@ export class OseDice { speaker: speaker, }; + let templateData = { title: title, flavor: flavor, @@ -62,6 +63,15 @@ export class OseDice { // Convert the roll to a chat message and return the roll let rollMode = game.settings.get("core", "rollMode"); rollMode = form ? form.rollMode.value : rollMode; + + // Force blind roll (ability formulas) + if (data.rollData.blindroll) { + rollMode = "blindroll"; + } + + if (["gmroll", "blindroll"].includes(rollMode)) chatData["whisper"] = ChatMessage.getWhisperRecipients("GM"); + if (rollMode === "selfroll") chatData["whisper"] = [game.user._id]; + if (rollMode === "blindroll") chatData["blind"] = true; templateData.result = OseDice.digestResult(data, roll); @@ -148,6 +158,10 @@ export class OseDice { // Convert the roll to a chat message and return the roll let rollMode = game.settings.get("core", "rollMode"); rollMode = form ? form.rollMode.value : rollMode; + + if (["gmroll", "blindroll"].includes(rollMode)) chatData["whisper"] = ChatMessage.getWhisperRecipients("GM"); + if (rollMode === "selfroll") chatData["whisper"] = [game.user._id]; + if (rollMode === "blindroll") chatData["blind"] = true; templateData.result = OseDice.digestAttackResult(data, roll); @@ -209,14 +223,13 @@ export class OseDice { title = null, item = false, } = {}) { - let rollMode = game.settings.get("core", "rollMode"); let rolled = false; const template = "systems/ose/templates/chat/roll-dialog.html"; let dialogData = { formula: parts.join(" "), data: data, - rollMode: rollMode, + rollMode: game.settings.get('core', 'rollMode'), rollModes: CONFIG.Dice.rollModes, }; @@ -225,7 +238,7 @@ export class OseDice { data: data, title: title, flavor: flavor, - speaker: speaker, + speaker: speaker }; if (skipDialog) { diff --git a/src/module/item/entity.js b/src/module/item/entity.js index ae125ff..8c11f85 100644 --- a/src/module/item/entity.js +++ b/src/module/item/entity.js @@ -72,7 +72,8 @@ export class OseItem extends Item { ...this.data, ...{ rollData: { - type: "Formula" + type: "Formula", + blindroll: this.data.data.blindroll }, }, }; diff --git a/src/module/macros.js b/src/module/macros.js new file mode 100644 index 0000000..9e13ca5 --- /dev/null +++ b/src/module/macros.js @@ -0,0 +1,61 @@ + +/* -------------------------------------------- */ +/* Hotbar Macros */ +/* -------------------------------------------- */ + +/** + * Create a Macro from an Item drop. + * Get an existing item macro if one exists, otherwise create a new one. + * @param {Object} data The dropped data + * @param {number} slot The hotbar slot to use + * @returns {Promise} + */ +export async function createOseMacro(data, slot) { + if ( data.type !== "Item" ) return; + if (!( "data" in data ) ) return ui.notifications.warn("You can only create macro buttons for owned Items"); + const item = data.data; + + // Create the macro command + const command = `game.dnd5e.rollItemMacro("${item.name}");`; + let macro = game.macros.entities.find(m => (m.name === item.name) && (m.command === command)); + if ( !macro ) { + macro = await Macro.create({ + name: item.name, + type: "script", + img: item.img, + command: command, + flags: {"dnd5e.itemMacro": true} + }); + } + game.user.assignHotbarMacro(macro, slot); + return false; + } + + /* -------------------------------------------- */ + + /** + * Create a Macro from an Item drop. + * Get an existing item macro if one exists, otherwise create a new one. + * @param {string} itemName + * @return {Promise} + */ + export function rollItemMacro(itemName) { + const speaker = ChatMessage.getSpeaker(); + let actor; + if ( speaker.token ) actor = game.actors.tokens[speaker.token]; + if ( !actor ) actor = game.actors.get(speaker.actor); + + // Get matching items + const items = actor ? actor.items.filter(i => i.name === itemName) : []; + if ( items.length > 1 ) { + ui.notifications.warn(`Your controlled Actor ${actor.name} has more than one Item with name ${itemName}. The first matched item will be chosen.`); + } else if ( items.length === 0 ) { + return ui.notifications.warn(`Your controlled Actor does not have an item named ${itemName}`); + } + const item = items[0]; + + // Trigger the item roll + if ( item.data.type === "spell" ) return actor.useSpell(item); + return item.roll(); + } + \ No newline at end of file diff --git a/src/ose.js b/src/ose.js index 632448a..16be833 100644 --- a/src/ose.js +++ b/src/ose.js @@ -9,6 +9,7 @@ import { OSE } from "./module/config.js"; import { registerSettings } from './module/settings.js'; import { registerHelpers } from './module/helpers.js'; import * as chat from "./module/chat.js"; +import * as macros from "./module/macros.js"; /* -------------------------------------------- */ /* Foundry VTT Initialization */ @@ -56,7 +57,7 @@ Hooks.once("init", async function () { */ Hooks.once("setup", function () { // Localize CONFIG objects once up-front - const toLocalize = ["saves_short", "saves_long", "scores"]; + const toLocalize = ["saves_short", "saves_long", "scores", "armor"]; for (let o of toLocalize) { CONFIG.OSE[o] = Object.entries(CONFIG.OSE[o]).reduce((obj, e) => { obj[e[0]] = game.i18n.localize(e[1]); @@ -65,5 +66,9 @@ Hooks.once("setup", function () { } }); +Hooks.once("ready", () => { + Hooks.on("hotbarDrop", (bar, data, slot) => macros.createOseMacro(data, slot)); +}); + Hooks.on("renderChatLog", (app, html, data) => OseItem.chatListeners(html)); Hooks.on("getChatLogEntryContext", chat.addChatMessageContextOptions); \ No newline at end of file diff --git a/src/template.json b/src/template.json index 93a7cc5..6e7ad2e 100644 --- a/src/template.json +++ b/src/template.json @@ -178,6 +178,7 @@ "description": "", "ac": 9, "aac": 10, + "type": "light", "cost": 0, "equipped": false, "weight": 0 @@ -196,6 +197,7 @@ "ability": { "requirements": "", "roll": "", + "blindroll": false, "description": "" } } diff --git a/src/templates/chat/item-card.html b/src/templates/chat/item-card.html index 6d753ea..ab746e9 100644 --- a/src/templates/chat/item-card.html +++ b/src/templates/chat/item-card.html @@ -29,7 +29,7 @@ {{/if}} {{#if data.roll}} - + {{/if}} diff --git a/src/templates/items/ability-sheet.html b/src/templates/items/ability-sheet.html index b675edf..bed477b 100644 --- a/src/templates/items/ability-sheet.html +++ b/src/templates/items/ability-sheet.html @@ -22,6 +22,12 @@ +
+ +
+ +
+
{{editor content=data.description target="data.description" button=true diff --git a/src/templates/items/armor-sheet.html b/src/templates/items/armor-sheet.html index 2afc332..cb9e630 100644 --- a/src/templates/items/armor-sheet.html +++ b/src/templates/items/armor-sheet.html @@ -22,6 +22,19 @@
+
+ +
+ +
+