Exemple #1
0
        Target FindNextResource(Actor actor, HarvesterTraitWrapper harv)
        {
            Func <CPos, bool> isValidResource = cell =>
                                                harv.Harvester.CanHarvestCell(cell) &&
                                                claimLayer.CanClaimCell(actor, cell);

            var path = harv.Mobile.PathFinder.FindUnitPathToTargetCellByPredicate(
                actor, new[] { actor.Location }, isValidResource, BlockedByActor.Stationary,
                loc => world.FindActorsInCircle(world.Map.CenterOfCell(loc), Info.HarvesterEnemyAvoidanceRadius)
                .Where(u => !u.IsDead && actor.Owner.RelationshipWith(u.Owner) == PlayerRelationship.Enemy)
                .Sum(u => Math.Max(WDist.Zero.Length, Info.HarvesterEnemyAvoidanceRadius.Length - (world.Map.CenterOfCell(loc) - u.CenterPosition).Length)));

            if (path.Count == 0)
            {
                return(Target.Invalid);
            }

            return(Target.FromCell(world, path[0]));
        }
Exemple #2
0
        Target FindNextResource(Actor actor, HarvesterTraitWrapper harv)
        {
            Func <CPos, bool> isValidResource = cell =>
                                                domainIndex.IsPassable(actor.Location, cell, harv.Locomotor) &&
                                                harv.Harvester.CanHarvestCell(actor, cell) &&
                                                claimLayer.CanClaimCell(actor, cell);

            var path = pathfinder.FindPath(
                PathSearch.Search(world, harv.Locomotor, actor, BlockedByActor.Stationary, isValidResource)
                .WithCustomCost(loc => world.FindActorsInCircle(world.Map.CenterOfCell(loc), Info.HarvesterEnemyAvoidanceRadius)
                                .Where(u => !u.IsDead && actor.Owner.RelationshipWith(u.Owner) == PlayerRelationship.Enemy)
                                .Sum(u => Math.Max(WDist.Zero.Length, Info.HarvesterEnemyAvoidanceRadius.Length - (world.Map.CenterOfCell(loc) - u.CenterPosition).Length)))
                .FromPoint(actor.Location));

            if (path.Count == 0)
            {
                return(Target.Invalid);
            }

            return(Target.FromCell(world, path[0]));
        }
Exemple #3
0
        protected void OrderHarvesters(IBot bot)
        {
            var toRemove = harvesters.Keys.Where(unitCannotBeOrdered).ToList();

            foreach (var a in toRemove)
            {
                harvesters.Remove(a);
            }

            // 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)
                {
                    var act = h.Key.CurrentActivity as FindAndDeliverResources;

                    // Ignore this actor if FindAndDeliverResources is working fine or it is performing a different activity
                    if (act == null || !act.LastSearchFailed)
                    {
                        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));
            }
        }
Exemple #4
0
        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);
                }
            }
        }