From 1c1728f6fa659e40d9688f895165a7c149ed1bd4 Mon Sep 17 00:00:00 2001 From: evanpelle Date: Mon, 8 Jun 2026 14:02:41 -0700 Subject: [PATCH] Add map hover/railroad graphics overrides and fix territory highlight Extend GraphicsOverrides with a mapOverlay group (territory highlight, border highlight amount, border highlight thickness) and a railroad group (train track draw distance), wired through the schema, applyGraphicsOverrides, and new sliders in the graphics settings modal. Fix the territory hover highlight: the shader received uHighlightBrighten but ignored it, applying a hardcoded saturation boost so the setting had no effect. It now drives a contrast boost (push channels away from mid-gray), with 0 disabling the effect. The train track slider is presented as a "draw distance" (inverted railMinZoom) so higher = tracks stay visible when more zoomed out. Also move the Graphics settings button to the top of the settings modal. --- resources/lang/en.json | 9 + .../hud/layers/GraphicsSettingsModal.ts | 195 ++++++++++++++++++ src/client/hud/layers/SettingsModal.ts | 40 ++-- src/client/render/gl/GraphicsOverrides.ts | 12 ++ src/client/render/gl/RenderOverrides.ts | 15 ++ .../shaders/map-overlay/territory.frag.glsl | 12 +- 6 files changed, 257 insertions(+), 26 deletions(-) diff --git a/resources/lang/en.json b/resources/lang/en.json index 64e96bf6b..18fa3da00 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -937,6 +937,15 @@ "section_structure_icons": "Structure Icons", "classic_icons_label": "Classic icons", "classic_icons_desc": "Lighter outline with near-black interior", + "section_map": "Map", + "highlight_fill_label": "Territory highlight", + "highlight_fill_desc": "How strongly territory brightens on hover (0 to disable)", + "highlight_brighten_label": "Border highlight amount", + "highlight_brighten_desc": "How strongly the border brightens on hover (0 to disable)", + "highlight_thicken_label": "Border highlight thickness", + "highlight_thicken_desc": "How much the border thickens on hover", + "rail_distance_label": "Train track draw distance", + "rail_distance_desc": "How far zoomed out train tracks remain visible", "reset_label": "Reset to defaults", "reset_desc": "Clear all graphics overrides" }, diff --git a/src/client/hud/layers/GraphicsSettingsModal.ts b/src/client/hud/layers/GraphicsSettingsModal.ts index cf4cb1e55..21ae8c9b4 100644 --- a/src/client/hud/layers/GraphicsSettingsModal.ts +++ b/src/client/hud/layers/GraphicsSettingsModal.ts @@ -20,6 +20,24 @@ const NAME_CULL_MIN = 0; const NAME_CULL_MAX = 0.05; const NAME_CULL_STEP = 0.001; +const HIGHLIGHT_FILL_MIN = 0; +const HIGHLIGHT_FILL_MAX = 1; +const HIGHLIGHT_FILL_STEP = 0.01; + +const HIGHLIGHT_BRIGHTEN_MIN = 0; +const HIGHLIGHT_BRIGHTEN_MAX = 1; +const HIGHLIGHT_BRIGHTEN_STEP = 0.01; + +const HIGHLIGHT_THICKEN_MIN = 0; +const HIGHLIGHT_THICKEN_MAX = 5; +const HIGHLIGHT_THICKEN_STEP = 1; + +// Train track "draw distance" is presented inverted: a higher slider value means +// tracks stay visible when more zoomed out, i.e. a lower railMinZoom. +const RAIL_ZOOM_MIN = 0; +const RAIL_ZOOM_MAX = 10; +const RAIL_ZOOM_STEP = 0.1; + export class ShowGraphicsSettingsModalEvent { constructor( public readonly isVisible: boolean = true, @@ -136,6 +154,73 @@ export class GraphicsSettingsModal extends LitElement implements Controller { this.requestUpdate(); } + private patchMapOverlay(patch: Partial) { + const current = this.userSettings.graphicsOverrides(); + this.userSettings.setGraphicsOverrides({ + ...current, + mapOverlay: { ...current.mapOverlay, ...patch }, + }); + this.requestUpdate(); + } + + private patchRailroad(patch: Partial) { + const current = this.userSettings.graphicsOverrides(); + this.userSettings.setGraphicsOverrides({ + ...current, + railroad: { ...current.railroad, ...patch }, + }); + this.requestUpdate(); + } + + private currentHighlightFill(): number { + return ( + this.userSettings.graphicsOverrides().mapOverlay?.highlightFillBrighten ?? + renderDefaults.mapOverlay.highlightFillBrighten + ); + } + + private currentHighlightBrighten(): number { + return ( + this.userSettings.graphicsOverrides().mapOverlay?.highlightBrighten ?? + renderDefaults.mapOverlay.highlightBrighten + ); + } + + private currentHighlightThicken(): number { + return ( + this.userSettings.graphicsOverrides().mapOverlay?.highlightThicken ?? + renderDefaults.mapOverlay.highlightThicken + ); + } + + private currentRailMinZoom(): number { + return ( + this.userSettings.graphicsOverrides().railroad?.railMinZoom ?? + renderDefaults.railroad.railMinZoom + ); + } + + private onHighlightFillChange(event: Event) { + const value = parseFloat((event.target as HTMLInputElement).value); + this.patchMapOverlay({ highlightFillBrighten: value }); + } + + private onHighlightBrightenChange(event: Event) { + const value = parseFloat((event.target as HTMLInputElement).value); + this.patchMapOverlay({ highlightBrighten: value }); + } + + private onHighlightThickenChange(event: Event) { + const value = parseFloat((event.target as HTMLInputElement).value); + this.patchMapOverlay({ highlightThicken: value }); + } + + private onRailDrawDistanceChange(event: Event) { + const drawDistance = parseFloat((event.target as HTMLInputElement).value); + // Invert: higher draw distance => tracks visible when more zoomed out. + this.patchRailroad({ railMinZoom: RAIL_ZOOM_MAX - drawDistance }); + } + private currentClassicIcons(): boolean { return ( this.userSettings.graphicsOverrides().structure?.classicIcons ?? false @@ -179,6 +264,10 @@ export class GraphicsSettingsModal extends LitElement implements Controller { const nameCull = this.currentNameCull(); const namesColored = !this.currentDarkNames(); const classicIcons = this.currentClassicIcons(); + const highlightFill = this.currentHighlightFill(); + const highlightBrighten = this.currentHighlightBrighten(); + const highlightThicken = this.currentHighlightThicken(); + const railDrawDistance = RAIL_ZOOM_MAX - this.currentRailMinZoom(); return html`
+
+ ${translateText("graphics_setting.section_map")} +
+ +
+
+
+ ${translateText("graphics_setting.highlight_fill_label")} +
+
+ ${translateText("graphics_setting.highlight_fill_desc")} +
+ +
+
+ ${highlightFill.toFixed(2)} +
+
+ +
+
+
+ ${translateText("graphics_setting.highlight_brighten_label")} +
+
+ ${translateText("graphics_setting.highlight_brighten_desc")} +
+ +
+
+ ${highlightBrighten.toFixed(2)} +
+
+ +
+
+
+ ${translateText("graphics_setting.highlight_thicken_label")} +
+
+ ${translateText("graphics_setting.highlight_thicken_desc")} +
+ +
+
+ ${highlightThicken.toFixed(0)} +
+
+ +
+
+
+ ${translateText("graphics_setting.rail_distance_label")} +
+
+ ${translateText("graphics_setting.rail_distance_desc")} +
+ +
+
+ ${railDrawDistance.toFixed(1)} +
+
+
+
@@ -491,26 +511,6 @@ export class SettingsModal extends LitElement implements Controller {
- -
0.25 = border tile @@ -104,11 +104,11 @@ void main() { } } - // Hover highlight: boost saturation on the hovered player's tiles. - // luma = grayscale equivalent; mixing past 1.0 pushes color away from gray. - if (uHighlightOwner != 0u && owner == uHighlightOwner) { - float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114)); - color.rgb = clamp(mix(vec3(luma), color.rgb, 1.6), 0.0, 1.0); + // Hover highlight: boost contrast on the hovered player's tiles, pushing + // channels away from mid-gray. uHighlightBrighten is the strength; 0 disables. + if (uHighlightOwner != 0u && owner == uHighlightOwner && uHighlightBrighten > 0.0) { + float contrast = 1.0 + uHighlightBrighten; + color.rgb = clamp((color.rgb - 0.5) * contrast + 0.5, 0.0, 1.0); } // Defense bonus: darken the fill on interior tiles defended by a same-owner