From 57ba1b54b4a50b4976f52734611ed5e88c1ecc9f Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 17 Aug 2014 17:33:50 +1200 Subject: [PATCH] Convert weapon plumbing to use integer damage modifiers. --- OpenRA.Game/GameRules/DamageWarhead.cs | 19 ++++++++++--------- OpenRA.Game/GameRules/Warhead.cs | 8 ++++---- OpenRA.Game/GameRules/WeaponInfo.cs | 6 +++--- OpenRA.Mods.Cnc/Effects/IonCannon.cs | 3 ++- OpenRA.Mods.Cnc/PoisonedByTiberium.cs | 2 +- OpenRA.Mods.D2k/DamagedWithoutFoundation.cs | 2 +- OpenRA.Mods.D2k/ThrowsShrapnel.cs | 6 ++---- OpenRA.Mods.RA/Air/FallsToEarth.cs | 3 ++- OpenRA.Mods.RA/Armament.cs | 6 ++---- OpenRA.Mods.RA/Bridge.cs | 2 +- OpenRA.Mods.RA/Crates/ExplodeCrateAction.cs | 3 ++- OpenRA.Mods.RA/Effects/Bullet.cs | 2 +- OpenRA.Mods.RA/Effects/GravityBomb.cs | 2 +- OpenRA.Mods.RA/Effects/LaserZap.cs | 2 +- OpenRA.Mods.RA/Effects/Missile.cs | 2 +- OpenRA.Mods.RA/Effects/NukeLaunch.cs | 2 +- OpenRA.Mods.RA/Effects/TeslaZap.cs | 2 +- OpenRA.Mods.RA/Explodes.cs | 2 +- OpenRA.Mods.RA/MadTank.cs | 5 +++-- .../Warheads/AbsoluteSpreadDamageWarhead.cs | 18 ++++++++++-------- .../Warheads/CreateEffectWarhead.cs | 2 +- .../Warheads/CreateResourceWarhead.cs | 2 +- .../Warheads/DestroyResourceWarhead.cs | 2 +- .../Warheads/HealthPercentageDamageWarhead.cs | 14 ++++++-------- OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs | 2 +- .../Warheads/PerCellDamageWarhead.cs | 14 ++++++-------- .../Warheads/SpreadDamageWarhead.cs | 17 +++++++++-------- 27 files changed, 75 insertions(+), 75 deletions(-) diff --git a/OpenRA.Game/GameRules/DamageWarhead.cs b/OpenRA.Game/GameRules/DamageWarhead.cs index 6ecaadabc0..104c0ce0e0 100644 --- a/OpenRA.Game/GameRules/DamageWarhead.cs +++ b/OpenRA.Game/GameRules/DamageWarhead.cs @@ -42,30 +42,31 @@ namespace OpenRA.GameRules : new Dictionary(); } - public override float EffectivenessAgainst(ActorInfo ai) + public override int EffectivenessAgainst(ActorInfo ai) { var health = ai.Traits.GetOrDefault(); if (health == null) - return 0f; + return 0; var armor = ai.Traits.GetOrDefault(); if (armor == null || armor.Type == null) - return 1f; + return 100; + // TODO: Change versus definitions to integer percentages float versus; - return Versus.TryGetValue(armor.Type, out versus) ? versus : 1f; + return Versus.TryGetValue(armor.Type, out versus) ? (int)(versus * 100) : 100; } - public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + public override void DoImpact(Target target, Actor firedBy, IEnumerable damageModifiers) { // Used by traits that damage a single actor, rather than a position if (target.Type == TargetType.Actor) - DoImpact(target.Actor, firedBy, firepowerModifier); + DoImpact(target.Actor, firedBy, damageModifiers); else - DoImpact(target.CenterPosition, firedBy, firepowerModifier); + DoImpact(target.CenterPosition, firedBy, damageModifiers); } - public abstract void DoImpact(Actor target, Actor firedBy, float firepowerModifier); - public abstract void DoImpact(WPos pos, Actor firedBy, float firepowerModifier); + public abstract void DoImpact(Actor target, Actor firedBy, IEnumerable damageModifiers); + public abstract void DoImpact(WPos pos, Actor firedBy, IEnumerable damageModifiers); } } diff --git a/OpenRA.Game/GameRules/Warhead.cs b/OpenRA.Game/GameRules/Warhead.cs index 9bdd950ace..0dab3044c1 100644 --- a/OpenRA.Game/GameRules/Warhead.cs +++ b/OpenRA.Game/GameRules/Warhead.cs @@ -27,9 +27,9 @@ namespace OpenRA.GameRules [Desc("Delay in ticks before applying the warhead effect.","0 = instant (old model).")] public readonly int Delay = 0; - public abstract void DoImpact(Target target, Actor firedBy, float firepowerModifier); + public abstract void DoImpact(Target target, Actor firedBy, IEnumerable damageModifiers); - public virtual float EffectivenessAgainst(ActorInfo ai) { return 0f; } + public virtual int EffectivenessAgainst(ActorInfo ai) { return 0; } public bool IsValidAgainst(Target target, World world, Actor firedBy) { @@ -59,7 +59,7 @@ namespace OpenRA.GameRules public bool IsValidAgainst(Actor victim, Actor firedBy) { // If this warhead is ineffective against the target, then it is not a valid target - if (EffectivenessAgainst(victim.Info) <= 0f) + if (EffectivenessAgainst(victim.Info) <= 0) return false; // A target type is valid if it is in the valid targets list, and not in the invalid targets list. @@ -84,7 +84,7 @@ namespace OpenRA.GameRules public bool IsValidAgainst(FrozenActor victim, Actor firedBy) { // If this warhead is ineffective against the target, then it is not a valid target - if (EffectivenessAgainst(victim.Info) <= 0f) + if (EffectivenessAgainst(victim.Info) <= 0) return false; // A target type is valid if it is in the valid targets list, and not in the invalid targets list. diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 4f8f46c98b..796bef68da 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -19,7 +19,7 @@ namespace OpenRA.GameRules public class ProjectileArgs { public WeaponInfo Weapon; - public float FirepowerModifier = 1.0f; + public IEnumerable DamageModifiers; public int Facing; public WPos Source; public Actor SourceActor; @@ -144,13 +144,13 @@ namespace OpenRA.GameRules return true; } - public void Impact(WPos pos, Actor firedBy, float damageModifier) + public void Impact(WPos pos, Actor firedBy, IEnumerable damageModifiers) { foreach (var wh in Warheads) { Action a; - a = () => wh.DoImpact(Target.FromPos(pos), firedBy, damageModifier); + a = () => wh.DoImpact(Target.FromPos(pos), firedBy, damageModifiers); if (wh.Delay > 0) firedBy.World.AddFrameEndTask( w => w.Add(new DelayedAction(wh.Delay, a))); diff --git a/OpenRA.Mods.Cnc/Effects/IonCannon.cs b/OpenRA.Mods.Cnc/Effects/IonCannon.cs index 114e57170b..2dac66756c 100644 --- a/OpenRA.Mods.Cnc/Effects/IonCannon.cs +++ b/OpenRA.Mods.Cnc/Effects/IonCannon.cs @@ -9,6 +9,7 @@ #endregion using System.Collections.Generic; +using System.Linq; using OpenRA.Effects; using OpenRA.GameRules; using OpenRA.Graphics; @@ -45,7 +46,7 @@ namespace OpenRA.Mods.Cnc.Effects if (!impacted && weaponDelay-- <= 0) { var weapon = world.Map.Rules.Weapons[this.weapon.ToLowerInvariant()]; - weapon.Impact(target.CenterPosition, firedBy.PlayerActor, 1f); + weapon.Impact(target.CenterPosition, firedBy.PlayerActor, Enumerable.Empty()); impacted = true; } } diff --git a/OpenRA.Mods.Cnc/PoisonedByTiberium.cs b/OpenRA.Mods.Cnc/PoisonedByTiberium.cs index 2b5d795f51..80f4aebb3e 100644 --- a/OpenRA.Mods.Cnc/PoisonedByTiberium.cs +++ b/OpenRA.Mods.Cnc/PoisonedByTiberium.cs @@ -43,7 +43,7 @@ namespace OpenRA.Mods.Cnc if (!info.Resources.Contains(r.Info.Name)) return; var weapon = self.World.Map.Rules.Weapons[info.Weapon.ToLowerInvariant()]; - weapon.Impact(self.CenterPosition, self.World.WorldActor, 1f); + weapon.Impact(self.CenterPosition, self.World.WorldActor, Enumerable.Empty()); poisonTicks = weapon.ReloadDelay; } } diff --git a/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs b/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs index c30edebde6..4ce49437e1 100644 --- a/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs +++ b/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs @@ -65,7 +65,7 @@ namespace OpenRA.Mods.D2k if (health.HP <= damageThreshold || --damageTicks > 0) return; - weapon.Impact(self.CenterPosition, self.World.WorldActor, 1f); + weapon.Impact(self.CenterPosition, self.World.WorldActor, Enumerable.Empty()); damageTicks = weapon.ReloadDelay; } } diff --git a/OpenRA.Mods.D2k/ThrowsShrapnel.cs b/OpenRA.Mods.D2k/ThrowsShrapnel.cs index 32e963acad..61a89b4a27 100644 --- a/OpenRA.Mods.D2k/ThrowsShrapnel.cs +++ b/OpenRA.Mods.D2k/ThrowsShrapnel.cs @@ -49,10 +49,8 @@ namespace OpenRA.Mods.D2k Weapon = wep, Facing = self.World.SharedRandom.Next(-1, 255), - // TODO: Convert to ints - FirepowerModifier = self.TraitsImplementing() - .Select(a => a.GetFirepowerModifier() / 100f) - .Product(), + DamageModifiers = self.TraitsImplementing() + .Select(a => a.GetFirepowerModifier()), Source = self.CenterPosition, SourceActor = self, diff --git a/OpenRA.Mods.RA/Air/FallsToEarth.cs b/OpenRA.Mods.RA/Air/FallsToEarth.cs index 06394aa455..2d6654fc8f 100755 --- a/OpenRA.Mods.RA/Air/FallsToEarth.cs +++ b/OpenRA.Mods.RA/Air/FallsToEarth.cs @@ -8,6 +8,7 @@ */ #endregion +using System.Linq; using OpenRA.GameRules; using OpenRA.Traits; @@ -54,7 +55,7 @@ namespace OpenRA.Mods.RA.Air if (info.Explosion != null) { var weapon = self.World.Map.Rules.Weapons[info.Explosion.ToLowerInvariant()]; - weapon.Impact(self.CenterPosition, self, 1f); + weapon.Impact(self.CenterPosition, self, Enumerable.Empty()); } self.Destroy(); diff --git a/OpenRA.Mods.RA/Armament.cs b/OpenRA.Mods.RA/Armament.cs index 397bab0986..e1f68f8053 100644 --- a/OpenRA.Mods.RA/Armament.cs +++ b/OpenRA.Mods.RA/Armament.cs @@ -154,10 +154,8 @@ namespace OpenRA.Mods.RA Weapon = Weapon, Facing = legacyFacing, - // TODO: Convert to ints - FirepowerModifier = self.TraitsImplementing() - .Select(a => a.GetFirepowerModifier() / 100f) - .Product(), + DamageModifiers = self.TraitsImplementing() + .Select(a => a.GetFirepowerModifier()), Source = muzzlePosition, SourceActor = self, diff --git a/OpenRA.Mods.RA/Bridge.cs b/OpenRA.Mods.RA/Bridge.cs index edae6bdbac..72cbf990af 100644 --- a/OpenRA.Mods.RA/Bridge.cs +++ b/OpenRA.Mods.RA/Bridge.cs @@ -299,7 +299,7 @@ namespace OpenRA.Mods.RA self.World.AddFrameEndTask(w => { var weapon = saboteur.World.Map.Rules.Weapons[Info.DemolishWeapon.ToLowerInvariant()]; - weapon.Impact(self.CenterPosition, saboteur, 1f); + weapon.Impact(self.CenterPosition, saboteur, Enumerable.Empty()); self.World.WorldActor.Trait().AddEffect(15, self.CenterPosition, 6); self.Kill(saboteur); }); diff --git a/OpenRA.Mods.RA/Crates/ExplodeCrateAction.cs b/OpenRA.Mods.RA/Crates/ExplodeCrateAction.cs index 9a6edeafec..27521ffc24 100644 --- a/OpenRA.Mods.RA/Crates/ExplodeCrateAction.cs +++ b/OpenRA.Mods.RA/Crates/ExplodeCrateAction.cs @@ -8,6 +8,7 @@ */ #endregion +using System.Linq; using OpenRA.GameRules; using OpenRA.Traits; @@ -30,7 +31,7 @@ namespace OpenRA.Mods.RA public override void Activate(Actor collector) { var weapon = self.World.Map.Rules.Weapons[((ExplodeCrateActionInfo)info).Weapon.ToLowerInvariant()]; - weapon.Impact(collector.CenterPosition, self, 1f); + weapon.Impact(collector.CenterPosition, self, Enumerable.Empty()); base.Activate(collector); } } diff --git a/OpenRA.Mods.RA/Effects/Bullet.cs b/OpenRA.Mods.RA/Effects/Bullet.cs index efc63893c0..9a4d171285 100755 --- a/OpenRA.Mods.RA/Effects/Bullet.cs +++ b/OpenRA.Mods.RA/Effects/Bullet.cs @@ -172,7 +172,7 @@ namespace OpenRA.Mods.RA.Effects world.AddFrameEndTask(w => w.Remove(this)); - args.Weapon.Impact(pos, args.SourceActor, args.FirepowerModifier); + args.Weapon.Impact(pos, args.SourceActor, args.DamageModifiers); } } } diff --git a/OpenRA.Mods.RA/Effects/GravityBomb.cs b/OpenRA.Mods.RA/Effects/GravityBomb.cs index 4a2af0fefd..e2eeeaf5ba 100644 --- a/OpenRA.Mods.RA/Effects/GravityBomb.cs +++ b/OpenRA.Mods.RA/Effects/GravityBomb.cs @@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA.Effects { pos += new WVec(0, 0, args.PassiveTarget.Z - pos.Z); world.AddFrameEndTask(w => w.Remove(this)); - args.Weapon.Impact(pos, args.SourceActor, args.FirepowerModifier); + args.Weapon.Impact(pos, args.SourceActor, args.DamageModifiers); } anim.Tick(); diff --git a/OpenRA.Mods.RA/Effects/LaserZap.cs b/OpenRA.Mods.RA/Effects/LaserZap.cs index ce4b638178..a38c38c09a 100644 --- a/OpenRA.Mods.RA/Effects/LaserZap.cs +++ b/OpenRA.Mods.RA/Effects/LaserZap.cs @@ -69,7 +69,7 @@ namespace OpenRA.Mods.RA.Effects if (hitanim != null) hitanim.PlayThen("idle", () => animationComplete = true); - args.Weapon.Impact(target, args.SourceActor, args.FirepowerModifier); + args.Weapon.Impact(target, args.SourceActor, args.DamageModifiers); doneDamage = true; } diff --git a/OpenRA.Mods.RA/Effects/Missile.cs b/OpenRA.Mods.RA/Effects/Missile.cs index c7a62b8896..20eba6f224 100755 --- a/OpenRA.Mods.RA/Effects/Missile.cs +++ b/OpenRA.Mods.RA/Effects/Missile.cs @@ -180,7 +180,7 @@ namespace OpenRA.Mods.RA.Effects if (ticks <= info.Arm) return; - args.Weapon.Impact(pos, args.SourceActor, args.FirepowerModifier); + args.Weapon.Impact(pos, args.SourceActor, args.DamageModifiers); } public IEnumerable Render(WorldRenderer wr) diff --git a/OpenRA.Mods.RA/Effects/NukeLaunch.cs b/OpenRA.Mods.RA/Effects/NukeLaunch.cs index 7db0ba0ddb..bce7fab50f 100755 --- a/OpenRA.Mods.RA/Effects/NukeLaunch.cs +++ b/OpenRA.Mods.RA/Effects/NukeLaunch.cs @@ -81,7 +81,7 @@ namespace OpenRA.Mods.RA.Effects { world.AddFrameEndTask(w => w.Remove(this)); var weapon = world.Map.Rules.Weapons[this.weapon.ToLowerInvariant()]; - weapon.Impact(pos, firedBy.PlayerActor, 1f); + weapon.Impact(pos, firedBy.PlayerActor, Enumerable.Empty()); world.WorldActor.Trait().AddEffect(20, pos, 5); foreach (var a in world.ActorsWithTrait()) diff --git a/OpenRA.Mods.RA/Effects/TeslaZap.cs b/OpenRA.Mods.RA/Effects/TeslaZap.cs index 9026dcce3a..59b5f1dc36 100644 --- a/OpenRA.Mods.RA/Effects/TeslaZap.cs +++ b/OpenRA.Mods.RA/Effects/TeslaZap.cs @@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA.Effects if (!doneDamage) { var pos = Args.GuidedTarget.IsValidFor(Args.SourceActor) ? Args.GuidedTarget.CenterPosition : Args.PassiveTarget; - Args.Weapon.Impact(pos, Args.SourceActor, Args.FirepowerModifier); + Args.Weapon.Impact(pos, Args.SourceActor, Args.DamageModifiers); doneDamage = true; } } diff --git a/OpenRA.Mods.RA/Explodes.cs b/OpenRA.Mods.RA/Explodes.cs index da310d9c6b..a2af881410 100644 --- a/OpenRA.Mods.RA/Explodes.cs +++ b/OpenRA.Mods.RA/Explodes.cs @@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA if (weapon.Report != null && weapon.Report.Any()) Sound.Play(weapon.Report.Random(e.Attacker.World.SharedRandom), self.CenterPosition); - weapon.Impact(self.CenterPosition, e.Attacker, 1f); + weapon.Impact(self.CenterPosition, e.Attacker, Enumerable.Empty()); } } diff --git a/OpenRA.Mods.RA/MadTank.cs b/OpenRA.Mods.RA/MadTank.cs index 93a3a113b0..cb6ed97a4c 100644 --- a/OpenRA.Mods.RA/MadTank.cs +++ b/OpenRA.Mods.RA/MadTank.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Drawing; +using System.Linq; using OpenRA.GameRules; using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Move; @@ -71,7 +72,7 @@ namespace OpenRA.Mods.RA if (info.ThumpDamageWeapon != null) { var weapon = self.World.Map.Rules.Weapons[info.ThumpDamageWeapon.ToLowerInvariant()]; - weapon.Impact(self.CenterPosition, self, 1f); + weapon.Impact(self.CenterPosition, self, Enumerable.Empty()); } screenShaker.AddEffect(info.ThumpShakeTime, self.CenterPosition, info.ThumpShakeIntensity, info.ThumpShakeMultiplier); tick = 0; @@ -110,7 +111,7 @@ namespace OpenRA.Mods.RA if (info.DetonationWeapon != null) { var weapon = self.World.Map.Rules.Weapons[info.DetonationWeapon.ToLowerInvariant()]; - weapon.Impact(self.CenterPosition, self, 1f); + weapon.Impact(self.CenterPosition, self, Enumerable.Empty()); } self.Kill(self); }); diff --git a/OpenRA.Mods.RA/Warheads/AbsoluteSpreadDamageWarhead.cs b/OpenRA.Mods.RA/Warheads/AbsoluteSpreadDamageWarhead.cs index defa314f15..7870fbf5bf 100644 --- a/OpenRA.Mods.RA/Warheads/AbsoluteSpreadDamageWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/AbsoluteSpreadDamageWarhead.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA [Desc("What factor to multiply the Damage by for this spread range.", "Each factor specified must have an associated Spread defined.")] public readonly float[] SpreadFactor = { 1f }; - public override void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + public override void DoImpact(WPos pos, Actor firedBy, IEnumerable damageModifiers) { var world = firedBy.World; @@ -44,33 +44,35 @@ namespace OpenRA.Mods.RA hitActors.Except(world.FindActorsInCircle(pos, previousSpread)); foreach (var victim in hitActors) + { if (IsValidAgainst(victim, firedBy)) { - var damage = GetDamageToInflict(victim, firedBy, firepowerModifier * currentFactor); + // 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, float firepowerModifier) + 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 = (int)GetDamageToInflict(victim, firedBy, firepowerModifier * currentFactor); + var damage = GetDamageToInflict(victim, firedBy, damageModifiers.Append((int)(currentFactor * 100))); victim.InflictDamage(firedBy, damage, this); } } - public int GetDamageToInflict(Actor target, Actor firedBy, float modifier) + public int GetDamageToInflict(Actor target, Actor firedBy, IEnumerable damageModifiers) { var healthInfo = target.Info.Traits.GetOrDefault(); if (healthInfo == null) return 0; - var rawDamage = (float)Damage; - - return (int)(rawDamage * modifier * EffectivenessAgainst(target.Info)); + return Util.ApplyPercentageModifiers(Damage, damageModifiers.Append(EffectivenessAgainst(target.Info))); } } } diff --git a/OpenRA.Mods.RA/Warheads/CreateEffectWarhead.cs b/OpenRA.Mods.RA/Warheads/CreateEffectWarhead.cs index 0abcedfafd..91bf3af422 100644 --- a/OpenRA.Mods.RA/Warheads/CreateEffectWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/CreateEffectWarhead.cs @@ -74,7 +74,7 @@ namespace OpenRA.Mods.RA return false; } - public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + public override void DoImpact(Target target, Actor firedBy, IEnumerable damageModifiers) { var pos = target.CenterPosition; var world = firedBy.World; diff --git a/OpenRA.Mods.RA/Warheads/CreateResourceWarhead.cs b/OpenRA.Mods.RA/Warheads/CreateResourceWarhead.cs index cd088f7b84..d80c01e04f 100644 --- a/OpenRA.Mods.RA/Warheads/CreateResourceWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/CreateResourceWarhead.cs @@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA // TODO: Allow maximum resource splatter to be defined. (Per tile, and in total). - public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + public override void DoImpact(Target target, Actor firedBy, IEnumerable damageModifiers) { if (string.IsNullOrEmpty(AddsResourceType)) return; diff --git a/OpenRA.Mods.RA/Warheads/DestroyResourceWarhead.cs b/OpenRA.Mods.RA/Warheads/DestroyResourceWarhead.cs index bd4048a9d1..07e64a288c 100644 --- a/OpenRA.Mods.RA/Warheads/DestroyResourceWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/DestroyResourceWarhead.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.RA // TODO: Allow maximum resource removal to be defined. (Per tile, and in total). - public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + public override void DoImpact(Target target, Actor firedBy, IEnumerable damageModifiers) { var world = firedBy.World; var targetTile = world.Map.CellContaining(target.CenterPosition); diff --git a/OpenRA.Mods.RA/Warheads/HealthPercentageDamageWarhead.cs b/OpenRA.Mods.RA/Warheads/HealthPercentageDamageWarhead.cs index 2bab70e713..98dc341b23 100644 --- a/OpenRA.Mods.RA/Warheads/HealthPercentageDamageWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/HealthPercentageDamageWarhead.cs @@ -22,7 +22,7 @@ namespace OpenRA.Mods.RA [Desc("Size of the area. Damage will be applied to this area.", "If two spreads are defined, the area of effect is a ring, where the second value is the inner radius.")] public readonly WRange[] Spread = { new WRange(43), WRange.Zero }; - public override void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + public override void DoImpact(WPos pos, Actor firedBy, IEnumerable damageModifiers) { var world = firedBy.World; var range = Spread[0]; @@ -31,14 +31,14 @@ namespace OpenRA.Mods.RA hitActors.Except(world.FindActorsInCircle(pos, Spread[1])); foreach (var victim in hitActors) - DoImpact(victim, firedBy, firepowerModifier); + DoImpact(victim, firedBy, damageModifiers); } - public override void DoImpact(Actor victim, Actor firedBy, float firepowerModifier) + public override void DoImpact(Actor victim, Actor firedBy, IEnumerable damageModifiers) { if (IsValidAgainst(victim, firedBy)) { - var damage = GetDamageToInflict(victim, firedBy, firepowerModifier); + 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(); @@ -49,15 +49,13 @@ namespace OpenRA.Mods.RA } } - public float GetDamageToInflict(Actor target, Actor firedBy, float modifier) + public float GetDamageToInflict(Actor target, Actor firedBy, IEnumerable damageModifiers) { var healthInfo = target.Info.Traits.GetOrDefault(); if (healthInfo == null) return 0; - var rawDamage = (float)Damage; - - return rawDamage * modifier * EffectivenessAgainst(target.Info); + return Util.ApplyPercentageModifiers(Damage, damageModifiers.Append(EffectivenessAgainst(target.Info))); } } } diff --git a/OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs b/OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs index 27bc6e4096..a8f944fc4b 100644 --- a/OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA [Desc("Type of smudge to apply to terrain.")] public readonly string[] SmudgeType = { }; - public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + public override void DoImpact(Target target, Actor firedBy, IEnumerable damageModifiers) { var world = firedBy.World; var targetTile = world.Map.CellContaining(target.CenterPosition); diff --git a/OpenRA.Mods.RA/Warheads/PerCellDamageWarhead.cs b/OpenRA.Mods.RA/Warheads/PerCellDamageWarhead.cs index 92e4e70e15..f17f2b36aa 100644 --- a/OpenRA.Mods.RA/Warheads/PerCellDamageWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/PerCellDamageWarhead.cs @@ -22,7 +22,7 @@ namespace OpenRA.Mods.RA [Desc("Size of the area. Damage will be applied to this area.")] public readonly int[] Size = { 0, 0 }; - public override void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + public override void DoImpact(WPos pos, Actor firedBy, IEnumerable damageModifiers) { var world = firedBy.World; var targetTile = world.Map.CellContaining(pos); @@ -31,27 +31,25 @@ namespace OpenRA.Mods.RA foreach (var t in affectedTiles) foreach (var victim in world.ActorMap.GetUnitsAt(t)) - DoImpact(victim, firedBy, firepowerModifier); + DoImpact(victim, firedBy, damageModifiers); } - public override void DoImpact(Actor victim, Actor firedBy, float firepowerModifier) + public override void DoImpact(Actor victim, Actor firedBy, IEnumerable damageModifiers) { if (IsValidAgainst(victim, firedBy)) { - var damage = GetDamageToInflict(victim, firedBy, firepowerModifier); + var damage = GetDamageToInflict(victim, firedBy, damageModifiers); victim.InflictDamage(firedBy, damage, this); } } - public int GetDamageToInflict(Actor target, Actor firedBy, float modifier) + public int GetDamageToInflict(Actor target, Actor firedBy, IEnumerable damageModifiers) { var healthInfo = target.Info.Traits.GetOrDefault(); if (healthInfo == null) return 0; - var rawDamage = (float)Damage; - - return (int)(rawDamage * modifier * EffectivenessAgainst(target.Info)); + 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 728f9f91e8..bca54147c4 100644 --- a/OpenRA.Mods.RA/Warheads/SpreadDamageWarhead.cs +++ b/OpenRA.Mods.RA/Warheads/SpreadDamageWarhead.cs @@ -22,40 +22,41 @@ namespace OpenRA.Mods.RA [Desc("For Normal DamageModel: Distance from the explosion center at which damage is 1/2.")] public readonly WRange Spread = new WRange(43); - public override void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + public override void DoImpact(WPos pos, Actor firedBy, IEnumerable damageModifiers) { var world = firedBy.World; var maxSpread = new WRange((int)(Spread.Range * (float)Math.Log(Math.Abs(Damage), 2))); var hitActors = world.FindActorsInCircle(pos, maxSpread); foreach (var victim in hitActors) + { if (IsValidAgainst(victim, firedBy)) { - var damage = (int)GetDamageToInflict(pos, victim, firedBy, firepowerModifier); + var damage = (int)GetDamageToInflict(pos, victim, firedBy, damageModifiers); victim.InflictDamage(firedBy, damage, this); } + } } - public override void DoImpact(Actor victim, Actor firedBy, float firepowerModifier) + public override void DoImpact(Actor victim, Actor firedBy, IEnumerable damageModifiers) { if (IsValidAgainst(victim, firedBy)) { - var damage = GetDamageToInflict(victim.CenterPosition, victim, firedBy, firepowerModifier); + var damage = GetDamageToInflict(victim.CenterPosition, victim, firedBy, damageModifiers); victim.InflictDamage(firedBy, damage, this); } } - public int GetDamageToInflict(WPos pos, Actor target, Actor firedBy, float modifier) + 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 = (float)GetDamageFalloff(distance * 1f / Spread.Range); - var rawDamage = (float)(falloff * Damage); + var falloff = (int)(100 * GetDamageFalloff(distance * 1f / Spread.Range)); - return (int)(rawDamage * modifier * EffectivenessAgainst(target.Info)); + return Util.ApplyPercentageModifiers(Damage, damageModifiers.Append(EffectivenessAgainst(target.Info), falloff)); } static readonly float[] falloff =