From ba500fef7fbf94725f18541b0e23a45591379dba Mon Sep 17 00:00:00 2001 From: salmonik Date: Tue, 27 Oct 2026 20:15:51 +0100 Subject: 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. --- src/gui.cpp | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) (limited to 'src/gui.cpp') diff --git a/src/gui.cpp b/src/gui.cpp index 0d5b458..dc0e4eb 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -293,6 +293,19 @@ static void build_cards() { add_card(0, &g_abh, "ABH", "Accelerate on the jump tick by facing away " "from the velocity.", true); + int sl = add_card(0, &g_stucklaunch, "Stucklaunch", + "Hop on a physics prop while spamming grab to build " + "speed in a small space.", + true); + add_toggle(sl, "Use spam", + "Rapidly press +use to keep regrabbing the prop.", + &g_stucklaunch_use_spam); + add_toggle(sl, "Gravity gun spam", + "Rapidly press +attack while holding the gravity gun.", + &g_stucklaunch_gravspam); + add_toggle(sl, "Auto-strafe", "Air-strafe each hop.", + &g_stucklaunch_autostrafe); + int jb = add_card(0, &g_jumpbug, "Jumpbug", "Duck+jump when landing would hurt.", true); add_toggle(jb, "Assist timing", @@ -523,26 +536,40 @@ static void text_in(const Rect &clip, int x, int y, const char *s, return; if (x >= clip.x + clip.w) return; - if (x + text_w(s, tall) > clip.x + clip.w) - x = clip.x + clip.w - text_w(s, tall); - if (max_w > 0 && text_w(s, tall) > max_w) { - char buf[256]; + + // Available space from x to the clip edge, optionally capped by max_w. + // Truncate first, then clamp: shifting before truncating used to draw the + // text outside the tooltip/button box. + int avail = clip.x + clip.w - x; + if (max_w > 0 && max_w < avail) + avail = max_w; + if (avail <= 0) + return; + + char buf[256]; + const char *draw = s; + int w = text_w(s, tall); + if (w > avail) { snprintf(buf, sizeof(buf), "%s", s); int n = (int)strlen(buf); - while (n > 3 && text_w(buf, tall) > max_w) + int dots = text_w("...", tall); + while (n > 0 && text_w(buf, tall) + dots > avail) buf[--n] = 0; - if (n > 3 && n < (int)sizeof(buf) - 3) { + if (n > 0 && n + 3 < (int)sizeof(buf)) { buf[n++] = '.'; buf[n++] = '.'; buf[n++] = '.'; buf[n] = 0; } - s_text_color(c.r, c.g, c.b, c.a); - draw_text_raw(x, y, buf, font, tall); - return; + draw = buf; + w = text_w(draw, tall); } + if (x + w > clip.x + clip.w) + x = clip.x + clip.w - w; + if (x < clip.x) + x = clip.x; s_text_color(c.r, c.g, c.b, c.a); - draw_text_raw(x, y, s, font, tall); + draw_text_raw(x, y, draw, font, tall); } static Rect clip_rect(const Rect &r, const Rect &clip) { -- cgit v1.2.3