add attachment only flag and logic

This commit is contained in:
psitacus 2025-07-08 22:35:57 -06:00
parent bee41cc546
commit 4e304adde7
5 changed files with 72 additions and 18 deletions

View file

@ -132,14 +132,15 @@ export default class ArmorSheet extends DHBaseItemSheet {
'system.attached': updatedAttached
});
// Copy effects from attached item to actor (only if armor is equipped)
// Copy ALL effects from attached item to actor (only if armor 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) {
console.log(`Copying ${item.effects.size} effects from attached item ${item.name} to actor ${actor.name} (armor is equipped)`);
console.log(`Checking ${item.effects.size} effects from attached item ${item.name}`);
const effectsToCreate = [];
for (const effect of item.effects) {
// Create a copy of the effect with metadata to track its source
// Copy ALL effects when item is attached - attachment-only flag only matters for non-attached items
const effectData = effect.toObject();
effectData.origin = `${this.document.uuid}:${newUUID}`; // Track which armor and which item this came from
effectData.flags = {
@ -154,10 +155,17 @@ export default class ArmorSheet extends DHBaseItemSheet {
}
};
effectsToCreate.push(effectData);
const isAttachmentOnly = effect.flags?.daggerheart?.attachmentOnly === true;
console.log(`Effect ${effect.name} (attachment-only: ${isAttachmentOnly}) will be copied to actor`);
}
const createdEffects = await actor.createEmbeddedDocuments('ActiveEffect', effectsToCreate);
console.log(`Created ${createdEffects.length} effects on actor from attached item`);
if (effectsToCreate.length > 0) {
const createdEffects = await actor.createEmbeddedDocuments('ActiveEffect', effectsToCreate);
console.log(`Created ${createdEffects.length} effects on actor from attached item`);
} else {
console.log(`No effects found on ${item.name}, no effects copied to actor`);
}
} else if (item.effects.size > 0 && !this.document.system.equipped) {
console.log(`Armor ${this.document.name} is not equipped, attachment effects will be applied when equipped`);
}

View file

@ -115,6 +115,7 @@ export default class DHArmor extends BaseDataItem {
const attachedItem = await fromUuid(attachedUuid);
if (attachedItem && attachedItem.effects.size > 0) {
for (const effect of attachedItem.effects) {
// Copy ALL effects when item is attached - attachment-only flag only matters for non-attached items
const effectData = effect.toObject();
effectData.origin = `${this.parent.uuid}:${attachedUuid}`;
effectData.flags = {

View file

@ -1,16 +1,60 @@
export default class DhActiveEffect extends ActiveEffect {
get isSuppressed() {
if (['weapon', 'armor'].includes(this.parent.type)) {
// If this is a copied effect from an attachment, never suppress it
// (These effects have attachmentSource metadata)
if (this.flags?.daggerheart?.attachmentSource) {
return false;
}
// First check for attachment-only effects - these should be suppressed unless attached
if (this.isAttachmentOnly && !this.isAttached) {
return true;
}
// Then apply the standard suppression rules
if (['weapon', 'armor'].includes(this.parent?.type)) {
return !this.parent.system.equipped;
}
if (this.parent.type === 'domainCard') {
if (this.parent?.type === 'domainCard') {
return this.parent.system.inVault;
}
return super.isSuppressed;
}
/**
* Check if this effect is marked as attachment-only
* @returns {boolean}
*/
get isAttachmentOnly() {
return this.flags?.daggerheart?.attachmentOnly === true;
}
/**
* Check if the parent item is currently attached to another item
* @returns {boolean}
*/
get isAttached() {
if (!this.parent || !this.parent.parent) return false;
// Check if this item's UUID is in any actor's armor attachment lists
const actor = this.parent.parent;
if (!actor || !actor.items) return false;
try {
return actor.items.some(item => {
return item.type === 'armor' &&
item.system?.attached &&
Array.isArray(item.system.attached) &&
item.system.attached.includes(this.parent.uuid);
});
} catch (error) {
console.warn('Error checking if item is attached:', error);
return false;
}
}
async _preCreate(data, options, user) {
const update = {};
if (!data.img) {
@ -51,14 +95,4 @@ export default class DhActiveEffect extends ActiveEffect {
cls.create(msg.toObject());
}
/**
* Retrieve the Document that this ActiveEffect targets for modification.
* @type {Document|null}
*/
get target() {
if (this.parent instanceof Actor) return this.parent;
if (CONFIG.ActiveEffect.legacyTransferral) return this.transfer ? null : this.parent;
return this.transfer ? (this.parent.parent ?? null) : this.parent;
}
}