diff --git a/changelog.md b/changelog.md index 7ffde96c..a96248bf 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,15 @@ # Item Piles Changelog +## Version 2.8.18 + +- Fixed items sometimes losing their flags when added vaults + +## Version 2.8.17 + +- Fixed swapping items in vaults would sometimes allow you to swap items so that one ended up outside the bounds of the vault +- Fixed merchants sometimes not refreshing their inventories when integrated with Simple Calendar +- Fixed users not being able to drop unstackable items into vaults + ## Version 2.8.16 - Fixed items that were linked with the item linking module losing their links diff --git a/src/API/api.js b/src/API/api.js index 4363770f..c532e071 100644 --- a/src/API/api.js +++ b/src/API/api.js @@ -1215,9 +1215,9 @@ class API { } else if (itemData.item) { item = itemData.item instanceof Item ? itemData.item.toObject() : itemData.item; if (itemData.flags) { - foundry.utils.setProperty(item, "flags", foundry.utils.mergeObject( - foundry.utils.getProperty(item, "flags") ?? {}, - foundry.utils.getProperty(itemData, "flags")) + foundry.utils.setProperty(item, CONSTANTS.FLAGS.ITEM, foundry.utils.mergeObject( + foundry.utils.getProperty(item, CONSTANTS.FLAGS.ITEM) ?? {}, + foundry.utils.getProperty(itemData, CONSTANTS.FLAGS.ITEM)) ); } } else if (itemData.id) { @@ -1352,7 +1352,7 @@ class API { return { id: item._id, quantity: Math.max(itemData?.quantity ?? Utilities.getItemQuantity(itemData), 0), - flags: foundry.utils.getProperty(itemData, "flags") + flags: foundry.utils.getProperty(itemData, CONSTANTS.FLAGS.ITEM) } }); @@ -1700,7 +1700,7 @@ class API { * * @param {Array} currencies An array of object containing the data and quantity for each currency | * @param {number} currencies[].cost The cost of the currency -| * @param {string} currencies[].denom The abbreviation of the currency, which are usually {#}GP, which when {#} is replaced with the number it becomes 5GP. +| * @param {string} currencies[].denom The abbreviation of the currency, which are usually {#}GP, which when {#} is replaced with the number it becomes 5GP. * @param {string} currencies[].percent The cost of the currency is in percentage (for work the 'abbreviation' property must includes '%' substring) * @returns {string} An array of object containing the data and quantity for each currency */ diff --git a/src/API/private-api.js b/src/API/private-api.js index b67b8333..1b8e3ff2 100644 --- a/src/API/private-api.js +++ b/src/API/private-api.js @@ -1671,8 +1671,9 @@ export default class PrivateAPI { const item = await Item.implementation.create(dropData.itemData.item, { temporary: true }); - let itemQuantity = Utilities.getItemQuantity(dropData.itemData.item); + dropData.itemData.quantity = 1; if (PileUtilities.canItemStack(dropData.itemData.item, vaultActor)) { + const itemQuantity = Utilities.getItemQuantity(dropData.itemData.item); if (itemQuantity > 1) { dropData.itemData.quantity = await DropItemDialog.show(item, vaultActor, { localizationTitle: localization @@ -1681,8 +1682,6 @@ export default class PrivateAPI { Helpers.custom_warning(game.i18n.localize("ITEM-PILES.Errors.ItemNoQuantity"), true); return; } - } else { - dropData.itemData.quantity = 1; } Utilities.setItemQuantity(dropData.itemData.item, dropData.itemData.quantity); @@ -1691,7 +1690,7 @@ export default class PrivateAPI { foundry.utils.setProperty(flagData, "x", dropData.gridPosition?.x ?? 0); foundry.utils.setProperty(flagData, "y", dropData.gridPosition?.y ?? 0); } - foundry.utils.setProperty(dropData.itemData, "flags", flagData); + foundry.utils.setProperty(dropData.itemData, CONSTANTS.FLAGS.ITEM, flagData); if (sourceActor) { return game.itempiles.API.transferItems(sourceActor, targetActor, [dropData.itemData], { interactionId: dropData.interactionId }); diff --git a/src/applications/components/Grid/grid-utils.js b/src/applications/components/Grid/grid-utils.js index 1836c405..ea7a56ec 100644 --- a/src/applications/components/Grid/grid-utils.js +++ b/src/applications/components/Grid/grid-utils.js @@ -108,8 +108,8 @@ export function isPlacementValid(item, collisions, items, options) { transform: finalTransform }; - const itemWithinBounds = (finalTransform.x + (finalTransform.w - 1)) < options.cols - && (finalTransform.y + (finalTransform.h - 1)) < options.rows + const itemWithinBounds = (finalTransform.x + (finalTransform.w - 1)) < options.enabledCols + && (finalTransform.y + (finalTransform.h - 1)) < options.enabledRows && (finalTransform.x) >= 0 && (finalTransform.y) >= 0; @@ -125,8 +125,8 @@ export function isPlacementValid(item, collisions, items, options) { if (!assumedCollisionMovement.every(entry => { return entry - && (entry.transform.x + (entry.transform.w - 1)) < options.cols - && (entry.transform.y + (entry.transform.h - 1)) < options.rows + && (entry.transform.x + (entry.transform.w - 1)) < options.enabledCols + && (entry.transform.y + (entry.transform.h - 1)) < options.enabledRows && (entry.transform.x) >= 0 && (entry.transform.y) >= 0 })) return false; diff --git a/src/helpers/pile-utilities.js b/src/helpers/pile-utilities.js index d17b095e..efe8dfa2 100644 --- a/src/helpers/pile-utilities.js +++ b/src/helpers/pile-utilities.js @@ -1964,7 +1964,7 @@ export async function rollTable({ if (existingItem) { existingItem.quantity += Math.max(newItem.quantity, 1); } else { - setProperty(newItem, "flags", newItem.item.flags); + setProperty(newItem, CONSTANTS.FLAGS.ITEM, getProperty(newItem.item, CONSTANTS.FLAGS.ITEM)); if (game.itempiles.API.QUANTITY_FOR_PRICE_ATTRIBUTE && !getProperty(newItem, game.itempiles.API.QUANTITY_FOR_PRICE_ATTRIBUTE)) { setProperty(newItem, game.itempiles.API.QUANTITY_FOR_PRICE_ATTRIBUTE, Utilities.getItemQuantity(newItem.item)); } @@ -2055,7 +2055,7 @@ export async function rollMerchantTables({ tableData = false, actor = false } = if (existingItem) { existingItem.quantity += Math.max(newItem.quantity, 1); } else { - setProperty(newItem, "flags", newItem.item.flags); + setProperty(newItem, CONSTANTS.FLAGS.ITEM, cleanItemFlagData(getProperty(newItem.item.flags, CONSTANTS.FLAGS.ITEM))); if (game.itempiles.API.QUANTITY_FOR_PRICE_ATTRIBUTE && !getProperty(newItem, game.itempiles.API.QUANTITY_FOR_PRICE_ATTRIBUTE)) { setProperty(newItem, game.itempiles.API.QUANTITY_FOR_PRICE_ATTRIBUTE, Utilities.getItemQuantity(newItem.item)); } diff --git a/src/helpers/transaction.js b/src/helpers/transaction.js index 26a90802..69f84492 100644 --- a/src/helpers/transaction.js +++ b/src/helpers/transaction.js @@ -1,6 +1,5 @@ import * as Utilities from "./utilities.js"; import * as PileUtilities from "./pile-utilities.js"; -import { areItemsColliding, getItemFlagData } from "./pile-utilities.js"; import ItemPileSocket from "../socket.js"; import PrivateAPI from "../API/private-api.js"; import { SYSTEMS } from "../systems.js"; @@ -61,7 +60,7 @@ export default class Transaction { foundry.utils.getProperty(itemData, CONSTANTS.FLAGS.ITEM + ".y") === undefined ) || - areItemsColliding(item, itemData) + PileUtilities.areItemsColliding(item, itemData) ) }); } @@ -199,8 +198,8 @@ export default class Transaction { this.itemDeltas = Array.from(this.itemDeltas).map(([id, quantity]) => { const item = this.actor.items.get(id).toObject(); - const existingFlagData = getItemFlagData(item); - const newFlagData = this.itemFlagMap.get(id) ?? {}; + const existingFlagData = PileUtilities.cleanItemFlagData(PileUtilities.getItemFlagData(item)); + const newFlagData = PileUtilities.cleanItemFlagData(this.itemFlagMap.get(id) ?? {}); setProperty(item, CONSTANTS.FLAGS.ITEM, foundry.utils.mergeObject(existingFlagData, newFlagData)); const type = this.itemTypeMap.get(id); Utilities.setItemQuantity(item, quantity, true); diff --git a/src/plugins/simple-calendar.js b/src/plugins/simple-calendar.js index 83af7616..ab9cec44 100644 --- a/src/plugins/simple-calendar.js +++ b/src/plugins/simple-calendar.js @@ -231,9 +231,6 @@ export default class SimpleCalendarPlugin extends BasePlugin { function merchantRefreshFilter(flags, newState, previousState, categories) { const openTimesEnabled = flags.openTimes.enabled; - - if (!openTimesEnabled) return false; - const openTimes = flags.openTimes.open; const closeTimes = flags.openTimes.close; @@ -253,23 +250,17 @@ function merchantRefreshFilter(flags, newState, previousState, categories) { ? (newState.time >= openingTime || newState.time <= closingTime) : (newState.time >= openingTime && newState.time <= closingTime); - const allWeekdays = window.SimpleCalendar.api.getAllWeekdays(); const dayLength = SimpleCalendar.api.timestampPlusInterval(0, { day: 1 }); - const daysPassed = Math.floor((newState.timestamp - previousState.timestamp) / dayLength); - const currentWeekday = newState.weekday; - - const shouldRefreshOnCurrentWeekday = flags.refreshItemsDays.includes(currentWeekday.name); - const shouldRefreshPastWeekday = flags.refreshItemsDays.length > 0 && daysPassed >= allWeekdays.length; + const allWeekdays = new Set(window.SimpleCalendar.api.getAllWeekdays()); - const shouldRefresh = ( - flags.refreshItemsOnOpen || - shouldRefreshOnCurrentWeekday || - shouldRefreshPastWeekday || - categories.intersection(new Set(flags.refreshItemsHolidays)).size > 0 - ); + const shouldRefreshOnCurrentWeekday = flags.refreshItemsDays.includes(newState.weekday); + const shouldRefreshPastWeekday = flags.refreshItemsDays.length > 0 && daysPassed >= allWeekdays.size; - return (!wasOpen && isOpen) && shouldRefresh; + return (flags.refreshItemsOnOpen && !wasOpen && isOpen && openTimesEnabled) + || shouldRefreshPastWeekday + || shouldRefreshOnCurrentWeekday + || categories.intersection(new Set(flags.refreshItemsHolidays)).size > 0; } diff --git a/src/stores/vault-store.js b/src/stores/vault-store.js index 5abf1716..89e05010 100644 --- a/src/stores/vault-store.js +++ b/src/stores/vault-store.js @@ -544,7 +544,7 @@ export class VaultItem extends PileItem { setProperty(flags, "x", x); setProperty(flags, "y", y); setProperty(flags, "flipped", flipped); - setProperty(itemData, "flags", flags); + setProperty(itemData, CONSTANTS.FLAGS.ITEM, flags); await game.itempiles.API.addItems(this.store.actor, [{ item: itemData, quantity