[V14] Update duality and fate chat commands (#1759)

* Update duality and fate chat commands for v14

* FateRoll withfear/withHope wasn't working after merging with v14-Dev. Fixed

---------

Co-authored-by: WBHarry <williambjrklund@gmail.com>
This commit is contained in:
Carlos Fernandez 2026-03-31 11:26:45 -04:00 committed by GitHub
parent f156b12d79
commit 259b66236c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 84 additions and 80 deletions

View file

@ -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,
@ -335,78 +332,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);

View file

@ -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(),

View file

@ -44,13 +44,11 @@ export default class FateRoll extends D20Roll {
}
get withHope() {
if (!this._evaluatedl) return;
return this.dHope.total >= this.dFear.total;
return this.data.fateType === 'Hope';
}
get withFear() {
if (!this._evaluated) return;
return this.dHope.total < this.dFear.total;
return this.data.fateType === 'Fear';
}
get totalLabel() {