From 9dc5830e18c7350a11b17c9d5f4bddc44998cf8d Mon Sep 17 00:00:00 2001 From: WBHarry Date: Mon, 9 Feb 2026 21:51:58 +0100 Subject: [PATCH] Added a updateArmorValue function that updates armoreffects according to an auto order --- module/data/activeEffect/armorEffect.mjs | 28 +++++++++++++ module/data/actor/character.mjs | 52 +++++++++++++++++++++--- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/module/data/activeEffect/armorEffect.mjs b/module/data/activeEffect/armorEffect.mjs index bd397abe..f52f5efc 100644 --- a/module/data/activeEffect/armorEffect.mjs +++ b/module/data/activeEffect/armorEffect.mjs @@ -115,6 +115,34 @@ export default class ArmorEffect extends foundry.data.ActiveEffectTypeDataModel await this.parent.update({ 'system.changes': newChanges }); } + static orderEffectsForAutoChange(armorEffects, increasing) { + const getEffectWeight = effect => { + switch (effect.parent.type) { + case 'loot': + case 'consumable': + return 2; + case 'class': + case 'subclass': + case 'ancestry': + case 'community': + case 'feature': + case 'domainCard': + return 3; + case 'weapon': + case 'armor': + return 4; + case 'character': + return 5; + default: + return 1; + } + }; + + return armorEffects.sort((a, b) => + increasing ? getEffectWeight(b) - getEffectWeight(a) : getEffectWeight(a) - getEffectWeight(b) + ); + } + /* Overrides */ prepareBaseData() { diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 128fef78..294fa77e 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -458,11 +458,6 @@ export default class DhCharacter extends BaseDataActor { return this.parent.items.find(x => x.type === 'armor' && x.system.equipped); } - /* TODO: Prep datastructure to be useful when applying automatic armor damage order */ - get armorEffects() { - return Array.from(this.parent.allApplicableEffects()); - } - get activeBeastform() { return this.parent.effects.find(x => x.type === 'beastform'); } @@ -512,6 +507,53 @@ export default class DhCharacter extends BaseDataActor { } } + async updateArmorValue(armorChange) { + if (armorChange === 0) return; + + const increasing = armorChange >= 0; + let remainingChange = Math.abs(armorChange); + const armorEffects = Array.from(this.parent.allApplicableEffects()).filter(x => x.type === 'armor'); + const orderedEffects = game.system.api.data.activeEffects.ArmorEffect.orderEffectsForAutoChange( + armorEffects, + increasing + ); + + const embeddedUpdates = []; + for (const armorEffect of orderedEffects) { + let usedArmorChange = 0; + if (increasing) { + const remainingArmor = armorEffect.system.armorChange.max - armorEffect.system.armorChange.value; + usedArmorChange = Math.min(remainingChange, remainingArmor); + remainingChange -= usedArmorChange; + } else { + const changeChange = Math.min(armorEffect.system.armorChange.value, remainingChange); + usedArmorChange -= changeChange; + remainingChange -= changeChange; + } + + if (!usedArmorChange) continue; + else { + if (!embeddedUpdates[armorEffect.parent.id]) + embeddedUpdates[armorEffect.parent.id] = { doc: armorEffect.parent, updates: [] }; + + embeddedUpdates[armorEffect.parent.id].updates.push({ + '_id': armorEffect.id, + 'system.changes': [ + { + ...armorEffect.system.armorChange, + value: armorEffect.system.armorChange.value + usedArmorChange + } + ] + }); + } + + if (remainingChange === 0) break; + } + + for (const { doc, updates } of Object.values(embeddedUpdates)) + doc.updateEmbeddedDocuments('ActiveEffect', updates); + } + get sheetLists() { const ancestryFeatures = [], communityFeatures = [],