From 714262bcf759a238daf906de16e7b204712a104f Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 14:28:21 +0100 Subject: Add usable item filter, projectile ESP and gravity-gun melee - Items: "Only if usable" hides health tags at full health and armor at full suit. Health ceiling is the server player's m_iMaxHealth; armor uses the server m_ArmorValue against HL2's 100 cap. Fails open when unreadable. - Projectiles: new Visuals feature/card for thrown grenades, RPG rockets, helicopter bombs and AR2 balls. Fuse from server m_flDetonateTime vs engine time; radius from m_DmgRadius with per-type fallback; optional 24-segment radius ring and FRAG timer label. - Melee: the killbot now handles the gravity gun as well; only VULNERABLE targets, 1200-unit range, primary attack to launch the held object, and no aim-punch compensation because the launch uses EyeVectors. - Server/netvars: m_ArmorValue, m_flDetonateTime, m_DmgRadius. --- src/server.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) (limited to 'src/server.cpp') diff --git a/src/server.cpp b/src/server.cpp index 39bb162..40aa850 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -31,7 +31,9 @@ enum { FIELD_CHARACTER = 8, FIELD_EMBEDDED = 10, FIELD_CUSTOM = 11, - FIELD_EHANDLE = 13 + FIELD_EHANDLE = 13, + FIELD_TIME = 16, + FIELD_FLOAT = 1 }; // SF_FLOOR_TURRET_CITIZEN (npc_turret_floor.h). Citizen-built turrets @@ -53,6 +55,9 @@ static int g_srv_hacked = -1; static int g_srv_npcstate = -1; static int g_srv_takedamage = -1; static int g_srv_mapname = -1; +static int g_srv_armor = -1; +static int g_srv_detonate = -1; +static int g_srv_grenade_radius = -1; static bool g_srv_ready = false; static bool g_srv_checked = false; @@ -150,17 +155,22 @@ bool resolve_server_netvars() { g_srv_takedamage = datamap_offset("m_takedamage", FIELD_INTEGER); // CChangeLevel::m_szMapName is a char[cchMapNameMost] on trigger_changelevel. g_srv_mapname = datamap_offset("m_szMapName", FIELD_CHARACTER, 0x40, 0x4000); + // CBasePlayer::m_ArmorValue (int). + g_srv_armor = datamap_offset("m_ArmorValue", FIELD_INTEGER); + // CBaseGrenade fuse / blast radius (m_flDetonateTime is not networked). + g_srv_detonate = datamap_offset("m_flDetonateTime", FIELD_TIME); + g_srv_grenade_radius = datamap_offset("m_DmgRadius", FIELD_FLOAT); g_srv_ready = g_srv_health > 0; if (g_srv_ready) { logf("server datamap (%s): health=%d maxhealth=%d lifeste=%d " "modelindex=%d absvel=%d vel=%d activeweapon=%d relationship=%d " "followtarget=%d spawnflags=%d hacked=%d npcstate=%d " - "takedamage=%d mapname=%d", + "takedamage=%d mapname=%d armor=%d detonate=%d dmgradius=%d", g_server.path.c_str(), g_srv_health, g_srv_maxhealth, g_srv_lifestate, g_srv_modelindex, g_srv_absvelocity, g_srv_velocity, g_srv_activeweapon, g_srv_relationship, g_srv_followtarget, g_srv_spawnflags, g_srv_hacked, g_srv_npcstate, g_srv_takedamage, - g_srv_mapname); + g_srv_mapname, g_srv_armor, g_srv_detonate, g_srv_grenade_radius); fail_logged = false; } else if (!fail_logged) { fail_logged = true; @@ -425,6 +435,39 @@ bool server_set_velocity_z(int idx, float vz) { return true; } +// Local player's HEV suit armor from the authoritative server entity. +int server_player_armor(int idx) { + if (!g_srv_ready || g_srv_armor < 0) + return -1; + void *base = nullptr; + server_entity_health(idx, nullptr, nullptr, &base); + if (!base) + return -1; + return *(int *)((uintptr_t)base + g_srv_armor); +} + +// CBaseGrenade fuse time and blast radius from the server entity. Both are +// non-networked (m_flDetonateTime is commented out of the send table). +float server_grenade_detonate(int idx) { + if (!g_srv_ready || g_srv_detonate < 0) + return -1.0f; + void *base = nullptr; + server_entity_health(idx, nullptr, nullptr, &base); + if (!base) + return -1.0f; + return *(float *)((uintptr_t)base + g_srv_detonate); +} + +float server_grenade_radius(int idx) { + if (!g_srv_ready || g_srv_grenade_radius < 0) + return -1.0f; + void *base = nullptr; + server_entity_health(idx, nullptr, nullptr, &base); + if (!base) + return -1.0f; + return *(float *)((uintptr_t)base + g_srv_grenade_radius); +} + // Entity index of the player's active weapon from the authoritative server // entity. Used as a fallback if the client m_hActiveWeapon netvar is missing. int server_active_weapon(int idx) { -- cgit v1.2.3