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
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import { DS4Actor } from "../actor/actor";
|
|
||||||
import { mathEvaluator } from "../expression-evaluation/evaluator";
|
import { mathEvaluator } from "../expression-evaluation/evaluator";
|
||||||
import { getGame } from "../helpers";
|
import { getGame } from "../helpers";
|
||||||
|
|
||||||
|
import type { DS4Actor } from "../actor/actor";
|
||||||
import type { DS4Item } from "../item/item";
|
import type { DS4Item } from "../item/item";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface DocumentClassConfig {
|
interface DocumentClassConfig {
|
||||||
ActiveEffect: typeof DS4ActiveEffect;
|
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.
|
* The item which this effect originates from if it has been transferred from an item to an actor.
|
||||||
*/
|
*/
|
||||||
get originatingItem(): DS4Item | undefined {
|
get originatingItem(): DS4Item | undefined {
|
||||||
if (!(this.parent instanceof DS4Actor)) {
|
if (!(this.parent instanceof Actor)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const itemIdRegex = /Item\.([a-zA-Z0-9]+)/;
|
const itemIdRegex = /Item\.([a-zA-Z0-9]+)/;
|
||||||
|
@ -127,12 +128,42 @@ export class DS4ActiveEffect extends ActiveEffect {
|
||||||
return result as number | `${number | boolean}`;
|
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}.
|
* 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
|
* @param predicate An optional predicate to filter which changes should be considered
|
||||||
* @returns The array of changes from this effect, considering the factor.
|
* @returns The array of changes from this effect, considering the factor.
|
||||||
*/
|
*/
|
||||||
getFactoredChangesWithEffect(
|
protected getFactoredChangesWithEffect(
|
||||||
predicate: (change: EffectChangeData) => boolean = () => true,
|
predicate: (change: EffectChangeData) => boolean = () => true,
|
||||||
): EffectChangeDataWithEffect[] {
|
): EffectChangeDataWithEffect[] {
|
||||||
if (this.data.disabled || this.isSurpressed) {
|
if (this.data.disabled || this.isSurpressed) {
|
||||||
|
@ -146,5 +177,5 @@ export class DS4ActiveEffect extends ActiveEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type EffectChangeData = foundry.data.ActiveEffectData["changes"][number];
|
type EffectChangeData = foundry.data.ActiveEffectData["changes"][number];
|
||||||
export type EffectChangeDataWithEffect = { effect: DS4ActiveEffect; change: EffectChangeData };
|
type EffectChangeDataWithEffect = { effect: DS4ActiveEffect; change: EffectChangeData };
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import { DS4ActiveEffect } from "../active-effect/active-effect";
|
||||||
import { DS4 } from "../config";
|
import { DS4 } from "../config";
|
||||||
import { mathEvaluator } from "../expression-evaluation/evaluator";
|
import { mathEvaluator } from "../expression-evaluation/evaluator";
|
||||||
import { getGame } from "../helpers";
|
import { getGame } from "../helpers";
|
||||||
|
@ -16,7 +17,7 @@ import type { DS4Item } from "../item/item";
|
||||||
import type { ItemType } from "../item/item-data-source";
|
import type { ItemType } from "../item/item-data-source";
|
||||||
import type { DS4ShieldDataProperties } from "../item/shield/shield-data-properties";
|
import type { DS4ShieldDataProperties } from "../item/shield/shield-data-properties";
|
||||||
import type { Check } from "./actor-data-properties-base";
|
import type { Check } from "./actor-data-properties-base";
|
||||||
import type { EffectChangeData } from "../active-effect/active-effect";
|
|
||||||
declare global {
|
declare global {
|
||||||
interface DocumentClassConfig {
|
interface DocumentClassConfig {
|
||||||
Actor: typeof DS4Actor;
|
Actor: typeof DS4Actor;
|
||||||
|
@ -105,7 +106,9 @@ export class DS4Actor extends Actor {
|
||||||
applyActiveEffectsToBaseData(): void {
|
applyActiveEffectsToBaseData(): void {
|
||||||
// reset overrides because our variant of applying active effects does not set them, it only adds overrides
|
// reset overrides because our variant of applying active effects does not set them, it only adds overrides
|
||||||
this.overrides = {};
|
this.overrides = {};
|
||||||
this.applyActiveEffectsFiltered(
|
DS4ActiveEffect.applyEffetcs(
|
||||||
|
this,
|
||||||
|
this.actorEffects,
|
||||||
(change) =>
|
(change) =>
|
||||||
!this.derivedDataProperties.includes(change.key) &&
|
!this.derivedDataProperties.includes(change.key) &&
|
||||||
!this.finalDerivedDataProperties.includes(change.key),
|
!this.finalDerivedDataProperties.includes(change.key),
|
||||||
|
@ -113,29 +116,9 @@ export class DS4Actor extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
applyActiveEffectsToDerivedData(): void {
|
applyActiveEffectsToDerivedData(): void {
|
||||||
this.applyActiveEffectsFiltered((change) => this.derivedDataProperties.includes(change.key));
|
DS4ActiveEffect.applyEffetcs(this, this.actorEffects, (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 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import { DS4ActiveEffect } from "../active-effect/active-effect";
|
||||||
import { getGame } from "../helpers";
|
import { getGame } from "../helpers";
|
||||||
|
|
||||||
import type { ItemType } from "./item-data-source";
|
import type { ItemType } from "./item-data-source";
|
||||||
|
@ -41,20 +42,7 @@ export class DS4Item extends Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.overrides = {};
|
this.overrides = {};
|
||||||
const overrides: Record<string, unknown> = {};
|
DS4ActiveEffect.applyEffetcs(this, this.actor.itemEffects(this));
|
||||||
|
|
||||||
// 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 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override prepareDerivedData(): void {
|
override prepareDerivedData(): void {
|
||||||
|
|
Loading…
Reference in a new issue