java-topology/defects/regamedll-0002/patch/regamedll-0002.patch

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