/// <summary> /// Changes action record at specified position. /// </summary> /// <param name="blockName">Name of block file.</param> /// <param name="position">Start position of action record.</param> /// <param name="axis">Rotation axis.</param> /// <param name="duration">Duration of action.</param> /// <param name="magnitude">Magnitude of action.</param> public void ModActionRecord(string blockName, long position, byte axis, UInt16 duration, UInt16 magnitude) { // Load resources string path = Path.Combine(arena2Path, "BLOCKS.BSA"); BsaFile bsaFile = new BsaFile( path, FileUsage.UseDisk, false); // Get binary record int index = bsaFile.GetRecordIndex(blockName); byte[] buffer = bsaFile.GetRecordBytes(index); // Create stream to binary record MemoryStream ms = new MemoryStream(buffer); ms.Position = position; // Write new data BinaryWriter writer = new BinaryWriter(ms, Encoding.UTF8); writer.Write(axis); writer.Write(duration); writer.Write(magnitude); writer.Close(); // Save back binary record bsaFile.RewriteRecord(index, buffer); }
/// <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); }
/// <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); }