Implement production vertical slice foundation
This commit is contained in:
1 parent
9d4a89f355
commit
a18e82eb44
104 files changed
+10595
-268
No files matched your search
@@ -0,0 +1,82 @@
|
||||
class_name CockpitCameraController
|
||||
extends Node3D
|
||||
|
||||
const CameraLookCommand = preload(
|
||||
"res://game/application/vehicle/camera_look_command.gd"
|
||||
)
|
||||
const VehicleTelemetry = preload("res://game/application/dive/vehicle_telemetry.gd")
|
||||
|
||||
@export var minimum_pitch_radians := -0.30
|
||||
@export var maximum_pitch_radians := 0.20
|
||||
@export var maximum_yaw_radians := deg_to_rad(30.0)
|
||||
@export var feedback_response := 4.5
|
||||
@export var maximum_feedback_pitch_radians := deg_to_rad(18.0)
|
||||
@export var maximum_feedback_roll_radians := deg_to_rad(16.0) * 0.55
|
||||
|
||||
var _look_yaw := 0.0
|
||||
var _look_pitch := -0.04
|
||||
var _feedback_pitch := 0.0
|
||||
var _feedback_roll := 0.0
|
||||
var _target_feedback_pitch := 0.0
|
||||
var _target_feedback_roll := 0.0
|
||||
|
||||
|
||||
func apply_look(command: CameraLookCommand) -> void:
|
||||
if command == null or not command.validation_error().is_empty():
|
||||
return
|
||||
if command.recenter_requested:
|
||||
_look_yaw = 0.0
|
||||
_look_pitch = -0.04
|
||||
else:
|
||||
_look_yaw = clampf(
|
||||
_look_yaw + command.yaw_delta_radians,
|
||||
-maximum_yaw_radians,
|
||||
maximum_yaw_radians
|
||||
)
|
||||
_look_pitch = clampf(
|
||||
_look_pitch + command.pitch_delta_radians,
|
||||
minimum_pitch_radians,
|
||||
maximum_pitch_radians
|
||||
)
|
||||
_apply_rotation()
|
||||
|
||||
|
||||
func present_telemetry(telemetry: VehicleTelemetry) -> void:
|
||||
if telemetry == null:
|
||||
return
|
||||
_target_feedback_pitch = (
|
||||
-telemetry.vertical_effort * maximum_feedback_pitch_radians
|
||||
)
|
||||
_target_feedback_roll = (
|
||||
-telemetry.steering_effort * maximum_feedback_roll_radians
|
||||
)
|
||||
|
||||
|
||||
func look_yaw_radians() -> float:
|
||||
return _look_yaw
|
||||
|
||||
|
||||
func look_pitch_radians() -> float:
|
||||
return _look_pitch
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_feedback_pitch = lerpf(
|
||||
_feedback_pitch,
|
||||
_target_feedback_pitch,
|
||||
1.0 - exp(-feedback_response * delta)
|
||||
)
|
||||
_feedback_roll = lerpf(
|
||||
_feedback_roll,
|
||||
_target_feedback_roll,
|
||||
1.0 - exp(-feedback_response * delta)
|
||||
)
|
||||
_apply_rotation()
|
||||
|
||||
|
||||
func _apply_rotation() -> void:
|
||||
rotation = Vector3(
|
||||
_look_pitch + _feedback_pitch,
|
||||
_look_yaw,
|
||||
_feedback_roll
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://game/presentation/cockpit/cockpit_camera_controller.gd" id="1_camera"]
|
||||
|
||||
[node name="CockpitCameraRig" type="Node3D"]
|
||||
position = Vector3(0, 0.52, -0.48)
|
||||
script = ExtResource("1_camera")
|
||||
|
||||
[node name="Camera" type="Camera3D" parent="."]
|
||||
current = true
|
||||
fov = 82.0
|
||||
near = 0.05
|
||||
@@ -0,0 +1,61 @@
|
||||
class_name CockpitHud
|
||||
extends Control
|
||||
|
||||
const DiveUpdate = preload("res://game/domain/dive/dive_update.gd")
|
||||
const DiveAlertLevel = preload("res://game/domain/dive/dive_alert_level.gd")
|
||||
const DiveTerminalReason = preload("res://game/domain/dive/dive_terminal_reason.gd")
|
||||
const VehicleTelemetry = preload("res://game/application/dive/vehicle_telemetry.gd")
|
||||
|
||||
@onready var _alert_panel: PanelContainer = %AlertPanel
|
||||
@onready var _alert_label: Label = %AlertLabel
|
||||
@onready var _ejection_panel: PanelContainer = %EjectionPanel
|
||||
@onready var _ejection_label: Label = %EjectionLabel
|
||||
@onready var _terminal_panel: PanelContainer = %TerminalPanel
|
||||
@onready var _terminal_label: Label = %TerminalLabel
|
||||
|
||||
|
||||
func present(update: DiveUpdate, telemetry: VehicleTelemetry) -> void:
|
||||
if update == null or update.snapshot == null or telemetry == null:
|
||||
return
|
||||
var snapshot = update.snapshot
|
||||
_alert_panel.visible = snapshot.alerts.maximum != DiveAlertLevel.Value.NORMAL
|
||||
_alert_label.text = "ALERTE · %s" % _alert_text(snapshot.alerts.maximum)
|
||||
_ejection_panel.visible = snapshot.ejection.held_seconds > 0.0
|
||||
_ejection_label.text = "ÉJECTION %.0f %%" % (snapshot.ejection.ratio * 100.0)
|
||||
_terminal_panel.visible = snapshot.is_terminal()
|
||||
if snapshot.is_terminal():
|
||||
_terminal_label.text = "%s\nÉchap pour ouvrir le menu de pause." % [
|
||||
_terminal_text(snapshot.terminal_reason)
|
||||
]
|
||||
|
||||
|
||||
func alert_overlay_visible() -> bool:
|
||||
return _alert_panel.visible
|
||||
|
||||
|
||||
func _alert_text(level: DiveAlertLevel.Value) -> String:
|
||||
match level:
|
||||
DiveAlertLevel.Value.NORMAL:
|
||||
return tr("NORMAL")
|
||||
DiveAlertLevel.Value.ATTENTION:
|
||||
return tr("ATTENTION")
|
||||
DiveAlertLevel.Value.RETURN:
|
||||
return tr("RETOUR")
|
||||
DiveAlertLevel.Value.CRITICAL:
|
||||
return tr("CRITIQUE")
|
||||
DiveAlertLevel.Value.FAILURE:
|
||||
return tr("DÉFAILLANCE")
|
||||
return tr("INCONNU")
|
||||
|
||||
|
||||
func _terminal_text(reason: DiveTerminalReason.Value) -> String:
|
||||
match reason:
|
||||
DiveTerminalReason.Value.VOLUNTARY_EJECTION:
|
||||
return tr("ÉJECTION DÉCLENCHÉE")
|
||||
DiveTerminalReason.Value.OXYGEN_DEPLETED:
|
||||
return tr("OXYGÈNE ÉPUISÉ")
|
||||
DiveTerminalReason.Value.HULL_DESTROYED:
|
||||
return tr("COQUE DÉTRUITE")
|
||||
DiveTerminalReason.Value.RETURNED:
|
||||
return tr("RETOUR TERMINÉ")
|
||||
return tr("PLONGÉE TERMINÉE")
|
||||
@@ -0,0 +1,109 @@
|
||||
[gd_scene load_steps=4 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://game/presentation/cockpit/cockpit_hud.gd" id="1_hud"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="AlertStyle"]
|
||||
bg_color = Color(0.14, 0.075, 0.02, 0.92)
|
||||
border_width_left = 2
|
||||
border_width_top = 2
|
||||
border_width_right = 2
|
||||
border_width_bottom = 2
|
||||
border_color = Color(1, 0.75, 0.2, 1)
|
||||
content_margin_left = 22.0
|
||||
content_margin_top = 10.0
|
||||
content_margin_right = 22.0
|
||||
content_margin_bottom = 10.0
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="DangerStyle"]
|
||||
bg_color = Color(0.16, 0.025, 0.018, 0.94)
|
||||
border_width_left = 2
|
||||
border_width_top = 2
|
||||
border_width_right = 2
|
||||
border_width_bottom = 2
|
||||
border_color = Color(1, 0.42, 0.31, 1)
|
||||
content_margin_left = 24.0
|
||||
content_margin_top = 12.0
|
||||
content_margin_right = 24.0
|
||||
content_margin_bottom = 12.0
|
||||
|
||||
[node name="CockpitHud" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
script = ExtResource("1_hud")
|
||||
|
||||
[node name="AlertPanel" type="PanelContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 10
|
||||
anchor_right = 1.0
|
||||
offset_left = 590.0
|
||||
offset_top = 26.0
|
||||
offset_right = -590.0
|
||||
offset_bottom = 78.0
|
||||
grow_horizontal = 2
|
||||
theme_override_styles/panel = SubResource("AlertStyle")
|
||||
|
||||
[node name="AlertLabel" type="Label" parent="AlertPanel"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(1, 0.82, 0.42, 1)
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "ALERTE · ATTENTION"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="EjectionPanel" type="PanelContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 7
|
||||
anchor_left = 0.5
|
||||
anchor_top = 1.0
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -190.0
|
||||
offset_top = -94.0
|
||||
offset_right = 190.0
|
||||
offset_bottom = -36.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
theme_override_styles/panel = SubResource("DangerStyle")
|
||||
|
||||
[node name="EjectionLabel" type="Label" parent="EjectionPanel"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(1, 0.48, 0.38, 1)
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "ÉJECTION —"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="TerminalPanel" type="PanelContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -280.0
|
||||
offset_top = -82.0
|
||||
offset_right = 280.0
|
||||
offset_bottom = 82.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_styles/panel = SubResource("DangerStyle")
|
||||
|
||||
[node name="TerminalLabel" type="Label" parent="TerminalPanel"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(1, 0.74, 0.68, 1)
|
||||
theme_override_font_sizes/font_size = 24
|
||||
text = "PLONGÉE TERMINÉE"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
@@ -0,0 +1,118 @@
|
||||
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 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
|
||||
|
||||
|
||||
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 = (
|
||||
"BATTERIE\n%.1f / %.1f kWh · %.0f %%\n%.0f kW\n\nOXYGÈNE\n%.1f / %.1f L · %.0f %%\n%.1f L/min"
|
||||
% [
|
||||
snapshot.battery.remaining_kwh,
|
||||
snapshot.battery.maximum_kwh,
|
||||
snapshot.battery.ratio * 100.0,
|
||||
snapshot.battery.current_power_kw,
|
||||
snapshot.oxygen.remaining_l,
|
||||
snapshot.oxygen.maximum_l,
|
||||
snapshot.oxygen.ratio * 100.0,
|
||||
snapshot.oxygen.consumption_l_per_min,
|
||||
]
|
||||
)
|
||||
_navigation_label.text = (
|
||||
"PROFONDEUR\n%.1f m\nMAX. CONSEILLÉ %.1f m\n\nVITESSE\n%.2f m/s"
|
||||
% [
|
||||
snapshot.depth.current_m,
|
||||
snapshot.depth.certified_m,
|
||||
telemetry.world_linear_velocity_mps.length(),
|
||||
]
|
||||
)
|
||||
_integrity_label.text = (
|
||||
"COQUE\n%.1f / %.1f · %.0f %%\n\nPRESSION\n%.2f / %.2f bar"
|
||||
% [
|
||||
snapshot.hull.current_integrity,
|
||||
snapshot.hull.maximum_integrity,
|
||||
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)
|
||||
|
||||
|
||||
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 _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
|
||||
@@ -0,0 +1,450 @@
|
||||
[gd_scene load_steps=19 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://game/presentation/cockpit/cockpit_instrument_panel.gd" id="1_instruments"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="SteelMaterial"]
|
||||
albedo_color = Color(0.095, 0.12, 0.12, 1)
|
||||
metallic = 0.82
|
||||
roughness = 0.34
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="PaintedMaterial"]
|
||||
albedo_color = Color(0.085, 0.185, 0.19, 1)
|
||||
metallic = 0.58
|
||||
roughness = 0.48
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="BrassMaterial"]
|
||||
albedo_color = Color(0.36, 0.24, 0.075, 1)
|
||||
metallic = 0.78
|
||||
roughness = 0.31
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="RubberMaterial"]
|
||||
albedo_color = Color(0.018, 0.024, 0.025, 1)
|
||||
roughness = 0.88
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="GlassMaterial"]
|
||||
transparency = 1
|
||||
shading_mode = 0
|
||||
albedo_color = Color(0.12, 0.42, 0.47, 0.09)
|
||||
metallic = 0.12
|
||||
roughness = 0.08
|
||||
cull_mode = 2
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="ScreenMaterial"]
|
||||
albedo_color = Color(0.006, 0.025, 0.028, 1)
|
||||
metallic = 0.15
|
||||
roughness = 0.22
|
||||
emission_enabled = true
|
||||
emission = Color(0.008, 0.07, 0.075, 1)
|
||||
emission_energy_multiplier = 1.7
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="CyanMaterial"]
|
||||
shading_mode = 0
|
||||
albedo_color = Color(0.2, 0.78, 0.82, 1)
|
||||
emission_enabled = true
|
||||
emission = Color(0.12, 0.72, 0.76, 1)
|
||||
emission_energy_multiplier = 3.2
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="AmberMaterial"]
|
||||
shading_mode = 0
|
||||
albedo_color = Color(0.95, 0.52, 0.08, 1)
|
||||
emission_enabled = true
|
||||
emission = Color(0.95, 0.33, 0.02, 1)
|
||||
emission_energy_multiplier = 2.6
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="RedMaterial"]
|
||||
shading_mode = 0
|
||||
albedo_color = Color(0.82, 0.08, 0.045, 1)
|
||||
emission_enabled = true
|
||||
emission = Color(0.92, 0.055, 0.025, 1)
|
||||
emission_energy_multiplier = 2.8
|
||||
|
||||
[sub_resource type="BoxMesh" id="UnitBoxMesh"]
|
||||
size = Vector3(1, 1, 1)
|
||||
|
||||
[sub_resource type="TorusMesh" id="PortholeTorusMesh"]
|
||||
inner_radius = 0.56
|
||||
outer_radius = 0.71
|
||||
rings = 48
|
||||
ring_segments = 16
|
||||
|
||||
[sub_resource type="CylinderMesh" id="GlassCylinderMesh"]
|
||||
top_radius = 0.56
|
||||
bottom_radius = 0.56
|
||||
height = 0.012
|
||||
radial_segments = 64
|
||||
|
||||
[sub_resource type="CylinderMesh" id="BoltMesh"]
|
||||
top_radius = 0.026
|
||||
bottom_radius = 0.026
|
||||
height = 0.045
|
||||
radial_segments = 12
|
||||
|
||||
[sub_resource type="QuadMesh" id="ScreenQuadMesh"]
|
||||
size = Vector2(1, 1)
|
||||
|
||||
[sub_resource type="CylinderMesh" id="LeverMesh"]
|
||||
top_radius = 0.018
|
||||
bottom_radius = 0.023
|
||||
height = 0.24
|
||||
radial_segments = 12
|
||||
|
||||
[sub_resource type="SphereMesh" id="KnobMesh"]
|
||||
radius = 0.046
|
||||
height = 0.092
|
||||
radial_segments = 16
|
||||
rings = 8
|
||||
|
||||
[sub_resource type="CylinderMesh" id="DialMesh"]
|
||||
top_radius = 0.105
|
||||
bottom_radius = 0.105
|
||||
height = 0.035
|
||||
radial_segments = 32
|
||||
|
||||
[node name="CockpitInterior" type="Node3D"]
|
||||
script = ExtResource("1_instruments")
|
||||
|
||||
[node name="CabinShell" type="Node3D" parent="."]
|
||||
|
||||
[node name="LeftWall" type="MeshInstance3D" parent="CabinShell"]
|
||||
position = Vector3(-1.03, 0.24, -0.15)
|
||||
scale = Vector3(0.16, 1.82, 2.7)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("PaintedMaterial")
|
||||
|
||||
[node name="RightWall" type="MeshInstance3D" parent="CabinShell"]
|
||||
position = Vector3(1.03, 0.24, -0.15)
|
||||
scale = Vector3(0.16, 1.82, 2.7)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("PaintedMaterial")
|
||||
|
||||
[node name="Ceiling" type="MeshInstance3D" parent="CabinShell"]
|
||||
position = Vector3(0, 1.22, -0.2)
|
||||
scale = Vector3(2.15, 0.16, 2.6)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="Floor" type="MeshInstance3D" parent="CabinShell"]
|
||||
position = Vector3(0, -0.7, -0.1)
|
||||
scale = Vector3(2.05, 0.18, 2.5)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("RubberMaterial")
|
||||
|
||||
[node name="RearBulkhead" type="MeshInstance3D" parent="CabinShell"]
|
||||
position = Vector3(0, 0.22, 1.08)
|
||||
scale = Vector3(2.08, 1.75, 0.16)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="LeftRib" type="MeshInstance3D" parent="CabinShell"]
|
||||
position = Vector3(-0.88, 0.26, -0.45)
|
||||
scale = Vector3(0.11, 1.75, 0.18)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("BrassMaterial")
|
||||
|
||||
[node name="RightRib" type="MeshInstance3D" parent="CabinShell"]
|
||||
position = Vector3(0.88, 0.26, -0.45)
|
||||
scale = Vector3(0.11, 1.75, 0.18)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("BrassMaterial")
|
||||
|
||||
[node name="CeilingRib" type="MeshInstance3D" parent="CabinShell"]
|
||||
position = Vector3(0, 1.05, -0.45)
|
||||
scale = Vector3(1.82, 0.1, 0.18)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("BrassMaterial")
|
||||
|
||||
[node name="PortholeAssembly" type="Node3D" parent="."]
|
||||
position = Vector3(0, 0.47, -1.32)
|
||||
|
||||
[node name="LeftBulkhead" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(-0.94, 0, 0)
|
||||
scale = Vector3(0.6, 1.82, 0.2)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="RightBulkhead" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(0.94, 0, 0)
|
||||
scale = Vector3(0.6, 1.82, 0.2)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="TopBulkhead" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(0, 0.91, 0)
|
||||
scale = Vector3(1.55, 0.52, 0.2)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="BottomBulkhead" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(0, -0.91, 0)
|
||||
scale = Vector3(1.55, 0.52, 0.2)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="WindowFrame" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
unique_name_in_owner = true
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
mesh = SubResource("PortholeTorusMesh")
|
||||
material_override = SubResource("BrassMaterial")
|
||||
|
||||
[node name="RubberSeal" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
scale = Vector3(0.91, 0.91, 0.91)
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
mesh = SubResource("PortholeTorusMesh")
|
||||
material_override = SubResource("RubberMaterial")
|
||||
|
||||
[node name="WindowGlass" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(0, 0, -0.01)
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
cast_shadow = 0
|
||||
mesh = SubResource("GlassCylinderMesh")
|
||||
material_override = SubResource("GlassMaterial")
|
||||
|
||||
[node name="BoltTop" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(0, 0.665, 0.1)
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
mesh = SubResource("BoltMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="BoltBottom" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(0, -0.665, 0.1)
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
mesh = SubResource("BoltMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="BoltLeft" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(-0.665, 0, 0.1)
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
mesh = SubResource("BoltMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="BoltRight" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(0.665, 0, 0.1)
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
mesh = SubResource("BoltMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="BoltUpperLeft" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(-0.47, 0.47, 0.1)
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
mesh = SubResource("BoltMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="BoltUpperRight" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(0.47, 0.47, 0.1)
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
mesh = SubResource("BoltMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="BoltLowerLeft" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(-0.47, -0.47, 0.1)
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
mesh = SubResource("BoltMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="BoltLowerRight" type="MeshInstance3D" parent="PortholeAssembly"]
|
||||
position = Vector3(0.47, -0.47, 0.1)
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
mesh = SubResource("BoltMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="Dashboard" type="Node3D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
position = Vector3(0, 0.05, -1.22)
|
||||
rotation_degrees = Vector3(-12, 0, 0)
|
||||
|
||||
[node name="MainPanel" type="MeshInstance3D" parent="Dashboard"]
|
||||
scale = Vector3(1.56, 0.44, 0.14)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("PaintedMaterial")
|
||||
|
||||
[node name="ResourcesFrame" type="MeshInstance3D" parent="Dashboard"]
|
||||
position = Vector3(-0.5, 0.03, 0.088)
|
||||
scale = Vector3(0.45, 0.31, 0.025)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("BrassMaterial")
|
||||
|
||||
[node name="ResourcesScreen" type="MeshInstance3D" parent="Dashboard"]
|
||||
position = Vector3(-0.5, 0.03, 0.102)
|
||||
scale = Vector3(0.41, 0.27, 1)
|
||||
mesh = SubResource("ScreenQuadMesh")
|
||||
material_override = SubResource("ScreenMaterial")
|
||||
|
||||
[node name="ResourcesLabel" type="Label3D" parent="Dashboard"]
|
||||
unique_name_in_owner = true
|
||||
position = Vector3(-0.5, 0.03, 0.108)
|
||||
pixel_size = 0.00115
|
||||
font_size = 20
|
||||
outline_size = 2
|
||||
text = "BATTERIE\n— / — kWh\n— kW\n\nOXYGÈNE\n— / — L\n— L/min"
|
||||
modulate = Color(0.45, 0.89, 0.9, 1)
|
||||
|
||||
[node name="NavigationFrame" type="MeshInstance3D" parent="Dashboard"]
|
||||
position = Vector3(0, 0.03, 0.088)
|
||||
scale = Vector3(0.4, 0.31, 0.025)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("BrassMaterial")
|
||||
|
||||
[node name="NavigationScreen" type="MeshInstance3D" parent="Dashboard"]
|
||||
position = Vector3(0, 0.03, 0.102)
|
||||
scale = Vector3(0.36, 0.27, 1)
|
||||
mesh = SubResource("ScreenQuadMesh")
|
||||
material_override = SubResource("ScreenMaterial")
|
||||
|
||||
[node name="NavigationLabel" type="Label3D" parent="Dashboard"]
|
||||
unique_name_in_owner = true
|
||||
position = Vector3(0, 0.03, 0.108)
|
||||
pixel_size = 0.00115
|
||||
font_size = 20
|
||||
outline_size = 2
|
||||
text = "PROFONDEUR\n— m\nMAX. — m\n\nVITESSE\n— m/s"
|
||||
modulate = Color(0.45, 0.89, 0.9, 1)
|
||||
|
||||
[node name="IntegrityFrame" type="MeshInstance3D" parent="Dashboard"]
|
||||
position = Vector3(0.5, 0.03, 0.088)
|
||||
scale = Vector3(0.45, 0.31, 0.025)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("BrassMaterial")
|
||||
|
||||
[node name="IntegrityScreen" type="MeshInstance3D" parent="Dashboard"]
|
||||
position = Vector3(0.5, 0.03, 0.102)
|
||||
scale = Vector3(0.41, 0.27, 1)
|
||||
mesh = SubResource("ScreenQuadMesh")
|
||||
material_override = SubResource("ScreenMaterial")
|
||||
|
||||
[node name="IntegrityLabel" type="Label3D" parent="Dashboard"]
|
||||
unique_name_in_owner = true
|
||||
position = Vector3(0.5, 0.03, 0.108)
|
||||
pixel_size = 0.00115
|
||||
font_size = 20
|
||||
outline_size = 2
|
||||
text = "COQUE\n— / —\n\nPRESSION\n— / — bar"
|
||||
modulate = Color(0.45, 0.89, 0.9, 1)
|
||||
|
||||
[node name="ReturnLabel" type="Label3D" parent="Dashboard"]
|
||||
unique_name_in_owner = true
|
||||
position = Vector3(0.32, 0.205, 0.108)
|
||||
pixel_size = 0.00082
|
||||
font_size = 15
|
||||
outline_size = 2
|
||||
text = "RETOUR · INCONNU"
|
||||
modulate = Color(1, 0.75, 0.2, 1)
|
||||
|
||||
[node name="StatusLabel" type="Label3D" parent="Dashboard"]
|
||||
unique_name_in_owner = true
|
||||
position = Vector3(-0.34, 0.205, 0.108)
|
||||
pixel_size = 0.00082
|
||||
font_size = 15
|
||||
outline_size = 2
|
||||
text = "SYSTÈMES · NORMAL"
|
||||
modulate = Color(0.45, 0.89, 0.9, 1)
|
||||
|
||||
[node name="LeftConsole" type="MeshInstance3D" parent="."]
|
||||
position = Vector3(-0.82, -0.23, -1.19)
|
||||
rotation_degrees = Vector3(-8, 18, 4)
|
||||
scale = Vector3(0.32, 0.16, 0.56)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("PaintedMaterial")
|
||||
|
||||
[node name="RightConsole" type="MeshInstance3D" parent="."]
|
||||
position = Vector3(0.82, -0.23, -1.19)
|
||||
rotation_degrees = Vector3(-8, -18, -4)
|
||||
scale = Vector3(0.32, 0.16, 0.56)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("PaintedMaterial")
|
||||
|
||||
[node name="ThrottleLever" type="MeshInstance3D" parent="."]
|
||||
position = Vector3(-0.79, -0.06, -1.13)
|
||||
rotation_degrees = Vector3(18, 0, -10)
|
||||
scale = Vector3(0.72, 0.72, 0.72)
|
||||
mesh = SubResource("LeverMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="ThrottleKnob" type="MeshInstance3D" parent="."]
|
||||
position = Vector3(-0.81, 0.025, -1.1)
|
||||
scale = Vector3(0.72, 0.72, 0.72)
|
||||
mesh = SubResource("KnobMesh")
|
||||
material_override = SubResource("BrassMaterial")
|
||||
|
||||
[node name="VerticalLever" type="MeshInstance3D" parent="."]
|
||||
position = Vector3(0.79, -0.06, -1.13)
|
||||
rotation_degrees = Vector3(18, 0, 10)
|
||||
scale = Vector3(0.72, 0.72, 0.72)
|
||||
mesh = SubResource("LeverMesh")
|
||||
material_override = SubResource("SteelMaterial")
|
||||
|
||||
[node name="VerticalKnob" type="MeshInstance3D" parent="."]
|
||||
position = Vector3(0.81, 0.025, -1.1)
|
||||
scale = Vector3(0.72, 0.72, 0.72)
|
||||
mesh = SubResource("KnobMesh")
|
||||
material_override = SubResource("BrassMaterial")
|
||||
|
||||
[node name="SonarMonitor" type="Node3D" parent="."]
|
||||
position = Vector3(0.72, 0.4, -1.24)
|
||||
rotation_degrees = Vector3(-5, -22, -2)
|
||||
|
||||
[node name="Housing" type="MeshInstance3D" parent="SonarMonitor"]
|
||||
scale = Vector3(0.32, 0.24, 0.08)
|
||||
mesh = SubResource("UnitBoxMesh")
|
||||
material_override = SubResource("RubberMaterial")
|
||||
|
||||
[node name="SonarScreen" type="MeshInstance3D" parent="SonarMonitor"]
|
||||
unique_name_in_owner = true
|
||||
position = Vector3(0, 0.025, 0.06)
|
||||
scale = Vector3(0.265, 0.165, 1)
|
||||
mesh = SubResource("ScreenQuadMesh")
|
||||
material_override = SubResource("ScreenMaterial")
|
||||
|
||||
[node name="SonarPlaceholder" type="Label3D" parent="SonarMonitor"]
|
||||
position = Vector3(0, 0.025, 0.068)
|
||||
pixel_size = 0.0009
|
||||
font_size = 16
|
||||
outline_size = 2
|
||||
text = "SONAR\nMODULE EN ATTENTE"
|
||||
modulate = Color(0.34, 0.6, 0.6, 1)
|
||||
|
||||
[node name="EmergencyDial" type="MeshInstance3D" parent="."]
|
||||
position = Vector3(-0.6, 0.39, -1.15)
|
||||
scale = Vector3(0.38, 0.38, 0.38)
|
||||
rotation_degrees = Vector3(90, 0, 0)
|
||||
mesh = SubResource("DialMesh")
|
||||
material_override = SubResource("RedMaterial")
|
||||
|
||||
[node name="EmergencyLabel" type="Label3D" parent="."]
|
||||
position = Vector3(-0.6, 0.3, -1.125)
|
||||
pixel_size = 0.0009
|
||||
font_size = 15
|
||||
outline_size = 2
|
||||
text = "ÉJECTION · X"
|
||||
modulate = Color(1, 0.48, 0.38, 1)
|
||||
|
||||
[node name="CyanIndicator" type="MeshInstance3D" parent="."]
|
||||
position = Vector3(-0.15, 0.305, -1.11)
|
||||
scale = Vector3(0.25, 0.25, 0.25)
|
||||
mesh = SubResource("KnobMesh")
|
||||
material_override = SubResource("CyanMaterial")
|
||||
|
||||
[node name="AmberIndicator" type="MeshInstance3D" parent="."]
|
||||
position = Vector3(0, 0.305, -1.11)
|
||||
scale = Vector3(0.25, 0.25, 0.25)
|
||||
mesh = SubResource("KnobMesh")
|
||||
material_override = SubResource("AmberMaterial")
|
||||
|
||||
[node name="RedIndicator" type="MeshInstance3D" parent="."]
|
||||
position = Vector3(0.15, 0.305, -1.11)
|
||||
scale = Vector3(0.25, 0.25, 0.25)
|
||||
mesh = SubResource("KnobMesh")
|
||||
material_override = SubResource("RedMaterial")
|
||||
|
||||
[node name="CabinLight" type="OmniLight3D" parent="."]
|
||||
position = Vector3(0, 0.92, -0.28)
|
||||
light_color = Color(0.42, 0.75, 0.74, 1)
|
||||
light_energy = 2.2
|
||||
shadow_enabled = true
|
||||
omni_range = 3.3
|
||||
|
||||
[node name="PanelLight" type="OmniLight3D" parent="."]
|
||||
position = Vector3(0, 0.18, -0.63)
|
||||
light_color = Color(0.23, 0.72, 0.76, 1)
|
||||
light_energy = 0.8
|
||||
shadow_enabled = false
|
||||
omni_range = 1.35
|
||||
@@ -0,0 +1,26 @@
|
||||
class_name ConfirmationDialogScreen
|
||||
extends Control
|
||||
|
||||
signal cancelled
|
||||
signal confirmed(action_id: StringName)
|
||||
|
||||
var _action_id: StringName
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
%CancelButton.pressed.connect(func() -> void: cancelled.emit())
|
||||
%ConfirmButton.pressed.connect(func() -> void: confirmed.emit(_action_id))
|
||||
%CancelButton.grab_focus()
|
||||
|
||||
|
||||
func configure(
|
||||
action_id: StringName,
|
||||
title: String,
|
||||
message: String,
|
||||
confirm_label: String
|
||||
) -> void:
|
||||
_action_id = action_id
|
||||
%Title.text = title
|
||||
%Message.text = message
|
||||
%ConfirmButton.text = confirm_label
|
||||
@@ -0,0 +1,74 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://game/presentation/confirmation/confirmation_dialog.gd" id="1_confirm"]
|
||||
|
||||
[node name="ConfirmationDialog" type="Control"]
|
||||
process_mode = 3
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_confirm")
|
||||
|
||||
[node name="Dim" type="ColorRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0, 0, 0, 0.72)
|
||||
|
||||
[node name="Center" type="CenterContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Panel" type="PanelContainer" parent="Center"]
|
||||
custom_minimum_size = Vector2(650, 280)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="Center/Panel"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 34
|
||||
theme_override_constants/margin_top = 28
|
||||
theme_override_constants/margin_right = 34
|
||||
theme_override_constants/margin_bottom = 28
|
||||
|
||||
[node name="Layout" type="VBoxContainer" parent="Center/Panel/Margin"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 18
|
||||
|
||||
[node name="Title" type="Label" parent="Center/Panel/Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 28
|
||||
text = "CONFIRMER"
|
||||
|
||||
[node name="Message" type="Label" parent="Center/Panel/Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
text = "Cette action doit être confirmée."
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="Actions" type="HBoxContainer" parent="Center/Panel/Margin/Layout"]
|
||||
layout_mode = 2
|
||||
alignment = 2
|
||||
|
||||
[node name="CancelButton" type="Button" parent="Center/Panel/Margin/Layout/Actions"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(190, 46)
|
||||
layout_mode = 2
|
||||
text = "RESTER EN PLONGÉE"
|
||||
|
||||
[node name="ConfirmButton" type="Button" parent="Center/Panel/Margin/Layout/Actions"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(210, 46)
|
||||
layout_mode = 2
|
||||
text = "CONFIRMER"
|
||||
@@ -0,0 +1,141 @@
|
||||
class_name DiagnosticDiveScreen
|
||||
extends Control
|
||||
|
||||
signal menu_requested
|
||||
|
||||
const DiveUpdate = preload("res://game/domain/dive/dive_update.gd")
|
||||
const DiveAlertLevel = preload("res://game/domain/dive/dive_alert_level.gd")
|
||||
const DiveTerminalReason = preload("res://game/domain/dive/dive_terminal_reason.gd")
|
||||
const ReturnEstimate = preload("res://game/domain/dive/return_estimate.gd")
|
||||
|
||||
@onready var _status_label: Label = %StatusLabel
|
||||
@onready var _tick_label: Label = %TickLabel
|
||||
@onready var _battery_label: Label = %BatteryLabel
|
||||
@onready var _oxygen_label: Label = %OxygenLabel
|
||||
@onready var _hull_label: Label = %HullLabel
|
||||
@onready var _depth_label: Label = %DepthLabel
|
||||
@onready var _return_label: Label = %ReturnLabel
|
||||
@onready var _alert_label: Label = %AlertLabel
|
||||
@onready var _event_label: Label = %EventLabel
|
||||
@onready var _menu_button: Button = %MenuButton
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_menu_button.pressed.connect(_on_menu_pressed)
|
||||
|
||||
|
||||
func present(update: DiveUpdate) -> void:
|
||||
if update == null or update.snapshot == null:
|
||||
present_setup_error("Mise à jour de plongée absente")
|
||||
return
|
||||
if not update.accepted:
|
||||
_status_label.text = "ÉTAT · PAS REFUSÉ · %s" % update.rejection_reason
|
||||
else:
|
||||
_status_label.text = "ÉTAT · SIMULATION DÉTERMINISTE · 60 HZ"
|
||||
|
||||
var snapshot = update.snapshot
|
||||
_tick_label.text = "SESSION %s · TICK %d" % [snapshot.session_id, snapshot.tick_sequence]
|
||||
_battery_label.text = (
|
||||
"BATTERIE %.2f / %.2f kWh · %.0f %% · %.1f kW"
|
||||
% [
|
||||
snapshot.battery.remaining_kwh,
|
||||
snapshot.battery.maximum_kwh,
|
||||
snapshot.battery.ratio * 100.0,
|
||||
snapshot.battery.current_power_kw,
|
||||
]
|
||||
)
|
||||
_oxygen_label.text = (
|
||||
"OXYGÈNE %.1f / %.1f L · %.0f %% · %.1f L/min · %.1f min"
|
||||
% [
|
||||
snapshot.oxygen.remaining_l,
|
||||
snapshot.oxygen.maximum_l,
|
||||
snapshot.oxygen.ratio * 100.0,
|
||||
snapshot.oxygen.consumption_l_per_min,
|
||||
snapshot.oxygen.endurance_minutes,
|
||||
]
|
||||
)
|
||||
_hull_label.text = (
|
||||
"COQUE %.1f / %.1f · %.0f %% · %.2f / %.2f bar recommandés"
|
||||
% [
|
||||
snapshot.hull.current_integrity,
|
||||
snapshot.hull.maximum_integrity,
|
||||
snapshot.hull.ratio * 100.0,
|
||||
snapshot.hull.exterior_pressure_bar,
|
||||
snapshot.hull.certified_pressure_bar,
|
||||
]
|
||||
)
|
||||
_depth_label.text = (
|
||||
"PROFONDEUR %.1f m · CERTIFIÉE %.1f m · CRITIQUE %.1f m"
|
||||
% [
|
||||
snapshot.depth.current_m,
|
||||
snapshot.depth.certified_m,
|
||||
snapshot.depth.critical_m,
|
||||
]
|
||||
)
|
||||
_return_label.text = _format_return_estimate(snapshot.return_estimate)
|
||||
_alert_label.text = "ALERTE MAXIMALE · %s" % _alert_level_text(snapshot.alerts.maximum)
|
||||
_event_label.text = (
|
||||
"TERMINAISON · %s · ÉVÉNEMENTS DU PAS · %d"
|
||||
% [_terminal_reason_text(snapshot.terminal_reason), update.events.size()]
|
||||
)
|
||||
|
||||
|
||||
func present_setup_error(message: String) -> void:
|
||||
_status_label.text = "ÉTAT · INITIALISATION IMPOSSIBLE"
|
||||
_tick_label.text = message
|
||||
|
||||
|
||||
func _on_menu_pressed() -> void:
|
||||
menu_requested.emit()
|
||||
|
||||
|
||||
func _format_return_estimate(estimate: ReturnEstimate) -> String:
|
||||
match estimate.status:
|
||||
ReturnEstimate.Status.UNKNOWN:
|
||||
return "RETOUR · ESTIMATION INCONNUE"
|
||||
ReturnEstimate.Status.SAFE:
|
||||
return "RETOUR %.2f kWh requis · MARGE %.2f kWh · SÛR" % [
|
||||
estimate.required_kwh,
|
||||
estimate.margin_kwh,
|
||||
]
|
||||
ReturnEstimate.Status.TIGHT:
|
||||
return "RETOUR %.2f kWh requis · MARGE %.2f kWh · SERRÉ" % [
|
||||
estimate.required_kwh,
|
||||
estimate.margin_kwh,
|
||||
]
|
||||
ReturnEstimate.Status.INSUFFICIENT:
|
||||
return "RETOUR %.2f kWh requis · MANQUE %.2f kWh" % [
|
||||
estimate.required_kwh,
|
||||
absf(estimate.margin_kwh),
|
||||
]
|
||||
return "RETOUR · ÉTAT INCONNU"
|
||||
|
||||
|
||||
func _alert_level_text(level: DiveAlertLevel.Value) -> String:
|
||||
match level:
|
||||
DiveAlertLevel.Value.NORMAL:
|
||||
return tr("NORMAL")
|
||||
DiveAlertLevel.Value.ATTENTION:
|
||||
return tr("ATTENTION")
|
||||
DiveAlertLevel.Value.RETURN:
|
||||
return tr("RETOUR")
|
||||
DiveAlertLevel.Value.CRITICAL:
|
||||
return tr("CRITIQUE")
|
||||
DiveAlertLevel.Value.FAILURE:
|
||||
return tr("DÉFAILLANCE")
|
||||
return tr("INCONNU")
|
||||
|
||||
|
||||
func _terminal_reason_text(reason: DiveTerminalReason.Value) -> String:
|
||||
match reason:
|
||||
DiveTerminalReason.Value.NONE:
|
||||
return tr("EN COURS")
|
||||
DiveTerminalReason.Value.RETURNED:
|
||||
return tr("RETOUR")
|
||||
DiveTerminalReason.Value.VOLUNTARY_EJECTION:
|
||||
return tr("ÉJECTION VOLONTAIRE")
|
||||
DiveTerminalReason.Value.OXYGEN_DEPLETED:
|
||||
return tr("OXYGÈNE ÉPUISÉ")
|
||||
DiveTerminalReason.Value.HULL_DESTROYED:
|
||||
return tr("COQUE DÉTRUITE")
|
||||
return tr("INCONNU")
|
||||
@@ -0,0 +1,119 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://game/presentation/diagnostic/diagnostic_dive_screen.gd" id="1_screen"]
|
||||
|
||||
[node name="DiagnosticDiveScreen" type="Control"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_screen")
|
||||
|
||||
[node name="Background" type="ColorRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0.0118, 0.0549, 0.0745, 1)
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 72.0
|
||||
offset_top = 56.0
|
||||
offset_right = -72.0
|
||||
offset_bottom = -56.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Rows" type="VBoxContainer" parent="Margin"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 18
|
||||
|
||||
[node name="Title" type="Label" parent="Margin/Rows"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.4549, 0.8902, 0.898, 1)
|
||||
theme_override_font_sizes/font_size = 30
|
||||
text = "RANSOM'S WAKE · DIAGNOSTIC DE PLONGÉE"
|
||||
|
||||
[node name="StatusLabel" type="Label" parent="Margin/Rows"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.7647, 0.8157, 0.8275, 1)
|
||||
theme_override_font_sizes/font_size = 16
|
||||
text = "ÉTAT · INITIALISATION"
|
||||
|
||||
[node name="Separator" type="HSeparator" parent="Margin/Rows"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TickLabel" type="Label" parent="Margin/Rows"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 18
|
||||
text = "SESSION — · TICK —"
|
||||
|
||||
[node name="BatteryLabel" type="Label" parent="Margin/Rows"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 22
|
||||
text = "BATTERIE —"
|
||||
|
||||
[node name="OxygenLabel" type="Label" parent="Margin/Rows"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 22
|
||||
text = "OXYGÈNE —"
|
||||
|
||||
[node name="HullLabel" type="Label" parent="Margin/Rows"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 22
|
||||
text = "COQUE —"
|
||||
|
||||
[node name="DepthLabel" type="Label" parent="Margin/Rows"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 22
|
||||
text = "PROFONDEUR —"
|
||||
|
||||
[node name="ReturnLabel" type="Label" parent="Margin/Rows"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.9098, 0.7686, 0.4039, 1)
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "RETOUR —"
|
||||
|
||||
[node name="AlertLabel" type="Label" parent="Margin/Rows"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "ALERTE MAXIMALE —"
|
||||
|
||||
[node name="EventLabel" type="Label" parent="Margin/Rows"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.7647, 0.8157, 0.8275, 1)
|
||||
theme_override_font_sizes/font_size = 16
|
||||
text = "TERMINAISON — · ÉVÉNEMENTS —"
|
||||
|
||||
[node name="MenuButton" type="Button" parent="Margin/Rows"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(260, 44)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
text = "RETOUR AU MENU"
|
||||
|
||||
[node name="Note" type="Label" parent="Margin/Rows"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 10
|
||||
theme_override_colors/font_color = Color(0.4824, 0.5804, 0.6078, 1)
|
||||
text = "Écran technique temporaire · aucune règle de gameplay n'est calculée ici."
|
||||
vertical_alignment = 2
|
||||
@@ -0,0 +1,24 @@
|
||||
class_name MainMenuScreen
|
||||
extends Control
|
||||
|
||||
signal new_game_requested
|
||||
signal quit_requested
|
||||
|
||||
@onready var _continue_button: Button = %ContinueButton
|
||||
@onready var _new_game_button: Button = %NewGameButton
|
||||
@onready var _quit_button: Button = %QuitButton
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_continue_button.disabled = true
|
||||
_continue_button.tooltip_text = "Aucune sauvegarde disponible"
|
||||
_new_game_button.pressed.connect(_on_new_game_pressed)
|
||||
_quit_button.pressed.connect(_on_quit_pressed)
|
||||
|
||||
|
||||
func _on_new_game_pressed() -> void:
|
||||
new_game_requested.emit()
|
||||
|
||||
|
||||
func _on_quit_pressed() -> void:
|
||||
quit_requested.emit()
|
||||
@@ -0,0 +1,85 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://game/presentation/main_menu/main_menu_screen.gd" id="1_menu"]
|
||||
|
||||
[node name="MainMenuScreen" type="Control"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_menu")
|
||||
|
||||
[node name="Background" type="ColorRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0.0078, 0.0353, 0.051, 1)
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="Center" type="CenterContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Menu" type="VBoxContainer" parent="Center"]
|
||||
custom_minimum_size = Vector2(460, 0)
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 14
|
||||
|
||||
[node name="Title" type="Label" parent="Center/Menu"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.4549, 0.8902, 0.898, 1)
|
||||
theme_override_font_sizes/font_size = 46
|
||||
text = "RANSOM'S WAKE"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="Subtitle" type="Label" parent="Center/Menu"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.6588, 0.7333, 0.749, 1)
|
||||
theme_override_font_sizes/font_size = 16
|
||||
text = "FONDATION DE LA VERTICALE"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="Spacer" type="Control" parent="Center/Menu"]
|
||||
custom_minimum_size = Vector2(0, 24)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ContinueButton" type="Button" parent="Center/Menu"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 52)
|
||||
layout_mode = 2
|
||||
text = "CONTINUER · AUCUNE SAUVEGARDE"
|
||||
|
||||
[node name="NewGameButton" type="Button" parent="Center/Menu"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 52)
|
||||
layout_mode = 2
|
||||
text = "NOUVELLE PARTIE"
|
||||
|
||||
[node name="SettingsButton" type="Button" parent="Center/Menu"]
|
||||
custom_minimum_size = Vector2(0, 52)
|
||||
layout_mode = 2
|
||||
disabled = true
|
||||
tooltip_text = "Écran de réglages prévu dans une tranche ultérieure"
|
||||
text = "RÉGLAGES · À VENIR"
|
||||
|
||||
[node name="QuitButton" type="Button" parent="Center/Menu"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 52)
|
||||
layout_mode = 2
|
||||
text = "QUITTER"
|
||||
|
||||
[node name="TechnicalNote" type="Label" parent="Center/Menu"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.3882, 0.4824, 0.5059, 1)
|
||||
text = "Build technique · Forward+ · simulation 60 Hz"
|
||||
horizontal_alignment = 1
|
||||
@@ -0,0 +1,18 @@
|
||||
class_name PauseMenu
|
||||
extends Control
|
||||
|
||||
signal resume_requested
|
||||
signal controls_requested
|
||||
signal abandon_requested
|
||||
signal main_menu_requested
|
||||
signal quit_requested
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
%ResumeButton.pressed.connect(func() -> void: resume_requested.emit())
|
||||
%ControlsButton.pressed.connect(func() -> void: controls_requested.emit())
|
||||
%AbandonButton.pressed.connect(func() -> void: abandon_requested.emit())
|
||||
%MainMenuButton.pressed.connect(func() -> void: main_menu_requested.emit())
|
||||
%QuitButton.pressed.connect(func() -> void: quit_requested.emit())
|
||||
%ResumeButton.grab_focus()
|
||||
@@ -0,0 +1,82 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://game/presentation/pause/pause_menu.gd" id="1_pause"]
|
||||
|
||||
[node name="PauseMenu" type="Control"]
|
||||
process_mode = 3
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_pause")
|
||||
|
||||
[node name="Dim" type="ColorRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0.01, 0.025, 0.04, 0.88)
|
||||
|
||||
[node name="Center" type="CenterContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Menu" type="VBoxContainer" parent="Center"]
|
||||
custom_minimum_size = Vector2(430, 0)
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="Title" type="Label" parent="Center/Menu"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.45, 0.89, 0.9, 1)
|
||||
theme_override_font_sizes/font_size = 34
|
||||
text = "PLONGÉE EN PAUSE"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="State" type="Label" parent="Center/Menu"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.65, 0.73, 0.75, 1)
|
||||
text = "SIMULATION ET CONSOMMATIONS SUSPENDUES"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="Spacer" type="Control" parent="Center/Menu"]
|
||||
custom_minimum_size = Vector2(0, 18)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ResumeButton" type="Button" parent="Center/Menu"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 48)
|
||||
layout_mode = 2
|
||||
text = "REPRENDRE"
|
||||
|
||||
[node name="ControlsButton" type="Button" parent="Center/Menu"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 48)
|
||||
layout_mode = 2
|
||||
text = "RÉGLAGES · COMMANDES"
|
||||
|
||||
[node name="AbandonButton" type="Button" parent="Center/Menu"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 48)
|
||||
layout_mode = 2
|
||||
text = "ABANDONNER LA PLONGÉE"
|
||||
|
||||
[node name="MainMenuButton" type="Button" parent="Center/Menu"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 48)
|
||||
layout_mode = 2
|
||||
text = "RETOUR AU MENU PRINCIPAL"
|
||||
|
||||
[node name="QuitButton" type="Button" parent="Center/Menu"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 48)
|
||||
layout_mode = 2
|
||||
text = "QUITTER LE JEU"
|
||||
@@ -0,0 +1,67 @@
|
||||
class_name ControlsSettingsScreen
|
||||
extends Control
|
||||
|
||||
signal rebind_requested(action_id: StringName)
|
||||
signal restore_defaults_requested
|
||||
signal conflict_resolution_requested(swap_bindings: bool)
|
||||
signal back_requested
|
||||
|
||||
const InputBindingSnapshot = preload(
|
||||
"res://game/application/input/input_binding_snapshot.gd"
|
||||
)
|
||||
const RebindResult = preload("res://game/application/input/rebind_result.gd")
|
||||
|
||||
@onready var _rows: VBoxContainer = %Rows
|
||||
@onready var _status_label: Label = %StatusLabel
|
||||
@onready var _conflict_panel: PanelContainer = %ConflictPanel
|
||||
@onready var _conflict_label: Label = %ConflictLabel
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
%RestoreButton.pressed.connect(func() -> void: restore_defaults_requested.emit())
|
||||
%BackButton.pressed.connect(func() -> void: back_requested.emit())
|
||||
%SwapButton.pressed.connect(func() -> void: conflict_resolution_requested.emit(true))
|
||||
%CancelConflictButton.pressed.connect(
|
||||
func() -> void: conflict_resolution_requested.emit(false)
|
||||
)
|
||||
_conflict_panel.visible = false
|
||||
|
||||
|
||||
func present_bindings(bindings: Array[InputBindingSnapshot]) -> void:
|
||||
for child: Node in _rows.get_children():
|
||||
child.queue_free()
|
||||
for binding: InputBindingSnapshot in bindings:
|
||||
var row := HBoxContainer.new()
|
||||
row.custom_minimum_size.y = 42.0
|
||||
var label := Label.new()
|
||||
label.text = binding.label
|
||||
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
var button := Button.new()
|
||||
button.custom_minimum_size.x = 180.0
|
||||
button.text = binding.binding_text
|
||||
button.pressed.connect(_on_binding_button_pressed.bind(binding.action_id))
|
||||
row.add_child(label)
|
||||
row.add_child(button)
|
||||
_rows.add_child(row)
|
||||
|
||||
|
||||
func _on_binding_button_pressed(action_id: StringName) -> void:
|
||||
rebind_requested.emit(action_id)
|
||||
|
||||
|
||||
func present_rebind_result(result: RebindResult) -> void:
|
||||
_status_label.text = result.message
|
||||
if result.conflicting_action_id.is_empty():
|
||||
_conflict_panel.visible = false
|
||||
return
|
||||
_conflict_label.text = (
|
||||
"La touche %s est déjà utilisée. Permuter les deux commandes ?"
|
||||
% result.binding_text
|
||||
)
|
||||
_conflict_panel.visible = true
|
||||
|
||||
|
||||
func show_waiting_for_key() -> void:
|
||||
_status_label.text = "Appuyez sur une touche · Échap pour annuler"
|
||||
_conflict_panel.visible = false
|
||||
@@ -0,0 +1,108 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://game/presentation/settings/controls_settings_screen.gd" id="1_controls"]
|
||||
|
||||
[node name="ControlsSettingsScreen" type="Control"]
|
||||
process_mode = 3
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_controls")
|
||||
|
||||
[node name="Dim" type="ColorRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0.01, 0.025, 0.04, 0.96)
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 190.0
|
||||
offset_top = 42.0
|
||||
offset_right = -190.0
|
||||
offset_bottom = -42.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Layout" type="VBoxContainer" parent="Margin"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="Title" type="Label" parent="Margin/Layout"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.45, 0.89, 0.9, 1)
|
||||
theme_override_font_sizes/font_size = 32
|
||||
text = "RÉGLAGES · COMMANDES"
|
||||
|
||||
[node name="Description" type="Label" parent="Margin/Layout"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.65, 0.73, 0.75, 1)
|
||||
text = "Le clavier oriente le sous-marin. La souris déplace uniquement le regard."
|
||||
|
||||
[node name="Rows" type="VBoxContainer" parent="Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 5
|
||||
|
||||
[node name="StatusLabel" type="Label" parent="Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 30)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.91, 0.77, 0.4, 1)
|
||||
text = "Sélectionnez une commande à remapper."
|
||||
|
||||
[node name="ConflictPanel" type="PanelContainer" parent="Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ConflictLayout" type="VBoxContainer" parent="Margin/Layout/ConflictPanel"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ConflictLabel" type="Label" parent="Margin/Layout/ConflictPanel/ConflictLayout"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Cette touche est déjà utilisée."
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="Actions" type="HBoxContainer" parent="Margin/Layout/ConflictPanel/ConflictLayout"]
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="CancelConflictButton" type="Button" parent="Margin/Layout/ConflictPanel/ConflictLayout/Actions"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(150, 42)
|
||||
layout_mode = 2
|
||||
text = "ANNULER"
|
||||
|
||||
[node name="SwapButton" type="Button" parent="Margin/Layout/ConflictPanel/ConflictLayout/Actions"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(150, 42)
|
||||
layout_mode = 2
|
||||
text = "PERMUTER"
|
||||
|
||||
[node name="Footer" type="HBoxContainer" parent="Margin/Layout"]
|
||||
layout_mode = 2
|
||||
alignment = 2
|
||||
|
||||
[node name="RestoreButton" type="Button" parent="Margin/Layout/Footer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(220, 44)
|
||||
layout_mode = 2
|
||||
text = "VALEURS PAR DÉFAUT"
|
||||
|
||||
[node name="BackButton" type="Button" parent="Margin/Layout/Footer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(160, 44)
|
||||
layout_mode = 2
|
||||
text = "RETOUR"
|
||||
Reference in new issue
Block a user