/// <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 int CalcMoveCost(MoveData moveData)
 {
     return(pathfinderGrid.MoveCost(moveData));
 }