using System; using System.Collections; using System.Collections.Generic; using Ichni.Menu; using Ichni.RhythmGame; using Ichni.Story; using Sirenix.OdinInspector; using UnityEngine; namespace Ichni { public class GameSaveManager : SerializedMonoBehaviour { public static GameSaveManager instance; public SongSaveModule SongSaveModule; public StorySaveModule StorySaveModule; [Title("Debug")] public UnlockKeysCollection unlockKeysCollection; private void Awake() { if (instance == null) { instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } private void Start() { SongSaveModule = new SongSaveModule(); SongSaveModule.LoadSongStatuses(); SongSaveModule.LoadUnlockKeys(); StorySaveModule = new StorySaveModule(); StorySaveModule.LoadStoryVariables(); StorySaveModule.LoadChoices(); } } public partial class SongSaveModule { public HashSet unlockKeys; public Dictionary songStatusSaves; private string SongSavePath => Application.persistentDataPath + "/GameSaves/SongSaves.json"; private string UnlockKeysPath => Application.persistentDataPath + "/GameSaves/UnlockKeys.json"; public SongSaveModule() { songStatusSaves = new Dictionary(); unlockKeys = new HashSet(); Debug.Log("Song save path: " + SongSavePath); } } public partial class SongSaveModule { public void InitializeUnlockKeys() { unlockKeys = new HashSet(GameSaveManager.instance.unlockKeysCollection.unlockKeys); SaveUnlockKeys(); } public void SaveUnlockKeys() { ES3.Save("UnlockKeys", unlockKeys, UnlockKeysPath); } public void LoadUnlockKeys() { if (ES3.FileExists(UnlockKeysPath)) { unlockKeys = ES3.Load>("UnlockKeys", UnlockKeysPath); } else { InitializeUnlockKeys(); } } public bool CheckUnlock(string key) { return key == string.Empty || unlockKeys.Contains(key); } public void ClearUnlock() { unlockKeys.Clear(); SaveUnlockKeys(); } } public partial class SongSaveModule { private void InitializeSongStatuses() { foreach (ChapterSelectionUnit chapter in ChapterSelectionManager.instance.chapters) { foreach (SongItemData song in chapter.songs) { SongStatusSave songStatus = new SongStatusSave(false, string.Empty, new List()); foreach (DifficultyData difficulty in song.difficultyDataList) { songStatus.beatmapSaves.Add(new BeatmapSave(0f,false, false)); } songStatusSaves.Add(song.songName, songStatus); } } SaveSongStatuses(); } private void CheckSongStatuses() { foreach (ChapterSelectionUnit chapter in ChapterSelectionManager.instance.chapters) { foreach (SongItemData song in chapter.songs) { SongStatusSave songStatus = songStatusSaves[song.songName]; int difficultiesCount = song.difficultyDataList.Count; if (songStatus.beatmapSaves.Count < difficultiesCount) { for (int i = songStatus.beatmapSaves.Count; i < difficultiesCount; i++) { songStatus.beatmapSaves.Add(new BeatmapSave(0f, false, false)); } } else if (songStatus.beatmapSaves.Count > difficultiesCount) { songStatus.beatmapSaves.RemoveRange(difficultiesCount, songStatus.beatmapSaves.Count - difficultiesCount); } } } SaveSongStatuses(); } [Button] public void SaveSongStatuses() { ES3.Save("SongSaves", songStatusSaves, SongSavePath); } public void LoadSongStatuses() { if (ES3.FileExists(SongSavePath)) { songStatusSaves = ES3.Load>("SongSaves", SongSavePath); CheckSongStatuses(); } else { InitializeSongStatuses(); } } [Button] public void ClearBeatmapRecords() { foreach (var songStatus in songStatusSaves.Values) { foreach (var beatmapSave in songStatus.beatmapSaves) { beatmapSave.accuracy = 0.0f; beatmapSave.isFullCombo = false; beatmapSave.isAllPerfect = false; } } SaveSongStatuses(); } public SongStatusSave GetSongStatusSave(string songName) { if (songStatusSaves.TryGetValue(songName, out SongStatusSave save)) { return save; } Debug.LogWarning("Song status save for " + songName + " does not exist."); return null; } } public partial class StorySaveModule { public Dictionary> tutorialBlockSaves; public Dictionary> songBlockSaves; public Dictionary> dialogBlockSaves; public Dictionary> connectorSaves; public Dictionary storyVariables; public Dictionary selectedChoices; private string GetStorySavePath(string chapterName) => Application.persistentDataPath + "/StorySaves/" + chapterName + ".json"; private string StoryVariablesPath => Application.persistentDataPath + "/StorySaves/StoryVariables.json"; private string ChoicesPath => Application.persistentDataPath + "/StorySaves/Choices.json"; public StorySaveModule() { tutorialBlockSaves = new Dictionary>(); songBlockSaves = new Dictionary>(); dialogBlockSaves = new Dictionary>(); connectorSaves = new Dictionary>(); storyVariables = new Dictionary(); selectedChoices = new Dictionary(); Debug.Log("Story Variables path: " + StoryVariablesPath); } } public partial class StorySaveModule { public bool IsNewStoryline(string chapterName) { return !ES3.FileExists(GetStorySavePath(chapterName)); } public void LoadStoryline(string chapterName) { tutorialBlockSaves[chapterName] = ES3.Load>("TutorialBlockSaves", GetStorySavePath(chapterName)); songBlockSaves[chapterName] = ES3.Load>("SongBlockSaves", GetStorySavePath(chapterName)); dialogBlockSaves[chapterName] = ES3.Load>("TextBlockSaves", GetStorySavePath(chapterName)); connectorSaves[chapterName] = ES3.Load>("BlockConnectorSaves", GetStorySavePath(chapterName)); } public void SaveStoryline(string chapterName, List tutorialBlocks, List songBlocks, List dialogBlocks, List connectors) { ES3.Save("TutorialBlockSaves", tutorialBlocks, GetStorySavePath(chapterName)); ES3.Save("SongBlockSaves", songBlocks, GetStorySavePath(chapterName)); ES3.Save("TextBlockSaves", dialogBlocks, GetStorySavePath(chapterName)); ES3.Save("BlockConnectorSaves", connectors, GetStorySavePath(chapterName)); SaveStoryVariables(); SaveChoices(); } public void ClearAllStoryline() { string path = GetStorySavePath("Chapter0"); if (ES3.FileExists(path)) { ES3.DeleteFile(path); Debug.Log("Cleared all story saves at: " + path); } else { Debug.LogWarning("No story saves found at: " + path); } } } public partial class StorySaveModule { public void SaveStoryVariables() { string path = Application.persistentDataPath + "/StorySaves/" + "StoryVariables.json"; ES3.Save("StoryVariables", storyVariables, path); } public void LoadStoryVariables() { string path = Application.persistentDataPath + "/StorySaves/" + "StoryVariables.json"; if (ES3.FileExists(path)) { storyVariables = ES3.Load>("StoryVariables", path); } else { storyVariables = new Dictionary(); } } public void SaveChoices() { string path = Application.persistentDataPath + "/StorySaves/" + "Choices.json"; ES3.Save("Choices", selectedChoices, path); } public void LoadChoices() { string path = Application.persistentDataPath + "/StorySaves/" + "Choices.json"; if (ES3.FileExists(path)) { selectedChoices = ES3.Load>("Choices", path); } else { selectedChoices = new Dictionary(); } } } }