diff --git a/OpenRA.Game/Network/Order.cs b/OpenRA.Game/Network/Order.cs index dc20d57670..035dc77d44 100644 --- a/OpenRA.Game/Network/Order.cs +++ b/OpenRA.Game/Network/Order.cs @@ -231,9 +231,9 @@ namespace OpenRA return new Order("Command", null, false) { IsImmediate = true, TargetString = text }; } - public static Order StartProduction(Actor subject, string item, int count) + public static Order StartProduction(Actor subject, string item, int count, bool queued = true) { - return new Order("StartProduction", subject, false) { ExtraData = (uint)count, TargetString = item }; + return new Order("StartProduction", subject, queued) { ExtraData = (uint)count, TargetString = item }; } public static Order PauseProduction(Actor subject, string item, bool pause) diff --git a/OpenRA.Mods.Common/Traits/Player/ParallelProductionQueue.cs b/OpenRA.Mods.Common/Traits/Player/ParallelProductionQueue.cs index 040ca96520..774d28ca05 100644 --- a/OpenRA.Mods.Common/Traits/Player/ParallelProductionQueue.cs +++ b/OpenRA.Mods.Common/Traits/Player/ParallelProductionQueue.cs @@ -50,6 +50,12 @@ namespace OpenRA.Mods.Common.Traits return Queue.Contains(item); } + protected override void BeginProduction(ProductionItem item, bool hasPriority) + { + // Ignore `hasPriority` as it's not relevant in parallel production context. + Queue.Add(item); + } + public override int RemainingTimeActual(ProductionItem item) { var parallelBuilds = Queue.FindAll(i => !i.Paused && !i.Done) diff --git a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs index 52440f2d04..ddd289b349 100644 --- a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs +++ b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs @@ -406,7 +406,7 @@ namespace OpenRA.Mods.Common.Traits else if (!hasPlayedSound && time > 0) hasPlayedSound = Game.Sound.PlayNotification(rules, self.Owner, "Speech", Info.BlockedAudio, self.Owner.Faction.InternalName); } - }))); + })), !order.Queued); } break; @@ -470,9 +470,12 @@ namespace OpenRA.Mods.Common.Traits Queue.Remove(item); } - protected void BeginProduction(ProductionItem item) + protected virtual void BeginProduction(ProductionItem item, bool hasPriority) { - Queue.Add(item); + if (hasPriority && Queue.Count > 1) + Queue.Insert(1, item); + else + Queue.Add(item); } public virtual int RemainingTimeActual(ProductionItem item) diff --git a/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs b/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs index 6e1c90d3c7..dde7bef230 100644 --- a/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs @@ -259,7 +259,7 @@ namespace OpenRA.Mods.Common.Widgets } } - bool HandleLeftClick(ProductionItem item, ProductionIcon icon, int handleCount) + bool HandleLeftClick(ProductionItem item, ProductionIcon icon, int handleCount, Modifiers modifiers) { if (PickUpCompletedBuildingIcon(icon, item)) { @@ -287,7 +287,8 @@ namespace OpenRA.Mods.Common.Widgets if (canQueue) { - World.IssueOrder(Order.StartProduction(CurrentQueue.Actor, icon.Name, handleCount)); + var queued = !modifiers.HasModifier(Modifiers.Ctrl); + World.IssueOrder(Order.StartProduction(CurrentQueue.Actor, icon.Name, handleCount, queued)); return true; } } @@ -338,7 +339,7 @@ namespace OpenRA.Mods.Common.Widgets // PERF: avoid an unnecessary enumeration by casting back to its known type var cancelCount = modifiers.HasModifier(Modifiers.Ctrl) ? ((List)CurrentQueue.AllQueued()).Count : startCount; var item = icon.Queued.FirstOrDefault(); - var handled = btn == MouseButton.Left ? HandleLeftClick(item, icon, startCount) + var handled = btn == MouseButton.Left ? HandleLeftClick(item, icon, startCount, modifiers) : btn == MouseButton.Right ? HandleRightClick(item, icon, cancelCount) : btn == MouseButton.Middle ? HandleMiddleClick(item, icon, cancelCount) : false;