public void Tick(List <Actor> harvesters) { if (resLayer == null || resLayer.IsResourceLayerEmpty) { return; } // Find idle harvesters and give them orders: foreach (var harvester in harvesters) { var harv = harvester.Trait <Harvester>(); if (!harv.IsEmpty) { continue; } if (!harvester.IsIdle) { var act = harvester.CurrentActivity; if (!harv.LastSearchFailed || act.NextActivity == null || act.NextActivity.GetType() != typeof(FindResources)) { continue; } } var para = harvester.TraitOrDefault <Parachutable>(); if (para != null && para.IsInAir) { continue; } // Tell the idle harvester to quit slacking: var newSafeResourcePatch = FindNextResource(harvester, harv); HackyAI.BotDebug("AI: Harvester {0} is idle. Ordering to {1} in search for new resources.".F(harvester, newSafeResourcePatch)); ai.QueueOrder(new Order("Harvest", harvester, Target.FromCell(world, newSafeResourcePatch), false)); } }
public void TryToUseSupportPower(Actor self) { if (supportPowerManager == null) { return; } foreach (var sp in supportPowerManager.Powers.Values) { if (sp.Disabled) { continue; } // Add power to dictionary if not in delay dictionary yet if (!waitingPowers.ContainsKey(sp)) { waitingPowers.Add(sp, 0); } if (waitingPowers[sp] > 0) { waitingPowers[sp]--; } // If we have recently tried and failed to find a use location for a power, then do not try again until later var isDelayed = waitingPowers[sp] > 0; if (sp.Ready && !isDelayed && powerDecisions.ContainsKey(sp.Info.OrderName)) { var powerDecision = powerDecisions[sp.Info.OrderName]; if (powerDecision == null) { HackyAI.BotDebug("Bot Bug: FindAttackLocationToSupportPower, couldn't find powerDecision for {0}", sp.Info.OrderName); continue; } var attackLocation = FindCoarseAttackLocationToSupportPower(sp); if (attackLocation == null) { HackyAI.BotDebug("AI: {1} can't find suitable coarse attack location for support power {0}. Delaying rescan.", sp.Info.OrderName, player.PlayerName); waitingPowers[sp] += powerDecision.GetNextScanTime(ai); continue; } // Found a target location, check for precise target attackLocation = FindFineAttackLocationToSupportPower(sp, (CPos)attackLocation); if (attackLocation == null) { HackyAI.BotDebug("AI: {1} can't find suitable final attack location for support power {0}. Delaying rescan.", sp.Info.OrderName, player.PlayerName); waitingPowers[sp] += powerDecision.GetNextScanTime(ai); continue; } // Valid target found, delay by a few ticks to avoid rescanning before power fires via order HackyAI.BotDebug("AI: {2} found new target location {0} for support power {1}.", attackLocation, sp.Info.OrderName, player.PlayerName); waitingPowers[sp] += 10; ai.QueueOrder(new Order(sp.Key, supportPowerManager.Self, Target.FromCell(world, attackLocation.Value), false) { SuppressVisualFeedback = true }); } } }
bool TickQueue(ProductionQueue queue) { var currentBuilding = queue.CurrentItem(); // Waiting to build something if (currentBuilding == null && failCount < ai.Info.MaximumFailedPlacementAttempts) { var item = ChooseBuildingToBuild(queue); if (item == null) { return(false); } ai.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; if (world.Map.Rules.Actors[currentBuilding.Item].HasTraitInfo <AttackBaseInfo>()) { type = BuildingType.Defense; } else if (world.Map.Rules.Actors[currentBuilding.Item].HasTraitInfo <RefineryInfo>()) { type = BuildingType.Refinery; } var location = ai.ChooseBuildLocation(currentBuilding.Item, true, type); if (location == null) { 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.ActorsHavingTrait <Building>().Count(a => a.Owner == player); cachedBases = world.ActorsHavingTrait <BaseProvider>().Count(a => a.Owner == player); } } else { failCount = 0; ai.QueueOrder(new Order("PlaceBuilding", player.PlayerActor, false) { TargetLocation = location.Value, TargetString = currentBuilding.Item, TargetActor = queue.Actor, SuppressVisualFeedback = true }); return(true); } } return(true); }