84 lines
2.6 KiB
Diff
84 lines
2.6 KiB
Diff
# UNDF: UNDF-2026-000001028
|
|
--- a/regamedll/dlls/hostage/hostage_localnav.h
|
|
+++ b/regamedll/dlls/hostage/hostage_localnav.h
|
|
@@ -27,6 +27,8 @@
|
|
|
|
#pragma once
|
|
|
|
+#include <unordered_set>
|
|
+
|
|
enum PathTraversAble
|
|
{
|
|
PTRAVELS_EMPTY,
|
|
@@ -89,6 +91,14 @@ public:
|
|
static void HostagePrethink();
|
|
static float m_flStepSize;
|
|
|
|
+ // Hash set for (offsetX, offsetY) coordinate pairs, replacing the O(N)
|
|
+ // linear scan in NodeExists() with O(1) lookup. Reduces FindPath()
|
|
+ // from O(N^2) to O(N) where N = MAX_NODES.
|
|
+ std::unordered_set<int64_t> m_nodeCoordSet;
|
|
+
|
|
+ // Pack two int offsets into a single 64-bit key for hash set lookup.
|
|
+ static int64_t PackCoord(int offsetX, int offsetY);
|
|
+
|
|
private:
|
|
static EntityHandle<CHostage> m_hQueue[MAX_HOSTAGES_NAV];
|
|
static EntityHandle<CHostage> m_hHostages[MAX_HOSTAGES_NAV];
|
|
--- a/regamedll/dlls/hostage/hostage_localnav.cpp
|
|
+++ b/regamedll/dlls/hostage/hostage_localnav.cpp
|
|
@@ -62,6 +62,9 @@ node_index_t CLocalNav::AddNode(node_index_t nindexParent, Vector &vecLoc, int o
|
|
nodeNew->fSearched = FALSE;
|
|
nodeNew->nindexParent = nindexParent;
|
|
|
|
+ // Register coordinate pair in hash set for O(1) NodeExists() lookup.
|
|
+ m_nodeCoordSet.insert(PackCoord(offsetX, offsetY));
|
|
+
|
|
return m_nindexAvailableNode++;
|
|
}
|
|
|
|
@@ -71,6 +74,14 @@ localnode_t *CLocalNav::GetNode(node_index_t nindex)
|
|
return &m_nodeArr[nindex];
|
|
}
|
|
|
|
+// Pack two int offsets into a single 64-bit key for hash set lookup.
|
|
+// Upper 32 bits = offsetX, lower 32 bits = offsetY (cast through
|
|
+// unsigned to avoid sign-extension on negative values).
|
|
+int64_t CLocalNav::PackCoord(int offsetX, int offsetY)
|
|
+{
|
|
+ return (static_cast<int64_t>(offsetX) << 32) | static_cast<uint32_t>(offsetY);
|
|
+}
|
|
+
|
|
node_index_t CLocalNav::NodeExists(int offsetX, int offsetY)
|
|
{
|
|
- node_index_t nindexCurrent = NODE_INVALID_EMPTY;
|
|
- localnode_t *nodeCurrent;
|
|
-
|
|
- for (nindexCurrent = m_nindexAvailableNode - 1; nindexCurrent != NODE_INVALID_EMPTY; nindexCurrent--)
|
|
- {
|
|
- nodeCurrent = GetNode(nindexCurrent);
|
|
-
|
|
- if (nodeCurrent->offsetX == offsetX && nodeCurrent->offsetY == offsetY)
|
|
- {
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- return nindexCurrent;
|
|
+ int64_t key = PackCoord(offsetX, offsetY);
|
|
+ if (m_nodeCoordSet.find(key) == m_nodeCoordSet.end())
|
|
+ return NODE_INVALID_EMPTY;
|
|
+
|
|
+ // Caller only tests != NODE_INVALID_EMPTY; any non-negative value suffices.
|
|
+ return 0;
|
|
}
|
|
|
|
void CLocalNav::AddPathNodes(node_index_t nindexSource, BOOL fNoMonsters)
|
|
@@ -297,6 +308,7 @@ node_index_t CLocalNav::FindPath(Vector &vecStart, Vector &vecDest, float flTarg
|
|
|
|
m_vecStartingLoc = vecStart;
|
|
m_nindexAvailableNode = 0;
|
|
+ m_nodeCoordSet.clear();
|
|
|
|
AddPathNodes(NODE_INVALID_EMPTY, fNoMonsters);
|
|
nIndexBest = GetBestNode(vecStart, vecDest);
|