fix(actor): prevent double ActiveEffect application in prepareData cycle
- Move wound data initialization to prepareBaseData() (before effects are applied) - Initialize combatStatus in prepareBaseData() to prevent undefined errors - Add protection against recursive effect application in prepareEmbeddedDocuments() - This prevents the 'ActiveEffect application phase has already completed' error The error occurred because modify data in prepareDerivedData() (like combatStatus) could trigger observers that try to re-apply effects during the same cycle. By initializing all required data in prepareBaseData() and protecting prepareEmbeddedDocuments() from recursive calls, we ensure effects are applied exactly once per preparation cycle. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
+52
-17
@@ -6,19 +6,37 @@
|
||||
export class VermineActor extends Actor {
|
||||
|
||||
/** @override */
|
||||
prepareData() {
|
||||
// Prepare data for the actor. Calling the super version of this executes
|
||||
// the following, in order: data reset (to clear active effects),
|
||||
// prepareBaseData(), prepareEmbeddedDocuments() (including active effects),
|
||||
// prepareDerivedData().
|
||||
prepareBaseData() {
|
||||
// Data modifications in this step occur before processing embedded
|
||||
// documents or derived data.
|
||||
|
||||
// Initialize wound data to prevent undefined errors with active effects
|
||||
if (!this.system.minorWound) this.system.minorWound = { value: 0, min: 0, max: 5, threshold: 1 };
|
||||
if (!this.system.majorWound) this.system.majorWound = { value: 0, min: 0, max: 4, threshold: 4 };
|
||||
if (!this.system.deadlyWound) this.system.deadlyWound = { value: 0, min: 0, max: 2, threshold: 8 };
|
||||
|
||||
super.prepareData();
|
||||
// Initialize combatStatus to prevent errors
|
||||
if (!this.system.combatStatus) {
|
||||
this.system.combatStatus = { difficulty: "9", label: "Passif" };
|
||||
}
|
||||
|
||||
if (this.type == 'character') {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/** @override */
|
||||
prepareEmbeddedDocuments() {
|
||||
// Prevent recursive effect application
|
||||
// Foundry V11+ can sometimes call this multiple times in a preparation cycle
|
||||
if (this._preparingEffects) return;
|
||||
this._preparingEffects = true;
|
||||
|
||||
try {
|
||||
super.prepareEmbeddedDocuments();
|
||||
} finally {
|
||||
delete this._preparingEffects;
|
||||
}
|
||||
}
|
||||
|
||||
/** @override */
|
||||
@@ -86,20 +104,37 @@ export class VermineActor extends Actor {
|
||||
}
|
||||
prepareCombatStatus() {
|
||||
// Ensure combatStatus exists (defined in base template)
|
||||
if (!this.system.combatStatus) return;
|
||||
if (!this.system.combatStatus) {
|
||||
this.system.combatStatus = { difficulty: "9", label: "Passif" };
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure difficulty exists
|
||||
if (!this.system.combatStatus.difficulty) {
|
||||
this.system.combatStatus.difficulty = "9";
|
||||
}
|
||||
|
||||
//combat initiative reaction difficulty
|
||||
switch (parseInt(this.system.combatStatus.difficulty)) {
|
||||
case 5: this.system.combatStatus.label = "Offensif";
|
||||
break;
|
||||
case 7: this.system.combatStatus.label = "Actif";
|
||||
break;
|
||||
case 9: this.system.combatStatus.label = "Passif";
|
||||
break;
|
||||
default:
|
||||
this.system.combatStatus.label = "Passif";
|
||||
const difficulty = parseInt(this.system.combatStatus.difficulty) || 9;
|
||||
|
||||
// Only update if values are different to avoid triggering unnecessary updates
|
||||
const currentLabel = this.system.combatStatus.label;
|
||||
let newLabel = "Passif";
|
||||
|
||||
switch (difficulty) {
|
||||
case 5: newLabel = "Offensif"; break;
|
||||
case 7: newLabel = "Actif"; break;
|
||||
case 9: newLabel = "Passif"; break;
|
||||
}
|
||||
|
||||
// Only update if label changed
|
||||
if (currentLabel !== newLabel) {
|
||||
this.system.combatStatus.label = newLabel;
|
||||
}
|
||||
|
||||
// Only update difficulty if it was undefined or invalid
|
||||
if (!this.system.combatStatus.difficulty || isNaN(parseInt(this.system.combatStatus.difficulty))) {
|
||||
this.system.combatStatus.difficulty = "9";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user