extends Node ## SAVE DATA #GAME DATA var data_cleared var player_loc var player_rot var player_health var player_velocity_cache var current_gun var current_ammo var reserve_ammo ## SAVE DATA PATHS var persistent_data_save_path = "user://persistent_data.save" func _ready() -> void: SignalBus.shot_fired.connect(shot_fired) func save_persistent_data(): var file = FileAccess.open(persistent_data_save_path, FileAccess.WRITE) file.store_var(GameGlobals.user_id) file.store_var(GameGlobals.last_leaderboard_id) file.store_var(GameGlobals.user_names) file.store_var(GameGlobals.all_user_leaderboards) file.close() func load_persistent_data(): if FileAccess.file_exists(persistent_data_save_path): var file = FileAccess.open(persistent_data_save_path, FileAccess.READ) var user_id = file.get_var() var last_leaderboard_id = file.get_var() var user_names = file.get_var() var all_user_leaderboards = file.get_var() GameGlobals.user_id = int(user_id) GameGlobals.last_leaderboard_id = int(last_leaderboard_id) GameGlobals.user_names = user_names GameGlobals.all_user_leaderboards = all_user_leaderboards file.close() else: print("No file found...") func save_user_data(): var user_save_path = str("user://user_",str(GameGlobals.user_id),"_",str(GameGlobals.all_user_leaderboards[GameGlobals.user_id][GameGlobals.last_leaderboard_id]),"_data.save") var file = FileAccess.open(user_save_path, FileAccess.WRITE) #cache data before saving and creating checksum in case it changes between data saving and checksum generating var leaderboard_name = str(GameGlobals.current_leaderboard_name) var money = GameGlobals.money var deposited_money = GameGlobals.deposited_money var health = GameGlobals.health var high_score = GameGlobals.high_score var player_deaths = GameGlobals.player_deaths var shots_fired = GameGlobals.shots_fired file.store_var(GameGlobals.last_hit_path) file.store_var(leaderboard_name) file.store_var(GameGlobals.current_level) file.store_var(GameGlobals.current_match) file.store_var(GameGlobals.current_match_id) file.store_var(GameGlobals.current_round_id) file.store_var(money) file.store_var(deposited_money) file.store_var(health) file.store_var(high_score) file.store_var(player_deaths) file.store_var(GameGlobals.enemies_killed) file.store_var(shots_fired) var held_guns = save_resource_path(GameGlobals.held_guns) file.store_var(held_guns) file.store_var(GameGlobals.gun_ammo) file.store_var(GameGlobals.ammo_reserve) file.store_var(GameGlobals.current_gun_index) var check_data = [user_save_path,leaderboard_name,money,deposited_money,health,high_score,player_deaths,shots_fired] file.store_var(HelperFuncs.checksum(check_data)) file.close() func check_user_data_exists(): var user_save_path = str("user://user_",str(GameGlobals.user_id),"_",str(GameGlobals.all_user_leaderboards[GameGlobals.user_id][GameGlobals.last_leaderboard_id]),"_data.save") if FileAccess.file_exists(user_save_path): return true else: return false func load_user_data(): print("ALL LEADERBOARDS: ",GameGlobals.all_user_leaderboards[0][0]) var user_save_path = str("user://user_",str(GameGlobals.user_id),"_",str(GameGlobals.all_user_leaderboards[GameGlobals.user_id][GameGlobals.last_leaderboard_id]),"_data.save") if FileAccess.file_exists(user_save_path): var file = FileAccess.open(user_save_path, FileAccess.READ) GameGlobals.last_hit_path = file.get_var() var file_leaderboard_name = file.get_var() GameGlobals.current_level = str(file.get_var()) GameGlobals.current_match = file.get_var() GameGlobals.current_match_id = file.get_var() GameGlobals.current_round_id = file.get_var() var money = set_nulls_zero(file.get_var()) var deposited_money = set_nulls_zero(file.get_var()) var health = file.get_var() var high_score = file.get_var() var player_deaths = set_nulls_zero(file.get_var()) GameGlobals.enemies_killed = set_nulls_zero(file.get_var()) var shots_fired = set_nulls_zero(file.get_var()) var held_guns_encoded = file.get_var() GameGlobals.money = money GameGlobals.deposited_money = deposited_money GameGlobals.health = health GameGlobals.high_score = high_score GameGlobals.player_deaths = player_deaths GameGlobals.shots_fired = shots_fired GameGlobals.held_guns = load_resource_path(held_guns_encoded) GameGlobals.gun_ammo = file.get_var() GameGlobals.ammo_reserve = file.get_var() GameGlobals.current_gun_index = file.get_var() if GameGlobals.current_gun_index != null: if !get_tree().current_scene.is_in_group("ui"): get_tree().current_scene.gun_spawn(GameGlobals.current_gun_index) var checksum = file.get_var() print("Checksum : ",checksum) var check_data = [user_save_path,file_leaderboard_name,money,deposited_money,health,high_score,player_deaths,shots_fired] print("CHECK DATA : ",check_data) print("CHECKSUM CALC : ",HelperFuncs.checksum(check_data)) file.close() await !file.is_open() if checksum == HelperFuncs.checksum(check_data): print("DATA VALID") #APPLY DATA AFTER else: print("DATA NOT VALID") else: print("no data saved...") GameGlobals.money = 0 GameGlobals.deposited_money = 0 GameGlobals.health = 10 GameGlobals.high_score = 0 GameGlobals.player_deaths = 0 GameGlobals.shots_fired = 0 GameGlobals.held_guns = [] GameGlobals.gun_ammo = {} GameGlobals.ammo_reserve = {} GameGlobals.current_gun_index = 0 func save_game_data(level_name): var level_control = get_tree().current_scene var player = level_control.player var game_save_path = str("user://user_",str(GameGlobals.user_id),"_",str(GameGlobals.all_user_leaderboards[GameGlobals.user_id][GameGlobals.last_leaderboard_id]),"_last_level","_data.save") var file = FileAccess.open(game_save_path, FileAccess.WRITE) #ASSIGN DATA TO VARIABLES data_cleared = false player_loc = player.global_position player_rot = player.global_rotation #save enemies var objects = get_tree().get_nodes_in_group("persist") for object in objects: if object.scene_file_path.is_empty(): print("persistent node '%s' is not an instanced scene, skipped" % object.name) continue # Check the node has a save function. if !object.has_method("save"): print("persistent node '%s' is missing a save() function, skipped" % object.name) continue var object_data = object.call("save") var json_string = JSON.stringify(object_data) file.store_line(json_string) file.close() func check_save_game_exists(level_name): var game_save_path = str("user://user_",str(GameGlobals.user_id),"_",str(GameGlobals.all_user_leaderboards[GameGlobals.user_id][GameGlobals.last_leaderboard_id]),"_last_level","_data.save") if FileAccess.file_exists(game_save_path): return true else: return false func load_save_game_data(level_name): var level_control = get_tree().current_scene var player = level_control.player var game_save_path = str("user://user_",str(GameGlobals.user_id),"_",str(GameGlobals.all_user_leaderboards[GameGlobals.user_id][GameGlobals.last_leaderboard_id]),"_last_level","_data.save") print("GAME SAVE PATH : ",game_save_path) if FileAccess.file_exists(game_save_path): var file = FileAccess.open(game_save_path, FileAccess.READ) #GET DATA if !data_cleared: var current_nodes = get_tree().get_nodes_in_group("persist") for i in current_nodes: if i.is_in_group("enemy"): i.queue_free() else: i.queue_free() while file.get_position() < file.get_length(): var json_string = file.get_line() var json = JSON.new() var parse_result = json.parse(json_string) if not parse_result == OK: print("JSON Parse Error: ",json.get_error_message()," in ",json_string, " at line ", json.get_error_line()) continue var node_data = json.data var new_object = load(node_data["filename"]).instantiate() get_node(node_data["parent"]).add_child(new_object) #apply transform if available if node_data["pos_x"] != null: new_object.position = Vector3(node_data["pos_x"],node_data["pos_y"],node_data["pos_z"]) if node_data["rot_x"] != null: new_object.rotation = Vector3(node_data["rot_x"],node_data["rot_y"],node_data["rot_z"]) #apply other save data for i in node_data.keys(): if i == "filename" or i == "pos_x" or i == "pos_y" or i == "pos_z": continue new_object.set(i,node_data[i]) file.close() await get_tree().create_timer(1).timeout #need to fix this SignalBus.emit_signal("game_loaded") GameGlobals.game_loaded = true else: print("no data saved...") func data_validate(file,variable): if file.get_var(variable): return file.get_var(variable) else: return null func set_nulls_zero(variable): if variable == null: return 0 else: return variable func null_data_check(variable,amount): #checks if value is null, adds the number to variable if variable == null: variable = amount else: variable += amount return variable func save_resource_path(array): var final_array = [] for i in array: if i is PackedScene: var resource_path = i.resource_path if resource_path != "": final_array.append(resource_path) return final_array func load_resource_path(array): if array != null: var final_array = [] for i in array: var i_loaded = load(i) final_array.append(i_loaded) return final_array else: return [] func shot_fired(): GameGlobals.shots_fired += null_data_check(GameGlobals.shots_fired, 1)