diff --git a/OpenRA.Mods.Common/Traits/Buildings/PrimaryBuilding.cs b/OpenRA.Mods.Common/Traits/Buildings/PrimaryBuilding.cs index da3558e6ce..089d2dda2d 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/PrimaryBuilding.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/PrimaryBuilding.cs @@ -40,6 +40,8 @@ namespace OpenRA.Mods.Common.Traits public class PrimaryBuilding : INotifyCreated, IIssueOrder, IResolveOrder { + const string OrderID = "PrimaryProducer"; + readonly PrimaryBuildingInfo info; ConditionManager conditionManager; int primaryToken = ConditionManager.InvalidConditionToken; @@ -58,12 +60,12 @@ namespace OpenRA.Mods.Common.Traits IEnumerable IIssueOrder.Orders { - get { yield return new DeployOrderTargeter("PrimaryProducer", 1); } + get { yield return new DeployOrderTargeter(OrderID, 1); } } Order IIssueOrder.IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued) { - if (order.OrderID == "PrimaryProducer") + if (order.OrderID == OrderID) return new Order(order.OrderID, self, false); return null; @@ -71,8 +73,9 @@ namespace OpenRA.Mods.Common.Traits void IResolveOrder.ResolveOrder(Actor self, Order order) { - if (order.OrderString == "PrimaryProducer") - SetPrimaryProducer(self, !IsPrimary); + var forceRallyPoint = RallyPoint.IsForceSet(order); + if (order.OrderString == OrderID || forceRallyPoint) + SetPrimaryProducer(self, !IsPrimary || forceRallyPoint); } public void SetPrimaryProducer(Actor self, bool isPrimary) diff --git a/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs b/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs index fa29583f05..971776c52f 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs @@ -36,10 +36,14 @@ namespace OpenRA.Mods.Common.Traits public class RallyPoint : IIssueOrder, IResolveOrder, ISync, INotifyOwnerChanged, INotifyCreated { + const string OrderID = "SetRallyPoint"; + [Sync] public CPos Location; public RallyPointInfo Info; public string PaletteName { get; private set; } + const uint ForceSet = 1; + public void ResetLocation(Actor self) { Location = self.Location + Info.Offset; @@ -72,23 +76,30 @@ namespace OpenRA.Mods.Common.Traits public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued) { - if (order.OrderID == "SetRallyPoint") - return new Order(order.OrderID, self, false) { TargetLocation = self.World.Map.CellContaining(target.CenterPosition), SuppressVisualFeedback = true }; + if (order.OrderID == OrderID) + return new Order(order.OrderID, self, false) { TargetLocation = self.World.Map.CellContaining(target.CenterPosition), SuppressVisualFeedback = true, + ExtraData = ((RallyPointOrderTargeter)order).ForceSet ? ForceSet : 0 }; return null; } public void ResolveOrder(Actor self, Order order) { - if (order.OrderString == "SetRallyPoint") + if (order.OrderString == OrderID) Location = order.TargetLocation; } + public static bool IsForceSet(Order order) + { + return order.OrderString == OrderID && order.ExtraData == ForceSet; + } + class RallyPointOrderTargeter : IOrderTargeter { public string OrderID { get { return "SetRallyPoint"; } } public int OrderPriority { get { return 0; } } public bool TargetOverridesSelection(TargetModifiers modifiers) { return true; } + public bool ForceSet { get; private set; } public bool CanTarget(Actor self, Target target, List othersAtTarget, ref TargetModifiers modifiers, ref string cursor) { @@ -99,6 +110,15 @@ namespace OpenRA.Mods.Common.Traits if (self.World.Map.Contains(location)) { cursor = "ability"; + + // Notify force-set 'RallyPoint' order watchers with Ctrl and only if this is the only building of its type selected + if (modifiers.HasModifier(TargetModifiers.ForceAttack)) + { + var selfName = self.Info.Name; + if (!self.World.Selection.Actors.Any(a => a.Info.Name == selfName && a.ActorID != self.ActorID)) + ForceSet = true; + } + return true; }