WIP: refactor boot order, re-introduce menu animations
This commit is contained in:
parent
8bdd48a365
commit
b2fd6af9f4
|
|
@ -1,5 +1,4 @@
|
|||
extends Node
|
||||
|
||||
func _ready() -> void:
|
||||
func _enter_tree() -> void:
|
||||
Main.normal_boot = true # Tell the system this is a normal game start
|
||||
|
||||
|
|
@ -3,9 +3,24 @@ class_name GlobalState
|
|||
|
||||
#region configuration
|
||||
signal settings_changed
|
||||
var _settings_initialized
|
||||
signal savegame_changed
|
||||
var _settings_initialized: bool = false
|
||||
var _savegame_initialized: bool = false
|
||||
|
||||
var all_ready: bool:
|
||||
get():
|
||||
return _settings_initialized and _savegame_initialized
|
||||
|
||||
func saves_loaded(save: SaveGame):
|
||||
save_game = save
|
||||
_savegame_initialized = true
|
||||
|
||||
|
||||
var active_room: Room
|
||||
var save_game: SaveGame:
|
||||
set(save):
|
||||
save_game = save
|
||||
savegame_changed.emit()
|
||||
signal environment_settings_changed
|
||||
|
||||
# FIXME find a better way to switch fonts and maybe emit the theme_changed signal!
|
||||
|
|
@ -167,10 +182,10 @@ func load_user_settings():
|
|||
file.close()
|
||||
var parsed: Dictionary = JSON.parse_string(raw_json)
|
||||
|
||||
for kategory in parsed.values():
|
||||
for key in kategory.keys():
|
||||
for kategory in parsed.keys():
|
||||
for key in parsed[kategory].keys():
|
||||
if key in self:
|
||||
set(key, parsed[key])
|
||||
set(key, parsed[kategory][key])
|
||||
|
||||
else:
|
||||
if OS.has_feature("macos"):
|
||||
|
|
@ -224,15 +239,14 @@ func save_settings():
|
|||
var file := FileAccess.open(user_settings_path, FileAccess.WRITE)
|
||||
file.store_string(JSON.stringify(out_dict))
|
||||
file.close()
|
||||
|
||||
_settings_initialized = true
|
||||
|
||||
settings_changed.emit()
|
||||
|
||||
func _ready():
|
||||
load_user_settings()
|
||||
await get_tree().process_frame
|
||||
music_volume = music_volume
|
||||
|
||||
|
||||
#region focus handling (called staging to avoid name colisions)
|
||||
|
||||
# CAUTION: scene_reference directly accesses stage list to play sequences.
|
||||
|
|
|
|||
|
|
@ -1,50 +1,49 @@
|
|||
extends Node
|
||||
extends Control
|
||||
|
||||
var normal_boot : bool = false
|
||||
@onready var menu_animation: AnimationNodeStateMachinePlayback = %MenuAnimationTree.get("parameters/playback")
|
||||
|
||||
@export_file(".tscn") var youth_room_path: String
|
||||
@export_file(".tscn") var transition_room_path: String
|
||||
@export_file(".tscn") var adulthood_room_path: String
|
||||
@export_file(".tscn") var ending_path: String
|
||||
|
||||
@onready var curtain: Curtain = %Curtain
|
||||
@onready var curtain: Panel = %Curtain
|
||||
@onready var credits_roll: Control = %CreditsRoll
|
||||
@onready var main_menu: MainMenu = %MainMenu
|
||||
@onready var pause_menu: PauseMenu = %PauseMenu
|
||||
|
||||
@onready var room_paths := {
|
||||
State.rooms.NULL: youth_room_path, # Maybe Draven story?
|
||||
State.rooms.YOUTH: youth_room_path,
|
||||
State.rooms.TRANSITION: transition_room_path,
|
||||
State.rooms.ADULTHOOD: adulthood_room_path,
|
||||
State.rooms.ENDING: ending_path
|
||||
Room.ids.NULL: youth_room_path, # Maybe Draven story?
|
||||
Room.ids.YOUTH: youth_room_path,
|
||||
Room.ids.TRANSITION: transition_room_path,
|
||||
Room.ids.ADULTHOOD: adulthood_room_path,
|
||||
Room.ids.ENDING: ending_path
|
||||
}
|
||||
|
||||
enum AppState {BOOT, MENU, PLAY, PAUSE, CREDITS}
|
||||
enum AppState {INIT, LOADING, MENU, PLAY, PAUSE, CREDITS}
|
||||
|
||||
var state: AppState = AppState.BOOT:
|
||||
var state: AppState = AppState.INIT:
|
||||
set(value):
|
||||
state = value
|
||||
print("main.gd: app_state changing to: %s" % str(state))
|
||||
match state:
|
||||
AppState.BOOT:
|
||||
credits_roll.hide()
|
||||
main_menu.hide()
|
||||
pause_menu.hide()
|
||||
match value:
|
||||
AppState.INIT:
|
||||
pass
|
||||
AppState.LOADING:
|
||||
%MenuAnimationTree["parameters/conditions/loading_done"] = false
|
||||
AppState.MENU:
|
||||
credits_roll.hide()
|
||||
pause_menu.hide()
|
||||
menu_animation.travel("loading_menu")
|
||||
await main_menu.execute()
|
||||
AppState.PLAY:
|
||||
pass
|
||||
menu_animation.travel("start_game")
|
||||
await_ui_clear()
|
||||
hide()
|
||||
AppState.PAUSE:
|
||||
credits_roll.hide()
|
||||
main_menu.hide()
|
||||
pause_menu.appear()
|
||||
menu_animation.travel("reveal_pause_menu")
|
||||
AppState.CREDITS:
|
||||
main_menu.hide()
|
||||
pause_menu.hide()
|
||||
credits_roll.play()
|
||||
menu_animation.travel("credits_roll")
|
||||
|
||||
state = value
|
||||
|
||||
func _enter_tree() -> void:
|
||||
print("main.gd: _enter_tree()")
|
||||
|
|
@ -53,51 +52,80 @@ func _ready() -> void:
|
|||
print("main.gd: _ready()")
|
||||
main_menu.continue_button.pressed.connect(func(): state = AppState.PLAY)
|
||||
main_menu.credits_button.pressed.connect(func(): state = AppState.CREDITS)
|
||||
|
||||
#TODO: Load the last savegame(?)
|
||||
await %Loading.stop()
|
||||
|
||||
|
||||
#await get_tree().process_frame
|
||||
await await_boot_completed()
|
||||
|
||||
if normal_boot:
|
||||
print("main.gd: normal boot (loading last save and showing main menu)")
|
||||
state = AppState.MENU
|
||||
call_deferred("start_menu")
|
||||
|
||||
else:
|
||||
print("main.gd: direct boot (hiding menus and entering main loop)")
|
||||
state = AppState.PLAY
|
||||
|
||||
func start_menu():
|
||||
|
||||
if Steam.resume_from_steamdeck():
|
||||
start_game()
|
||||
|
||||
initialise_room(State.save_game.current_room)
|
||||
state = AppState.MENU
|
||||
|
||||
|
||||
func start_game(save: SaveGame) -> void:
|
||||
func await_boot_completed():
|
||||
print("main.gd: Awaiting Boot Completion ...")
|
||||
while not State.all_ready:
|
||||
await get_tree().process_frame
|
||||
print("main.gd: Boot Completed.")
|
||||
|
||||
func await_ui_clear():
|
||||
print("main.gd: Awaiting Menu Clear ...")
|
||||
while not menu_animation.get_current_node() == "start_game":
|
||||
await get_tree().process_frame
|
||||
print("main.gd: Menu Cleared.")
|
||||
|
||||
func start_game(save: SaveGame = State.save_game) -> void:
|
||||
print("main.gd: play_game()")
|
||||
var room_path := room_paths.get(save.current_room, youth_room_path) as String
|
||||
|
||||
initialise_room(save.current_room)
|
||||
State.active_room.play()
|
||||
state = AppState.PLAY
|
||||
|
||||
while room_path:
|
||||
await _load_room(room_path)
|
||||
room_path = await State.room.play()
|
||||
|
||||
# Ending? Roll credits?
|
||||
|
||||
func is_game_active() -> bool:
|
||||
return state == AppState.PLAY or state == AppState.PAUSE
|
||||
|
||||
|
||||
func initialise_room(room_id: Room.ids):
|
||||
if State.active_room:
|
||||
if State.active_room.id == room_id:
|
||||
return
|
||||
else:
|
||||
menu_animation.travel("change_savegame")
|
||||
_load_room(room_paths.get(room_id, youth_room_path) as String)
|
||||
|
||||
|
||||
func _load_room(scene_path: String) -> void:
|
||||
await curtain.close()
|
||||
%Loading.play()
|
||||
|
||||
if State.room:
|
||||
State.room.unload()
|
||||
State.room.queue_free()
|
||||
State.room = null
|
||||
|
||||
ResourceLoader.load_threaded_request(scene_path, "PackedScene", true)
|
||||
|
||||
await get_tree().create_timer(0.1).timeout
|
||||
|
||||
if State.active_room:
|
||||
State.active_room.unload()
|
||||
State.active_room.queue_free()
|
||||
State.active_room = null
|
||||
|
||||
while true:
|
||||
await get_tree().process_frame
|
||||
var load_state := ResourceLoader.load_threaded_get_status(scene_path)
|
||||
match load_state:
|
||||
ResourceLoader.THREAD_LOAD_LOADED:
|
||||
var next_scene := ResourceLoader.load_threaded_get(scene_path) as PackedScene
|
||||
State.room = next_scene.instantiate() as Room
|
||||
%Stage.add_child(State.room)
|
||||
State.active_room = next_scene.instantiate() as Room
|
||||
%Stage.add_child(State.active_room)
|
||||
await get_tree().process_frame
|
||||
%Loading.stop()
|
||||
%MenuAnimationTree["parameters/conditions/loading_done"] = true
|
||||
return
|
||||
ResourceLoader.THREAD_LOAD_FAILED:
|
||||
push_error("Failed to load room.")
|
||||
|
|
@ -109,7 +137,10 @@ func _load_room(scene_path: String) -> void:
|
|||
var last_mode := DisplayServer.WINDOW_MODE_WINDOWED
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
#if event.is_action_type(): print_debug("Unhandled Input", event)
|
||||
#if event.is_actionxxx_type(): print_debug("Unhandled Input", event)
|
||||
|
||||
if event.is_action_pressed("ui_pause") and state == AppState.PLAY:
|
||||
state = AppState.PAUSE
|
||||
|
||||
if not Engine.is_editor_hint():
|
||||
if event.is_action_pressed("toggle_fullscreen"):
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@ func _validate_property(property: Dictionary) -> void:
|
|||
|
||||
var _tween: Tween = null
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_load_games()
|
||||
hide()
|
||||
set_process_input(false)
|
||||
back_button.pressed.connect(cancel)
|
||||
|
||||
|
||||
func _ensure_directory() -> void:
|
||||
var dir := DirAccess.open(State.user_saves_path)
|
||||
|
||||
|
|
@ -49,8 +51,7 @@ func _load_games():
|
|||
# Skip invalid/empty saves
|
||||
if save != null and not save.is_empty:
|
||||
saves.append(save)
|
||||
|
||||
_sort_saves()
|
||||
State.saves_loaded(get_most_recent_save())
|
||||
_rebuild_buttons()
|
||||
|
||||
|
||||
|
|
@ -69,6 +70,7 @@ func _get_slot_number(save: SaveGame) -> int:
|
|||
# Find this save's position in the creation-order list
|
||||
return saves_by_creation.find(save) + 1
|
||||
|
||||
|
||||
func _rebuild_buttons() -> void:
|
||||
save_buttons = []
|
||||
for child in list_container.get_children():
|
||||
|
|
@ -93,6 +95,7 @@ func _rebuild_buttons() -> void:
|
|||
func _on_game_picked(id: int) -> void:
|
||||
_picked.emit(saves[id])
|
||||
|
||||
|
||||
func _on_delete_requested(id: int) -> void:
|
||||
var save_to_delete := saves[id]
|
||||
var save_path := save_to_delete.file_name
|
||||
|
|
@ -116,23 +119,28 @@ func _on_delete_requested(id: int) -> void:
|
|||
var focus_index := mini(id, save_buttons.size() - 1)
|
||||
save_buttons[focus_index].grab_focus()
|
||||
|
||||
|
||||
func get_most_recent_save() -> SaveGame:
|
||||
_sort_saves()
|
||||
return saves[0] if saves.size() > 0 else SaveGame.new()
|
||||
|
||||
|
||||
func has_more_saves() -> bool:
|
||||
for save in saves:
|
||||
if save != State.save_game:
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
cancel()
|
||||
|
||||
|
||||
func cancel()->void:
|
||||
_picked.emit(State.save_game)
|
||||
|
||||
|
||||
# This function is called when the user us supposed to choose a slot to load or create a new game.
|
||||
func pick_save_slot() -> SaveGame:
|
||||
await open()
|
||||
|
|
@ -140,6 +148,7 @@ func pick_save_slot() -> SaveGame:
|
|||
await close()
|
||||
return result
|
||||
|
||||
|
||||
# TODO: ugh, godot tweens are the wurst
|
||||
func open() -> void:
|
||||
show()
|
||||
|
|
@ -156,6 +165,7 @@ func open() -> void:
|
|||
_tween.tween_property(self, "modulate", Color.WHITE, 0.5)
|
||||
await _tween.finished
|
||||
|
||||
|
||||
func close() -> void:
|
||||
if _tween != null:
|
||||
_tween.kill()
|
||||
|
|
|
|||
Loading…
Reference in New Issue