From 88dfbe657c60f6afb9d8df1ac751952f5584b4b3 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 27 Aug 2010 01:18:09 +1200 Subject: [PATCH] Route "Can i build X" queries via the appropriate ProductionQueue --- OpenRA.Game/Traits/Player/PlaceBuilding.cs | 7 ++-- OpenRA.Game/Traits/Player/ProductionQueue.cs | 22 ++++++++++-- OpenRA.Mods.RA/HackyAI.cs | 31 +++++++++-------- OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs | 35 +++++++------------- 4 files changed, 52 insertions(+), 43 deletions(-) diff --git a/OpenRA.Game/Traits/Player/PlaceBuilding.cs b/OpenRA.Game/Traits/Player/PlaceBuilding.cs index 658791b127..bcb34ca7c9 100644 --- a/OpenRA.Game/Traits/Player/PlaceBuilding.cs +++ b/OpenRA.Game/Traits/Player/PlaceBuilding.cs @@ -103,10 +103,9 @@ namespace OpenRA.Traits { if (p != p.World.LocalPlayer) return 0; // this only matters for local players. - // todo: this will simplify once queues know about what they can build - var queues = p.World.Queries.WithTraitMultiple().Where(a => a.Actor.Owner == p) - .Select(a => a.Trait.Info.Type).Distinct().ToArray(); - return Rules.TechTree.BuildableItems(p, queues).Count(); + return p.World.Queries.WithTraitMultiple() + .Where(a => a.Actor.Owner == p) + .SelectMany(a => a.Trait.BuildableItems()).Distinct().Count(); } } } diff --git a/OpenRA.Game/Traits/Player/ProductionQueue.cs b/OpenRA.Game/Traits/Player/ProductionQueue.cs index 543ec8b0ea..76a52db036 100644 --- a/OpenRA.Game/Traits/Player/ProductionQueue.cs +++ b/OpenRA.Game/Traits/Player/ProductionQueue.cs @@ -46,9 +46,27 @@ namespace OpenRA.Traits return Producing; } + public IEnumerable AllItems() + { + return Rules.TechTree.AllBuildables(Info.Type) + .Where(a => a.Traits.Get().Owner.Contains(self.Owner.Country.Race)) + .OrderBy(a => a.Traits.Get().BuildPaletteOrder); + } + + public IEnumerable BuildableItems() + { + return Rules.TechTree.BuildableItems(self.Owner, Info.Type).Select(b => Rules.Info[b.ToLowerInvariant()]); + } + + public bool CanBuild(ActorInfo actor) + { + var buildings = Rules.TechTree.GatherBuildings( self.Owner ); + return Rules.TechTree.CanBuild(actor, self.Owner, buildings); + } + public void Tick( Actor self ) { - while( Producing.Count > 0 && !Rules.TechTree.BuildableItems( self.Owner, Info.Type ).Contains( Producing[ 0 ].Item ) ) + while( Producing.Count > 0 && !BuildableItems().Any(b => b.Name == Producing[ 0 ].Item) ) { self.Owner.PlayerActor.Trait().GiveCash(Producing[0].TotalCost - Producing[0].RemainingCost); // refund what's been paid so far. FinishProduction(); @@ -71,7 +89,7 @@ namespace OpenRA.Traits var cost = unit.Traits.Contains() ? unit.Traits.Get().Cost : 0; var time = GetBuildTime(order.TargetString); - if (!Rules.TechTree.BuildableItems(order.Player, bi.Queue).Contains(order.TargetString)) + if (!BuildableItems().Any(b => b.Name == order.TargetString)) return; /* you can't build that!! */ bool hasPlayedSound = false; diff --git a/OpenRA.Mods.RA/HackyAI.cs b/OpenRA.Mods.RA/HackyAI.cs index 75cdee8fa8..0ed905c696 100644 --- a/OpenRA.Mods.RA/HackyAI.cs +++ b/OpenRA.Mods.RA/HackyAI.cs @@ -70,23 +70,23 @@ namespace OpenRA.Mods.RA playerResources = p.PlayerActor.Trait(); } - int GetPowerProvidedBy(string building) + int GetPowerProvidedBy(ActorInfo building) { - var bi = Rules.Info[building].Traits.GetOrDefault(); + var bi = building.Traits.GetOrDefault(); if (bi == null) return 0; return bi.Power; } - string ChooseRandomUnitToBuild(string category) + ActorInfo ChooseRandomUnitToBuild(ProductionQueue queue) { - var buildableThings = Rules.TechTree.BuildableItems(p, category).ToArray(); - if (buildableThings.Length == 0) return null; - return buildableThings[random.Next(buildableThings.Length)]; + var buildableThings = queue.BuildableItems(); + if (buildableThings.Count() == 0) return null; + return buildableThings.ElementAtOrDefault(random.Next(buildableThings.Count())); } - string ChooseBuildingToBuild() + ActorInfo ChooseBuildingToBuild(ProductionQueue queue) { - var buildableThings = Rules.TechTree.BuildableItems(p, "Building").ToArray(); + var buildableThings = queue.BuildableItems(); if (playerResources.PowerProvided <= playerResources.PowerDrained * 1.2) /* try to maintain 20% excess power */ { @@ -107,9 +107,9 @@ namespace OpenRA.Mods.RA .Select( a => a.Actor.Info.Name ).ToArray(); foreach (var frac in buildingFractions) - if (buildableThings.Contains(frac.Key)) + if (buildableThings.Any(b => b.Name == frac.Key)) if (myBuildings.Count(a => a == frac.Key) < frac.Value * myBuildings.Length) - return frac.Key; + return Rules.Info[frac.Key]; return null; } @@ -290,10 +290,10 @@ namespace OpenRA.Mods.RA if (queue == null) return; - var unit = ChooseRandomUnitToBuild(category); + var unit = ChooseRandomUnitToBuild(queue); if (unit != null) { - Game.IssueOrder(Order.StartProduction(queue.self, unit, 1)); + Game.IssueOrder(Order.StartProduction(queue.self, unit.Name, 1)); } } @@ -305,12 +305,15 @@ namespace OpenRA.Mods.RA .Select(a => a.Trait) .FirstOrDefault(); + if (queue == null) + return; + var currentBuilding = queue.CurrentItem(); switch (state) { case BuildState.ChooseItem: { - var item = ChooseBuildingToBuild(); + var item = ChooseBuildingToBuild(queue); if (item == null) { state = BuildState.WaitForFeedback; @@ -319,7 +322,7 @@ namespace OpenRA.Mods.RA else { state = BuildState.WaitForProduction; - Game.IssueOrder(Order.StartProduction(queue.self, item, 1)); + Game.IssueOrder(Order.StartProduction(queue.self, item.Name, 1)); } } break; diff --git a/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs b/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs index e0df318145..aa37c43548 100755 --- a/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs +++ b/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs @@ -82,13 +82,10 @@ namespace OpenRA.Mods.RA.Widgets .Select(p => p.Trait); foreach (var queue in queues) - if (!Rules.TechTree.BuildableItems(world.LocalPlayer, queue.Info.Type).Any()) - { - if (CurrentQueue == queue) - CurrentQueue = null; - } - else + if (queue.BuildableItems().Count() > 0) visibleTabs.Add(queue); + else if (CurrentQueue == queue) + CurrentQueue = null; if (CurrentQueue == null) CurrentQueue = queues.FirstOrDefault(); @@ -185,19 +182,15 @@ namespace OpenRA.Mods.RA.Widgets string paletteCollection = "palette-" + world.LocalPlayer.Country.Race; float2 origin = new float2(paletteOrigin.X + 9, paletteOrigin.Y + 9); - var queueName = queue.Info.Type; // Collect info var x = 0; var y = 0; - var buildableItems = Rules.TechTree.BuildableItems(world.LocalPlayer, queueName).ToArray(); - var allBuildables = Rules.TechTree.AllBuildables(queueName) - .Where(a => a.Traits.Get().Owner.Contains(world.LocalPlayer.Country.Race)) - .OrderBy(a => a.Traits.Get().BuildPaletteOrder) - .ToArray(); + var buildableItems = queue.BuildableItems(); + var allBuildables = queue.AllItems(); var overlayBits = new List>(); - numActualRows = Math.Max((allBuildables.Length + Columns - 1) / Columns, Rows); + numActualRows = Math.Max((allBuildables.Count() + Columns - 1) / Columns, Rows); // Palette Background WidgetUtils.DrawRGBA(ChromeProvider.GetImage(paletteCollection, "top"), new float2(origin.X - 9, origin.Y - 9)); @@ -260,10 +253,10 @@ namespace OpenRA.Mods.RA.Widgets } } else - if (!buildableItems.Contains(item.Name) || isBuildingSomething) + if (!buildableItems.Any(a => a.Name == item.Name) || isBuildingSomething) overlayBits.Add(Pair.New(cantBuild.Image, drawPos)); - var closureName = buildableItems.Contains(item.Name) ? item.Name : null; + var closureName = buildableItems.Any(a => a.Name == item.Name) ? item.Name : null; buttons.Add(Pair.New(new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height), HandleClick(closureName, world))); if (++x == Columns) { x = 0; y++; } @@ -444,9 +437,8 @@ namespace OpenRA.Mods.RA.Widgets var tooltip = info.Traits.Get(); var buildable = info.Traits.Get(); var cost = info.Traits.Get().Cost; - var buildings = Rules.TechTree.GatherBuildings( pl ); - var canBuildThis = Rules.TechTree.CanBuild(info, pl, buildings); - + var canBuildThis = CurrentQueue.CanBuild(info); + var longDescSize = Game.Renderer.RegularFont.Measure(tooltip.Description.Replace("\\n", "\n")).Y; if (!canBuildThis) longDescSize += 8; @@ -494,15 +486,12 @@ namespace OpenRA.Mods.RA.Widgets bool DoBuildingHotkey(char c, World world) { if (!paletteOpen) return false; - - var buildable = Rules.TechTree.BuildableItems(world.LocalPlayer, CurrentQueue.Info.Type); - - var toBuild = buildable.FirstOrDefault(b => Rules.Info[b.ToLowerInvariant()].Traits.Get().Hotkey == c.ToString()); + var toBuild = CurrentQueue.BuildableItems().FirstOrDefault(b => b.Traits.Get().Hotkey == c.ToString()); if ( toBuild != null ) { Sound.Play(TabClick); - HandleBuildPalette(world, toBuild, true); + HandleBuildPalette(world, toBuild.Name, true); return true; }