IEnumerator LoadGame(SaveData_v1 saveData) { // Must have a serializable player if (!serializablePlayer) { yield break; } // Immediately set date so world is loaded with correct season RestoreDateTimeData(saveData.dateAndTime); // Must have PlayerEnterExit to respawn player at saved location PlayerEnterExit playerEnterExit = serializablePlayer.GetComponent <PlayerEnterExit>(); if (!playerEnterExit) { yield break; } // Check exterior doors are included in save, we need these to exit building bool hasExteriorDoors; if (saveData.playerData.playerPosition.exteriorDoors == null || saveData.playerData.playerPosition.exteriorDoors.Length == 0) { hasExteriorDoors = false; } else { hasExteriorDoors = true; } // Raise reposition flag if terrain sampler changed // This is required as changing terrain samplers will invalidate serialized player coordinates bool repositionPlayer = false; if (saveData.playerData.playerPosition.terrainSamplerName != DaggerfallUnity.Instance.TerrainSampler.ToString() || saveData.playerData.playerPosition.terrainSamplerVersion != DaggerfallUnity.Instance.TerrainSampler.Version) { repositionPlayer = true; if (DaggerfallUI.Instance.DaggerfallHUD != null) { DaggerfallUI.Instance.DaggerfallHUD.PopupText.AddText("Terrain sampler changed. Repositioning player."); } } // Raise reposition flag if player is supposed to start indoors but building has no doors if (saveData.playerData.playerPosition.insideBuilding && !hasExteriorDoors) { repositionPlayer = true; if (DaggerfallUI.Instance.DaggerfallHUD != null) { DaggerfallUI.Instance.DaggerfallHUD.PopupText.AddText("Building has no exterior doors. Repositioning player."); } } // Start the respawn process based on saved player location if (saveData.playerData.playerPosition.insideDungeon && !repositionPlayer) { // Start in dungeon playerEnterExit.RespawnPlayer( saveData.playerData.playerPosition.worldPosX, saveData.playerData.playerPosition.worldPosZ, true); } else if (saveData.playerData.playerPosition.insideBuilding && hasExteriorDoors && !repositionPlayer) { // Start in building playerEnterExit.RespawnPlayer( saveData.playerData.playerPosition.worldPosX, saveData.playerData.playerPosition.worldPosZ, saveData.playerData.playerPosition.insideDungeon, saveData.playerData.playerPosition.insideBuilding, saveData.playerData.playerPosition.exteriorDoors); } else { // Start outside playerEnterExit.RespawnPlayer( saveData.playerData.playerPosition.worldPosX, saveData.playerData.playerPosition.worldPosZ, false, false, null, repositionPlayer); } // Keep yielding frames until world is ready again while (playerEnterExit.IsRespawning) { yield return(new WaitForEndOfFrame()); } // Wait another frame so everthing has a chance to register yield return(new WaitForEndOfFrame()); // Restore save data to objects in newly spawned world RestoreSaveData(saveData); // Raise OnLoad event RaiseOnLoadEvent(saveData); }
IEnumerator LoadGame(string saveName, string path) { GameManager.Instance.PlayerDeath.ClearDeathAnimation(); GameManager.Instance.PlayerMotor.CancelMovement = true; InputManager.Instance.ClearAllActions(); // Read save data from files string saveDataJson = ReadSaveFile(Path.Combine(path, saveDataFilename)); // Deserialize JSON strings SaveData_v1 saveData = Deserialize(typeof(SaveData_v1), saveDataJson) as SaveData_v1; // Must have a serializable player if (!serializablePlayer) { yield break; } // Immediately set date so world is loaded with correct season RestoreDateTimeData(saveData.dateAndTime); // Must have PlayerEnterExit to respawn player at saved location PlayerEnterExit playerEnterExit = serializablePlayer.GetComponent <PlayerEnterExit>(); if (!playerEnterExit) { yield break; } // Check exterior doors are included in save, we need these to exit building bool hasExteriorDoors; if (saveData.playerData.playerPosition.exteriorDoors == null || saveData.playerData.playerPosition.exteriorDoors.Length == 0) { hasExteriorDoors = false; } else { hasExteriorDoors = true; } // Raise reposition flag if terrain sampler changed // This is required as changing terrain samplers will invalidate serialized player coordinates bool repositionPlayer = false; if (saveData.playerData.playerPosition.terrainSamplerName != DaggerfallUnity.Instance.TerrainSampler.ToString() || saveData.playerData.playerPosition.terrainSamplerVersion != DaggerfallUnity.Instance.TerrainSampler.Version) { repositionPlayer = true; if (DaggerfallUI.Instance.DaggerfallHUD != null) { DaggerfallUI.Instance.DaggerfallHUD.PopupText.AddText("Terrain sampler changed. Repositioning player."); } } // Raise reposition flag if player is supposed to start indoors but building has no doors if (saveData.playerData.playerPosition.insideBuilding && !hasExteriorDoors) { repositionPlayer = true; if (DaggerfallUI.Instance.DaggerfallHUD != null) { DaggerfallUI.Instance.DaggerfallHUD.PopupText.AddText("Building has no exterior doors. Repositioning player."); } } // Start the respawn process based on saved player location if (saveData.playerData.playerPosition.insideDungeon && !repositionPlayer) { // Start in dungeon playerEnterExit.RespawnPlayer( saveData.playerData.playerPosition.worldPosX, saveData.playerData.playerPosition.worldPosZ, true); } else if (saveData.playerData.playerPosition.insideBuilding && hasExteriorDoors && !repositionPlayer) { // Start in building playerEnterExit.RespawnPlayer( saveData.playerData.playerPosition.worldPosX, saveData.playerData.playerPosition.worldPosZ, saveData.playerData.playerPosition.insideDungeon, saveData.playerData.playerPosition.insideBuilding, saveData.playerData.playerPosition.exteriorDoors); } else { // Start outside playerEnterExit.RespawnPlayer( saveData.playerData.playerPosition.worldPosX, saveData.playerData.playerPosition.worldPosZ, false, false, null, repositionPlayer); } // Smash to black while respawning DaggerfallUI.Instance.SmashHUDToBlack(); // Keep yielding frames until world is ready again while (playerEnterExit.IsRespawning) { yield return(new WaitForEndOfFrame()); } // Wait another frame so everthing has a chance to register yield return(new WaitForEndOfFrame()); // Restore save data to objects in newly spawned world RestoreSaveData(saveData); // Load automap state try { string automapDataJson = ReadSaveFile(Path.Combine(path, automapDataFilename)); Dictionary <string, DaggerfallAutomap.AutomapGeometryDungeonState> automapState = null; if (!string.IsNullOrEmpty(automapDataJson)) { automapState = Deserialize(typeof(Dictionary <string, DaggerfallAutomap.AutomapGeometryDungeonState>), automapDataJson) as Dictionary <string, DaggerfallAutomap.AutomapGeometryDungeonState>; } if (automapState != null) { GameManager.Instance.Automap.SetState(automapState); } } catch (Exception ex) { string message = string.Format("Failed to load automap state. Message: {0}", ex.Message); Debug.Log(message); } // Lower load in progress flag loadInProgress = false; // Fade out from black DaggerfallUI.Instance.FadeHUDFromBlack(1.5f); // Raise OnLoad event RaiseOnLoadEvent(saveData); }