Beispiel #1
0
        public List <CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor)
        {
            var li = self.Info.TraitInfo <MobileInfo>().LocomotorInfo;

            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();
                cached      = true;
            }

            // If a water-land transition is required, bail early
            if (domainIndex != null && !domainIndex.IsPassable(source, target, li))
            {
                return(EmptyPath);
            }

            var distance = source - target;

            if (source.Layer == target.Layer && distance.LengthSquared < 3 && li.CanMoveFreelyInto(world, self, target, null, CellConditions.All))
            {
                return new List <CPos> {
                           target
                }
            }
            ;

            List <CPos> pb;

            using (var fromSrc = PathSearch.FromPoint(world, li, self, target, source, true).WithIgnoredActor(ignoreActor))
                using (var fromDest = PathSearch.FromPoint(world, li, self, source, target, true).WithIgnoredActor(ignoreActor).Reverse())
                    pb = FindBidiPath(fromSrc, fromDest);

            return(pb);
        }
Beispiel #2
0
 protected override void TraitEnabled(Actor self)
 {
     pathfinder  = world.WorldActor.Trait <IPathFinder>();
     domainIndex = world.WorldActor.Trait <DomainIndex>();
     resLayer    = world.WorldActor.TraitOrDefault <ResourceLayer>();
     claimLayer  = world.WorldActor.TraitOrDefault <ResourceClaimLayer>();
     scanForIdleHarvestersTicks = Info.ScanForIdleHarvestersInterval;
 }
Beispiel #3
0
 public ProductionFromMapEdge(ActorInitializer init, ProductionInfo info)
     : base(init, info)
 {
     domainIndex = init.Self.World.WorldActor.Trait <DomainIndex>();
     if (init.Contains <ProductionSpawnLocationInit>())
     {
         spawnLocation = init.Get <ProductionSpawnLocationInit, CPos>();
     }
 }
Beispiel #4
0
 protected override void TraitEnabled(Actor self)
 {
     requestUnitProduction = player.PlayerActor.TraitsImplementing <IBotRequestUnitProduction>().ToArray();
     pathfinder            = world.WorldActor.Trait <IPathFinder>();
     domainIndex           = world.WorldActor.Trait <DomainIndex>();
     resLayer   = world.WorldActor.TraitOrDefault <ResourceLayer>();
     claimLayer = world.WorldActor.TraitOrDefault <ResourceClaimLayer>();
     scanForIdleHarvestersTicks = Info.ScanForIdleHarvestersInterval;
 }
Beispiel #5
0
        protected override void TraitEnabled(Actor self)
        {
            pathfinder    = world.WorldActor.Trait <IPathFinder>();
            domainIndex   = world.WorldActor.Trait <DomainIndex>();
            resourceLayer = world.WorldActor.TraitOrDefault <IResourceLayer>();
            claimLayer    = world.WorldActor.TraitOrDefault <ResourceClaimLayer>();

            // Avoid all AIs scanning for idle harvesters on the same tick, randomize their initial scan delay.
            scanForIdleHarvestersTicks = world.LocalRandom.Next(Info.ScanForIdleHarvestersInterval, Info.ScanForIdleHarvestersInterval * 2);
        }
Beispiel #6
0
        public ProductionFromMapEdge(ActorInitializer init, ProductionInfo info)
            : base(init, info)
        {
            domainIndex = init.Self.World.WorldActor.Trait <DomainIndex>();

            var spawnLocationInit = init.GetOrDefault <ProductionSpawnLocationInit>(info);

            if (spawnLocationInit != null)
            {
                spawnLocation = spawnLocationInit.Value;
            }
        }
Beispiel #7
0
        public List <CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor, BlockedByActor check)
        {
            // PERF: Because we can be sure that OccupiesSpace is Mobile here, we can save some performance by avoiding querying for the trait.
            var locomotor = ((Mobile)self.OccupiesSpace).Locomotor;

            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();
                cached      = true;
            }

            // If a water-land transition is required, bail early
            if (domainIndex != null && !domainIndex.IsPassable(source, target, locomotor))
            {
                return(EmptyPath);
            }

            var distance      = source - target;
            var canMoveFreely = locomotor.CanMoveFreelyInto(self, target, check, null);

            if (distance.LengthSquared < 3 && !canMoveFreely)
            {
                return new List <CPos> {
                }
            }
            ;

            if (source.Layer == target.Layer && distance.LengthSquared < 3 && canMoveFreely)
            {
                return new List <CPos> {
                           target
                }
            }
            ;

            List <CPos> pb;

            using (var fromSrc = PathSearch.FromPoint(world, locomotor, self, target, source, check).WithIgnoredActor(ignoreActor))
                using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, target, check).WithIgnoredActor(ignoreActor).Reverse())
                    pb = FindBidiPath(fromSrc, fromDest);

            return(pb);
        }
