chore: refactor stage system, clear dead code

This commit is contained in:
tiger tiger tiger 2026-01-05 16:28:45 +01:00
parent 8dfbf4ef23
commit dbde200416
19 changed files with 28 additions and 310 deletions

View File

@ -15,7 +15,7 @@ func _ready() -> void:
func start_room():
save_game = State.save_game
State.pass_stage_to(%PlayerController)
%PlayerController.has_stage = true
on_first_station()
var left_first_station: bool = false

View File

@ -19,7 +19,7 @@ func start_room():
save_room())
%PlayerController.process_mode = Node.PROCESS_MODE_INHERIT
ini_room.emit()
State.pass_stage_to(%PlayerController)
%PlayerController.has_stage = true
func _ready():
id = State.rooms.ADULTHOOD

View File

@ -44,7 +44,7 @@ func _ready():
break
func _on_mouse_entered():
if not State.focus_locked:
if not Scenes.is_playing:
input_ray_pickable = false
ui.is_collapsed = false
has_mouse = true

View File

@ -19,17 +19,17 @@ func start_room():
if not Scenes.is_sequence_repeating(Scenes.id.YOUTH_DRAEVEN):
# Play intro scene directly (not triggered by CollectableUi)
await _play_intro_scene()
State.pass_stage_to(%PlayerController)
else:
State.pass_stage_to(%PlayerController)
%LightAnimation.lights_on()
# Give player control after intro (or immediately if repeating)
%PlayerController.has_stage = true
func _play_intro_scene() -> void:
# The intro scene is auto-played, not triggered by CollectableUi
var intro_playable: StoryPlayable = $logic/ScenePlayer/draven
State.take_stage(self)
Scenes.begin_sequence(Scenes.id.YOUTH_DRAEVEN)
Input.mouse_mode = Input.MOUSE_MODE_HIDDEN
@ -39,7 +39,6 @@ func _play_intro_scene() -> void:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
State.leave_stage(self)
Scenes.end_sequence(Scenes.id.YOUTH_DRAEVEN)

View File

@ -19,7 +19,7 @@ func create_bug_report():
Current Focus: %s
Current Scene: %s
Mementos: %s
""" % [OS.get_name(), OS.get_video_adapter_driver_info(), State.stage_list, State.current_room, Scenes.completed_sequences]
""" % [OS.get_name(), OS.get_video_adapter_driver_info(), Scenes.current_sequence, State.current_room, Scenes.completed_sequences]
#debug_text = debug_text.replace(" ", "%20").replace("\n", "%0A").replace("\t", "")

View File

@ -22,7 +22,7 @@ func _input(event: InputEvent) -> void:
# viewport.push_input(event)
func _on_input_event(_camera: Camera3D, event: InputEvent, pos: Vector3, _normal: Vector3, _shape_idx: int):
if not State.focus_locked:
if not Scenes.is_playing:
# Position of the event in Sprite3D local coordinates.
var texture_3d_position := sprite.get_global_transform().affine_inverse() * pos
#if !is_zero_approx(texture_3d_position.z):

View File

@ -408,7 +408,7 @@ func _input(event) -> void:
if not has_stage or not is_instance_valid(currently_active_node): return
if event.is_action_pressed("ui_cancel"):
State.leave_stage(self)
has_stage = false
get_viewport().set_input_as_handled()
if event is InputEventMouse:
@ -568,7 +568,7 @@ func on_scene_skipped(i: int):
mementos_collected += i # FIXME: sometimes -1 is passed here, why?
func claim_focus():
State.pass_stage_to(self)
has_stage = true
func find_first_free_card() -> int:
for i in range(dropzone.get_child_count()):

View File

