diff --git a/OpenRA.Mods.RA/AttackBase.cs b/OpenRA.Mods.RA/AttackBase.cs index c7d7396c20..380db77f40 100644 --- a/OpenRA.Mods.RA/AttackBase.cs +++ b/OpenRA.Mods.RA/AttackBase.cs @@ -47,8 +47,11 @@ namespace OpenRA.Mods.RA public List Weapons = new List(); public List Turrets = new List(); + readonly Actor self; + public AttackBase(Actor self) { + this.self = self; var info = self.Info.Traits.Get(); Turrets.Add(new Turret(info.PrimaryOffset)); @@ -127,7 +130,7 @@ namespace OpenRA.Mods.RA if (w.Info.MinRange * w.Info.MinRange * Game.CellSize * Game.CellSize > (target.CenterLocation - self.CenterLocation).LengthSquared) return false; - if (!w.IsValidAgainst(target)) return false; + if (!w.IsValidAgainst(self.World, target)) return false; var barrel = w.Barrels[w.Burst % w.Barrels.Length]; var destMove = target.IsActor ? target.Actor.TraitOrDefault() : null; @@ -243,10 +246,10 @@ namespace OpenRA.Mods.RA Math.Max(0, (int)weapon.Info.Range))); } - public bool HasAnyValidWeapons(Target t) { return Weapons.Any(w => w.IsValidAgainst(t)); } + public bool HasAnyValidWeapons(Target t) { return Weapons.Any(w => w.IsValidAgainst(self.World, t)); } public float GetMaximumRange() { return Weapons.Max(w => w.Info.Range); } - public Weapon ChooseWeaponForTarget(Target t) { return Weapons.FirstOrDefault(w => w.IsValidAgainst(t)); } + public Weapon ChooseWeaponForTarget(Target t) { return Weapons.FirstOrDefault(w => w.IsValidAgainst(self.World, t)); } class AttackOrderTargeter : IOrderTargeter { diff --git a/OpenRA.Mods.RA/Combat.cs b/OpenRA.Mods.RA/Combat.cs index 21234f1dd2..2b02b2367c 100755 --- a/OpenRA.Mods.RA/Combat.cs +++ b/OpenRA.Mods.RA/Combat.cs @@ -149,7 +149,7 @@ namespace OpenRA.Mods.RA static float GetDamageToInflict(Actor target, ProjectileArgs args, WarheadInfo warhead, float modifier) { // don't hit air units with splash from ground explosions, etc - if (!WeaponValidForTarget(args.weapon, Target.FromActor(target))) return 0f; + if (!WeaponValidForTarget(args.weapon, target)) return 0f; var selectable = target.Info.Traits.GetOrDefault(); var radius = selectable != null ? selectable.Radius : 0; @@ -161,24 +161,25 @@ namespace OpenRA.Mods.RA return (float)(rawDamage * multiplier); } - public static bool WeaponValidForTarget(WeaponInfo weapon, Target target) + public static bool WeaponValidForTarget(WeaponInfo weapon, Actor target) { - // todo: fix this properly. - if (!target.IsValid) return false; - if (!target.IsActor) return weapon.ValidTargets.Contains("Ground") // hack! - || (weapon.ValidTargets.Contains("Water") && - Game.world.GetTerrainType(Util.CellContaining(target.CenterLocation)) == "Water"); // even bigger hack! - - var targetable = target.Actor.TraitOrDefault(); + var targetable = target.TraitOrDefault(); if (targetable == null || !weapon.ValidTargets.Intersect(targetable.TargetTypes).Any()) return false; - if (weapon.Warheads.All( w => w.EffectivenessAgainst(target.Actor) <= 0)) + if (weapon.Warheads.All( w => w.EffectivenessAgainst(target) <= 0)) return false; return true; } + public static bool WeaponValidForTarget( WeaponInfo weapon, World world, int2 location ) + { + if( weapon.ValidTargets.Contains( "Ground" ) && world.GetTerrainType( location ) != "Water" ) return true; + if( weapon.ValidTargets.Contains( "Water" ) && world.GetTerrainType( location ) == "Water" ) return true; + return false; + } + static float2 GetRecoil(Actor self, float recoil) { var abInfo = self.Info.Traits.GetOrDefault(); diff --git a/OpenRA.Mods.RA/Weapon.cs b/OpenRA.Mods.RA/Weapon.cs index 5e0b5e4a01..f41432ef5e 100644 --- a/OpenRA.Mods.RA/Weapon.cs +++ b/OpenRA.Mods.RA/Weapon.cs @@ -72,9 +72,12 @@ namespace OpenRA.Mods.RA Turret.Recoil = Math.Max(0f, Turret.Recoil - .2f); } - public bool IsValidAgainst(Target target) + public bool IsValidAgainst(World world, Target target) { - return Combat.WeaponValidForTarget(Info, target); + if( target.IsActor ) + return Combat.WeaponValidForTarget( Info, target.Actor ); + else + return Combat.WeaponValidForTarget( Info, world, Util.CellContaining( target.CenterLocation ) ); } public void FiredShot()