public TrailblazerPather_TwinAStar(PathfindData pathfindData) : base(pathfindData)
        {
            rraOpenSet   = new Priority_Queue.FastPriorityQueue <CellRefNode>(map.Area);
            rraClosedSet = new Dictionary <CellRef, int>();

            cellRefNodeCache = new Dictionary <CellRef, CellRefNode>();

            var cellPassRules = ThatApply <CellPassabilityRule>(
                new CellPassabilityRule_PathGrid(pathfindData),
                new CellPassabilityRule_DoorByPawn(pathfindData),
                new CellPassabilityRule_NoPassDoors(pathfindData)
                );

            var passRules = Enumerable.Empty <PassabilityRule>();

            var cellCostRules = ThatApply <CellCostRule>(
                new CellCostRule_PathGrid(pathfindData),
                new CellCostRule_Walls(pathfindData)
                );

            var costRules = ThatApply <CostRule>(new CostRule_MoveTicks(pathfindData));

            rraPathfinderGrid = new PathfinderGrid(cellCostRules, costRules, cellPassRules, passRules);

            // Initialize the RRA* algorithm
            foreach (IntVec3 cell in pathfindData.DestRect)
            {
                CellRef cellRef = pathfindData.map.GetCellRef(cell);
                rraClosedSet[cellRef] = 0;
                rraOpenSet.Enqueue(GetNode(cellRef), 0);
            }
        }
        public TrailblazerPather_HAStar(PathfindData pathfindData) : base(pathfindData)
        {
            regionGrid = pathfindData.map.regionGrid;
            int regions = regionGrid.AllRegions.Count();

            // Worst case scenario - a large region where every single edge cell links to a different neighboring region
            maxLinks = Region.GridSize * 4 * regions;

            rraOpenSet   = new Priority_Queue.FastPriorityQueue <LinkNode>(maxLinks);
            rraClosedSet = new Dictionary <LinkNode, int>();

            destRegions.AddRange(from cell in pathfindData.DestRect.Cells
                                 let region = regionGrid.GetValidRegionAt(cell)
                                              where region != null
                                              select region);


            // Initialize the RRA* algorithm
            LinkNode.ClearCaches();
            IEnumerable <LinkNode> initialNodes = (from region in destRegions
                                                   from link in region.links
                                                   from node in LinkNode.Both(link)
                                                   select node).Distinct();

            foreach (LinkNode node in initialNodes)
            {
                rraClosedSet[node] = RRAHeuristic(node, destCell);
                rraOpenSet.Enqueue(node, rraClosedSet[node]);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Stub that replaces the vanilla pathfind method. Performs error checking, then creates a TrailblazerPather
        /// to perform the actual pathfinding.
        /// </summary>
        /// <returns>The path.</returns>
        /// <param name="start">Start.</param>
        /// <param name="dest">Destination.</param>
        /// <param name="traverseParms">Traverse parms.</param>
        /// <param name="peMode">Path end mode.</param>
        public static PawnPath FindPath(Map map, IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, PathEndMode peMode)
        {
            if (DebugSettings.pathThroughWalls)
            {
                traverseParms.mode = TraverseMode.PassAllDestroyableThings;
            }
            Pawn pawn = traverseParms.pawn;

            if (pawn != null && pawn.Map != map)
            {
                Log.Error("Tried to FindPath for pawn which is spawned in another map. His map PathFinder should have been used, not this one. pawn=" + pawn + " pawn.Map=" + pawn.Map + " map=" + map, false);
                return(PawnPath.NotFound);
            }
            if (!start.IsValid)
            {
                Log.Error("Tried to FindPath with invalid start " + start + ", pawn= " + pawn, false);
                return(PawnPath.NotFound);
            }
            if (!dest.IsValid)
            {
                Log.Error("Tried to FindPath with invalid dest " + dest + ", pawn= " + pawn, false);
                return(PawnPath.NotFound);
            }
            if (traverseParms.mode == TraverseMode.ByPawn)
            {
                if (!pawn.CanReach(dest, peMode, Danger.Deadly, traverseParms.canBash, traverseParms.mode))
                {
                    return(PawnPath.NotFound);
                }
            }
            else if (!map.reachability.CanReach(start, dest, peMode, traverseParms))
            {
                return(PawnPath.NotFound);
            }

            PathfindData      pathfindData = new PathfindData(map, map.GetCellRef(start), dest, traverseParms, peMode);
            TrailblazerPather pather;

            switch (LoadedModManager.GetMod <TrailblazerSettingController>().GetSettings <TrailblazerSettings>().pathfinder)
            {
            case PathfinderEnum.AStar:
                pather = new TrailblazerPather_AStar(pathfindData);
                break;

            case PathfinderEnum.HAStar:
                pather = new TrailblazerPather_HAStar(pathfindData);
                break;

            case PathfinderEnum.TwinAStar:
                pather = new TrailblazerPather_TwinAStar(pathfindData);
                break;

            default:
                throw new Exception("Invalid pathfinder");
            }
            return(pather.FindPath());
        }
        /// <summary>
        /// Creates an enumerable of all possible cell passability rules (regardless of whether they apply)
        /// Extend this method via harmony patching to add additional passability rules.
        /// </summary>
        /// <returns>The passability rules.</returns>
        /// <param name="pathfindData">Pathfind data.</param>
        public static IEnumerable <CellPassabilityRule> CellPassabilityRules(PathfindData pathfindData)
        {
            yield return(new CellPassabilityRule_PathGrid(pathfindData));

            yield return(new CellPassabilityRule_DoorByPawn(pathfindData));

            yield return(new CellPassabilityRule_NoPassDoors(pathfindData));

            yield return(new CellPassabilityRule_Water(pathfindData));
        }
        protected TrailblazerPather(PathfindData pathfindData)
        {
            this.pathfindData = pathfindData;
            var cellPassRules = ThatApply(CellPassabilityRules(pathfindData));
            var passRules     = ThatApply(PassabilityRules(pathfindData));
            var cellCostRules = ThatApply(CellCostRules(pathfindData));
            var costRules     = ThatApply(CostRules(pathfindData));

            pathfinderGrid = new PathfinderGrid(cellCostRules, costRules, cellPassRules, passRules);
        }
        /// <summary>
        /// Creates an enumerable of all possible cell cost rules (regardless of whether they apply)
        /// Extend this method via harmony patching to add additional cost rules.
        /// </summary>
        /// <returns>The passability rules.</returns>
        /// <param name="pathfindData">Pathfind data.</param>
        public static IEnumerable <CellCostRule> CellCostRules(PathfindData pathfindData)
        {
            yield return(new CellCostRule_AllowedArea(pathfindData));

            yield return(new CellCostRule_AvoidGrid(pathfindData));

            yield return(new CellCostRule_Blueprints(pathfindData));

            yield return(new CellCostRule_Buildings(pathfindData));

            yield return(new CellCostRule_Doors(pathfindData));

            yield return(new CellCostRule_PathGrid(pathfindData));

            yield return(new CellCostRule_Pawns(pathfindData));

            yield return(new CellCostRule_Walls(pathfindData));
        }
        public TrailblazerPather_AStar(PathfindData pathfindData) : base(pathfindData)
        {
            map = pathfindData.map;

            openSet   = new Priority_Queue.FastPriorityQueue <CellRefNode>(map.Area);
            closedSet = new Dictionary <CellRef, CellNode>();

            cellRefNodeCache = new Dictionary <CellRef, CellRefNode>();

            startCell = pathfindData.start;
            destCell  = pathfindData.map.GetCellRef(pathfindData.dest.Cell);

            CostRule_MoveTicks.GetMoveTicks(pathfindData, out moveTicksCardinal, out moveTicksDiagonal);

            debugMat++;
            debugVisualizer = pathfindData.map.GetComponent <TrailblazerDebugVisualizer>();
            debugReplay     = debugVisualizer.CreateNewReplay();
#if PROFILE
            performanceTracker = new PerformanceTracker();
#endif
        }
 /// <summary>
 /// Creates an enumerable of all possible cost rules (regardless of whether they apply)
 /// Extend this method via harmony patching to add additional cost rules.
 /// </summary>
 /// <returns>The passability rules.</returns>
 /// <param name="pathfindData">Pathfind data.</param>
 public static IEnumerable <CostRule> CostRules(PathfindData pathfindData)
 {
     yield return(new CostRule_MoveTicks(pathfindData));
 }
 /// <summary>
 /// Creates an enumerable of all possible passability rules (regardless of whether they apply)
 /// Extend this method via harmony patching to add additional passability rules.
 /// </summary>
 /// <returns>The passability rules.</returns>
 /// <param name="pathfindData">Pathfind data.</param>
 public static IEnumerable <PassabilityRule> PassabilityRules(PathfindData pathfindData)
 {
     yield return(new PassabilityRule_Diagonals(pathfindData));
 }