From 907bb8be506a14a0e5feca7423886dccb63d38ba Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Sat, 18 Jul 2026 01:06:58 -0400 Subject: [PATCH] Fix taking damage --- module/data/fields/action/damageField.mjs | 16 ++-- module/documents/actor.mjs | 100 +++++++++++----------- 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/module/data/fields/action/damageField.mjs b/module/data/fields/action/damageField.mjs index 4edc2533..9f382b59 100644 --- a/module/data/fields/action/damageField.mjs +++ b/module/data/fields/action/damageField.mjs @@ -80,7 +80,7 @@ export default class DamageField extends fields.SchemaField { const targetDamage = []; const damagePromises = []; - for (let target of targets) { + for (const target of targets) { const actor = foundry.utils.fromUuidSync(target.actorId); if (!actor) continue; if (!config.hasHealing && config.onSave && target.saved?.success === true) { @@ -102,14 +102,12 @@ export default class DamageField extends fields.SchemaField { actor.takeHealing(config.damage.types).then(updates => targetDamage.push({ token, updates })) ); else { - const configDamage = foundry.utils.deepClone(config.damage.types); - const hpDamageMultiplier = config.actionActor?.system.rules?.attack?.damage?.hpDamageMultiplier ?? 1; - const hpDamageTakenMultiplier = actor.system.rules?.attack?.damage?.hpDamageTakenMultiplier; - if (configDamage.hitPoints) { - configDamage.hitPoints = configDamage.hitPoints.toJSON(); - configDamage.hitPoints.total = Math.ceil( - configDamage.hitPoints.total * hpDamageMultiplier * hpDamageTakenMultiplier - ); + const configDamage = config.damage.clone(); + configDamage.main &&= configDamage.main.toJSON(); + if (configDamage.main) { + const multiplier = config.actionActor?.system.rules?.attack?.damage?.hpDamageMultiplier ?? 1; + const takenMultiplier = actor.system.rules?.attack?.damage?.hpDamageTakenMultiplier; + configDamage.main.total = Math.ceil(configDamage.main.total * multiplier * takenMultiplier); } damagePromises.push( diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index d7733dd5..5048abef 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -656,62 +656,66 @@ export default class DhpActor extends Actor { return; } - const updates = []; - - Object.entries(damages).forEach(([key, damage]) => { - if (key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) - damage.total = this.calculateDamage(damage.total, damage.damageTypes); - const update = updates.find(u => u.key === key); - if (update) { - update.value += damage.total; - update.damageTypes.add(...new Set(damage.damageTypes)); - } else updates.push({ value: damage.total, key, damageTypes: new Set(damage.damageTypes) }); - }); + if (damages.main) { + damages.main.total = this.calculateDamage(damages.main.total, damages.main.damageTypes); + } if (Hooks.call(`${CONFIG.DH.id}.postCalculateDamage`, this, damages) === false) return null; - if (!updates.length) return; + // Convert deducted resources and damage to a record of updates, merging damage to hp with hp marked + const updates = []; + for (const [key, damage] of Object.entries(damages.resources)) { + updates.push({ key, value: damage.total }); + } + if (damages.main) { + const existing = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id); + const value = this.convertDamageToThreshold(damages.main.total) + (existing?.value ?? 0); + const damageTypes = new Set(damages.main.options.damageTypes); + if (existing) { + existing.value = value; + existing.damageTypes = damageTypes; + } else { + updates.push({ value, damageTypes, key: CONFIG.DH.GENERAL.healingTypes.hitPoints.id }); + } + } + if (!updates.some(u => u.value !== 0)) return; // early return if nothing to do const hpDamage = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id); - if (hpDamage?.value) { - hpDamage.value = this.convertDamageToThreshold(hpDamage.value); - if (this.type === 'character' && !isDirect && this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes)) { - const armorSlotResult = await this.owner.query( - 'armorSlot', - { - actorId: this.uuid, - damage: hpDamage.value, - type: [...hpDamage.damageTypes] - }, - { - timeout: 30000 - } - ); - if (armorSlotResult) { - const { modifiedDamage, armorChanges, stressSpent } = armorSlotResult; - updates.find(u => u.key === 'hitPoints').value = modifiedDamage; - for (const armorChange of armorChanges) { - updates.push({ value: armorChange.amount, key: 'armor', uuid: armorChange.uuid }); - } - if (stressSpent) { - const stressUpdate = updates.find(u => u.key === 'stress'); - if (stressUpdate) stressUpdate.value += stressSpent; - else updates.push({ value: stressSpent, key: 'stress' }); - } + if (hpDamage && this.type === 'character' && !isDirect && this.#canReduceDamage(hpDamage.total, hpDamage.damageTypes)) { + const armorSlotResult = await this.owner.query( + 'armorSlot', + { + actorId: this.uuid, + damage: hpDamage.value, + type: [...hpDamage.damageTypes] + }, + { + timeout: 30000 + } + ); + if (armorSlotResult) { + const { modifiedDamage, armorChanges, stressSpent } = armorSlotResult; + hpDamage.value = modifiedDamage; + for (const armorChange of armorChanges) { + updates.push({ value: armorChange.amount, key: 'armor', uuid: armorChange.uuid }); + } + if (stressSpent) { + const stressUpdate = updates.find(u => u.key === 'stress'); + if (stressUpdate) stressUpdate.value += stressSpent; + else updates.push({ value: stressSpent, key: 'stress' }); } } - if (this.type === 'adversary') { - const reducedSeverity = hpDamage.damageTypes.reduce((value, curr) => { - return Math.max(this.system.rules.damageReduction.reduceSeverity[curr], value); - }, 0); - hpDamage.value = Math.max(hpDamage.value - reducedSeverity, 0); + } else if (hpDamage && this.type === 'adversary') { + const reducedSeverity = hpDamage.damageTypes.reduce((value, curr) => { + return Math.max(this.system.rules.damageReduction.reduceSeverity[curr], value); + }, 0); + hpDamage.value = Math.max(hpDamage.value - reducedSeverity, 0); - if ( - hpDamage.value && - this.system.rules.damageReduction.thresholdImmunities[getDamageKey(hpDamage.value)] - ) { - hpDamage.value -= 1; - } + if ( + hpDamage.value && + this.system.rules.damageReduction.thresholdImmunities[getDamageKey(hpDamage.value)] + ) { + hpDamage.value -= 1; } }