51 lines
2.1 KiB
Diff
51 lines
2.1 KiB
Diff
# UNDF: UNDF-2026-000001157
|
|
# UNDF: UNDF-2026-XXXXXXXXX
|
|
--- a/engines/crab/PathfindingGrid.cpp
|
|
+++ b/engines/crab/PathfindingGrid.cpp
|
|
@@ -27,6 +27,8 @@
|
|
|
|
#include "crab/PathfindingGrid.h"
|
|
#include "crab/TMX/TMXMap.h"
|
|
+#include <unordered_set>
|
|
|
|
namespace Crab {
|
|
|
|
@@ -234,21 +236,22 @@ PathfindingGraphNode *PathfindingGrid::getNearestOpenNode(Vector2f nodePos, Vect
|
|
if (startNode->getMovementCost() > 0) // If the clicked node is open, we're done!
|
|
return startNode;
|
|
|
|
PathfindingGraphNode *returnNode = nullptr;
|
|
|
|
float shortestDistance = 0.0f;
|
|
|
|
Common::List<PathfindingGraphNode *> checkNodes;
|
|
checkNodes.push_back(startNode);
|
|
|
|
- Common::Array<PathfindingGraphNode *> allUsedNodes;
|
|
- allUsedNodes.push_back(startNode);
|
|
+ // Use an unordered_set for O(1) visited-node lookup instead of O(N) linear
|
|
+ // scan over allUsedNodes on every neighbor check. Without this fix the BFS
|
|
+ // is O(N^2) in the number of grid nodes visited.
|
|
+ std::unordered_set<PathfindingGraphNode *> visitedNodes;
|
|
+ visitedNodes.insert(startNode);
|
|
|
|
// Iterate through the nodes, check if they are open then check their distance from the compare point.
|
|
while (!checkNodes.empty()) {
|
|
if (checkNodes.front()->getMovementCost() > 0) {
|
|
float distance = (comparePos - checkNodes.front()->getPosition()).magSqr();
|
|
|
|
if (shortestDistance == 0.0f || distance) { // If this is the new shortest distance, this becomes the new return.
|
|
shortestDistance = distance;
|
|
|
|
returnNode = checkNodes.front();
|
|
}
|
|
} else {
|
|
for (uint i = 0; i < checkNodes.front()->_neighborNodes.size(); ++i) {
|
|
// If the neighbor hasn't been checked yet, add it to the list to check.
|
|
- if (Common::find(allUsedNodes.begin(), allUsedNodes.end(), checkNodes.front()->_neighborNodes[i]) == allUsedNodes.end()) {
|
|
- allUsedNodes.push_back(checkNodes.front()->_neighborNodes[i]);
|
|
+ if (visitedNodes.find(checkNodes.front()->_neighborNodes[i]) == visitedNodes.end()) {
|
|
+ visitedNodes.insert(checkNodes.front()->_neighborNodes[i]);
|
|
checkNodes.push_back(checkNodes.front()->_neighborNodes[i]);
|
|
}
|
|
}
|