diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index e941931a..5faa5d5c 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -725,7 +725,7 @@ export default function DHApplicationMixin(Base) { : null : this.document; - let systemData = null; + let systemData = {}; if (featureOnCharacter) { systemData = { originItemType: this.document.type, @@ -738,11 +738,10 @@ export default function DHApplicationMixin(Base) { const data = { name: cls.defaultName({ type, parent }), - type + type, + system: systemData }; - if (systemData) data.system = systemData; - if (inVault) data['system.inVault'] = true; if (disabled) data.disabled = true; if (type === 'domainCard' && parent?.system.domains?.length) { diff --git a/module/config/itemBrowserConfig.mjs b/module/config/itemBrowserConfig.mjs index 04b387cb..5c0a219b 100644 --- a/module/config/itemBrowserConfig.mjs +++ b/module/config/itemBrowserConfig.mjs @@ -177,8 +177,8 @@ export const typeConfig = { key: 'system.secondary', label: 'DAGGERHEART.UI.ItemBrowser.subtype', choices: [ - { value: false, label: 'DAGGERHEART.ITEMS.Weapon.primaryWeapon.full' }, - { value: true, label: 'DAGGERHEART.ITEMS.Weapon.secondaryWeapon.full' } + { value: false, label: 'DAGGERHEART.ITEMS.Weapon.primaryWeapon' }, + { value: true, label: 'DAGGERHEART.ITEMS.Weapon.secondaryWeapon' } ] }, { diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs index 9efbe7d7..13ff0a38 100644 --- a/module/data/actor/base.mjs +++ b/module/data/actor/base.mjs @@ -1,6 +1,6 @@ import DHBaseActorSettings from '../../applications/sheets/api/actor-setting.mjs'; import DHItem from '../../documents/item.mjs'; -import { createShallowProxy, getScrollTextData } from '../../helpers/utils.mjs'; +import { getScrollTextData } from '../../helpers/utils.mjs'; const fields = foundry.data.fields; @@ -180,7 +180,8 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel { * @returns {object} */ getRollData() { - return createShallowProxy(this); + const data = { ...this }; + return data; } /** diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index aebf33bf..f6c794f1 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -7,12 +7,7 @@ * @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item */ -import { - addLinkedItemsDiff, - getScrollTextData, - createShallowProxy, - updateLinkedItemApps -} from '../../helpers/utils.mjs'; +import { addLinkedItemsDiff, getScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs'; import { ActionsField } from '../fields/actionField.mjs'; import FormulaField from '../fields/formulaField.mjs'; @@ -164,8 +159,8 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { * @returns {object} */ getRollData(options = {}) { - const data = this.actor?.getRollData() ?? {}; - data.item = createShallowProxy(this); + const actorRollData = this.actor?.getRollData() ?? {}; + const data = { ...actorRollData, item: { ...this } }; return data; } diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 84e4de7f..75e6dc8e 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -28,10 +28,7 @@ export default class DHWeapon extends AttachableItem { equipped: new fields.BooleanField({ initial: false }), //SETTINGS - secondary: new fields.BooleanField({ - initial: false, - label: 'DAGGERHEART.ITEMS.Weapon.secondaryWeapon.full' - }), + secondary: new fields.BooleanField({ initial: false, label: 'DAGGERHEART.ITEMS.Weapon.secondaryWeapon' }), burden: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.burden, diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index 08463818..227e2613 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -169,36 +169,27 @@ 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 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); + 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 (_) {} } - // 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(value, { stacks: effect.system.stacking.value }) - : value; - const evalValue = this.effectSafeEval(itemAbleRollParse(stackingParsedValue, actor, item)); - return evalValue ?? value; + ? Roll.replaceFormulaData(key, { stacks: effect.system.stacking.value }) + : key; + const evalValue = itemAbleRollParse(stackingParsedValue, parseModel, effect.parent); + return evalValue ?? key; } /** diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index eb57a186..52150dae 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -1,7 +1,7 @@ import { emitAsGM, GMUpdateEvent } from '../systemRegistration/socket.mjs'; import { LevelOptionType } from '../data/levelTier.mjs'; import DHFeature from '../data/item/feature.mjs'; -import { createScrollText, damageKeyToNumber, getDamageKey, createShallowProxy } from '../helpers/utils.mjs'; +import { createScrollText, damageKeyToNumber, getDamageKey } from '../helpers/utils.mjs'; import DhCompanionLevelUp from '../applications/levelup/companionLevelup.mjs'; import { ResourceUpdateMap } from '../data/action/baseAction.mjs'; import { abilities } from '../config/actorConfig.mjs'; @@ -595,7 +595,10 @@ export default class DhpActor extends Actor { /**@inheritdoc */ getRollData() { - const rollData = createShallowProxy(super.getRollData()); + const rollData = foundry.utils.deepClone(super.getRollData()); + /* system gets repeated infinately which causes issues when trying to use the data for document creation */ + delete rollData.system; + rollData.id = this.id; rollData.name = this.name; rollData.system = this.system.getRollData(); diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 93aa3b28..8ece56fa 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -54,7 +54,13 @@ export default class DHItem extends foundry.documents.Item { * @returns */ getRollData(options = {}) { - let data = this.system.getRollData(options); + let data; + if (this.system.getRollData) data = this.system.getRollData(options); + else { + const actorRollData = this.actor?.getRollData(options) ?? {}; + data = { ...actorRollData, item: { ...this.system } }; + } + if (data?.item) { data.item.flags = { ...this.flags }; data.item.name = this.name; diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 1650b505..b4a04579 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -372,11 +372,10 @@ export const itemAbleRollParse = (value, actor, item) => { const isItemTarget = value.toLowerCase().includes('item.@'); const slicedValue = isItemTarget ? value.replaceAll(/item\.@/gi, '@') : value; - const model = isItemTarget || item instanceof Item ? item : actor; - const rollData = isItemTarget || !model?.getRollData ? model : model.getRollData(); + const model = isItemTarget ? item : actor; try { - return Roll.replaceFormulaData(slicedValue, rollData); + return Roll.replaceFormulaData(slicedValue, isItemTarget || !model?.getRollData ? model : model.getRollData()); } catch (_) { return ''; } @@ -810,31 +809,3 @@ export function sortBy(arr, fn) { }; return arr.sort(cmp); } - -/** - * Creates a proxy that allows retrieval of top data but diverts updates to a different object. - * Generally used for roll data - */ -export function createShallowProxy(obj) { - if (obj._isShallowProxy) return obj; - - const overrides = {}; - return new Proxy(obj, { - get(target, prop, receiver) { - if (prop === '_isShallowProxy') return true; - if (prop in overrides) return overrides[prop]; - return Reflect.get(target, prop, receiver); - }, - set(_target, prop, newValue) { - overrides[prop] = newValue; - return true; - }, - deleteProperty(_target, prop) { - delete overrides[prop]; - return true; - }, - has(target, key) { - return key in overrides || key in target; - } - }); -} diff --git a/templates/settings/variant-rules.hbs b/templates/settings/variant-rules.hbs index 9c9650dd..cdaef024 100644 --- a/templates/settings/variant-rules.hbs +++ b/templates/settings/variant-rules.hbs @@ -32,7 +32,7 @@