MagicNStuff/game/src/game.gd

170 lines
4.8 KiB
GDScript

class_name Game
extends Node
## TODO: sicherungskasten minigames (Kabel verbinden, oder draufhauen und geht wieder)
const SAVE_DIR: String = "user://saves/%s/"
const SAVE_PATH: String = SAVE_DIR + "%s"
const INITIAL_SAVE_DATA: SaveData = preload("res://src/initial_save_data.tres")
static var is_debug: bool = true
@export_file("*.tscn", "*.scn") var main_menu_path: String = "uid://7v62dybcabgw"
var current_save_slot: int = 0
var current_save_data: SaveData = INITIAL_SAVE_DATA.duplicate()
var world: World
var main_menu: MainMenu
@onready var loading_screen: LoadingScreen = $LoadingScreen
@onready var world_container: Node = $WorldContainer
static func _static_init() -> void:
is_debug = OS.is_debug_build() or Engine.is_editor_hint()
static func debug_draw(draw_shape: String, args: Array) -> void:
if is_debug and Engine.has_singleton(&"DebugDraw3D"):
Engine.get_singleton(&"DebugDraw3D").callv("draw_" + draw_shape, args)
func _ready() -> void:
load_main_menu()
func load_game(save_data: SaveData, save_slot: int) -> void:
current_save_data = save_data.duplicate()
current_save_slot = save_slot
load_world(current_save_data.current_world, false)
func save_game() -> Error:
if not is_instance_valid(world):
return ERR_DOES_NOT_EXIST
var save_slot: String = str(current_save_slot)
var file_name: String = "save_data.tres"
if is_instance_valid(world):
current_save_data.current_world = ResourceUID.path_to_uid(world.scene_file_path)
DirAccess.make_dir_recursive_absolute(SAVE_DIR % save_slot)
return ResourceSaver.save(current_save_data, SAVE_PATH % [save_slot, file_name])
#func _ready() -> void:
#await load_world("res://src/worlds/exposition/exposition.tscn")
#await get_tree().create_timer(5.0, false).timeout
#await unload_world()
#await loading_screen.fade_out()
#await get_tree().create_timer(3.0, false).timeout
#_ready()
func load_world(world_path: String, save_previous: bool = true, load_from_save: bool = true) -> Error:
if not ResourceLoader.exists(world_path, "PackedScene"):
return ERR_FILE_NOT_FOUND
await loading_screen.fade_in()
unload_main_menu()
unload_world(save_previous)
var loader := InteractiveLoader.create_oneshot(self)
var loaded_scene: PackedScene = await loader.load_threaded(world_path)
world = loaded_scene.instantiate() as World
if not is_instance_valid(world):
loading_screen.fade_out()
return ERR_INVALID_DATA
if load_from_save:
world.world_state = load_world_state(world_path)
world.change_world_requested.connect(load_world)
world.world_unload_requested.connect(_on_unload_world_request)
world_container.add_child.call_deferred(world)
await world.loaded
loading_screen.fade_out()
return OK
func unload_world(do_save: bool = true) -> void:
if not is_instance_valid(world):
return
if do_save:
save_world_state()
world.process_mode = Node.PROCESS_MODE_DISABLED
await loading_screen.fade_in()
world.queue_free()
func save_world_state() -> Error:
if not is_instance_valid(world):
return ERR_DOES_NOT_EXIST
world.update_world_state()
var world_state: WorldState = world.world_state
var save_slot: String = str(current_save_slot)
var file_name: String = _get_world_save_file_name_from_world_path(world_state.world_path)
print("File name: ", file_name)
print(SAVE_PATH % [save_slot, file_name])
DirAccess.make_dir_recursive_absolute(SAVE_DIR % save_slot)
save_game()
return ResourceSaver.save(world_state, SAVE_PATH % [save_slot, file_name])
func load_world_state(world_path: String) -> WorldState:
var save_slot: String = str(current_save_slot)
var file_name: String = _get_world_save_file_name_from_world_path(world_path)
var file_path: String = SAVE_PATH % [save_slot, file_name]
if not ResourceLoader.exists(file_path):
return null
return ResourceLoader.load(file_path)
func load_main_menu() -> void:
var loader := InteractiveLoader.create_oneshot(self)
var loaded_scene: PackedScene = await loader.load_threaded(main_menu_path)
var _main_menu: MainMenu = loaded_scene.instantiate()
_main_menu.load_game_request.connect(load_game)
_main_menu.quit_request.connect(quit_game)
main_menu = _main_menu
world_container.add_child(main_menu)
func unload_main_menu() -> void:
if is_instance_valid(main_menu):
main_menu.queue_free()
func quit_game() -> void:
await loading_screen.fade_in()
get_tree().quit()
func _on_unload_world_request(do_save: bool) -> void:
await unload_world(do_save)
if do_save:
save_game()
await load_main_menu()
loading_screen.fade_out()
func _get_world_save_file_name_from_world_path(world_path: String) -> String:
world_path = ResourceUID.path_to_uid(world_path)
print("World path: ", world_path)
if world_path.begins_with("res://"):
return world_path.get_file().replace(".tscn", ".tres").replace(".scn", ".res")
return world_path.replace("uid://", "") + ".tres"