java-topology/defects/scummvm-0001/patch/scummvm-0001.patch

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]);
}
}