summaryrefslogtreecommitdiffstats
path: root/src/esp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/esp.cpp')
-rw-r--r--src/esp.cpp41
1 files changed, 28 insertions, 13 deletions
diff --git a/src/esp.cpp b/src/esp.cpp
index 405dea7..50d7b5d 100644
--- a/src/esp.cpp
+++ b/src/esp.cpp
@@ -139,8 +139,10 @@ static bool model_is_friendly(const char *m) {
139 139
140// harmless wildlife that also happens to be CAI_BaseNPC 140// harmless wildlife that also happens to be CAI_BaseNPC
141static bool model_is_neutral(const char *m) { 141static bool model_is_neutral(const char *m) {
142 // Lamarr is Kleiner's pet headcrab: scripted and harmless, and the user
143 // wants her shown neutral rather than hostile.
142 static const char *patterns[] = {"crow", "gull", "pigeon", "seagull", 144 static const char *patterns[] = {"crow", "gull", "pigeon", "seagull",
143 "bird", nullptr}; 145 "bird", "Lamarr", nullptr};
144 if (!m) return false; 146 if (!m) return false;
145 for (int i = 0; patterns[i]; i++) 147 for (int i = 0; patterns[i]; i++)
146 if (strstr(m, patterns[i])) 148 if (strstr(m, patterns[i]))
@@ -155,42 +157,55 @@ static bool model_is_floor_turret(const char *m) {
155static bool npc_is_friendly(int idx, const char *model, int local_idx, 157static bool npc_is_friendly(int idx, const char *model, int local_idx,
156 bool &neutral) { 158 bool &neutral) {
157 int rel = server_npc_relation(idx, local_idx); 159 int rel = server_npc_relation(idx, local_idx);
160 int state = server_npc_state(idx);
158 int turret = -1; 161 int turret = -1;
159 // Citizen-built and Alyx-hacked turrets never add an m_Relationship row; 162 // Citizen-built and Alyx-hacked turrets never add an m_Relationship row;
160 // their Classify() (CLASS_PLAYER_ALLY) comes from server runtime state. 163 // their Classify() (CLASS_PLAYER_ALLY) comes from server runtime state.
161 if (model_is_floor_turret(model)) 164 if (model_is_floor_turret(model))
162 turret = server_npc_turret_flags(idx); 165 turret = server_npc_turret_flags(idx);
163 // Debug-only: relation values are the authoritative answer and are the 166 // Debug-only: relation/state changes are the authoritative signals and the
164 // first thing to check when a friendly NPC still looks hostile. Logged only 167 // first thing to check when a friendly NPC still looks hostile.
165 // when an entity's relation changes, so this does not flood the log.
166 static int rel_cache[2048]; 168 static int rel_cache[2048];
167 static bool rel_cache_init = false; 169 static int state_cache[2048];
168 if (!rel_cache_init) { 170 static bool cache_init = false;
171 if (!cache_init) {
169 for (int i = 0; i < 2048; i++) 172 for (int i = 0; i < 2048; i++)
170 rel_cache[i] = -999; 173 rel_cache[i] = state_cache[i] = -999;
171 rel_cache_init = true; 174 cache_init = true;
172 } 175 }
173 if (idx > 0 && idx < 2048 && rel_cache[idx] != rel) { 176 if (idx > 0 && idx < 2048 &&
177 (rel_cache[idx] != rel || state_cache[idx] != state)) {
174 rel_cache[idx] = rel; 178 rel_cache[idx] = rel;
175 logd("npc %d (%s): relation=%d followtarget=%d turret=%d local=%d", idx, 179 state_cache[idx] = state;
176 model ? model : "?", rel, 180 logd("npc %d (%s): relation=%d state=%d followtarget=%d turret=%d "
181 "local=%d", idx, model ? model : "?", rel, state,
177 (int)server_npc_has_follow_target(idx), turret, local_idx); 182 (int)server_npc_has_follow_target(idx), turret, local_idx);
178 } 183 }
179 if (rel == 3) { // D_LI 184 if (rel == 3) { // D_LI
180 neutral = false; 185 neutral = false;
181 return true; 186 return true;
182 } 187 }
188 if (turret > 0) { // citizen-built / Alyx-hacked
189 neutral = false;
190 return true;
191 }
183 if (rel == 4) { // D_NU 192 if (rel == 4) { // D_NU
184 neutral = true; 193 neutral = true;
185 return false; 194 return false;
186 } 195 }
196 // NPC_STATE_SCRIPT = 4: cutscene actors and scripted pets are passive even
197 // when their class relationship says hate (Lamarr, scripted Combine, ...).
198 if (state == 4) {
199 neutral = true;
200 return false;
201 }
187 if (rel == 1 || rel == 2) { // D_HT / D_FR 202 if (rel == 1 || rel == 2) { // D_HT / D_FR
188 neutral = false; 203 neutral = false;
189 return false; 204 return false;
190 } 205 }
191 if (turret >= 0) { 206 if (turret >= 0) { // ordinary floor turret
192 neutral = false; 207 neutral = false;
193 return turret != 0; 208 return false;
194 } 209 }
195 // Bugbait-controlled antlions follow a target even when their default 210 // Bugbait-controlled antlions follow a target even when their default
196 // relationship was never rewritten. 211 // relationship was never rewritten.