/// <summary>
        /// Opens the save game index specified.
        /// </summary>
        /// <param name="save">Save index</param>
        /// <returns>True if successful.</returns>
        public bool OpenSave(int save)
        {
            if (!HasSave(save))
            {
                return(false);
            }

            if (!LoadSaveImage(save))
            {
                throw new Exception("Could not open SaveImage for index " + save);
            }

            if (!LoadSaveName(save))
            {
                throw new Exception("Could not open SaveName for index " + save);
            }

            saveTree = new SaveTree();
            if (!saveTree.Open(Path.Combine(saveGameDict[save], SaveTree.Filename)))
            {
                throw new Exception("Could not open SaveTree for index " + save);
            }

            saveVars = new SaveVars();
            if (!saveVars.Open(Path.Combine(saveGameDict[save], SaveVars.Filename)))
            {
                throw new Exception("Could not open SaveVars for index " + save);
            }

            return(true);
        }
Example #2
0
        /// <summary>
        /// Opens the save game index specified.
        /// </summary>
        /// <param name="save">Save index</param>
        /// <param name="loadingInGame">True if the save game is being loaded for regular play, false if loading for Save Explorer.</param>
        /// <returns>True if successful.</returns>
        public bool OpenSave(int save, bool loadingInGame = true)
        {
            if (!HasSave(save))
            {
                return(false);
            }

            if (!LoadSaveImage(save))
            {
                throw new Exception("Could not open SaveImage for index " + save);
            }

            if (!LoadSaveName(save))
            {
                throw new Exception("Could not open SaveName for index " + save);
            }

            saveTree = new SaveTree();
            if (!saveTree.Open(Path.Combine(saveGameDict[save], SaveTree.Filename)))
            {
                throw new Exception("Could not open SaveTree for index " + save);
            }

            saveVars = new SaveVars();
            if (!saveVars.Open(Path.Combine(saveGameDict[save], SaveVars.Filename)))
            {
                throw new Exception("Could not open SaveVars for index " + save);
            }

            mapSave = new BsaFile();
            if (!mapSave.Load(Path.Combine(saveGameDict[save], "MAPSAVE.SAV"), FileUsage.UseMemory, true))
            {
                throw new Exception("Could not open MapSave for index " + save);
            }

            if (loadingInGame) // Only check MAPSAVE if loading in-game, not if viewing in Save Explorer. There is a noticeable delay for
                               // Save Explorer as the classic saves are loaded, and a null exception if the Save Explorer is opened
                               // without the game running in the editor, due to PlayerGPS.dfUnity not being instantiated.
                               // Save Explorer currently has no use for MAPSAVE data. This code should be revisited (speed up MAPSAVE processing,
                               // fix null exception, remove this bool check) if MAPSAVE-related functionality is added to Save Explorer.
            {
                PlayerGPS gps = GameManager.Instance.PlayerGPS;
                gps.ClearDiscoveryData();
                for (int regionIndex = 0; regionIndex < 62; regionIndex++)
                {
                    // Generate name from region index
                    string name = string.Format("MAPSAVE.{0:000}", regionIndex);

                    // Get record index
                    int index = mapSave.GetRecordIndex(name);
                    if (index == -1)
                    {
                        return(false);
                    }

                    // Read MAPSAVE data
                    byte[] data = mapSave.GetRecordBytes(index);

                    // Parse MAPSAVE data for discovered locations
                    DFRegion regionData    = DaggerfallUnity.Instance.ContentReader.MapFileReader.GetRegion(regionIndex);
                    int      locationCount = Math.Min(data.Length, (int)regionData.LocationCount);
                    for (int i = 0; i < locationCount; i++)
                    {
                        // If a location is marked as discovered in classic but not DF Unity, discover it for DF Unity
                        if ((data[i] & 0x40) != 0 && !regionData.MapTable[i].Discovered)
                        {
                            DFLocation location = DaggerfallUnity.Instance.ContentReader.MapFileReader.GetLocation(regionIndex, i);
                            gps.DiscoverLocation(regionData.Name, location.Name);
                        }
                    }
                }
            }

            rumorFile = new RumorFile();
            if (!rumorFile.Load(Path.Combine(saveGameDict[save], "RUMOR.DAT"), FileUsage.UseMemory, true))
            {
                UnityEngine.Debug.Log("Could not open RUMOR.DAT for index " + save);
            }

            for (int i = 0; i < rumorFile.rumors.Count; i++)
            {
                GameManager.Instance.TalkManager.ImportClassicRumor(rumorFile.rumors[i]);
            }

            bioFile = new BioFile();
            if (!bioFile.Load(Path.Combine(saveGameDict[save], "BIO.DAT")))
            {
                UnityEngine.Debug.Log("Could not open BIO.DAT for index " + save);
            }

            return(true);
        }
        void OnGUI()
        {
            if (!IsReady())
            {
                EditorGUILayout.HelpBox("DaggerfallUnity instance not ready. Have you set your Arena2 path?", MessageType.Info);
                return;
            }

            if (selectedSave != lastSelectedSave || currentSaveTree == null)
            {
                currentSaveTree = saveTrees[selectedSave];
                currentSaveVars = saveVars[selectedSave];
                if (currentSaveTree == null || currentSaveVars == null)
                    return;

                currentItems = currentSaveTree.FindRecords(RecordTypes.Item).ToArray();

                // Merge savetree faction data
                factionDict = factionFile.Merge(currentSaveVars);

                lastSelectedSave = selectedSave;
            }

            if (saveTrees != null && saveTrees.Length > 0)
            {
                DisplaySaveSelectGUI();
                DisplaySaveImageGUI();
                DisplaySaveStatsGUI();
                DisplaySaveCharacterGUI();

                scrollPos = GUILayoutHelper.ScrollView(scrollPos, () =>
                {
                    EditorGUILayout.Space();
                    showFactionsFoldout = GUILayoutHelper.Foldout(showFactionsFoldout, new GUIContent("Factions"), () =>
                    {
                        GUILayoutHelper.Indent(() =>
                        {
                            DisplayFactionsFoldout();
                        });
                    });

                    EditorGUILayout.Space();
                    showItemsFoldout = GUILayoutHelper.Foldout(showItemsFoldout, new GUIContent("Items"), () =>
                    {
                        GUILayoutHelper.Indent(() =>
                        {
                            DisplayItemsFoldout();
                        });
                    });

                    EditorGUILayout.Space();
                    showSaveTreeFoldout = GUILayoutHelper.Foldout(showSaveTreeFoldout, new GUIContent("SaveTree"), () =>
                    {
                        EditorGUILayout.HelpBox("Temporarily Filtering out records of type UnknownTownLink and UnknownItemRecord to keep list manageable.", MessageType.Info);

                        DisplaySaveTree(currentSaveTree.RootRecord);
                    });
                });
            }
        }
