extends CanvasLayer const WATER_SURFACE_Y: float = 60.0 @onready var _oxygen_bar: ProgressBar = %OxygenBar @onready var _health_bar: ProgressBar = %HealthBar @onready var _hunger_bar: ProgressBar = %HungerBar var _dolphin: Node3D = null var _world_seed: int = 12345 var _info_panel: PanelContainer = null var _depth_label: Label = null var _biome_label: Label = null var _compass_label: Label = null var _biome_cache_pos: Vector3 = Vector3(99999, 99999, 99999) var _biome_cached_name: String = "" func _ready() -> void: _style_bar(_oxygen_bar, Color(0.31, 0.76, 0.97)) _style_bar(_health_bar, Color(0.91, 0.30, 0.24)) _style_bar(_hunger_bar, Color(0.95, 0.61, 0.07)) _build_info_panel() func _build_info_panel() -> void: _info_panel = PanelContainer.new() _info_panel.anchor_left = 1.0 _info_panel.anchor_right = 1.0 _info_panel.anchor_top = 0.0 _info_panel.anchor_bottom = 0.0 _info_panel.offset_left = -220.0 _info_panel.offset_top = 16.0 _info_panel.offset_right = -16.0 _info_panel.offset_bottom = 112.0 var style := StyleBoxFlat.new() style.bg_color = Color(0.05, 0.05, 0.05, 0.7) style.corner_radius_top_left = 10 style.corner_radius_top_right = 10 style.corner_radius_bottom_left = 10 style.corner_radius_bottom_right = 10 _info_panel.add_theme_stylebox_override("panel", style) var vbox := VBoxContainer.new() vbox.add_theme_constant_override("separation", 4) _info_panel.add_child(vbox) _compass_label = Label.new() _compass_label.text = "⬆ N" _compass_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER _compass_label.add_theme_font_size_override("font_size", 20) _compass_label.add_theme_color_override("font_color", Color(0.85, 0.95, 1.0)) vbox.add_child(_compass_label) _depth_label = Label.new() _depth_label.text = "Prof. 0 m" _depth_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER _depth_label.add_theme_font_size_override("font_size", 14) _depth_label.add_theme_color_override("font_color", Color(0.70, 0.88, 1.0)) vbox.add_child(_depth_label) _biome_label = Label.new() _biome_label.text = "Biome : —" _biome_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER _biome_label.add_theme_font_size_override("font_size", 14) _biome_label.add_theme_color_override("font_color", Color(0.85, 0.95, 0.75)) vbox.add_child(_biome_label) add_child(_info_panel) func _style_bar(bar: ProgressBar, color: Color) -> void: var style := StyleBoxFlat.new() style.bg_color = color style.corner_radius_top_left = 4 style.corner_radius_top_right = 4 style.corner_radius_bottom_left = 4 style.corner_radius_bottom_right = 4 bar.add_theme_stylebox_override("fill", style) var bg_style := StyleBoxFlat.new() bg_style.bg_color = Color(0.1, 0.1, 0.1, 0.6) bg_style.corner_radius_top_left = 4 bg_style.corner_radius_top_right = 4 bg_style.corner_radius_bottom_left = 4 bg_style.corner_radius_bottom_right = 4 bar.add_theme_stylebox_override("background", bg_style) func connect_to_dolphin(dolphin: CharacterBody3D) -> void: dolphin.stats_changed.connect(_on_stats_changed) _dolphin = dolphin var main: Node = get_tree().get_first_node_in_group("main") if main != null: var cm: Node = main.get_node_or_null("World/ChunkManager") if cm != null and cm.get("world_seed") != null: _world_seed = cm.world_seed func _on_stats_changed(oxygen: float, hp: float, hunger: float) -> void: _oxygen_bar.value = oxygen _health_bar.value = hp _hunger_bar.value = hunger func _process(_delta: float) -> void: if not is_instance_valid(_dolphin): return var depth_m: int = int(round(WATER_SURFACE_Y - _dolphin.global_position.y)) if _depth_label != null: _depth_label.text = "Prof. %d m" % depth_m if _compass_label != null: _compass_label.text = _compass_text(_dolphin.rotation.y) if _biome_label != null: _update_biome_label() func _compass_text(yaw: float) -> String: # Player forward is -Z when yaw=0 → North. Yaw rotates counterclockwise in Godot. # Convert yaw to a heading [0, 360) where 0 = North, 90 = East. var heading: float = rad_to_deg(-yaw) heading = fposmod(heading, 360.0) var labels: PackedStringArray = PackedStringArray(["N", "NE", "E", "SE", "S", "SO", "O", "NO"]) var arrows: PackedStringArray = PackedStringArray([ "⬆", "⬈", "➡", "⬊", "⬇", "⬋", "⬅", "⬉" ]) var idx: int = int(round(heading / 45.0)) % 8 return "%s %s" % [arrows[idx], labels[idx]] func _update_biome_label() -> void: var pos: Vector3 = _dolphin.global_position if pos.distance_to(_biome_cache_pos) < 4.0 and _biome_cached_name != "": _biome_label.text = "Biome : %s" % _biome_cached_name return _biome_cache_pos = pos _biome_cached_name = WorldGenerator.biome_name_at(pos.x, pos.z, pos.y, _world_seed) _biome_label.text = "Biome : %s" % _biome_cached_name