summaryrefslogtreecommitdiffstats
path: root/src/menu.cpp
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-10-27 20:15:51 +0100
committersalmonik <salmonik@tuta.io>2026-10-27 20:15:51 +0100
commitba500fef7fbf94725f18541b0e23a45591379dba (patch)
treef1eec8ad34e532fb7bcb9172083c78d96bcdca4f /src/menu.cpp
parentOverlay: keep GUI and toasts drawing if the ESP font fails (diff)
downloadhl2h-ba500fef7fbf94725f18541b0e23a45591379dba.tar.gz
hl2h-ba500fef7fbf94725f18541b0e23a45591379dba.zip
Fix tooltip truncation; add Stucklaunch assist
Tooltips: text_in() shifted the x position to fit the full string before truncating, which drew the tooltip text outside its box. Truncate to the available width first, then clamp inside the clip. Stucklaunch (Movement): - opt-in feature (Active off by default) with its own bind; - holds jump, alternates +use every 2 ticks to regrab a physics prop, optionally +attack while the gravity gun is active, and air-strafes; - engagement uses m_hGroundEntity (client netvar) latched for ~0.5 s so the prop stays active while airborne; falls back to running whenever active if the netvar is unavailable, with a startup warning to bind it; - does not spawn or place props; the player supplies the prop and initial speed. Config gets [stucklaunch] active/bind/use_spam/gravspam/autostrafe; Reset restores those defaults. CONTEXT documents the assist and its limits.
Diffstat (limited to '')
-rw-r--r--src/menu.cpp40
1 files changed, 35 insertions, 5 deletions
diff --git a/src/menu.cpp b/src/menu.cpp
index 3d008bb..00ba9be 100644
--- a/src/menu.cpp
+++ b/src/menu.cpp
@@ -44,6 +44,10 @@ FeatureState g_esp{true, 0};
44FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in the GUI 44FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in the GUI
45FeatureState g_triggerbot{true, 603}; // default Mouse4 45FeatureState g_triggerbot{true, 603}; // default Mouse4
46FeatureState g_silentaim{true, 602}; // default Mouse3 46FeatureState g_silentaim{true, 602}; // default Mouse3
47FeatureState g_stucklaunch{false, 0}; // opt-in movement assist
48bool g_stucklaunch_use_spam = true;
49bool g_stucklaunch_gravspam = false;
50bool g_stucklaunch_autostrafe = true;
47 51
48// Aimbot bone checklist. Head defaults on (v1 behaviour). 52// Aimbot bone checklist. Head defaults on (v1 behaviour).
49bool g_aim_bones[AIM_BONE_COUNT] = {true, false, false, 53bool g_aim_bones[AIM_BONE_COUNT] = {true, false, false,
@@ -158,6 +162,11 @@ void config_save() {
158 fprintf(f, "[bhop]\nactive=%d\nbind=%d\nautostrafe=%d\n", g_bhop.active, 162 fprintf(f, "[bhop]\nactive=%d\nbind=%d\nautostrafe=%d\n", g_bhop.active,
159 g_bhop.bind, g_bhop_autostrafe); 163 g_bhop.bind, g_bhop_autostrafe);
160 fprintf(f, "[abh]\nactive=%d\nbind=%d\n", g_abh.active, g_abh.bind); 164 fprintf(f, "[abh]\nactive=%d\nbind=%d\n", g_abh.active, g_abh.bind);
165 fprintf(f, "[stucklaunch]\nactive=%d\nbind=%d\nuse_spam=%d\n"
166 "gravspam=%d\nautostrafe=%d\n",
167 g_stucklaunch.active, g_stucklaunch.bind,
168 (int)g_stucklaunch_use_spam, (int)g_stucklaunch_gravspam,
169 (int)g_stucklaunch_autostrafe);
161 fprintf(f, "[jumpbug]\nactive=%d\nbind=%d\nassist=%d\n", 170 fprintf(f, "[jumpbug]\nactive=%d\nbind=%d\nassist=%d\n",
162 g_jumpbug.active, g_jumpbug.bind, (int)g_jumpbug_assist); 171 g_jumpbug.active, g_jumpbug.bind, (int)g_jumpbug_assist);
163 fprintf(f, "[melee]\nactive=%d\nbind=%d\n", g_melee.active, g_melee.bind); 172 fprintf(f, "[melee]\nactive=%d\nbind=%d\n", g_melee.active, g_melee.bind);
@@ -204,7 +213,7 @@ static bool config_load() {
204 char line[256]; 213 char line[256];
205 FeatureState *cur = nullptr; 214 FeatureState *cur = nullptr;
206 bool in_esp = false, in_bhop = false, in_aim = false, in_silent = false, 215 bool in_esp = false, in_bhop = false, in_aim = false, in_silent = false,
207 in_jumpbug = false, in_spread = false; 216 in_jumpbug = false, in_spread = false, in_stucklaunch = false;
208 while (fgets(line, sizeof(line), f)) { 217 while (fgets(line, sizeof(line), f)) {
209 line[strcspn(line, "\r\n")] = 0; 218 line[strcspn(line, "\r\n")] = 0;
210 if (line[0] == '[') { 219 if (line[0] == '[') {
@@ -212,6 +221,8 @@ static bool config_load() {
212 cur = &g_bhop; 221 cur = &g_bhop;
213 else if (strstr(line, "[abh]")) 222 else if (strstr(line, "[abh]"))
214 cur = &g_abh; 223 cur = &g_abh;
224 else if (strstr(line, "[stucklaunch]"))
225 cur = &g_stucklaunch;
215 else if (strstr(line, "[jumpbug]")) 226 else if (strstr(line, "[jumpbug]"))
216 cur = &g_jumpbug; 227 cur = &g_jumpbug;
217 else if (strstr(line, "[melee]")) 228 else if (strstr(line, "[melee]"))
@@ -234,6 +245,7 @@ static bool config_load() {
234 in_silent = (cur == &g_silentaim); 245 in_silent = (cur == &g_silentaim);
235 in_jumpbug = (cur == &g_jumpbug); 246 in_jumpbug = (cur == &g_jumpbug);
236 in_spread = (cur == &g_spread); 247 in_spread = (cur == &g_spread);
248 in_stucklaunch = (cur == &g_stucklaunch);
237 } else if (cur) { 249 } else if (cur) {
238 char *eq = strchr(line, '='); 250 char *eq = strchr(line, '=');
239 if (!eq) 251 if (!eq)
@@ -249,6 +261,14 @@ static bool config_load() {
249 if (in_spread && strcmp(key, "no_spread") == 0) { 261 if (in_spread && strcmp(key, "no_spread") == 0) {
250 g_spread_no_spread = atoi(val) != 0; 262 g_spread_no_spread = atoi(val) != 0;
251 } 263 }
264 if (in_stucklaunch) {
265 if (strcmp(key, "use_spam") == 0)
266 g_stucklaunch_use_spam = atoi(val) != 0;
267 else if (strcmp(key, "gravspam") == 0)
268 g_stucklaunch_gravspam = atoi(val) != 0;
269 else if (strcmp(key, "autostrafe") == 0)
270 g_stucklaunch_autostrafe = atoi(val) != 0;
271 }
252 if (in_aim) { 272 if (in_aim) {
253 if (strcmp(key, "smooth") == 0) { 273 if (strcmp(key, "smooth") == 0) {
254 int v = atoi(val); 274 int v = atoi(val);
@@ -327,6 +347,10 @@ void config_reset_defaults() {
327 g_bhop = {true, 0}; 347 g_bhop = {true, 0};
328 g_bhop_autostrafe = true; 348 g_bhop_autostrafe = true;
329 g_abh = {true, 0}; 349 g_abh = {true, 0};
350 g_stucklaunch = {false, 0};
351 g_stucklaunch_use_spam = true;
352 g_stucklaunch_gravspam = false;
353 g_stucklaunch_autostrafe = true;
330 g_jumpbug = {true, 0}; 354 g_jumpbug = {true, 0};
331 g_jumpbug_assist = false; 355 g_jumpbug_assist = false;
332 g_melee = {true, 0}; 356 g_melee = {true, 0};
@@ -432,10 +456,10 @@ static bool key_held(int sc) {
432// feature gate queried from hl2h.cpp do_move(): feature must be Active AND 456// feature gate queried from hl2h.cpp do_move(): feature must be Active AND
433// its bind key held (always-on when unbound). 457// its bind key held (always-on when unbound).
434static FeatureState *feature_state(int feature) { 458static FeatureState *feature_state(int feature) {
435 static FeatureState *feats[9] = {&g_bhop, &g_abh, &g_esp, 459 static FeatureState *feats[FEAT_COUNT] = {
436 &g_aimbot, &g_triggerbot, &g_silentaim, 460 &g_bhop, &g_abh, &g_esp, &g_aimbot, &g_triggerbot,
437 &g_jumpbug, &g_melee, &g_spread}; 461 &g_silentaim, &g_jumpbug, &g_melee, &g_spread, &g_stucklaunch};
438 if (feature < 0 || feature > 8) 462 if (feature < 0 || feature >= FEAT_COUNT)
439 return nullptr; 463 return nullptr;
440 return feats[feature]; 464 return feats[feature];
441} 465}
@@ -467,6 +491,12 @@ bool jumpbug_assist_enabled() { return g_jumpbug_assist; }
467 491
468bool spread_no_spread_enabled() { return g_spread_no_spread; } 492bool spread_no_spread_enabled() { return g_spread_no_spread; }
469 493
494bool stucklaunch_use_spam_enabled() { return g_stucklaunch_use_spam; }
495
496bool stucklaunch_gravspam_enabled() { return g_stucklaunch_gravspam; }
497
498bool stucklaunch_autostrafe_enabled() { return g_stucklaunch_autostrafe; }
499
470unsigned aimbot_bone_mask() { 500unsigned aimbot_bone_mask() {
471 unsigned m = 0; 501 unsigned m = 0;
472 if (g_aim_bones[AIM_BONE_HEAD]) 502 if (g_aim_bones[AIM_BONE_HEAD])