From 72491891edc7fff5a48a4aca7b54dab69dbfef26 Mon Sep 17 00:00:00 2001 From: WBHarry Date: Thu, 24 Jul 2025 15:46:43 +0200 Subject: [PATCH] . --- lang/en.json | 3 +- module/applications/ui/chatLog.mjs | 1 + module/dice/d20Roll.mjs | 46 +++++++++++++++++++++++----- module/dice/dualityRoll.mjs | 15 +++++++-- styles/less/ui/chat/chat.less | 20 ++++++++++++ templates/ui/chat/adversary-roll.hbs | 3 ++ templates/ui/chat/duality-roll.hbs | 2 ++ 7 files changed, 79 insertions(+), 11 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 19834680..c1801097 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -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: { diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index 5f95b80d..42ce9dde 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)) @@ -173,9 +182,35 @@ export default class D20Roll extends DHRoll { return (this._formula = this.constructor.getFormula(this.terms)); } - static async reroll(rollString, _target, message) { - let parsedRoll = game.system.api.dice.D20Roll.fromData(rollString); - parsedRoll = await parsedRoll.reroll(); + static async reroll(rollString, target, message) { + let parsedRoll = game.system.api.dice.D20Roll.fromData({ ...rollString, evaluated: false }); + + const term = parsedRoll.terms[0]; + await term.reroll(`/r1=${term.total}`); + + if (game.modules.get('dice-so-nice')?.active) { + const diceSoNiceRoll = { + _evaluated: true, + dice: [ + new foundry.dice.terms.Die({ + ...term, + faces: term._faces, + results: term.results.filter(x => !x.rerolled) + }) + ], + options: { appearance: {} } + }; + + const diceSoNicePresets = getDiceSoNicePresets(); + const type = target.dataset.type; + if (diceSoNicePresets[type]) { + diceSoNiceRoll.dice[0].options = { appearance: diceSoNicePresets[type] }; + } + + await game.dice3d.showForRoll(diceSoNiceRoll, game.user, true); + } + await parsedRoll.evaluate(); + const newRoll = game.system.api.dice.D20Roll.postEvaluate(parsedRoll, { targets: message.system.targets, roll: { @@ -184,10 +219,7 @@ export default class D20Roll extends DHRoll { } }); - if (game.modules.get('dice-so-nice')?.active) { - await game.dice3d.showForRoll(parsedRoll, game.user, true); - } - + newRoll.extra = newRoll.extra.slice(1); return { newRoll, parsedRoll }; } } diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 91f2456c..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, @@ -236,7 +244,8 @@ export default class DualityRoll extends D20Roll { source: { actor: message.system.source.actor ?? '' }, targets: message.system.targets, roll: newRoll, - rerolledRoll: message.system.roll + 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}}