diff options
| author | salmonik <salmonik@tuta.io> | 2026-10-27 20:15:51 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-10-27 20:15:51 +0100 |
| commit | ba500fef7fbf94725f18541b0e23a45591379dba (patch) | |
| tree | f1eec8ad34e532fb7bcb9172083c78d96bcdca4f /src/menu.cpp | |
| parent | Overlay: keep GUI and toasts drawing if the ESP font fails (diff) | |
| download | hl2h-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 'src/menu.cpp')
| -rw-r--r-- | src/menu.cpp | 40 |
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}; | |||
| 44 | FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in the GUI | 44 | FeatureState g_aimbot{true, 604}; // default Mouse5, rebindable in the GUI |
| 45 | FeatureState g_triggerbot{true, 603}; // default Mouse4 | 45 | FeatureState g_triggerbot{true, 603}; // default Mouse4 |
| 46 | FeatureState g_silentaim{true, 602}; // default Mouse3 | 46 | FeatureState g_silentaim{true, 602}; // default Mouse3 |
| 47 | FeatureState g_stucklaunch{false, 0}; // opt-in movement assist | ||
| 48 | bool g_stucklaunch_use_spam = true; | ||
| 49 | bool g_stucklaunch_gravspam = false; | ||
| 50 | bool g_stucklaunch_autostrafe = true; | ||
| 47 | 51 | ||
| 48 | // Aimbot bone checklist. Head defaults on (v1 behaviour). | 52 | // Aimbot bone checklist. Head defaults on (v1 behaviour). |
| 49 | bool g_aim_bones[AIM_BONE_COUNT] = {true, false, false, | 53 | bool 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). |
| 434 | static FeatureState *feature_state(int feature) { | 458 | static 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 | ||
| 468 | bool spread_no_spread_enabled() { return g_spread_no_spread; } | 492 | bool spread_no_spread_enabled() { return g_spread_no_spread; } |
| 469 | 493 | ||
| 494 | bool stucklaunch_use_spam_enabled() { return g_stucklaunch_use_spam; } | ||
| 495 | |||
| 496 | bool stucklaunch_gravspam_enabled() { return g_stucklaunch_gravspam; } | ||
| 497 | |||
| 498 | bool stucklaunch_autostrafe_enabled() { return g_stucklaunch_autostrafe; } | ||
| 499 | |||
| 470 | unsigned aimbot_bone_mask() { | 500 | unsigned 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]) |
