using UnityEngine; using UnityEngine.SceneManagement; public class GameStateManager : MonoBehaviour { public static GameStateManager Instance { get; private set; } [Header("Game State")] public bool hasActiveGame = false; public string currentSceneName = ""; public int gameVersion = 1; [Header("Team Data")] public TeamCharacter[] savedTeam = new TeamCharacter[4]; public bool teamSetupComplete = false; [Header("Progress Data")] public int currentLevel = 1; public int totalGoldEarned = 0; public int battlesWon = 0; public int battlesLost = 0; [Header("Map Data")] public bool hasGeneratedMap = false; public int mapSeed = 0; public int mapWidth = 100; public int mapHeight = 100; public float mapNoiseScale = 5f; public float mapOceanThreshold = 0.3f; public float mapMountainThreshold = 0.7f; public float mapForestThreshold = 0.5f; [Header("New Game Flags")] public bool isNewGame = false; // Flag to indicate this is a new game (not a load) private void Awake() { // Implement singleton pattern if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); // Restore new game flag from PlayerPrefs in case instance was recreated isNewGame = PlayerPrefs.GetInt("IsNewGame", 0) == 1; // Subscribe to scene loading events SceneManager.sceneLoaded += OnSceneLoaded; } else { Destroy(gameObject); } } private void OnDestroy() { if (Instance == this) { SceneManager.sceneLoaded -= OnSceneLoaded; } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { currentSceneName = scene.name; // Auto-save when moving between scenes (if we have an active game) if (hasActiveGame && currentSceneName != "TitleScreen") { AutoSave(); } } public void StartNewGame() { // Reset all game state hasActiveGame = true; teamSetupComplete = false; currentLevel = 1; totalGoldEarned = 0; battlesWon = 0; battlesLost = 0; // Clear team data savedTeam = new TeamCharacter[4]; // Clear map data hasGeneratedMap = false; mapSeed = Random.Range(0, 999999); // Set new game flag - this will force random team placement isNewGame = true; PlayerPrefs.SetInt("IsNewGame", 1); // Store in PlayerPrefs to persist across scenes PlayerPrefs.Save(); // Force immediate save // Clear any existing save data ClearSaveData(); // Mark that we have a new game started PlayerPrefs.SetInt("GameSaved", 1); PlayerPrefs.Save(); } public void SaveGame() { if (!hasActiveGame) { Debug.LogWarning("No active game to save!"); return; } // Save basic game state PlayerPrefs.SetInt("GameSaved", 1); PlayerPrefs.SetInt("GameVersion", gameVersion); PlayerPrefs.SetString("CurrentScene", currentSceneName); PlayerPrefs.SetInt("TeamSetupComplete", teamSetupComplete ? 1 : 0); PlayerPrefs.SetInt("CurrentLevel", currentLevel); PlayerPrefs.SetInt("TotalGoldEarned", totalGoldEarned); PlayerPrefs.SetInt("BattlesWon", battlesWon); PlayerPrefs.SetInt("BattlesLost", battlesLost); // Save team data SaveTeamData(); // Save map data SaveMapData(); PlayerPrefs.Save(); } public void LoadGame() { if (!PlayerPrefs.HasKey("GameSaved")) { Debug.LogWarning("No saved game found!"); return; } // Load basic game state hasActiveGame = true; gameVersion = PlayerPrefs.GetInt("GameVersion", 1); currentSceneName = PlayerPrefs.GetString("CurrentScene", "MainTeamSelectScene"); teamSetupComplete = PlayerPrefs.GetInt("TeamSetupComplete", 0) == 1; currentLevel = PlayerPrefs.GetInt("CurrentLevel", 1); totalGoldEarned = PlayerPrefs.GetInt("TotalGoldEarned", 0); battlesWon = PlayerPrefs.GetInt("BattlesWon", 0); battlesLost = PlayerPrefs.GetInt("BattlesLost", 0); // Clear new game flag - this is a load operation, use saved positions isNewGame = false; PlayerPrefs.SetInt("IsNewGame", 0); // Clear from PlayerPrefs too PlayerPrefs.Save(); // Force immediate save // Load team data LoadTeamData(); // Load map data LoadMapData(); } public void AutoSave() { if (hasActiveGame) { SaveGame(); } } public void SaveTeam(TeamCharacter[] team) { if (team == null) return; for (int i = 0; i < Mathf.Min(team.Length, savedTeam.Length); i++) { if (team[i] != null) { savedTeam[i] = team[i].CreateCopy(); } } teamSetupComplete = true; if (hasActiveGame) { SaveGame(); } } public TeamCharacter[] GetSavedTeam() { return savedTeam; } private void SaveTeamData() { for (int i = 0; i < savedTeam.Length; i++) { string prefix = $"Character{i}_"; if (savedTeam[i] != null) { PlayerPrefs.SetInt(prefix + "Exists", 1); PlayerPrefs.SetString(prefix + "Name", savedTeam[i].name); PlayerPrefs.SetInt(prefix + "IsMale", savedTeam[i].isMale ? 1 : 0); PlayerPrefs.SetInt(prefix + "Strength", savedTeam[i].strength); PlayerPrefs.SetInt(prefix + "Dexterity", savedTeam[i].dexterity); PlayerPrefs.SetInt(prefix + "Constitution", savedTeam[i].constitution); PlayerPrefs.SetInt(prefix + "Wisdom", savedTeam[i].wisdom); PlayerPrefs.SetInt(prefix + "Gold", savedTeam[i].gold); PlayerPrefs.SetInt(prefix + "Silver", savedTeam[i].silver); PlayerPrefs.SetInt(prefix + "Copper", savedTeam[i].copper); PlayerPrefs.SetString(prefix + "EquippedWeapon", savedTeam[i].equippedWeapon); PlayerPrefs.SetString(prefix + "EquippedArmor", savedTeam[i].equippedArmor); // Save inventory lists as comma-separated strings PlayerPrefs.SetString(prefix + "Weapons", string.Join(",", savedTeam[i].weapons)); PlayerPrefs.SetString(prefix + "Armor", string.Join(",", savedTeam[i].armor)); PlayerPrefs.SetString(prefix + "MiscItems", string.Join(",", savedTeam[i].miscItems)); } else { PlayerPrefs.SetInt(prefix + "Exists", 0); } } } private void LoadTeamData() { savedTeam = new TeamCharacter[4]; for (int i = 0; i < savedTeam.Length; i++) { string prefix = $"Character{i}_"; if (PlayerPrefs.GetInt(prefix + "Exists", 0) == 1) { savedTeam[i] = new TeamCharacter(); savedTeam[i].name = PlayerPrefs.GetString(prefix + "Name", ""); savedTeam[i].isMale = PlayerPrefs.GetInt(prefix + "IsMale", 1) == 1; savedTeam[i].strength = PlayerPrefs.GetInt(prefix + "Strength", 10); savedTeam[i].dexterity = PlayerPrefs.GetInt(prefix + "Dexterity", 10); savedTeam[i].constitution = PlayerPrefs.GetInt(prefix + "Constitution", 10); savedTeam[i].wisdom = PlayerPrefs.GetInt(prefix + "Wisdom", 10); savedTeam[i].gold = PlayerPrefs.GetInt(prefix + "Gold", 25); savedTeam[i].silver = PlayerPrefs.GetInt(prefix + "Silver", 0); savedTeam[i].copper = PlayerPrefs.GetInt(prefix + "Copper", 0); savedTeam[i].equippedWeapon = PlayerPrefs.GetString(prefix + "EquippedWeapon", ""); savedTeam[i].equippedArmor = PlayerPrefs.GetString(prefix + "EquippedArmor", ""); // Load inventory lists string weaponsStr = PlayerPrefs.GetString(prefix + "Weapons", ""); string armorStr = PlayerPrefs.GetString(prefix + "Armor", ""); string miscStr = PlayerPrefs.GetString(prefix + "MiscItems", ""); savedTeam[i].weapons = new System.Collections.Generic.List(); savedTeam[i].armor = new System.Collections.Generic.List(); savedTeam[i].miscItems = new System.Collections.Generic.List(); if (!string.IsNullOrEmpty(weaponsStr)) savedTeam[i].weapons.AddRange(weaponsStr.Split(',')); if (!string.IsNullOrEmpty(armorStr)) savedTeam[i].armor.AddRange(armorStr.Split(',')); if (!string.IsNullOrEmpty(miscStr)) savedTeam[i].miscItems.AddRange(miscStr.Split(',')); } } } private void ClearSaveData() { // Clear main save indicators PlayerPrefs.DeleteKey("GameSaved"); PlayerPrefs.DeleteKey("GameVersion"); PlayerPrefs.DeleteKey("CurrentScene"); PlayerPrefs.DeleteKey("TeamSetupComplete"); PlayerPrefs.DeleteKey("CurrentLevel"); PlayerPrefs.DeleteKey("TotalGoldEarned"); PlayerPrefs.DeleteKey("BattlesWon"); PlayerPrefs.DeleteKey("BattlesLost"); // Note: We DON'T clear "IsNewGame" here because it should persist until team placement is done // Clear team data for (int i = 0; i < 4; i++) { string prefix = $"Character{i}_"; PlayerPrefs.DeleteKey(prefix + "Exists"); PlayerPrefs.DeleteKey(prefix + "Name"); PlayerPrefs.DeleteKey(prefix + "IsMale"); PlayerPrefs.DeleteKey(prefix + "Strength"); PlayerPrefs.DeleteKey(prefix + "Dexterity"); PlayerPrefs.DeleteKey(prefix + "Constitution"); PlayerPrefs.DeleteKey(prefix + "Wisdom"); PlayerPrefs.DeleteKey(prefix + "Gold"); PlayerPrefs.DeleteKey(prefix + "Silver"); PlayerPrefs.DeleteKey(prefix + "Copper"); PlayerPrefs.DeleteKey(prefix + "EquippedWeapon"); PlayerPrefs.DeleteKey(prefix + "EquippedArmor"); PlayerPrefs.DeleteKey(prefix + "Weapons"); PlayerPrefs.DeleteKey(prefix + "Armor"); PlayerPrefs.DeleteKey(prefix + "MiscItems"); } // Clear map data PlayerPrefs.DeleteKey("MapSeed"); PlayerPrefs.DeleteKey("MapWidth"); PlayerPrefs.DeleteKey("MapHeight"); PlayerPrefs.DeleteKey("MapNoiseScale"); PlayerPrefs.DeleteKey("MapOceanThreshold"); PlayerPrefs.DeleteKey("MapMountainThreshold"); PlayerPrefs.DeleteKey("MapForestThreshold"); PlayerPrefs.DeleteKey("HasGeneratedMap"); PlayerPrefs.Save(); } // Method to check if we're currently in a game public bool IsInGame() { return hasActiveGame && currentSceneName != "TitleScreen"; } // Method to return to title screen public void ReturnToTitle() { SceneManager.LoadScene("TitleScreen"); } private void SaveMapData() { PlayerPrefs.SetInt("MapSeed", mapSeed); PlayerPrefs.SetInt("MapWidth", mapWidth); PlayerPrefs.SetInt("MapHeight", mapHeight); PlayerPrefs.SetFloat("MapNoiseScale", mapNoiseScale); PlayerPrefs.SetFloat("MapOceanThreshold", mapOceanThreshold); PlayerPrefs.SetFloat("MapMountainThreshold", mapMountainThreshold); PlayerPrefs.SetFloat("MapForestThreshold", mapForestThreshold); PlayerPrefs.SetInt("HasGeneratedMap", hasGeneratedMap ? 1 : 0); } private void LoadMapData() { mapSeed = PlayerPrefs.GetInt("MapSeed", Random.Range(0, 999999)); mapWidth = PlayerPrefs.GetInt("MapWidth", 100); mapHeight = PlayerPrefs.GetInt("MapHeight", 100); mapNoiseScale = PlayerPrefs.GetFloat("MapNoiseScale", 5f); mapOceanThreshold = PlayerPrefs.GetFloat("MapOceanThreshold", 0.3f); mapMountainThreshold = PlayerPrefs.GetFloat("MapMountainThreshold", 0.7f); mapForestThreshold = PlayerPrefs.GetFloat("MapForestThreshold", 0.5f); hasGeneratedMap = PlayerPrefs.GetInt("HasGeneratedMap", 0) == 1; } public void GenerateNewMap() { mapSeed = Random.Range(0, 999999); hasGeneratedMap = true; SaveMapData(); } public bool HasSavedMap() { return PlayerPrefs.HasKey("MapSeed"); } /// /// Check if this is a new game that should force random team placement /// public bool IsNewGameForceRandom() { // Check both the instance variable and PlayerPrefs in case of timing issues bool instanceFlag = isNewGame; bool playerPrefsFlag = PlayerPrefs.GetInt("IsNewGame", 0) == 1; bool result = instanceFlag || playerPrefsFlag; return result; } /// /// Clear the new game flag after initial team placement is complete /// public void ClearNewGameFlag() { isNewGame = false; PlayerPrefs.SetInt("IsNewGame", 0); // Clear from PlayerPrefs too PlayerPrefs.Save(); } }