From 27c9ad766e1b1333922b4c14cbde9d9b77c8dab0 Mon Sep 17 00:00:00 2001 From: salmonik Date: Tue, 27 Oct 2026 15:22:19 +0100 Subject: Spread control: client-seed no-spread HL2's CBaseEntity::FireBullets seeds its RNG from the usercmd random_seed (m_bUseServerRandomSeed is false for HL2 weapons), so the client can select the 8-bit seed that puts CShotManipulator::ApplySpread closest to the center. - New feature Spread control -> Active / No spread (both default on). - Precompute the best seed for a single shot and for the shotgun's 8-shot primary (first pellet accurate) and 12-shot secondary windows using the engine's own RandomSeed/RandomFloat from libvstdlib. - Set cmd->random_seed on attack commands; note_modified repairs the CRC. - The random cone offset is neutralized, but the cone size, the pistol accuracy penalty, server view punch and any damage falloff remain server-side; stock HL2 has no distance damage falloff. --- src/menu.cpp | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'src/menu.cpp') diff --git a/src/menu.cpp b/src/menu.cpp index f590d69..9dffc9e 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -40,7 +40,7 @@ struct MenuNode { const char *label; bool expanded; // for root/feature: whether children are visible int child_count; - MenuNode *children[8]; // max children per node + MenuNode *children[12]; // max children per node // leaf data bool *active_ptr; // NODE_TOGGLE: pointer to the active flag @@ -65,6 +65,8 @@ static FeatureState g_abh{true, 0}; static FeatureState g_jumpbug{true, 0}; static bool g_jumpbug_assist = false; static FeatureState g_melee{true, 0}; +static FeatureState g_spread{true, 0}; +static bool g_spread_no_spread = true; static FeatureState g_esp{true, 0}; static FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in menu static FeatureState g_triggerbot{true, 603}; // default Mouse4 @@ -104,6 +106,9 @@ static MenuNode g_jumpbug_active{NODE_TOGGLE, "Active", false, 0, {}, &g_jumpbug static MenuNode g_jumpbug_assist_node{NODE_TOGGLE, "Assist timing", false, 0, {}, &g_jumpbug_assist, nullptr, nullptr}; static MenuNode g_melee_feat{NODE_FEATURE, "Melee killbot", false, 1, {}, nullptr, nullptr, nullptr}; static MenuNode g_melee_active{NODE_TOGGLE, "Active", false, 0, {}, &g_melee.active, nullptr, nullptr}; +static MenuNode g_spread_feat{NODE_FEATURE, "Spread control", false, 1, {}, nullptr, nullptr, nullptr}; +static MenuNode g_spread_active{NODE_TOGGLE, "Active", false, 0, {}, &g_spread.active, nullptr, nullptr}; +static MenuNode g_spread_no_spread_node{NODE_TOGGLE, "No spread", false, 0, {}, &g_spread_no_spread, nullptr, nullptr}; static MenuNode g_esp_feat{NODE_FEATURE, "ESP", false, 1, {}, nullptr, nullptr, nullptr}; static MenuNode g_esp_active{NODE_TOGGLE, "Active", false, 0, {}, &g_esp.active, nullptr, nullptr}; static MenuNode g_esp_opt_nodes[ESP_OPT_COUNT] = { @@ -161,6 +166,9 @@ static void build_tree() { g_jumpbug_feat.child_count = 2; g_melee_feat.children[0] = &g_melee_active; g_melee_feat.child_count = 1; + g_spread_feat.children[0] = &g_spread_active; + g_spread_feat.children[1] = &g_spread_no_spread_node; + g_spread_feat.child_count = 2; g_esp_feat.children[0] = &g_esp_active; g_aimbot_feat.children[0] = &g_aimbot_active; g_aimbot_feat.children[1] = &g_aimbot_bind; @@ -187,11 +195,12 @@ static void build_tree() { g_root.children[1] = &g_abh_feat; g_root.children[2] = &g_jumpbug_feat; g_root.children[3] = &g_melee_feat; - g_root.children[4] = &g_esp_feat; - g_root.children[5] = &g_aimbot_feat; - g_root.children[6] = &g_triggerbot_feat; - g_root.children[7] = &g_silentaim_feat; - g_root.child_count = 8; + g_root.children[4] = &g_spread_feat; + g_root.children[5] = &g_esp_feat; + g_root.children[6] = &g_aimbot_feat; + g_root.children[7] = &g_triggerbot_feat; + g_root.children[8] = &g_silentaim_feat; + g_root.child_count = 9; } static int g_depth[48]; // depth of each visible row (for indentation) @@ -316,6 +325,8 @@ static void config_save() { fprintf(f, "[jumpbug]\nactive=%d\nassist=%d\n", g_jumpbug.active, (int)g_jumpbug_assist); fprintf(f, "[melee]\nactive=%d\n", g_melee.active); + fprintf(f, "[spread]\nactive=%d\nno_spread=%d\n", g_spread.active, + (int)g_spread_no_spread); fprintf(f, "[aimbot]\nactive=%d\nbind=%d\nsmooth=%d\nvischeck=%d\n" "fov=%d\nfov_circle=%d\n" "bone_head=%d\nbone_torso=%d\nbone_larm=%d\nbone_rarm=%d\n" @@ -346,7 +357,7 @@ static void config_load() { char line[256]; FeatureState *cur = nullptr; bool in_esp = false, in_bhop = false, in_aim = false, in_silent = false, - in_jumpbug = false; + in_jumpbug = false, in_spread = false; while (fgets(line, sizeof(line), f)) { line[strcspn(line, "\r\n")] = 0; if (line[0] == '[') { @@ -358,6 +369,8 @@ static void config_load() { cur = &g_jumpbug; else if (strstr(line, "[melee]")) cur = &g_melee; + else if (strstr(line, "[spread]")) + cur = &g_spread; else if (strstr(line, "[esp]")) cur = &g_esp; else if (strstr(line, "[aimbot]")) @@ -373,6 +386,7 @@ static void config_load() { in_aim = (cur == &g_aimbot); in_silent = (cur == &g_silentaim); in_jumpbug = (cur == &g_jumpbug); + in_spread = (cur == &g_spread); } else if (cur) { char *eq = strchr(line, '='); if (!eq) @@ -385,6 +399,9 @@ static void config_load() { if (in_jumpbug && strcmp(key, "assist") == 0) { g_jumpbug_assist = atoi(val) != 0; } + if (in_spread && strcmp(key, "no_spread") == 0) { + g_spread_no_spread = atoi(val) != 0; + } if (in_aim) { if (strcmp(key, "smooth") == 0) { int v = atoi(val); @@ -546,10 +563,10 @@ static bool key_pressed(int sc) { // feature gate queried from hl2h.cpp do_move(): feature must be Active AND // its bind key held (always-on when unbound). static FeatureState *feature_state(int feature) { - static FeatureState *feats[8] = {&g_bhop, &g_abh, &g_esp, - &g_aimbot, &g_triggerbot, &g_silentaim, - &g_jumpbug, &g_melee}; - if (feature < 0 || feature > 7) + static FeatureState *feats[9] = {&g_bhop, &g_abh, &g_esp, + &g_aimbot, &g_triggerbot, &g_silentaim, + &g_jumpbug, &g_melee, &g_spread}; + if (feature < 0 || feature > 8) return nullptr; return feats[feature]; } @@ -579,6 +596,8 @@ bool bhop_autostrafe_enabled() { return g_bhop_autostrafe; } bool jumpbug_assist_enabled() { return g_jumpbug_assist; } +bool spread_no_spread_enabled() { return g_spread_no_spread; } + unsigned aimbot_bone_mask() { unsigned m = 0; if (g_aim_bones[AIM_BONE_HEAD]) -- cgit v1.2.3