// Find any MCV and deploy them at a sensible location. void DeployMcv(IBot bot, Actor mcv, bool move) { if (move) { // If we lack a base, we need to make sure we don't restrict deployment of the MCV to the base! var restrictToBase = Info.RestrictMCVDeploymentFallbackToBase && AIUtils.CountBuildingByCommonName(Info.ConstructionYardTypes, player) > 0; var transformsInfo = mcv.Info.TraitInfo <TransformsInfo>(); var desiredLocation = ChooseMcvDeployLocation(transformsInfo.IntoActor, transformsInfo.Offset, restrictToBase); if (desiredLocation == null) { return; } bot.QueueOrder(new Order("Move", mcv, Target.FromCell(world, desiredLocation.Value), true)); } // If the MCV has to move first, we can't be sure it reaches the destination alive, so we only // update base and defense center if the MCV is deployed immediately (i.e. at game start). // TODO: This could be adressed via INotifyTransform. foreach (var n in notifyPositionsUpdated) { n.UpdatedBaseCenter(mcv.Location); n.UpdatedDefenseCenter(mcv.Location); } bot.QueueOrder(new Order("DeployTransform", mcv, true)); }
public int NumBuildingsBuiltBuildingOrOrdered(ActorInfo building) { var nameComparisons = new HashSet <string>() { building.Name.ToLowerInvariant(), building.Name.ToLowerInvariant().Replace(".constructing", string.Empty) }; var numBuildings = AIUtils.CountBuildingByCommonName(nameComparisons, player); return(numBuildings + NumBuildingsOrdered(building)); }
bool ShouldBuildMCV() { // Only build MCV if we don't already have one in the field. var allowedToBuildMCV = AIUtils.CountActorByCommonName(Info.McvTypes, player) == 0; if (!allowedToBuildMCV) { return(false); } // Build MCV if we don't have the desired number of construction yards, unless we have no factory (can't build it). return(AIUtils.CountBuildingByCommonName(Info.ConstructionYardTypes, player) < Info.MinimumConstructionYardCount && AIUtils.CountBuildingByCommonName(Info.McvFactoryTypes, player) > 0); }
// Find any BEV and deploy them at a sensible location. void DeployBev(IBot bot, Actor bev, bool move) { if (move) { // If we lack a base, we need to make sure we don't restrict deployment of the MCV to the base! var restrictToBase = Info.RestrictBevDeploymentFallbackToBase && AIUtils.CountBuildingByCommonName(Info.ConstructionYardTypes, player) > 0; var transformsInfo = bev.Info.TraitInfo <TransformsInfo>(); var desiredLocation = ChooseBevDeployLocation(transformsInfo.IntoActor, transformsInfo.Offset, restrictToBase); if (desiredLocation == null) { return; } bot.QueueOrder(new Order("Move", bev, Target.FromCell(world, desiredLocation.Value), true)); } bot.QueueOrder(new Order("DeployTransform", bev, true)); }
protected void ProduceHarvesters(IBot bot) { // Less harvesters than refineries - build a new harvester var unitBuilder = requestUnitProduction.FirstOrDefault(Exts.IsTraitEnabled); if (unitBuilder != null && Info.HarvesterTypes.Any()) { var harvInfo = AIUtils.GetInfoByCommonName(Info.HarvesterTypes, player); var numHarvesters = AIUtils.CountActorByCommonName(Info.HarvesterTypes, player); if (numHarvesters >= Info.MaxHarvesters) { return; } var harvCountTooLow = numHarvesters < AIUtils.CountBuildingByCommonName(Info.RefineryTypes, player) * Info.HarvestersPerRefinery; if (harvCountTooLow && unitBuilder.RequestedProductionCount(bot, harvInfo.Name) == 0) { unitBuilder.RequestUnitProduction(bot, harvInfo.Name); } } }
void IBotTick.BotTick(IBot bot) { if (resourceLayer == null || resourceLayer.IsEmpty) { return; } if (--scanForIdleHarvestersTicks > 0) { return; } var toRemove = harvesters.Keys.Where(unitCannotBeOrdered).ToList(); foreach (var a in toRemove) { harvesters.Remove(a); } scanForIdleHarvestersTicks = Info.ScanForIdleHarvestersInterval; // Find new harvesters // TODO: Look for a more performance-friendly way to update this list var newHarvesters = world.ActorsHavingTrait <Harvester>().Where(a => a.Owner == player && !harvesters.ContainsKey(a)); foreach (var a in newHarvesters) { harvesters[a] = new HarvesterTraitWrapper(a); } // Find idle harvesters and give them orders: foreach (var h in harvesters) { if (!h.Key.IsIdle) { // Ignore this actor if FindAndDeliverResources is working fine or it is performing a different activity if (!(h.Key.CurrentActivity is FindAndDeliverResources act) || !act.LastSearchFailed) { continue; } } if (h.Value.Parachutable != null && h.Value.Parachutable.IsInAir) { continue; } // Tell the idle harvester to quit slacking: var newSafeResourcePatch = FindNextResource(h.Key, h.Value); AIUtils.BotDebug("AI: Harvester {0} is idle. Ordering to {1} in search for new resources.".F(h.Key, newSafeResourcePatch)); bot.QueueOrder(new Order("Harvest", h.Key, newSafeResourcePatch, false)); } // Less harvesters than refineries - build a new harvester var unitBuilder = requestUnitProduction.FirstOrDefault(Exts.IsTraitEnabled); if (unitBuilder != null && Info.HarvesterTypes.Any()) { var harvInfo = AIUtils.GetInfoByCommonName(Info.HarvesterTypes, player); var harvCountTooLow = AIUtils.CountActorByCommonName(Info.HarvesterTypes, player) < AIUtils.CountBuildingByCommonName(Info.RefineryTypes, player); if (harvCountTooLow && unitBuilder.RequestedProductionCount(bot, harvInfo.Name) == 0) { unitBuilder.RequestUnitProduction(bot, harvInfo.Name); } } }
void IBotTick.BotTick(IBot bot) { if (resourceLayer == null || resourceLayer.IsResourceLayerEmpty) { return; } if (--scanForIdleMinersTicks > 0) { return; } scanForIdleMinersTicks = Info.MinimumScanDelay; var toRemove = miners.Keys.Where(unitCannotBeOrdered).ToList(); foreach (var a in toRemove) { miners.Remove(a); } // TODO: Look for a more performance friendly way to update this list var newMiners = world.Actors.Where(a => Info.DeployableActorTypes.Contains(a.Info.Name) && a.Owner == player && !miners.ContainsKey(a)); foreach (var a in newMiners) { miners[a] = new MinerTraitWrapper(a); } foreach (var miner in miners) { if (!miner.Key.IsIdle) { continue; } if (Info.DeployableTerrainTypes.Contains(world.Map.GetTerrainInfo(miner.Key.Location).Type)) { bot.QueueOrder(new Order("DeployTransform", miner.Key, true)); continue; } // Tell the idle miner to quit slacking: var newSafeResourcePatch = FindNextResource(miner.Key, miner.Value); if (newSafeResourcePatch.Type == TargetType.Invalid) { scanForIdleMinersTicks = Info.LastSearchFailedDelay; return; } AIUtils.BotDebug("AI: Miner {0} is idle. Ordering to {1} in search for new resources.".F(miner.Key, newSafeResourcePatch)); bot.QueueOrder(new Order("Move", miner.Key, newSafeResourcePatch, true)); } // Keep the economy running before starving out. var unitBuilder = requestUnitProduction.FirstOrDefault(Exts.IsTraitEnabled); if (unitBuilder != null) { var minerInfo = AIUtils.GetInfoByCommonName(Info.DeployableActorTypes, player); var miningTowers = AIUtils.CountBuildingByCommonName(Info.DeployedActorTypes, player); if (miningTowers < Info.MinimumDeployedActors && unitBuilder.RequestedProductionCount(bot, minerInfo.Name) == 0) { unitBuilder.RequestUnitProduction(bot, minerInfo.Name); } } }