diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index bd5b111b..c86086f9 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -7,7 +7,12 @@ * @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item */ -import { addLinkedItemsDiff, getScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs'; +import { + addLinkedItemsDiff, + getScrollTextData, + shallowCopyWithGetters, + updateLinkedItemApps +} from '../../helpers/utils.mjs'; import { ActionsField } from '../fields/actionField.mjs'; import FormulaField from '../fields/formulaField.mjs'; @@ -159,9 +164,8 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { * @returns {object} */ getRollData(options = {}) { - const actorRollData = this.actor?.getRollData() ?? {}; - const data = Object.assign(actorRollData, {}); - data.item = Object.assign(this, {}); + const data = this.actor?.getRollData() ?? {}; + data.item = this; return data; } diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 52150dae..47b4bfdc 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 } from '../helpers/utils.mjs'; +import { createScrollText, damageKeyToNumber, getDamageKey, shallowCopyWithGetters } 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,10 +595,7 @@ export default class DhpActor extends Actor { /**@inheritdoc */ 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; - + const rollData = shallowCopyWithGetters(super.getRollData()); rollData.id = this.id; rollData.name = this.name; rollData.system = this.system.getRollData(); diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index deef78f5..8f08788e 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -809,3 +809,30 @@ export function sortBy(arr, fn) { }; return arr.sort(cmp); } + +/** + * Returns a shallow copy including getters of the given object. + * Generally used for expanding roll data without side effects + */ +export function shallowCopyWithGetters(obj) { + function getAllPropertyDescriptors(obj) { + if (!obj) { + return Object.create(null); + } + + return { + ...getAllPropertyDescriptors(Object.getPrototypeOf(obj)), + ...Object.getOwnPropertyDescriptors(obj) + }; + } + + const props = getAllPropertyDescriptors(obj); + const result = {}; + for (const key of Object.keys(props)) { + const value = obj[key]; + if (key !== '__proto__' && typeof value !== 'function') { + result[key] = obj[key]; + } + } + return result; +}