From a78e1533d795e8e2c081673bbd6b4b49f73fceb8 Mon Sep 17 00:00:00 2001 From: psitacus Date: Fri, 11 Jul 2025 19:11:04 -0600 Subject: [PATCH] change armor and weapon to be attachableItem --- .../sheets/api/item-attachment-sheet.mjs | 66 +++++++++++++++++++ module/data/item/armor.mjs | 9 --- module/data/item/attachableItem.mjs | 15 +++++ module/data/item/weapon.mjs | 9 --- module/helpers/attachmentHelper.mjs | 2 +- 5 files changed, 82 insertions(+), 19 deletions(-) diff --git a/module/applications/sheets/api/item-attachment-sheet.mjs b/module/applications/sheets/api/item-attachment-sheet.mjs index e69de29b..9cfc22d8 100644 --- a/module/applications/sheets/api/item-attachment-sheet.mjs +++ b/module/applications/sheets/api/item-attachment-sheet.mjs @@ -0,0 +1,66 @@ +import { + removeAttachmentFromItem, + prepareAttachmentContext, + addAttachmentToItem +} from '../../../helpers/attachmentHelper.mjs'; + +export default function ItemAttachmentSheet(Base) { + return class extends Base { + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + dragDrop: [ + ...(super.DEFAULT_OPTIONS.dragDrop || []), + { dragSelector: null, dropSelector: '.attachments-section' } + ], + actions: { + ...super.DEFAULT_OPTIONS.actions, + removeAttachment: this.#removeAttachment + } + }; + + static PARTS = { + ...super.PARTS, + attachments: { + template: 'systems/daggerheart/templates/sheets/global/tabs/tab-attachments.hbs', + scrollable: ['.attachments'] + } + }; + + async _preparePartContext(partId, context) { + await super._preparePartContext(partId, context); + + if (partId === 'attachments') { + context.attachedItems = await prepareAttachmentContext(this.document); + } + + return context; + } + + async _onDrop(event) { + const data = TextEditor.getDragEventData(event); + + const attachmentsSection = event.target.closest('.attachments-section'); + if (!attachmentsSection) return super._onDrop(event); + + event.preventDefault(); + event.stopPropagation(); + + const item = await Item.implementation.fromDropData(data); + if (!item) return; + + await addAttachmentToItem({ + parentItem: this.document, + droppedItem: item, + parentType: this.document.type + }); + } + + static async #removeAttachment(event, target) { + await removeAttachmentFromItem({ + parentItem: this.document, + attachedUuid: target.dataset.uuid, + parentType: this.document.type + }); + } + }; +} \ No newline at end of file diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index a024138a..413b63ab 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -54,15 +54,6 @@ export default class DHArmor extends AttachableItem { const allowed = await super._preUpdate(changes, options, user); if (allowed === false) return false; - // Handle equipped status changes for attachment effects - if (changes.system?.equipped !== undefined && changes.system.equipped !== this.equipped) { - await handleAttachmentEffectsOnEquipChange({ - parentItem: this.parent, - newEquippedStatus: changes.system.equipped, - parentType: 'armor' - }); - } - if (changes.system.features) { const removed = this.features.filter(x => !changes.system.features.includes(x)); const added = changes.system.features.filter(x => !this.features.includes(x)); diff --git a/module/data/item/attachableItem.mjs b/module/data/item/attachableItem.mjs index 11fa222b..945e750a 100644 --- a/module/data/item/attachableItem.mjs +++ b/module/data/item/attachableItem.mjs @@ -1,4 +1,5 @@ import BaseDataItem from './base.mjs'; +import { handleAttachmentEffectsOnEquipChange } from '../../helpers/attachmentHelper.mjs'; export default class AttachableItem extends BaseDataItem { static defineSchema() { @@ -8,4 +9,18 @@ export default class AttachableItem extends BaseDataItem { attached: new fields.ArrayField(new fields.DocumentUUIDField({ type: "Item", nullable: true })) }; } + + async _preUpdate(changes, options, user) { + const allowed = await super._preUpdate(changes, options, user); + if (allowed === false) return false; + + // Handle equipped status changes for attachment effects + if (changes.system?.equipped !== undefined && changes.system.equipped !== this.equipped) { + await handleAttachmentEffectsOnEquipChange({ + parentItem: this.parent, + newEquippedStatus: changes.system.equipped, + parentType: this.parent.type + }); + } + } } \ No newline at end of file diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index a5b440f8..cd8de09b 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -79,15 +79,6 @@ export default class DHWeapon extends AttachableItem { const allowed = await super._preUpdate(changes, options, user); if (allowed === false) return false; - // Handle equipped status changes for attachment effects - if (changes.system?.equipped !== undefined && changes.system.equipped !== this.equipped) { - await handleAttachmentEffectsOnEquipChange({ - parentItem: this.parent, - newEquippedStatus: changes.system.equipped, - parentType: 'weapon' - }); - } - if (changes.system?.features) { const removed = this.features.filter(x => !changes.system.features.includes(x)); const added = changes.system.features.filter(x => !this.features.includes(x)); diff --git a/module/helpers/attachmentHelper.mjs b/module/helpers/attachmentHelper.mjs index 8f15c18b..1b9b1f71 100644 --- a/module/helpers/attachmentHelper.mjs +++ b/module/helpers/attachmentHelper.mjs @@ -129,7 +129,7 @@ export async function handleAttachmentEffectsOnEquipChange({ parentItem, newEqui // Item is being unequipped - remove attachment effects const parentUuidProperty = `${parentType}Uuid`; const effectsToRemove = actor.effects.filter(effect => { - const attachmentSource = effect.flags?.daggerheart?.attachmentSource; + const attachmentSource = effect.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.itemAttachmentSource); return attachmentSource && attachmentSource[parentUuidProperty] === parentItem.uuid; });