From 1fa3b61163b233f6c8c6b86dfa196fb798a6f094 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 12:39:45 +0100 Subject: ESP: classify NPC damage immunity/armour/vulnerability - Resolve server m_takedamage (DAMAGE_NO/DAMAGE_EVENTS_ONLY = immune). - Classify gunship/strider/dropship as ARMORED (OnTakeDamage only accepts DMG_BLAST; only the RPG passes), and headcrab/antlion/manhack as VULN (gravity gun / physics impact). - ESP draws ARMORED/VULN/IMMUNE tags above the name (new "Damage tags" toggle, [esp] dmg). - Aimbot, silent aim, triggerbot and melee skip immune targets and armoured targets unless the active weapon is the RPG. --- src/server.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'src/server.cpp') diff --git a/src/server.cpp b/src/server.cpp index c2864c8..e9fd921 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -51,6 +51,7 @@ static int g_srv_followtarget = -1; static int g_srv_spawnflags = -1; static int g_srv_hacked = -1; static int g_srv_npcstate = -1; +static int g_srv_takedamage = -1; static bool g_srv_ready = false; static bool g_srv_checked = false; @@ -141,15 +142,17 @@ bool resolve_server_netvars() { g_srv_spawnflags = datamap_offset("m_spawnflags", FIELD_INTEGER, 0x4); g_srv_hacked = datamap_offset("m_bHackedByAlyx", FIELD_BOOLEAN); g_srv_npcstate = datamap_offset("m_NPCState", FIELD_INTEGER); + g_srv_takedamage = datamap_offset("m_takedamage", FIELD_INTEGER); 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", + "followtarget=%d spawnflags=%d hacked=%d npcstate=%d " + "takedamage=%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_spawnflags, g_srv_hacked, g_srv_npcstate, g_srv_takedamage); fail_logged = false; } else if (!fail_logged) { fail_logged = true; @@ -268,6 +271,18 @@ int server_npc_state(int idx) { return *(int *)((uintptr_t)base + g_srv_npcstate); } +// TAKEDAMAGE: 0 = DAMAGE_NO, 1 = DAMAGE_EVENTS_ONLY, 2 = DAMAGE_YES, +// 3 = DAMAGE_AIM. 0/1 cannot be damaged at all. +int server_npc_takedamage(int idx) { + if (!g_srv_ready || g_srv_takedamage < 0) + return -1; + void *base = nullptr; + server_entity_health(idx, nullptr, nullptr, &base); + if (!base) + return -1; + return *(int *)((uintptr_t)base + g_srv_takedamage); +} + bool server_npc_has_follow_target(int idx) { if (!g_srv_ready || g_srv_followtarget < 0) return false; -- cgit v1.2.3