Files
Ransom-s-wake/game/presentation/cockpit/cockpit_instrument_panel.gd

142 lines
4.1 KiB
GDScript

class_name CockpitInstrumentPanel
extends Node3D
const DiveUpdate = preload("res://game/domain/dive/dive_update.gd")
const DiveAlertLevel = preload("res://game/domain/dive/dive_alert_level.gd")
const ReturnEstimate = preload("res://game/domain/dive/return_estimate.gd")
const VehicleTelemetry = preload("res://game/application/dive/vehicle_telemetry.gd")
const CockpitDetailing = preload(
"res://game/presentation/cockpit/cockpit_detailing.gd"
)
const COLOR_NORMAL := Color(0.45, 0.89, 0.90, 1.0)
const COLOR_ATTENTION := Color(1.0, 0.75, 0.20, 1.0)
const COLOR_CRITICAL := Color(1.0, 0.42, 0.31, 1.0)
@onready var _resources_label: Label3D = %ResourcesLabel
@onready var _navigation_label: Label3D = %NavigationLabel
@onready var _integrity_label: Label3D = %IntegrityLabel
@onready var _return_label: Label3D = %ReturnLabel
@onready var _status_label: Label3D = %StatusLabel
@onready var _sonar_screen: MeshInstance3D = %SonarScreen
@onready var _sonar_placeholder: Label3D = %SonarPlaceholder
@onready var _detailing: CockpitDetailing = %CockpitDetailing
var _sonar_texture: Texture2D
func present(update: DiveUpdate, telemetry: VehicleTelemetry) -> void:
if update == null or update.snapshot == null or telemetry == null:
return
var snapshot = update.snapshot
_resources_label.text = (
"BAT %.1f kWh · O₂ %.0f %%\n%.0f kW · %.1f L/min"
% [
snapshot.battery.remaining_kwh,
snapshot.oxygen.ratio * 100.0,
snapshot.battery.current_power_kw,
snapshot.oxygen.consumption_l_per_min,
]
)
_navigation_label.text = (
"PROF. %.1f / %.1f m\nVIT. %.2f m/s"
% [
snapshot.depth.current_m,
snapshot.depth.certified_m,
telemetry.world_linear_velocity_mps.length(),
]
)
_integrity_label.text = (
"COQUE %.0f %% · %.2f bar\nLIMITE %.2f bar"
% [
snapshot.hull.ratio * 100.0,
snapshot.hull.exterior_pressure_bar,
snapshot.hull.certified_pressure_bar,
]
)
_return_label.text = _return_text(snapshot.return_estimate)
_status_label.text = "SYSTÈMES · %s" % _alert_text(snapshot.alerts.maximum)
_resources_label.modulate = _alert_color(
maxi(snapshot.alerts.battery, snapshot.alerts.oxygen)
)
_integrity_label.modulate = _alert_color(
maxi(snapshot.alerts.hull, snapshot.alerts.depth)
)
_status_label.modulate = _alert_color(snapshot.alerts.maximum)
_detailing.present(update, telemetry)
func resources_text() -> String:
return _resources_label.text
func navigation_text() -> String:
return _navigation_label.text
func integrity_text() -> String:
return _integrity_label.text
func return_text() -> String:
return _return_label.text
func attach_sonar_texture(texture: Texture2D) -> void:
_sonar_texture = texture
var material := StandardMaterial3D.new()
material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
material.albedo_texture = texture
material.emission_enabled = true
material.emission_texture = texture
material.emission_energy_multiplier = 1.7
_sonar_screen.material_override = material
_sonar_placeholder.visible = false
func sonar_texture() -> Texture2D:
return _sonar_texture
func detailing() -> CockpitDetailing:
return _detailing
func _return_text(estimate: ReturnEstimate) -> String:
match estimate.status:
ReturnEstimate.Status.SAFE:
return "RETOUR %.1f kWh · MARGE %.1f kWh" % [
estimate.required_kwh,
estimate.margin_kwh,
]
ReturnEstimate.Status.TIGHT:
return "RETOUR SERRÉ · MARGE %.1f kWh" % estimate.margin_kwh
ReturnEstimate.Status.INSUFFICIENT:
return "RETOUR INSUFFISANT · MANQUE %.1f kWh" % absf(
estimate.margin_kwh
)
return "RETOUR · INCONNU"
func _alert_text(level: DiveAlertLevel.Value) -> String:
match level:
DiveAlertLevel.Value.NORMAL:
return "NORMAL"
DiveAlertLevel.Value.ATTENTION:
return "ATTENTION"
DiveAlertLevel.Value.RETURN:
return "RETOUR"
DiveAlertLevel.Value.CRITICAL:
return "CRITIQUE"
DiveAlertLevel.Value.FAILURE:
return "DÉFAILLANCE"
return "INCONNU"
func _alert_color(level: DiveAlertLevel.Value) -> Color:
if level >= DiveAlertLevel.Value.CRITICAL:
return COLOR_CRITICAL
if level >= DiveAlertLevel.Value.ATTENTION:
return COLOR_ATTENTION
return COLOR_NORMAL