diff options
Diffstat (limited to 'src/menu.cpp')
| -rw-r--r-- | src/menu.cpp | 107 |
1 files changed, 102 insertions, 5 deletions
diff --git a/src/menu.cpp b/src/menu.cpp index 269174d..56f8c95 100644 --- a/src/menu.cpp +++ b/src/menu.cpp | |||
| @@ -30,7 +30,7 @@ void init_conmsg() { | |||
| 30 | // menu tree structure | 30 | // menu tree structure |
| 31 | // --------------------------------------------------------------------------- | 31 | // --------------------------------------------------------------------------- |
| 32 | 32 | ||
| 33 | enum NodeType { NODE_ROOT, NODE_FEATURE, NODE_TOGGLE, NODE_BIND }; | 33 | enum NodeType { NODE_ROOT, NODE_FEATURE, NODE_TOGGLE, NODE_BIND, NODE_VALUE }; |
| 34 | 34 | ||
| 35 | struct MenuNode { | 35 | struct MenuNode { |
| 36 | NodeType type; | 36 | NodeType type; |
| @@ -43,6 +43,10 @@ struct MenuNode { | |||
| 43 | bool *active_ptr; // NODE_TOGGLE: pointer to the active flag | 43 | bool *active_ptr; // NODE_TOGGLE: pointer to the active flag |
| 44 | int *bind_ptr; // NODE_BIND: pointer to the key binding (SDL scancode) | 44 | int *bind_ptr; // NODE_BIND: pointer to the key binding (SDL scancode) |
| 45 | const char *bind_name; // NODE_BIND: current bind display name | 45 | const char *bind_name; // NODE_BIND: current bind display name |
| 46 | int *value_ptr = nullptr; // NODE_VALUE: pointer to the value | ||
| 47 | int value_min = 0; | ||
| 48 | int value_max = 0; | ||
| 49 | int value_step = 0; | ||
| 46 | }; | 50 | }; |
| 47 | 51 | ||
| 48 | // feature data | 52 | // feature data |
| @@ -58,6 +62,20 @@ static FeatureState g_abh{true, 0}; | |||
| 58 | static FeatureState g_esp{true, 0}; | 62 | static FeatureState g_esp{true, 0}; |
| 59 | static FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in menu | 63 | static FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in menu |
| 60 | 64 | ||
| 65 | // Aimbot bone checklist. Head defaults on (v1 behaviour). | ||
| 66 | enum { | ||
| 67 | AIM_BONE_HEAD = 0, | ||
| 68 | AIM_BONE_TORSO, | ||
| 69 | AIM_BONE_LARM, | ||
| 70 | AIM_BONE_RARM, | ||
| 71 | AIM_BONE_LLEG, | ||
| 72 | AIM_BONE_RLEG, | ||
| 73 | AIM_BONE_COUNT | ||
| 74 | }; | ||
| 75 | static bool g_aim_bones[AIM_BONE_COUNT] = {true, false, false, | ||
| 76 | false, false, false}; | ||
| 77 | static int g_aim_smooth = 5; // degrees per tick | ||
| 78 | |||
| 61 | // ESP sub-options (menu "ESP" children). Defaults match the pre-option | 79 | // ESP sub-options (menu "ESP" children). Defaults match the pre-option |
| 62 | // behaviour: everything on. | 80 | // behaviour: everything on. |
| 63 | static bool g_esp_opt[ESP_OPT_COUNT] = {true, true, true, true, true}; | 81 | static bool g_esp_opt[ESP_OPT_COUNT] = {true, true, true, true, true}; |
| @@ -81,6 +99,17 @@ static MenuNode g_esp_opt_nodes[ESP_OPT_COUNT] = { | |||
| 81 | static MenuNode g_aimbot_feat{NODE_FEATURE, "Aimbot", false, 1, {}, nullptr, nullptr, nullptr}; | 99 | static MenuNode g_aimbot_feat{NODE_FEATURE, "Aimbot", false, 1, {}, nullptr, nullptr, nullptr}; |
| 82 | static MenuNode g_aimbot_active{NODE_TOGGLE, "Active", false, 0, {}, &g_aimbot.active, nullptr, nullptr}; | 100 | static MenuNode g_aimbot_active{NODE_TOGGLE, "Active", false, 0, {}, &g_aimbot.active, nullptr, nullptr}; |
| 83 | static MenuNode g_aimbot_bind{NODE_BIND, "Bind", false, 0, {}, nullptr, &g_aimbot.bind, nullptr}; | 101 | static MenuNode g_aimbot_bind{NODE_BIND, "Bind", false, 0, {}, nullptr, &g_aimbot.bind, nullptr}; |
| 102 | static MenuNode g_aimbot_bones_feat{NODE_FEATURE, "Bones", false, 0, {}, nullptr, nullptr, nullptr}; | ||
| 103 | static MenuNode g_aimbot_bone_nodes[AIM_BONE_COUNT] = { | ||
| 104 | {NODE_TOGGLE, "Head", false, 0, {}, &g_aim_bones[AIM_BONE_HEAD], nullptr, nullptr}, | ||
| 105 | {NODE_TOGGLE, "Torso", false, 0, {}, &g_aim_bones[AIM_BONE_TORSO], nullptr, nullptr}, | ||
| 106 | {NODE_TOGGLE, "Left arm", false, 0, {}, &g_aim_bones[AIM_BONE_LARM], nullptr, nullptr}, | ||
| 107 | {NODE_TOGGLE, "Right arm", false, 0, {}, &g_aim_bones[AIM_BONE_RARM], nullptr, nullptr}, | ||
| 108 | {NODE_TOGGLE, "Left leg", false, 0, {}, &g_aim_bones[AIM_BONE_LLEG], nullptr, nullptr}, | ||
| 109 | {NODE_TOGGLE, "Right leg", false, 0, {}, &g_aim_bones[AIM_BONE_RLEG], nullptr, nullptr}, | ||
| 110 | }; | ||
| 111 | static MenuNode g_aimbot_smooth_node{NODE_VALUE, "Smoothness", false, 0, {}, nullptr, | ||
| 112 | nullptr, nullptr, &g_aim_smooth, 1, 45, 1}; | ||
| 84 | 113 | ||
| 85 | static MenuNode *g_visible[32]; // flattened visible nodes for arrow navigation | 114 | static MenuNode *g_visible[32]; // flattened visible nodes for arrow navigation |
| 86 | static int g_visible_count = 0; | 115 | static int g_visible_count = 0; |
| @@ -96,7 +125,12 @@ static void build_tree() { | |||
| 96 | g_esp_feat.children[0] = &g_esp_active; | 125 | g_esp_feat.children[0] = &g_esp_active; |
| 97 | g_aimbot_feat.children[0] = &g_aimbot_active; | 126 | g_aimbot_feat.children[0] = &g_aimbot_active; |
| 98 | g_aimbot_feat.children[1] = &g_aimbot_bind; | 127 | g_aimbot_feat.children[1] = &g_aimbot_bind; |
| 99 | g_aimbot_feat.child_count = 2; | 128 | g_aimbot_feat.children[2] = &g_aimbot_bones_feat; |
| 129 | g_aimbot_feat.children[3] = &g_aimbot_smooth_node; | ||
| 130 | g_aimbot_feat.child_count = 4; | ||
| 131 | for (int i = 0; i < AIM_BONE_COUNT; i++) | ||
| 132 | g_aimbot_bones_feat.children[i] = &g_aimbot_bone_nodes[i]; | ||
| 133 | g_aimbot_bones_feat.child_count = AIM_BONE_COUNT; | ||
| 100 | for (int i = 0; i < ESP_OPT_COUNT; i++) | 134 | for (int i = 0; i < ESP_OPT_COUNT; i++) |
| 101 | g_esp_feat.children[i + 1] = &g_esp_opt_nodes[i]; | 135 | g_esp_feat.children[i + 1] = &g_esp_opt_nodes[i]; |
| 102 | g_esp_feat.child_count = ESP_OPT_COUNT + 1; | 136 | g_esp_feat.child_count = ESP_OPT_COUNT + 1; |
| @@ -115,6 +149,7 @@ static void flatten(MenuNode *node, int depth) { | |||
| 115 | node->type = (depth == 0) ? NODE_ROOT | 149 | node->type = (depth == 0) ? NODE_ROOT |
| 116 | : (node->child_count > 0) ? NODE_FEATURE | 150 | : (node->child_count > 0) ? NODE_FEATURE |
| 117 | : (node->active_ptr) ? NODE_TOGGLE | 151 | : (node->active_ptr) ? NODE_TOGGLE |
| 152 | : (node->value_ptr) ? NODE_VALUE | ||
| 118 | : NODE_BIND; | 153 | : NODE_BIND; |
| 119 | g_depth[g_visible_count] = depth; | 154 | g_depth[g_visible_count] = depth; |
| 120 | g_visible[g_visible_count++] = node; | 155 | g_visible[g_visible_count++] = node; |
| @@ -167,8 +202,13 @@ static void config_save() { | |||
| 167 | fprintf(f, "[bhop]\nactive=%d\nbind=%d\nautostrafe=%d\n", g_bhop.active, | 202 | fprintf(f, "[bhop]\nactive=%d\nbind=%d\nautostrafe=%d\n", g_bhop.active, |
| 168 | g_bhop.bind, g_bhop_autostrafe); | 203 | g_bhop.bind, g_bhop_autostrafe); |
| 169 | fprintf(f, "[abh]\nactive=%d\nbind=%d\n", g_abh.active, g_abh.bind); | 204 | fprintf(f, "[abh]\nactive=%d\nbind=%d\n", g_abh.active, g_abh.bind); |
| 170 | fprintf(f, "[aimbot]\nactive=%d\nbind=%d\n", g_aimbot.active, | 205 | fprintf(f, "[aimbot]\nactive=%d\nbind=%d\nsmooth=%d\n" |
| 171 | g_aimbot.bind); | 206 | "bone_head=%d\nbone_torso=%d\nbone_larm=%d\nbone_rarm=%d\n" |
| 207 | "bone_lleg=%d\nbone_rleg=%d\n", | ||
| 208 | g_aimbot.active, g_aimbot.bind, g_aim_smooth, | ||
| 209 | g_aim_bones[AIM_BONE_HEAD], g_aim_bones[AIM_BONE_TORSO], | ||
| 210 | g_aim_bones[AIM_BONE_LARM], g_aim_bones[AIM_BONE_RARM], | ||
| 211 | g_aim_bones[AIM_BONE_LLEG], g_aim_bones[AIM_BONE_RLEG]); | ||
| 172 | fprintf(f, "[esp]\nactive=%d\nbind=%d\nneutral=%d\nhealthbar=%d\n" | 212 | fprintf(f, "[esp]\nactive=%d\nbind=%d\nneutral=%d\nhealthbar=%d\n" |
| 173 | "healthnum=%d\nname=%d\nskeleton=%d\n", | 213 | "healthnum=%d\nname=%d\nskeleton=%d\n", |
| 174 | g_esp.active, g_esp.bind, g_esp_opt[ESP_OPT_SHOW_NEUTRAL], | 214 | g_esp.active, g_esp.bind, g_esp_opt[ESP_OPT_SHOW_NEUTRAL], |
| @@ -184,7 +224,7 @@ static void config_load() { | |||
| 184 | return; | 224 | return; |
| 185 | char line[256]; | 225 | char line[256]; |
| 186 | FeatureState *cur = nullptr; | 226 | FeatureState *cur = nullptr; |
| 187 | bool in_esp = false, in_bhop = false; | 227 | bool in_esp = false, in_bhop = false, in_aim = false; |
| 188 | while (fgets(line, sizeof(line), f)) { | 228 | while (fgets(line, sizeof(line), f)) { |
| 189 | line[strcspn(line, "\r\n")] = 0; | 229 | line[strcspn(line, "\r\n")] = 0; |
| 190 | if (line[0] == '[') { | 230 | if (line[0] == '[') { |
| @@ -200,6 +240,7 @@ static void config_load() { | |||
| 200 | cur = nullptr; | 240 | cur = nullptr; |
| 201 | in_esp = (cur == &g_esp); | 241 | in_esp = (cur == &g_esp); |
| 202 | in_bhop = (cur == &g_bhop); | 242 | in_bhop = (cur == &g_bhop); |
| 243 | in_aim = (cur == &g_aimbot); | ||
| 203 | } else if (cur) { | 244 | } else if (cur) { |
| 204 | char *eq = strchr(line, '='); | 245 | char *eq = strchr(line, '='); |
| 205 | if (!eq) | 246 | if (!eq) |
| @@ -209,6 +250,26 @@ static void config_load() { | |||
| 209 | if (in_bhop && strcmp(key, "autostrafe") == 0) { | 250 | if (in_bhop && strcmp(key, "autostrafe") == 0) { |
| 210 | g_bhop_autostrafe = atoi(val) != 0; | 251 | g_bhop_autostrafe = atoi(val) != 0; |
| 211 | } | 252 | } |
| 253 | if (in_aim) { | ||
| 254 | if (strcmp(key, "smooth") == 0) { | ||
| 255 | int v = atoi(val); | ||
| 256 | if (v < 1) v = 1; | ||
| 257 | if (v > 45) v = 45; | ||
| 258 | g_aim_smooth = v; | ||
| 259 | } else if (strcmp(key, "bone_head") == 0) { | ||
| 260 | g_aim_bones[AIM_BONE_HEAD] = atoi(val) != 0; | ||
| 261 | } else if (strcmp(key, "bone_torso") == 0) { | ||
| 262 | g_aim_bones[AIM_BONE_TORSO] = atoi(val) != 0; | ||
| 263 | } else if (strcmp(key, "bone_larm") == 0) { | ||
| 264 | g_aim_bones[AIM_BONE_LARM] = atoi(val) != 0; | ||
| 265 | } else if (strcmp(key, "bone_rarm") == 0) { | ||
| 266 | g_aim_bones[AIM_BONE_RARM] = atoi(val) != 0; | ||
| 267 | } else if (strcmp(key, "bone_lleg") == 0) { | ||
| 268 | g_aim_bones[AIM_BONE_LLEG] = atoi(val) != 0; | ||
| 269 | } else if (strcmp(key, "bone_rleg") == 0) { | ||
| 270 | g_aim_bones[AIM_BONE_RLEG] = atoi(val) != 0; | ||
| 271 | } | ||
| 272 | } | ||
| 212 | if (in_esp) { | 273 | if (in_esp) { |
| 213 | if (strcmp(key, "neutral") == 0) | 274 | if (strcmp(key, "neutral") == 0) |
| 214 | g_esp_opt[ESP_OPT_SHOW_NEUTRAL] = atoi(val) != 0; | 275 | g_esp_opt[ESP_OPT_SHOW_NEUTRAL] = atoi(val) != 0; |
| @@ -346,6 +407,25 @@ bool esp_option(int opt) { | |||
| 346 | 407 | ||
| 347 | bool bhop_autostrafe_enabled() { return g_bhop_autostrafe; } | 408 | bool bhop_autostrafe_enabled() { return g_bhop_autostrafe; } |
| 348 | 409 | ||
| 410 | unsigned aimbot_bone_mask() { | ||
| 411 | unsigned m = 0; | ||
| 412 | if (g_aim_bones[AIM_BONE_HEAD]) | ||
| 413 | m |= 1u << 1; // HITGROUP_HEAD | ||
| 414 | if (g_aim_bones[AIM_BONE_TORSO]) | ||
| 415 | m |= (1u << 2) | (1u << 3); // chest + stomach | ||
| 416 | if (g_aim_bones[AIM_BONE_LARM]) | ||
| 417 | m |= 1u << 4; | ||
| 418 | if (g_aim_bones[AIM_BONE_RARM]) | ||
| 419 | m |= 1u << 5; | ||
| 420 | if (g_aim_bones[AIM_BONE_LLEG]) | ||
| 421 | m |= 1u << 6; | ||
| 422 | if (g_aim_bones[AIM_BONE_RLEG]) | ||
| 423 | m |= 1u << 7; | ||
| 424 | return m; | ||
| 425 | } | ||
| 426 | |||
| 427 | int aimbot_smooth_step() { return g_aim_smooth; } | ||
| 428 | |||
| 349 | static void menu_handle_input() { | 429 | static void menu_handle_input() { |
| 350 | poll_keyboard(); | 430 | poll_keyboard(); |
| 351 | 431 | ||
| @@ -415,6 +495,19 @@ static void menu_handle_input() { | |||
| 415 | g_selected++; | 495 | g_selected++; |
| 416 | return; | 496 | return; |
| 417 | } | 497 | } |
| 498 | if (key_pressed(SCAN_LEFT) || key_pressed(SCAN_RIGHT)) { | ||
| 499 | MenuNode *n = g_visible[g_selected]; | ||
| 500 | if (n->type == NODE_VALUE && n->value_ptr) { | ||
| 501 | int dir = key_pressed(SCAN_RIGHT) ? 1 : -1; | ||
| 502 | int step = n->value_step ? n->value_step : 1; | ||
| 503 | int v = *n->value_ptr + dir * step; | ||
| 504 | if (v < n->value_min) v = n->value_min; | ||
| 505 | if (v > n->value_max) v = n->value_max; | ||
| 506 | *n->value_ptr = v; | ||
| 507 | config_save(); | ||
| 508 | } | ||
| 509 | return; | ||
| 510 | } | ||
| 418 | if (key_pressed(SCAN_ENTER)) { | 511 | if (key_pressed(SCAN_ENTER)) { |
| 419 | MenuNode *n = g_visible[g_selected]; | 512 | MenuNode *n = g_visible[g_selected]; |
| 420 | if (n->child_count > 0) { | 513 | if (n->child_count > 0) { |
| @@ -599,6 +692,10 @@ void outer_draw() { | |||
| 599 | snprintf(bn[fi], 32, "[%s]", scancode_name(*n->bind_ptr)); | 692 | snprintf(bn[fi], 32, "[%s]", scancode_name(*n->bind_ptr)); |
| 600 | draw_text(270, 10 + i * 20, bn[fi]); | 693 | draw_text(270, 10 + i * 20, bn[fi]); |
| 601 | } | 694 | } |
| 695 | } else if (n->type == NODE_VALUE) { | ||
| 696 | char vb[32]; | ||
| 697 | snprintf(vb, sizeof(vb), "%d deg/tick", *n->value_ptr); | ||
| 698 | draw_text(270, 10 + i * 20, vb); | ||
| 602 | } | 699 | } |
| 603 | } | 700 | } |
| 604 | surf_pop_make_current(panel); | 701 | surf_pop_make_current(panel); |