Example #4
0
        /// <summary>
        /// Opens the save game index specified.
        /// </summary>
        /// <param name="save">Save index</param>
        /// <returns>True if successful.</returns>
        public bool OpenSave(int save)
        {
            if (!HasSave(save))
            {
                return(false);
            }

            if (!LoadSaveImage(save))
            {
                throw new Exception("Could not open SaveImage for index " + save);
            }

            if (!LoadSaveName(save))
            {
                throw new Exception("Could not open SaveName for index " + save);
            }

            saveTree = new SaveTree();
            if (!saveTree.Open(Path.Combine(saveGameDict[save], SaveTree.Filename)))
            {
                throw new Exception("Could not open SaveTree for index " + save);
            }

            saveVars = new SaveVars();
            if (!saveVars.Open(Path.Combine(saveGameDict[save], SaveVars.Filename)))
            {
                throw new Exception("Could not open SaveVars for index " + save);
            }

            mapSave = new BsaFile();
            if (!mapSave.Load(Path.Combine(saveGameDict[save], "MAPSAVE.SAV"), FileUsage.UseMemory, true))
            {
                throw new Exception("Could not open MapSave for index " + save);
            }

            PlayerGPS gps = GameManager.Instance.PlayerGPS;

            gps.ClearDiscoveryData();
            for (int regionIndex = 0; regionIndex < 62; regionIndex++)
            {
                // Generate name from region index
                string name = string.Format("MAPSAVE.{0:000}", regionIndex);

                // Get record index
                int index = mapSave.GetRecordIndex(name);
                if (index == -1)
                {
                    return(false);
                }

                // Read MAPSAVE data
                byte[] data = mapSave.GetRecordBytes(index);

                // Parse MAPSAVE data for discovered locations
                DFRegion regionData = DaggerfallUnity.Instance.ContentReader.MapFileReader.GetRegion(regionIndex);
                for (int i = 0; i < regionData.LocationCount; i++)
                {
                    if ((data[i] & 0x40) != 0)
                    {
                        // Discover the location in DF Unity's data
                        if (regionData.MapTable[i].Discovered == false)
                        {
                            DFLocation location = DaggerfallUnity.Instance.ContentReader.MapFileReader.GetLocation(regionIndex, i);
                            gps.DiscoverLocation(regionData.Name, location.Name);
                        }
                    }
                }
            }

            return(true);
        }
        /// <summary>
        /// Opens the save game index specified.
        /// </summary>
        /// <param name="save">Save index</param>
        /// <returns>True if successful.</returns>
        public bool OpenSave(int save)
        {
            if (!HasSave(save))
                return false;

            if (!LoadSaveImage(save))
                throw new Exception("Could not open SaveImage for index " + save);

            if (!LoadSaveName(save))
                throw new Exception("Could not open SaveName for index " + save);

            saveTree = new SaveTree();
            if (!saveTree.Open(Path.Combine(saveGameDict[save], SaveTree.Filename)))
                throw new Exception("Could not open SaveTree for index " + save);

            saveVars = new SaveVars();
            if (!saveVars.Open(Path.Combine(saveGameDict[save], SaveVars.Filename)))
                throw new Exception("Could not open SaveVars for index " + save);

            return true;
        }
        /// <summary>
        /// Merges faction data from savevars into a new faction dictionary.
        /// Does not affect factions as read from FACTIONS.TXT.
        /// This resultant set of factions is the character's live faction setup.
        /// This is only used when importing a classic save.
        /// Daggerfall Unity uses a different method of storing faction data with saves.
        /// </summary>
        /// <param name="saveVars"></param>
        public Dictionary<int, FactionData> Merge(SaveVars saveVars)
        {
            // Create clone of base faction dictionary
            Dictionary<int, FactionData> dict = new Dictionary<int, FactionData>();
            foreach (var kvp in factionDict)
            {
                dict.Add(kvp.Key, kvp.Value);
            }

            // Merge save faction data from savevars
            FactionData[] factions = saveVars.Factions;
            foreach(var srcFaction in factions)
            {
                if (dict.ContainsKey(srcFaction.id))
                {
                    FactionData dstFaction = dict[srcFaction.id];

                    // First a quick sanity check to ensure IDs are the same
                    if (dstFaction.id != srcFaction.id)
                        throw new Exception(string.Format("ID mismatch while merging faction data. SrcFaction=#{0}, DstFaction=#{1}", srcFaction.id, dstFaction.id));

                    // Copy live data from SAVEVARS.DAT
                    dstFaction.type = srcFaction.type;
                    dstFaction.name = srcFaction.name;
                    dstFaction.rep = srcFaction.rep;
                    dstFaction.region = srcFaction.region;
                    dstFaction.power = srcFaction.power;
                    dstFaction.flags = srcFaction.flags;
                    dstFaction.ruler = srcFaction.ruler;
                    dstFaction.ally1 = srcFaction.ally1;
                    dstFaction.ally2 = srcFaction.ally2;
                    dstFaction.ally3 = srcFaction.ally3;
                    dstFaction.enemy1 = srcFaction.enemy1;
                    dstFaction.enemy2 = srcFaction.enemy2;
                    dstFaction.enemy3 = srcFaction.enemy3;
                    dstFaction.face = srcFaction.face;
                    dstFaction.race = srcFaction.race;
                    dstFaction.flat1 = srcFaction.flat1;
                    dstFaction.flat2 = srcFaction.flat2;
                    dstFaction.sgroup = srcFaction.sgroup;
                    dstFaction.ggroup = srcFaction.ggroup;
                    dstFaction.vam = srcFaction.vam;

                    // Store data back in new dictionary
                    dict[srcFaction.id] = dstFaction;
                }
            }

            return dict;
        }