extends Control @export_group("Database") @export var database: ProjectDatabase @export_group("Editor Defaults") @export var default_cabinet_id: StringName = &"cabinet_01" @export var default_scenario_id: StringName = &"proof_of_concept" @onready var game_host: GameHost = $GameHost @onready var status_label: Label = ( $DebugUI/VBoxContainer/StatusLabel ) var active_scenario: ScenarioDefinition var active_assignment: ScenarioAssignment var launch_config: LaunchConfig func _ready() -> void: if database == null: push_error( "Main has no ProjectDatabase assigned." ) return launch_config = LaunchConfig.from_command_line( default_cabinet_id, default_scenario_id ) launch_config.print_debug() if not _resolve_scenario(): return if not _resolve_assignment(): return if not _validate_assignment(): return _start_assignment() func _resolve_scenario() -> bool: active_scenario = database.get_scenario( launch_config.scenario_id ) if active_scenario == null: push_error( "Scenario '%s' was not found in ProjectDatabase." % launch_config.scenario_id ) return false print( "[LAUNCHER] Scenario resolved: %s v%d" % [ active_scenario.display_name, active_scenario.version ] ) return true func _resolve_assignment() -> bool: active_assignment = ( active_scenario.get_assignment_for_cabinet( launch_config.cabinet_id ) ) if active_assignment == null: push_error( "Scenario '%s' has no assignment for cabinet '%s'." % [ active_scenario.scenario_id, launch_config.cabinet_id ] ) return false print( "[LAUNCHER] Assignment: %s -> %s" % [ active_assignment.cabinet.display_name, active_assignment.game.display_name ] ) return true func _validate_assignment() -> bool: if active_assignment.cabinet == null: push_error( "Scenario assignment has no CabinetProfile." ) return false if active_assignment.game == null: push_error( "Scenario assignment has no GameDefinition." ) return false if ( active_assignment.cabinet.cabinet_id != launch_config.cabinet_id ): push_error( "Assignment cabinet ID does not match " + "requested cabinet." ) return false if not active_assignment.game.can_run_on( active_assignment.cabinet ): push_error( "Game '%s' is incompatible with cabinet '%s'." % [ active_assignment.game.game_id, active_assignment.cabinet.cabinet_id ] ) return false print("[LAUNCHER] Assignment validated.") return true func _start_assignment() -> void: RoomRuntime.configure( active_assignment ) var game := game_host.load_game( active_assignment.game ) if game == null: return game.game_started.connect( _update_status_started ) game.game_won.connect( _update_status_won ) game.game_lost.connect( _update_status_lost ) game.game_reset.connect( _update_status_reset ) status_label.text = ( "%s\n%s\n%s" % [ active_scenario.display_name, active_assignment.cabinet.display_name, active_assignment.game.display_name ] ) print("") print("=========== READY ===========") print( "Scenario: ", active_scenario.display_name ) print( "Cabinet: ", active_assignment.cabinet.display_name ) print( "Game: ", active_assignment.game.display_name ) print("=============================") print("") func _on_start_button_pressed() -> void: if game_host.current_game: game_host.current_game.start_game() func _on_force_win_button_pressed() -> void: if game_host.current_game: game_host.current_game.win_game() func _on_force_lose_button_pressed() -> void: if game_host.current_game: game_host.current_game.lose_game() func _on_reset_button_pressed() -> void: if game_host.current_game: game_host.current_game.reset_game() func _update_status_started() -> void: status_label.text = "GAME RUNNING" func _update_status_won() -> void: status_label.text = "GAME WON" func _update_status_lost() -> void: status_label.text = "GAME LOST" func _update_status_reset() -> void: status_label.text = "READY"