import { SYSTEM } from "../config/system.mjs" export default class OathHammerMiracleDialog { static async prompt(actor, miracle) { const sys = miracle.system const actorSys = actor.system const wpRank = actorSys.attributes.willpower.rank const magicRank = actorSys.skills.magic.rank const basePool = wpRank + magicRank const isRitual = sys.isRitual const dv = isRitual ? (sys.difficultyValue || 1) : null const traditionLabel = (() => { const key = SYSTEM.DIVINE_TRADITIONS?.[sys.divineTradition] return key ? game.i18n.localize(key) : sys.divineTradition })() // Miracle count options — DV = miracle number today const miracleCountOptions = Array.from({ length: 10 }, (_, i) => ({ value: i + 1, label: `${i + 1}${_ordinal(i + 1)} — DV${i + 1}`, selected: i === 0, })) const bonusOptions = Array.from({ length: 13 }, (_, i) => { const v = i - 6 return { value: v, label: v > 0 ? `+${v}` : String(v), selected: v === 0 } }) const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes) const context = { actorName: actor.name, miracleName: miracle.name, miracleImg: miracle.img, dv, traditionLabel, isRitual, range: sys.range, duration: sys.duration, spellSave: sys.spellSave, wpRank, magicRank, basePool, miracleCountOptions, bonusOptions, rollModes, visibility: game.settings.get("core", "rollMode"), } const content = await foundry.applications.handlebars.renderTemplate( "systems/fvtt-oath-hammer/templates/miracle-cast-dialog.hbs", context ) const result = await foundry.applications.api.DialogV2.wait({ window: { title: game.i18n.format("OATHHAMMER.Dialog.MiracleCastTitle", { miracle: miracle.name }) }, classes: ["fvtt-oath-hammer"], content, rejectClose: false, buttons: [{ label: game.i18n.localize("OATHHAMMER.Dialog.InvokeMiracle"), callback: (_ev, btn) => { const out = {} for (const el of btn.form.elements) { if (!el.name) continue out[el.name] = el.type === "checkbox" ? String(el.checked) : el.value } return out }, }], }) if (!result) return null const computedDV = isRitual ? dv : (parseInt(result.miracleCount) || 1) return { dv: computedDV, isRitual, bonus: parseInt(result.bonus) || 0, visibility: result.visibility ?? game.settings.get("core", "rollMode"), explodeOn5: result.explodeOn5 === "true", } } } function _ordinal(n) { const s = ["th", "st", "nd", "rd"] const v = n % 100 return s[(v - 20) % 10] ?? s[v] ?? s[0] }