Пример #1
0
        void TeleportPlayer()
        {
            // Validate references
            if (!serializablePlayer || !playerEnterExit)
            {
                return;
            }

            // Get anchor position from player entity
            anchorPosition = GameManager.Instance.PlayerEntity.AnchorPosition;

            // Is player in same interior as anchor?
            if (IsSameInterior())
            {
                // Just need to move player
                serializablePlayer.RestorePosition(anchorPosition);
            }
            else
            {
                // When teleporting to interior anchor, restore world compensation height early before initworld
                // Ensures exterior world level is aligned with building height at time of anchor
                // Only works with floating origin v3 saves and above with both serialized world compensation and context
                if (anchorPosition.worldContext == WorldContext.Interior)
                {
                    GameManager.Instance.StreamingWorld.RestoreWorldCompensationHeight(anchorPosition.worldCompensation.y);
                }
                else
                {
                    GameManager.Instance.StreamingWorld.RestoreWorldCompensationHeight(0);
                }

                // Cache scene before departing
                if (!playerEnterExit.IsPlayerInside)
                {
                    SaveLoadManager.CacheScene(GameManager.Instance.StreamingWorld.SceneName);      // Player is outside
                }
                else if (playerEnterExit.IsPlayerInsideBuilding)
                {
                    SaveLoadManager.CacheScene(playerEnterExit.Interior.name);                      // Player inside a building
                }
                else // Player inside a dungeon
                {
                    playerEnterExit.TransitionDungeonExteriorImmediate();
                }

                // Need to load some other part of the world again - player could be anywhere
                PlayerEnterExit.OnRespawnerComplete += PlayerEnterExit_OnRespawnerComplete;
                playerEnterExit.RestorePositionHelper(anchorPosition, false, true);

                // Restore building summary data
                if (anchorPosition.insideBuilding)
                {
                    playerEnterExit.BuildingDiscoveryData = anchorPosition.buildingDiscoveryData;
                }

                // When moving anywhere other than same interior trigger a fade so transition appears smoother
                DaggerfallUI.Instance.FadeBehaviour.FadeHUDFromBlack();
            }
        }
