Fix taking damage

This commit is contained in:
Carlos Fernandez 2026-07-18 01:06:58 -04:00
parent 2ef78f2c89
commit 907bb8be50
2 changed files with 59 additions and 57 deletions

View file

@ -80,7 +80,7 @@ export default class DamageField extends fields.SchemaField {
const targetDamage = []; const targetDamage = [];
const damagePromises = []; const damagePromises = [];
for (let target of targets) { for (const target of targets) {
const actor = foundry.utils.fromUuidSync(target.actorId); const actor = foundry.utils.fromUuidSync(target.actorId);
if (!actor) continue; if (!actor) continue;
if (!config.hasHealing && config.onSave && target.saved?.success === true) { 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 })) actor.takeHealing(config.damage.types).then(updates => targetDamage.push({ token, updates }))
); );
else { else {
const configDamage = foundry.utils.deepClone(config.damage.types); const configDamage = config.damage.clone();
const hpDamageMultiplier = config.actionActor?.system.rules?.attack?.damage?.hpDamageMultiplier ?? 1; configDamage.main &&= configDamage.main.toJSON();
const hpDamageTakenMultiplier = actor.system.rules?.attack?.damage?.hpDamageTakenMultiplier; if (configDamage.main) {
if (configDamage.hitPoints) { const multiplier = config.actionActor?.system.rules?.attack?.damage?.hpDamageMultiplier ?? 1;
configDamage.hitPoints = configDamage.hitPoints.toJSON(); const takenMultiplier = actor.system.rules?.attack?.damage?.hpDamageTakenMultiplier;
configDamage.hitPoints.total = Math.ceil( configDamage.main.total = Math.ceil(configDamage.main.total * multiplier * takenMultiplier);
configDamage.hitPoints.total * hpDamageMultiplier * hpDamageTakenMultiplier
);
} }
damagePromises.push( damagePromises.push(

View file

@ -656,62 +656,66 @@ export default class DhpActor extends Actor {
return; return;
} }
const updates = []; if (damages.main) {
damages.main.total = this.calculateDamage(damages.main.total, damages.main.damageTypes);
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 (Hooks.call(`${CONFIG.DH.id}.postCalculateDamage`, this, damages) === false) return null; 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); const hpDamage = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id);
if (hpDamage?.value) { if (hpDamage && this.type === 'character' && !isDirect && this.#canReduceDamage(hpDamage.total, hpDamage.damageTypes)) {
hpDamage.value = this.convertDamageToThreshold(hpDamage.value); const armorSlotResult = await this.owner.query(
if (this.type === 'character' && !isDirect && this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes)) { 'armorSlot',
const armorSlotResult = await this.owner.query( {
'armorSlot', actorId: this.uuid,
{ damage: hpDamage.value,
actorId: this.uuid, type: [...hpDamage.damageTypes]
damage: hpDamage.value, },
type: [...hpDamage.damageTypes] {
}, timeout: 30000
{ }
timeout: 30000 );
} if (armorSlotResult) {
); const { modifiedDamage, armorChanges, stressSpent } = armorSlotResult;
if (armorSlotResult) { hpDamage.value = modifiedDamage;
const { modifiedDamage, armorChanges, stressSpent } = armorSlotResult; for (const armorChange of armorChanges) {
updates.find(u => u.key === 'hitPoints').value = modifiedDamage; updates.push({ value: armorChange.amount, key: 'armor', uuid: armorChange.uuid });
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 (stressSpent) { if (stressUpdate) stressUpdate.value += stressSpent;
const stressUpdate = updates.find(u => u.key === 'stress'); else updates.push({ value: stressSpent, key: 'stress' });
if (stressUpdate) stressUpdate.value += stressSpent;
else updates.push({ value: stressSpent, key: 'stress' });
}
} }
} }
if (this.type === 'adversary') { } else if (hpDamage && this.type === 'adversary') {
const reducedSeverity = hpDamage.damageTypes.reduce((value, curr) => { const reducedSeverity = hpDamage.damageTypes.reduce((value, curr) => {
return Math.max(this.system.rules.damageReduction.reduceSeverity[curr], value); return Math.max(this.system.rules.damageReduction.reduceSeverity[curr], value);
}, 0); }, 0);
hpDamage.value = Math.max(hpDamage.value - reducedSeverity, 0); hpDamage.value = Math.max(hpDamage.value - reducedSeverity, 0);
if ( if (
hpDamage.value && hpDamage.value &&
this.system.rules.damageReduction.thresholdImmunities[getDamageKey(hpDamage.value)] this.system.rules.damageReduction.thresholdImmunities[getDamageKey(hpDamage.value)]
) { ) {
hpDamage.value -= 1; hpDamage.value -= 1;
}
} }
} }