extends Node3D ## A Room is a location that can be played through, and it emits a proceed signal that holds ## the scene path to the next room (or null for credits roll) class_name Room @onready var ui: Control = %UI ## Tells the main loop to proceed to the next scene signal proceed(next_scene_path: String) @export var id: State.rooms = State.rooms.NULL @onready var player: PlayerController = %PlayerController @onready var scene_player : AnimationPlayer = %SceneAnimationPlayer ## get-only property with the current authoritative savegame. var save_game : SaveGame: get: return State.save_game func _ready() -> void: assert(id != State.rooms.NULL, "Room " + str(self) + name + " has no proper ID set, it's still State.Rooms.NULL") prints("room.gd", "_ready()", self) State.room = self if not save_game: var debug_save_path := "res://dev-util/debug_save.tres" push_warning("Room initialised without a SaveGame. Making a copy of ", debug_save_path) State.save_game = ResourceLoader.load(debug_save_path).duplicate(true) if not Main.normal_boot: _debug_mode() func get_ready(): prints("----------", "GET_READY", self.name, "--------------") pull_save_state(save_game) save_game.seen.append(name) func play() -> String: for i in range(20): await get_tree().process_frame await get_ready() await start_room() var next_room : StringName = await proceed prints("----------", "PROCEEDING", next_room, "--------------") return next_room func start_room(): prints("----------", "START_ROOM", self.name, "--------------") await get_tree().process_frame # so this registers as a coroutine in IDE func pull_save_state(save: SaveGame) -> void: # Override this function to load the state of the chapter from State.save_game restore_player_from_save(save) ## Attempts to find player controller and restore position/rotation from save func restore_player_from_save(save: SaveGame) -> void: # only restore the player if we've already been in this room if name in save.seen: player.restore_from_save(save) func save_room(): prints("room.gd", "save_room", self) save_game.save_to_file(get_tree().root.get_texture()) func unload(): # Override this function to clean up things not owned by this room pass ## Called before a scene starts to allow room-specific preparation (e.g., animations) ## Override in subclasses to add custom scene preparation logic func prepare_scene_start(_scene_id: Scenes.id, _is_repeating: bool) -> void: prints("PREPARE SCENE", _scene_id, _is_repeating) await get_tree().process_frame # Dummy wait for LSP warning otherwise ## Override this (and call super._debug_mode()) if you want to initialize some data ## for running this Room standalone ("play current scene") func _debug_mode() -> void: push_warning("room.gd: DEBUG MODE - ", self) await get_tree().create_timer(1).timeout play()