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]); } }
/// <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)); }