@ -59,30 +59,6 @@ signal cards_picked(cardnames: Array[String])
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
reset()
return
#
# #FIXME: can I make this less annoying somehow?
# if State.onready_room == State.rooms.YOUTH:
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_DRAEVEN, 2)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_CHILDHOOD, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_VOICE_TRAINING, 2)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_JUI_JUTSU, 1)
# elif State.onready_room == State.rooms.ADULTHOOD:
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_DND, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_VOLUNTARY, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_CHRISTMAS, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_EATING, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_UNI, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_THERAPY, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_BURNOUT, 1)
# else:
# assert(false, "Not Implemented")
#
# if get_tree().root == self.get_parent():
# pick_cards(3, false)
# State.take_stage(self)
#
# reset()
func reset():
card_anim_skipped = false
@ -276,7 +252,6 @@ func pick_cards(id: int, repeat: bool):
if not repeat:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
fill_card_slots(id)
#State.transition_stage_to(self, true)
selection_state = CARDS
if id == Scenes.id.YOUTH_DRAEVEN and not repeat:
$Meaning.play()

View File

@ -22,23 +22,6 @@ var canvas_layer: CanvasLayer
get_viewport().gui_release_focus()
is_collapsed = true
#@export var collapsed = true:
# set(collapse):
# if is_inside_tree() and not Engine.is_editor_hint():
# if State.reduce_motion:
# collapsed = false
# return
# if collapse and not collapsed:
# if is_inside_tree():
# _hide_buttons()
# collapsed = collapse
# elif not collapse and collapsed:
# if is_inside_tree():
# _show_buttons()
# collapsed = collapse
#
# if collapse and has_stage: State.leave_stage(self)
@export var scene: Scenes.id = Scenes.id.YOUTH_DRAEVEN:
set(id):
scene = id

View File

@ -116,7 +116,11 @@ func _process(_delta):
#emit_signal("ui_exited")
#dhas_entered = false
if Input.is_action_just_pressed("ui_accept"):
State.pass_stage_to(focus_ray.get_collider())
# Pass focus to the collider if it has has_stage property
var collider = focus_ray.get_collider()
if collider and "has_stage" in collider:
has_stage = false
collider.has_stage = true
else:
camera.fov = base_fov / (1 + Input.get_action_raw_strength("zoom_in_controller"))
@ -274,7 +278,7 @@ func play_scene(_id: int, _repeat: bool):
func scene_finished(_id, repeat: bool):
if repeat:
State.take_stage(self)
has_stage = true
func _on_bed_enter(_body):
if not (crouched or on_crouch_cooldown):

View File

