From f55698af02ae8d80d79b2af40dd28d0e02d85346 Mon Sep 17 00:00:00 2001 From: Psitacus <59754077+Psitacus@users.noreply.github.com> Date: Sun, 27 Jul 2025 15:26:55 -0600 Subject: [PATCH] Fix duality roll (#436) * allow /dr and [[/dr]] to be rolled without selection * fix weird ternary * Fixed so trait modifier comes along correctly --------- Co-authored-by: psitacus Co-authored-by: WBHarry --- daggerheart.mjs | 2 +- module/applications/dialogs/d20RollDialog.mjs | 5 +++-- module/enrichers/DualityRollEnricher.mjs | 16 +++++++++++----- module/helpers/utils.mjs | 13 ++++++++----- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/daggerheart.mjs b/daggerheart.mjs index 20557fde..bf8a9f63 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -202,7 +202,7 @@ Hooks.on('chatMessage', (_, message) => { : undefined; const difficulty = rollCommand.difficulty; - const target = getCommandTarget(); + const target = getCommandTarget({ allowNull: true }); const title = traitValue ? game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { ability: game.i18n.localize(SYSTEM.ACTOR.abilities[traitValue].label) diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs index 05ca1505..76871b6a 100644 --- a/module/applications/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -91,9 +91,10 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio context.roll = this.roll; context.rollType = this.roll?.constructor.name; context.rallyDie = this.roll.rallyChoices; - context.experiences = Object.keys(this.config.data.experiences).map(id => ({ + const experiences = this.config.data?.experiences || {}; + context.experiences = Object.keys(experiences).map(id => ({ id, - ...this.config.data.experiences[id] + ...experiences[id] })); context.selectedExperiences = this.config.experiences; context.advantage = this.config.roll?.advantage; diff --git a/module/enrichers/DualityRollEnricher.mjs b/module/enrichers/DualityRollEnricher.mjs index 690262ce..24dd0602 100644 --- a/module/enrichers/DualityRollEnricher.mjs +++ b/module/enrichers/DualityRollEnricher.mjs @@ -58,7 +58,7 @@ function getDualityMessage(roll) { export const renderDualityButton = async event => { const button = event.currentTarget, traitValue = button.dataset.trait?.toLowerCase(), - target = getCommandTarget(), + target = getCommandTarget({ allowNull: true }), difficulty = button.dataset.difficulty, advantage = button.dataset.advantage ? Number(button.dataset.advantage) : undefined; @@ -80,13 +80,11 @@ export const enrichedDualityRoll = async ( { traitValue, target, difficulty, title, label, actionType, advantage }, event ) => { - if (!target) return; - const config = { event: event ?? {}, title: title, roll: { - modifier: traitValue ? target.system.traits[traitValue].value : null, + trait: traitValue && target ? traitValue : null, label: label, difficulty: difficulty, advantage, @@ -96,5 +94,13 @@ export const enrichedDualityRoll = async ( template: 'systems/daggerheart/templates/ui/chat/duality-roll.hbs' } }; - await target.diceRoll(config); + + if (target) { + await target.diceRoll(config); + } else { + // For no target, call DualityRoll directly with basic data + config.data = { experiences: {}, traits: {} }; + config.source = { actor: null }; + await CONFIG.Dice.daggerheart.DualityRoll.build(config); + } }; diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 8a302013..30f360cf 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -31,21 +31,24 @@ export function rollCommandToJSON(text) { return Object.keys(result).length > 0 ? result : null; } -export const getCommandTarget = () => { +export const getCommandTarget = (options = {}) => { + const { allowNull = false } = options; let target = game.canvas.tokens.controlled.length > 0 ? game.canvas.tokens.controlled[0].actor : null; if (!game.user.isGM) { target = game.user.character; - if (!target) { + if (!target && !allowNull) { ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noAssignedPlayerCharacter')); return null; } } - if (!target) { + if (!target && !allowNull) { ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noSelectedToken')); return null; } - if (target.type !== 'character') { - ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.onlyUseableByPC')); + if (target && target.type !== 'character') { + if (!allowNull) { + ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.onlyUseableByPC')); + } return null; }