Beispiel #8
0
        public List <CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor, BlockedByActor check)
        {
            var mobile    = self.Trait <Mobile>();
            var locomotor = mobile.Locomotor;

            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();
                cached      = true;
            }

            // If a water-land transition is required, bail early
            if (domainIndex != null && !domainIndex.IsPassable(source, target, locomotor.Info))
            {
                return(EmptyPath);
            }

            var distance      = source - target;
            var canMoveFreely = locomotor.CanMoveFreelyInto(self, target, check, null);

            if (distance.LengthSquared < 3 && !canMoveFreely)
            {
                return new List <CPos> {
                }
            }
            ;

            if (source.Layer == target.Layer && distance.LengthSquared < 3 && canMoveFreely)
            {
                return new List <CPos> {
                           target
                }
            }
            ;

            List <CPos> pb;

            using (var fromSrc = PathSearch.FromPoint(world, locomotor, self, target, source, check).WithIgnoredActor(ignoreActor))
                using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, target, check).WithIgnoredActor(ignoreActor).Reverse())
                    pb = FindBidiPath(fromSrc, fromDest);

            return(pb);
        }
Beispiel #9
0
        public List <CPos> FindUnitPathToRange(CPos source, SubCell srcSub, WPos target, WDist range, Actor self, BlockedByActor check)
        {
            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();

                cached = true;
            }

            // PERF: Because we can be sure that OccupiesSpace is Mobile here, we can save some performance by avoiding querying for the trait.
            var mobile    = (Mobile)self.OccupiesSpace;
            var locomotor = mobile.Locomotor;

            var targetCell = world.Map.CellContaining(target);

            // Correct for SubCell offset
            target -= world.Map.Grid.OffsetOfSubCell(srcSub);

            var rangeLengthSquared = range.LengthSquared;
            var map = world.Map;

            // Select only the tiles that are within range from the requested SubCell
            // This assumes that the SubCell does not change during the path traversal
            var tilesInRange = map.FindTilesInCircle(targetCell, range.Length / 1024 + 1)
                               .Where(t => (map.CenterOfCell(t) - target).LengthSquared <= rangeLengthSquared &&
                                      mobile.Info.CanEnterCell(world, self, t));

            // See if there is any cell within range that does not involve a cross-domain request
            // Really, we only need to check the circle perimeter, but it's not clear that would be a performance win
            if (domainIndex != null)
            {
                tilesInRange = new List <CPos>(tilesInRange.Where(t => domainIndex.IsPassable(source, t, locomotor)));
                if (!tilesInRange.Any())
                {
                    return(EmptyPath);
                }
            }

            using (var fromSrc = PathSearch.FromPoints(world, locomotor, self, tilesInRange, source, check))
                using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, targetCell, check).Reverse())
                    return(FindBidiPath(fromSrc, fromDest));
        }
Beispiel #10
0
        public List <CPos> FindUnitPathToRange(CPos source, SubCell srcSub, WPos target, WDist range, Actor self)
        {
            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();

                cached = true;
            }

            var mobile     = self.Trait <Mobile>();
            var mi         = mobile.Info;
            var li         = mi.LocomotorInfo;
            var targetCell = world.Map.CellContaining(target);

            // Correct for SubCell offset
            target -= world.Map.Grid.OffsetOfSubCell(srcSub);

            // Select only the tiles that are within range from the requested SubCell
            // This assumes that the SubCell does not change during the path traversal
            var tilesInRange = world.Map.FindTilesInCircle(targetCell, range.Length / 1024 + 1)
                               .Where(t => (world.Map.CenterOfCell(t) - target).LengthSquared <= range.LengthSquared &&
                                      mi.CanEnterCell(self.World, self, t));

            // See if there is any cell within range that does not involve a cross-domain request
            // Really, we only need to check the circle perimeter, but it's not clear that would be a performance win
            if (domainIndex != null)
            {
                tilesInRange = new List <CPos>(tilesInRange.Where(t => domainIndex.IsPassable(source, t, li)));
                if (!tilesInRange.Any())
                {
                    return(EmptyPath);
                }
            }

            var locomotor = mobile.Locomotor;

            using (var fromSrc = PathSearch.FromPoints(world, locomotor, self, tilesInRange, source, true))
                using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, targetCell, true).Reverse())
                    return(FindBidiPath(fromSrc, fromDest));
        }