From 5d5f302d07b8ea86677d3739f7a6236b3199f7d3 Mon Sep 17 00:00:00 2001 From: huwpascoe Date: Mon, 6 Oct 2014 00:34:33 +0100 Subject: [PATCH] DevEnableTech now displays from all factions --- OpenRA.Game/Network/Order.cs | 12 ++-- OpenRA.Mods.D2k/Widgets/BuildPaletteWidget.cs | 8 +-- OpenRA.Mods.RA/AI/BaseBuilder.cs | 4 +- OpenRA.Mods.RA/AI/HackyAI.cs | 4 +- OpenRA.Mods.RA/Player/ProductionQueue.cs | 45 ++++++++++++-- .../Properties/ProductionProperties.cs | 4 +- .../Widgets/ProductionPaletteWidget.cs | 8 +-- .../Widgets/ProductionTabsWidget.cs | 61 ++++++++++--------- 8 files changed, 91 insertions(+), 55 deletions(-) diff --git a/OpenRA.Game/Network/Order.cs b/OpenRA.Game/Network/Order.cs index e44c98f647..817845d18d 100755 --- a/OpenRA.Game/Network/Order.cs +++ b/OpenRA.Game/Network/Order.cs @@ -223,19 +223,19 @@ 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, int queueID, string item, int count) { - return new Order("StartProduction", subject, false) { ExtraData = (uint)count, TargetString = item }; + return new Order("StartProduction", subject, false) { TargetString = item, ExtraLocation = new CPos(queueID, count) }; } - public static Order PauseProduction(Actor subject, string item, bool pause) + public static Order PauseProduction(Actor subject, int queueID, string item, bool pause) { - return new Order("PauseProduction", subject, false) { ExtraData = pause ? 1u : 0u, TargetString = item }; + return new Order("PauseProduction", subject, false) { TargetString = item, ExtraLocation = new CPos(queueID, pause ? 1 : 0) }; } - public static Order CancelProduction(Actor subject, string item, int count) + public static Order CancelProduction(Actor subject, int queueID, string item, int count) { - return new Order("CancelProduction", subject, false) { ExtraData = (uint)count, TargetString = item }; + return new Order("CancelProduction", subject, false) { TargetString = item, ExtraLocation = new CPos(queueID, count) }; } } } diff --git a/OpenRA.Mods.D2k/Widgets/BuildPaletteWidget.cs b/OpenRA.Mods.D2k/Widgets/BuildPaletteWidget.cs index fe85d46592..2d89c22fe4 100644 --- a/OpenRA.Mods.D2k/Widgets/BuildPaletteWidget.cs +++ b/OpenRA.Mods.D2k/Widgets/BuildPaletteWidget.cs @@ -383,7 +383,7 @@ namespace OpenRA.Mods.D2k.Widgets if (producing.Paused) { - world.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, item, false)); + world.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, CurrentQueue.QueueID, item, false)); return; } } @@ -412,12 +412,12 @@ namespace OpenRA.Mods.D2k.Widgets Sound.PlayNotification(world.Map.Rules, world.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, world.LocalPlayer.Country.Race); var numberToCancel = Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1; - world.IssueOrder(Order.CancelProduction(CurrentQueue.Actor, item, numberToCancel)); + world.IssueOrder(Order.CancelProduction(CurrentQueue.Actor, CurrentQueue.QueueID, item, numberToCancel)); } else { Sound.PlayNotification(world.Map.Rules, world.LocalPlayer, "Speech", CurrentQueue.Info.OnHoldAudio, world.LocalPlayer.Country.Race); - world.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, item, true)); + world.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, CurrentQueue.QueueID, item, true)); } } } @@ -425,7 +425,7 @@ namespace OpenRA.Mods.D2k.Widgets void StartProduction(World world, string item) { - world.IssueOrder(Order.StartProduction(CurrentQueue.Actor, item, + world.IssueOrder(Order.StartProduction(CurrentQueue.Actor, CurrentQueue.QueueID, item, Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1)); } diff --git a/OpenRA.Mods.RA/AI/BaseBuilder.cs b/OpenRA.Mods.RA/AI/BaseBuilder.cs index c0cd52aa76..45224b4864 100644 --- a/OpenRA.Mods.RA/AI/BaseBuilder.cs +++ b/OpenRA.Mods.RA/AI/BaseBuilder.cs @@ -71,7 +71,7 @@ namespace OpenRA.Mods.RA.AI return false; HackyAI.BotDebug("AI: {0} is starting production of {1}".F(player, item.Name)); - world.IssueOrder(Order.StartProduction(queue.Actor, item.Name, 1)); + world.IssueOrder(Order.StartProduction(queue.Actor, queue.QueueID, item.Name, 1)); } // Production is complete @@ -89,7 +89,7 @@ namespace OpenRA.Mods.RA.AI if (location == null) { HackyAI.BotDebug("AI: {0} has nowhere to place {1}".F(player, currentBuilding.Item)); - world.IssueOrder(Order.CancelProduction(queue.Actor, currentBuilding.Item, 1)); + world.IssueOrder(Order.CancelProduction(queue.Actor, queue.QueueID, currentBuilding.Item, 1)); } else { diff --git a/OpenRA.Mods.RA/AI/HackyAI.cs b/OpenRA.Mods.RA/AI/HackyAI.cs index e614219ae0..c8f8911238 100644 --- a/OpenRA.Mods.RA/AI/HackyAI.cs +++ b/OpenRA.Mods.RA/AI/HackyAI.cs @@ -886,7 +886,7 @@ namespace OpenRA.Mods.RA.AI ChooseUnitToBuild(queue); if (unit != null && Info.UnitsToBuild.Any(u => u.Key == unit.Name)) - world.IssueOrder(Order.StartProduction(queue.Actor, unit.Name, 1)); + world.IssueOrder(Order.StartProduction(queue.Actor, queue.QueueID, unit.Name, 1)); } void BuildUnit(string category, string name) @@ -896,7 +896,7 @@ namespace OpenRA.Mods.RA.AI return; if (Map.Rules.Actors[name] != null) - world.IssueOrder(Order.StartProduction(queue.Actor, name, 1)); + world.IssueOrder(Order.StartProduction(queue.Actor, queue.QueueID, name, 1)); } public void Damaged(Actor self, AttackInfo e) diff --git a/OpenRA.Mods.RA/Player/ProductionQueue.cs b/OpenRA.Mods.RA/Player/ProductionQueue.cs index e37a70ffdf..de1e597908 100644 --- a/OpenRA.Mods.RA/Player/ProductionQueue.cs +++ b/OpenRA.Mods.RA/Player/ProductionQueue.cs @@ -69,7 +69,10 @@ namespace OpenRA.Mods.RA public class ProductionQueue : IResolveOrder, ITick, ITechTreeElement, INotifyOwnerChanged, INotifyKilled, INotifySold, ISync, INotifyTransform { + static int nextQueueID = 1; + public readonly ProductionQueueInfo Info; + public readonly int QueueID; readonly Actor self; // Will change if the owner changes @@ -80,6 +83,7 @@ namespace OpenRA.Mods.RA // A list of things we could possibly build Dictionary produceable; List queue = new List(); + bool allTech = false; // A list of things we are currently building public Actor Actor { get { return self; } } @@ -93,6 +97,8 @@ namespace OpenRA.Mods.RA [Sync] public bool Enabled { get; private set; } public string Race { get; private set; } + public int Name = 0; + public string DisplayName = ""; public ProductionQueue(ActorInitializer init, Actor playerActor, ProductionQueueInfo info) { @@ -103,7 +109,8 @@ namespace OpenRA.Mods.RA developerMode = playerActor.Trait(); Race = init.Contains() ? init.Get() : self.Owner.Country.Race; - Enabled = !info.Race.Any() || info.Race.Contains(Race); + Enabled = (!Info.Race.Any() || Info.Race.Contains(Race)) || developerMode.AllTech; + QueueID = nextQueueID++; CacheProduceables(playerActor); } @@ -129,7 +136,7 @@ namespace OpenRA.Mods.RA if (!Info.Sticky) { Race = self.Owner.Country.Race; - Enabled = !Info.Race.Any() || Info.Race.Contains(Race); + Enabled = (!Info.Race.Any() || Info.Race.Contains(Race)) || developerMode.AllTech; } // Regenerate the produceables and tech tree state @@ -235,6 +242,27 @@ namespace OpenRA.Mods.RA public virtual void Tick(Actor self) { + if (self.World.AllowDevCommands && developerMode.AllTech != allTech) + { + allTech = developerMode.AllTech; + + Enabled = (!Info.Race.Any() || Info.Race.Contains(Race)) || developerMode.AllTech; + OnOwnerChanged(self, self.Owner, self.Owner); + + self.World.AddFrameEndTask((World w) => { + var selected = w.Selection.Contains(self); + var controlgroup = w.Selection.GetControlGroupForActor(self); + + w.Remove(self); // force production palettes to update + w.Add(self); + + if (selected) + w.Selection.Add(w, self); + if (controlgroup.HasValue) + w.Selection.AddToControlGroup(self, controlgroup.Value); + }); + } + while (queue.Count > 0 && BuildableItems().All(b => b.Name != queue[0].Item)) { playerResources.GiveCash(queue[0].TotalCost - queue[0].RemainingCost); // refund what's been paid so far. @@ -254,6 +282,9 @@ namespace OpenRA.Mods.RA { case "StartProduction": { + if (order.ExtraLocation.X != QueueID) + return; + var unit = self.World.Map.Rules.Actors[order.TargetString]; var bi = unit.Traits.Get(); if (!bi.Queue.Contains(Info.Type)) @@ -277,7 +308,7 @@ namespace OpenRA.Mods.RA return; } - var amountToBuild = Math.Min(fromLimit, order.ExtraData); + var amountToBuild = Math.Min(fromLimit, order.ExtraLocation.Y); for (var n = 0; n < amountToBuild; n++) { var hasPlayedSound = false; @@ -305,15 +336,19 @@ namespace OpenRA.Mods.RA case "PauseProduction": { + if (order.ExtraLocation.X != QueueID) + return; if (queue.Count > 0 && queue[0].Item == order.TargetString) - queue[0].Pause(order.ExtraData != 0); + queue[0].Pause(order.ExtraLocation.Y != 0); break; } case "CancelProduction": { - CancelProduction(order.TargetString, order.ExtraData); + if (order.ExtraLocation.X != QueueID) + return; + CancelProduction(order.TargetString, (uint)order.ExtraLocation.Y); break; } } diff --git a/OpenRA.Mods.RA/Scripting/Properties/ProductionProperties.cs b/OpenRA.Mods.RA/Scripting/Properties/ProductionProperties.cs index ed47d59cfd..9c2db972bc 100644 --- a/OpenRA.Mods.RA/Scripting/Properties/ProductionProperties.cs +++ b/OpenRA.Mods.RA/Scripting/Properties/ProductionProperties.cs @@ -140,7 +140,7 @@ namespace OpenRA.Mods.RA.Scripting } foreach (var actorType in actorTypes) - queue.ResolveOrder(self, Order.StartProduction(self, actorType, 1)); + queue.ResolveOrder(self, Order.StartProduction(self, queue.QueueID, actorType, 1)); return true; } @@ -243,7 +243,7 @@ namespace OpenRA.Mods.RA.Scripting foreach (var actorType in actorTypes) { var queue = queues[typeToQueueMap[actorType]]; - queue.ResolveOrder(queue.Actor, Order.StartProduction(queue.Actor, actorType, 1)); + queue.ResolveOrder(queue.Actor, Order.StartProduction(queue.Actor, queue.QueueID, actorType, 1)); } return true; diff --git a/OpenRA.Mods.RA/Widgets/ProductionPaletteWidget.cs b/OpenRA.Mods.RA/Widgets/ProductionPaletteWidget.cs index 59184ef3c0..5d17ec62aa 100644 --- a/OpenRA.Mods.RA/Widgets/ProductionPaletteWidget.cs +++ b/OpenRA.Mods.RA/Widgets/ProductionPaletteWidget.cs @@ -150,14 +150,14 @@ namespace OpenRA.Mods.RA.Widgets { // Resume a paused item Sound.Play(TabClick); - World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, icon.Name, false)); + World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, CurrentQueue.QueueID, icon.Name, false)); } else if (CurrentQueue.BuildableItems().Any(a => a.Name == icon.Name)) { // Queue a new item Sound.Play(TabClick); Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.QueuedAudio, World.LocalPlayer.Country.Race); - World.IssueOrder(Order.StartProduction(CurrentQueue.Actor, icon.Name, + World.IssueOrder(Order.StartProduction(CurrentQueue.Actor, CurrentQueue.QueueID, icon.Name, handleMultiple ? 5 : 1)); } else @@ -174,13 +174,13 @@ namespace OpenRA.Mods.RA.Widgets if (first.Paused || first.Done || first.TotalCost == first.RemainingCost) { Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, World.LocalPlayer.Country.Race); - World.IssueOrder(Order.CancelProduction(CurrentQueue.Actor, icon.Name, + World.IssueOrder(Order.CancelProduction(CurrentQueue.Actor, CurrentQueue.QueueID, icon.Name, handleMultiple ? 5 : 1)); } else { Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.OnHoldAudio, World.LocalPlayer.Country.Race); - World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, icon.Name, true)); + World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, CurrentQueue.QueueID, icon.Name, true)); } } else diff --git a/OpenRA.Mods.RA/Widgets/ProductionTabsWidget.cs b/OpenRA.Mods.RA/Widgets/ProductionTabsWidget.cs index 1eb017e282..2704eead5a 100644 --- a/OpenRA.Mods.RA/Widgets/ProductionTabsWidget.cs +++ b/OpenRA.Mods.RA/Widgets/ProductionTabsWidget.cs @@ -18,42 +18,43 @@ using OpenRA.Widgets; namespace OpenRA.Mods.RA.Widgets { - public class ProductionTab - { - public string Name; - public ProductionQueue Queue; - } - public class ProductionTabGroup { - public List Tabs = new List(); + public List Tabs = new List(); public string Group; - public int NextQueueName = 1; - public bool Alert { get { return Tabs.Any(t => t.Queue.CurrentDone); } } + public bool Alert { get { return Tabs.Any(t => t.CurrentDone); } } public void Update(IEnumerable allQueues) { var queues = allQueues.Where(q => q.Info.Group == Group).ToList(); - var tabs = new List(); + var names = new Queue(Enumerable.Range(1, queues.Count).Except(queues.Select(q => q.Name))); - // Remove stale queues - foreach (var t in Tabs) + // Assign names based on available numbers + foreach (var queue in queues.Where(q => q.Name == 0)) { - if (!queues.Contains(t.Queue)) - continue; - - tabs.Add(t); - queues.Remove(t.Queue); + foreach (var q in queues.Where(q => q.Name > 0)) + if (queue.Actor == q.Actor) + queue.Name = q.Name; + + if (queue.Name == 0) + queue.Name = names.Dequeue(); } - // Add new queues - foreach (var queue in queues) - tabs.Add(new ProductionTab() + Tabs = queues.OrderBy(q => q.Name).ToList(); + + // distinction between tabs of the same actor + foreach (var group in queues.GroupBy(q => q.Actor)) + { + if (group.Count() > 1) { - Name = (NextQueueName++).ToString(), - Queue = queue - }); - Tabs = tabs; + var n = 'a'; + foreach (var queue in group) + queue.DisplayName = queue.Name + (n++).ToString(); + } + else + group.First().DisplayName = group.First().Name.ToString(); + + } } } @@ -98,7 +99,7 @@ namespace OpenRA.Mods.RA.Widgets return true; // Prioritize alerted queues - var queues = Groups[queueGroup].Tabs.Select(t => t.Queue) + var queues = Groups[queueGroup].Tabs.Select(t => t) .OrderByDescending(q => q.CurrentDone ? 1 : 0) .ToList(); @@ -171,13 +172,13 @@ namespace OpenRA.Mods.RA.Widgets { var rect = new Rectangle(origin.X + contentWidth, origin.Y, TabWidth, rb.Height); var hover = !leftHover && !rightHover && Ui.MouseOverWidget == this && rect.Contains(Viewport.LastMousePos); - var baseName = tab.Queue == CurrentQueue ? "button-highlighted" : "button"; + var baseName = tab == CurrentQueue ? "button-highlighted" : "button"; ButtonWidget.DrawBackground(baseName, rect, false, false, hover, false); contentWidth += TabWidth - 1; - var textSize = font.Measure(tab.Name); + var textSize = font.Measure(tab.DisplayName); var position = new int2(rect.X + (rect.Width - textSize.X) / 2, rect.Y + (rect.Height - textSize.Y) / 2); - font.DrawTextWithContrast(tab.Name, position, tab.Queue.CurrentDone ? Color.Gold : Color.White, Color.Black, 1); + font.DrawTextWithContrast(tab.DisplayName, position, tab.CurrentDone ? Color.Gold : Color.White, Color.Black, 1); } Game.Renderer.DisableScissor(); @@ -210,7 +211,7 @@ namespace OpenRA.Mods.RA.Widgets .Select(g => g.Key).FirstOrDefault(); // Queue destroyed, others of same type: switch to another tab - else if (!Groups[queueGroup].Tabs.Select(t => t.Queue).Contains(CurrentQueue)) + else if (!Groups[queueGroup].Tabs.Contains(CurrentQueue)) SelectNextTab(false); } } @@ -264,7 +265,7 @@ namespace OpenRA.Mods.RA.Widgets var offsetloc = mi.Location - new int2(leftButtonRect.Right - 1 + (int)listOffset, leftButtonRect.Y); if (offsetloc.X > 0 && offsetloc.X < contentWidth) { - CurrentQueue = Groups[queueGroup].Tabs[offsetloc.X / (TabWidth - 1)].Queue; + CurrentQueue = Groups[queueGroup].Tabs[offsetloc.X / (TabWidth - 1)]; Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null); }