Skip to content

Commit 1110e16

Browse files
committed
Allow AI build refinery more precisely
1 parent 0431e19 commit 1110e16

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

OpenRA.Mods.CA/Traits/BotModules/BaseBuilderBotModuleCA.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ public class BaseBuilderBotModuleCAInfo : ConditionalTraitInfo
165165
[Desc("Radius in cells around building being considered for sale to scan for units")]
166166
public readonly int SellScanRadius = 8;
167167

168+
[Desc("Delay (in ticks) between finding a good resource point to harvest.")]
169+
public readonly int CheckBestResourceLocationInterval = 123;
170+
168171
public override object Create(ActorInitializer init) { return new BaseBuilderBotModuleCA(init.Self, this); }
169172
}
170173

@@ -192,9 +195,11 @@ public CPos GetRandomBaseCenter()
192195
IPathFinder pathFinder;
193196
IBotPositionsUpdated[] positionsUpdatedModules;
194197
CPos initialBaseCenter;
198+
public CPos? ResourceCenter;
195199

196200
readonly Stack<TraitPair<RallyPoint>> rallyPoints = new();
197201
int assignRallyPointsTicks;
202+
int checkBestResourceLocationTicks;
198203

199204
readonly BaseBuilderQueueManagerCA[] builders; // CA: Uses CA queue manager instead of engine version
200205
int currentBuilderIndex = 0;
@@ -231,6 +236,7 @@ protected override void TraitEnabled(Actor self)
231236
{
232237
// Avoid all AIs reevaluating assignments on the same tick, randomize their initial evaluation delay.
233238
assignRallyPointsTicks = world.LocalRandom.Next(0, Info.AssignRallyPointsInterval);
239+
checkBestResourceLocationTicks = world.LocalRandom.Next(0, Info.CheckBestResourceLocationInterval);
234240

235241
var i = 0;
236242

@@ -281,6 +287,31 @@ void IBotTick.BotTick(IBot bot)
281287
}
282288
}
283289

290+
if (--checkBestResourceLocationTicks <= 0 && resourceLayer != null)
291+
{
292+
checkBestResourceLocationTicks = Info.CheckBestResourceLocationInterval;
293+
294+
Actor bestconyard = null;
295+
var best = int.MinValue;
296+
297+
foreach (var conyard in constructionYardBuildings.Actors.Where(a => !a.IsDead))
298+
{
299+
if (!world.Map.FindTilesInAnnulus(conyard.Location, Info.MinBaseRadius, Info.MaxBaseRadius).Any(a => resourceLayer.GetResource(a).Type != null))
300+
continue;
301+
302+
var suitable = -world.FindActorsInCircle(conyard.CenterPosition, WDist.FromCells(Info.MaxBaseRadius))
303+
.Count(a => (a.Owner.IsAlliedWith(player) && Info.RefineryTypes.Contains(a.Info.Name)) || a.Owner.RelationshipWith(player) == PlayerRelationship.Enemy);
304+
305+
if (suitable > best)
306+
{
307+
best = suitable;
308+
bestconyard = conyard;
309+
}
310+
}
311+
312+
ResourceCenter = bestconyard?.Location;
313+
}
314+
284315
BuildingsBeingProduced.Clear();
285316

286317
// PERF: We tick only one type of valid queue at a time

OpenRA.Mods.CA/Traits/BotModules/BotModuleLogic/BaseBuilderQueueManagerCA.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -526,13 +526,16 @@ ActorInfo ChooseBuildingToBuild(ProductionQueue queue)
526526
// Try and place the refinery near a resource field
527527
if (resourceLayer != null)
528528
{
529-
var nearbyResources = world.Map.FindTilesInAnnulus(baseCenter, baseBuilder.Info.MinBaseRadius, baseBuilder.Info.MaxBaseRadius)
529+
// If we have failed to place to the best refinery point, try and place it near the base center
530+
var resourceCenter = failCount > 0 ? baseCenter : (baseBuilder.ResourceCenter ?? baseCenter);
531+
532+
var nearbyResources = world.Map.FindTilesInAnnulus(resourceCenter, baseBuilder.Info.MinBaseRadius, baseBuilder.Info.MaxBaseRadius)
530533
.Where(a => resourceLayer.GetResource(a).Type != null)
531534
.Shuffle(world.LocalRandom).Take(baseBuilder.Info.MaxResourceCellsToCheck);
532535

533536
foreach (var r in nearbyResources)
534537
{
535-
var found = findPos(baseCenter, r, baseBuilder.Info.MinBaseRadius, baseBuilder.Info.MaxBaseRadius);
538+
var found = findPos(resourceCenter, r, baseBuilder.Info.MinBaseRadius, baseBuilder.Info.MaxBaseRadius);
536539
if (found != null)
537540
return found;
538541
}

0 commit comments

Comments
 (0)