Check for consecutive failures to place a structure.

After 3 consecutive failed attempts, wait one minute before resetting the counter and trying again.
This commit is contained in:
reaperrr
2015-07-21 07:27:10 +02:00
parent 6ff394991d
commit 0a5b812bb7
2 changed files with 20 additions and 3 deletions

View File

@@ -28,6 +28,8 @@ namespace OpenRA.Mods.Common.AI
int waitTicks; int waitTicks;
Actor[] playerBuildings; Actor[] playerBuildings;
int failCount;
int failRetryTicks;
public BaseBuilder(HackyAI ai, string category, Player p, PowerManager pm, PlayerResources pr) public BaseBuilder(HackyAI ai, string category, Player p, PowerManager pm, PlayerResources pr)
{ {
@@ -37,10 +39,15 @@ namespace OpenRA.Mods.Common.AI
playerPower = pm; playerPower = pm;
playerResources = pr; playerResources = pr;
this.category = category; this.category = category;
failRetryTicks = ai.Info.StructureProductionResumeDelay;
} }
public void Tick() public void Tick()
{ {
// If failed to place something N consecutive times, wait M ticks until resuming building production
if (failCount >= ai.Info.MaximumFailedPlacementAttempts && --failRetryTicks <= 0)
failCount = 0;
// Only update once per second or so // Only update once per second or so
if (--waitTicks > 0) if (--waitTicks > 0)
return; return;
@@ -63,7 +70,7 @@ namespace OpenRA.Mods.Common.AI
var currentBuilding = queue.CurrentItem(); var currentBuilding = queue.CurrentItem();
// Waiting to build something // Waiting to build something
if (currentBuilding == null) if (currentBuilding == null && failCount < ai.Info.MaximumFailedPlacementAttempts)
{ {
var item = ChooseBuildingToBuild(queue); var item = ChooseBuildingToBuild(queue);
if (item == null) if (item == null)
@@ -77,6 +84,7 @@ namespace OpenRA.Mods.Common.AI
// Production is complete // Production is complete
// Choose the placement logic // Choose the placement logic
// HACK: HACK HACK HACK // HACK: HACK HACK HACK
// TODO: Derive this from BuildingCommonNames instead
var type = BuildingType.Building; var type = BuildingType.Building;
if (world.Map.Rules.Actors[currentBuilding.Item].Traits.Contains<AttackBaseInfo>()) if (world.Map.Rules.Actors[currentBuilding.Item].Traits.Contains<AttackBaseInfo>())
type = BuildingType.Defense; type = BuildingType.Defense;
@@ -88,9 +96,11 @@ namespace OpenRA.Mods.Common.AI
{ {
HackyAI.BotDebug("AI: {0} has nowhere to place {1}".F(player, currentBuilding.Item)); HackyAI.BotDebug("AI: {0} has nowhere to place {1}".F(player, currentBuilding.Item));
ai.QueueOrder(Order.CancelProduction(queue.Actor, currentBuilding.Item, 1)); ai.QueueOrder(Order.CancelProduction(queue.Actor, currentBuilding.Item, 1));
failCount += failCount;
} }
else else
{ {
failCount = 0;
ai.QueueOrder(new Order("PlaceBuilding", player.PlayerActor, false) ai.QueueOrder(new Order("PlaceBuilding", player.PlayerActor, false)
{ {
TargetLocation = location.Value, TargetLocation = location.Value,

View File

@@ -49,6 +49,9 @@ namespace OpenRA.Mods.Common.AI
[Desc("Minimum delay (in ticks) between creating squads.")] [Desc("Minimum delay (in ticks) between creating squads.")]
public readonly int MinimumAttackForceDelay = 0; public readonly int MinimumAttackForceDelay = 0;
[Desc("Minimum portion of pending orders to issue each tick (e.g. 5 issues at least 1/5th of all pending orders). Excess orders remain queued for subsequent ticks.")]
public readonly int MinOrderQuotientPerTick = 5;
[Desc("Minimum excess power the AI should try to maintain.")] [Desc("Minimum excess power the AI should try to maintain.")]
public readonly int MinimumExcessPower = 0; public readonly int MinimumExcessPower = 0;
@@ -58,8 +61,12 @@ namespace OpenRA.Mods.Common.AI
[Desc("How long to wait (in ticks) between structure production checks ticks when actively building things.")] [Desc("How long to wait (in ticks) between structure production checks ticks when actively building things.")]
public readonly int StructureProductionActiveDelay = 10; public readonly int StructureProductionActiveDelay = 10;
[Desc("Minimum portion of pending orders to issue each tick (e.g. 5 issues at least 1/5th of all pending orders). Excess orders remain queued for subsequent ticks.")] [Desc("How long to wait (in ticks) until retrying to build structure after the last 3 consecutive attempts failed.")]
public readonly int MinOrderQuotientPerTick = 5; public readonly int StructureProductionResumeDelay = 1500;
[Desc("After how many failed attempts to place a structure should AI give up and wait",
"for StructureProductionResumeDelay before retrying.")]
public readonly int MaximumFailedPlacementAttempts = 3;
[Desc("Minimum range at which to build defensive structures near a combat hotspot.")] [Desc("Minimum range at which to build defensive structures near a combat hotspot.")]
public readonly int MinimumDefenseRadius = 5; public readonly int MinimumDefenseRadius = 5;