diff --git a/OpenRA.Game/GameRules/DamageWarhead.cs b/OpenRA.Game/GameRules/DamageWarhead.cs index 104c0ce0e0..7ec8a1ddd7 100644 --- a/OpenRA.Game/GameRules/DamageWarhead.cs +++ b/OpenRA.Game/GameRules/DamageWarhead.cs @@ -42,19 +42,27 @@ namespace OpenRA.GameRules : new Dictionary(); } + public int DamageVersus(ActorInfo victim) + { + var armor = victim.Traits.GetOrDefault(); + if (armor == null || armor.Type == null) + return 100; + + // TODO: Change versus definitions to integer percentages + float versus; + if (Versus.TryGetValue(armor.Type, out versus)) + return (int)(versus * 100); + + return 100; + } + public override int EffectivenessAgainst(ActorInfo ai) { var health = ai.Traits.GetOrDefault(); if (health == null) return 0; - var armor = ai.Traits.GetOrDefault(); - if (armor == null || armor.Type == null) - return 100; - - // TODO: Change versus definitions to integer percentages - float versus; - return Versus.TryGetValue(armor.Type, out versus) ? (int)(versus * 100) : 100; + return DamageVersus(ai); } public override void DoImpact(Target target, Actor firedBy, IEnumerable damageModifiers) @@ -66,7 +74,12 @@ namespace OpenRA.GameRules DoImpact(target.CenterPosition, firedBy, damageModifiers); } - public abstract void DoImpact(Actor target, Actor firedBy, IEnumerable damageModifiers); public abstract void DoImpact(WPos pos, Actor firedBy, IEnumerable damageModifiers); + + public virtual void DoImpact(Actor victim, Actor firedBy, IEnumerable damageModifiers) + { + var damage = Util.ApplyPercentageModifiers(Damage, damageModifiers.Append(DamageVersus(victim.Info))); + victim.InflictDamage(firedBy, damage, this); + } } } diff --git a/OpenRA.Mods.RA/Warheads/AbsoluteSpreadDamageWarhead.cs b/OpenRA.Mods.RA/Warheads/AbsoluteSpreadDamageWarhead.cs index 7870fbf5bf..012ff5f476 100644 --- a/OpenRA.Mods.RA/Warheads/AbsoluteSpreadDamageWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/AbsoluteSpreadDamageWarhead.cs @@ -43,36 +43,10 @@ namespace OpenRA.Mods.RA if (previousSpread.Range > 0) hitActors.Except(world.FindActorsInCircle(pos, previousSpread)); - foreach (var victim in hitActors) - { - if (IsValidAgainst(victim, firedBy)) - { - // TODO: Keep currentFactor as int from the start - var damage = GetDamageToInflict(victim, firedBy, damageModifiers.Append((int)(currentFactor * 100))); - victim.InflictDamage(firedBy, damage, this); - } - } - } - } - - public override void DoImpact(Actor victim, Actor firedBy, IEnumerable damageModifiers) - { - if (IsValidAgainst(victim, firedBy)) - { // TODO: Keep currentFactor as int from the start - var currentFactor = SpreadFactor[0]; - var damage = GetDamageToInflict(victim, firedBy, damageModifiers.Append((int)(currentFactor * 100))); - victim.InflictDamage(firedBy, damage, this); + foreach (var victim in hitActors) + DoImpact(victim, firedBy, damageModifiers.Append((int)(currentFactor * 100))); } } - - public int GetDamageToInflict(Actor target, Actor firedBy, IEnumerable damageModifiers) - { - var healthInfo = target.Info.Traits.GetOrDefault(); - if (healthInfo == null) - return 0; - - return Util.ApplyPercentageModifiers(Damage, damageModifiers.Append(EffectivenessAgainst(target.Info))); - } } } diff --git a/OpenRA.Mods.RA/Warheads/HealthPercentageDamageWarhead.cs b/OpenRA.Mods.RA/Warheads/HealthPercentageDamageWarhead.cs index 98dc341b23..b3b00e5d3c 100644 --- a/OpenRA.Mods.RA/Warheads/HealthPercentageDamageWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/HealthPercentageDamageWarhead.cs @@ -36,26 +36,13 @@ namespace OpenRA.Mods.RA public override void DoImpact(Actor victim, Actor firedBy, IEnumerable damageModifiers) { - if (IsValidAgainst(victim, firedBy)) - { - var damage = GetDamageToInflict(victim, firedBy, damageModifiers); - if (damage != 0) // will be 0 if the target doesn't have HealthInfo - { - var healthInfo = victim.Info.Traits.Get(); - damage = (float)(damage / 100 * healthInfo.HP); - } - - victim.InflictDamage(firedBy, (int)damage, this); - } - } - - public float GetDamageToInflict(Actor target, Actor firedBy, IEnumerable damageModifiers) - { - var healthInfo = target.Info.Traits.GetOrDefault(); + var healthInfo = victim.Info.Traits.GetOrDefault(); if (healthInfo == null) - return 0; + return; - return Util.ApplyPercentageModifiers(Damage, damageModifiers.Append(EffectivenessAgainst(target.Info))); + // Damage is measured as a percentage of the target health + var damage = Util.ApplyPercentageModifiers(healthInfo.HP, damageModifiers.Append(Damage, DamageVersus(victim.Info))); + victim.InflictDamage(firedBy, damage, this); } } } diff --git a/OpenRA.Mods.RA/Warheads/PerCellDamageWarhead.cs b/OpenRA.Mods.RA/Warheads/PerCellDamageWarhead.cs index f17f2b36aa..745b82fbc9 100644 --- a/OpenRA.Mods.RA/Warheads/PerCellDamageWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/PerCellDamageWarhead.cs @@ -33,23 +33,5 @@ namespace OpenRA.Mods.RA foreach (var victim in world.ActorMap.GetUnitsAt(t)) DoImpact(victim, firedBy, damageModifiers); } - - public override void DoImpact(Actor victim, Actor firedBy, IEnumerable damageModifiers) - { - if (IsValidAgainst(victim, firedBy)) - { - var damage = GetDamageToInflict(victim, firedBy, damageModifiers); - victim.InflictDamage(firedBy, damage, this); - } - } - - public int GetDamageToInflict(Actor target, Actor firedBy, IEnumerable damageModifiers) - { - var healthInfo = target.Info.Traits.GetOrDefault(); - if (healthInfo == null) - return 0; - - return Util.ApplyPercentageModifiers(Damage, damageModifiers.Append(EffectivenessAgainst(target.Info))); - } } } diff --git a/OpenRA.Mods.RA/Warheads/SpreadDamageWarhead.cs b/OpenRA.Mods.RA/Warheads/SpreadDamageWarhead.cs index bca54147c4..2ba9f0fbe6 100644 --- a/OpenRA.Mods.RA/Warheads/SpreadDamageWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/SpreadDamageWarhead.cs @@ -30,35 +30,21 @@ namespace OpenRA.Mods.RA foreach (var victim in hitActors) { - if (IsValidAgainst(victim, firedBy)) + if (!IsValidAgainst(victim, firedBy)) + continue; + + var localModifiers = damageModifiers; + var healthInfo = victim.Info.Traits.GetOrDefault(); + if (healthInfo != null) { - var damage = (int)GetDamageToInflict(pos, victim, firedBy, damageModifiers); - victim.InflictDamage(firedBy, damage, this); + var distance = Math.Max(0, (victim.CenterPosition - pos).Length - healthInfo.Radius.Range); + localModifiers = localModifiers.Append((int)(100 * GetDamageFalloff(distance * 1f / Spread.Range))); } + + DoImpact(victim, firedBy, localModifiers); } } - public override void DoImpact(Actor victim, Actor firedBy, IEnumerable damageModifiers) - { - if (IsValidAgainst(victim, firedBy)) - { - var damage = GetDamageToInflict(victim.CenterPosition, victim, firedBy, damageModifiers); - victim.InflictDamage(firedBy, damage, this); - } - } - - public int GetDamageToInflict(WPos pos, Actor target, Actor firedBy, IEnumerable damageModifiers) - { - var healthInfo = target.Info.Traits.GetOrDefault(); - if (healthInfo == null) - return 0; - - var distance = Math.Max(0, (target.CenterPosition - pos).Length - healthInfo.Radius.Range); - var falloff = (int)(100 * GetDamageFalloff(distance * 1f / Spread.Range)); - - return Util.ApplyPercentageModifiers(Damage, damageModifiers.Append(EffectivenessAgainst(target.Info), falloff)); - } - static readonly float[] falloff = { 1f, 0.3678795f, 0.1353353f, 0.04978707f,