summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--CONTEXT.md3
-rw-r--r--src/esp.cpp22
2 files changed, 21 insertions, 4 deletions
diff --git a/CONTEXT.md b/CONTEXT.md
index a3cbdf8..737a6b2 100644
--- a/CONTEXT.md
+++ b/CONTEXT.md
@@ -286,6 +286,9 @@ vocabulary / decisions.
286- Only `item_item_crate` and `item_beacon_crate` are tagged as supply crates. 286- Only `item_item_crate` and `item_beacon_crate` are tagged as supply crates.
287 Other breakable crates are intentionally ignored; crate chunk debris is 287 Other breakable crates are intentionally ignored; crate chunk debris is
288 skipped. 288 skipped.
289- Client `CPhysicsProp` entities often have `m_nModelIndex == 0`, including
290 item crates. The item scan falls back to the server entity's model index
291 (`server_model_index`) to recover the model name.
289 292
290## Roadmap / TODO 293## Roadmap / TODO
291 294
diff --git a/src/esp.cpp b/src/esp.cpp
index 2fb5d1b..ec3e94b 100644
--- a/src/esp.cpp
+++ b/src/esp.cpp
@@ -100,10 +100,9 @@ static const char *entity_class_name(void *net, void **out_cc) {
100 100
101// m_nModelIndex -> IVModelInfoClient(006)::GetModel/GetModelName. 101// m_nModelIndex -> IVModelInfoClient(006)::GetModel/GetModelName.
102// Itanium ABI: two dtor slots, so GetModel=2, GetModelName=4. 102// Itanium ABI: two dtor slots, so GetModel=2, GetModelName=4.
103static const char *entity_model_name(void *ent) { 103static const char *model_name_from_index(int modelindex) {
104 if (!g_iface.modelinfo || g_net.modelindex < 0) return nullptr; 104 if (!g_iface.modelinfo || modelindex <= 0)
105 int modelindex = *(int *)((uintptr_t)ent + g_net.modelindex); 105 return nullptr;
106 if (modelindex <= 0) return nullptr;
107 const void *model = 106 const void *model =
108 vfunc<GetModelFn>(g_iface.modelinfo, 2)(g_iface.modelinfo, modelindex); 107 vfunc<GetModelFn>(g_iface.modelinfo, 2)(g_iface.modelinfo, modelindex);
109 if (!model) 108 if (!model)
@@ -111,6 +110,12 @@ static const char *entity_model_name(void *ent) {
111 return vfunc<GetModelNameFn>(g_iface.modelinfo, 4)(g_iface.modelinfo, model); 110 return vfunc<GetModelNameFn>(g_iface.modelinfo, 4)(g_iface.modelinfo, model);
112} 111}
113 112
113static const char *entity_model_name(void *ent) {
114 if (!g_iface.modelinfo || g_net.modelindex < 0) return nullptr;
115 int modelindex = *(int *)((uintptr_t)ent + g_net.modelindex);
116 return model_name_from_index(modelindex);
117}
118
114// HL2 SP: generic NPCs (combine, metrocop, zombie, citizen, antlion, ...) all 119// HL2 SP: generic NPCs (combine, metrocop, zombie, citizen, antlion, ...) all
115// use the single client class "CAI_BaseNPC" — only special NPCs register their 120// use the single client class "CAI_BaseNPC" — only special NPCs register their
116// own class names (CNPC_Manhack, CNPC_Strider, CNPC_CombineGunship, ...). 121// own class names (CNPC_Manhack, CNPC_Strider, CNPC_CombineGunship, ...).
@@ -1629,6 +1634,7 @@ static void items_collect(int local_idx) {
1629 g_nitems = 0; 1634 g_nitems = 0;
1630 if (!g_iface.entitylist || g_net.origin < 0 || g_net.modelindex < 0) 1635 if (!g_iface.entitylist || g_net.origin < 0 || g_net.modelindex < 0)
1631 return; 1636 return;
1637 resolve_server_netvars();
1632 1638
1633 using Fn = int (*)(void *); 1639 using Fn = int (*)(void *);
1634 int hi = vfunc<Fn>(g_iface.entitylist, 6)(g_iface.entitylist); 1640 int hi = vfunc<Fn>(g_iface.entitylist, 6)(g_iface.entitylist);
@@ -1664,6 +1670,14 @@ static void items_collect(int local_idx) {
1664 continue; 1670 continue;
1665 const char *cls = entity_class_name(net, nullptr); 1671 const char *cls = entity_class_name(net, nullptr);
1666 const char *model = entity_model_name(ent); 1672 const char *model = entity_model_name(ent);
1673 // CPhysicsProp's client m_nModelIndex is often 0 (e.g. item_item_crate);
1674 // fall back to the server entity's model index, which is set in Spawn().
1675 if ((!model || !*model) && g_iface.engineserver) {
1676 void *sbase = nullptr;
1677 server_entity_health(idx, nullptr, nullptr, &sbase);
1678 if (sbase)
1679 model = model_name_from_index(server_model_index(sbase));
1680 }
1667 char label[128]; 1681 char label[128];
1668 int kind = classify_item(model, cls, label, sizeof(label)); 1682 int kind = classify_item(model, cls, label, sizeof(label));
1669 1683