From 80744381f5494b47873c19cfa3d996019a516195 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Fri, 25 Jul 2025 00:06:41 +0200 Subject: [PATCH] [Fix] 397 - Reroll Improvements (#400) * Fixed reroll correcting automation hope/fear/stress * Fixed advantage/disadvantage reroll counting on d20s --- lang/en.json | 3 ++- module/applications/ui/chatLog.mjs | 10 ++++++--- module/dice/d20Roll.mjs | 31 +++++++++++++++++++++++++++- module/dice/dhRoll.mjs | 5 +++++ module/dice/dualityRoll.mjs | 19 +++++++++++++++-- styles/less/ui/chat/chat.less | 20 ++++++++++++++++++ templates/ui/chat/adversary-roll.hbs | 3 +++ templates/ui/chat/duality-roll.hbs | 2 ++ 8 files changed, 86 insertions(+), 7 deletions(-) diff --git a/lang/en.json b/lang/en.json index 8af39fa3..bf2f0fc3 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1695,7 +1695,8 @@ "makeDeathMove": "Make a Death Move", "rangeAndTarget": "Range & Target", "dragApplyEffect": "Drag effect to apply it to an actor", - "appliedEvenIfSuccessful": "Applied even if save succeeded" + "appliedEvenIfSuccessful": "Applied even if save succeeded", + "diceIsRerolled": "The dice has been rerolled (x{times})" } } } diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index bcdff961..c1801097 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -47,13 +47,13 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo element.addEventListener('click', this.onToggleTargets) ); html.querySelectorAll('.ability-use-button').forEach(element => - element.addEventListener('click', event => this.abilityUseButton(this, event, data.message)) + element.addEventListener('click', event => this.abilityUseButton(event, data.message)) ); html.querySelectorAll('.action-use-button').forEach(element => - element.addEventListener('click', event => this.actionUseButton(this, event, data.message)) + element.addEventListener('click', event => this.actionUseButton(event, data.message)) ); html.querySelectorAll('.reroll-button').forEach(element => - element.addEventListener('click', event => this.rerollEvent(this, event, data.message)) + element.addEventListener('click', event => this.rerollEvent(event, data.message)) ); }; @@ -271,6 +271,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo } async rerollEvent(event, message) { + event.stopPropagation(); if (!event.shiftKey) { const confirmed = await foundry.applications.api.DialogV2.confirm({ window: { @@ -287,6 +288,9 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo game.system.api.dice[ message.type === 'dualityRoll' ? 'DualityRoll' : target.dataset.type === 'damage' ? 'DHRoll' : 'D20Roll' ]; + + if (!game.modules.get('dice-so-nice')?.active) foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice }); + const { newRoll, parsedRoll } = await rollClass.reroll(originalRoll_parsed, target, message); await game.messages.get(message._id).update({ diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index 5f95b80d..dcf0143a 100644 --- a/module/dice/d20Roll.mjs +++ b/module/dice/d20Roll.mjs @@ -1,4 +1,5 @@ import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; +import { getDiceSoNicePresets } from '../config/generalConfig.mjs'; import DHRoll from './dhRoll.mjs'; export default class D20Roll extends DHRoll { @@ -156,6 +157,14 @@ export default class D20Roll extends DHRoll { dice: roll.dAdvantage?.denomination, value: roll.dAdvantage?.total }; + data.dice = data.dice.map(dice => ({ + ...dice, + results: dice.results.filter(x => !x.rerolled), + rerolled: { + any: dice.results.some(x => x.rerolled), + rerolls: dice.results.filter(x => x.rerolled) + } + })); data.isCritical = roll.isCritical; data.extra = roll.dice .filter(d => !roll.baseTerms.includes(d)) @@ -188,6 +197,26 @@ export default class D20Roll extends DHRoll { await game.dice3d.showForRoll(parsedRoll, game.user, true); } - return { newRoll, parsedRoll }; + const rerolled = { + any: true, + rerolls: [ + ...(message.system.roll.dice[0].rerolled?.rerolls?.length > 0 + ? [message.system.roll.dice[0].rerolled?.rerolls] + : []), + rollString.terms[0].results + ] + }; + return { + newRoll: { + ...newRoll, + dice: [ + { + ...newRoll.dice[0], + rerolled: rerolled + } + ] + }, + parsedRoll + }; } } diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index c50c126a..52759316 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -193,6 +193,11 @@ export const registerRollDiceHooks = () => { if (config.roll.isCritical) updates.push({ key: 'stress', value: -1 }); if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1 }); + if (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1) + updates.push({ key: 'hope', value: -1 }); + if (config.rerolledRoll.isCritical) updates.push({ key: 'stress', value: 1 }); + if (config.rerolledRoll.result.duality === -1) updates.push({ key: 'fear', value: -1 }); + if (updates.length) { const target = actor.system.partner ?? actor; if (!['dead', 'unconcious'].some(x => actor.statuses.has(x))) { diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 151d63df..1c414a63 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -171,11 +171,19 @@ export default class DualityRoll extends D20Roll { data.hope = { dice: roll.dHope.denomination, - value: roll.dHope.total + value: roll.dHope.total, + rerolled: { + any: roll.dHope.results.some(x => x.rerolled), + rerolls: roll.dHope.results.filter(x => x.rerolled) + } }; data.fear = { dice: roll.dFear.denomination, - value: roll.dFear.total + value: roll.dFear.total, + rerolled: { + any: roll.dFear.results.some(x => x.rerolled), + rerolls: roll.dFear.results.filter(x => x.rerolled) + } }; data.rally = { dice: roll.dRally?.denomination, @@ -232,6 +240,13 @@ export default class DualityRoll extends D20Roll { }); newRoll.extra = newRoll.extra.slice(2); + Hooks.call(`${CONFIG.DH.id}.postRollDuality`, { + source: { actor: message.system.source.actor ?? '' }, + targets: message.system.targets, + roll: newRoll, + rerolledRoll: + newRoll.result.duality !== message.system.roll.result.duality ? message.system.roll : undefined + }); return { newRoll, parsedRoll }; } } diff --git a/styles/less/ui/chat/chat.less b/styles/less/ui/chat/chat.less index c593a919..4558cf8e 100644 --- a/styles/less/ui/chat/chat.less +++ b/styles/less/ui/chat/chat.less @@ -62,6 +62,17 @@ } &.rerollable { + position: relative; + flex: none; + + .dice-rerolled { + z-index: 2; + position: absolute; + right: 0; + font-size: 12px; + cursor: help; + } + .reroll-button { border: none; background: initial; @@ -85,12 +96,21 @@ display: flex; flex-direction: column; gap: 2px; + position: relative; .dice-title { color: var(--color-light-1); text-shadow: 0 0 1px black; } + .dice-rerolled { + z-index: 2; + position: absolute; + right: -2px; + font-size: 12px; + cursor: help; + } + .dice-inner-container { display: flex; align-items: center; diff --git a/templates/ui/chat/adversary-roll.hbs b/templates/ui/chat/adversary-roll.hbs index acf9a759..63187a52 100644 --- a/templates/ui/chat/adversary-roll.hbs +++ b/templates/ui/chat/adversary-roll.hbs @@ -13,6 +13,9 @@
    + {{#if dice.rerolled.any}} + + {{/if}}