Initial release
This commit is contained in:
@@ -97,15 +97,18 @@ export default class MGNERoll {
|
||||
|
||||
const modifier = Number.parseInt(dialogData.modifier ?? 0, 10) || 0
|
||||
const spendOmen = Boolean(dialogData.spendOmen)
|
||||
const dr = (Number.parseInt(dialogData.dr ?? baseDR, 10) || baseDR) - (spendOmen ? 4 : 0)
|
||||
// Re-read omens after dialog close to avoid race condition (omen could have changed)
|
||||
const currentOmensAfterDialog = actor.system.omens?.current ?? 0
|
||||
const canSpendOmen = spendOmen && currentOmensAfterDialog > 0
|
||||
const dr = (Number.parseInt(dialogData.dr ?? baseDR, 10) || baseDR) - (canSpendOmen ? 4 : 0)
|
||||
const abilityValue = actor.system.abilities?.[abilityId]?.value ?? 0
|
||||
const sign = modifier >= 0 ? "+" : "-"
|
||||
const formula = modifier === 0 ? `1d20 + ${abilityValue}` : `1d20 + ${abilityValue} ${sign} ${Math.abs(modifier)}`
|
||||
const roll = await (new Roll(formula)).evaluate()
|
||||
const natural = roll.dice?.[0]?.results?.[0]?.result ?? roll.total
|
||||
|
||||
if (spendOmen && (actor.system.omens?.current ?? 0) > 0) {
|
||||
await actor.update({ "system.omens.current": Math.max(0, actor.system.omens.current - 1) })
|
||||
if (canSpendOmen) {
|
||||
await actor.update({ "system.omens.current": Math.max(0, currentOmensAfterDialog - 1) })
|
||||
}
|
||||
|
||||
const critical = natural === 20
|
||||
@@ -126,6 +129,15 @@ export default class MGNERoll {
|
||||
specialText = rollType === "attack" ? t("MGNE.Roll.AttackFumble") : rollType === "defense" ? t("MGNE.Roll.DefenseFumble") : pickRandom(SYSTEM.tables.mishaps)
|
||||
}
|
||||
|
||||
const actorOmens = actor.system.omens?.current ?? 0
|
||||
let omenNeutralizeReminder = ""
|
||||
let omenRerollReminder = ""
|
||||
if (actorOmens > 0) {
|
||||
if (critical) omenNeutralizeReminder = f("MGNE.Roll.OmenNeutralizeCrit", { omens: actorOmens })
|
||||
else if (fumble) omenNeutralizeReminder = f("MGNE.Roll.OmenNeutralizeFumble", { omens: actorOmens })
|
||||
else omenRerollReminder = f("MGNE.Roll.OmenRerollReminder", { omens: actorOmens })
|
||||
}
|
||||
|
||||
const showDamageButton = rollType === "attack" && (success || critical) && !!item
|
||||
const contentHtml = await renderCard({
|
||||
mode: "check",
|
||||
@@ -137,6 +149,8 @@ export default class MGNERoll {
|
||||
total: roll.total,
|
||||
outcome,
|
||||
specialText,
|
||||
omenNeutralizeReminder,
|
||||
omenRerollReminder,
|
||||
showDamageButton,
|
||||
damageActorId: showDamageButton ? actor.id : null,
|
||||
damageItemId: showDamageButton ? item.id : null,
|
||||
@@ -183,7 +197,30 @@ export default class MGNERoll {
|
||||
const multiplier = damageBonus?.multiplier ?? 1
|
||||
const baseFormula = item.system.damage || "1"
|
||||
const formula = multiplier > 1 ? `${multiplier} * (${baseFormula})` : baseFormula
|
||||
const roll = await (new Roll(formula)).evaluate()
|
||||
|
||||
const actorOmens = actor.system.omens?.current ?? 0
|
||||
let maximize = false
|
||||
if (actorOmens > 0) {
|
||||
const choice = await foundry.applications.api.DialogV2.wait({
|
||||
window: { title: f("MGNE.Roll.ItemDamageLabel", { item: item.name }) },
|
||||
classes: ["mgne", "roll-dialog"],
|
||||
content: `<section class="mgne-roll-dialog"><p>${f("MGNE.RollDialog.OmenMaximizePrompt", { omens: actorOmens })}</p></section>`,
|
||||
buttons: [
|
||||
{ action: "roll", label: t("MGNE.Common.Roll"), icon: "fa-solid fa-dice", callback: () => "roll" },
|
||||
{ action: "maximize", label: t("MGNE.RollDialog.SpendOmenMaximize"), icon: "fa-solid fa-star", callback: () => "maximize" },
|
||||
],
|
||||
rejectClose: false,
|
||||
})
|
||||
if (choice === null) return null
|
||||
maximize = choice === "maximize"
|
||||
}
|
||||
|
||||
const roll = await (new Roll(formula)).evaluate(maximize ? { maximize: true } : {})
|
||||
if (maximize) {
|
||||
// Re-read omens after dialog to avoid overwriting concurrent changes
|
||||
const currentOmens = actor.system.omens?.current ?? 0
|
||||
await actor.update({ "system.omens.current": Math.max(0, currentOmens - 1) })
|
||||
}
|
||||
const isCritical = multiplier > 1
|
||||
const contentHtml = await renderCard({
|
||||
mode: "damage",
|
||||
@@ -195,6 +232,7 @@ export default class MGNERoll {
|
||||
total: roll.total,
|
||||
outcome: t("MGNE.Roll.OutcomeRolled"),
|
||||
specialText: isCritical ? t("MGNE.Roll.CriticalDamageApplied") : "",
|
||||
omenMaximized: maximize,
|
||||
showApplyButton: true,
|
||||
damageTotal: roll.total,
|
||||
damageCritical: isCritical,
|
||||
|
||||
Reference in New Issue
Block a user