3df46b5848
- Extract all inline HTML from JS into 21 Handlebars templates (chat/, dialogs/, ui/) - Split utils.mjs (1507) into barrel + helpers.mjs, combat.mjs, d30.mjs - Split roll.mjs (1632) into barrel + roll-base.mjs, roll-prompt.mjs, roll-combat.mjs, roll-damage.mjs - Split lethal-fantasy.mjs (1426) into bootstrap + chat-reaction.mjs - Fix: missing async on injectDiceTray (free-roll.mjs:29 SyntaxError) - Fix: weapon._id fallback for deserialized chat-message weapon objects - Fix: missing await on rollModifier.evaluate() calls in roll-combat.mjs - Fix: choices→choicesList ReferenceError in utils.mjs - Fix: add 12 missing i18n keys (chooseWeapon, chooseSave, attackRoll, etc.) - Fix: restore sideLabel in bonus-die-select.hbs - Clean: remove dead messageContent param, console.log→log() - Style: barrel files preserve existing import paths
40 lines
1.6 KiB
JavaScript
40 lines
1.6 KiB
JavaScript
/**
|
|
* Evaluate a spell/miracle damage formula with per-die explosion, then post to chat.
|
|
* Explosion dice are shown manually via showForRoll; the main roll is shown automatically
|
|
* by toMessage() (which triggers Dice So Nice via its createChatMessage hook).
|
|
* Append "NE" to the formula to disable explosion.
|
|
*
|
|
* @param {string} formula Dice formula, e.g. "1d8", "2d6", "1d8NE"
|
|
* @param {Object} rollOpts Options for LethalFantasyRoll (rollType, actorId, defenderId, etc.)
|
|
* @returns {Promise<ChatMessage>}
|
|
*/
|
|
export async function rollSpellDamageToMessage(formula, rollOpts) {
|
|
const roll = new this(formula, {}, rollOpts)
|
|
await roll.evaluate()
|
|
const shouldExplode = !/NE$/i.test(formula)
|
|
const diceResults = []
|
|
let diceSum = 0
|
|
for (const term of roll.dice) {
|
|
const singleDice = `1D${term.faces}`
|
|
const termResults = Array.from(term.results)
|
|
for (const r of termResults) {
|
|
let diceResult = r.result
|
|
diceResults.push({ dice: singleDice.toUpperCase(), value: diceResult })
|
|
diceSum += diceResult
|
|
if (shouldExplode && term.faces > 0) {
|
|
while (diceResult === term.faces) {
|
|
const xr = await new Roll(singleDice).evaluate()
|
|
// Optional chaining guards against unexpected roll structure
|
|
diceResult = xr.dice?.[0]?.results?.[0]?.result ?? (term.faces - 1)
|
|
diceResults.push({ dice: `${singleDice.toUpperCase()}-1`, value: diceResult - 1 })
|
|
diceSum += (diceResult - 1)
|
|
term.results.push({ result: diceResult, active: true })
|
|
}
|
|
}
|
|
}
|
|
}
|
|
roll.options.diceResults = diceResults
|
|
roll.options.rollTotal = diceSum
|
|
return roll.toMessage()
|
|
}
|