170 lines
4.8 KiB
GDScript
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"
|