Further improved building placement failure check

Since naval structures have their own safety measures now and therefore shouldn't count towards failCount under normal circumstances, we can now assume that 3 consecutive placement failures mean lack of space. Therefore, rather than unconditionally resetting the failCount and retry every N ticks, we now cache the number of buildings and construction yards at the time of the 3rd consecutive failure and if the number of buildings hasn't decreased and number of construction yards not increased, we assume there is still not enough space and reset the retry delay instead.
This commit is contained in:
reaperrr
2015-07-25 09:49:38 +02:00
parent 65a6489ef1
commit c7af9c180e

View File

@@ -33,6 +33,7 @@ namespace OpenRA.Mods.Common.AI
int failCount;
int failRetryTicks;
int cachedBases;
int cachedBuildings;
public BaseBuilder(HackyAI ai, string category, Player p, PowerManager pm, PlayerResources pr)
{
@@ -49,7 +50,23 @@ namespace OpenRA.Mods.Common.AI
{
// If failed to place something N consecutive times, wait M ticks until resuming building production
if (failCount >= ai.Info.MaximumFailedPlacementAttempts && --failRetryTicks <= 0)
failCount = 0;
{
var currentBuildings = world.ActorsWithTrait<Building>()
.Where(a => a.Actor.Owner == player)
.Count();
var baseProviders = world.ActorsWithTrait<BaseBuilding>()
.Where(a => a.Actor.Owner == player)
.Count();
// Only bother resetting failCount if either a) the number of buildings has decreased since last failure M ticks ago,
// or b) number of BaseProviders (construction yard or similar) has increased since then.
// Otherwise reset failRetryTicks instead to wait again.
if (currentBuildings < cachedBuildings || baseProviders > cachedBases)
failCount = 0;
else
failRetryTicks = ai.Info.StructureProductionResumeDelay;
}
// Only update once per second or so
if (--waitTicks > 0)
@@ -119,6 +136,18 @@ namespace OpenRA.Mods.Common.AI
HackyAI.BotDebug("AI: {0} has nowhere to place {1}".F(player, currentBuilding.Item));
ai.QueueOrder(Order.CancelProduction(queue.Actor, currentBuilding.Item, 1));
failCount += failCount;
// If we just reached the maximum fail count, cache the number of current structures
if (failCount == ai.Info.MaximumFailedPlacementAttempts)
{
cachedBuildings = world.ActorsWithTrait<Building>()
.Where(a => a.Actor.Owner == player)
.Count();
cachedBases = world.ActorsWithTrait<BaseBuilding>()
.Where(a => a.Actor.Owner == player)
.Count();
}
}
else
{