From 15b696398cc64c6c9cf1917a01eafa2d2dcb4c3d Mon Sep 17 00:00:00 2001 From: Joaquin Pereyra Date: Sat, 28 Jun 2025 15:37:04 -0300 Subject: [PATCH] REFACTOR: rename dhpItem to DHItem REFACTOR: improvement Item#isInventoryItem getter REFACTOR: simplify Item's createDialog static method. REFACTOR: remove documentCreate template --- daggerheart.mjs | 2 +- module/data/item/armor.mjs | 3 +- module/data/item/base.mjs | 4 +- module/data/item/consumable.mjs | 3 +- module/data/item/miscellaneous.mjs | 3 +- module/data/item/weapon.mjs | 4 +- module/documents/_module.mjs | 2 +- module/documents/item.mjs | 110 ++++++++++++--------------- templates/sidebar/documentCreate.hbs | 45 ----------- 9 files changed, 61 insertions(+), 115 deletions(-) delete mode 100644 templates/sidebar/documentCreate.hbs diff --git a/daggerheart.mjs b/daggerheart.mjs index 239b307d..36838fb8 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -52,7 +52,7 @@ Hooks.once('init', () => { CONFIG.MeasuredTemplate.objectClass = DhMeasuredTemplate; - CONFIG.Item.documentClass = documents.DhpItem; + CONFIG.Item.documentClass = documents.DHItem; //Registering the Item DataModel CONFIG.Item.dataModels = models.items.config; diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index b0fdf0ae..d9895787 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -9,7 +9,8 @@ export default class DHArmor extends BaseDataItem { label: 'TYPES.Item.armor', type: 'armor', hasDescription: true, - isQuantifiable: true + isQuantifiable: true, + isInventoryItem: true, }); } diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 492fcfe1..c8c4306b 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -5,6 +5,7 @@ * @property {string} type - The system type that this data model represents. * @property {boolean} hasDescription - Indicates whether items of this type have description field * @property {boolean} isQuantifiable - Indicates whether items of this type have quantity field + * @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item */ const fields = foundry.data.fields; @@ -16,7 +17,8 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { label: 'Base Item', type: 'base', hasDescription: false, - isQuantifiable: false + isQuantifiable: false, + isInventoryItem: false, }; } diff --git a/module/data/item/consumable.mjs b/module/data/item/consumable.mjs index 6c8df798..cb8a13b5 100644 --- a/module/data/item/consumable.mjs +++ b/module/data/item/consumable.mjs @@ -8,7 +8,8 @@ export default class DHConsumable extends BaseDataItem { label: 'TYPES.Item.consumable', type: 'consumable', hasDescription: true, - isQuantifiable: true + isQuantifiable: true, + isInventoryItem: true, }); } diff --git a/module/data/item/miscellaneous.mjs b/module/data/item/miscellaneous.mjs index d7687dc7..529cf9a9 100644 --- a/module/data/item/miscellaneous.mjs +++ b/module/data/item/miscellaneous.mjs @@ -8,7 +8,8 @@ export default class DHMiscellaneous extends BaseDataItem { label: 'TYPES.Item.miscellaneous', type: 'miscellaneous', hasDescription: true, - isQuantifiable: true + isQuantifiable: true, + isInventoryItem: true, }); } diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 3da7705e..f989f3f2 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -12,9 +12,7 @@ export default class DHWeapon extends BaseDataItem { type: 'weapon', hasDescription: true, isQuantifiable: true, - embedded: { - feature: 'featureTest' - } + isInventoryItem: true, }); } diff --git a/module/documents/_module.mjs b/module/documents/_module.mjs index 03237ee5..e6099009 100644 --- a/module/documents/_module.mjs +++ b/module/documents/_module.mjs @@ -1,4 +1,4 @@ export { default as DhpActor } from './actor.mjs'; -export { default as DhpItem } from './item.mjs'; +export { default as DHItem } from './item.mjs'; export { default as DhpCombat } from './combat.mjs'; export { default as DhActiveEffect } from './activeEffect.mjs'; diff --git a/module/documents/item.mjs b/module/documents/item.mjs index dce2c0e1..6f2d6eaa 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -1,4 +1,8 @@ -export default class DhpItem extends Item { +/** + * Override and extend the basic Item implementation. + * @extends {foundry.documents.Item} + */ +export default class DHItem extends foundry.documents.Item { /** @inheritDoc */ prepareEmbeddedDocuments() { super.prepareEmbeddedDocuments(); @@ -25,75 +29,59 @@ export default class DhpItem extends Item { return data; } - isInventoryItem() { - return ['weapon', 'armor', 'miscellaneous', 'consumable'].includes(this.type); + /** + * Determine if this item is classified as an inventory item based on its metadata. + * @returns {boolean} Returns `true` if the item is an inventory item. + */ + get isInventoryItem() { + return this.system.constructor.metadata.isInventoryItem ?? false; } - static async createDialog(data = {}, { parent = null, pack = null, ...options } = {}) { - const documentName = this.metadata.name; - const types = game.documentTypes[documentName].filter(t => t !== CONST.BASE_DOCUMENT_TYPE); - let collection; - if (!parent) { - if (pack) collection = game.packs.get(pack); - else collection = game.collections.get(documentName); - } - const folders = collection?._formatFolderSelectOptions() ?? []; - const label = game.i18n.localize(this.metadata.label); - const title = game.i18n.format('DOCUMENT.Create', { type: label }); - const typeObjects = types.reduce((obj, t) => { - const label = CONFIG[documentName]?.typeLabels?.[t] ?? t; - obj[t] = { value: t, label: game.i18n.has(label) ? game.i18n.localize(label) : t }; - return obj; - }, {}); + /** @inheritdoc */ + static async createDialog(data = {}, createOptions = {}, options = {}) { + const { folders, types, template, context = {}, ...dialogOptions } = options; - // Render the document creation form - const html = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/sidebar/documentCreate.hbs', - { - folders, - name: data.name || game.i18n.format('DOCUMENT.New', { type: label }), - folder: data.folder, - hasFolders: folders.length >= 1, - type: data.type || CONFIG[documentName]?.defaultType || typeObjects.armor, - types: { - Items: [typeObjects.armor, typeObjects.weapon, typeObjects.consumable, typeObjects.miscellaneous], - Character: [ - typeObjects.class, - typeObjects.subclass, - typeObjects.ancestry, - typeObjects.community, - typeObjects.feature, - typeObjects.domainCard - ] - }, - hasTypes: types.length > 1 + if (types?.length === 0) { + throw new Error('The array of sub-types to restrict to must not be empty.'); + } + + const documentTypes = this.TYPES.filter(type => type !== 'base' && (!types || types.includes(type))).map( + type => { + const labelKey = CONFIG.Item?.typeLabels?.[type]; + const label = labelKey && game.i18n.has(labelKey) ? game.i18n.localize(labelKey) : type; + + const isInventoryItem = CONFIG.Item.dataModels[type]?.metadata?.isInventoryItem; + const group = + isInventoryItem === true + ? 'Inventory Items' + : isInventoryItem === false + ? 'Character Items' + : 'Other'; + + return { value: type, label, group }; } ); - // Render the confirmation dialog window - return Dialog.prompt({ - title: title, - content: html, - label: title, - callback: html => { - const form = html[0].querySelector('form'); - const fd = new FormDataExtended(form); - foundry.utils.mergeObject(data, fd.object, { inplace: true }); - if (!data.folder) delete data.folder; - if (types.length === 1) data.type = types[0]; - if (!data.name?.trim()) data.name = this.defaultName(); - return this.create(data, { parent, pack, renderSheet: true }); - }, - rejectClose: false, - options + if (!documentTypes.length) { + throw new Error('No document types were permitted to be created.'); + } + + const sortedTypes = documentTypes.sort((a, b) => a.label.localeCompare(b.label, game.i18n.lang)); + + return await super.createDialog(data, createOptions, { + folders, + types, + template, + context: { types: sortedTypes, ...context }, + ...dialogOptions }); } async selectActionDialog() { const content = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/views/actionSelect.hbs', - { actions: this.system.actions } - ), + 'systems/daggerheart/templates/views/actionSelect.hbs', + { actions: this.system.actions } + ), title = 'Select Action', type = 'div', data = {}; @@ -139,8 +127,8 @@ export default class DhpItem extends Item { this.type === 'ancestry' ? game.i18n.localize('DAGGERHEART.Chat.FoundationCard.AncestryTitle') : this.type === 'community' - ? game.i18n.localize('DAGGERHEART.Chat.FoundationCard.CommunityTitle') - : game.i18n.localize('DAGGERHEART.Chat.FoundationCard.SubclassFeatureTitle'), + ? game.i18n.localize('DAGGERHEART.Chat.FoundationCard.CommunityTitle') + : game.i18n.localize('DAGGERHEART.Chat.FoundationCard.SubclassFeatureTitle'), origin: origin, img: this.img, name: this.name, diff --git a/templates/sidebar/documentCreate.hbs b/templates/sidebar/documentCreate.hbs deleted file mode 100644 index ac5559cb..00000000 --- a/templates/sidebar/documentCreate.hbs +++ /dev/null @@ -1,45 +0,0 @@ -
-
- -
- -
-
- - {{#if hasTypes}} -
- -
- -
-
- {{/if}} - - {{#if hasFolders}} -
- -
- -
-
- {{/if}} - - {{{content}}} -