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