diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-03 23:07:40 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-03 23:07:40 +0100 |
| commit | 3249caf17de0dcab005398995ef3e611b3f81131 (patch) | |
| tree | 159ed49a5010d330e52322572026e0bcd046717a /src/esp.cpp | |
| parent | AI: debug-log NPC relation changes (diff) | |
| download | hl2h-3249caf17de0dcab005398995ef3e611b3f81131.tar.gz hl2h-3249caf17de0dcab005398995ef3e611b3f81131.zip | |
AI: fix relationship lookup; classify citizen/hacked turrets
m_Relationship is DEFINE_UTLVECTOR (FIELD_CUSTOM), not FIELD_EMBEDDED, so the
datamap scan always returned -1 and every NPC fell back to the model
heuristic. Resolve it as FIELD_CUSTOM with an embedded fallback.
Floor turrets never add relationship rows when friendly: CNPC_FloorTurret
overrides Classify() to CLASS_PLAYER_ALLY for citizen-built
(SF_FLOOR_TURRET_CITIZEN) and Alyx-hacked turrets. Read m_spawnflags and
m_bHackedByAlyx from the server instead.
Widen the datamap offset window (0x4..0x4000) for derived-class fields and
log the new offsets plus turret state in the NPC debug line.
Diffstat (limited to 'src/esp.cpp')
| -rw-r--r-- | src/esp.cpp | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/src/esp.cpp b/src/esp.cpp index b09588f..40e00f6 100644 --- a/src/esp.cpp +++ b/src/esp.cpp | |||
| @@ -148,9 +148,18 @@ static bool model_is_neutral(const char *m) { | |||
| 148 | return false; | 148 | return false; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | static bool model_is_floor_turret(const char *m) { | ||
| 152 | return m && strstr(m, "floor_turret"); | ||
| 153 | } | ||
| 154 | |||
| 151 | static bool npc_is_friendly(int idx, const char *model, int local_idx, | 155 | static bool npc_is_friendly(int idx, const char *model, int local_idx, |
| 152 | bool &neutral) { | 156 | bool &neutral) { |
| 153 | int rel = server_npc_relation(idx, local_idx); | 157 | int rel = server_npc_relation(idx, local_idx); |
| 158 | int turret = -1; | ||
| 159 | // Citizen-built and Alyx-hacked turrets never add an m_Relationship row; | ||
| 160 | // their Classify() (CLASS_PLAYER_ALLY) comes from server runtime state. | ||
| 161 | if (model_is_floor_turret(model)) | ||
| 162 | turret = server_npc_turret_flags(idx); | ||
| 154 | // Debug-only: relation values are the authoritative answer and are the | 163 | // Debug-only: relation values are the authoritative answer and are the |
| 155 | // first thing to check when a friendly NPC still looks hostile. Logged only | 164 | // first thing to check when a friendly NPC still looks hostile. Logged only |
| 156 | // when an entity's relation changes, so this does not flood the log. | 165 | // when an entity's relation changes, so this does not flood the log. |
| @@ -163,9 +172,9 @@ static bool npc_is_friendly(int idx, const char *model, int local_idx, | |||
| 163 | } | 172 | } |
| 164 | if (idx > 0 && idx < 2048 && rel_cache[idx] != rel) { | 173 | if (idx > 0 && idx < 2048 && rel_cache[idx] != rel) { |
| 165 | rel_cache[idx] = rel; | 174 | rel_cache[idx] = rel; |
| 166 | logd("npc %d (%s): relation=%d followtarget=%d local=%d", idx, | 175 | logd("npc %d (%s): relation=%d followtarget=%d turret=%d local=%d", idx, |
| 167 | model ? model : "?", rel, | 176 | model ? model : "?", rel, |
| 168 | (int)server_npc_has_follow_target(idx), local_idx); | 177 | (int)server_npc_has_follow_target(idx), turret, local_idx); |
| 169 | } | 178 | } |
| 170 | if (rel == 3) { // D_LI | 179 | if (rel == 3) { // D_LI |
| 171 | neutral = false; | 180 | neutral = false; |
| @@ -179,6 +188,10 @@ static bool npc_is_friendly(int idx, const char *model, int local_idx, | |||
| 179 | neutral = false; | 188 | neutral = false; |
| 180 | return false; | 189 | return false; |
| 181 | } | 190 | } |
| 191 | if (turret >= 0) { | ||
| 192 | neutral = false; | ||
| 193 | return turret != 0; | ||
| 194 | } | ||
| 182 | // Bugbait-controlled antlions follow a target even when their default | 195 | // Bugbait-controlled antlions follow a target even when their default |
| 183 | // relationship was never rewritten. | 196 | // relationship was never rewritten. |
| 184 | if (model && strstr(model, "antlion") && | 197 | if (model && strstr(model, "antlion") && |
