diff --git a/OpenRA.Mods.RA/AttackBase.cs b/OpenRA.Mods.RA/AttackBase.cs index e581995f4b..139e42c6b8 100644 --- a/OpenRA.Mods.RA/AttackBase.cs +++ b/OpenRA.Mods.RA/AttackBase.cs @@ -48,10 +48,10 @@ namespace OpenRA.Mods.RA public int[] Offset; public Barrel[] Barrels; - public Weapon(WeaponInfo info, int[] offset, int[] localOffset) + public Weapon(string weaponName, int[] offset, int[] localOffset) { - Info = info; - Burst = info.Burst; + Info = Rules.Weapons[weaponName.ToLowerInvariant()]; + Burst = Info.Burst; Offset = offset; var barrels = new List(); @@ -76,6 +76,11 @@ namespace OpenRA.Mods.RA if (FireDelay > 0) --FireDelay; Recoil = Math.Max(0f, Recoil - .2f); } + + public bool IsValidAgainst(Target target) + { + return Combat.WeaponValidForTarget(Info, target); + } } public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IOrderCursor, IOrderVoice @@ -88,12 +93,12 @@ namespace OpenRA.Mods.RA { var info = self.Info.Traits.Get(); - if (self.GetPrimaryWeapon() != null) - Weapons.Add(new Weapon(self.GetPrimaryWeapon(), + if (info.PrimaryWeapon != null) + Weapons.Add(new Weapon(info.PrimaryWeapon, info.PrimaryOffset, info.PrimaryLocalOffset)); if (self.GetSecondaryWeapon() != null) - Weapons.Add(new Weapon(self.GetSecondaryWeapon(), + Weapons.Add(new Weapon(info.SecondaryWeapon, info.SecondaryOffset ?? info.PrimaryOffset, info.SecondaryLocalOffset)); } @@ -158,7 +163,7 @@ namespace OpenRA.Mods.RA if (w.Info.Range * w.Info.Range * Game.CellSize * Game.CellSize < (target.CenterLocation - self.CenterLocation).LengthSquared) return false; - if (!Combat.WeaponValidForTarget(w.Info, target)) return false; + if (!w.IsValidAgainst(target)) return false; var barrel = w.Barrels[w.Burst % w.Barrels.Length]; @@ -226,7 +231,7 @@ namespace OpenRA.Mods.RA var target = underCursor == null ? Target.FromCell(xy) : Target.FromActor(underCursor); - var isHeal = self.GetPrimaryWeapon().Warheads.First().Damage < 0; + var isHeal = Weapons[0].Info.Warheads[0].Damage < 0; var forceFire = mi.Modifiers.HasModifier(Modifiers.Ctrl); if (isHeal) @@ -252,7 +257,7 @@ namespace OpenRA.Mods.RA return null; } - if (!Combat.HasAnyValidWeapons(self, target)) return null; + if (!HasAnyValidWeapons(target)) return null; return new Order(isHeal ? "Heal" : "Attack", self, underCursor); } @@ -308,5 +313,8 @@ namespace OpenRA.Mods.RA /* temp hack */ public float GetPrimaryRecoil() { return Weapons.Count > 0 ? Weapons[0].Recoil : 0; } public float GetSecondaryRecoil() { return Weapons.Count > 1 ? Weapons[1].Recoil : 0; } + + public bool HasAnyValidWeapons(Target t) { return Weapons.Any(w => w.IsValidAgainst(t)); } + public float GetMaximumRange() { return Weapons.Max(w => w.Info.Range); } } } diff --git a/OpenRA.Mods.RA/AutoHeal.cs b/OpenRA.Mods.RA/AutoHeal.cs index 41e27ff979..184a580a55 100644 --- a/OpenRA.Mods.RA/AutoHeal.cs +++ b/OpenRA.Mods.RA/AutoHeal.cs @@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA bool NeedsNewTarget(Actor self) { var attack = self.traits.Get(); - var range = Combat.GetMaximumRange(self); + var range = attack.GetMaximumRange(); if (!attack.target.IsValid) return true; // he's dead. @@ -47,7 +47,8 @@ namespace OpenRA.Mods.RA public void Tick(Actor self) { - var range = Combat.GetMaximumRange(self); + var attack = self.traits.Get(); + var range = attack.GetMaximumRange(); if (NeedsNewTarget(self)) AttackTarget(self, ChooseTarget(self, range)); @@ -56,12 +57,13 @@ namespace OpenRA.Mods.RA Actor ChooseTarget(Actor self, float range) { var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range); + var attack = self.traits.Get(); return inRange - .Where(a => a != self && self.Owner.Stances[ a.Owner ] == Stance.Ally) + .Where(a => a != self && self.Owner.Stances[a.Owner] == Stance.Ally) .Where(a => !a.IsDead()) .Where(a => a.traits.Contains() && a.GetDamageState() > DamageState.Undamaged) - .Where(a => Combat.HasAnyValidWeapons(self, Target.FromActor(a))) + .Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) .OrderBy(a => (a.Location - self.Location).LengthSquared) .FirstOrDefault(); } diff --git a/OpenRA.Mods.RA/AutoTarget.cs b/OpenRA.Mods.RA/AutoTarget.cs index 67c8c194c0..0039aea067 100644 --- a/OpenRA.Mods.RA/AutoTarget.cs +++ b/OpenRA.Mods.RA/AutoTarget.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA if (--nextScanTime <= 0) { var attack = self.traits.Get(); - var range = Combat.GetMaximumRange(self); + var range = attack.GetMaximumRange(); if (!attack.target.IsValid || (Util.CellContaining(attack.target.CenterLocation) - self.Location).LengthSquared > range * range) @@ -53,10 +53,11 @@ namespace OpenRA.Mods.RA Actor ChooseTarget(Actor self, float range) { var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range); + var attack = self.traits.Get(); return inRange .Where(a => a.Owner != null && self.Owner.Stances[ a.Owner ] == Stance.Enemy) - .Where(a => Combat.HasAnyValidWeapons(self, Target.FromActor(a))) + .Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) .Where(a => !a.traits.Contains() || !a.traits.Get().Cloaked) .OrderBy(a => (a.Location - self.Location).LengthSquared) .FirstOrDefault(); @@ -67,7 +68,8 @@ namespace OpenRA.Mods.RA if (!self.IsIdle) return; // not a lot we can do about things we can't hurt... although maybe we should automatically run away? - if (!Combat.HasAnyValidWeapons(self, Target.FromActor(e.Attacker))) return; + var attack = self.traits.Get(); + if (!attack.HasAnyValidWeapons(Target.FromActor(e.Attacker))) return; // don't retaliate against own units force-firing on us. it's usually not what the player wanted. if (self.Owner.Stances[e.Attacker.Owner] == Stance.Ally) return; diff --git a/OpenRA.Mods.RA/Combat.cs b/OpenRA.Mods.RA/Combat.cs index 99f854f539..c810e9d3b8 100755 --- a/OpenRA.Mods.RA/Combat.cs +++ b/OpenRA.Mods.RA/Combat.cs @@ -176,23 +176,6 @@ namespace OpenRA.Mods.RA return true; } - public static bool HasAnyValidWeapons(Actor self, Target target) - { - var info = self.Info.Traits.Get(); - if (info.PrimaryWeapon != null && - WeaponValidForTarget(self.GetPrimaryWeapon(), target)) return true; - if (info.SecondaryWeapon != null && - WeaponValidForTarget(self.GetSecondaryWeapon(), target)) return true; - - return false; - } - - public static float GetMaximumRange(Actor self) - { - return new[] { self.GetPrimaryWeapon(), self.GetSecondaryWeapon() } - .Where(w => w != null).Max(w => w.Range); - } - public static WeaponInfo GetPrimaryWeapon(this Actor self) { var info = self.Info.Traits.GetOrDefault();