From 99aca056c85f7c5c581762fa14d24ce614c1a392 Mon Sep 17 00:00:00 2001 From: psitacus Date: Wed, 9 Jul 2025 01:14:54 -0600 Subject: [PATCH] its a desert --- module/applications/sheets/items/armor.mjs | 40 ++--------- module/applications/sheets/items/weapon.mjs | 42 ++--------- module/helpers/attachmentHelper.mjs | 78 +++++++++++++++++++++ 3 files changed, 90 insertions(+), 70 deletions(-) diff --git a/module/applications/sheets/items/armor.mjs b/module/applications/sheets/items/armor.mjs index 55902b5f..f583d55e 100644 --- a/module/applications/sheets/items/armor.mjs +++ b/module/applications/sheets/items/armor.mjs @@ -1,5 +1,5 @@ import DHBaseItemSheet from '../api/base-item.mjs'; -import { copyAttachmentEffectsToActor, removeAttachmentFromItem } from '../../../helpers/attachmentHelper.mjs'; +import { copyAttachmentEffectsToActor, removeAttachmentFromItem, prepareAttachmentContext, addAttachmentToItem } from '../../../helpers/attachmentHelper.mjs'; export default class ArmorSheet extends DHBaseItemSheet { /**@inheritdoc */ @@ -57,17 +57,7 @@ export default class ArmorSheet extends DHBaseItemSheet { context.features = this.document.system.features.map(x => x.value); break; case 'attachments': - const attachedUUIDs = this.document.system.attached; - context.attachedItems = await Promise.all( - attachedUUIDs.map(async uuid => { - const item = await fromUuid(uuid); - return { - uuid: uuid, - name: item?.name || 'Unknown Item', - img: item?.img || 'icons/svg/item-bag.svg' - }; - }) - ); + context.attachedItems = await prepareAttachmentContext(this.document); break; } @@ -98,29 +88,11 @@ export default class ArmorSheet extends DHBaseItemSheet { const item = await Item.implementation.fromDropData(data); if (!item) return; - const currentAttached = this.document.system.attached; - const newUUID = item.uuid; - - if (currentAttached.includes(newUUID)) { - ui.notifications.warn(`${item.name} is already attached to this armor.`); - return; - } - - const updatedAttached = [...currentAttached, newUUID]; - - await this.document.update({ - 'system.attached': updatedAttached + await addAttachmentToItem({ + parentItem: this.document, + droppedItem: item, + parentType: 'armor' }); - - const actor = this.document.parent; - if (actor && item.effects.size > 0 && this.document.system.equipped) { - await copyAttachmentEffectsToActor({ - parentItem: this.document, - attachedItem: item, - attachedUuid: newUUID, - parentType: 'armor' - }); - } } /** diff --git a/module/applications/sheets/items/weapon.mjs b/module/applications/sheets/items/weapon.mjs index a07fad88..a376de9d 100644 --- a/module/applications/sheets/items/weapon.mjs +++ b/module/applications/sheets/items/weapon.mjs @@ -1,5 +1,5 @@ import DHBaseItemSheet from '../api/base-item.mjs'; -import { copyAttachmentEffectsToActor, removeAttachmentFromItem } from '../../../helpers/attachmentHelper.mjs'; +import { copyAttachmentEffectsToActor, removeAttachmentFromItem, prepareAttachmentContext, addAttachmentToItem } from '../../../helpers/attachmentHelper.mjs'; export default class WeaponSheet extends DHBaseItemSheet { /**@inheritdoc */ @@ -57,17 +57,7 @@ export default class WeaponSheet extends DHBaseItemSheet { context.systemFields.attack.fields = this.document.system.attack.schema.fields; break; case 'attachments': - const attachedUUIDs = this.document.system.attached; - context.attachedItems = await Promise.all( - attachedUUIDs.map(async uuid => { - const item = await fromUuid(uuid); - return { - uuid: uuid, - name: item?.name || 'Unknown Item', - img: item?.img || 'icons/svg/item-bag.svg' - }; - }) - ); + context.attachedItems = await prepareAttachmentContext(this.document); break; } return context; @@ -97,31 +87,11 @@ export default class WeaponSheet extends DHBaseItemSheet { const item = await Item.implementation.fromDropData(data); if (!item) return; - const currentAttached = this.document.system.attached; - const newUUID = item.uuid; - - if (currentAttached.includes(newUUID)) { - ui.notifications.warn(`${item.name} is already attached to this weapon.`); - return; - } - - const updatedAttached = [...currentAttached, newUUID]; - - await this.document.update({ - 'system.attached': updatedAttached + await addAttachmentToItem({ + parentItem: this.document, + droppedItem: item, + parentType: 'weapon' }); - - // Copy ALL effects from attached item to actor (only if weapon is equipped) - // Both attachment-only and regular effects should be copied when attached - const actor = this.document.parent; - if (actor && item.effects.size > 0 && this.document.system.equipped) { - await copyAttachmentEffectsToActor({ - parentItem: this.document, - attachedItem: item, - attachedUuid: newUUID, - parentType: 'weapon' - }); - } } /** diff --git a/module/helpers/attachmentHelper.mjs b/module/helpers/attachmentHelper.mjs index b378a815..132423b0 100644 --- a/module/helpers/attachmentHelper.mjs +++ b/module/helpers/attachmentHelper.mjs @@ -136,3 +136,81 @@ export async function handleAttachmentEffectsOnEquipChange({ parentItem, newEqui } } } + +/** + * Prepare attachment context data for rendering + * @param {Item} parentItem - The item (armor/weapon) that has attachments + * @returns {Promise} Array of attachment data objects + */ +export async function prepareAttachmentContext(parentItem) { + const attachedUUIDs = parentItem.system.attached; + return await Promise.all( + attachedUUIDs.map(async uuid => { + const item = await fromUuid(uuid); + return { + uuid: uuid, + name: item?.name || 'Unknown Item', + img: item?.img || 'icons/svg/item-bag.svg' + }; + }) + ); +} + +/** + * Add an attachment to an item via drag and drop + * @param {Object} options - Configuration options + * @param {Item} options.parentItem - The item (armor/weapon) that the item is being attached to + * @param {Item} options.droppedItem - The item being attached + * @param {string} options.parentType - Type of parent item ("armor" or "weapon") + * @returns {Promise} + */ +export async function addAttachmentToItem({ parentItem, droppedItem, parentType }) { + const currentAttached = parentItem.system.attached; + const newUUID = droppedItem.uuid; + + if (currentAttached.includes(newUUID)) { + ui.notifications.warn(`${droppedItem.name} is already attached to this ${parentType}.`); + return; + } + + const updatedAttached = [...currentAttached, newUUID]; + + await parentItem.update({ + 'system.attached': updatedAttached + }); + + // Copy effects from attached item to actor (only if parent item is equipped) + const actor = parentItem.parent; + if (actor && droppedItem.effects.size > 0 && parentItem.system.equipped) { + await copyAttachmentEffectsToActor({ + parentItem, + attachedItem: droppedItem, + attachedUuid: newUUID, + parentType + }); + } +} + +/** + * Remove an attachment from an item and clean up its effects + * @param {Object} options - Configuration options + * @param {Item} options.parentItem - The item (armor/weapon) that the item is attached to + * @param {string} options.attachedUuid - UUID of the attached item being removed + * @param {string} options.parentType - Type of parent item ("armor" or "weapon") + * @returns {Promise} + */ +export async function removeAttachmentFromItem({ parentItem, attachedUuid, parentType }) { + const currentAttached = parentItem.system.attached; + + // Remove the attachment from the parent item's attached array + await parentItem.update({ + 'system.attached': currentAttached.filter(uuid => uuid !== attachedUuid) + }); + + // Remove any effects that came from this attachment + await removeAttachmentEffectsFromActor({ + parentItem, + attachedUuid, + parentType + }); +}