summaryrefslogtreecommitdiffstats
path: root/src/esp.cpp
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-04 17:25:31 +0100
committersalmonik <salmonik@tuta.io>2026-11-04 17:25:31 +0100
commit710e8cc59557bc95ed74af8726ea13012fde50c3 (patch)
treef1fd242c12d2ce5a939fbf1d3828e3546bc8f1cf /src/esp.cpp
parentNetvars: catch array element props and log the walk (diff)
downloadhl2h-710e8cc59557bc95ed74af8726ea13012fde50c3.tar.gz
hl2h-710e8cc59557bc95ed74af8726ea13012fde50c3.zip
Items: read ammo and inventory from the server arrays
The client m_iAmmo/m_hMyWeapons recv props still do not resolve, but the listen server has the same CBaseCombatCharacter arrays in its datamap. Resolve m_iAmmo and m_hMyWeapons there: - reserve ammo comes from server_player_ammo() when the client array is missing, so full-ammo filtering works (RPG rockets at 3); - the owned-weapon mask is filled from the server m_hMyWeapons[48] handles, so fallen weapons count as ammo before the player equips them. Widen the datamap field-size filter to 512 for the 192-byte handle array.
Diffstat (limited to 'src/esp.cpp')
-rw-r--r--src/esp.cpp33
1 files changed, 31 insertions, 2 deletions
diff --git a/src/esp.cpp b/src/esp.cpp
index 1d4a6a5..b4d3eee 100644
--- a/src/esp.cpp
+++ b/src/esp.cpp
@@ -2396,9 +2396,14 @@ static int ammo_max(int type) {
2396} 2396}
2397 2397
2398static int local_ammo(void *local_ent, int type) { 2398static int local_ammo(void *local_ent, int type) {
2399 if (!local_ent || g_net.ammo < 0 || type < 0 || type >= 32) 2399 if (type < 0 || type >= 32)
2400 return -1; 2400 return -1;
2401 return *(int *)((uintptr_t)local_ent + g_net.ammo + type * 4); 2401 if (local_ent && g_net.ammo >= 0)
2402 return *(int *)((uintptr_t)local_ent + g_net.ammo + type * 4);
2403 // Client array offset may not resolve; the listen-server player has the
2404 // same array in its datamap.
2405 int local = engine_get_local_player();
2406 return local > 0 ? server_player_ammo(local, type) : -1;
2402} 2407}
2403 2408
2404static int classify_item(const char *model, const char *cls, char *label, 2409static int classify_item(const char *model, const char *cls, char *label,
@@ -2627,6 +2632,30 @@ static void items_collect(int local_idx) {
2627 if (wt > 0) 2632 if (wt > 0)
2628 owned_mask |= 1u << wt; 2633 owned_mask |= 1u << wt;
2629 } 2634 }
2635 // Server-side inventory, independent of the client recv-table arrays.
2636 if (g_iface.engineserver) {
2637 for (int slot = 0; slot < 48; slot++) {
2638 uint32_t h = server_player_weapon(local_idx, slot);
2639 if (!item_handle_valid(h))
2640 continue;
2641 int wi = (int)(h & 0x7FF);
2642 if (wi <= 0 || wi > 4096)
2643 continue;
2644 void *wep = entitylist_get(wi);
2645 void *net = entity_networkable(wi);
2646 const char *wc = net ? entity_class_name(net, nullptr) : nullptr;
2647 const char *wm = wep ? entity_model_name(wep) : nullptr;
2648 if (!wm) {
2649 void *sb = nullptr;
2650 server_entity_health(wi, nullptr, nullptr, &sb);
2651 if (sb)
2652 wm = model_name_from_index(server_model_index(sb));
2653 }
2654 int wt = weapon_type_id(wm, wc);
2655 if (wt > 0)
2656 owned_mask |= 1u << wt;
2657 }
2658 }
2630 bool owned_weapon[WT_COUNT] = {}; 2659 bool owned_weapon[WT_COUNT] = {};
2631 for (int t = 1; t < WT_COUNT; t++) 2660 for (int t = 1; t < WT_COUNT; t++)
2632 owned_weapon[t] = (owned_mask & (1u << t)) != 0; 2661 owned_weapon[t] = (owned_mask & (1u << t)) != 0;