[Fix] origin change values and prioritize item options (#1835)
Some checks are pending
Project CI / build (24.x) (push) Waiting to run

* Fix origin key replacement and prioritize item options

* Rename key to value

* Some fixes

* Attempt to always retrieve the source item for same actor origin

* Fix getters in item roll data

* Performance improvement

* Allow apply to item system data

* Replace implementation with shallow proxy

* Add delete to the shallow proxy

* Add proxy trap for the in operator

---------

Co-authored-by: WBHarry <williambjrklund@gmail.com>
This commit is contained in:
Carlos Fernandez 2026-04-25 18:06:41 -04:00 committed by GitHub
parent c82bcbeb01
commit 6d09c5504d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 70 additions and 37 deletions

View file

@ -169,27 +169,36 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
super._applyChangeUnguided(actor, change, changes, options);
}
/** Recursively finds the first parent document of the given object */
static #resolveParentDocument(model, documentClass) {
return model instanceof documentClass
? model
: model.parent
? this.#resolveParentDocument(model.parent, documentClass)
: null;
}
static getChangeValue(model, change, effect) {
let key = change.value.toString();
const isOriginTarget = key.toLowerCase().includes('origin.@');
let parseModel = model;
if (isOriginTarget && effect.origin) {
key = change.key.replaceAll(/origin\.@/gi, '@');
try {
const originEffect = foundry.utils.fromUuidSync(effect.origin);
const doc =
originEffect.parent?.parent instanceof game.system.api.documents.DhpActor
? originEffect.parent
: originEffect.parent.parent;
if (doc) parseModel = doc;
} catch (_) {}
let value = change.value.toString();
const useOrigin = value.toLowerCase().includes('origin.@') && effect.origin;
let origin = null;
if (effect.origin) {
if (useOrigin) value = value.replaceAll(/origin\.@/gi, '@');
const originEffect = foundry.utils.fromUuidSync(effect.origin);
origin = this.#resolveParentDocument(originEffect, Item);
}
// Get the actor and item documents. Note that actor roll data is inclusive of system roll data
const actor = this.#resolveParentDocument(model, Actor);
const item =
(useOrigin ? origin : null) ??
this.#resolveParentDocument(effect.parent, Item) ??
(origin?.actor === actor ? origin : null);
const stackingParsedValue = effect.system.stacking
? Roll.replaceFormulaData(key, { stacks: effect.system.stacking.value })
: key;
const evalValue = itemAbleRollParse(stackingParsedValue, parseModel, effect.parent);
return evalValue ?? key;
? Roll.replaceFormulaData(value, { stacks: effect.system.stacking.value })
: value;
const evalValue = this.effectSafeEval(itemAbleRollParse(stackingParsedValue, actor, item));
return evalValue ?? value;
}
/**