From 95b5be2299b332917ae63c45252cb9744a3460cd Mon Sep 17 00:00:00 2001 From: salmonik Date: Tue, 3 Nov 2026 23:51:02 +0100 Subject: World: add skybox changer New Visuals -> Skybox card with a runtime sv_skyname override using the same mechanism as the stock skybox_swapper entity. The choice list is the HL2 skybox set extracted from the game VPKs. The map's own sky is captured from loaded materials (SkyBox group, parsing skybox/... face names) before the first override, so turning the feature off or picking "Map default" restores it; a level change restores it implicitly. Sky changes invalidate the world tint so new sky materials are tinted as well. GUI: add a CK_CHOICE control (value box with < / > zones). --- src/gui.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) (limited to 'src/gui.cpp') diff --git a/src/gui.cpp b/src/gui.cpp index aa47868..5fb8fa7 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -183,7 +183,8 @@ enum CtrlKind { CK_SECTION, CK_INFO, CK_BUTTON, - CK_COLOR + CK_COLOR, + CK_CHOICE }; enum CtrlAction { ACT_NONE = 0, ACT_RELOAD, ACT_RESET }; @@ -195,6 +196,8 @@ struct Ctrl { bool *bval; // CK_TOGGLE int *ival; // CK_SLIDER int *rgb; // CK_COLOR: three ints, 0..255 + const char *const *opts; // CK_CHOICE: option labels + int nopts; int min, max; int action; // CK_BUTTON bool zero_unlimited; // slider: value 0 displays as "All" @@ -253,6 +256,8 @@ static void add_ctrl(int card, int kind, const char *label, const char *desc, c.action = action; c.zero_unlimited = false; c.rgb = nullptr; + c.opts = nullptr; + c.nopts = 0; c.hue = 0.0f; c.sat = 0.0f; c.val = 1.0f; @@ -282,11 +287,19 @@ static void add_color(int card, const char *label, const char *desc, add_ctrl(card, CK_COLOR, label, desc, 0, 255, nullptr, nullptr, ACT_NONE); g_ctrls[i].rgb = rgb; } +static void add_choice(int card, const char *label, const char *desc, + const char *const *opts, int nopts, int *value) { + int i = g_nctrl; + add_ctrl(card, CK_CHOICE, label, desc, 0, nopts > 0 ? nopts - 1 : 0, + nullptr, value, ACT_NONE); + g_ctrls[i].opts = opts; + g_ctrls[i].nopts = nopts; +} static int ctrl_val(const Ctrl &c) { if (c.kind == CK_TOGGLE && c.bval) return *c.bval ? 1 : 0; - if (c.kind == CK_SLIDER && c.ival) + if ((c.kind == CK_SLIDER || c.kind == CK_CHOICE) && c.ival) return *c.ival; return 0; } @@ -294,7 +307,7 @@ static void ctrl_set(Ctrl &c, int v) { if (c.kind == CK_TOGGLE && c.bval) { *c.bval = v != 0; config_save(); - } else if (c.kind == CK_SLIDER && c.ival) { + } else if ((c.kind == CK_SLIDER || c.kind == CK_CHOICE) && c.ival) { if (v < c.min) v = c.min; if (v > c.max) v = c.max; if (*c.ival != v) { @@ -420,6 +433,13 @@ static void build_cards() { add_toggle(fog, "Remove fog", "Disable fog entirely instead of recolouring it.", &g_fog_disable); + int sky = add_card(2, &g_skybox, "Skybox", + "Swap the skybox at runtime through sv_skyname. The " + "map's own sky comes back on level change.", + true); + add_choice(sky, "Sky", "Pick a skybox from the HL2 set.", skybox_options(), + skybox_option_count(), &g_skybox_choice); + int spread = add_card(3, &g_spread, "Spread control", "Choose a server shot seed that tightens the cone.", true); @@ -835,6 +855,8 @@ static int header_h(const Card &c) { static int label_max_w(const Ctrl &c) { if (c.kind == CK_SLIDER) return S(214.0f); + if (c.kind == CK_CHOICE) + return card_content_w() - S(16.0f) - S(250.0f); return card_content_w() - S(16.0f) - S(110.0f); } @@ -1409,6 +1431,25 @@ static void handle_mouse_click() { } return; } + if (ct.kind == CK_CHOICE) { + int base = label_row_h(ct); + Rect box{cr.x + cr.w - S(238.0f), + by + (base - S(24.0f)) / 2, S(222.0f), S(24.0f)}; + if (box.has(mx, my)) { + int v = ctrl_val(ct); + if (mx < box.x + S(36.0f)) + v--; + else if (mx >= box.x + box.w - S(36.0f)) + v++; + if (v < 0) v = 0; + if (ct.nopts > 0 && v >= ct.nopts) v = ct.nopts - 1; + if (v != ctrl_val(ct)) { + *ct.ival = v; + config_save(); + } + } + return; + } if (ct.kind == CK_BUTTON) { int bw = button_w(ct.label); Rect b{cr.x + cr.w - S(16.0f) - bw, @@ -1799,6 +1840,25 @@ static void draw_card(const Rect &clip, int index, int y) { outline(sw, picker_open_for(ct) ? C_ACCENT : C_BORDER, &clip); if (picker_open_for(ct)) draw_picker(clip, cr, ct, by); + } else if (ct.kind == CK_CHOICE) { + int v = ctrl_val(ct); + const char *name = (ct.opts && v >= 0 && v < ct.nopts) + ? ct.opts[v] + : "?"; + Rect box{cr.x + cr.w - S(238.0f), + by + (base_h - S(24.0f)) / 2, S(222.0f), S(24.0f)}; + fill(box, Col{45, 50, 60, 255}, &clip); + outline(box, C_BORDER, &clip); + int ty = box.y + (box.h - g_body_h) / 2; + text_in(clip, box.x + S(8.0f), ty, "<", g_font_body, g_body_h, 0, + C_DIM); + text_in(clip, box.x + box.w - S(16.0f), ty, ">", g_font_body, g_body_h, + 0, C_DIM); + int w = text_w(name, g_body_h); + int tx = box.x + (box.w - w) / 2; + if (tx < box.x + S(24.0f)) + tx = box.x + S(24.0f); + text_in(clip, tx, ty, name, g_font_body, g_body_h, 0, C_TEXT); } } by += rh; -- cgit v1.2.3