diff --git a/main.tscn b/main.tscn index 73af81e..bec9b80 100644 --- a/main.tscn +++ b/main.tscn @@ -9,6 +9,7 @@ [ext_resource type="Script" uid="uid://bbwol3mrjgn2x" path="res://world/active_world_adapter.gd" id="9_adapter"] [ext_resource type="Script" path="res://simulation/persistence/SaveSlotController.gd" id="10_save"] [ext_resource type="PackedScene" path="res://world/jajce/JajceWorld.tscn" id="11_jajce"] +[ext_resource type="Script" path="res://world/ui/time_dial.gd" id="12_timedial"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_o5qli"] radius = 0.4 @@ -124,3 +125,12 @@ layout_mode = 2 theme_override_colors/font_color = Color(0.96, 0.91, 0.78, 1) theme_override_font_sizes/font_size = 15 text = "Villager inspector" + +[node name="TimeDial" type="Control" parent="UI" node_paths=PackedStringArray("day_night_cycle")] +layout_mode = 0 +offset_left = 880.0 +offset_top = 6.0 +offset_right = 940.0 +offset_bottom = 66.0 +script = ExtResource("12_timedial") +day_night_cycle = NodePath("../JajceWorld/DayNightCycle") diff --git a/world/ui/time_dial.gd b/world/ui/time_dial.gd new file mode 100644 index 0000000..cdac8a6 --- /dev/null +++ b/world/ui/time_dial.gd @@ -0,0 +1,93 @@ +extends Control + +@export var day_night_cycle: Node + +const SIZE_DIAL := 60.0 +const RING_RADIUS := 24.0 +const RING_THICKNESS := 4.0 +const GLOW_RADIUS := 2.5 + +const COLOR_NIGHT := Color(0.12, 0.16, 0.42, 1) +const COLOR_DAWN := Color(0.95, 0.5, 0.2, 1) +const COLOR_DAY := Color(1, 0.84, 0.38, 1) +const COLOR_DUSK := Color(0.9, 0.35, 0.2, 1) +const COLOR_BG := Color(0.06, 0.06, 0.08, 0.65) + +var _last_fraction := -1.0 +var _last_color := Color.TRANSPARENT + + +func _process(_delta: float) -> void: + var fraction := _cycle_fraction() + if not is_equal_approx(fraction, _last_fraction): + _last_fraction = fraction + queue_redraw() + + +func _draw() -> void: + var center := Vector2(SIZE_DIAL / 2.0, SIZE_DIAL / 2.0) + var fraction := _last_fraction + if fraction < 0.0: + fraction = _cycle_fraction() + _last_fraction = fraction + + var time_color := _time_color(fraction) + + draw_circle(center, RING_RADIUS + 1.0, COLOR_BG) + + var start_angle := -PI / 2.0 + var end_angle := start_angle + fraction * TAU + draw_arc(center, RING_RADIUS, start_angle, end_angle, 48, time_color, RING_THICKNESS, true) + + if fraction > 0.0: + var tip_dir := Vector2.from_angle(end_angle) + var tip_pos := center + tip_dir * RING_RADIUS + draw_circle(tip_pos, GLOW_RADIUS, time_color.lightened(0.3)) + + var label := _phase_label(fraction) + var font := ThemeDB.fallback_font + if font == null: + return + var font_size := 11 + var text_size := font.get_string_size(label, HORIZONTAL_ALIGNMENT_CENTER, -1, font_size) + var text_x := (SIZE_DIAL - text_size.x) / 2.0 + var text_y := SIZE_DIAL - text_size.y + 4.0 + draw_string(font, Vector2(text_x, text_y), label, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color.WHITE) + + +func _cycle_fraction() -> float: + if day_night_cycle == null: + return 0.0 + var elapsed: float = day_night_cycle.get("elapsed") if "elapsed" in day_night_cycle else 0.0 + var duration: float = ( + day_night_cycle.get("cycle_duration_seconds") + if "cycle_duration_seconds" in day_night_cycle + else 240.0 + ) + if duration <= 0.0: + return 0.0 + return fmod(elapsed / duration, 1.0) + + +func _time_color(fraction: float) -> Color: + if fraction < 0.15: + return COLOR_NIGHT + if fraction < 0.3: + return COLOR_NIGHT.lerp(COLOR_DAWN, smoothstep(0.15, 0.3, fraction)) + if fraction < 0.7: + return COLOR_DAY + if fraction < 0.85: + return COLOR_DAY.lerp(COLOR_DUSK, smoothstep(0.7, 0.85, fraction)) + return COLOR_DUSK.lerp(COLOR_NIGHT, smoothstep(0.85, 1.0, fraction)) + + +func _phase_label(fraction: float) -> String: + if fraction < 0.1: + return "Night" + if fraction < 0.2: + return "Dawn" + if fraction < 0.65: + return "Day" + if fraction < 0.8: + return "Dusk" + return "Night"