diff --git a/lang/en.json b/lang/en.json index 797781d8..91d0fa52 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1070,7 +1070,8 @@ "mastery": "Mastery", "optional": "Optional", "setup": "Setup", - "equipment": "Equipment" + "equipment": "Equipment", + "attachments": "Attachments" }, "Tiers": { "singular": "Tier", diff --git a/module/applications/sheets/items/armor.mjs b/module/applications/sheets/items/armor.mjs index bb98c8c3..d0422c6f 100644 --- a/module/applications/sheets/items/armor.mjs +++ b/module/applications/sheets/items/armor.mjs @@ -4,7 +4,13 @@ export default class ArmorSheet extends DHBaseItemSheet { /**@inheritdoc */ static DEFAULT_OPTIONS = { classes: ['armor'], - dragDrop: [{ dragSelector: null, dropSelector: null }], + dragDrop: [ + { dragSelector: null, dropSelector: null }, + { dragSelector: null, dropSelector: '.attachments-section' } + ], + actions: { + removeAttachment: ArmorSheet.#removeAttachment + }, tagifyConfigs: [ { selector: '.features-input', @@ -26,6 +32,19 @@ export default class ArmorSheet extends DHBaseItemSheet { settings: { template: 'systems/daggerheart/templates/sheets/items/armor/settings.hbs', scrollable: ['.settings'] + }, + attachments: { + template: 'systems/daggerheart/templates/sheets/items/armor/attachments.hbs', + scrollable: ['.attachments'] + } + }; + + /** @override */ + static TABS = { + primary: { + tabs: [{ id: 'description' }, { id: 'actions' }, { id: 'settings' }, { id: 'attachments' }], + initial: 'description', + labelPrefix: 'DAGGERHEART.GENERAL.Tabs' } }; @@ -37,6 +56,28 @@ export default class ArmorSheet extends DHBaseItemSheet { case 'settings': context.features = this.document.system.features.map(x => x.value); break; + case 'attachments': + // Prepare attached items for display + const attachedUUIDs = this.document.system.attached || []; + context.attachedItems = await Promise.all( + attachedUUIDs.map(async uuid => { + try { + const item = await fromUuid(uuid); + return { + uuid: uuid, + name: item?.name || 'Unknown Item', + img: item?.img || 'icons/svg/item-bag.svg' + }; + } catch (error) { + return { + uuid: uuid, + name: 'Unknown Item', + img: 'icons/svg/item-bag.svg' + }; + } + }) + ); + break; } return context; @@ -49,4 +90,48 @@ export default class ArmorSheet extends DHBaseItemSheet { static async #onFeatureSelect(selectedOptions) { await this.document.update({ 'system.features': selectedOptions.map(x => ({ value: x.value })) }); } + + /** + * Handle dropping items onto the attachments section + * @param {DragEvent} event - The drop event + */ + async _onDrop(event) { + const data = TextEditor.getDragEventData(event); + + // Only handle Item drops + if (data.type !== 'Item') return; + + // Check if dropped on attachments section + const attachmentsSection = event.target.closest('.attachments-section'); + if (!attachmentsSection) return super._onDrop(event); + + // Get the item being dropped + const item = await Item.implementation.fromDropData(data); + if (!item) return; + + // Get current attached UUIDs + const currentAttached = this.document.system.attached || []; + const newUUID = item.uuid; + + // Prevent duplicates + if (currentAttached.includes(newUUID)) return; + + await this.document.update({ + 'system.attached': [...currentAttached, newUUID] + }); + } + + /** + * Remove an attached item + * @param {Event} event - The click event + * @param {HTMLElement} target - The clicked element + */ + static async #removeAttachment(event, target) { + const uuid = target.dataset.uuid; + const currentAttached = this.document.system.attached || []; + + await this.document.update({ + 'system.attached': currentAttached.filter(attachedUuid => attachedUuid !== uuid) + }); + } } diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index 4e5a26e6..08f2c68d 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -40,6 +40,7 @@ export default class DHArmor extends BaseDataItem { major: new fields.NumberField({ integer: true, initial: 0 }), severe: new fields.NumberField({ integer: true, initial: 0 }) }), + attached: new fields.ArrayField(new fields.StringField()), actions: new fields.ArrayField(new ActionField()) }; } diff --git a/templates/sheets/items/armor/attachments.hbs b/templates/sheets/items/armor/attachments.hbs new file mode 100644 index 00000000..5b632d8b --- /dev/null +++ b/templates/sheets/items/armor/attachments.hbs @@ -0,0 +1,30 @@ +
+
+ {{localize tabs.attachments.label}} + + {{#if attachedItems}} +
+ {{#each attachedItems as |item|}} +
+ {{item.name}} +
+
{{item.name}}
+
+
+ +
+
+ {{/each}} +
+ {{/if}} + +
+ + Drop items here to attach them +
+
+