diff --git a/OpenRA.Mods.Common/Traits/BotModules/BaseBuilderBotModule.cs b/OpenRA.Mods.Common/Traits/BotModules/BaseBuilderBotModule.cs index 4cf4d2f8e6..fc65482d82 100644 --- a/OpenRA.Mods.Common/Traits/BotModules/BaseBuilderBotModule.cs +++ b/OpenRA.Mods.Common/Traits/BotModules/BaseBuilderBotModule.cs @@ -150,8 +150,8 @@ namespace OpenRA.Mods.Common.Traits readonly Player player; PowerManager playerPower; PlayerResources playerResources; + IResourceLayer resourceLayer; IBotPositionsUpdated[] positionsUpdatedModules; - BitArray resourceTypeIndices; CPos initialBaseCenter; CPos defenseCenter; @@ -168,20 +168,16 @@ namespace OpenRA.Mods.Common.Traits { playerPower = self.Owner.PlayerActor.TraitOrDefault(); playerResources = self.Owner.PlayerActor.Trait(); + resourceLayer = self.World.WorldActor.TraitOrDefault(); positionsUpdatedModules = self.Owner.PlayerActor.TraitsImplementing().ToArray(); } protected override void TraitEnabled(Actor self) { - var terrainInfo = world.Map.Rules.TerrainInfo; - resourceTypeIndices = new BitArray(terrainInfo.TerrainTypes.Length); // Big enough - foreach (var t in world.Map.Rules.Actors["world"].TraitInfos()) - resourceTypeIndices.Set(terrainInfo.GetTerrainIndex(t.TerrainType), true); - foreach (var building in Info.BuildingQueues) - builders.Add(new BaseBuilderQueueManager(this, building, player, playerPower, playerResources, resourceTypeIndices)); + builders.Add(new BaseBuilderQueueManager(this, building, player, playerPower, playerResources, resourceLayer)); foreach (var defense in Info.DefenseQueues) - builders.Add(new BaseBuilderQueueManager(this, defense, player, playerPower, playerResources, resourceTypeIndices)); + builders.Add(new BaseBuilderQueueManager(this, defense, player, playerPower, playerResources, resourceLayer)); } void IBotPositionsUpdated.UpdatedBaseCenter(CPos newLocation) diff --git a/OpenRA.Mods.Common/Traits/BotModules/BotModuleLogic/BaseBuilderQueueManager.cs b/OpenRA.Mods.Common/Traits/BotModules/BotModuleLogic/BaseBuilderQueueManager.cs index c6fbb4af8b..f4635ce6b4 100644 --- a/OpenRA.Mods.Common/Traits/BotModules/BotModuleLogic/BaseBuilderQueueManager.cs +++ b/OpenRA.Mods.Common/Traits/BotModules/BotModuleLogic/BaseBuilderQueueManager.cs @@ -26,6 +26,7 @@ namespace OpenRA.Mods.Common.Traits readonly Player player; readonly PowerManager playerPower; readonly PlayerResources playerResources; + readonly IResourceLayer resourceLayer; int waitTicks; Actor[] playerBuildings; @@ -35,22 +36,21 @@ namespace OpenRA.Mods.Common.Traits int cachedBases; int cachedBuildings; int minimumExcessPower; - BitArray resourceTypeIndices; WaterCheck waterState = WaterCheck.NotChecked; public BaseBuilderQueueManager(BaseBuilderBotModule baseBuilder, string category, Player p, PowerManager pm, - PlayerResources pr, BitArray resourceTypeIndices) + PlayerResources pr, IResourceLayer rl) { this.baseBuilder = baseBuilder; world = p.World; player = p; playerPower = pm; playerResources = pr; + resourceLayer = rl; this.category = category; failRetryTicks = baseBuilder.Info.StructureProductionResumeDelay; minimumExcessPower = baseBuilder.Info.MinimumExcessPower; - this.resourceTypeIndices = resourceTypeIndices; if (!baseBuilder.Info.NavalProductionTypes.Any()) waterState = WaterCheck.DontCheck; } @@ -418,15 +418,18 @@ namespace OpenRA.Mods.Common.Traits case BuildingType.Refinery: // Try and place the refinery near a resource field - var nearbyResources = world.Map.FindTilesInAnnulus(baseCenter, baseBuilder.Info.MinBaseRadius, baseBuilder.Info.MaxBaseRadius) - .Where(a => resourceTypeIndices.Get(world.Map.GetTerrainIndex(a))) - .Shuffle(world.LocalRandom).Take(baseBuilder.Info.MaxResourceCellsToCheck); - - foreach (var r in nearbyResources) + if (resourceLayer != null) { - var found = findPos(baseCenter, r, baseBuilder.Info.MinBaseRadius, baseBuilder.Info.MaxBaseRadius); - if (found != null) - return found; + var nearbyResources = world.Map.FindTilesInAnnulus(baseCenter, baseBuilder.Info.MinBaseRadius, baseBuilder.Info.MaxBaseRadius) + .Where(a => resourceLayer.GetResource(a).Type != null) + .Shuffle(world.LocalRandom).Take(baseBuilder.Info.MaxResourceCellsToCheck); + + foreach (var r in nearbyResources) + { + var found = findPos(baseCenter, r, baseBuilder.Info.MinBaseRadius, baseBuilder.Info.MaxBaseRadius); + if (found != null) + return found; + } } // Try and find a free spot somewhere else in the base