class_name CockpitDetailing extends Node3D const DiveUpdate = preload("res://game/domain/dive/dive_update.gd") const DiveAlertLevel = preload("res://game/domain/dive/dive_alert_level.gd") const VehicleTelemetry = preload("res://game/application/dive/vehicle_telemetry.gd") const CockpitAlertBox = preload("res://game/presentation/cockpit/cockpit_alert_box.gd") const CockpitAnalogGauges = preload("res://game/presentation/cockpit/cockpit_analog_gauges.gd") const CockpitDashboardDetailing = preload( "res://game/presentation/cockpit/cockpit_dashboard_detailing.gd" ) const CockpitMaterialPalette = preload("res://game/presentation/cockpit/cockpit_material_palette.gd") const CockpitMeshFactory = preload("res://game/presentation/cockpit/cockpit_mesh_factory.gd") const CockpitSideEquipment = preload( "res://game/presentation/cockpit/cockpit_side_equipment.gd" ) const CockpitSonarConsole = preload( "res://game/presentation/cockpit/cockpit_sonar_console.gd" ) const CockpitPracticalLighting = preload( "res://game/presentation/cockpit/cockpit_practical_lighting.gd" ) const CockpitSwitchPanel = preload( "res://game/presentation/cockpit/cockpit_switch_panel.gd" ) var _materials: CockpitMaterialPalette var _painted_steel: Material var _dark_steel: Material var _analog_gauges: CockpitAnalogGauges var _alert_box: CockpitAlertBox var _switch_panel: CockpitSwitchPanel var _gas_bottle: Node3D var _dashboard_detailing: CockpitDashboardDetailing var _side_equipment: CockpitSideEquipment var _sonar_console: CockpitSonarConsole var _practical_lighting: CockpitPracticalLighting func _ready() -> void: _create_materials() _apply_materials_to_existing_cockpit() _build_dashboard_instrumentation() _build_equipment_assemblies() func present(update: DiveUpdate, telemetry: VehicleTelemetry) -> void: if update == null or update.snapshot == null or telemetry == null: return var snapshot = update.snapshot var alert_level: DiveAlertLevel.Value = snapshot.alerts.maximum if _analog_gauges != null: _analog_gauges.present( snapshot.oxygen.ratio, snapshot.battery.ratio, snapshot.hull.ratio, clampf( snapshot.depth.current_m / maxf(snapshot.depth.certified_m, 0.001), 0.0, 1.0 ) ) if _alert_box != null: _alert_box.present(alert_level) _practical_lighting.present(alert_level) func battery_needle_degrees() -> float: return 0.0 if _analog_gauges == null else _analog_gauges.battery_needle_degrees() func textures_are_loaded() -> bool: return ( _materials != null and _materials.overhead_steel.albedo_texture != null and _analog_gauges != null and _analog_gauges.dial_texture_is_loaded() ) func dashboard_control_count() -> int: return 0 if _switch_panel == null else _switch_panel.control_count() func side_equipment_count() -> int: if _side_equipment == null: return 0 return _side_equipment.junction_box_count() + (0 if _gas_bottle == null else 1) func side_control_count() -> int: if _side_equipment == null: return 0 var bottle_valve_count := ( 0 if _gas_bottle == null else _gas_bottle.find_children("*ValveWheel", "Node3D", true, false).size() ) return _side_equipment.control_count() + bottle_valve_count func sonar_control_count() -> int: return 0 if _sonar_console == null else _sonar_console.control_count() func practical_light_count() -> int: return 0 if _practical_lighting == null else _practical_lighting.practical_light_count() func gauges_are_dashboard_mounted() -> bool: return _analog_gauges != null and _analog_gauges.get_parent() == get_parent().get_node("Dashboard") func _create_materials() -> void: _materials = CockpitMaterialPalette.new() _painted_steel = _materials.painted_steel _dark_steel = _materials.dark_steel func _apply_materials_to_existing_cockpit() -> void: _apply_material_to_paths( _painted_steel, [ "CabinShell/LeftWall", "CabinShell/RightWall", ] ) _apply_material_to_paths(_dark_steel, ["CabinShell/RearBulkhead"]) _apply_material_to_paths( _materials.overhead_steel, ["CabinShell/Ceiling"] ) func _apply_material_to_paths(material: Material, paths: Array[String]) -> void: var cockpit := get_parent() for path: String in paths: var mesh := cockpit.get_node_or_null(path) as MeshInstance3D if mesh != null: mesh.material_override = material func _build_dashboard_instrumentation() -> void: var dashboard := get_parent().get_node_or_null("Dashboard") as Node3D if dashboard == null: return _dashboard_detailing = CockpitDashboardDetailing.new() dashboard.add_child(_dashboard_detailing) _dashboard_detailing.hide_obsolete_elements(get_parent()) _analog_gauges = dashboard.get_node_or_null("AnalogGauges") as CockpitAnalogGauges func _build_equipment_assemblies() -> void: _side_equipment = CockpitSideEquipment.new(_materials) add_child(_side_equipment) var cockpit := get_parent() _sonar_console = cockpit.get_node_or_null("SonarMonitor") as CockpitSonarConsole _alert_box = cockpit.get_node_or_null("AlertBox") as CockpitAlertBox _switch_panel = cockpit.get_node_or_null("SwitchPanel") as CockpitSwitchPanel _gas_bottle = cockpit.get_node_or_null("GasBottle") as Node3D _practical_lighting = CockpitPracticalLighting.new(_materials) add_child(_practical_lighting) # The alert box hangs between the left lamp and the gas bottle: casting, it # puts the bottle in full shadow. CockpitMeshFactory.disable_shadow_casting(_alert_box)