summaryrefslogtreecommitdiffstats
path: root/src/esp.cpp
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-05 20:32:59 +0100
committersalmonik <salmonik@tuta.io>2026-11-05 20:32:59 +0100
commit57b53d579f32f094c1cdefad62a6224baf270e0d (patch)
tree67b335b8ac0933078628c0e7b746a4bb253533fd /src/esp.cpp
parentItems: keep health chargers visible, add charger diagnostics (diff)
downloadhl2h-57b53d579f32f094c1cdefad62a6224baf270e0d.tar.gz
hl2h-57b53d579f32f094c1cdefad62a6224baf270e0d.zip
Items: server ammo counts and frag-grenade type
- local_ammo now prefers the authoritative server m_iAmmo array (header skip) and only falls back to the client netvar array. The client offset can be off by an element, which made "full" checks flicker as other ammo was spent. - Frag grenade pickups were falling through to a generic "Ammo" label with ammo_type=-1, so the usable filter never ran. w_grenade/w_frag/ items/grenade/frag_grenade are now "Frag grenade" and map to m_iAmmo[11] (sk_max_grenade, stock 5); AR2/SMG1 grenade variants map to m_iAmmo[8].
Diffstat (limited to '')
-rw-r--r--src/esp.cpp31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/esp.cpp b/src/esp.cpp
index 3785107..7ddc86b 100644
--- a/src/esp.cpp
+++ b/src/esp.cpp
@@ -2419,10 +2419,15 @@ static int item_ammo_type(const char *model) {
2419 item_icontains(model, "w_rocket_launcher")) 2419 item_icontains(model, "w_rocket_launcher"))
2420 return 7; 2420 return 7;
2421 if (item_icontains(model, "ar2_grenade") || 2421 if (item_icontains(model, "ar2_grenade") ||
2422 item_icontains(model, "ammocrate_smg2")) 2422 item_icontains(model, "ammocrate_smg2") ||
2423 item_icontains(model, "smg1_grenade") ||
2424 item_icontains(model, "smg_grenade"))
2423 return 8; 2425 return 8;
2424 if (item_icontains(model, "ammocrate_grenade") || 2426 if (item_icontains(model, "ammocrate_grenade") ||
2425 item_icontains(model, "w_grenade") || item_icontains(model, "w_frag")) 2427 item_icontains(model, "w_grenade") ||
2428 item_icontains(model, "w_frag") ||
2429 item_icontains(model, "frag_grenade") ||
2430 item_icontains(model, "items/grenade"))
2426 return 11; 2431 return 11;
2427 if (item_icontains(model, "w_smg1") || item_icontains(model, "w_smg2")) 2432 if (item_icontains(model, "w_smg1") || item_icontains(model, "w_smg2"))
2428 return 3; 2433 return 3;
@@ -2479,12 +2484,19 @@ static int ammo_max(int type) {
2479static int local_ammo(void *local_ent, int type) { 2484static int local_ammo(void *local_ent, int type) {
2480 if (type < 0 || type >= 32) 2485 if (type < 0 || type >= 32)
2481 return -1; 2486 return -1;
2487 // Prefer the authoritative server array; the client m_iAmmo netvar offset
2488 // can be off by an element, which made "full" counts flicker as other ammo
2489 // was spent. server_player_ammo already skips the CNetworkArray header.
2490 int local = engine_get_local_player();
2491 if (local > 0 && g_iface.engineserver) {
2492 resolve_server_netvars();
2493 int s = server_player_ammo(local, type);
2494 if (s >= 0)
2495 return s;
2496 }
2482 if (local_ent && g_net.ammo >= 0) 2497 if (local_ent && g_net.ammo >= 0)
2483 return *(int *)((uintptr_t)local_ent + g_net.ammo + type * 4); 2498 return *(int *)((uintptr_t)local_ent + g_net.ammo + type * 4);
2484 // Client array offset may not resolve; the listen-server player has the 2499 return -1;
2485 // same array in its datamap.
2486 int local = engine_get_local_player();
2487 return local > 0 ? server_player_ammo(local, type) : -1;
2488} 2500}
2489 2501
2490static int classify_item(const char *model, const char *cls, char *label, 2502static int classify_item(const char *model, const char *cls, char *label,
@@ -2610,6 +2622,13 @@ static int classify_item(const char *model, const char *cls, char *label,
2610 snprintf(label, outn, "AR2 grenade"); 2622 snprintf(label, outn, "AR2 grenade");
2611 return IK_AMMO; 2623 return IK_AMMO;
2612 } 2624 }
2625 if (item_icontains(model, "w_grenade") ||
2626 item_icontains(model, "w_frag") ||
2627 item_icontains(model, "frag_grenade") ||
2628 item_icontains(model, "items/grenade")) {
2629 snprintf(label, outn, "Frag grenade");
2630 return IK_AMMO;
2631 }
2613 if (item_icontains(model, "models/items/")) { 2632 if (item_icontains(model, "models/items/")) {
2614 snprintf(label, outn, "Ammo"); 2633 snprintf(label, outn, "Ammo");
2615 return IK_AMMO; 2634 return IK_AMMO;