Skip to content

Commit

Permalink
Fix bug that AI producion pause when there is too many unit in UnitDe…
Browse files Browse the repository at this point in the history
…lays
  • Loading branch information
dnqbob committed Jul 18, 2023
1 parent 58e8b12 commit ca06353
Showing 1 changed file with 34 additions and 42 deletions.
76 changes: 34 additions & 42 deletions OpenRA.Mods.Common/Traits/BotModules/UnitBuilderBotModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,11 @@ void IBotTick.BotTick(IBot bot)
queuedBuildRequests.Remove(buildRequest);
}

foreach (var q in Info.UnitQueues)
BuildUnit(bot, q, idleUnitCount < Info.IdleBaseUnitsMaximum);
if (Info.IdleBaseUnitsMaximum > idleUnitCount)
{
foreach (var q in Info.UnitQueues)
BuildRandomUnit(bot, q);
}
}
}

Expand All @@ -101,36 +104,22 @@ int IBotRequestUnitProduction.RequestedProductionCount(IBot bot, string requeste
return queuedBuildRequests.Count(r => r == requestedActor);
}

void BuildUnit(IBot bot, string category, bool buildRandom)
void BuildRandomUnit(IBot bot, string category)
{
if (Info.UnitsToBuild.Count == 0)
return;

// Pick a free queue
var queue = AIUtils.FindQueues(player, category).FirstOrDefault(q => !q.AllQueued().Any());
if (queue == null)
return;

var unit = buildRandom ?
ChooseRandomUnitToBuild(queue) :
ChooseUnitToBuild(queue);
var unit = ChooseRandomUnitToBuild(queue);

if (unit == null)
return;

var name = unit.Name;

if (Info.UnitsToBuild != null && !Info.UnitsToBuild.ContainsKey(name))
return;

if (Info.UnitDelays != null &&
Info.UnitDelays.TryGetValue(name, out var delay) &&
delay > world.WorldTick)
return;

if (Info.UnitLimits != null &&
Info.UnitLimits.TryGetValue(name, out var limit) &&
world.Actors.Count(a => a.Owner == player && a.Info.Name == name) >= limit)
return;

bot.QueueOrder(Order.StartProduction(queue.Actor, name, 1));
bot.QueueOrder(Order.StartProduction(queue.Actor, unit.Name, 1));
}

// In cases where we want to build a specific unit but don't know the queue name (because there's more than one possibility)
Expand Down Expand Up @@ -161,32 +150,35 @@ void BuildUnit(IBot bot, string name)

ActorInfo ChooseRandomUnitToBuild(ProductionQueue queue)
{
var buildableThings = queue.BuildableItems();
if (!buildableThings.Any())
var buildableThings = queue.BuildableItems().Shuffle(world.LocalRandom).ToArray();
if (buildableThings.Length == 0)
return null;

var unit = buildableThings.Random(world.LocalRandom);
return HasAdequateAirUnitReloadBuildings(unit) ? unit : null;
}
var allUnits = world.Actors.Where(a => a.Owner == player && Info.UnitsToBuild.ContainsKey(a.Info.Name) && !a.IsDead).ToArray();

ActorInfo ChooseUnitToBuild(ProductionQueue queue)
{
var buildableThings = queue.BuildableItems();
if (!buildableThings.Any())
return null;
ActorInfo desiredUnit = null;
var desiredError = int.MaxValue;
foreach (var unit in buildableThings)
{
if (!Info.UnitsToBuild.ContainsKey(unit.Name) || (Info.UnitDelays != null && Info.UnitDelays.TryGetValue(unit.Name, out var delay) && delay > world.WorldTick))
continue;

var myUnits = player.World
.ActorsHavingTrait<IPositionable>()
.Where(a => a.Owner == player)
.Select(a => a.Info.Name).ToList();
var unitCount = allUnits.Count(a => a.Info.Name == unit.Name);
if (Info.UnitLimits != null && Info.UnitLimits.TryGetValue(unit.Name, out var count) && unitCount >= count)
continue;

foreach (var unit in Info.UnitsToBuild.Shuffle(world.LocalRandom))
if (buildableThings.Any(b => b.Name == unit.Key))
if (myUnits.Count(a => a == unit.Key) * 100 < unit.Value * myUnits.Count)
if (HasAdequateAirUnitReloadBuildings(world.Map.Rules.Actors[unit.Key]))
return world.Map.Rules.Actors[unit.Key];
var error = allUnits.Length > 0 ? unitCount * 100 / allUnits.Length - Info.UnitsToBuild[unit.Name] : -1;
if (error < 0)
return HasAdequateAirUnitReloadBuildings(unit) ? unit : null;

if (error < desiredError)
{
desiredError = error;
desiredUnit = unit;
}
}

return null;
return HasAdequateAirUnitReloadBuildings(desiredUnit) ? desiredUnit : null;
}

// For mods like RA (number of RearmActors must match the number of aircraft)
Expand Down

0 comments on commit ca06353

Please sign in to comment.