SaveManager.gd 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. extends Node
  2. const SAVE_DIR := "user://saves/CAMPAIGN.sav"
  3. var visited_levels := "1000000000000000000000000000000010000000000000000000"
  4. var current_file := {}
  5. const SAVE_TEMPLATE := {
  6. "World": 1,
  7. "Level": 1,
  8. "Lives": 3,
  9. "Coins": 0,
  10. "Score": 0,
  11. "GameWin": false,
  12. "PowerStates": "0000",
  13. "LevelsVisited": "1000000000000000000000000000000000000000000000000000",
  14. "BestAnyTime": 0.0,
  15. "BestWarplessTime": 0.0,
  16. "ClearedBooLevels": "00000000",
  17. "ChallengeScores": [
  18. [0.0, 0.0, 0.0, 0.0],
  19. [0.0, 0.0, 0.0, 0.0],
  20. [0.0, 0.0, 0.0, 0.0],
  21. [0.0, 0.0, 0.0, 0.0],
  22. [0.0, 0.0, 0.0, 0.0],
  23. [0.0, 0.0, 0.0, 0.0],
  24. [0.0, 0.0, 0.0, 0.0],
  25. [0.0, 0.0, 0.0, 0.0]
  26. ],
  27. "RedCoins": [
  28. [0.0, 0.0, 0.0, 0.0],
  29. [0.0, 0.0, 0.0, 0.0],
  30. [0.0, 0.0, 0.0, 0.0],
  31. [0.0, 0.0, 0.0, 0.0],
  32. [0.0, 0.0, 0.0, 0.0],
  33. [0.0, 0.0, 0.0, 0.0],
  34. [0.0, 0.0, 0.0, 0.0],
  35. [0.0, 0.0, 0.0, 0.0]
  36. ],
  37. "BooBestTimes": [
  38. -1.0, -1.0, -1.0, -1.0,
  39. -1.0, -1.0, -1.0, -1.0
  40. ],
  41. "HighScore": 0,
  42. "ExtraWorldWin": false
  43. }
  44. func _ready() -> void:
  45. verify_saves()
  46. load_achievements()
  47. func load_save(campaign := "SMB1") -> Dictionary:
  48. if FileAccess.file_exists(SAVE_DIR.replace("CAMPAIGN", campaign)) == false:
  49. write_save(campaign)
  50. var file = FileAccess.open(SAVE_DIR.replace("CAMPAIGN", campaign), FileAccess.READ)
  51. var json = JSON.parse_string(file.get_as_text())
  52. print(file.get_as_text())
  53. current_file = json
  54. file.close()
  55. return json
  56. func verify_saves() -> void:
  57. for campaign in Global.CAMPAIGNS:
  58. if FileAccess.file_exists(SAVE_DIR.replace("CAMPAIGN", campaign)) == false:
  59. write_save(campaign, true)
  60. func write_save(campaign: String = Global.current_campaign, force := false) -> void:
  61. if Global.debugged_in and not force:
  62. return
  63. var save = null
  64. DirAccess.make_dir_recursive_absolute("user://saves")
  65. var save_json = {}
  66. var path = "user://saves/" + campaign + ".sav"
  67. if FileAccess.file_exists(path):
  68. save = FileAccess.open("user://saves/" + campaign + ".sav", FileAccess.READ)
  69. save_json = JSON.parse_string(save.get_as_text())
  70. save.close()
  71. else:
  72. save_json = SAVE_TEMPLATE.duplicate(true)
  73. match Global.current_game_mode:
  74. Global.GameMode.CAMPAIGN:
  75. if Global.high_score < Global.score:
  76. Global.high_score = Global.score
  77. save_json["World"] = Global.world_num
  78. save_json["Level"] = Global.level_num
  79. save_json["Coins"] = Global.coins
  80. save_json["Score"] = Global.score
  81. save_json["GameWin"] = Global.game_beaten
  82. save_json["PowerStates"] = Global.player_power_states
  83. save_json["LevelsVisited"] = visited_levels
  84. save_json["HighScore"] = Global.high_score
  85. save_json["ExtraWorldWin"] = Global.extra_worlds_win
  86. Global.GameMode.CHALLENGE:
  87. save_json["ChallengeScores"] = ChallengeModeHandler.top_challenge_scores
  88. save_json["RedCoins"] = ChallengeModeHandler.red_coins_collected
  89. Global.GameMode.BOO_RACE:
  90. save_json["ClearedBooLevels"] = BooRaceHandler.cleared_boo_levels
  91. save_json["BooBestTimes"] = BooRaceHandler.best_times
  92. Global.GameMode.MARATHON:
  93. save_json["BestAnyTime"] = SpeedrunHandler.marathon_best_any_time
  94. save_json["BestWarplessTime"] = SpeedrunHandler.marathon_best_warpless_time
  95. _:
  96. pass
  97. if campaign == "SMBANN":
  98. save_json["Ranks"] = DiscoLevel.level_ranks
  99. write_save_to_file(save_json, path)
  100. func write_save_to_file(json := {}, path := "") -> void:
  101. var file = FileAccess.open(path, FileAccess.WRITE)
  102. file.store_string(JSON.stringify(json, "\t", false, false))
  103. file.close()
  104. func apply_save(json := {}) -> void:
  105. Global.world_num = clamp(json["World"], 1, 8)
  106. Global.level_num = json.get_or_add("Level", 1)
  107. Global.lives = json["Lives"]
  108. Global.coins = json["Coins"]
  109. Global.score = json["Score"]
  110. ChallengeModeHandler.red_coins_collected = json["RedCoins"]
  111. ChallengeModeHandler.top_challenge_scores = json["ChallengeScores"]
  112. BooRaceHandler.cleared_boo_levels = json["ClearedBooLevels"]
  113. Global.player_power_states = json["PowerStates"]
  114. Global.game_beaten = json["GameWin"]
  115. for i in json["LevelsVisited"].length():
  116. visited_levels[i] = json["LevelsVisited"][i]
  117. Global.extra_worlds_win = json.get("ExtraWorldWin", false)
  118. SpeedrunHandler.marathon_best_any_time = json.get("BestAnyTime", -1)
  119. SpeedrunHandler.marathon_best_warpless_time = json.get("BestWarplessTime", -1.0)
  120. Global.high_score = json["HighScore"]
  121. if json.has("Ranks"):
  122. DiscoLevel.level_ranks = json.get("Ranks")
  123. if json.has("BooBestTimes"):
  124. BooRaceHandler.best_times = json.get("BooBestTimes").duplicate()
  125. func clear_save() -> void:
  126. for i in [BooRaceHandler.cleared_boo_levels, ChallengeModeHandler.top_challenge_scores, ChallengeModeHandler.red_coins_collected, visited_levels]:
  127. if i is Array:
  128. clear_array(i)
  129. else:
  130. i = clear_text(i)
  131. visited_levels[0][0] = "1"
  132. var save = SAVE_TEMPLATE.duplicate(true)
  133. apply_save(save)
  134. DirAccess.remove_absolute("user://saves/" + Global.current_campaign + ".sav")
  135. write_save(Global.current_campaign)
  136. func clear_array(arr := []) -> void:
  137. for i in arr.size():
  138. if arr[i] is Array:
  139. clear_array(arr[i])
  140. elif arr[i] is bool:
  141. arr[i] = false
  142. else:
  143. arr[i] = 0
  144. func clear_text(text := "") -> String:
  145. for i in text.length():
  146. if text[i].is_valid_int():
  147. text[i] = "0"
  148. return text
  149. func get_level_idx(world_num := 1, level_num := 1) -> int:
  150. return ((world_num - 1) * 4) + (level_num - 1)
  151. func load_achievements() -> void:
  152. if FileAccess.file_exists("user://achievements.sav") == false:
  153. write_achievements()
  154. var file = FileAccess.open("user://achievements.sav", FileAccess.READ)
  155. var idx := 0
  156. for i in file.get_as_text():
  157. Global.achievements[idx] = i
  158. idx += 1
  159. AchievementMenu.unlocked_achievements = Global.achievements
  160. file.close()
  161. func write_achievements() -> void:
  162. var file = FileAccess.open("user://achievements.sav", FileAccess.WRITE)
  163. file.store_string(Global.achievements)
  164. file.close()