MCPcopy Create free account
hub / github.com/TombEngine/TombEngine / SearchLOT_DijkstraAStar

Function SearchLOT_DijkstraAStar

TombEngine/Game/control/box.cpp:1891–2036  ·  view source on GitHub ↗

* @brief Cost-based path search (Dijkstra / A*) for pathfinding through boxes. * * This function expands the search using a priority queue ordered by accumulated * path cost. It builds a "flow field" where each box's exitBox points toward the * target, preferring lower-cost paths. When A* is selected, a heuristic is added * to guide the search toward the creature's source box. * * ALGORITHM

Source from the content-addressed store, hash-verified

1889 * @return true if more boxes remain to expand, false if search exhausted.
1890 */
1891bool SearchLOT_DijkstraAStar(LOTInfo* LOT, int depth, PathfindingMode mode)
1892{
1893 PathQueue queue = {};
1894 auto& zone = g_Level.Zones[(int)LOT->Zone][(int)FlipStatus];
1895
1896 // Determine whether A* heuristic should be applied.
1897 bool useHeuristic = (mode == PathfindingMode::AStar && LOT->SourceBox != NO_VALUE);
1898
1899 // A* heuristic target (creature's source box center).
1900 auto sourceCenter = useHeuristic ? GetBoxCenter(LOT->SourceBox) : Vector3::Zero;
1901
1902 // Move legacy Head/Tail expansion list into priority queue.
1903 int currentBox = LOT->Head;
1904 while (currentBox != NO_VALUE)
1905 {
1906 auto* node = &LOT->Node[currentBox];
1907
1908 int next = node->nextExpansion;
1909 node->nextExpansion = NO_VALUE;
1910
1911 float pathCost = node->cost;
1912 float heuristicCost = useHeuristic ? Vector3::Distance(GetBoxCenter(currentBox), sourceCenter) : 0.0f;
1913
1914 queue.push({ pathCost + heuristicCost, pathCost, currentBox });
1915
1916 currentBox = next;
1917 }
1918
1919 // Reset legacy queue; it will be rebuilt from remaining PQ entries.
1920 LOT->Head = NO_VALUE;
1921 LOT->Tail = NO_VALUE;
1922
1923 int expansions = 0;
1924
1925 // Main Dijkstra / A* expansion loop.
1926 while (expansions < depth && !queue.empty())
1927 {
1928 auto [currentEstimatedCost, currentPathCost, headBox] = queue.top();
1929 queue.pop();
1930
1931 auto* box = &g_Level.PathfindingBoxes[headBox];
1932 auto* node = &LOT->Node[headBox];
1933
1934 // Skip stale queue entries superseded by a cheaper path.
1935 if (currentPathCost > node->cost)
1936 continue;
1937
1938 expansions++;
1939
1940 int index = box->overlapIndex;
1941 int searchZone = zone[headBox];
1942
1943 auto currentCenter = GetBoxCenter(headBox);
1944 bool done = false;
1945
1946 // Iterate through all overlapping neighbor boxes.
1947 if (index >= 0)
1948 {

Callers 1

SearchLOTFunction · 0.85

Calls 6

GetBoxCenterFunction · 0.85
CanExpandToBoxFunction · 0.85
topMethod · 0.80
pushMethod · 0.45
emptyMethod · 0.45
popMethod · 0.45

Tested by

no test coverage detected