diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index c7c7b1f5b8..96efe75e0a 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -725,6 +725,7 @@ + diff --git a/OpenRA.Mods.Common/Orders/GuardOrderGenerator.cs b/OpenRA.Mods.Common/Orders/GuardOrderGenerator.cs new file mode 100644 index 0000000000..569121c6f3 --- /dev/null +++ b/OpenRA.Mods.Common/Orders/GuardOrderGenerator.cs @@ -0,0 +1,62 @@ +#region Copyright & License Information +/* + * Copyright 2007-2015 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 System.Collections.Generic; +using System.Linq; +using OpenRA.Mods.Common.Traits; +using OpenRA.Orders; + +namespace OpenRA.Mods.Common.Orders +{ + public class GuardOrderGenerator : GenericSelectTarget + { + public GuardOrderGenerator(IEnumerable subjects, string order, string cursor, MouseButton button) + : base(subjects, order, cursor, button) { } + + protected override IEnumerable OrderInner(World world, CPos xy, MouseInput mi) + { + var target = FriendlyGuardableUnits(world, mi).FirstOrDefault(); + + if (target == null || Subjects.All(s => s.IsDead)) + yield break; + + world.CancelInputMode(); + foreach (var subject in Subjects) + if (subject != target) + yield return new Order(OrderName, subject, false) { TargetActor = target }; + } + + public override void Tick(World world) + { + if (Subjects.All(s => s.IsDead || !s.Info.HasTraitInfo())) + world.CancelInputMode(); + } + + public override string GetCursor(World world, CPos cell, int2 worldPixel, MouseInput mi) + { + if (!Subjects.Any()) + return null; + + var multiple = Subjects.Count() > 1; + var canGuard = FriendlyGuardableUnits(world, mi) + .Any(a => multiple || a != Subjects.First()); + + return canGuard ? Cursor : "move-blocked"; + } + + static IEnumerable FriendlyGuardableUnits(World world, MouseInput mi) + { + return world.ScreenMap.ActorsAt(mi) + .Where(a => !world.FogObscures(a) && !a.IsDead && + a.AppearsFriendlyTo(world.LocalPlayer.PlayerActor) && + a.Info.HasTraitInfo()); + } + } +} diff --git a/OpenRA.Mods.Common/Traits/Guard.cs b/OpenRA.Mods.Common/Traits/Guard.cs index 8bec2c52a6..34ed23a53d 100644 --- a/OpenRA.Mods.Common/Traits/Guard.cs +++ b/OpenRA.Mods.Common/Traits/Guard.cs @@ -20,22 +20,28 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("The player can give this unit the order to follow and protect friendly units with the Guardable trait.")] - public class GuardInfo : ITraitInfo + public class GuardInfo : ITraitInfo, Requires { [VoiceReference] public readonly string Voice = "Action"; public object Create(ActorInitializer init) { return new Guard(this); } } - public class Guard : IResolveOrder, IOrderVoice + public class Guard : IResolveOrder, IOrderVoice, INotifyCreated { readonly GuardInfo info; + IMove move; public Guard(GuardInfo info) { this.info = info; } + public void Created(Actor self) + { + move = self.Trait(); + } + public void ResolveOrder(Actor self, Order order) { if (order.OrderString == "Guard") @@ -51,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits self.SetTargetLine(target, Color.Yellow); var range = target.Actor.Info.TraitInfo().Range; - self.QueueActivity(false, new AttackMoveActivity(self, self.Trait().MoveFollow(self, target, WDist.Zero, range))); + self.QueueActivity(false, new AttackMoveActivity(self, move.MoveFollow(self, target, WDist.Zero, range))); } public string VoicePhraseForOrder(Actor self, Order order) @@ -59,49 +65,4 @@ namespace OpenRA.Mods.Common.Traits return order.OrderString == "Guard" ? info.Voice : null; } } - - public class GuardOrderGenerator : GenericSelectTarget - { - public GuardOrderGenerator(IEnumerable subjects, string order, string cursor, MouseButton button) - : base(subjects, order, cursor, button) { } - - protected override IEnumerable OrderInner(World world, CPos xy, MouseInput mi) - { - var target = FriendlyGuardableUnits(world, mi).FirstOrDefault(); - - if (target == null || Subjects.All(s => s.IsDead)) - yield break; - - world.CancelInputMode(); - foreach (var subject in Subjects) - if (subject != target) - yield return new Order(OrderName, subject, false) { TargetActor = target }; - } - - public override void Tick(World world) - { - if (Subjects.All(s => s.IsDead || !s.Info.HasTraitInfo())) - world.CancelInputMode(); - } - - public override string GetCursor(World world, CPos cell, int2 worldPixel, MouseInput mi) - { - if (!Subjects.Any()) - return null; - - var multiple = Subjects.Count() > 1; - var canGuard = FriendlyGuardableUnits(world, mi) - .Any(a => multiple || a != Subjects.First()); - - return canGuard ? Cursor : "move-blocked"; - } - - static IEnumerable FriendlyGuardableUnits(World world, MouseInput mi) - { - return world.ScreenMap.ActorsAt(mi) - .Where(a => !world.FogObscures(a) && !a.IsDead && - a.AppearsFriendlyTo(world.LocalPlayer.PlayerActor) && - a.Info.HasTraitInfo()); - } - } } diff --git a/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs b/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs index 402221167d..9835255b5c 100644 --- a/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs +++ b/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs @@ -12,6 +12,7 @@ using System; using System.Drawing; using System.Linq; using OpenRA.Graphics; +using OpenRA.Mods.Common.Orders; using OpenRA.Mods.Common.Traits; using OpenRA.Orders; using OpenRA.Primitives;