diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 69a8ae50b8..99db31f290 100755 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -121,7 +121,8 @@ namespace OpenRA .OrderByDescending(a => a.Info.Traits.Contains() ? a.Info.Traits.Get().Priority : int.MinValue) .FirstOrDefault(); - return TraitsImplementing() + return TraitsImplementing() + .OrderByDescending( x => x.OrderPriority( this, xy, mi, underCursor ) ) .Select( x => x.IssueOrder( this, xy, mi, underCursor ) ) .FirstOrDefault( x => x != null ); } diff --git a/OpenRA.Game/Traits/Mobile.cs b/OpenRA.Game/Traits/Mobile.cs index bbc4dbbba3..5b180d1750 100644 --- a/OpenRA.Game/Traits/Mobile.cs +++ b/OpenRA.Game/Traits/Mobile.cs @@ -113,22 +113,21 @@ namespace OpenRA.Traits self.CenterLocation = Util.CenterOfCell(fromCell); } + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + // Force move takes precidence + return mi.Modifiers.HasModifier(Modifiers.Alt) ? int.MaxValue : 0; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (Info.OnRails) return null; if (mi.Button == MouseButton.Left) return null; - // force-fire should *always* take precedence over move. - if (mi.Modifiers.HasModifier(Modifiers.Ctrl)) return null; - - if (underCursor != null && underCursor.Owner != null) - { - // force-move - if (!mi.Modifiers.HasModifier(Modifiers.Alt)) return null; - if (!CanEnterCell(underCursor.Location, null, true)) return null; - } - if (MovementSpeedForCell(self, toCell) == 0) return null; /* allow disabling move orders from modifiers */ + if (!CanEnterCell(xy)) + return null; + if (xy == toCell) return null; return new Order("Move", self, xy, mi.Modifiers.HasModifier(Modifiers.Shift)); diff --git a/OpenRA.Game/Traits/PrimaryBuilding.cs b/OpenRA.Game/Traits/PrimaryBuilding.cs index e24a70a292..06a3c4d8f7 100644 --- a/OpenRA.Game/Traits/PrimaryBuilding.cs +++ b/OpenRA.Game/Traits/PrimaryBuilding.cs @@ -24,6 +24,11 @@ namespace OpenRA.Traits { yield return (isPrimary) ? TagType.Primary : TagType.None; } + + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 0; + } public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { diff --git a/OpenRA.Game/Traits/RallyPoint.cs b/OpenRA.Game/Traits/RallyPoint.cs index 2d4affc5b2..6969dd5614 100644 --- a/OpenRA.Game/Traits/RallyPoint.cs +++ b/OpenRA.Game/Traits/RallyPoint.cs @@ -42,6 +42,11 @@ namespace OpenRA.Traits anim.Image, Util.CenterOfCell(rallyPoint)); } + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 0; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button == MouseButton.Left || underCursor != null) return null; diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 4dac916619..934392ff63 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -33,7 +33,11 @@ namespace OpenRA.Traits public interface ITick { void Tick(Actor self); } public interface IRender { IEnumerable Render(Actor self); } - public interface IIssueOrder { Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor ); } + public interface IIssueOrder + { + Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor ); + int OrderPriority( Actor self, int2 xy, MouseInput mi, Actor underCursor ); + } public interface IResolveOrder { void ResolveOrder(Actor self, Order order); } public interface IOrderCursor { string CursorForOrder(Actor self, Order order); } public interface IOrderVoice { string VoicePhraseForOrder(Actor self, Order order); } diff --git a/OpenRA.Mods.RA/AttackBase.cs b/OpenRA.Mods.RA/AttackBase.cs index 7ede247a1e..6b4344f7f0 100644 --- a/OpenRA.Mods.RA/AttackBase.cs +++ b/OpenRA.Mods.RA/AttackBase.cs @@ -174,6 +174,11 @@ namespace OpenRA.Mods.RA return info.FireDelay; } + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return mi.Modifiers.HasModifier(Modifiers.Ctrl) ? int.MaxValue : 1; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button == MouseButton.Left) return null; diff --git a/OpenRA.Mods.RA/C4Demolition.cs b/OpenRA.Mods.RA/C4Demolition.cs index 2f20246588..add89dc374 100644 --- a/OpenRA.Mods.RA/C4Demolition.cs +++ b/OpenRA.Mods.RA/C4Demolition.cs @@ -23,6 +23,11 @@ namespace OpenRA.Mods.RA class C4Demolition : IIssueOrder, IResolveOrder, IOrderCursor, IOrderVoice { + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button != MouseButton.Right) return null; diff --git a/OpenRA.Mods.RA/Cargo.cs b/OpenRA.Mods.RA/Cargo.cs index 6f3d04ad80..40a9fd4921 100644 --- a/OpenRA.Mods.RA/Cargo.cs +++ b/OpenRA.Mods.RA/Cargo.cs @@ -26,6 +26,11 @@ namespace OpenRA.Mods.RA List cargo = new List(); public IEnumerable Passengers { get { return cargo; } } + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button == MouseButton.Right && underCursor == self) diff --git a/OpenRA.Mods.RA/ChronoshiftDeploy.cs b/OpenRA.Mods.RA/ChronoshiftDeploy.cs index ad81291890..4ae64865e0 100644 --- a/OpenRA.Mods.RA/ChronoshiftDeploy.cs +++ b/OpenRA.Mods.RA/ChronoshiftDeploy.cs @@ -33,6 +33,11 @@ namespace OpenRA.Mods.RA chargeTick--; } + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button == MouseButton.Right && xy == self.Location) diff --git a/OpenRA.Mods.RA/EngineerCapture.cs b/OpenRA.Mods.RA/EngineerCapture.cs index 704343e47f..1af055451a 100644 --- a/OpenRA.Mods.RA/EngineerCapture.cs +++ b/OpenRA.Mods.RA/EngineerCapture.cs @@ -19,6 +19,11 @@ namespace OpenRA.Mods.RA class EngineerCaptureInfo : TraitInfo {} class EngineerCapture : IIssueOrder, IResolveOrder, IOrderCursor, IOrderVoice { + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button != MouseButton.Right) return null; diff --git a/OpenRA.Mods.RA/EngineerRepair.cs b/OpenRA.Mods.RA/EngineerRepair.cs index 24fdbc2e36..19998151f9 100644 --- a/OpenRA.Mods.RA/EngineerRepair.cs +++ b/OpenRA.Mods.RA/EngineerRepair.cs @@ -20,6 +20,11 @@ namespace OpenRA.Mods.RA class EngineerRepair : IIssueOrder, IResolveOrder, IOrderCursor, IOrderVoice { + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button != MouseButton.Right) return null; diff --git a/OpenRA.Mods.RA/Harvester.cs b/OpenRA.Mods.RA/Harvester.cs index d85162bcfb..73ddcffbc2 100644 --- a/OpenRA.Mods.RA/Harvester.cs +++ b/OpenRA.Mods.RA/Harvester.cs @@ -91,6 +91,11 @@ namespace OpenRA.Mods.RA proc.Trait().GiveOre(contents.Sum(kv => kv.Key.ValuePerUnit * kv.Value)); contents.Clear(); + } + + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; } public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) diff --git a/OpenRA.Mods.RA/Helicopter.cs b/OpenRA.Mods.RA/Helicopter.cs index 3b9e4d00f0..c3b7a6f6be 100644 --- a/OpenRA.Mods.RA/Helicopter.cs +++ b/OpenRA.Mods.RA/Helicopter.cs @@ -39,10 +39,15 @@ namespace OpenRA.Mods.RA Info = info; } + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + // Force move takes precidence + return mi.Modifiers.HasModifier(Modifiers.Alt) ? int.MaxValue : 0; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button == MouseButton.Left) return null; - if (mi.Modifiers.HasModifier(Modifiers.Ctrl)) return null; if (underCursor == null) if (self.TraitOrDefault().CanEnterCell(xy)) diff --git a/OpenRA.Mods.RA/Minelayer.cs b/OpenRA.Mods.RA/Minelayer.cs index 5e2a361a5e..d8b55daba8 100644 --- a/OpenRA.Mods.RA/Minelayer.cs +++ b/OpenRA.Mods.RA/Minelayer.cs @@ -32,6 +32,11 @@ namespace OpenRA.Mods.RA public int2[] minefield = null; [Sync] int2 minefieldStart; + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button == MouseButton.Right && underCursor == null && mi.Modifiers.HasModifier(Modifiers.Ctrl)) diff --git a/OpenRA.Mods.RA/Passenger.cs b/OpenRA.Mods.RA/Passenger.cs index 61441a8508..12044368ed 100644 --- a/OpenRA.Mods.RA/Passenger.cs +++ b/OpenRA.Mods.RA/Passenger.cs @@ -25,6 +25,11 @@ namespace OpenRA.Mods.RA class Passenger : IIssueOrder, IResolveOrder, IOrderCursor, IOrderVoice { + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button != MouseButton.Right) diff --git a/OpenRA.Mods.RA/Plane.cs b/OpenRA.Mods.RA/Plane.cs index c9b8215085..771a55c207 100644 --- a/OpenRA.Mods.RA/Plane.cs +++ b/OpenRA.Mods.RA/Plane.cs @@ -46,6 +46,12 @@ namespace OpenRA.Mods.RA } } + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + // Force move takes precidence + return mi.Modifiers.HasModifier(Modifiers.Alt) ? int.MaxValue : 0; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button == MouseButton.Left) return null; diff --git a/OpenRA.Mods.RA/Render/RenderSpy.cs b/OpenRA.Mods.RA/Render/RenderSpy.cs index c24ce46113..836005b26c 100755 --- a/OpenRA.Mods.RA/Render/RenderSpy.cs +++ b/OpenRA.Mods.RA/Render/RenderSpy.cs @@ -45,6 +45,11 @@ namespace OpenRA.Mods.RA.Render if (order.OrderString == "Disguise") disguisedAs = order.TargetActor == self ? null : order.TargetActor; } + + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { diff --git a/OpenRA.Mods.RA/Repairable.cs b/OpenRA.Mods.RA/Repairable.cs index 0515e40f37..c37cbb6a75 100644 --- a/OpenRA.Mods.RA/Repairable.cs +++ b/OpenRA.Mods.RA/Repairable.cs @@ -31,11 +31,15 @@ namespace OpenRA.Mods.RA Health = self.Trait(); } + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button != MouseButton.Right) return null; if (underCursor == null) return null; - if (mi.Modifiers.HasModifier(Modifiers.Ctrl)) return null; // force-fire, so don't do this. if (self.Info.Traits.Get().RepairBuildings.Contains(underCursor.Info.Name) && underCursor.Owner == self.Owner) diff --git a/OpenRA.Mods.RA/RepairableNear.cs b/OpenRA.Mods.RA/RepairableNear.cs index 7aaa16de2f..bda386be34 100644 --- a/OpenRA.Mods.RA/RepairableNear.cs +++ b/OpenRA.Mods.RA/RepairableNear.cs @@ -24,6 +24,11 @@ namespace OpenRA.Mods.RA class RepairableNear : IIssueOrder, IResolveOrder, IOrderCursor { + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button != MouseButton.Right) return null; diff --git a/OpenRA.Mods.RA/Spy.cs b/OpenRA.Mods.RA/Spy.cs index 30e21fc1e3..f4c8e67ea9 100644 --- a/OpenRA.Mods.RA/Spy.cs +++ b/OpenRA.Mods.RA/Spy.cs @@ -19,6 +19,11 @@ namespace OpenRA.Mods.RA class Spy : IIssueOrder, IResolveOrder, IOrderCursor { + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button != MouseButton.Right) return null; diff --git a/OpenRA.Mods.RA/Transforms.cs b/OpenRA.Mods.RA/Transforms.cs index a4da5c65d7..81277f1ba8 100644 --- a/OpenRA.Mods.RA/Transforms.cs +++ b/OpenRA.Mods.RA/Transforms.cs @@ -38,6 +38,11 @@ namespace OpenRA.Mods.RA bi = Rules.Info[info.IntoActor].Traits.GetOrDefault(); } + public int OrderPriority(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return 5; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button == MouseButton.Right && self == underCursor)