From efaae57b24962e48456bfdef255cc1783a8f6630 Mon Sep 17 00:00:00 2001 From: Haxxer Date: Sat, 24 Aug 2024 22:22:01 +0100 Subject: [PATCH] Fixed unlinked tokens --- changelog.md | 1 + src/API/private-api.js | 41 +++++++++++++++--------- src/helpers/pile-utilities.js | 59 ++++++++++++++--------------------- src/stores/item-pile-store.js | 6 ++++ 4 files changed, 57 insertions(+), 50 deletions(-) diff --git a/changelog.md b/changelog.md index 9f9a134a..d5df5f23 100644 --- a/changelog.md +++ b/changelog.md @@ -10,6 +10,7 @@ - Added option for a custom sell price on items - Added detection for when the GM is unresponsive for item piles to make changes for players - Fixed localization issue with `ITEM-PILES.Trade`, now moved to `ITEM-PILES.PlayerList.TradeButton` +- Fixed item piles interfaces of unlinked tokens not reacting to some changes to their flags ## Version 3.0.11 diff --git a/src/API/private-api.js b/src/API/private-api.js index f77334a3..da70a1a6 100644 --- a/src/API/private-api.js +++ b/src/API/private-api.js @@ -34,6 +34,7 @@ export default class PrivateAPI { Helpers.hooks.on("deleteActor", this._onDeleteActor.bind(this)); Helpers.hooks.on("preCreateToken", this._onPreCreateToken.bind(this)) Helpers.hooks.on("preUpdateToken", this._onPreUpdateToken.bind(this)); + Helpers.hooks.on("updateToken", this._onUpdateToken.bind(this)); Helpers.hooks.on("createToken", this._onCreateToken.bind(this)) Helpers.hooks.on("dropCanvasData", this._dropData.bind(this)); } @@ -52,9 +53,9 @@ export default class PrivateAPI { * @private */ static _onCreateItem(doc) { - if (!doc.parent) return; + if (!doc.parent) return true; ItemPileStore.notifyChanges("createItem", doc.parent, doc); - if (!PileUtilities.isValidItemPile(doc.parent)) return; + if (!PileUtilities.isValidItemPile(doc.parent)) return true; this._evaluateItemPileChange(doc.parent, {}, true); } @@ -62,8 +63,8 @@ export default class PrivateAPI { * @private */ static _onUpdateItem(doc) { - if (!doc.parent) return; - if (!PileUtilities.isValidItemPile(doc.parent)) return; + if (!doc.parent) return true; + if (!PileUtilities.isValidItemPile(doc.parent)) return true; this._evaluateItemPileChange(doc.parent, {}, true); } @@ -71,9 +72,9 @@ export default class PrivateAPI { * @private */ static _onDeleteItem(doc) { - if (!doc.parent) return; + if (!doc.parent) return true; ItemPileStore.notifyChanges("deleteItem", doc.parent, doc); - if (!PileUtilities.isValidItemPile(doc.parent)) return; + if (!PileUtilities.isValidItemPile(doc.parent)) return true; this._evaluateItemPileChange(doc.parent, {}, true); } @@ -81,7 +82,7 @@ export default class PrivateAPI { * @private */ static _onUpdateActor(doc, changes) { - if (!PileUtilities.isValidItemPile(doc)) return; + if (!PileUtilities.isValidItemPile(doc)) return true; this._evaluateItemPileChange(doc, changes); } @@ -90,7 +91,7 @@ export default class PrivateAPI { */ static _onDeleteToken(doc) { ItemPileStore.notifyChanges("delete", doc.actor) - if (!PileUtilities.isValidItemPile(doc)) return; + if (!PileUtilities.isValidItemPile(doc)) return true; Helpers.hooks.callAll(CONSTANTS.HOOKS.PILE.DELETE, doc); } @@ -117,7 +118,7 @@ export default class PrivateAPI { foundry.utils.deepClone(foundry.utils.getProperty(sourceActor, CONSTANTS.FLAGS.PILE) ?? {}) ); } - if (!itemPileConfig?.enabled) return; + if (!itemPileConfig?.enabled) return true; if (!doc.isLinked) { Utilities.deleteProperty(docData, CONSTANTS.ACTOR_DELTA_PROPERTY + "." + CONSTANTS.FLAGS.SHARING); } @@ -162,18 +163,28 @@ export default class PrivateAPI { static _onPreUpdateToken(doc, changes) { const diff = foundry.utils.diffObject(doc, changes); - if (!foundry.utils.hasProperty(diff, "actorLink")) return; - if (!PileUtilities.isValidItemPile(doc)) return; - const flagData = PileUtilities.getActorFlagData(doc); - const cleanFlagData = PileUtilities.cleanFlagData(flagData); - changes[CONSTANTS.FLAGS.PILE] = diff.actorLink ? cleanFlagData : null; + if (!foundry.utils.hasProperty(diff, "actorLink")) return true; + if (!PileUtilities.isValidItemPile(doc)) return true; + const actor = Utilities.getActor(doc); + const changingFlags = foundry.utils.getProperty(changes, CONSTANTS.FLAGS.PILE) ?? {}; + const flagData = foundry.utils.mergeObject( + PileUtilities.getActorFlagData(actor), + changingFlags + ); + changes[CONSTANTS.FLAGS.PILE] = PileUtilities.cleanFlagData(flagData); + } + + static _onUpdateToken(doc) { + if (doc.actorLink) return true; + if (!PileUtilities.isValidItemPile(doc)) return true; + ItemPileStore.notifyChanges("updateUnlinkedToken", doc.actor) } /** * @private */ static _onCreateToken(doc) { - if (!PileUtilities.isValidItemPile(doc)) return; + if (!PileUtilities.isValidItemPile(doc)) return true; const itemPileConfig = PileUtilities.getActorFlagData(doc.actor) Helpers.hooks.callAll(CONSTANTS.HOOKS.PILE.CREATE, doc, itemPileConfig); return this._preloadItemPileFiles(doc); diff --git a/src/helpers/pile-utilities.js b/src/helpers/pile-utilities.js index 5c731261..bd16688e 100644 --- a/src/helpers/pile-utilities.js +++ b/src/helpers/pile-utilities.js @@ -682,33 +682,6 @@ export function shouldEvaluateChange(target, changes) { || flags.displayOne || flags.showItemName || flags.overrideSingleItemScale; } -function getRelevantTokensAndActor(target) { - - const relevantDocument = Utilities.getDocument(target); - - let documentActor; - let documentTokens = []; - - if (relevantDocument instanceof Actor) { - documentActor = relevantDocument; - if (relevantDocument.token) { - documentTokens.push(relevantDocument?.token); - } else { - documentTokens = canvas.tokens.placeables.filter(token => token.document.actor === documentActor).map(token => token.document); - } - } else { - documentActor = relevantDocument.actor; - if (relevantDocument.isLinked) { - documentTokens = canvas.tokens.placeables.filter(token => token.document.actor === documentActor).map(token => token.document); - } else { - documentTokens.push(relevantDocument); - } - } - - return [documentActor, documentTokens] - -} - export async function updateItemPileData(target, newFlags, tokenData) { if (!target) return; @@ -717,7 +690,8 @@ export async function updateItemPileData(target, newFlags, tokenData) { if (!tokenData) tokenData = {}; tokenData = foundry.utils.mergeObject(tokenData, {}); - let [documentActor, documentTokens] = getRelevantTokensAndActor(target); + let documentActor = Utilities.getActor(target); + const documentTokens = documentActor.getActiveTokens(); const items = getActorItems(documentActor, { itemFilters: flagData.overrideItemFilters }); const actorCurrencies = (flagData.overrideCurrencies || []).concat(flagData.overrideSecondaryCurrencies || []); @@ -727,9 +701,13 @@ export async function updateItemPileData(target, newFlags, tokenData) { const currentFlagData = getActorFlagData(target, { useDefaults: false }); - const cleanedFlagData = cleanFlagData(flagData, { addRemoveFlag: true, existingData: currentFlagData }); + const cleanedFlagData = cleanFlagData(flagData, { + addRemoveFlag: true, + existingData: currentFlagData + }); - const updates = documentTokens.map(tokenDocument => { + const sceneUpdates = documentTokens.reduce((acc, token) => { + const tokenDocument = token.document; const overrideImage = foundry.utils.getProperty(tokenData, "texture.src") ?? foundry.utils.getProperty(tokenData, "img"); const overrideScale = foundry.utils.getProperty(tokenData, "texture.scaleX") @@ -748,12 +726,23 @@ export async function updateItemPileData(target, newFlags, tokenData) { [CONSTANTS.FLAGS.VERSION]: Helpers.getModuleVersion(), ...newTokenData }; - if (!tokenDocument.actorLink) documentActor = false; - return foundry.utils.mergeObject({}, data); - }); + if (!tokenDocument.actorLink) { + data[CONSTANTS.ACTOR_DELTA_PROPERTY] = { + [CONSTANTS.FLAGS.PILE]: cleanedFlagData, + [CONSTANTS.FLAGS.VERSION]: Helpers.getModuleVersion(), + } + } + acc[tokenDocument.parent.id] ??= []; + acc[tokenDocument.parent.id].push(foundry.utils.mergeObject({}, data)); + return acc; + }, {}); - if (canvas.scene && !foundry.utils.isEmpty(updates)) { - await canvas.scene.updateEmbeddedDocuments("Token", updates, { animate: false }); + if (!foundry.utils.isEmpty(sceneUpdates)) { + for (const [sceneId, updates] of Object.entries(sceneUpdates)) { + const scene = game.scenes.get(sceneId); + if (!scene) continue + await scene.updateEmbeddedDocuments("Token", updates, { animate: false }); + } } if (documentActor) { diff --git a/src/stores/item-pile-store.js b/src/stores/item-pile-store.js index d3199e5b..c089ff5a 100644 --- a/src/stores/item-pile-store.js +++ b/src/stores/item-pile-store.js @@ -250,6 +250,12 @@ export default class ItemPileStore { } + updateUnlinkedToken() { + this.pileData.set(PileUtilities.getActorFlagData(this.actor)); + this.shareData.set(SharingUtilities.getItemPileSharingData(this.actor)); + this.refreshItems(); + } + updateSource(newSource) { this.uuid = Utilities.getUuid(newSource); this.actor = Utilities.getActor(newSource);