/// <summary> /// Initiates or resumes RRA* pathfinding to the given target. /// This variant of RRA* paths on the same grid as the main A* pather but only uses a subset of rules /// </summary> /// <returns>The region link closest to the target cell</returns> /// <param name="targetCell">Target cell.</param> private void ReverseResumableAStar(CellRef targetCell) { ProfilerStart("RRA"); ProfilerStart("RRA Reprioritize"); // Rebuild the open set based on the new target CellRefNode[] cachedNodes = rraOpenSet.ToArray(); // Cache the nodes because we'll be messing with the queue foreach (CellRefNode cell in cachedNodes) { rraOpenSet.UpdatePriority(cell, rraClosedSet[cell] + RRAHeuristic(cell, targetCell)); } ProfilerEnd("RRA Reprioritize"); int closedNodes = 0; while (rraOpenSet.Count > 0) { CellRef current = rraOpenSet.Dequeue(); debugReplay.DrawCell(current); ProfilerCount("RRA Closed"); // Check if we've reached our goal if (current.Equals(targetCell)) { ProfilerEnd("RRA"); return; } if (closedNodes > SearchLimit) { Log.Error("[Trailblazer] RRA* Heuristic closed too many cells, aborting"); ProfilerEnd("RRA"); return; } foreach (Direction direction in DirectionUtils.AllDirections) { IntVec3 neighborCell = direction.From(current); CellRef neighbor = map.GetCellRef(neighborCell); ProfilerStart("RRA Bounds Check"); bool inBounds = neighborCell.InBounds(map); ProfilerEnd("RRA Bounds Check"); if (inBounds) { MoveData moveData = new MoveData(neighbor, direction); ProfilerStart("RRA Move Check"); bool passable = rraPathfinderGrid.MoveIsValid(moveData); ProfilerEnd("RRA Move Check"); if (!passable) { continue; } ProfilerStart("RRA Move Cost"); int newCost = rraClosedSet[current] + rraPathfinderGrid.MoveCost(moveData); ProfilerEnd("RRA Move Cost"); if (!rraClosedSet.ContainsKey(neighbor) || newCost < rraClosedSet[neighbor]) { if (rraClosedSet.ContainsKey(neighbor)) { ProfilerCount("RRA Reopened"); } else { ProfilerCount("RRA New Open"); } rraClosedSet[neighbor] = newCost; int estimatedCost = newCost + RRAHeuristic(neighbor, targetCell); ProfilerStart("RRA Enqueue"); CellRefNode neighborNode = GetNode(neighbor); if (rraOpenSet.Contains(neighborNode)) { rraOpenSet.UpdatePriority(neighborNode, estimatedCost); } else { rraOpenSet.Enqueue(neighborNode, estimatedCost); } ProfilerEnd("RRA Enqueue"); } else { ProfilerCount("RRA Rescanned"); } } } debugReplay.NextFrame(); closedNodes++; } Log.Error("[Trailblazer] RRA heuristic failed to reach target cell " + targetCell); ProfilerEnd("RRA"); }
protected bool MoveIsValid(MoveData moveData) { return(pathfinderGrid.MoveIsValid(moveData)); }