bool TickQueue(IBot bot, ProductionQueue queue)
{
var currentBuilding = queue.AllQueued().FirstOrDefault();
// Waiting to build something
if (currentBuilding == null && failCount < baseBuilder.Info.MaximumFailedPlacementAttempts)
{
var item = ChooseBuildingToBuild(queue);
if (item == null)
{
return(false);
}
bot.QueueOrder(Order.StartProduction(queue.Actor, item.Name, 1));
}
else if (currentBuilding != null && currentBuilding.Done)
{
// Production is complete
// Choose the placement logic
// HACK: HACK HACK HACK
// TODO: Derive this from BuildingCommonNames instead
var type = BuildingType.Building;
CPos? location = null;
string orderString = "PlaceBuilding";
// Check if Building is a plug for other Building
var actorInfo = world.Map.Rules.Actors[currentBuilding.Item];
var plugInfo = actorInfo.TraitInfoOrDefault <PlugInfo>();
if (plugInfo != null)
{
var possibleBuilding = world.ActorsWithTrait <Pluggable>().FirstOrDefault(a =>
a.Actor.Owner == player && a.Trait.AcceptsPlug(a.Actor, plugInfo.Type));
if (possibleBuilding.Actor != null)
{
orderString = "PlacePlug";
location = possibleBuilding.Actor.Location + possibleBuilding.Trait.Info.Offset;
}
}
else
{
// Check if Building is a defense and if we should place it towards the enemy or not.
if (actorInfo.HasTraitInfo <AttackBaseInfo>() && world.LocalRandom.Next(100) < baseBuilder.Info.PlaceDefenseTowardsEnemyChance)
{
type = BuildingType.Defense;
}
else if (baseBuilder.Info.RefineryTypes.Contains(actorInfo.Name))
{
type = BuildingType.Refinery;
}
location = ChooseBuildLocation(currentBuilding.Item, true, type);
}
if (location == null)
{
AIUtils.BotDebug("{0} has nowhere to place {1}".F(player, currentBuilding.Item));
bot.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 == baseBuilder.Info.MaximumFailedPlacementAttempts)
{
cachedBuildings = world.ActorsHavingTrait <Building>().Count(a => a.Owner == player);
cachedBases = world.ActorsHavingTrait <BaseProvider>().Count(a => a.Owner == player);
}
}
else
{
failCount = 0;
bot.QueueOrder(new Order(orderString, player.PlayerActor, Target.FromCell(world, location.Value), false)
{
// Building to place
TargetString = currentBuilding.Item,
// Actor ID to associate the placement with
ExtraData = queue.Actor.ActorID,
SuppressVisualFeedback = true
});
return(true);
}
}
return(true);
}