@@ -1680,8 +1680,9 @@ Bool PathfindCell::removeObstacle( Object *obstacle )
16801680 return true ;
16811681}
16821682
1683- // / put self on "open" list in ascending cost order, return new list
1684- void PathfindCell::putOnSortedOpenList ( PathfindCellList &list )
1683+ #if RETAIL_COMPATIBLE_PATHFINDING
1684+ // Retail compatible insertion sort
1685+ void PathfindCell::forwardInsertionSortRetailCompatible (PathfindCellList& list)
16851686{
16861687 DEBUG_ASSERTCRASH (m_info, (" Has to have info." ));
16871688 DEBUG_ASSERTCRASH (m_info->m_closed == FALSE && m_info->m_open == FALSE , (" Serious error - Invalid flags. jba" ));
@@ -1701,18 +1702,10 @@ void PathfindCell::putOnSortedOpenList( PathfindCellList &list )
17011702 // insertion sort
17021703 PathfindCell* currentCell = list.m_head ;
17031704 PathfindCell* previousCell = nullptr ;
1704- #if RETAIL_COMPATIBLE_PATHFINDING
1705- // TheSuperHackers @bugfix In the retail compatible pathfinding, on rare occasions, we get stuck in an infinite loop
1706- // External code should pickup on the bad behaviour and cleanup properly, but we need to explicitly break out here
1707- // The fixed pathfinding does not have this issue due to the proper cleanup of pathfindCells and their pathfindCellInfos
17081705 UnsignedInt cellCount = 0 ;
17091706 while (currentCell && cellCount < PATHFIND_CELLS_PER_FRAME && currentCell->m_info ->m_totalCost <= m_info->m_totalCost )
17101707 {
17111708 cellCount++;
1712- #else
1713- while (currentCell && currentCell->m_info ->m_totalCost <= m_info->m_totalCost )
1714- {
1715- #endif
17161709 previousCell = currentCell;
17171710 currentCell = currentCell->getNextOpen ();
17181711 }
@@ -1739,6 +1732,61 @@ void PathfindCell::putOnSortedOpenList( PathfindCellList &list )
17391732 m_info->m_nextOpen = nullptr ;
17401733 }
17411734}
1735+ #endif
1736+
1737+ // Forward insertion sort, returns early if the list is being initialised or we are prepending the list
1738+ void PathfindCell::forwardInsertionSort (PathfindCellList& list)
1739+ {
1740+ DEBUG_ASSERTCRASH (m_info, (" Has to have info." ));
1741+ DEBUG_ASSERTCRASH (m_info->m_closed == FALSE && m_info->m_open == FALSE , (" Serious error - Invalid flags. jba" ));
1742+
1743+ // mark the new cell as being on the open list
1744+ m_info->m_open = true ;
1745+ m_info->m_closed = false ;
1746+
1747+ if (list.m_head == nullptr ) {
1748+ m_info->m_prevOpen = nullptr ;
1749+ m_info->m_nextOpen = nullptr ;
1750+ list.m_head = this ;
1751+ return ;
1752+ }
1753+
1754+ // If the node needs inserting before the current list head
1755+ if (m_info->m_totalCost < list.m_head ->m_info ->m_totalCost ) {
1756+ m_info->m_prevOpen = nullptr ;
1757+ list.m_head ->m_info ->m_prevOpen = this ->m_info ;
1758+ m_info->m_nextOpen = list.m_head ->m_info ;
1759+ list.m_head = this ;
1760+ return ;
1761+ }
1762+
1763+ // Traverse the list to find correct position
1764+ PathfindCell* current = list.m_head ;
1765+ while (current->m_info ->m_nextOpen && current->m_info ->m_nextOpen ->m_totalCost <= m_info->m_totalCost ) {
1766+ current = current->getNextOpen ();
1767+ }
1768+
1769+ // Insert the new node in the correct position
1770+ m_info->m_nextOpen = current->m_info ->m_nextOpen ;
1771+ if (current->m_info ->m_nextOpen != nullptr ) {
1772+ current->m_info ->m_nextOpen ->m_prevOpen = this ->m_info ;
1773+ }
1774+ current->m_info ->m_nextOpen = this ->m_info ;
1775+ m_info->m_prevOpen = current->m_info ;
1776+ }
1777+
1778+ // / put self on "open" list in ascending cost order, return new list
1779+ void PathfindCell::putOnSortedOpenList ( PathfindCellList &list )
1780+ {
1781+ #if RETAIL_COMPATIBLE_PATHFINDING
1782+ if (!s_useFixedPathfinding) {
1783+ forwardInsertionSortRetailCompatible (list);
1784+ return ;
1785+ }
1786+ #endif
1787+
1788+ forwardInsertionSort (list);
1789+ }
17421790
17431791// / remove self from "open" list
17441792void PathfindCell::removeFromOpenList ( PathfindCellList &list )
0 commit comments