Пример #2
0
        void TeleportPlayer()
        {
            // Validate references
            if (!serializablePlayer || !playerEnterExit)
            {
                return;
            }

            // Is player in same interior as anchor?
            if (IsSameInterior())
            {
                // Just need to move player
                serializablePlayer.RestorePosition(anchorPosition);
                return;
            }
            else
            {
                // Cache scene before departing
                if (!playerEnterExit.IsPlayerInside)
                {
                    SaveLoadManager.CacheScene(GameManager.Instance.StreamingWorld.SceneName);      // Player is outside
                }
                else if (playerEnterExit.IsPlayerInsideBuilding)
                {
                    SaveLoadManager.CacheScene(playerEnterExit.Interior.name);                      // Player inside a building
                }
                else // Player inside a dungeon
                {
                    playerEnterExit.TransitionDungeonExteriorImmediate();
                }

                // Need to load some other part of the world again - player could be anywhere
                PlayerEnterExit.OnRespawnerComplete += PlayerEnterExit_OnRespawnerComplete;
                playerEnterExit.RestorePositionHelper(anchorPosition, false, true);

                // Restore building summary data
                if (anchorPosition.insideBuilding)
                {
                    playerEnterExit.BuildingDiscoveryData = anchorPosition.buildingDiscoveryData;
                }

                // When moving anywhere other than same interior trigger a fade so transition appears smoother
                DaggerfallUI.Instance.FadeBehaviour.FadeHUDFromBlack();
            }

            // End and resign
            // Player will need to create a new teleport with a new anchor from here
            // This is same behaviour as classic
            forcedRoundsRemaining = 0;
            ResignAsIncumbent();
            anchorSet = false;
        }
        IEnumerator LoadGame(string path)
        {
            GameManager.Instance.PlayerDeath.ClearDeathAnimation();
            GameManager.Instance.PlayerMotor.CancelMovement = true;
            InputManager.Instance.ClearAllActions();
            QuestMachine.Instance.ClearState();
            stateManager.ClearSceneCache();
            PlayerEntity playerEntity = GameManager.Instance.PlayerEntity;

            playerEntity.Reset();

            // Read save data from files
            string saveDataJson         = ReadSaveFile(Path.Combine(path, saveDataFilename));
            string factionDataJson      = ReadSaveFile(Path.Combine(path, factionDataFilename));
            string questDataJson        = ReadSaveFile(Path.Combine(path, questDataFilename));
            string discoveryDataJson    = ReadSaveFile(Path.Combine(path, discoveryDataFilename));
            string conversationDataJson = ReadSaveFile(Path.Combine(path, conversationDataFilename));
            string notebookDataJson     = ReadSaveFile(Path.Combine(path, notebookDataFilename));

            // Load backstory text
            playerEntity.BackStory = new List <string>();
            if (File.Exists(Path.Combine(path, bioFileName)))
            {
                StreamReader file = new StreamReader(Path.Combine(path, bioFileName).ToString());
                string       line;
                while ((line = file.ReadLine()) != null)
                {
                    playerEntity.BackStory.Add(line);
                }
                file.Close();
            }

            // Deserialize JSON strings
            SaveData_v1 saveData = Deserialize(typeof(SaveData_v1), saveDataJson) as SaveData_v1;

            // Must have a serializable player
            if (!stateManager.SerializablePlayer)
            {
                yield break;
            }

            // Call start load event
            RaiseOnStartLoadEvent(saveData);

            // Immediately set date so world is loaded with correct season
            RestoreDateTimeData(saveData.dateAndTime);

            // Restore discovery data
            if (!string.IsNullOrEmpty(discoveryDataJson))
            {
                Dictionary <int, PlayerGPS.DiscoveredLocation> discoveryData =
                    Deserialize(typeof(Dictionary <int, PlayerGPS.DiscoveredLocation>), discoveryDataJson) as Dictionary <int, PlayerGPS.DiscoveredLocation>;
                GameManager.Instance.PlayerGPS.RestoreDiscoveryData(discoveryData);
            }
            else
            {
                // Clear discovery data when not in save, or live state will be retained from previous session
                GameManager.Instance.PlayerGPS.ClearDiscoveryData();
            }

            // Must have PlayerEnterExit to respawn player at saved location
            PlayerEnterExit playerEnterExit = stateManager.SerializablePlayer.GetComponent <PlayerEnterExit>();

            if (!playerEnterExit)
            {
                yield break;
            }

            // Restore building summary, house ownership, and guild membership early for interior layout code
            if (saveData.playerData.playerPosition.insideBuilding)
            {
                playerEnterExit.BuildingDiscoveryData  = saveData.playerData.playerPosition.buildingDiscoveryData;
                playerEnterExit.IsPlayerInsideOpenShop = saveData.playerData.playerPosition.insideOpenShop;
                if (saveData.bankDeeds != null)
                {
                    RestoreHousesData(saveData.bankDeeds.houses);
                }
                GameManager.Instance.GuildManager.RestoreMembershipData(saveData.playerData.guildMemberships);
            }

            // Restore faction data to player entity
            // This is done early as later objects may require faction information on restore
            if (!string.IsNullOrEmpty(factionDataJson))
            {
                FactionData_v2 factionData = Deserialize(typeof(FactionData_v2), factionDataJson) as FactionData_v2;
                stateManager.RestoreFactionData(factionData);
                Debug.Log("LoadGame() restored faction state from save.");
            }
            else
            {
                Debug.Log("LoadGame() did not find saved faction data. Player will resume with default faction state.");
            }

            // Restore quest machine state
            if (!string.IsNullOrEmpty(questDataJson))
            {
                QuestMachine.QuestMachineData_v1 questData = Deserialize(typeof(QuestMachine.QuestMachineData_v1), questDataJson) as QuestMachine.QuestMachineData_v1;
                QuestMachine.Instance.RestoreSaveData(questData);
            }

            // Restore conversation data (must be done after quest data restoration)
            if (!string.IsNullOrEmpty(conversationDataJson))
            {
                TalkManager.SaveDataConversation conversationData = Deserialize(typeof(TalkManager.SaveDataConversation), conversationDataJson) as TalkManager.SaveDataConversation;
                GameManager.Instance.TalkManager.RestoreConversationData(conversationData);
            }
            else
            {
                GameManager.Instance.TalkManager.RestoreConversationData(null);
            }

            // Restore notebook data
            if (!string.IsNullOrEmpty(notebookDataJson))
            {
                PlayerNotebook.NotebookData_v1 notebookData = Deserialize(typeof(PlayerNotebook.NotebookData_v1), notebookDataJson) as PlayerNotebook.NotebookData_v1;
                playerEntity.Notebook.RestoreNotebookData(notebookData);
            }

            // Restore player position to world
            playerEnterExit.RestorePositionHelper(saveData.playerData.playerPosition, true, false);

            //Restore Travel Map settings
            DaggerfallUI.Instance.DfTravelMapWindow.SetTravelMapFromSaveData(saveData.travelMapData);

            // Smash to black while respawning
            DaggerfallUI.Instance.FadeBehaviour.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, Automap.AutomapDungeonState> automapState = null;

                if (!string.IsNullOrEmpty(automapDataJson))
                {
                    automapState = Deserialize(typeof(Dictionary <string, Automap.AutomapDungeonState>), automapDataJson) as Dictionary <string, Automap.AutomapDungeonState>;
                }

                if (automapState != null)
                {
                    GameManager.Instance.InteriorAutomap.SetState(automapState);
                }
            }
            catch (Exception ex)
            {
                string message = string.Format("Failed to load automap state. Message: {0}", ex.Message);
                Debug.Log(message);
            }

            // Clear any orphaned quest items
            RemoveAllOrphanedItems();

            // Check mod manager is available
            if (ModManager.Instance != null)
            {
                // Restore mod data
                foreach (Mod mod in ModManager.Instance.GetAllModsWithSaveData())
                {
                    string modDataPath = Path.Combine(path, GetModDataFilename(mod));
                    object modData;
                    if (File.Exists(modDataPath))
                    {
                        modData = Deserialize(mod.SaveDataInterface.SaveDataType, ReadSaveFile(modDataPath));
                    }
                    else
                    {
                        modData = mod.SaveDataInterface.NewSaveData();
                    }
                    mod.SaveDataInterface.RestoreSaveData(modData);
                }
            }

            // Clamp legal reputation
            playerEntity.ClampLegalReputations();

            // Lower load in progress flag
            loadInProgress = false;

            // Fade out from black
            DaggerfallUI.Instance.FadeBehaviour.FadeHUDFromBlack(1.0f);

            // Raise OnLoad event
            RaiseOnLoadEvent(saveData);
        }