@tool class_name SkyDebugPanel extends Control @export var dynamic_sky: DynamicSkyRoot var _panel: PanelContainer var _vbox: VBoxContainer var _time_label: Label var _period_label: Label var _preset_label: Label var _weather_label: Label var _sun_label: Label var _moon_label: Label var _ambient_label: Label var _cloud_label: Label var _fog_label: Label var _rain_label: Label var _seed_label: Label var _time_slider: HSlider var _weather_dropdown: OptionButton var _pause_button: Button func _ready() -> void: _create_ui() _connect_signals() func _process(_delta: float) -> void: if dynamic_sky == null: return _update_labels() func _create_ui() -> void: _panel = PanelContainer.new() _panel.name = "DebugPanel" _panel.custom_minimum_size = Vector2(300, 200) add_child(_panel) var margin := MarginContainer.new() margin.add_theme_constant_override("margin_left", 10) margin.add_theme_constant_override("margin_right", 10) margin.add_theme_constant_override("margin_top", 10) margin.add_theme_constant_override("margin_bottom", 10) _panel.add_child(margin) _vbox = VBoxContainer.new() _vbox.add_theme_constant_override("separation", 8) margin.add_child(_vbox) var title := Label.new() title.text = "Dynamic Sky Debug" title.add_theme_font_size_override("font_size", 18) _vbox.add_child(title) _vbox.add_child(HSeparator.new()) _preset_label = Label.new() _preset_label.text = "Preset: —" _vbox.add_child(_preset_label) _time_label = Label.new() _time_label.text = "Time: 00:00 (0.00)" _vbox.add_child(_time_label) _period_label = Label.new() _period_label.text = "Period: —" _vbox.add_child(_period_label) var time_hbox := HBoxContainer.new() _vbox.add_child(time_hbox) var time_label := Label.new() time_label.text = "Time:" time_label.custom_minimum_size.x = 60 time_hbox.add_child(time_label) _time_slider = HSlider.new() _time_slider.min_value = 0.0 _time_slider.max_value = 1.0 _time_slider.step = 0.001 _time_slider.size_flags_horizontal = Control.SIZE_EXPAND_FILL time_hbox.add_child(_time_slider) _pause_button = Button.new() _pause_button.text = "Pause" _pause_button.toggle_mode = true _vbox.add_child(_pause_button) _vbox.add_child(HSeparator.new()) _sun_label = Label.new() _sun_label.text = "Sun: —" _vbox.add_child(_sun_label) _moon_label = Label.new() _moon_label.text = "Moon: —" _vbox.add_child(_moon_label) _ambient_label = Label.new() _ambient_label.text = "Ambient: —" _vbox.add_child(_ambient_label) _vbox.add_child(HSeparator.new()) _weather_label = Label.new() _weather_label.text = "Weather: Clear" _vbox.add_child(_weather_label) var weather_hbox := HBoxContainer.new() _vbox.add_child(weather_hbox) var weather_label := Label.new() weather_label.text = "Set:" weather_label.custom_minimum_size.x = 60 weather_hbox.add_child(weather_label) _weather_dropdown = OptionButton.new() _weather_dropdown.size_flags_horizontal = Control.SIZE_EXPAND_FILL for state_name in WeatherProfile.WeatherState.keys(): _weather_dropdown.add_item(state_name) weather_hbox.add_child(_weather_dropdown) _vbox.add_child(HSeparator.new()) _cloud_label = Label.new() _cloud_label.text = "Clouds: 0%" _vbox.add_child(_cloud_label) _fog_label = Label.new() _fog_label.text = "Fog: —" _vbox.add_child(_fog_label) _rain_label = Label.new() _rain_label.text = "Rain: 0% | Snow: 0%" _vbox.add_child(_rain_label) _seed_label = Label.new() _seed_label.text = "Seed: 0 | Day: 1" _vbox.add_child(_seed_label) var meteor_button := Button.new() meteor_button.text = "Trigger Meteor Shower" meteor_button.pressed.connect(_on_meteor_pressed) _vbox.add_child(meteor_button) func _connect_signals() -> void: _time_slider.value_changed.connect(_on_time_slider_changed) _pause_button.toggled.connect(_on_pause_toggled) _weather_dropdown.item_selected.connect(_on_weather_selected) func _update_labels() -> void: if dynamic_sky == null: return _preset_label.text = "Preset: %s" % dynamic_sky.preset_name if dynamic_sky.preset_name != "" else "Preset: (none)" var time := dynamic_sky.get_time_of_day() var hours := int(time * 24.0) var minutes := int(fmod(time * 24.0 * 60.0, 60.0)) _time_label.text = "Time: %02d:%02d (%.3f)" % [hours, minutes, time] if not _time_slider.has_focus(): _time_slider.set_value_no_signal(time) if dynamic_sky.day_night_controller: _period_label.text = "Period: %s" % dynamic_sky.day_night_controller.get_time_period().to_upper() _pause_button.set_pressed_no_signal(dynamic_sky.day_night_controller.paused) if dynamic_sky.sun_light: _sun_label.text = "Sun: %.2f %s" % [ dynamic_sky.sun_light.light_energy, "visible" if dynamic_sky.sun_light.visible else "hidden" ] if dynamic_sky.moon_light: _moon_label.text = "Moon: %.2f %s" % [ dynamic_sky.moon_light.light_energy, "visible" if dynamic_sky.moon_light.visible else "hidden" ] if dynamic_sky.world_environment and dynamic_sky.world_environment.environment: var env := dynamic_sky.world_environment.environment _ambient_label.text = "Ambient: %.2f" % env.ambient_light_energy _fog_label.text = "Fog: %s density=%.4f" % [ "ON" if env.fog_enabled else "OFF", env.fog_density ] var weather := dynamic_sky.get_current_weather() var weather_name: String = WeatherProfile.WeatherState.keys()[weather] _weather_label.text = "Weather: %s" % weather_name if dynamic_sky.weather_controller: var coverage := dynamic_sky.weather_controller.get_cloud_coverage() _cloud_label.text = "Clouds: %d%%" % int(coverage * 100) if dynamic_sky.weather_controller.is_transitioning(): var progress := dynamic_sky.weather_controller.get_transition_progress() _weather_label.text += " (transitioning %.0f%%)" % (progress * 100) if dynamic_sky.weather_controller: var rain := dynamic_sky.weather_controller.get_rain_intensity() var snow := dynamic_sky.weather_controller.get_snow_intensity() _rain_label.text = "Rain: %d%% | Snow: %d%%" % [int(rain * 100), int(snow * 100)] var day_num := 1 if dynamic_sky.day_night_controller: day_num = dynamic_sky.day_night_controller.current_day _seed_label.text = "Seed: %d | Day: %d" % [dynamic_sky.deterministic_seed, day_num] func _on_time_slider_changed(value: float) -> void: if dynamic_sky: dynamic_sky.set_time_of_day(value) func _on_pause_toggled(pressed: bool) -> void: if dynamic_sky: if pressed: dynamic_sky.pause_time() else: dynamic_sky.resume_time() _pause_button.text = "Resume" if pressed else "Pause" func _on_weather_selected(index: int) -> void: if dynamic_sky: var state: WeatherProfile.WeatherState = index as WeatherProfile.WeatherState dynamic_sky.set_weather(state) func _on_meteor_pressed() -> void: if dynamic_sky: dynamic_sky.trigger_meteor_shower(30.0)