class_name RoomController extends Node signal scenario_loaded(scenario: ScenarioDefinition) signal validation_completed( result: ValidationResult ) signal cabinet_status_changed( cabinet_id: StringName, status: StringName ) signal room_status_changed( status: StringName ) var database: ProjectDatabase var active_scenario: ScenarioDefinition var cabinet_statuses: Dictionary = {} var room: RoomDefinition func configure( project_database: ProjectDatabase, room_definition: RoomDefinition = null ) -> void: database = project_database room = room_definition func load_scenario( scenario_id: StringName ) -> bool: if database == null: push_error( "RoomController has no ProjectDatabase." ) return false var scenario := database.get_scenario( scenario_id ) if scenario == null: push_error( "Scenario '%s' not found." % scenario_id ) return false active_scenario = scenario _initialize_cabinet_statuses() print("") print("======= ROOM CONTROLLER =======") print( "Loaded scenario: %s v%d" % [ scenario.display_name, scenario.version ] ) print("===============================") print("") scenario_loaded.emit( active_scenario ) room_status_changed.emit( &"LOADED" ) return true func validate_active_scenario() -> ValidationResult: var result := ValidationResult.new() result.merge( ScenarioValidator.validate( active_scenario ) ) if room != null: result.merge( RoomValidator.validate( room, database ) ) validation_completed.emit( result ) if result.is_valid(): room_status_changed.emit( &"VALID" ) else: room_status_changed.emit( &"INVALID" ) return result func prep_room() -> bool: if active_scenario == null: push_error( "Cannot prep room: no scenario loaded." ) return false var validation := validate_active_scenario() if not validation.is_valid(): print( "[ROOM CONTROLLER] Prep aborted: " + validation.get_summary() ) room_status_changed.emit( &"PREP_FAILED" ) return false room_status_changed.emit( &"PREPARING" ) print("") print("=========== PREP ROOM ===========") for assignment in active_scenario.assignments: _prep_assignment(assignment) print("=================================") print("") room_status_changed.emit( &"READY" ) return true func _prep_assignment( assignment: ScenarioAssignment ) -> void: var cabinet := assignment.cabinet var game := assignment.game _set_cabinet_status( cabinet.cabinet_id, &"PREPARING" ) print( "[ROOM CONTROLLER] Cabinet '%s'" % cabinet.cabinet_id ) print( " Game: %s" % game.game_id ) print( " Variant: %s" % assignment.variant ) print( " Hardware: %s" % cabinet.hardware_config.controller_id ) # # Networking will eventually happen here. # # send_to_cabinet( # cabinet.cabinet_id, # scenario, # assignment # ) # print( " [SIMULATION] Cabinet ready." ) _set_cabinet_status( cabinet.cabinet_id, &"READY" ) func _initialize_cabinet_statuses() -> void: cabinet_statuses.clear() if active_scenario == null: return for assignment in active_scenario.assignments: if assignment == null: continue if assignment.cabinet == null: continue _set_cabinet_status( assignment.cabinet.cabinet_id, &"NOT_PREPARED" ) func _set_cabinet_status( cabinet_id: StringName, status: StringName ) -> void: cabinet_statuses[cabinet_id] = status cabinet_status_changed.emit( cabinet_id, status ) func get_cabinet_status( cabinet_id: StringName ) -> StringName: return cabinet_statuses.get( cabinet_id, &"UNKNOWN" ) func simulate_game_event( cabinet_id: StringName, event_name: StringName ) -> void: if active_scenario == null: push_error( "Cannot simulate event: no active scenario." ) return var assignment := ( active_scenario .get_assignment_for_cabinet( cabinet_id ) ) if assignment == null: push_error( "No assignment exists for cabinet '%s'." % cabinet_id ) return print("") print( "[ROOM SIMULATION] %s -> %s" % [ cabinet_id, event_name ] ) var actions := ( assignment .get_actions_for_event( event_name ) ) if actions.is_empty(): print( "[ROOM SIMULATION] No actions mapped." ) return for action_id in actions: print( "[ROOM SIMULATION] %s -> %s" % [ event_name, action_id ] ) HardwareManager.trigger_for_cabinet( assignment.cabinet, action_id, { "game_event": event_name } )