diff --git a/OpenRA.Mods.RA/AttackBase.cs b/OpenRA.Mods.RA/AttackBase.cs index 4188d05533..c86a8518a2 100644 --- a/OpenRA.Mods.RA/AttackBase.cs +++ b/OpenRA.Mods.RA/AttackBase.cs @@ -103,7 +103,7 @@ namespace OpenRA.Mods.RA delayedActions.RemoveAll(a => a.First <= 0); } - void ScheduleDelayedAction(int t, Action a) + internal void ScheduleDelayedAction(int t, Action a) { if (t > 0) delayedActions.Add(Pair.New(t, a)); @@ -118,69 +118,7 @@ namespace OpenRA.Mods.RA var move = self.TraitOrDefault(); var facing = self.TraitOrDefault(); foreach (var w in Weapons) - if (CheckFire(self, move, facing, w)) - w.FiredShot(); - } - - bool CheckFire(Actor self, IMove move, IFacing facing, Weapon w) - { - if (w.FireDelay > 0) return false; - - var limitedAmmo = self.TraitOrDefault(); - if (limitedAmmo != null && !limitedAmmo.HasAmmo()) - return false; - - if (w.Info.Range * w.Info.Range * Game.CellSize * Game.CellSize - < (target.CenterLocation - self.CenterLocation).LengthSquared) return false; - - if (w.Info.MinRange * w.Info.MinRange * Game.CellSize * Game.CellSize > - (target.CenterLocation - self.CenterLocation).LengthSquared) 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; - - var args = new ProjectileArgs - { - weapon = w.Info, - - firedBy = self, - target = this.target, - - src = (self.CenterLocation - + Combat.GetTurretPosition(self, facing, w.Turret) - + Combat.GetBarrelPosition(self, facing, w.Turret, barrel)).ToInt2(), - srcAltitude = move != null ? move.Altitude : 0, - dest = target.CenterLocation.ToInt2(), - destAltitude = destMove != null ? destMove.Altitude : 0, - - facing = barrel.Facing + - (self.HasTrait() ? self.Trait().turretFacing : - facing != null ? facing.Facing : Util.GetFacing(target.CenterLocation - self.CenterLocation, 0)), - - firepowerModifier = self.TraitsImplementing() - .Select(a => a.GetFirepowerModifier()) - .Product() - }; - - ScheduleDelayedAction( FireDelay( self, self.Info.Traits.Get() ), () => - { - if (args.weapon.Projectile != null) - { - var projectile = args.weapon.Projectile.Create(args); - if (projectile != null) - self.World.Add(projectile); - - if (!string.IsNullOrEmpty(args.weapon.Report)) - Sound.Play(args.weapon.Report + ".aud", self.CenterLocation); - } - }); - - foreach (var na in self.TraitsImplementing()) - na.Attacking(self); - - return true; + w.CheckFire(self, this, move, facing, target); } public virtual int FireDelay( Actor self, AttackBaseInfo info ) diff --git a/OpenRA.Mods.RA/Weapon.cs b/OpenRA.Mods.RA/Weapon.cs index f41432ef5e..fdb9e59207 100644 --- a/OpenRA.Mods.RA/Weapon.cs +++ b/OpenRA.Mods.RA/Weapon.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; +using System.Linq; using OpenRA.GameRules; using OpenRA.Traits; @@ -92,5 +93,66 @@ namespace OpenRA.Mods.RA Burst = Info.Burst; } } + + public void CheckFire(Actor self, AttackBase attack, IMove move, IFacing facing, Target target) + { + if (FireDelay > 0) return; + + var limitedAmmo = self.TraitOrDefault(); + if (limitedAmmo != null && !limitedAmmo.HasAmmo()) + return; + + if (Info.Range * Info.Range * Game.CellSize * Game.CellSize + < (target.CenterLocation - self.CenterLocation).LengthSquared) return; + + if (Info.MinRange * Info.MinRange * Game.CellSize * Game.CellSize > + (target.CenterLocation - self.CenterLocation).LengthSquared) return; + + if (!IsValidAgainst(self.World, target)) return; + + var barrel = Barrels[Burst % Barrels.Length]; + var destMove = target.IsActor ? target.Actor.TraitOrDefault() : null; + + var args = new ProjectileArgs + { + weapon = Info, + + firedBy = self, + target = target, + + src = (self.CenterLocation + + Combat.GetTurretPosition(self, facing, Turret) + + Combat.GetBarrelPosition(self, facing, Turret, barrel)).ToInt2(), + srcAltitude = move != null ? move.Altitude : 0, + dest = target.CenterLocation.ToInt2(), + destAltitude = destMove != null ? destMove.Altitude : 0, + + facing = barrel.Facing + + (self.HasTrait() ? self.Trait().turretFacing : + facing != null ? facing.Facing : Util.GetFacing(target.CenterLocation - self.CenterLocation, 0)), + + firepowerModifier = self.TraitsImplementing() + .Select(a => a.GetFirepowerModifier()) + .Product() + }; + + attack.ScheduleDelayedAction( attack.FireDelay( self, self.Info.Traits.Get() ), () => + { + if (args.weapon.Projectile != null) + { + var projectile = args.weapon.Projectile.Create(args); + if (projectile != null) + self.World.Add(projectile); + + if (!string.IsNullOrEmpty(args.weapon.Report)) + Sound.Play(args.weapon.Report + ".aud", self.CenterLocation); + } + }); + + foreach (var na in self.TraitsImplementing()) + na.Attacking(self); + + FiredShot(); + } } }