summaryrefslogtreecommitdiffstats
path: root/src/menu.cpp
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-10-26 15:56:03 +0100
committersalmonik <salmonik@tuta.io>2026-10-26 15:56:03 +0100
commit164bdcbf3e8ed2b7377351b619150586012e1007 (patch)
tree63660fc6f33c0e77e81f73a5d544418307e1b7e5 /src/menu.cpp
parentESP: menu toggles for neutral/healthbar/healthnum/name (diff)
downloadhl2h-164bdcbf3e8ed2b7377351b619150586012e1007.tar.gz
hl2h-164bdcbf3e8ed2b7377351b619150586012e1007.zip
Bhop: uni-directional auto-strafe for all movement directions
- derive the desired air direction from the raw W/S/A/D input (view-relative) - pick the velocity perpendicular that rotates toward that target, so S/A/D work instead of only forward and A/D no longer spin in circles - no keys: accelerate along the crosshair - menu label now "Uni-directional auto-strafe"; state column moved to x=270
Diffstat (limited to '')
-rw-r--r--src/menu.cpp21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/menu.cpp b/src/menu.cpp
index 2caf0aa..c8dffc9 100644
--- a/src/menu.cpp
+++ b/src/menu.cpp
@@ -52,6 +52,7 @@ struct FeatureState {
52}; 52};
53 53
54static FeatureState g_bhop{true, 0}; 54static FeatureState g_bhop{true, 0};
55static bool g_bhop_autostrafe = true;
55 56
56static FeatureState g_abh{true, 0}; 57static FeatureState g_abh{true, 0};
57static FeatureState g_esp{true, 0}; 58static FeatureState g_esp{true, 0};
@@ -64,6 +65,7 @@ static bool g_esp_opt[ESP_OPT_COUNT] = {true, true, true, true};
64static MenuNode g_root{NODE_ROOT, "HL2hake", true, 0, {}, nullptr, nullptr, nullptr}; 65static MenuNode g_root{NODE_ROOT, "HL2hake", true, 0, {}, nullptr, nullptr, nullptr};
65static MenuNode g_bhop_feat{NODE_FEATURE, "Bunnyhop", true, 1, {}, nullptr, nullptr, nullptr}; 66static MenuNode g_bhop_feat{NODE_FEATURE, "Bunnyhop", true, 1, {}, nullptr, nullptr, nullptr};
66static MenuNode g_bhop_active{NODE_TOGGLE, "Active", false, 0, {}, &g_bhop.active, nullptr, nullptr}; 67static MenuNode g_bhop_active{NODE_TOGGLE, "Active", false, 0, {}, &g_bhop.active, nullptr, nullptr};
68static MenuNode g_bhop_autostrafe_node{NODE_TOGGLE, "Uni-directional auto-strafe", false, 0, {}, &g_bhop_autostrafe, nullptr, nullptr};
67static MenuNode g_abh_feat{NODE_FEATURE, "ABH", true, 1, {}, nullptr, nullptr, nullptr}; 69static MenuNode g_abh_feat{NODE_FEATURE, "ABH", true, 1, {}, nullptr, nullptr, nullptr};
68static MenuNode g_abh_active{NODE_TOGGLE, "Active", false, 0, {}, &g_abh.active, nullptr, nullptr}; 70static MenuNode g_abh_active{NODE_TOGGLE, "Active", false, 0, {}, &g_abh.active, nullptr, nullptr};
69static MenuNode g_esp_feat{NODE_FEATURE, "ESP", true, 1, {}, nullptr, nullptr, nullptr}; 71static MenuNode g_esp_feat{NODE_FEATURE, "ESP", true, 1, {}, nullptr, nullptr, nullptr};
@@ -83,6 +85,8 @@ bool g_menu_open = false;
83static bool g_bind_mode = false; 85static bool g_bind_mode = false;
84static void build_tree() { 86static void build_tree() {
85 g_bhop_feat.children[0] = &g_bhop_active; 87 g_bhop_feat.children[0] = &g_bhop_active;
88 g_bhop_feat.children[1] = &g_bhop_autostrafe_node;
89 g_bhop_feat.child_count = 2;
86 g_abh_feat.children[0] = &g_abh_active; 90 g_abh_feat.children[0] = &g_abh_active;
87 g_esp_feat.children[0] = &g_esp_active; 91 g_esp_feat.children[0] = &g_esp_active;
88 for (int i = 0; i < ESP_OPT_COUNT; i++) 92 for (int i = 0; i < ESP_OPT_COUNT; i++)
@@ -151,7 +155,8 @@ static void config_save() {
151 FILE *f = fopen(config_path().c_str(), "w"); 155 FILE *f = fopen(config_path().c_str(), "w");
152 if (!f) 156 if (!f)
153 return; 157 return;
154 fprintf(f, "[bhop]\nactive=%d\nbind=%d\n", g_bhop.active, g_bhop.bind); 158 fprintf(f, "[bhop]\nactive=%d\nbind=%d\nautostrafe=%d\n", g_bhop.active,
159 g_bhop.bind, g_bhop_autostrafe);
155 fprintf(f, "[abh]\nactive=%d\nbind=%d\n", g_abh.active, g_abh.bind); 160 fprintf(f, "[abh]\nactive=%d\nbind=%d\n", g_abh.active, g_abh.bind);
156 fprintf(f, "[esp]\nactive=%d\nbind=%d\nneutral=%d\nhealthbar=%d\n" 161 fprintf(f, "[esp]\nactive=%d\nbind=%d\nneutral=%d\nhealthbar=%d\n"
157 "healthnum=%d\nname=%d\n", 162 "healthnum=%d\nname=%d\n",
@@ -167,7 +172,7 @@ static void config_load() {
167 return; 172 return;
168 char line[256]; 173 char line[256];
169 FeatureState *cur = nullptr; 174 FeatureState *cur = nullptr;
170 bool in_esp = false; 175 bool in_esp = false, in_bhop = false;
171 while (fgets(line, sizeof(line), f)) { 176 while (fgets(line, sizeof(line), f)) {
172 line[strcspn(line, "\r\n")] = 0; 177 line[strcspn(line, "\r\n")] = 0;
173 if (line[0] == '[') { 178 if (line[0] == '[') {
@@ -180,12 +185,16 @@ static void config_load() {
180 else 185 else
181 cur = nullptr; 186 cur = nullptr;
182 in_esp = (cur == &g_esp); 187 in_esp = (cur == &g_esp);
188 in_bhop = (cur == &g_bhop);
183 } else if (cur) { 189 } else if (cur) {
184 char *eq = strchr(line, '='); 190 char *eq = strchr(line, '=');
185 if (!eq) 191 if (!eq)
186 continue; 192 continue;
187 *eq = 0; 193 *eq = 0;
188 const char *key = line, *val = eq + 1; 194 const char *key = line, *val = eq + 1;
195 if (in_bhop && strcmp(key, "autostrafe") == 0) {
196 g_bhop_autostrafe = atoi(val) != 0;
197 }
189 if (in_esp) { 198 if (in_esp) {
190 if (strcmp(key, "neutral") == 0) 199 if (strcmp(key, "neutral") == 0)
191 g_esp_opt[ESP_OPT_SHOW_NEUTRAL] = atoi(val) != 0; 200 g_esp_opt[ESP_OPT_SHOW_NEUTRAL] = atoi(val) != 0;
@@ -319,6 +328,8 @@ bool esp_option(int opt) {
319 return opt >= 0 && opt < ESP_OPT_COUNT && g_esp_opt[opt]; 328 return opt >= 0 && opt < ESP_OPT_COUNT && g_esp_opt[opt];
320} 329}
321 330
331bool bhop_autostrafe_enabled() { return g_bhop_autostrafe; }
332
322static void menu_handle_input() { 333static void menu_handle_input() {
323 poll_keyboard(); 334 poll_keyboard();
324 335
@@ -557,10 +568,10 @@ void outer_draw() {
557 draw_text(x, 10 + i * 20, line); 568 draw_text(x, 10 + i * 20, line);
558 // right-aligned state 569 // right-aligned state
559 if (n->type == NODE_TOGGLE) { 570 if (n->type == NODE_TOGGLE) {
560 draw_text(200, 10 + i * 20, *n->active_ptr ? "[on]" : "[off]"); 571 draw_text(270, 10 + i * 20, *n->active_ptr ? "[on]" : "[off]");
561 } else if (n->type == NODE_BIND) { 572 } else if (n->type == NODE_BIND) {
562 if (g_bind_mode && i == g_selected) 573 if (g_bind_mode && i == g_selected)
563 draw_text(200, 10 + i * 20, "[press key]"); 574 draw_text(270, 10 + i * 20, "[press key]");
564 else { 575 else {
565 /* stable name for current bind */ 576 /* stable name for current bind */
566 static char bn[2][32]; 577 static char bn[2][32];
@@ -570,7 +581,7 @@ void outer_draw() {
570 if (n->bind_ptr == &feats[k]->bind) 581 if (n->bind_ptr == &feats[k]->bind)
571 fi = k; 582 fi = k;
572 snprintf(bn[fi], 32, "[%s]", scancode_name(*n->bind_ptr)); 583 snprintf(bn[fi], 32, "[%s]", scancode_name(*n->bind_ptr));
573 draw_text(200, 10 + i * 20, bn[fi]); 584 draw_text(270, 10 + i * 20, bn[fi]);
574 } 585 }
575 } 586 }
576 } 587 }