Fix E dice in dice Tray
All checks were successful
Release Creation / build (release) Successful in 55s

This commit is contained in:
2026-04-17 23:21:49 +02:00
parent 7f15450566
commit b8174d5e22
26 changed files with 117 additions and 104 deletions

View File

@@ -75,39 +75,53 @@ export function injectDiceTray(_chatLog, html) {
/**
* Roll one or more dice of the given type and post the result to chat.
* For exploding dice, follows the Lethal Fantasy rule: each exploded reroll
* contributes (result 1) to the total, same as all other system rolls.
*
* @param {string} dieType Die face, e.g. "d20"
* @param {number} count Number of dice to roll (19)
* @param {boolean} explode Whether to use the exploding modifier (x = max-value explode)
* @param {boolean} explode Whether to use the exploding variant (max triggers reroll at 1)
* @returns {Promise<void>}
*/
export async function rollFreeDie(dieType, count = 1, explode = false) {
const sides = parseInt(dieType.replace("d", "")) || 20
const formula = explode ? `${count}d${sides}x` : `${count}d${sides}`
const baseFormula = `1d${sides}`
const label = explode
? `${count}${dieType.toUpperCase()}E`
: `${count}${dieType.toUpperCase()}`
const roll = new Roll(formula)
await roll.evaluate()
const results = roll.terms
.filter(t => t.results)
.flatMap(t => t.results)
const total = roll.total
const dieLabel = dieType.toUpperCase()
const resultHtml = results.map(r => {
const val = r.result
const isMax = val === sides
const isMin = val === 1
const explodeIcon = r.exploded ? `<i class="fa-solid fa-burst lf-dt-explode-icon"></i>` : ""
const dieChips = []
let total = 0
for (let i = 0; i < count; i++) {
const r0 = await new Roll(baseFormula).evaluate()
if (game?.dice3d) await game.dice3d.showForRoll(r0, game.user, true)
let diceResult = r0.dice[0].results[0].result
dieChips.push({ label: dieLabel, value: diceResult, exploded: false })
total += diceResult
if (explode) {
while (diceResult === sides) {
const rx = await new Roll(baseFormula).evaluate()
if (game?.dice3d) await game.dice3d.showForRoll(rx, game.user, true)
diceResult = rx.dice[0].results[0].result
const contrib = diceResult - 1
dieChips.push({ label: `${dieLabel}-1`, value: contrib, exploded: true })
total += contrib
}
}
}
const resultHtml = dieChips.map(chip => {
const isMax = !chip.exploded && chip.value === sides
const isMin = chip.value === 1
const explodeIcon = chip.exploded ? `<i class="fa-solid fa-burst lf-dt-explode-icon"></i>` : ""
const classes = ["lf-frc-die-chip", isMax ? "lf-frc-max" : "", isMin ? "lf-frc-min" : ""].filter(Boolean).join(" ")
return `<div class="${classes}">
<span class="lf-frc-die-type">${dieLabel}</span>
<span class="lf-frc-die-type">${chip.label}</span>
<span class="lf-frc-die-sep">→</span>
<span class="lf-frc-die-val">${val}${explodeIcon}</span>
<span class="lf-frc-die-val">${chip.value}${explodeIcon}</span>
</div>`
}).join("")
@@ -131,7 +145,6 @@ export async function rollFreeDie(dieType, count = 1, explode = false) {
const msgData = {
speaker: ChatMessage.getSpeaker(),
content,
rolls: [roll],
sound: CONFIG.sounds.dice,
}
ChatMessage.applyRollMode(msgData, rollMode)