diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index e090812c3a..e63053720a 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -153,6 +153,7 @@ namespace OpenRA.Traits Activity MoveTo(CPos cell, int nearEnough); Activity MoveTo(CPos cell, Actor ignoredActor); Activity MoveWithinRange(Target target, WRange range); + Activity MoveFollow(Actor self, Target target, WRange range); CPos NearestMoveableCell(CPos target); } diff --git a/OpenRA.Mods.RA/Activities/FlyFollow.cs b/OpenRA.Mods.RA/Activities/FlyFollow.cs new file mode 100644 index 0000000000..18664cd1f7 --- /dev/null +++ b/OpenRA.Mods.RA/Activities/FlyFollow.cs @@ -0,0 +1,44 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using OpenRA.Mods.RA.Air; +using OpenRA.Mods.RA.Move; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA.Activities +{ + public class FlyFollow : Activity + { + Target target; + Plane plane; + WRange range; + + public FlyFollow(Actor self, Target target, WRange range) + { + this.target = target; + plane = self.Trait(); + this.range = range; + } + + public override Activity Tick(Actor self) + { + if (IsCanceled || !target.IsValidFor(self)) + return NextActivity; + + if (target.IsInRange(self.CenterPosition, range)) + { + Fly.FlyToward(self, plane, plane.Facing, plane.Info.CruiseAltitude); + return this; + } + + return Util.SequenceActivities(new Fly(self, target, WRange.Zero, range), this); + } + } +} diff --git a/OpenRA.Mods.RA/Air/Helicopter.cs b/OpenRA.Mods.RA/Air/Helicopter.cs index 9621b815b7..039cb87a38 100755 --- a/OpenRA.Mods.RA/Air/Helicopter.cs +++ b/OpenRA.Mods.RA/Air/Helicopter.cs @@ -156,6 +156,7 @@ namespace OpenRA.Mods.RA.Air public Activity MoveTo(CPos cell, Actor ignoredActor) { return new HeliFly(self, Target.FromCell(cell)); } public Activity MoveWithinRange(Target target, WRange range) { return new HeliFly(self, target, WRange.Zero, range); } public Activity MoveWithinRange(Target target, WRange minRange, WRange maxRange) { return new HeliFly(self, target, minRange, maxRange); } + public Activity MoveFollow(Actor self, Target target, WRange range) { return new Follow(self, target, range); } public CPos NearestMoveableCell(CPos cell) { return cell; } } } diff --git a/OpenRA.Mods.RA/Air/Plane.cs b/OpenRA.Mods.RA/Air/Plane.cs index 5bf446f90e..e21b6e0468 100755 --- a/OpenRA.Mods.RA/Air/Plane.cs +++ b/OpenRA.Mods.RA/Air/Plane.cs @@ -9,6 +9,7 @@ #endregion using System.Drawing; +using OpenRA.Mods.RA.Activities; using OpenRA.Traits; namespace OpenRA.Mods.RA.Air @@ -96,6 +97,7 @@ namespace OpenRA.Mods.RA.Air public Activity MoveTo(CPos cell, Actor ignoredActor) { return Util.SequenceActivities(new Fly(self, Target.FromCell(cell)), new FlyCircle()); } public Activity MoveWithinRange(Target target, WRange range) { return Util.SequenceActivities(new Fly(self, target, WRange.Zero, range), new FlyCircle()); } public Activity MoveWithinRange(Target target, WRange minRange, WRange maxRange) { return Util.SequenceActivities(new Fly(self, target, minRange, maxRange), new FlyCircle()); } + public Activity MoveFollow(Actor self, Target target, WRange range) { return new FlyFollow(self, target, range); } public CPos NearestMoveableCell(CPos cell) { return cell; } } } diff --git a/OpenRA.Mods.RA/Attack/AttackTurreted.cs b/OpenRA.Mods.RA/Attack/AttackTurreted.cs index 4bfae3a11d..f57d86072a 100644 --- a/OpenRA.Mods.RA/Attack/AttackTurreted.cs +++ b/OpenRA.Mods.RA/Attack/AttackTurreted.cs @@ -99,8 +99,10 @@ namespace OpenRA.Mods.RA var range = WRange.FromCells(Math.Max(0, weapon.Weapon.Range.Range / 1024 - RangeTolerance)); attack.Target = target; - if (allowMove && self.HasTrait() && !self.Info.Traits.Get().OnRails) - return Util.SequenceActivities(new Follow(self, target, range), this); + var mobile = self.TraitOrDefault(); + + if (allowMove && mobile != null && !mobile.Info.OnRails) + return Util.SequenceActivities(mobile.MoveFollow(self, target, range), this); } return NextActivity; diff --git a/OpenRA.Mods.RA/Guard.cs b/OpenRA.Mods.RA/Guard.cs index 621fba527c..89fed40e7e 100644 --- a/OpenRA.Mods.RA/Guard.cs +++ b/OpenRA.Mods.RA/Guard.cs @@ -30,8 +30,7 @@ namespace OpenRA.Mods.RA self.SetTargetLine(target, Color.Yellow); var range = WRange.FromCells(target.Actor.Info.Traits.Get().Range); - self.QueueActivity(false, new AttackMove.AttackMoveActivity(self, - new Follow(self, target, range))); + self.QueueActivity(false, new AttackMove.AttackMoveActivity(self, self.Trait().MoveFollow(self, target, range))); } } diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index 887c12ec03..6ca8d2c80e 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -540,6 +540,7 @@ namespace OpenRA.Mods.RA.Move public Activity MoveTo(CPos cell, int nearEnough) { return new Move(cell, nearEnough); } public Activity MoveTo(CPos cell, Actor ignoredActor) { return new Move(cell, ignoredActor); } public Activity MoveWithinRange(Target target, WRange range) { return new Move(target, range); } + public Activity MoveFollow(Actor self, Target target, WRange range) { return new Follow(self, target, range); } public Activity MoveTo(Func> pathFunc) { return new Move(pathFunc); } } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index dc186b9443..b84c567381 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -488,6 +488,7 @@ +