Compare commits

..

2 Commits

Author SHA1 Message Date
uberwald 5734f3a5e3 Fix layperson skills ate character creation
Release Creation / build (release) Successful in 53s
2026-07-07 08:30:23 +02:00
uberwald 7675c47ff9 fix: persist rollType/actorId on rollBase.options, re-evaluate canReroll after mulligan
Release Creation / build (release) Failing after 2m9s
- roll-prompt.mjs: explicitly save rollType, actorId, actorName, actorImage
  to rollBase.options so mulligan reroll context reads valid values
- chat-reaction.mjs: replace canRerollDefense/canRerollAttack = false with
  recomputation from updated D30 message — aligns same-client with
  cross-client behavior (new D30 always takes effect, mulligan chain loops)
2026-07-06 08:56:58 +02:00
3 changed files with 14 additions and 9 deletions
+4 -2
View File
@@ -7,8 +7,10 @@ export default class LethalFantasyActor extends Actor {
if (data instanceof Array) { if (data instanceof Array) {
return super.create(data, options); return super.create(data, options);
} }
// If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic // If the created actor already has items (duplicated or imported) bypass the new actor creation logic.
if (data.items) { // Use .length check because Foundry V2 initializes data.items as an empty array by default
// (truthy), which would incorrectly skip the layperson skill auto-population.
if (data.items?.length > 0) {
let actor = super.create(data, options); let actor = super.create(data, options);
return actor; return actor;
} }
+4
View File
@@ -570,6 +570,10 @@ export async function prompt(options = {}) {
rollBase.options.D30result = options.D30result rollBase.options.D30result = options.D30result
rollBase.options.D30message = options.D30message rollBase.options.D30message = options.D30message
rollBase.options.badResult = badResult rollBase.options.badResult = badResult
rollBase.options.rollType = options.rollType
rollBase.options.actorId = options.actorId
rollBase.options.actorName = options.actorName
rollBase.options.actorImage = options.actorImage
rollBase.options.rollData = foundry.utils.duplicate(rollData) rollBase.options.rollData = foundry.utils.duplicate(rollData)
rollBase.options.defenderId = options.defenderId rollBase.options.defenderId = options.defenderId
rollBase.options.defenderTokenId = options.defenderTokenId rollBase.options.defenderTokenId = options.defenderTokenId
+6 -7
View File
@@ -549,7 +549,6 @@ Hooks.on("createChatMessage", async (message) => {
if (choice === "rerollDefense" && canRerollDefense) { if (choice === "rerollDefense" && canRerollDefense) {
const oldDefenseRoll = defenseRoll const oldDefenseRoll = defenseRoll
const reroll = await LethalFantasyUtils.rerollConfiguredRoll(defenseRerollContext) const reroll = await LethalFantasyUtils.rerollConfiguredRoll(defenseRerollContext)
canRerollDefense = false
if (!reroll) continue if (!reroll) continue
defenseRoll = reroll.options?.rollTotal || reroll.total || oldDefenseRoll defenseRoll = reroll.options?.rollTotal || reroll.total || oldDefenseRoll
try { try {
@@ -566,12 +565,13 @@ Hooks.on("createChatMessage", async (message) => {
} catch(e) { } catch(e) {
console.error("Mulligan message creation failed (non-fatal):", e) console.error("Mulligan message creation failed (non-fatal):", e)
} }
// Apply new D30 result on the restart // Apply new D30 result on the restart — the new D30 always takes effect,
// and if it's another mulligan the reroll button reappears.
if (reroll.options?.D30message) { if (reroll.options?.D30message) {
defenseD30message = reroll.options.D30message defenseD30message = reroll.options.D30message
defenseD30Processed = false defenseD30Processed = false
} }
// Restart the full comparison so both sides can react to the new roll canRerollDefense = LethalFantasyUtils.hasD30Reroll(defenseD30message)
mulliganRestart = true mulliganRestart = true
break break
} }
@@ -755,7 +755,6 @@ Hooks.on("createChatMessage", async (message) => {
if (choice === "rerollAttack" && canRerollAttack && attackRerollContext) { if (choice === "rerollAttack" && canRerollAttack && attackRerollContext) {
const oldAttackRoll = attackRollFinal const oldAttackRoll = attackRollFinal
const reroll = await LethalFantasyUtils.rerollConfiguredRoll(attackRerollContext) const reroll = await LethalFantasyUtils.rerollConfiguredRoll(attackRerollContext)
canRerollAttack = false
if (!reroll) continue if (!reroll) continue
attackRollFinal = reroll.options?.rollTotal || reroll.total || oldAttackRoll attackRollFinal = reroll.options?.rollTotal || reroll.total || oldAttackRoll
try { try {
@@ -772,14 +771,14 @@ Hooks.on("createChatMessage", async (message) => {
} catch(e) { } catch(e) {
console.error("Mulligan message creation failed (non-fatal):", e) console.error("Mulligan message creation failed (non-fatal):", e)
} }
// Apply new D30 result on the restart // Apply new D30 result on the restart — the new D30 always takes effect,
// and if it's another mulligan the reroll button reappears.
if (reroll.options?.D30message) { if (reroll.options?.D30message) {
attackD30message = reroll.options.D30message attackD30message = reroll.options.D30message
attackD30Processed = false attackD30Processed = false
// Invalidate pre-computed effects — the new D30 message must be processed fresh
d30AttackPrecomputedStale = true d30AttackPrecomputedStale = true
} }
// Restart the full comparison so both sides can react to the new roll canRerollAttack = LethalFantasyUtils.hasD30Reroll(attackD30message)
mulliganRestart = true mulliganRestart = true
break break
} }