Files
room_glitch/core/runtime/room_controller.gd
T

316 lines
4.5 KiB
GDScript

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
}
)