diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 636ca7ad..a35ea452 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -8,6 +8,8 @@ * @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item */ +import { addLinkedItemsDiff, updateLinkedItemApps } from '../../helpers/utils.mjs'; + const fields = foundry.data.fields; export default class BaseDataItem extends foundry.abstract.TypeDataModel { @@ -153,30 +155,12 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { const allowed = await super._preUpdate(changed, options, userId); if (allowed === false) return false; - if (changed.system?.features) { - const prevFeatures = new Set(this.features); - const newFeatures = new Set(changed.system.features); - options.changedFeatures = { - toLink: Array.from(newFeatures.difference(prevFeatures).map(feature => feature.item ?? feature)), - toUnlink: Array.from( - prevFeatures.difference(newFeatures).map(feature => feature.item?.uuid ?? feature.uuid) - ) - }; - } + addLinkedItemsDiff(changed.system?.features, this.features, options, 'changedFeatures'); } _onUpdate(changed, options, userId) { super._onUpdate(changed, options, userId); - if (options.changedFeatures) { - options.changedFeatures.toLink.forEach(featureUuid => { - const doc = foundry.utils.fromUuidSync(featureUuid); - doc.apps[this.parent.sheet.id] = this.parent.sheet; - }); - options.changedFeatures.toUnlink.forEach(featureUuid => { - const doc = foundry.utils.fromUuidSync(featureUuid); - delete doc.apps[this.parent.sheet.id]; - }); - } + updateLinkedItemApps(options, 'changedFeatures', this.parent.sheet); } } diff --git a/module/data/item/class.mjs b/module/data/item/class.mjs index a8b8dffa..3242aafb 100644 --- a/module/data/item/class.mjs +++ b/module/data/item/class.mjs @@ -2,6 +2,7 @@ import BaseDataItem from './base.mjs'; import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs'; import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs'; import ItemLinkFields from '../fields/itemLinkFields.mjs'; +import { addLinkedItemsDiff, updateLinkedItemApps } from '../../helpers/utils.mjs'; export default class DHClass extends BaseDataItem { /** @inheritDoc */ @@ -96,4 +97,49 @@ export default class DHClass extends BaseDataItem { foundry.utils.getProperty(options.parent, `${path}.subclass`)?.delete(); } } + + async _preUpdate(changed, options, userId) { + const allowed = await super._preUpdate(changed, options, userId); + if (allowed === false) return false; + + addLinkedItemsDiff(changed.system?.subclasses, this.subclasses, options, 'changedSubclasses'); + + const guide = changed.system?.characterGuide; + addLinkedItemsDiff( + guide?.suggestedPrimaryWeapon ? [guide.suggestedPrimaryWeapon] : null, + this.characterGuide.suggestedPrimaryWeapon ? [this.characterGuide.suggestedPrimaryWeapon] : [], + options, + 'primaryWeapon' + ); + addLinkedItemsDiff( + guide?.suggestedSecondaryWeapon ? [guide.suggestedSecondaryWeapon] : null, + this.characterGuide.suggestedSecondaryWeapon ? [this.characterGuide.suggestedSecondaryWeapon] : [], + options, + 'secondaryWeapon' + ); + addLinkedItemsDiff( + guide?.suggestedArmor ? [guide.suggestedArmor] : null, + this.characterGuide.suggestedArmor ? [this.characterGuide.suggestedArmor] : [], + options, + 'armor' + ); + + addLinkedItemsDiff(changed.system?.inventory?.take, this.inventory.take, options, 'changedTake'); + addLinkedItemsDiff(changed.system?.inventory?.choiceA, this.inventory.choiceA, options, 'changedChoiceA'); + addLinkedItemsDiff(changed.system?.inventory?.choiceB, this.inventory.choiceB, options, 'changedChoiceB'); + } + + _onUpdate(changed, options, userId) { + super._onUpdate(changed, options, userId); + + updateLinkedItemApps(options, 'changedSubclasses', this.parent.sheet); + + updateLinkedItemApps(options, 'primaryWeapon', this.parent.sheet); + updateLinkedItemApps(options, 'secondaryWeapon', this.parent.sheet); + updateLinkedItemApps(options, 'armor', this.parent.sheet); + + updateLinkedItemApps(options, 'changedTake', this.parent.sheet); + updateLinkedItemApps(options, 'changedChoiceA', this.parent.sheet); + updateLinkedItemApps(options, 'changedChoiceB', this.parent.sheet); + } } diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 7e73695e..88189feb 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -241,6 +241,45 @@ export function getDocFromElement(element) { return foundry.utils.fromUuidSync(target.dataset.itemUuid) ?? null; } +/** + * Adds the update diff on a linkedItem property to update.options for use + * in _onUpdate via the updateLinkedItemApps function. + * @param {Array} changedItems The candidate changed list + * @param {Array} currentItems The current list + * @param {object} options Additional options which modify the update request + * @param {string} optionsName The name of the options property holding the diff + */ +export function addLinkedItemsDiff(changedItems, currentItems, options, optionsName) { + if (changedItems) { + const prevItems = new Set(currentItems); + const newItems = new Set(changedItems); + options[optionsName] = { + toLink: Array.from(newItems.difference(prevItems).map(item => item?.item ?? item)), + toUnlink: Array.from(prevItems.difference(newItems).map(item => item?.item?.uuid ?? item?.uuid ?? item)) + }; + } +} + +/** + * Adds or removes the current Application from linked document apps + * depending on an update diff in the linked item list. + * @param {object} options Additional options which modify the update requests + * @param {string} optionName The prop name on options of the update diff + * @param {object} sheet The application to add or remove from document apps + */ +export function updateLinkedItemApps(options, optionName, sheet) { + if (options[optionName]) { + options[optionName].toLink.forEach(featureUuid => { + const doc = foundry.utils.fromUuidSync(featureUuid); + doc.apps[sheet.id] = sheet; + }); + options[optionName].toUnlink.forEach(featureUuid => { + const doc = foundry.utils.fromUuidSync(featureUuid); + delete doc.apps[sheet.id]; + }); + } +} + export const itemAbleRollParse = (value, actor, item) => { if (!value) return value; diff --git a/templates/sheets/items/class/settings.hbs b/templates/sheets/items/class/settings.hbs index ee436408..de31ad38 100644 --- a/templates/sheets/items/class/settings.hbs +++ b/templates/sheets/items/class/settings.hbs @@ -53,7 +53,7 @@ {{localize "DAGGERHEART.ITEMS.Class.guide.suggestedSecondaryWeaponTitle"}}
{{#if document.system.characterGuide.suggestedSecondaryWeapon}} -
+
{{document.system.characterGuide.suggestedSecondaryWeapon.name}}