refactor: extract active effect application to DS4ActiveEffect
This commit is contained in:
parent
b1ed05a796
commit
ddfab1813e
3 changed files with 46 additions and 44 deletions
|
@ -2,11 +2,12 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4Actor } from "../actor/actor";
|
||||
import { mathEvaluator } from "../expression-evaluation/evaluator";
|
||||
import { getGame } from "../helpers";
|
||||
|
||||
import type { DS4Actor } from "../actor/actor";
|
||||
import type { DS4Item } from "../item/item";
|
||||
|
||||
declare global {
|
||||
interface DocumentClassConfig {
|
||||
ActiveEffect: typeof DS4ActiveEffect;
|
||||
|
@ -52,7 +53,7 @@ export class DS4ActiveEffect extends ActiveEffect {
|
|||
* The item which this effect originates from if it has been transferred from an item to an actor.
|
||||
*/
|
||||
get originatingItem(): DS4Item | undefined {
|
||||
if (!(this.parent instanceof DS4Actor)) {
|
||||
if (!(this.parent instanceof Actor)) {
|
||||
return;
|
||||
}
|
||||
const itemIdRegex = /Item\.([a-zA-Z0-9]+)/;
|
||||
|
@ -127,12 +128,42 @@ export class DS4ActiveEffect extends ActiveEffect {
|
|||
return result as number | `${number | boolean}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the given effects to the gicen Actor or item.
|
||||
* @param document The Actor or Item to which to apply the effects
|
||||
* @param effetcs The effects to apply
|
||||
* @param predicate Apply only changes that fullfill this predicate
|
||||
*/
|
||||
static applyEffetcs(
|
||||
document: DS4Actor | DS4Item,
|
||||
effetcs: DS4ActiveEffect[],
|
||||
predicate: (change: EffectChangeData) => boolean = () => true,
|
||||
): void {
|
||||
const overrides: Record<string, unknown> = {};
|
||||
|
||||
// Organize non-disabled and -surpressed effects by their application priority
|
||||
const changesWithEffect = effetcs.flatMap((e) => e.getFactoredChangesWithEffect(predicate));
|
||||
changesWithEffect.sort((a, b) => (a.change.priority ?? 0) - (b.change.priority ?? 0));
|
||||
|
||||
// Apply all changes
|
||||
for (const changeWithEffect of changesWithEffect) {
|
||||
const result = changeWithEffect.effect.apply(document, changeWithEffect.change);
|
||||
if (result !== null) overrides[changeWithEffect.change.key] = result;
|
||||
}
|
||||
|
||||
// Expand the set of final overrides
|
||||
document.overrides = foundry.utils.expandObject({
|
||||
...foundry.utils.flattenObject(document.overrides),
|
||||
...overrides,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array of changes for this effect, considering the {@link DS4ActiveEffect#factor}.
|
||||
* @param predicate An optional predicate to filter which changes should be considered
|
||||
* @returns The array of changes from this effect, considering the factor.
|
||||
*/
|
||||
getFactoredChangesWithEffect(
|
||||
protected getFactoredChangesWithEffect(
|
||||
predicate: (change: EffectChangeData) => boolean = () => true,
|
||||
): EffectChangeDataWithEffect[] {
|
||||
if (this.data.disabled || this.isSurpressed) {
|
||||
|
@ -146,5 +177,5 @@ export class DS4ActiveEffect extends ActiveEffect {
|
|||
}
|
||||
}
|
||||
|
||||
export type EffectChangeData = foundry.data.ActiveEffectData["changes"][number];
|
||||
export type EffectChangeDataWithEffect = { effect: DS4ActiveEffect; change: EffectChangeData };
|
||||
type EffectChangeData = foundry.data.ActiveEffectData["changes"][number];
|
||||
type EffectChangeDataWithEffect = { effect: DS4ActiveEffect; change: EffectChangeData };
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4ActiveEffect } from "../active-effect/active-effect";
|
||||
import { DS4 } from "../config";
|
||||
import { mathEvaluator } from "../expression-evaluation/evaluator";
|
||||
import { getGame } from "../helpers";
|
||||
|
@ -16,7 +17,7 @@ import type { DS4Item } from "../item/item";
|
|||
import type { ItemType } from "../item/item-data-source";
|
||||
import type { DS4ShieldDataProperties } from "../item/shield/shield-data-properties";
|
||||
import type { Check } from "./actor-data-properties-base";
|
||||
import type { EffectChangeData } from "../active-effect/active-effect";
|
||||
|
||||
declare global {
|
||||
interface DocumentClassConfig {
|
||||
Actor: typeof DS4Actor;
|
||||
|
@ -105,7 +106,9 @@ export class DS4Actor extends Actor {
|
|||
applyActiveEffectsToBaseData(): void {
|
||||
// reset overrides because our variant of applying active effects does not set them, it only adds overrides
|
||||
this.overrides = {};
|
||||
this.applyActiveEffectsFiltered(
|
||||
DS4ActiveEffect.applyEffetcs(
|
||||
this,
|
||||
this.actorEffects,
|
||||
(change) =>
|
||||
!this.derivedDataProperties.includes(change.key) &&
|
||||
!this.finalDerivedDataProperties.includes(change.key),
|
||||
|
@ -113,29 +116,9 @@ export class DS4Actor extends Actor {
|
|||
}
|
||||
|
||||
applyActiveEffectsToDerivedData(): void {
|
||||
this.applyActiveEffectsFiltered((change) => this.derivedDataProperties.includes(change.key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply ActiveEffectChanges to the Actor data which are caused by ActiveEffects and satisfy the given predicate.
|
||||
*
|
||||
* @param predicate - The predicate that ActiveEffectChanges need to satisfy in order to be applied
|
||||
*/
|
||||
applyActiveEffectsFiltered(predicate: (change: EffectChangeData) => boolean): void {
|
||||
const overrides: Record<string, unknown> = {};
|
||||
|
||||
// Organize non-disabled and -surpressed effects by their application priority
|
||||
const changesWithEffect = this.actorEffects.flatMap((e) => e.getFactoredChangesWithEffect(predicate));
|
||||
changesWithEffect.sort((a, b) => (a.change.priority ?? 0) - (b.change.priority ?? 0));
|
||||
|
||||
// Apply all changes
|
||||
for (const changeWithEffect of changesWithEffect) {
|
||||
const result = changeWithEffect.effect.apply(this, changeWithEffect.change);
|
||||
if (result !== null) overrides[changeWithEffect.change.key] = result;
|
||||
}
|
||||
|
||||
// Expand the set of final overrides
|
||||
this.overrides = foundry.utils.expandObject({ ...foundry.utils.flattenObject(this.overrides), ...overrides });
|
||||
DS4ActiveEffect.applyEffetcs(this, this.actorEffects, (change) =>
|
||||
this.derivedDataProperties.includes(change.key),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { DS4ActiveEffect } from "../active-effect/active-effect";
|
||||
import { getGame } from "../helpers";
|
||||
|
||||
import type { ItemType } from "./item-data-source";
|
||||
|
@ -41,20 +42,7 @@ export class DS4Item extends Item {
|
|||
}
|
||||
|
||||
this.overrides = {};
|
||||
const overrides: Record<string, unknown> = {};
|
||||
|
||||
// Organize non-disabled and -surpressed effects by their application priority
|
||||
const changesWithEffect = this.actor?.itemEffects(this).flatMap((e) => e.getFactoredChangesWithEffect()) ?? [];
|
||||
changesWithEffect.sort((a, b) => (a.change.priority ?? 0) - (b.change.priority ?? 0));
|
||||
|
||||
// Apply all changes
|
||||
for (const changeWithEffect of changesWithEffect) {
|
||||
const result = changeWithEffect.effect.apply(this, changeWithEffect.change);
|
||||
if (result !== null) overrides[changeWithEffect.change.key] = result;
|
||||
}
|
||||
|
||||
// Expand the set of final overrides
|
||||
this.overrides = foundry.utils.expandObject({ ...foundry.utils.flattenObject(this.overrides), ...overrides });
|
||||
DS4ActiveEffect.applyEffetcs(this, this.actor.itemEffects(this));
|
||||
}
|
||||
|
||||
override prepareDerivedData(): void {
|
||||
|
|
Loading…
Reference in a new issue