@ -250,137 +250,9 @@ func _ready():
push_warning("Room initialised without a SaveGame. Creating proxy save.")
#TODO: make this a bit more clean maybe?
save_game = ResourceLoader.load("res://dev-util/debug_save.tres")
if "has_stage" in child:
take_stage(child)
break
music_volume = music_volume
#region focus handling (called staging to avoid name colisions)
# Stage list is a stack. Only the front (top) element "has" the stage.
# The stage manager sets has_stage on actors when they take/leave stage.
var stage_list: Array = []
var focus_locked: bool = false
# Helper to safely set has_stage on an actor
func _set_actor_stage(actor: Object, value: bool) -> void:
if is_instance_valid(actor) and "has_stage" in actor:
actor.has_stage = value
# Actor takes the stage (pushes to front of stack)
func take_stage(actor: Object) -> void:
print_debug(">>> take_stage(", actor, ")")
assert(not focus_locked, "Focus is locked, %s cannot take focus." % actor)
assert(is_instance_valid(actor), "Cannot take stage with invalid actor")
# Remove actor if already in list (to re-add at front)
if actor in stage_list:
stage_list.erase(actor)
# Remove stage from current front
if stage_list.size() > 0:
_set_actor_stage(stage_list.front(), false)
# Add new actor to front and give it stage
stage_list.push_front(actor)
_set_actor_stage(actor, true)
# Actor leaves the stage (removes from stack)
func leave_stage(actor: Object) -> void:
print_debug("<<< leave_stage(", actor, ")")
if not (actor in stage_list):
push_warning("Actor %s not in stage list, ignoring leave_stage call." % actor)
return
var was_front = false
if stage_list.size() > 0:
if stage_list.front() == actor:
was_front = true
# Remove stage from actor and remove from list
_set_actor_stage(actor, false)
stage_list.erase(actor)
# If actor was at front, give stage to new front
if was_front:
if stage_list.size() > 0:
_set_actor_stage(stage_list.front(), true)
# Pass stage to a new target (pushes target to front)
func pass_stage_to(target: Object, force: bool = false) -> void:
print_debug(">>> pass_stage_to(", target, ")")
if not is_instance_valid(target):
push_error("Cannot pass stage to invalid target")
return
if not "has_stage" in target:
push_error(target, " has no has_stage property")
return
if (focus_locked or get_tree().paused) and not force:
push_error(target, " requested focus while it was locked or tree is paused")
return
# If target is already at front, nothing to do
if stage_list.size() > 0 and stage_list.front() == target:
push_warning(target, " is already at front of stage. Ignoring.")
return
take_stage(target)
# Queue an actor for stage at a specific position (does not give it stage yet)
func queue_for_stage(target: Object, index: int = 1) -> void:
print_debug(">>> queue_for_stage(", target, ") at index ", index)
if target in stage_list:
stage_list.erase(target)
stage_list.insert(index, target)
# Currently focused element loses stage but remains in stack
func free_focus() -> void:
if focus_locked:
return
if stage_list.size() > 0:
_set_actor_stage(stage_list.front(), false)
# Reset stack to only contain the bottom element (original/root)
func reset_focus() -> void:
# Remove stage from current front
if stage_list.size() > 0:
_set_actor_stage(stage_list.front(), false)
# Keep only the last element
if stage_list.size() > 0:
var root = stage_list[-1]
stage_list = [root]
_set_actor_stage(root, true)
# Transfer stage from current front to a new actor (removes current front)
func transition_stage_to(target: Object, lock: bool = false) -> void:
print_debug(">>> transition_stage_to(", target, ")")
# Remove current front from stack entirely
if stage_list.size() > 0:
var old_front = stage_list.pop_front()
_set_actor_stage(old_front, false)
# Add new target
stage_list.push_front(target)
_set_actor_stage(target, true)
focus_locked = lock
#endregion
#region play state
enum rooms {

View File

@ -116,112 +116,4 @@ func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("ui_menu"):
app_state = AppState.PLAY
# if not get_tree().paused:
# get_tree().paused = true
# var state_machine := menu_animation["parameters/playback"]
# state_machine.travel("reveal_pause_menu")
# Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
# else:
# get_tree().paused = false
# var state_machine := menu_animation["parameters/playback"]
# state_machine.travel("start_game")
#
# if State.stage_list[0] is Player:
# Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
#func debug_youth():
# get_child(1).hide()
# get_child(2).hide()
# get_child(3).hide()
# get_child(0).get_ready()
# get_child(0).start()
#
#func _return_to_menu():
# State.active_save_game = null
#
# menu_animation["parameters/conditions/start_game"] = false
#
# State.pass_stage_to(main_menu)
#
# currently_loading_room = get_room_path_from_id(main_menu.save_game_handle.get_most_recent_save().current_room)
#
# menu_animation["parameters/conditions/return_to_menu"] = true
# await(get_tree().create_timer(0.5).timeout)
# menu_animation["parameters/conditions/return_to_menu"] = false
# _on_ready_to_unload()
#
#func load_save(save: SaveGame):
#
# if currently_loading_room != "":
# await(room_loaded)
#
# if save.current_room != current_room.id:
# # TODO Prevent race condition from appearing when save is loaded while room is still loading.
# currently_loading_room = get_room_path_from_id(save.current_room)
# await(room_loaded)
#
# menu_animation["parameters/conditions/start_game"] = true
#
# State.active_save_game = save
# in_game = true
# current_room.start_room()
#
#func _on_ready_to_unload():
# if get_child(0) is Node3D:
# get_child(0).free()
#
#func get_room_path_from_id(id: State.rooms) -> String:
# match id:
# State.rooms.YOUTH, State.rooms.NULL:
# return youth_room_path
# State.rooms.TRANSITION:
# return transition_room_path
# State.rooms.ADULTHOOD:
# return adulthood_room_path
# _:
# return ending_path
#
#func get_room_id_from_path(path: String) -> State.rooms:
# match path:
# youth_room_path:
# return State.rooms.YOUTH
# transition_room_path:
# return State.rooms.TRANSITION
# adulthood_room_path:
# return State.rooms.ADULTHOOD
# _:
# return State.rooms.NULL
#
#
#func start_demo():
# #FIXME this causes the room to reload
# #load_save(SaveGame.new())
# current_room.start_room()
# in_game = true
#
#func pause_mode_changed():
# print_debug(get_tree().paused)
#
#var await_swap: bool = false
#func prepare_transition(scene_id: Scenes.id, _repeat):
# if scene_id == Scenes.id.TRANSITION:
# await_swap = true
# #FIXME: this does not need to be part of the sequence
# await(get_tree().process_frame)
# current_room.prepare_transition()
# if not _repeat:
# currently_loading_room = get_room_path_from_id(State.rooms.TRANSITION)
# else:
#
# currently_loading_room = get_room_path_from_id(State.rooms.ADULTHOOD)
#
#func transition(scene_id: Scenes.id, _repeat):
# if scene_id == Scenes.id.TRANSITION:
# State.reset_focus()
# await_swap = false
# await room_loaded
# if not _repeat:
# State.queue_for_stage(current_room)
# Scenes.end_current_sequence()
# else:
# State.pass_stage_to(current_room)

View File

@ -10,15 +10,16 @@ func _ready() -> void:
pass_to_actor = get_child(current_tab)
func _on_tab_changed(tab_id: int):
var child_has_stage:bool = false
# Transfer has_stage to the new tab's child
for child in get_children():
if "has_stage" in child:
if child.has_stage:
child_has_stage = true
if child_has_stage:
State.transition_stage_to(get_child(tab_id))
child.has_stage = false
pass_to_actor = get_child(tab_id)
var new_child = get_child(tab_id)
if "has_stage" in new_child:
new_child.has_stage = true
pass_to_actor = new_child
func _on_stage_left():
await get_tree().process_frame

View File

@ -15,9 +15,7 @@ var is_active:bool = false:
if is_node_ready() and active:
screenreader_check.grab_focus()
if not active and is_active:
if has_stage:
State.leave_stage(self)
leave_stage.emit()
leave_stage.emit()
is_active = active
if (is_active and not has_stage) and not get_tree().paused:

View File

@ -84,8 +84,7 @@ func update_ui_from_state():
func _on_exit_button_pressed() -> void:
leave_stage.emit()
State.save_settings()
State.leave_stage(self)
func _input(event: InputEvent) -> void:
if event.is_action_pressed("ui_cancel") and has_stage:
State.leave_stage(self)
leave_stage.emit()

View File

@ -45,8 +45,7 @@ func _on_exit_button_pressed() -> void:
State.save_settings()
has_unsaved_changes = false
leave_stage.emit()
State.leave_stage(self)
func _input(event: InputEvent) -> void:
if event.is_action_pressed("ui_cancel") and has_stage:
State.leave_stage(self)
leave_stage.emit()

View File

@ -37,8 +37,7 @@ func update_ui_from_state():
func _on_exit_button_pressed() -> void:
leave_stage.emit()
State.save_settings()
State.leave_stage(self)
func _input(event: InputEvent) -> void:
if event.is_action_pressed("ui_cancel") and has_stage:
State.leave_stage(self)
leave_stage.emit()

View File

@ -39,11 +39,10 @@ func update_ui_from_state():
func _on_exit_button_pressed() -> void:
leave_stage.emit()
State.save_settings()
State.leave_stage(self)
func _input(event: InputEvent) -> void:
if event.is_action_pressed("ui_cancel") and has_stage:
State.leave_stage(self)
leave_stage.emit()
func reset_all_stats():
Steam.resetAllStats(true)

View File

@ -175,14 +175,12 @@ func save_settings():
func _on_exit_confirmed() -> void:
leave_stage.emit()
State.leave_stage(self)
func _on_exit_button_pressed() -> void:
if has_changed:
$Popup.show()
else:
leave_stage.emit()
State.leave_stage(self)
func _on_confirm_button_pressed() -> void:
ProjectSettings.set_setting("display/window/size/mode", window_mode)