feat: add applyDamage to Damage

This commit is contained in:
dualfroz committed 2026-09-06 23:41:48 +02:00
1 parent 468a60e9d2
commit e8c4fc27f4
1 file changed
+73
+73
View File
@@ -334,3 +334,76 @@ int wearArmor(ArmorSet& armor, float incomingDamage, uint32_t& rng) {
return spent;
}
CombatResult applyDamage(CombatStats& target, const EffectSet& targetEffects,
const DamageEvent& event, uint32_t& rng) {
CombatResult result;
result.incoming = event.amount;
if (!target.alive || event.amount <= 0.0f) return result;
DamageType type = event.source.type;
EffectModifier modifier = effectModifiers(targetEffects);
if (modifier.fireImmune && isFireDamage(type)) return result;
float raw = event.amount;
if (!bypassesInvulnerability(type)) {
if (target.invulnerableTicks > 0) {
if (raw <= target.lastDamageTaken) {
result.blockedByInvulnerability = true;
result.applied = false;
return result;
}
raw -= target.lastDamageTaken;
target.lastDamageTaken = event.amount;
} else {
target.lastDamageTaken = event.amount;
target.invulnerableTicks = invulnerabilityTicks;
}
}
float afterArmor = raw;
if (!bypassesArmor(type)) {
afterArmor = armorReduction(target.armor.totalPoints(), target.armor.totalToughness(), raw);
}
result.afterArmor = afterArmor;
float afterResistance = afterArmor;
float afterProtection = afterArmor;
if (!bypassesMitigation(type)) {
afterResistance = afterArmor * modifier.incomingDamageMultiplier;
afterProtection = afterResistance * protectionFactor(target.armor.protectionPoints(type));
}
result.afterResistance = afterResistance;
result.afterProtection = afterProtection;
float remaining = afterProtection;
if (target.absorption > 0.0f) {
float absorbed = std::min(target.absorption, remaining);
target.absorption -= absorbed;
remaining -= absorbed;
result.absorbedByAbsorption = absorbed;
}
float before = target.health;
target.health = std::max(0.0f, target.health - remaining);
result.healthLost = before - target.health;
result.applied = true;
result.fatal = target.health <= 0.0f;
if (result.fatal) target.alive = false;
if (!bypassesArmor(type) && afterProtection > 0.0f) {
result.armorDurabilityLost = wearArmor(target.armor, raw, rng);
}
if (type == DamageType::Melee || type == DamageType::Projectile) {
result.knockback = knockbackAlong(event.direction, event.knockbackStrength);
int thorns = target.armor.levelOf(EnchantKind::Thorns);
if (thorns > 0 && event.source.attackerId >= 0) {
if (rollBelow(rng, 100) < thorns * 15) {
result.thornsDamage = static_cast<float>(1 + rollBelow(rng, 4));
}
}
}
return result;
}
} // namespace vf