From 3a7e355d06f4c1ea6044ff981e73c0c4d045b883 Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Tue, 31 Mar 2026 02:21:13 -0400 Subject: [PATCH] Update duality and fate chat commands for v14 --- daggerheart.mjs | 75 --------------------------- module/applications/ui/chatLog.mjs | 83 +++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 76 deletions(-) diff --git a/daggerheart.mjs b/daggerheart.mjs index 0bbbd274..77dad7e8 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -9,10 +9,7 @@ import * as dice from './module/dice/_module.mjs'; import * as fields from './module/data/fields/_module.mjs'; import RegisterHandlebarsHelpers from './module/helpers/handlebarsHelper.mjs'; import { enricherConfig, enricherRenderSetup } from './module/enrichers/_module.mjs'; -import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs'; import { BaseRoll, DHRoll, DualityRoll, D20Roll, DamageRoll, FateRoll } from './module/dice/_module.mjs'; -import { enrichedDualityRoll } from './module/enrichers/DualityRollEnricher.mjs'; -import { enrichedFateRoll, getFateTypeData } from './module/enrichers/FateRollEnricher.mjs'; import { handlebarsRegistration, runMigrations, @@ -333,78 +330,6 @@ Hooks.on('renderHandlebarsApplication', (_, element) => { enricherRenderSetup(element); }); -Hooks.on('chatMessage', (_, message) => { - if (message.startsWith('/dr')) { - const result = - message.trim().toLowerCase() === '/dr' ? { result: {} } : rollCommandToJSON(message.replace(/\/dr\s?/, '')); - if (!result) { - ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.dualityParsing')); - return false; - } - - const { result: rollCommand, flavor } = result; - - const reaction = rollCommand.reaction; - const traitValue = rollCommand.trait?.toLowerCase(); - const advantage = rollCommand.advantage - ? CONFIG.DH.ACTIONS.advantageState.advantage.value - : rollCommand.disadvantage - ? CONFIG.DH.ACTIONS.advantageState.disadvantage.value - : undefined; - const difficulty = rollCommand.difficulty; - const grantResources = rollCommand.grantResources; - - const target = getCommandTarget({ allowNull: true }); - const title = - (flavor ?? traitValue) - ? game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { - ability: game.i18n.localize(SYSTEM.ACTOR.abilities[traitValue].label) - }) - : game.i18n.localize('DAGGERHEART.GENERAL.duality'); - - enrichedDualityRoll({ - reaction, - traitValue, - target, - difficulty, - title, - label: game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll'), - actionType: null, - advantage, - grantResources - }); - return false; - } - - if (message.startsWith('/fr')) { - const result = - message.trim().toLowerCase() === '/fr' ? { result: {} } : rollCommandToJSON(message.replace(/\/fr\s?/, '')); - - if (!result) { - ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateParsing')); - return false; - } - - const { result: rollCommand, flavor } = result; - const fateTypeData = getFateTypeData(rollCommand?.type); - - if (!fateTypeData) - return ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateTypeParsing')); - - const { value: fateType, label: fateTypeLabel } = fateTypeData; - const target = getCommandTarget({ allowNull: true }); - const title = flavor ?? game.i18n.localize('DAGGERHEART.GENERAL.fateRoll'); - - enrichedFateRoll({ - target, - title, - label: fateTypeLabel, - fateType - }); - return false; - } -}); - Hooks.on(CONFIG.DH.HOOKS.hooksConfig.tagTeamStart, async data => { if (data.openForAllPlayers && data.partyId) { const party = game.actors.get(data.partyId); diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index e29498e6..82300d03 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -1,5 +1,8 @@ import { abilities } from '../../config/actorConfig.mjs'; -import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; +import { enrichedDualityRoll } from '../../enrichers/DualityRollEnricher.mjs'; +import { enrichedFateRoll, getFateTypeData } from '../../enrichers/FateRollEnricher.mjs'; +import { getCommandTarget, rollCommandToJSON } from '../../helpers/utils.mjs'; +import { emitAsGM, GMUpdateEvent } from '../../systemRegistration/socket.mjs'; export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLog { constructor(options) { @@ -21,6 +24,84 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo classes: ['daggerheart'] }; + static CHAT_COMMANDS = { + ...super.CHAT_COMMANDS, + dr: { + rgx: /^(?:\/dr)((?:\s)[^]*)?/, + fn: (_, match) => { + const argString = match[1]?.trim(); + const result = argString ? rollCommandToJSON(argString) : { result: {} }; + if (!result) { + ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.dualityParsing')); + return false; + } + + const { result: rollCommand, flavor } = result; + + const reaction = rollCommand.reaction; + const traitValue = rollCommand.trait?.toLowerCase(); + const advantage = rollCommand.advantage + ? CONFIG.DH.ACTIONS.advantageState.advantage.value + : rollCommand.disadvantage + ? CONFIG.DH.ACTIONS.advantageState.disadvantage.value + : undefined; + const difficulty = rollCommand.difficulty; + const grantResources = rollCommand.grantResources; + + const target = getCommandTarget({ allowNull: true }); + const title = + (flavor ?? traitValue) + ? game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { + ability: game.i18n.localize(SYSTEM.ACTOR.abilities[traitValue].label) + }) + : game.i18n.localize('DAGGERHEART.GENERAL.duality'); + + enrichedDualityRoll({ + reaction, + traitValue, + target, + difficulty, + title, + label: game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll'), + actionType: null, + advantage, + grantResources + }); + return false; + } + }, + fr: { + rgx: /^(?:\/fr)((?:\s)[^]*)?/, + fn: (_, match) => { + const argString = match[1]?.trim(); + const result = argString ? rollCommandToJSON(argString) : { result: {} }; + + if (!result) { + ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateParsing')); + return false; + } + + const { result: rollCommand, flavor } = result; + const fateTypeData = getFateTypeData(rollCommand?.type); + + if (!fateTypeData) + return ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateTypeParsing')); + + const { value: fateType, label: fateTypeLabel } = fateTypeData; + const target = getCommandTarget({ allowNull: true }); + const title = flavor ?? game.i18n.localize('DAGGERHEART.GENERAL.fateRoll'); + + enrichedFateRoll({ + target, + title, + label: fateTypeLabel, + fateType + }); + return false; + } + } + }; + _getEntryContextOptions() { return [ ...super._getEntryContextOptions(),