feat: add applyDamage to Damage
This commit is contained in:
1 parent
468a60e9d2
commit
e8c4fc27f4
1 file changed
+73
@@ -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
|
||||
Reference in new issue
Block a user