refactor: interactables also spawn more controlled, and there's a delayed inversion of control to ensure cardboard is ready.
This commit is contained in:
parent
7653be9555
commit
294a5c2a7d
|
|
@ -1,37 +1,21 @@
|
|||
extends RoomWithBoard
|
||||
class_name VolunteerRoom
|
||||
|
||||
@onready var card_picker: CardPicker = %Picker
|
||||
@onready var player: PlayerController = %PlayerController
|
||||
|
||||
func _ready() -> void:
|
||||
func _ready() -> void:
|
||||
super._ready() # UwU, superclass _ready is not called by Godot automatically...
|
||||
prints("volunteer_room.gd", "_ready()", self)
|
||||
|
||||
func get_ready() -> void:
|
||||
await super.get_ready()
|
||||
|
||||
# Interactions can this way load their correct prompts
|
||||
get_tree().call_group("interactables", "pull_save_state")
|
||||
%TherapyVoluntaryInteractable.visible = not save_game.subway_burnout
|
||||
%TherapyUniInteractable.visible = save_game.subway_burnout
|
||||
|
||||
pull_save_state(State.save_game)
|
||||
|
||||
Scenes.scene_finished.connect(_on_scene_finished)
|
||||
card_picker.cards_picked.connect(card_board.populate_board)
|
||||
|
||||
card_board.closed.connect(save_room)
|
||||
card_board.board_completed.connect(func():
|
||||
save_game.childhood_board_complete = true
|
||||
#%DoorInteractable.show()
|
||||
)
|
||||
|
||||
# This MUST happen after the signal connection, or the door will remain locked
|
||||
card_board.initialise_from_save(save_game)
|
||||
|
||||
%TherapyVoluntaryInteractable.visible = not save_game.subway_burnout
|
||||
%TherapyUniInteractable.visible = save_game.subway_burnout
|
||||
|
||||
|
||||
|
||||
func start_room():
|
||||
await super.start_room()
|
||||
|
|
@ -43,18 +27,6 @@ func start_room():
|
|||
|
||||
await Main.curtain.open()
|
||||
|
||||
|
||||
func _on_scene_finished(_id: int, _repeat:bool):
|
||||
await get_tree().create_timer(3).timeout
|
||||
save_room()
|
||||
|
||||
func save_room():
|
||||
# Update board state before saving
|
||||
card_board.save_to_resource(save_game)
|
||||
save_game.mementos_complete = Scenes.completed_sequences
|
||||
save_game.sequences_enabled = Scenes.enabled_sequences
|
||||
super.save_room()
|
||||
|
||||
func prepare_transition():
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,7 @@
|
|||
class_name YouthRoom
|
||||
extends RoomWithBoard
|
||||
|
||||
## Used by the room system when this room becomes active
|
||||
# var is_active: bool = false # Reminder, do not uncomment, this field is inherited from RoomTemplate!
|
||||
|
||||
@onready var card_picker: CardPicker = %Picker
|
||||
@onready var ui: Control = %UI
|
||||
|
||||
func _ready() -> void:
|
||||
func _ready() -> void:
|
||||
super._ready() # UwU, superclass _ready is not called by Godot automatically...
|
||||
prints("youth_room.gd", "_ready()", self)
|
||||
|
||||
|
|
@ -41,49 +35,25 @@ func _play_intro_scene() -> void:
|
|||
|
||||
func get_ready() -> void:
|
||||
await super.get_ready()
|
||||
|
||||
pull_save_state(State.save_game)
|
||||
|
||||
card_board.closed.connect(save_room)
|
||||
card_board.board_completed.connect(func():
|
||||
save_game.childhood_board_complete = true
|
||||
%DoorInteractable.show()
|
||||
)
|
||||
|
||||
Scenes.scene_finished.connect(_on_scene_finished)
|
||||
card_picker.cards_picked.connect(card_board.populate_board)
|
||||
|
||||
# This MUST happen after the signal connection, or the door will remain locked
|
||||
card_board.initialise_from_save(save_game)
|
||||
prints("youth_room.gd", "get_ready()", self)
|
||||
|
||||
ui.hide()# Not sure?
|
||||
|
||||
card_board.board_completed.connect(func():
|
||||
save_game.childhood_board_complete = true
|
||||
#%DoorInteractable.show()
|
||||
)
|
||||
|
||||
|
||||
|
||||
func pull_save_state(save: SaveGame) -> void:
|
||||
save_game = save
|
||||
save_game.current_room = id
|
||||
super.pull_save_state(save)
|
||||
prints("youth_room.gd", "pull_save_state()", self)
|
||||
|
||||
# Interactions can this way load their correct prompts
|
||||
get_tree().call_group("interactables", "pull_save_state")
|
||||
|
||||
# TODO: These should be deprecated, SaveGame is our source of truth
|
||||
# TODO: These should be deprecated, SaveGame is our source of truth, and that contains what's complete etc.
|
||||
Scenes.started_sequences = save_game.mementos_complete
|
||||
Scenes.completed_sequences = save_game.mementos_complete
|
||||
|
||||
# Call parent to restore player position
|
||||
super.pull_save_state(save)
|
||||
|
||||
|
||||
func _on_scene_finished(_id: int, _repeat:bool):
|
||||
await get_tree().create_timer(3).timeout
|
||||
save_room()
|
||||
|
||||
func save_room():
|
||||
# Update board state before saving
|
||||
card_board.save_to_resource(save_game)
|
||||
save_game.mementos_complete = Scenes.completed_sequences
|
||||
super.save_room()
|
||||
|
||||
|
||||
## Override to handle scene-specific preparation (chest reveal animation)
|
||||
func prepare_scene_start(scene_id: Scenes.id, is_repeating: bool) -> void:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_resource type="Resource" script_class="SaveGame" format=3 uid="uid://pndvrrytubnr"]
|
||||
[gd_resource type="Resource" script_class="SaveGame" load_steps=2 format=3 uid="uid://pndvrrytubnr"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://d06gpwuxmkxkt" path="res://dev-util/savegame.gd" id="1_jr18u"]
|
||||
|
||||
|
|
@ -6,6 +6,6 @@
|
|||
script = ExtResource("1_jr18u")
|
||||
unique_save_name = "DEBUG"
|
||||
current_room = 3
|
||||
mementos_complete = 1669
|
||||
mementos_complete = 1665
|
||||
sequences_enabled = 255
|
||||
metadata/_custom_type_script = "uid://d06gpwuxmkxkt"
|
||||
|
|
|
|||
|
|
@ -3,34 +3,43 @@ extends Node3D
|
|||
## 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:
|
||||
prints("room.gd", "_ready()", self)
|
||||
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 State.save_game:
|
||||
if not save_game:
|
||||
var debug_save_path := "res://dev-util/debug_save.tres"
|
||||
push_warning("Room initialised without a SaveGame. Loading DEBUG save.", debug_save_path)
|
||||
State.save_game = ResourceLoader.load(debug_save_path)
|
||||
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, "--------------")
|
||||
for i in range(20): await get_tree().process_frame
|
||||
pull_save_state(save_game)
|
||||
save_game.seen.append(name)
|
||||
|
||||
|
||||
func play() -> String:
|
||||
for i in range(20):
|
||||
|
|
@ -47,26 +56,18 @@ func start_room():
|
|||
await get_tree().process_frame # so this registers as a coroutine in IDE
|
||||
|
||||
|
||||
func pull_save_state(_save: SaveGame) -> void:
|
||||
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)
|
||||
restore_player_from_save(save)
|
||||
|
||||
## Attempts to find player controller and restore position/rotation from save
|
||||
func restore_player_from_save(save: SaveGame) -> void:
|
||||
var player: PlayerController = null
|
||||
|
||||
# Try to find player controller in common locations
|
||||
if has_node("%PlayerController"):
|
||||
player = get_node("%PlayerController")
|
||||
elif has_node("logic/PlayerController"):
|
||||
player = get_node("logic/PlayerController")
|
||||
|
||||
if player and player is PlayerController:
|
||||
# only restore the player if we've already been in this room
|
||||
if name in save.seen:
|
||||
player.restore_from_save(save)
|
||||
else:
|
||||
print("RoomTemplate: Could not find PlayerController to restore position")
|
||||
|
||||
func save_room():
|
||||
prints("room.gd", "save_room", self)
|
||||
save_game.save_to_file(get_tree().root.get_texture())
|
||||
|
||||
func unload():
|
||||
|
|
|
|||
|
|
@ -2,9 +2,45 @@ extends Room
|
|||
## A room with a CardBoard in it, has some special properties and initialization rules!
|
||||
class_name RoomWithBoard
|
||||
|
||||
func _ready() -> void:
|
||||
prints("room_with_board.gd", "_ready()", self)
|
||||
super._ready() # UwU, superclass _ready is not called by Godot automatically...
|
||||
@onready var card_picker: CardPicker = %Picker
|
||||
var card_board : CardBoard # Initialized by CardBoard itself.
|
||||
|
||||
|
||||
var card_board : CardBoard # Optional Board, if present - set by the board in its own _ready()
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready() # UwU, superclass _ready is not called by Godot automatically...
|
||||
prints("room_with_board.gd", "_ready()", self, owner)
|
||||
|
||||
|
||||
|
||||
func get_ready():
|
||||
super.get_ready()
|
||||
prints("room_with_board.gd", "get_ready()", self)
|
||||
|
||||
assert(card_board, str(self) + " has no CardBoard")
|
||||
|
||||
# Interactions can this way load their correct prompts
|
||||
get_tree().call_group("interactables", "pull_save_state")
|
||||
|
||||
Scenes.scene_finished.connect(_on_scene_finished)
|
||||
|
||||
card_picker.cards_picked.connect(card_board.populate_board)
|
||||
|
||||
card_board.closed.connect(save_room)
|
||||
|
||||
# This MUST happen after the signal connection, or the door will remain locked
|
||||
card_board.initialise_from_save(save_game)
|
||||
|
||||
|
||||
func _on_scene_finished(_id: int, _repeat:bool):
|
||||
save_room.call_deferred() # Formerly there was a 3 second wait here.
|
||||
|
||||
|
||||
func save_room():
|
||||
prints("room_with_board.gd", "save_room", self)
|
||||
card_board.save_to_resource(save_game)
|
||||
|
||||
#TODO these should be deprecated
|
||||
save_game.mementos_complete = Scenes.completed_sequences
|
||||
save_game.sequences_enabled = Scenes.enabled_sequences
|
||||
|
||||
super.save_room()
|
||||
|
|
|
|||
|
|
@ -27,14 +27,22 @@ enum {NAVIGATE, ASSIGN, DRAG}
|
|||
|
||||
|
||||
func _ready() -> void:
|
||||
prints("card-board.gd:", "_ready()", self, "room:", State.room)
|
||||
prints("card-board.gd:", "_ready()", self, "room:", State.room, owner)
|
||||
super._ready()
|
||||
|
||||
_delayed_ready.call_deferred()
|
||||
|
||||
# We need to wait for our room further up our parent hierarchy to actually make itself known
|
||||
# for interactables to do things with it, e.g. CardBoard needs to register itself
|
||||
func _delayed_ready() ->void:
|
||||
var board_room := State.room as RoomWithBoard
|
||||
assert(board_room, "A CardBoard is placed in a Room that's not a RoomWithBoard")
|
||||
assert(board_room, "CardBoard spawned in room that's not a RoomWithboard.")
|
||||
board_room.card_board = self
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func play():
|
||||
check_board_completion()
|
||||
await closed
|
||||
|
|
|
|||
|
|
@ -31,19 +31,25 @@ var tween: Tween = null
|
|||
func _ready() -> void:
|
||||
assert(note and frame and canvas_layer, "Interactable must have views and frame attached")
|
||||
|
||||
# how did this ever work?
|
||||
await get_tree().process_frame
|
||||
|
||||
if interaction:
|
||||
playable = interaction.instantiate() as Control
|
||||
canvas_layer.add_child(playable)
|
||||
|
||||
view.scale = Vector3.ZERO
|
||||
frame.modulate.a = 0.0
|
||||
light.visible = false
|
||||
|
||||
Scenes.player_enable.connect(_player_active) # TODO: do I have to clean this up?
|
||||
|
||||
assert(interaction, "Interactable " + name + " doesn't have an interaction PackedScene set")
|
||||
playable = interaction.instantiate() as Control
|
||||
canvas_layer.add_child(playable)
|
||||
|
||||
_delayed_ready.call_deferred()
|
||||
|
||||
# We need to wait for our room further up our parent hierarchy to actually make itself known
|
||||
# for interactables to do things with it, e.g. CardBoard needs to register itself
|
||||
func _delayed_ready() ->void:
|
||||
playable.unique_name_in_owner = true
|
||||
|
||||
|
||||
|
||||
|
||||
## To be called by room
|
||||
func pull_save_state() -> void:
|
||||
|
|
|
|||
Loading…
Reference in New Issue