Skip to content

Commit cdce1d3

Browse files
committed
fix(pathfinder): Implement new robust forward insertion sort code
1 parent 6abe245 commit cdce1d3

2 files changed

Lines changed: 53 additions & 0 deletions

File tree

Core/GameEngine/Include/GameLogic/AIPathfind.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,9 @@ class PathfindCell
331331
void forwardInsertionSortRetailCompatible(PathfindCellList& list);
332332
#endif
333333

334+
// Forward insertion sort, in ascending cost order
335+
void forwardInsertionSort(PathfindCellList& list);
336+
334337
/// put self on "open" list in ascending cost order
335338
void putOnSortedOpenList( PathfindCellList &list );
336339

Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,6 +1680,7 @@ Bool PathfindCell::removeObstacle( Object *obstacle )
16801680
return true;
16811681
}
16821682

1683+
#if RETAIL_COMPATIBLE_PATHFINDING
16831684
// Retail compatible insertion sort
16841685
void PathfindCell::forwardInsertionSortRetailCompatible(PathfindCellList& list)
16851686
{
@@ -1731,11 +1732,60 @@ void PathfindCell::forwardInsertionSortRetailCompatible(PathfindCellList& list)
17311732
m_info->m_nextOpen = nullptr;
17321733
}
17331734
}
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+
}
17341777

17351778
/// put self on "open" list in ascending cost order, return new list
17361779
void PathfindCell::putOnSortedOpenList( PathfindCellList &list )
17371780
{
1781+
#if RETAIL_COMPATIBLE_PATHFINDING
1782+
if (!s_useFixedPathfinding) {
17381783
forwardInsertionSortRetailCompatible(list);
1784+
return;
1785+
}
1786+
#endif
1787+
1788+
forwardInsertionSort(list);
17391789
}
17401790

17411791
/// remove self from "open" list

0 commit comments

Comments
 (0)