From bdb17cfac7685051a78e9bef17db5bbdd7178e2d Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Sat, 5 Nov 2022 02:42:01 +0100 Subject: [PATCH] fix: apply effects to embedded items after all embedded items have been prepared --- src/documents/actor/actor.ts | 31 +++++++++++++++++++++++++++---- src/documents/item/item.ts | 18 ------------------ 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/documents/actor/actor.ts b/src/documents/actor/actor.ts index 800885b4..0b1be492 100644 --- a/src/documents/actor/actor.ts +++ b/src/documents/actor/actor.ts @@ -28,13 +28,11 @@ declare global { * The Actor class for DS4 */ export class DS4Actor extends Actor { - initialized: boolean | undefined; - override prepareData(): void { - this.initialized = true; this.data.reset(); this.prepareBaseData(); this.prepareEmbeddedDocuments(); + this.applyActiveEffectsToItems(); this.applyActiveEffectsToBaseData(); this.prepareDerivedData(); this.applyActiveEffectsToDerivedData(); @@ -118,8 +116,33 @@ export class DS4Actor extends Actor { return; } + /** + * Apply active effects to items. + * + * @remarks + * Talents are handled before all other item types, because if the total rank of a talent is affected by any + * effects, that affects how many times effects provided by this talent need to be applied. At the moment, there is + * no special ordering among talents. This means that having a talents that provide effects that adjust the total + * rank of talents can lead to nondeterministic behavior and thus must be avoided. + */ + applyActiveEffectsToItems(): void { + /* Handle talents before all other item types, because their rank might be affected, which in turn affects how + many times effects provided by that talent are applied */ + for (const item of this.itemTypes.talent) { + this.applyActiveEffectsToItem(item); + } + for (const item of this.items) { + if (item.type === "talent") continue; + this.applyActiveEffectsToItem(item); + } + } + + protected applyActiveEffectsToItem(item: DS4Item) { + item.overrides = {}; + DS4ActiveEffect.applyEffetcs(item, this.itemEffects(item)); + } + applyActiveEffectsToBaseData(): void { - // reset overrides because our variant of applying active effects does not set them, it only adds overrides this.overrides = {}; DS4ActiveEffect.applyEffetcs( this, diff --git a/src/documents/item/item.ts b/src/documents/item/item.ts index f1655ba0..50015e37 100644 --- a/src/documents/item/item.ts +++ b/src/documents/item/item.ts @@ -4,7 +4,6 @@ // SPDX-License-Identifier: MIT import { getGame } from "../../utils/utils"; -import { DS4ActiveEffect } from "../active-effect"; import type { ItemType } from "./item-data-source"; @@ -28,23 +27,6 @@ export class DS4Item extends Item { /** An object that tracks the changes to the data model which were applied by active effects */ overrides: Record = {}; - override prepareData() { - this.data.reset(); - this.prepareBaseData(); - this.prepareEmbeddedDocuments(); - this.prepareDerivedData(); - this.applyActiveEffects(); - } - - applyActiveEffects(): void { - if (!this.actor?.initialized) { - return; - } - - this.overrides = {}; - DS4ActiveEffect.applyEffetcs(this, this.actor.itemEffects(this)); - } - override prepareDerivedData(): void { this.data.data.rollable = false; }