summaryrefslogtreecommitdiffstats
path: root/src/menu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/menu.cpp')
-rw-r--r--src/menu.cpp107
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
33enum NodeType { NODE_ROOT, NODE_FEATURE, NODE_TOGGLE, NODE_BIND }; 33enum NodeType { NODE_ROOT, NODE_FEATURE, NODE_TOGGLE, NODE_BIND, NODE_VALUE };
34 34
35struct MenuNode { 35struct 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};
58static FeatureState g_esp{true, 0}; 62static FeatureState g_esp{true, 0};
59static FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in menu 63static FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in menu
60 64
65// Aimbot bone checklist. Head defaults on (v1 behaviour).
66enum {
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};
75static bool g_aim_bones[AIM_BONE_COUNT] = {true, false, false,
76 false, false, false};
77static 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.
63static bool g_esp_opt[ESP_OPT_COUNT] = {true, true, true, true, true}; 81static 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] = {
81static MenuNode g_aimbot_feat{NODE_FEATURE, "Aimbot", false, 1, {}, nullptr, nullptr, nullptr}; 99static MenuNode g_aimbot_feat{NODE_FEATURE, "Aimbot", false, 1, {}, nullptr, nullptr, nullptr};
82static MenuNode g_aimbot_active{NODE_TOGGLE, "Active", false, 0, {}, &g_aimbot.active, nullptr, nullptr}; 100static MenuNode g_aimbot_active{NODE_TOGGLE, "Active", false, 0, {}, &g_aimbot.active, nullptr, nullptr};
83static MenuNode g_aimbot_bind{NODE_BIND, "Bind", false, 0, {}, nullptr, &g_aimbot.bind, nullptr}; 101static MenuNode g_aimbot_bind{NODE_BIND, "Bind", false, 0, {}, nullptr, &g_aimbot.bind, nullptr};
102static MenuNode g_aimbot_bones_feat{NODE_FEATURE, "Bones", false, 0, {}, nullptr, nullptr, nullptr};
103static 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};
111static MenuNode g_aimbot_smooth_node{NODE_VALUE, "Smoothness", false, 0, {}, nullptr,
112 nullptr, nullptr, &g_aim_smooth, 1, 45, 1};
84 113
85static MenuNode *g_visible[32]; // flattened visible nodes for arrow navigation 114static MenuNode *g_visible[32]; // flattened visible nodes for arrow navigation
86static int g_visible_count = 0; 115static 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
347bool bhop_autostrafe_enabled() { return g_bhop_autostrafe; } 408bool bhop_autostrafe_enabled() { return g_bhop_autostrafe; }
348 409
410unsigned 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
427int aimbot_smooth_step() { return g_aim_smooth; }
428
349static void menu_handle_input() { 429static 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);