import type { RenderSettings } from "../render-settings"; import type { DebugNode } from "./folder"; import { folder } from "./folder"; import { color } from "./props/color"; import { select } from "./props/select"; import { slider } from "./props/slider"; import { toggle } from "./props/toggle"; export function buildTree(s: RenderSettings, d: RenderSettings): DebugNode[] { return [ folder("Pass Enables", [ toggle(s.passEnabled, "terrain", d.passEnabled), toggle(s.passEnabled, "mapOverlay", d.passEnabled), toggle(s.passEnabled, "structure", d.passEnabled), toggle(s.passEnabled, "unit", d.passEnabled), toggle(s.passEnabled, "name", d.passEnabled), toggle(s.passEnabled, "falloutBloom", d.passEnabled), toggle(s.passEnabled, "railroad", d.passEnabled), toggle(s.passEnabled, "fx", d.passEnabled), toggle(s.passEnabled, "bar", d.passEnabled), toggle(s.passEnabled, "dayNight", d.passEnabled), toggle(s.passEnabled, "nameDebug", d.passEnabled, "Name Debug Boxes"), ]), folder("Fallout Bloom", [ slider(s.falloutBloom, "broilSpeedCold", d.falloutBloom, 0, 0.05, 0.0001), slider(s.falloutBloom, "broilSpeedHot", d.falloutBloom, 0, 0.05, 0.0001), slider(s.falloutBloom, "noiseFreq1", d.falloutBloom, 0, 0.5, 0.001), slider(s.falloutBloom, "noiseFreq2", d.falloutBloom, 0, 0.5, 0.001), slider(s.falloutBloom, "contrastLoCold", d.falloutBloom, 0, 1, 0.01), slider(s.falloutBloom, "contrastLoHot", d.falloutBloom, 0, 1, 0.01), slider(s.falloutBloom, "contrastHiCold", d.falloutBloom, 0, 1, 0.01), slider(s.falloutBloom, "contrastHiHot", d.falloutBloom, 0, 1, 0.01), slider(s.falloutBloom, "metaFreq", d.falloutBloom, 0, 0.2, 0.001), slider(s.falloutBloom, "intensityCold", d.falloutBloom, 0, 10, 0.05), slider(s.falloutBloom, "intensityHot", d.falloutBloom, 0, 20, 0.1), slider(s.falloutBloom, "metaInfluenceCold", d.falloutBloom, 0, 1, 0.01), slider(s.falloutBloom, "metaInfluenceHot", d.falloutBloom, 0, 1, 0.01), slider(s.falloutBloom, "opacityFadeEnd", d.falloutBloom, 0, 1, 0.01), color( s.falloutBloom, "bloomR", "bloomG", "bloomB", d.falloutBloom, "Bloom Color", ), slider(s.falloutBloom, "bloomCoverage", d.falloutBloom, 0, 10, 0.1), slider(s.falloutBloom, "heatDecayPerTick", d.falloutBloom, 0, 5, 0.01), ]), folder("Day / Night", [ select( s.dayNight, "mode", d.dayNight, ["light", "dark", "cycle"], "Mode", ), slider(s.dayNight, "cycleTicks", d.dayNight, 60, 6000, 10), slider( s.dayNight, "startPhase", d.dayNight, 0, 1, 0.01, "Start Phase (0=noon)", ), slider(s.dayNight, "noonHold", d.dayNight, 0, 1, 0.01, "Noon Hold"), slider(s.dayNight, "nightHold", d.dayNight, 0, 1, 0.01, "Night Hold"), slider(s.dayNight, "nightAmbient", d.dayNight, 0, 1, 0.01), slider(s.dayNight, "dayAmbient", d.dayNight, 0, 1, 0.01), slider(s.dayNight, "falloffPower", d.dayNight, 0.5, 5, 0.1), slider(s.dayNight, "falloutLightIntensity", d.dayNight, 0, 20, 0.1), slider(s.dayNight, "falloutLightThreshold", d.dayNight, 0, 0.5, 0.001), slider(s.dayNight, "blurZoomDivisor", d.dayNight, 1, 20, 0.5), slider(s.dayNight, "lightRadiusMultiplier", d.dayNight, 0.1, 5, 0.1), color( s.dayNight, "falloutLightR", "falloutLightG", "falloutLightB", d.dayNight, "Fallout Light Color", ), slider(s.dayNight, "emberLightIntensity", d.dayNight, 0, 20, 0.1), color( s.dayNight, "emberLightR", "emberLightG", "emberLightB", d.dayNight, "Ember Light Color", ), ]), folder("Map Overlay", [ slider(s.mapOverlay, "trailAlpha", d.mapOverlay, 0, 1, 0.01), slider(s.mapOverlay, "defenseCheckerDarken", d.mapOverlay, 0, 1, 0.01), slider(s.mapOverlay, "charcoalBase", d.mapOverlay, 0, 0.3, 0.005), slider(s.mapOverlay, "charcoalVariation", d.mapOverlay, 0, 0.3, 0.005), slider(s.mapOverlay, "charcoalAlpha", d.mapOverlay, 0, 1, 0.01), slider( s.mapOverlay, "emberThresholdUnowned", d.mapOverlay, 0.5, 1, 0.005, ), slider(s.mapOverlay, "emberThresholdOwned", d.mapOverlay, 0.5, 1, 0.005), slider(s.mapOverlay, "emberFlickerSpeed", d.mapOverlay, 0, 2, 0.01), color( s.mapOverlay, "emberColorDarkR", "emberColorDarkG", "emberColorDarkB", d.mapOverlay, "Ember Color Dark", ), color( s.mapOverlay, "emberColorBrightR", "emberColorBrightG", "emberColorBrightB", d.mapOverlay, "Ember Color Bright", ), slider(s.mapOverlay, "emberStrengthUnowned", d.mapOverlay, 0, 2, 0.01), slider( s.mapOverlay, "highlightBrighten", d.mapOverlay, 0, 1, 0.01, "Highlight Brighten", ), slider( s.mapOverlay, "highlightThicken", d.mapOverlay, 0, 10, 1, "Highlight Thicken (tiles)", ), folder("Railroad", [ slider(s.railroad, "railMinZoom", d.railroad, 0, 10, 0.1, "Min Zoom"), slider( s.railroad, "railDetailZoom", d.railroad, 0, 20, 0.1, "Detail Zoom", ), slider(s.railroad, "railAlpha", d.railroad, 0, 1, 0.01, "Alpha"), ]), ]), folder("Structure", [ slider(s.structure, "iconSize", d.structure, 10, 60, 1), slider(s.structure, "dotsZoomThreshold", d.structure, 0.1, 2, 0.05), slider( s.structure, "iconScaleFactorZoomedOut", d.structure, 0.5, 3, 0.05, ), slider( s.structure, "highlightOutlineWidth", d.structure, 0, 0.2, 0.005, "Highlight Outline W", ), slider( s.structure, "highlightDimAlpha", d.structure, 0, 1, 0.01, "Highlight Dim Alpha", ), folder( "Per-Shape", Object.entries(s.structure.shapes).map(([name, cfg]) => folder(name, [ slider( cfg, "scale", d.structure.shapes[name], 0.5, 2, 0.05, "Frame Scale", ), slider( cfg, "iconFill", d.structure.shapes[name], 0.2, 1.5, 0.05, "Icon Fill", ), ]), ), ), ]), folder("Bar", [ slider(s.bar, "healthBarW", d.bar, 3, 30, 1, "Health Width"), slider(s.bar, "healthBarH", d.bar, 1, 10, 1, "Health Height"), slider(s.bar, "healthBarOffsetY", d.bar, -20, 0, 1, "Health Offset Y"), slider(s.bar, "progressBarW", d.bar, 3, 30, 1, "Progress Width"), slider(s.bar, "progressBarH", d.bar, 1, 10, 1, "Progress Height"), slider(s.bar, "progressBarOffsetY", d.bar, 0, 20, 1, "Progress Offset Y"), slider(s.bar, "borderWidth", d.bar, 0, 3, 0.5, "Border Width"), slider(s.bar, "threshold1", d.bar, 0, 1, 0.05, "Red→Orange"), slider(s.bar, "threshold2", d.bar, 0, 1, 0.05, "Orange→Yellow"), slider(s.bar, "threshold3", d.bar, 0, 1, 0.05, "Yellow→Green"), color(s.bar, "colorRedR", "colorRedG", "colorRedB", d.bar, "Red"), color( s.bar, "colorOrangeR", "colorOrangeG", "colorOrangeB", d.bar, "Orange", ), color( s.bar, "colorYellowR", "colorYellowG", "colorYellowB", d.bar, "Yellow", ), color(s.bar, "colorGreenR", "colorGreenG", "colorGreenB", d.bar, "Green"), ]), folder("Unit", [ slider(s.unit, "unitSize", d.unit, 4, 64, 1), slider(s.unit, "flickerSpeed", d.unit, 0, 2, 0.01), color(s.unit, "angryR", "angryG", "angryB", d.unit, "Angry Color"), ]), folder("Name", [ slider(s.name, "lerpSpeed", d.name, 1, 30, 0.5), slider(s.name, "cullThreshold", d.name, 0, 0.05, 0.001), slider(s.name, "nameScaleFactor", d.name, 0.1, 1, 0.05), slider(s.name, "nameScaleCap", d.name, 1, 10, 0.5), slider(s.name, "troopSizeMultiplier", d.name, 0.1, 2, 0.05), slider(s.name, "outlineWidth", d.name, 0, 10, 0.1, "Outline Width (px)"), color( s.name, "outlineR", "outlineG", "outlineB", d.name, "Outline Color", ), toggle(s.name, "outlineUsePlayerColor", d.name, "Outline = Player Color"), toggle(s.name, "fillUsePlayerColor", d.name, "Fill = Player Color"), slider(s.name, "emojiRowOffset", d.name, 0, 5, 0.1, "Emoji Row Offset"), slider(s.name, "statusRowOffset", d.name, 0, 5, 0.1, "Status Row Offset"), ]), folder("FX", [ slider(s.fx, "shockwaveRingWidth", d.fx, 0.01, 0.2, 0.005), slider( s.fx, "nukeShockwaveDurationMs", d.fx, 200, 5000, 100, "Nuke Shock Duration", ), slider( s.fx, "nukeShockwaveRadiusFactor", d.fx, 0.5, 3, 0.1, "Nuke Shock Radius ×", ), slider( s.fx, "samShockwaveDurationMs", d.fx, 200, 3000, 50, "SAM Shock Duration", ), slider(s.fx, "samShockwaveRadius", d.fx, 10, 100, 5, "SAM Shock Radius"), slider( s.fx, "debrisLifetimeMs", d.fx, 1000, 15000, 500, "Debris Lifetime", ), slider(s.fx, "debrisFadeIn", d.fx, 0, 0.5, 0.01, "Debris Fade In"), slider(s.fx, "debrisFadeOut", d.fx, 0.3, 1, 0.01, "Debris Fade Out"), slider( s.fx, "conquestLifetimeMs", d.fx, 500, 8000, 250, "Conquest Lifetime", ), slider(s.fx, "conquestFadeIn", d.fx, 0, 0.5, 0.01, "Conquest Fade In"), slider(s.fx, "conquestFadeOut", d.fx, 0.3, 1, 0.01, "Conquest Fade Out"), ]), folder("Nuke Trajectory", [ slider( s.nukeTrajectory, "lineWidth", d.nukeTrajectory, 0.5, 5, 0.25, "Line Width (px)", ), slider( s.nukeTrajectory, "outlineWidth", d.nukeTrajectory, 0, 4, 0.25, "Outline Width (px)", ), slider( s.nukeTrajectory, "dashTargetable", d.nukeTrajectory, 1, 30, 1, "Dash (targetable)", ), slider( s.nukeTrajectory, "gapTargetable", d.nukeTrajectory, 1, 20, 1, "Gap (targetable)", ), slider( s.nukeTrajectory, "dashUntargetable", d.nukeTrajectory, 1, 20, 1, "Dash (untargetable)", ), slider( s.nukeTrajectory, "gapUntargetable", d.nukeTrajectory, 1, 20, 1, "Gap (untargetable)", ), color( s.nukeTrajectory, "lineR", "lineG", "lineB", d.nukeTrajectory, "Line Color", ), color( s.nukeTrajectory, "interceptR", "interceptG", "interceptB", d.nukeTrajectory, "Intercept Color", ), color( s.nukeTrajectory, "outlineR", "outlineG", "outlineB", d.nukeTrajectory, "Outline Color", ), color( s.nukeTrajectory, "interceptOutlineR", "interceptOutlineG", "interceptOutlineB", d.nukeTrajectory, "Intercept Outline", ), slider( s.nukeTrajectory, "markerCircleRadius", d.nukeTrajectory, 2, 16, 1, "Circle Marker (px)", ), slider( s.nukeTrajectory, "markerXRadius", d.nukeTrajectory, 2, 16, 1, "X Marker (px)", ), ]), folder("Nuke Telegraph", [ slider( s.nukeTelegraph, "strokeWidth", d.nukeTelegraph, 0.5, 5, 0.25, "Stroke Width", ), slider( s.nukeTelegraph, "dashLen", d.nukeTelegraph, 2, 30, 1, "Dash Length", ), slider( s.nukeTelegraph, "gapLen", d.nukeTelegraph, 1, 20, 1, "Gap Length", ), slider( s.nukeTelegraph, "rotationSpeed", d.nukeTelegraph, 0, 60, 1, "Rotation Speed", ), slider( s.nukeTelegraph, "baseAlpha", d.nukeTelegraph, 0, 1, 0.05, "Base Alpha", ), slider( s.nukeTelegraph, "pulseAmplitude", d.nukeTelegraph, 0, 0.5, 0.01, "Pulse Amplitude", ), slider( s.nukeTelegraph, "pulseSpeed", d.nukeTelegraph, 0, 10, 0.5, "Pulse Speed", ), slider( s.nukeTelegraph, "fillAlphaOffset", d.nukeTelegraph, 0, 1, 0.05, "Fill Alpha Offset", ), color( s.nukeTelegraph, "colorR", "colorG", "colorB", d.nukeTelegraph, "Color", ), ]), folder("Move Indicator", [ slider( s.moveIndicator, "startRadius", d.moveIndicator, 1, 40, 1, "Start Radius (px)", ), slider( s.moveIndicator, "chevronSize", d.moveIndicator, 1, 20, 0.5, "Chevron Size (px)", ), slider( s.moveIndicator, "lineWidth", d.moveIndicator, 0.5, 6, 0.25, "Line Width (px)", ), slider( s.moveIndicator, "duration", d.moveIndicator, 100, 3000, 50, "Duration (ms)", ), slider( s.moveIndicator, "converge", d.moveIndicator, 0, 1, 0.05, "Converge", ), ]), folder("SAM Radius", [ slider( s.samRadius, "strokeWidth", d.samRadius, 0.5, 5, 0.1, "Stroke Width", ), slider(s.samRadius, "dashLen", d.samRadius, 2, 30, 1, "Dash Length"), slider(s.samRadius, "gapLen", d.samRadius, 1, 20, 1, "Gap Length"), slider( s.samRadius, "rotationSpeed", d.samRadius, 0, 40, 1, "Rotation Speed", ), slider(s.samRadius, "alpha", d.samRadius, 0, 1, 0.05, "Alpha"), slider( s.samRadius, "outlineWidth", d.samRadius, 0, 2, 0.05, "Outline Width", ), slider( s.samRadius, "outlineSoftness", d.samRadius, 0, 1, 0.05, "Outline Softness", ), ]), folder("Bonus Popup", [ slider(s.bonusPopup, "scale", d.bonusPopup, 1, 12, 0.5, "Scale"), slider( s.bonusPopup, "lifetimeMs", d.bonusPopup, 500, 5000, 100, "Lifetime (ms)", ), slider(s.bonusPopup, "riseSpeed", d.bonusPopup, 0, 10, 0.5, "Rise Speed"), slider(s.bonusPopup, "yOffset", d.bonusPopup, -10, 10, 0.5, "Y Offset"), slider( s.bonusPopup, "outlineWidth", d.bonusPopup, 0, 5, 0.1, "Outline Width", ), color(s.bonusPopup, "colorR", "colorG", "colorB", d.bonusPopup, "Color"), slider( s.bonusPopup, "minScreenScale", d.bonusPopup, 0, 1, 0.01, "Min Screen Scale", ), slider(s.bonusPopup, "cullZoom", d.bonusPopup, 0, 2, 0.05, "Cull Zoom"), ]), folder("Spawn Overlay", [ slider( s.spawnOverlay, "highlightRadius", d.spawnOverlay, 1, 20, 1, "Highlight Radius", ), slider( s.spawnOverlay, "highlightAlpha", d.spawnOverlay, 0, 1, 0.05, "Highlight Alpha", ), slider( s.spawnOverlay, "selfMinRad", d.spawnOverlay, 1, 30, 0.5, "Self Min Radius", ), slider( s.spawnOverlay, "selfMaxRad", d.spawnOverlay, 5, 50, 0.5, "Self Max Radius", ), slider( s.spawnOverlay, "mateMinRad", d.spawnOverlay, 1, 20, 0.5, "Mate Min Radius", ), slider( s.spawnOverlay, "mateMaxRad", d.spawnOverlay, 5, 30, 0.5, "Mate Max Radius", ), slider( s.spawnOverlay, "animSpeed", d.spawnOverlay, 0.001, 0.02, 0.001, "Anim Speed", ), slider( s.spawnOverlay, "gradientInnerEdge", d.spawnOverlay, 0.001, 0.1, 0.001, "Gradient Inner Edge", ), slider( s.spawnOverlay, "gradientSolidEnd", d.spawnOverlay, 0.01, 0.5, 0.01, "Gradient Solid End", ), ]), folder("Alt View", [ slider(s.altView, "gridFontSize", d.altView, 6, 32, 1, "Grid Font Size"), toggle(s.altView, "recolorStructures", d.altView, "Recolor Structures"), ]), folder( "Light Configs", Object.entries(s.lightConfigs).map(([name, cfg]) => folder(name, [ slider(cfg, "radius", d.lightConfigs[name], 1, 60, 1), slider(cfg, "intensity", d.lightConfigs[name], 0, 10, 0.1), ]), ), ), ]; }