Validate POC A and POC B foundations

This commit is contained in:
chindit committed 2026-08-07 13:31:21 +02:00
1 parent 44fd4b4b43
commit c38e09a663
47 files changed
+4990 -35

No files matched your search

+251
View File
@@ -0,0 +1,251 @@
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)