From 293eda2bdce9d732fad168b5b6838bd89ce59fe8 Mon Sep 17 00:00:00 2001 From: salmonik Date: Tue, 27 Oct 2026 14:52:00 +0100 Subject: Melee killbot: 360-degree crowbar silent aim - New feature (default on): while the local player's active weapon is the crowbar, pick the nearest visible hostile NPC within the 75-unit crowbar range, sorted by distance to its collision AABB, and attack it through the normal silent-aim path (usercmd view + IN_ATTACK, movement preserved, rendered view restored at FRAME_RENDER_START). - Prefer the nearest visible hitbox center; fall back to the AABB center / closest point when bones are unavailable. Reuses the existing friendly / neutral and life-state filters and the world-only vischeck. - Detect the active weapon from the client m_hActiveWeapon handle, with the authoritative server m_hActiveWeapon handle as a fallback (client entity index from the low 16 bits). - While the crowbar is active and this feature is on, skip the gun aimbot, triggerbot and silent aim so they do not fight over the usercmd view. - Menu: Melee killbot -> Active; config [melee] active=... --- src/server.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/server.cpp') diff --git a/src/server.cpp b/src/server.cpp index 3766906..896ce3e 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -33,6 +33,7 @@ int g_srv_lifestate = -1; int g_srv_modelindex = -1; int g_srv_absvelocity = -1; int g_srv_velocity = -1; +int g_srv_activeweapon = -1; static bool g_srv_ready = false; static bool g_srv_checked = false; @@ -109,12 +110,14 @@ bool resolve_server_netvars() { g_srv_modelindex = datamap_offset("m_nModelIndex", 7); // FIELD_SHORT g_srv_absvelocity = datamap_offset("m_vecAbsVelocity", 3); // FIELD_VECTOR g_srv_velocity = datamap_offset("m_vecVelocity", 3); // FIELD_VECTOR + g_srv_activeweapon = datamap_offset("m_hActiveWeapon", 13); // FIELD_EHANDLE 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", + "modelindex=%d absvel=%d vel=%d activeweapon=%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_modelindex, g_srv_absvelocity, g_srv_velocity, + g_srv_activeweapon); fail_logged = false; } else if (!fail_logged) { fail_logged = true; @@ -194,3 +197,18 @@ bool server_set_velocity_z(int idx, float vz) { *(float *)((uintptr_t)base + g_srv_absvelocity + 8) = vz; return true; } + +// 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) { + if (!g_srv_ready || !g_iface.engineserver || g_srv_activeweapon <= 0) + return -1; + void *base = nullptr; + if (server_entity_health(idx, nullptr, nullptr, &base) < 0 || !base) + return -1; + uint32_t h = *(uint32_t *)((uintptr_t)base + g_srv_activeweapon); + if (h == 0xFFFFFFFFu) + return -1; + int wi = (int)(h & 0xFFFF); + return (wi > 0 && wi <= 4096) ? wi : -1; +} -- cgit v1.2.3