From 16a2cb0bdf05edcdfc7dded1eade5774f5c76833 Mon Sep 17 00:00:00 2001 From: Haxxer Date: Mon, 16 Sep 2024 08:18:39 +0100 Subject: [PATCH] Update --- changelog.md | 86 +++++-- languages/cs.json | 3 +- languages/de.json | 3 +- languages/en.json | 4 +- languages/fr.json | 3 +- languages/ja.json | 3 +- languages/pl.json | 1 + languages/pt-BR.json | 1 + languages/ru.json | 3 +- languages/zh_Hans.json | 3 +- src/API/private-api.js | 13 +- .../item-pile-config/item-pile-config.svelte | 7 +- src/helpers/pile-utilities.js | 13 + src/helpers/utilities.js | 1 + src/systems/dnd5e-2.4.1.js | 2 +- src/systems/dnd5e-3.1.2.js | 2 +- src/systems/dnd5e.js | 2 +- src/systems/vaarfeu.js | 241 +++++++++--------- 18 files changed, 225 insertions(+), 166 deletions(-) diff --git a/changelog.md b/changelog.md index c7534b6a..c8f30cf0 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,16 @@ # Item Piles Changelog +## Version 3.1.5 + +- Added missing localization for "Give To Character" item right click menu in D&D5e +- Updated Polish localization (thank you Lioheart on weblate!) +- Tweaked item piles config UI to have the Default Item Piles' configuration, unless it already has some item pile configuration +- Fixed issue with secondary currencies throwing errors when being added to vaults +- Fixed folders being created out of place when using the `folder` parameter in `game.itempiles.API.createItemPile()` +- Fixed missing localization in the edit currencies dialog + +Next update will not have v11 support. + ## Version 3.1.4 Hotfix - Fixed minor issue with item quantities breaking the entire module @@ -34,7 +45,8 @@ - Added support for currency exchange in custom item purchase prices - If you have configured an item that costs 1 gold piece and 1 magical rock, and you only have 1 platinum piece and 1 magical rock, you now get 9 gold pieces back as change, whereas before you needed exactly 1 gold piece and 1 magical rock. - Added option for a custom sell price on items, similar to custom purchase price -- Added `game.itempiles.API.combineItemPiles` which allows you to combine several item piles' inventory into a single item pile +- Added + `game.itempiles.API.combineItemPiles` which allows you to combine several item piles' inventory into a single item pile - 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 @@ -116,7 +128,8 @@ - Updated the Tormenta20 system configuration to fix its currency issues - Added support for the [Dragonbane - Drakar och Demoner](https://foundryvtt.com/packages/dragonbane) system (thank you xdy on github!) - Added the `game.itempiles.macro_execution_types` constants - see docs for more info - - For the above, added `game.itempiles.macro_execution_types.RENDER_INTERFACE`, which means that macros that are attached to item piles will execute its macro when the item piles interface is rendered + - For the above, added + `game.itempiles.macro_execution_types.RENDER_INTERFACE`, which means that macros that are attached to item piles will execute its macro when the item piles interface is rendered - Added item price modifiers on items, so items can decide how much they will deviate from the base price - Fixed merchant columns not being editable in newer versions of D&D 5e - Fixed rolltables not applying custom categories to items properly @@ -275,7 +288,8 @@ - `game.itempiles.API.getItemQuantity()` - `game.itempiles.API.calculateCurrencies()` which can be used to calculate different currency strings; - `game.itempiles.API.calculateCurrencies("10gp", "5gp")` would result in 5GP (wow, impressive right?) - - `game.itempiles.API.calculateCurrencies("9gp 4sp 9cp", "5sp 4cp")` would result in `8GP 9SP 4CP`, which is a bit more impressive + - `game.itempiles.API.calculateCurrencies("9gp 4sp 9cp", "5sp 4cp")` would result in + `8GP 9SP 4CP`, which is a bit more impressive - `game.itempiles.API.calculateCurrencies("9gp 4sp 9cp", "5sp 4cp", false)` would result in `10GP 3CP` - `game.itempiles.API.calculateCurrencies("9gp", 0.5)` would result in `4GP 5EP` - Deprecated `game.itempiles.API.getPaymentDataFromString()` in favor of `game.itempiles.API.getPaymentData()` @@ -294,7 +308,8 @@ - Added "Send To Character" when right-clicking items in your inventory in D&D5e - a much faster way to send items between characters - Added Merchant price modifier support for "group" type actors in D&D5e - adding a group to a merchant's price modifiers will apply the price modifiers to anyone belonging to that group actor (thanks to Paith on discord for the idea!) -- Added `game.itempiles.API.refreshMerchantInventory()`, which can be called to manually refresh a merchant's inventory based on its configured tables +- Added + `game.itempiles.API.refreshMerchantInventory()`, which can be called to manually refresh a merchant's inventory based on its configured tables - Added `PRICE_MODIFIER_TRANSFORMER` and `SYSTEM_HOOKS` to `game.itempiles.API.addSystemIntegration()` - Updated Chinese and Czech localization (thank you EternalRider and Mortan on weblate!) @@ -330,7 +345,8 @@ ## Version 2.7.17 - Fixed services would not stack and instead duplicate when added to merchants - if you still want non-stacking services, set them as non-stacking in the service's settings -- Fixed services not being removed by the Simple Calendar during refreshes - if you want to keep them, turn on `Keep On Merchant` +- Fixed services not being removed by the Simple Calendar during refreshes - if you want to keep them, turn on + `Keep On Merchant` ## Version 2.7.16 @@ -396,7 +412,8 @@ ## Version 2.7.7 - Added item quantity to the populate items tab of merchants -- Added `game.itempiles.API.getMerchantPriceModifiers` and `game.itempiles.API.updateMerchantPriceModifiers` (see API docs) +- Added `game.itempiles.API.getMerchantPriceModifiers` and + `game.itempiles.API.updateMerchantPriceModifiers` (see API docs) - Tweaked merchant populate items menu tables dropdown to recursively find every table under the configured tables folder - Tweaked merchant populate items to recursively roll all tables within tables, including tables in compendiums - Tweaked merchant populate items table behavior - if an item has quantity, item piles will assume that its quantity is how many one will get when buying 1 quantity of the item @@ -464,7 +481,8 @@ ## Version 2.6.14 -- Added `game.itempiles.API.unrenderItemPileInterface` which can be used to remotely close item pile interfaces for players +- Added + `game.itempiles.API.unrenderItemPileInterface` which can be used to remotely close item pile interfaces for players - Fixed opening document sheets in compendiums would throw error and fail to open (Foundry v11) - Fixed hovering over vault items sometimes throwing errors in the console - Fixed not having any hotkeys configured would throw errors when opening item pile UIs @@ -517,7 +535,8 @@ - Fixed merchant open/close time not evaluating the first time you open the shop, so players could access the shop when it should have been closed - Fixed merchant tables not saving their roll formula - Fixed merchant buy/sell/service tables being crunched up into a small space when too few items had been added, which made it impossible to select a different price on items with more than one price -- Fixed issues with creating new item piles on some systems (like Starfinder), caused by item piles trying to create items on the new item pile with `Item`s instead of the item's data +- Fixed issues with creating new item piles on some systems (like Starfinder), caused by item piles trying to create items on the new item pile with + `Item`s instead of the item's data - Fixed split currencies button being incorrectly disabled ## Version 2.6.7 @@ -559,7 +578,8 @@ - Updated Portuguese (Brazil) and French localization (thank you eunaumtenhoid and rectulo on Weblate!) - Added `PILE_DEFAULTS` and `TOKEN_FLAG_DEFAULT` system specific settings - Tweaked the way default item pile data is applied, in the case of merchant columns -- Fixed `game.itempiles.API.createItemPile` not respecting an overriding `texture.src`, `texture.scaleX`, and `texture.scaleY` property on the token data +- Fixed `game.itempiles.API.createItemPile` not respecting an overriding `texture.src`, `texture.scaleX`, and + `texture.scaleY` property on the token data - Fixed populate items not having scroll bars when enough items was added to the merchant - Fixed item piles created in PF2e would not be scaled appropriately due to overriding system flags @@ -617,7 +637,9 @@ ## Version 2.5.2 -- Tweaked the way rendering item piles work - if the actor sheet is rendered without holding the actor sheet hotkey, it will render the item pile UI - if you call `ActorSheet#render` you can add `{ bypassItemPiles: true }` to the secondary options to prevent the item piles UI from opening, and instead open the actor sheet +- Tweaked the way rendering item piles work - if the actor sheet is rendered without holding the actor sheet hotkey, it will render the item pile UI - if you call + `ActorSheet#render` you can add + `{ bypassItemPiles: true }` to the secondary options to prevent the item piles UI from opening, and instead open the actor sheet - Fixed `Split x ways` sometimes being able to be clicked when the item pile has nothing to be split ## Version 2.5.1 @@ -626,7 +648,8 @@ ## Version 2.5.0 -- Added support for `quantity per price` - this per item setting allows you to configure how many of the item is received when paying its price +- Added support for + `quantity per price` - this per item setting allows you to configure how many of the item is received when paying its price - Updated PF2e's system settings to account for the above - Updated Polish localization (thank you Leoheart on weblate!) - Updated WFRP4e system settings to take into account the multiple currencies on prices for items @@ -651,8 +674,10 @@ ## Version 2.4.17 - Updates to German localization - thank you blueacousticmusic! -- Added `x[quantity]` to the name of new pile-type item pile tokens, so you know how many of that item was dropped on the ground -- Changed `Infinite Quantity` on items to be a multi-choice option whether to defer to the owner's setting, or whether to have infinite quantity +- Added + `x[quantity]` to the name of new pile-type item pile tokens, so you know how many of that item was dropped on the ground +- Changed + `Infinite Quantity` on items to be a multi-choice option whether to defer to the owner's setting, or whether to have infinite quantity - Dropping items now always prompts whether to create an item pile or not - Dropping items from the sidebar or compendiums should now allow you to change the dropped quantity - Fixed issue with items not being passed properly to macros being called when buying from and selling to merchants (thank you FeistyMango!) @@ -706,7 +731,8 @@ - Updated German localization (thanks blueacousticmusic on Weblate!) - Added further Simple Calendar support; merchants can now be closed on specific weekday, and categories on notes can cause merchants to be closed (think holidays) - Added support for vault item styling based on item properties -- Added `Hide Items With Zero Cost` setting to merchants, which automatically hides items in the buy/sell/service tabs if they are free +- Added + `Hide Items With Zero Cost` setting to merchants, which automatically hides items in the buy/sell/service tabs if they are free - Tweaked `Buy Items` tab to be hidden if the merchant has no visible items for sale, and the customer can sell items - Fixed disabled elements being blue due to styling being incorrect - Fixed item-based currencies would show up in the vault grids @@ -776,14 +802,16 @@ - Added chat message for when users give each other items - Added `game.itempiles.API.addSystemIntegration()` for systems to integrate into item piles more readily - Added support for `true` and `false` values in system item filters -- Added `change` as a secondary argument to `game.itempiles.API.removeCurrencies()` and `game.itempiles.API.transferCurrencies()` so that the currency removal/transfer can handle converting currencies into change to cover the full transfer +- Added `change` as a secondary argument to `game.itempiles.API.removeCurrencies()` and + `game.itempiles.API.transferCurrencies()` so that the currency removal/transfer can handle converting currencies into change to cover the full transfer - Added more hooks: - `item-piles-preClickItemPile` - `item-piles-preGiveItem` - `item-piles-giveItem` - Added more item piles constants and useful info in `game.itempiles` - Updated DnD5e system support to support the new 2.1.0 update -- Tweaked `game.itempiles.api.turnTokensIntoItemPiles` to use the default item pile's settings when converting tokens into item piles +- Tweaked + `game.itempiles.api.turnTokensIntoItemPiles` to use the default item pile's settings when converting tokens into item piles - Tweaked item piles containers to be the only tokens that get the additional buttons in its token HUD - Tweaked the item similarities setting - a lack of them will now treat every item as distinct items rather than the same - Fixed GMs still being able to drop items on the canvas when the setting was not enabled @@ -849,7 +877,8 @@ ## Version 2.3.3 -- Reworked the `Populate Items` tab in merchants - you can now add all items on rollable tables to populate a merchant's inventory, rolling for the quantity of each item +- Reworked the + `Populate Items` tab in merchants - you can now add all items on rollable tables to populate a merchant's inventory, rolling for the quantity of each item - Added "Show To Which Players" dialog when "Show to players" is clicked on item piles and merchants - Added `Hide header button` client setting - Fixed `Split currency x ways` not working when "Sharing Enabled: Currencies" was disabled @@ -885,7 +914,8 @@ - Fixed spectating users would cause the trade to be cancelled when closing the trade window - Fixed spectating users would not see newly added items in trades - Fixed users not being able to spectate trades after they reconnect -- Fixed `turnTokensToItemPiles` would make every token be updated to use the image of the last token passed to the function +- Fixed + `turnTokensToItemPiles` would make every token be updated to use the image of the last token passed to the function - Updated German localization (Thanks IrishWolf!) ## Version 2.2.13 @@ -1097,7 +1127,8 @@ ## Version 1.4.6 -- Adjusted API to use native foundry `Item#fromDropData` instead of my own implementation (Thank you, TheGiddyLimit on GitHub!) +- Adjusted API to use native foundry + `Item#fromDropData` instead of my own implementation (Thank you, TheGiddyLimit on GitHub!) - Fixed issue relating to some systems not generating a new ID for items, which caused false-positives when trying to find similar items on actors that were the source of said items - Fixed issue where systems would override core functions on items that modify names and other data, Item Piles will now always call the system's Item specific functions - Fixes issue with PF1 items sometimes showing up as identified when they were unidentified @@ -1203,7 +1234,8 @@ ## Version 1.2.6 -- Added `Item Filters` setting - now you can more accurately filter items you do not want to show up in item piles, such as natural weapons +- Added + `Item Filters` setting - now you can more accurately filter items you do not want to show up in item piles, such as natural weapons - Updated all supported systems to support the above and added migrations to convert existing settings to the new system - Reset your Item Piles module settings to ensure you have the latest system configurations - Removed `Item Type Attribute` and `Item Type Filters` as the above feature covers these cases @@ -1244,7 +1276,8 @@ - Added setting to hide the "Item Piles" text in the actor header - useful if you have too many modules, and the header is getting crowded - Added support for the Tormenta 20 system: -- Tweaked `game.itempiles.API.turnTokensIntoItemPiles` to turn tokens into item piles without having the "Display Single Item +- Tweaked + `game.itempiles.API.turnTokensIntoItemPiles` to turn tokens into item piles without having the "Display Single Item Image" setting turned on - API changes: - Changed: `game.itempiles.API.addItems` @@ -1301,9 +1334,11 @@ - `item-piles-preOpenItemPileInventory` - Called locally before an item pile's inventory is opened - `item-piles-openItemPileInventory` - Called locally after an item pile's inventory has been opened - API changes: - - Changed `game.itempiles.API.turnTokenIntoItemPile` to `game.itempiles.API.turnTokensIntoItemPiles`, now can take array of + - Changed `game.itempiles.API.turnTokenIntoItemPile` to + `game.itempiles.API.turnTokensIntoItemPiles`, now can take array of tokens to turn into piles - - Changed `game.itempiles.API.revertTokenFromItemPile` to `game.itempiles.API.revertTokensFromItemPiles`, now can take array + - Changed `game.itempiles.API.revertTokenFromItemPile` to + `game.itempiles.API.revertTokensFromItemPiles`, now can take array of tokens to revert - Improved token detection when multiple owned tokens are interacting with item piles, it should now more reliably pick sane tokens. @@ -1330,8 +1365,9 @@ - Added API endpoints: - `game.itempiles.API.getActorItemFilters(TokenDocument|Actor)` - Returns the item type filters for a given item pile - - `game.itempiles.API.getActorItems(TokenDocument|Actor, Array|Boolean)` - Returns the items the item pile contains and - can transfer + - + `game.itempiles.API.getActorItems(TokenDocument|Actor, Array|Boolean)` - Returns the items the item pile contains and + can transfer - Updated japanese localization - Fixed item piles not respecting item type filters - Fixed issue with `game.itempiles.API.turnTokenIntoItemPile` not actually turning the token into an item pile diff --git a/languages/cs.json b/languages/cs.json index 9dbb4a35..3db83164 100644 --- a/languages/cs.json +++ b/languages/cs.json @@ -567,6 +567,7 @@ "Title": "Editovat měny", "Content": "Jako GM můžete aktualizovat měny v této kupě položek:", "Secondary": "Sekundární měny:", + "NoCurrency": "{actor_name} nemá žádnou platnou měnu...", "Submit": "Potvrdit" }, "DropCurrencies": { @@ -863,4 +864,4 @@ "Deposit": "{actor_name} ({user_name}) *uložil* {item_name} x {quantity} ({date})" } } -} \ No newline at end of file +} diff --git a/languages/de.json b/languages/de.json index 19a77e5e..9344bb44 100644 --- a/languages/de.json +++ b/languages/de.json @@ -907,6 +907,7 @@ "Title": "Währungen anpassen", "Content": "Als SL kannst du die Währungen dieses Stapels anpassen:", "Submit": "Speichern", + "NoCurrency": "{actor_name} besitzt keine validen Währungen...", "Secondary": "Sekundärwährungen:" }, "CustomItemCategoriesEditor": { @@ -1090,4 +1091,4 @@ "Withdraw": "{actor_name} ({user_name}) **entnahm** {item_name} x {quantity} ({date})" } } -} \ No newline at end of file +} diff --git a/languages/en.json b/languages/en.json index 3ecac0db..b9e18136 100644 --- a/languages/en.json +++ b/languages/en.json @@ -5,7 +5,8 @@ "Currency": "Currency", "ContextMenu": { "ShowToPlayers": "Show To Players", - "RequestTrade": "Request Trade" + "RequestTrade": "Request Trade", + "GiveToCharacter": "Give To Character" }, "PlayerList": { "TradeButton": "Trade" @@ -359,6 +360,7 @@ "Title": "Editing Currencies", "Content": "As a GM, you can update the currencies on this item pile:", "Secondary": "Secondary Currencies:", + "NoCurrency": "{actor_name} has no valid currencies...", "Submit": "Submit" }, "DropCurrencies": { diff --git a/languages/fr.json b/languages/fr.json index 07e4b304..d51edfb2 100644 --- a/languages/fr.json +++ b/languages/fr.json @@ -887,6 +887,7 @@ "Content": "En tant que MJ, vous pouvez mettre à jour les devises de cette pile d'objets :", "Submit": "Soumettre", "Title": "Modifier les devises", + "NoCurrency": "{actor_name} n'a pas de devises valables...", "Secondary": "Devises secondaires :" }, "CustomItemCategoriesEditor": { @@ -1106,4 +1107,4 @@ "Deposit": "{actor_name} ({user_name}) *a déposé* {item_name} x {quantity} ({date})" } } -} \ No newline at end of file +} diff --git a/languages/ja.json b/languages/ja.json index 7d8b8d9a..69963d1d 100644 --- a/languages/ja.json +++ b/languages/ja.json @@ -913,6 +913,7 @@ "Submit": "送信", "Title": "通貨を編集", "Content": "GMとして、このアイテムの山の金額を更新できます:", + "NoCurrency": "{actor_name}には有効な硬貨がありません...", "Secondary": "補助通貨:" }, "WithdrawItem": { @@ -1042,4 +1043,4 @@ "Deposit": "{actor_name}({user_name})が{item_name} x {quantity}を預けました({date})" } } -} \ No newline at end of file +} diff --git a/languages/pl.json b/languages/pl.json index a39f0f6b..07068e3f 100644 --- a/languages/pl.json +++ b/languages/pl.json @@ -346,6 +346,7 @@ "Title": "Edycja walut", "Content": "Jako GM możesz zaktualizować waluty na tym stosie przedmiotów:", "Submit": "Wyślij", + "NoCurrency": "{aktor_name} nie ma ważnych walut...", "Secondary": "Waluty dodatkowe:" }, "TradeMerchantItem": { diff --git a/languages/pt-BR.json b/languages/pt-BR.json index a20e87dc..84767d06 100644 --- a/languages/pt-BR.json +++ b/languages/pt-BR.json @@ -359,6 +359,7 @@ "Title": "Editando Moedas", "Content": "Como MJ, você pode atualizar as moedas nesta pilha de itens:", "Secondary": "Moedas Secundárias:", + "NoCurrency": "{actor_name} não tem moedas válidas.", "Submit": "Enviar" }, "DropCurrencies": { diff --git a/languages/ru.json b/languages/ru.json index 74f7eec3..629cc771 100644 --- a/languages/ru.json +++ b/languages/ru.json @@ -340,6 +340,7 @@ "Title": "Редактирование денег", "Content": "Как ГМ, вы можете обновить валюты в этой добыче:", "Secondary": "Вторичные монеты:", + "NoCurrency": "У {actor_name} нет денег...", "Submit": "Принять" }, "DropCurrencies": { @@ -922,4 +923,4 @@ } } } -} \ No newline at end of file +} diff --git a/languages/zh_Hans.json b/languages/zh_Hans.json index 504e4e8e..4c726161 100644 --- a/languages/zh_Hans.json +++ b/languages/zh_Hans.json @@ -517,6 +517,7 @@ "Title": "编辑货币", "Content": "作为 GM,你可以在这个物品堆上更新货币:", "Submit": "提交", + "NoCurrency": "{actor_name} 没有可用的货币…", "Secondary": "次要货币:" }, "UnstackableItemTypesEditor": { @@ -910,4 +911,4 @@ "Withdraw": "{actor_name} ({user_name}) **取出了** {item_name} x {quantity} ({date})" } } -} \ No newline at end of file +} diff --git a/src/API/private-api.js b/src/API/private-api.js index cb3aaa3d..f2a0847f 100644 --- a/src/API/private-api.js +++ b/src/API/private-api.js @@ -17,6 +17,7 @@ import ReceiveItemsShell from "../applications/dialogs/receive-items-dialog/rece import BankVaultApp from "../applications/vault-app/vault-app.js"; import { hotkeyActionState } from "../hotkeys.js"; import { ensureValidIds } from "../helpers/utilities.js"; +import { getPileActorDefaults } from "../helpers/pile-utilities.js"; const preloadedFiles = new Set(); @@ -1211,17 +1212,7 @@ export default class PrivateAPI { if (createActor) { - const defaultItemPileId = Helpers.getSetting(SETTINGS.DEFAULT_ITEM_PILE_ACTOR_ID); - const defaultItemPileActor = game.actors.get(defaultItemPileId); - - let pileDataDefaults = foundry.utils.deepClone(CONSTANTS.PILE_DEFAULTS); - pileDataDefaults.enabled = true; - if (foundry.utils.isEmpty(itemPileFlags) && defaultItemPileActor) { - const defaultItemPileSettings = PileUtilities.getActorFlagData(defaultItemPileActor); - itemPileFlags = foundry.utils.mergeObject(pileDataDefaults, defaultItemPileSettings); - } - - pileDataDefaults = foundry.utils.mergeObject(pileDataDefaults, itemPileFlags); + const pileDataDefaults = PileUtilities.getPileActorDefaults({ ...itemPileFlags, enabled: true }); const actorData = { name: actor || "New Item Pile", type: Helpers.getSetting("actorClassType"), img: "icons/svg/item-bag.svg" diff --git a/src/applications/item-pile-config/item-pile-config.svelte b/src/applications/item-pile-config/item-pile-config.svelte index 8c0b9424..cf106ae3 100644 --- a/src/applications/item-pile-config/item-pile-config.svelte +++ b/src/applications/item-pile-config/item-pile-config.svelte @@ -28,7 +28,12 @@ let form; - let pileData = PileUtilities.getActorFlagData(pileActor); + let pileData = PileUtilities.getActorFlagData(pileActor, { useDefaults: false }); + if (foundry.utils.isEmpty(pileData)) { + pileData = PileUtilities.getPileActorDefaults(); + } else { + pileData = PileUtilities.getActorFlagData(pileActor); + } if (typeof pileData?.deleteWhenEmpty === "boolean") { pileData.deleteWhenEmpty = !!pileData?.deleteWhenEmpty; diff --git a/src/helpers/pile-utilities.js b/src/helpers/pile-utilities.js index cad97c83..c2336d62 100644 --- a/src/helpers/pile-utilities.js +++ b/src/helpers/pile-utilities.js @@ -17,6 +17,19 @@ export function getPileDefaults() { return foundry.utils.mergeObject({}, CONSTANTS.PILE_DEFAULTS, Helpers.getSetting(SETTINGS.PILE_DEFAULTS) ?? {}); } +export function getPileActorDefaults(itemPileFlags = {}) { + const defaultItemPileId = Helpers.getSetting(SETTINGS.DEFAULT_ITEM_PILE_ACTOR_ID); + const defaultItemPileActor = game.actors.get(defaultItemPileId); + + let pileDataDefaults = foundry.utils.deepClone(CONSTANTS.PILE_DEFAULTS); + if (foundry.utils.isEmpty(itemPileFlags) && defaultItemPileActor) { + const defaultItemPileSettings = getActorFlagData(defaultItemPileActor); + itemPileFlags = foundry.utils.mergeObject(pileDataDefaults, defaultItemPileSettings); + } + + return foundry.utils.mergeObject(pileDataDefaults, itemPileFlags); +} + function getFlagData(inDocument, flag, defaults, existing = false) { const defaultFlags = foundry.utils.deepClone(defaults); let flags = foundry.utils.deepClone(existing || (foundry.utils.getProperty(inDocument, flag) ?? {})); diff --git a/src/helpers/utilities.js b/src/helpers/utilities.js index 9c8184fc..f8f0efde 100644 --- a/src/helpers/utilities.js +++ b/src/helpers/utilities.js @@ -403,6 +403,7 @@ export async function createFoldersFromNames(folders, type = "Actor") { if (!actualFolder) { const folderData = { name: folder, type, sorting: 'a' }; if (lastFolder) { + folderData.folder = lastFolder.id; folderData.parent = lastFolder.id; } actualFolder = await Folder.create(folderData); diff --git a/src/systems/dnd5e-2.4.1.js b/src/systems/dnd5e-2.4.1.js index 8ba4a9fa..38e6c49c 100644 --- a/src/systems/dnd5e-2.4.1.js +++ b/src/systems/dnd5e-2.4.1.js @@ -247,7 +247,7 @@ export default { Hooks.on("dnd5e.getItemContextOptions", (item, options) => { options.push({ - name: "Give to character", + name: game.i18n.localize("ITEM-PILES.ContextMenu.GiveToCharacter"), icon: "", callback: async () => { const result = await GiveItems.show(item); diff --git a/src/systems/dnd5e-3.1.2.js b/src/systems/dnd5e-3.1.2.js index f1390663..8921e52a 100644 --- a/src/systems/dnd5e-3.1.2.js +++ b/src/systems/dnd5e-3.1.2.js @@ -258,7 +258,7 @@ export default { Hooks.on("dnd5e.getItemContextOptions", (item, options) => { options.push({ - name: "Give to character", + name: game.i18n.localize("ITEM-PILES.ContextMenu.GiveToCharacter"), icon: "", callback: async () => { const result = await GiveItems.show(item); diff --git a/src/systems/dnd5e.js b/src/systems/dnd5e.js index 16447578..88d253dd 100644 --- a/src/systems/dnd5e.js +++ b/src/systems/dnd5e.js @@ -259,7 +259,7 @@ export default { Hooks.on("dnd5e.getItemContextOptions", (item, options) => { options.push({ - name: "Give to character", + name: game.i18n.localize("ITEM-PILES.ContextMenu.GiveToCharacter"), icon: "", callback: async () => { const result = await GiveItems.show(item); diff --git a/src/systems/vaarfeu.js b/src/systems/vaarfeu.js index 1871a67b..4a33bd48 100644 --- a/src/systems/vaarfeu.js +++ b/src/systems/vaarfeu.js @@ -4,67 +4,70 @@ import CONSTANTS from "../constants/constants.js"; export default { -"VERSION": "1.0.0", - // The actor class type is the type of actor that will be used for the default item pile actor that is created on first item drop. - "ACTOR_CLASS_TYPE": "character", - // The item class type is the type of item that will be used for the default loot item - "ITEM_CLASS_LOOT_TYPE": "loot", - // The item class type is the type of item that will be used for the default weapon item - "ITEM_CLASS_WEAPON_TYPE": "weapon", - // The item class type is the type of item that will be used for the default equipment item - "ITEM_CLASS_EQUIPMENT_TYPE": "equipment", - // The item quantity attribute is the path to the attribute on items that denote how many of that item that exists - "ITEM_QUANTITY_ATTRIBUTE": "system.quantity", - // The item price attribute is the path to the attribute on each item that determine how much it costs - "ITEM_PRICE_ATTRIBUTE": "system.price.value", - // Item filters actively remove items from the item pile inventory UI that users cannot loot, such as spells, feats, and classes - "ITEM_FILTERS": [ - { - "path": "type", - "filters": "spell,feat,class,subclass,background" - }, - { - "path": "system.type.value", - "filters": "natural" - } - ], - // This function is an optional system handler that specifically transforms an item's price into a more unified numeric format - "ITEM_COST_TRANSFORMER": (item, currencies) => { - const overallCost = Number(foundry.utils.getProperty(item, "system.price.value")) ?? 0; - const priceDenomination = foundry.utils.getProperty(item, "system.price.denomination"); - if (priceDenomination) { - const currencyDenomination = currencies.filter((currency) => currency.type === "attribute").find((currency) => { - return currency.data.path.toLowerCase().endsWith(priceDenomination); - }); - if (currencyDenomination) { - return overallCost * currencyDenomination.exchangeRate; - } - } - return overallCost ?? 0; - }, - "PRICE_MODIFIER_TRANSFORMER": ({ - buyPriceModifier, - sellPriceModifier, - actor = false, - actorPriceModifiers = [] - } = {}) => { - const modifiers = { - buyPriceModifier, - sellPriceModifier - }; - if (!actor) - return modifiers; - const groupModifiers = actorPriceModifiers.map((data2) => ({ ...data2, actor: fromUuidSync(data2.actorUuid) })).filter((data2) => { - return data2.actor && data2.actor.type === "group" && data2.actor.system.members.some((member) => member === actor); - }); - modifiers.buyPriceModifier = groupModifiers.reduce((acc, data2) => { - return data2.override ? data2.buyPriceModifier ?? acc : acc * data2.buyPriceModifier; - }, buyPriceModifier); - modifiers.sellPriceModifier = groupModifiers.reduce((acc, data2) => { - return data2.override ? data2.sellPriceModifier ?? acc : acc * data2.sellPriceModifier; - }, sellPriceModifier); - return modifiers; - }, + "VERSION": "1.0.0", + // The actor class type is the type of actor that will be used for the default item pile actor that is created on first item drop. + "ACTOR_CLASS_TYPE": "character", + // The item class type is the type of item that will be used for the default loot item + "ITEM_CLASS_LOOT_TYPE": "loot", + // The item class type is the type of item that will be used for the default weapon item + "ITEM_CLASS_WEAPON_TYPE": "weapon", + // The item class type is the type of item that will be used for the default equipment item + "ITEM_CLASS_EQUIPMENT_TYPE": "equipment", + // The item quantity attribute is the path to the attribute on items that denote how many of that item that exists + "ITEM_QUANTITY_ATTRIBUTE": "system.quantity", + // The item price attribute is the path to the attribute on each item that determine how much it costs + "ITEM_PRICE_ATTRIBUTE": "system.price.value", + // Item filters actively remove items from the item pile inventory UI that users cannot loot, such as spells, feats, and classes + "ITEM_FILTERS": [ + { + "path": "type", + "filters": "spell,feat,class,subclass,background" + }, + { + "path": "system.type.value", + "filters": "natural" + } + ], + // This function is an optional system handler that specifically transforms an item's price into a more unified numeric format + "ITEM_COST_TRANSFORMER": (item, currencies) => { + const overallCost = Number(foundry.utils.getProperty(item, "system.price.value")) ?? 0; + const priceDenomination = foundry.utils.getProperty(item, "system.price.denomination"); + if (priceDenomination) { + const currencyDenomination = currencies.filter((currency) => currency.type === "attribute").find((currency) => { + return currency.data.path.toLowerCase().endsWith(priceDenomination); + }); + if (currencyDenomination) { + return overallCost * currencyDenomination.exchangeRate; + } + } + return overallCost ?? 0; + }, + "PRICE_MODIFIER_TRANSFORMER": ({ + buyPriceModifier, + sellPriceModifier, + actor = false, + actorPriceModifiers = [] + } = {}) => { + const modifiers = { + buyPriceModifier, + sellPriceModifier + }; + if (!actor) + return modifiers; + const groupModifiers = actorPriceModifiers.map((data2) => ({ + ...data2, + actor: fromUuidSync(data2.actorUuid) + })).filter((data2) => { + return data2.actor && data2.actor.type === "group" && data2.actor.system.members.some((member) => member === actor); + }); + modifiers.buyPriceModifier = groupModifiers.reduce((acc, data2) => { + return data2.override ? data2.buyPriceModifier ?? acc : acc * data2.buyPriceModifier; + }, buyPriceModifier); + modifiers.sellPriceModifier = groupModifiers.reduce((acc, data2) => { + return data2.override ? data2.sellPriceModifier ?? acc : acc * data2.sellPriceModifier; + }, sellPriceModifier); + return modifiers; + }, "PILE_DEFAULTS": { merchantColumns: [{ @@ -101,63 +104,63 @@ export default { // In the case of attributes, the path is relative to the "actor.system" // In the case of items, it is recommended you export the item with `.toObject()` and strip out any module data "CURRENCIES": [ - { - type: "attribute", - name: "VAARFEU.CurrencyPP", - img: "icons/commodities/currency/coin-inset-snail-silver.webp", - abbreviation: "{#}PP", - data: { - path: "system.currency.pp" - }, - primary: false, - exchangeRate: 10 - }, - { - type: "attribute", - name: "VAARFEU.CurrencyGP", - img: "icons/commodities/currency/coin-embossed-crown-gold.webp", - abbreviation: "{#}GP", - data: { - path: "system.currency.gp" - }, - primary: true, - exchangeRate: 1 - }, - { - type: "attribute", - name: "VAARFEU.CurrencyEP", - img: "icons/commodities/currency/coin-inset-copper-axe.webp", - abbreviation: "{#}EP", - data: { - path: "system.currency.ep" - }, - primary: false, - exchangeRate: 0.5 - }, - { - type: "attribute", - name: "VAARFEU.CurrencySP", - img: "icons/commodities/currency/coin-engraved-moon-silver.webp", - abbreviation: "{#}SP", - data: { - path: "system.currency.sp" - }, - primary: false, - exchangeRate: 0.1 - }, - { - type: "attribute", - name: "VAARFEU.CurrencyCP", - img: "icons/commodities/currency/coin-engraved-waves-copper.webp", - abbreviation: "{#}CP", - data: { - path: "system.currency.cp" - }, - primary: false, - exchangeRate: 0.01 - } - ], - + { + type: "attribute", + name: "VAARFEU.CurrencyPP", + img: "icons/commodities/currency/coin-inset-snail-silver.webp", + abbreviation: "{#}PP", + data: { + path: "system.currency.pp" + }, + primary: false, + exchangeRate: 10 + }, + { + type: "attribute", + name: "VAARFEU.CurrencyGP", + img: "icons/commodities/currency/coin-embossed-crown-gold.webp", + abbreviation: "{#}GP", + data: { + path: "system.currency.gp" + }, + primary: true, + exchangeRate: 1 + }, + { + type: "attribute", + name: "VAARFEU.CurrencyEP", + img: "icons/commodities/currency/coin-inset-copper-axe.webp", + abbreviation: "{#}EP", + data: { + path: "system.currency.ep" + }, + primary: false, + exchangeRate: 0.5 + }, + { + type: "attribute", + name: "VAARFEU.CurrencySP", + img: "icons/commodities/currency/coin-engraved-moon-silver.webp", + abbreviation: "{#}SP", + data: { + path: "system.currency.sp" + }, + primary: false, + exchangeRate: 0.1 + }, + { + type: "attribute", + name: "VAARFEU.CurrencyCP", + img: "icons/commodities/currency/coin-engraved-waves-copper.webp", + abbreviation: "{#}CP", + data: { + path: "system.currency.cp" + }, + primary: false, + exchangeRate: 0.01 + } + ], + "VAULT_STYLES": [ { path: "system.rarity", @@ -200,7 +203,7 @@ export default { Hooks.on("vaarfeu.getItemContextOptions", (item, options) => { options.push({ - name: "Give to character", + name: game.i18n.localize("ITEM-PILES.ContextMenu.GiveToCharacter"), icon: "", callback: async () => { const result = await GiveItems.show(item);