Esempio n. 1
0
        public List <CPos> FindUnitPathToRange(CPos src, CPos target, int range, Actor self)
        {
            using (new PerfSample("Pathfinder"))
            {
                var mi           = self.Info.Traits.Get <MobileInfo>();
                var tilesInRange = world.FindTilesInCircle(target, range)
                                   .Where(t => mi.CanEnterCell(self.World, self, t, null, true, true));

                var path = FindBidiPath(
                    PathSearch.FromPoints(world, mi, self, tilesInRange, src, true),
                    PathSearch.FromPoint(world, mi, self, src, target, true).InReverse()
                    );

                return(path);
            }
        }
Esempio n. 2
0
        public List <CPos> FindUnitPathToRange(CPos src, SubCell srcSub, WPos target, WRange range, Actor self)
        {
            using (new PerfSample("Pathfinder"))
            {
                var mi           = self.Info.Traits.Get <MobileInfo>();
                var targetCell   = self.World.Map.CellContaining(target);
                var rangeSquared = range.Range * range.Range;

                // Correct for SubCell offset
                target -= MobileInfo.SubCellOffsets[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.Range / 1024 + 1)
                                   .Where(t => (world.Map.CenterOfCell(t) - target).LengthSquared <= rangeSquared &&
                                          mi.CanEnterCell(self.World, self, t, null, true, true));

                // 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
                var domainIndex = self.World.WorldActor.TraitOrDefault <DomainIndex>();
                if (domainIndex != null)
                {
                    var passable = mi.GetMovementClass(world.TileSet);
                    tilesInRange = new List <CPos>(tilesInRange.Where(t => domainIndex.IsPassable(src, t, (uint)passable)));
                    if (!tilesInRange.Any())
                    {
                        return(emptyPath);
                    }
                }

                var path = FindBidiPath(
                    PathSearch.FromPoints(world, mi, self, tilesInRange, src, true),
                    PathSearch.FromPoint(world, mi, self, src, targetCell, true).Reverse()
                    );

                return(path);
            }
        }