Files
Ransom-s-wake/src/sonar_hud.gd
T

252 lines
8.6 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
class_name SonarHud
extends CanvasLayer
const SonarModelScript = preload("res://src/sonar_model.gd")
const SonarReliefRendererScript = preload("res://src/sonar_relief_renderer.gd")
signal expanded_changed(is_expanded: bool)
var _renderer: SubViewport
var _telemetry_label: Label
var _compact_panel: PanelContainer
var _compact_status: Label
var _expanded_overlay: ColorRect
var _expanded_status: Label
var _help_label: Label
var _expanded := false
func _ready() -> void:
layer = 2
_renderer = SonarReliefRendererScript.new()
_renderer.name = "SonarReliefRenderer"
add_child(_renderer)
_build_hud()
func update_telemetry(snapshot: Dictionary) -> void:
_telemetry_label.text = "PROFONDEUR %.1f m\nVITESSE %.1f m/s\nPROPULSION %d%%" % [
float(snapshot.get("depth", 0.0)),
float(snapshot.get("speed", 0.0)),
int(round(float(snapshot.get("battery", 0.0)))),
]
func update_sonar_pose(new_transform: Transform3D) -> void:
_renderer.update_submarine_pose(new_transform)
func show_ping_started(_max_range: float) -> void:
_renderer.start_scan()
_set_status(
"SCAN 0% • PREMIERS RETOURS EN ATTENTE",
Color("9cf7f2"),
"SCAN 0%"
)
func show_ping_progress(
current_cells: Array[Dictionary],
previous_cells: Array[Dictionary],
_max_range: float,
progress: float
) -> void:
_renderer.update_scan(current_cells, previous_cells, progress)
var metal_detected := _metal_cell_count(current_cells) > 0
var color := Color("ffad52") if metal_detected else Color("9cf7f2")
var suffix := " • ANOMALIE" if metal_detected else ""
var status := "SCAN %d%%%s" % [int(round(progress * 100.0)), suffix]
_set_status(status, color, status)
func show_ping_results(
current_cells: Array[Dictionary],
_previous_cells: Array[Dictionary],
_max_range: float
) -> void:
_renderer.finish_scan(current_cells)
var metal_count := _metal_cell_count(current_cells)
var status := "SCAN TERMINÉ • RELIEF RECONSTRUIT"
var color := Color("9cf7f2")
if metal_count > 0:
status += " • ANOMALIE ORANGE"
color = Color("ffad52")
_set_status(
status,
color,
"SCAN TERMINÉ • ANOMALIE" if metal_count > 0 else "SCAN TERMINÉ"
)
func toggle_expanded() -> void:
set_expanded(not _expanded)
func set_expanded(is_expanded: bool) -> void:
if _expanded == is_expanded:
return
_expanded = is_expanded
_expanded_overlay.visible = is_expanded
_compact_panel.visible = not is_expanded
_help_label.visible = not is_expanded
expanded_changed.emit(is_expanded)
func is_expanded() -> bool:
return _expanded
func relief_renderer() -> SubViewport:
return _renderer
func _set_status(text: String, color: Color, compact_text: String = "") -> void:
_compact_status.text = text if compact_text.is_empty() else compact_text
_compact_status.modulate = color
_expanded_status.text = text
_expanded_status.modulate = color
func _metal_cell_count(cells: Array[Dictionary]) -> int:
var count := 0
for cell: Dictionary in cells:
if int(cell["material"]) == SonarModelScript.MaterialCategory.METAL:
count += 1
return count
func _build_hud() -> void:
var root := Control.new()
root.name = "SonarHudRoot"
root.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
add_child(root)
var objective := Label.new()
objective.set_anchors_preset(Control.PRESET_CENTER_TOP)
objective.position = Vector2(-390.0, 24.0)
objective.size = Vector2(780.0, 38.0)
objective.text = "LISEZ LE RELIEF • FRANCHISSEZ L'OUVERTURE • IDENTIFIEZ L'ANOMALIE"
objective.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
objective.add_theme_font_size_override("font_size", 18)
root.add_child(objective)
var telemetry_panel := PanelContainer.new()
telemetry_panel.position = Vector2(22.0, 82.0)
telemetry_panel.size = Vector2(280.0, 118.0)
root.add_child(telemetry_panel)
_telemetry_label = Label.new()
_telemetry_label.text = "PROFONDEUR\nVITESSE\nPROPULSION"
_telemetry_label.add_theme_font_size_override("font_size", 16)
telemetry_panel.add_child(_telemetry_label)
var instruction_panel := PanelContainer.new()
instruction_panel.position = Vector2(22.0, 214.0)
instruction_panel.size = Vector2(294.0, 112.0)
root.add_child(instruction_panel)
var instruction := Label.new()
instruction.text = (
"F ÉMETTRE UN SCAN MANUEL\n"
+ "Le relief apparaît du proche au lointain.\n"
+ "L'orange signale un retour anormal."
)
instruction.modulate = Color(0.78, 0.94, 0.95, 0.94)
instruction_panel.add_child(instruction)
_compact_panel = PanelContainer.new()
_compact_panel.set_anchors_preset(Control.PRESET_TOP_RIGHT)
_compact_panel.position = Vector2(-342.0, 82.0)
_compact_panel.size = Vector2(320.0, 276.0)
root.add_child(_compact_panel)
var compact_box := VBoxContainer.new()
compact_box.add_theme_constant_override("separation", 6)
_compact_panel.add_child(compact_box)
var compact_title := Label.new()
compact_title.text = "SONAR BATHYMÉTRIQUE • AGRANDIR"
compact_title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
compact_title.add_theme_font_size_override("font_size", 14)
compact_box.add_child(compact_title)
var compact_view := _make_sonar_texture_rect(Vector2(298.0, 190.0))
compact_view.tooltip_text = "Cliquez pour ouvrir le grand écran sonar"
compact_view.mouse_filter = Control.MOUSE_FILTER_STOP
compact_view.gui_input.connect(_on_compact_view_input)
compact_box.add_child(compact_view)
_compact_status = Label.new()
_compact_status.text = "F • LANCER LE PREMIER SCAN"
_compact_status.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
compact_box.add_child(_compact_status)
var compact_reference := Label.new()
compact_reference.text = "PORTÉE 95 M • SOUS-MARIN EN BAS • CAP VERS LE HAUT"
compact_reference.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
compact_reference.modulate = Color(0.62, 0.82, 0.84, 0.86)
compact_reference.add_theme_font_size_override("font_size", 11)
compact_box.add_child(compact_reference)
_expanded_overlay = ColorRect.new()
_expanded_overlay.name = "ExpandedSonarOverlay"
_expanded_overlay.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
_expanded_overlay.color = Color(0.0, 0.015, 0.02, 0.96)
_expanded_overlay.mouse_filter = Control.MOUSE_FILTER_STOP
_expanded_overlay.visible = false
root.add_child(_expanded_overlay)
var expanded_panel := PanelContainer.new()
expanded_panel.position = Vector2(110.0, 34.0)
expanded_panel.size = Vector2(1060.0, 652.0)
_expanded_overlay.add_child(expanded_panel)
var expanded_box := VBoxContainer.new()
expanded_box.add_theme_constant_override("separation", 7)
expanded_panel.add_child(expanded_box)
var expanded_title := Label.new()
expanded_title.text = "SONAR BATHYMÉTRIQUE • PORTÉE 95 M • CAP VERS LE HAUT"
expanded_title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
expanded_title.add_theme_font_size_override("font_size", 19)
expanded_box.add_child(expanded_title)
var expanded_view := _make_sonar_texture_rect(Vector2(1038.0, 556.0))
expanded_box.add_child(expanded_view)
_expanded_status = Label.new()
_expanded_status.text = "F • LANCER LE PREMIER SCAN"
_expanded_status.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_expanded_status.add_theme_font_size_override("font_size", 16)
expanded_box.add_child(_expanded_status)
var legend := Label.new()
legend.text = "BLEU PROFOND • VERT/JAUNE HAUTEUR • ORANGE CAISSE/ANOMALIE • NOIR INCONNU"
legend.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
legend.modulate = Color(0.68, 0.88, 0.90, 0.90)
expanded_box.add_child(legend)
var close_button := Button.new()
close_button.position = Vector2(1044.0, 46.0)
close_button.size = Vector2(108.0, 36.0)
close_button.text = "FERMER ×"
close_button.pressed.connect(func() -> void: set_expanded(false))
_expanded_overlay.add_child(close_button)
_help_label = Label.new()
_help_label.set_anchors_preset(Control.PRESET_BOTTOM_WIDE)
_help_label.offset_left = 20.0
_help_label.offset_top = -42.0
_help_label.offset_right = -20.0
_help_label.offset_bottom = -12.0
_help_label.text = "F scanner • Tab agrandir/fermer • W/S propulsion • A/D gouvernail • Espace/Ctrl profondeur • Échap souris"
_help_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_help_label.modulate = Color(0.75, 0.90, 0.94, 0.9)
root.add_child(_help_label)
func _make_sonar_texture_rect(minimum_size: Vector2) -> TextureRect:
var view := TextureRect.new()
view.custom_minimum_size = minimum_size
view.texture = _renderer.get_texture()
view.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
view.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
return view
func _on_compact_view_input(event: InputEvent) -> void:
if (
event is InputEventMouseButton
and event.button_index == MOUSE_BUTTON_LEFT
and event.pressed
):
set_expanded(true)