/// <summary> /// Reads a attack/armor entry list member from the given buffer. /// The modification flag is read also. /// </summary> /// <param name="buffer">The buffer where the member shall be read from.</param> /// <param name="member">The member where the read data shall be stored.</param> protected static void ReadMember(IORAMHelper.RAMBuffer buffer, AttackArmorEntryListDiffElement member) { // Member must be defined if (member == null) { return; } // Read member if modified if (buffer.ReadByte() == 1) { // Read entries int count = buffer.ReadInteger(); List <AttackArmorEntry> entries = new List <AttackArmorEntry>(count); for (int i = 0; i < count; ++i) { entries.Add(new AttackArmorEntry ( buffer.ReadUShort(), buffer.ReadUShort() )); } member.Value = new EquatableObservableCollection <AttackArmorEntry>(entries); } }
/// <summary> /// Saves the given attack/armor entry list member into the given buffer. /// The modification flag is written also. /// </summary> /// <param name="buffer">The buffer for the member to written to.</param> /// <param name="member">The member to be written.</param> protected static void SaveMember(IORAMHelper.RAMBuffer buffer, AttackArmorEntryListDiffElement member) { // Member must be defined if (member == null) { return; } // Write modification flag buffer.WriteByte((byte)(member.Modified ? 1 : 0)); // Write member if (member.Modified) { // Write count buffer.WriteInteger(member.Value.Count); // Write members foreach (AttackArmorEntry aae in member.Value) { // Write member fields buffer.WriteUShort(aae.ArmorClass); buffer.WriteUShort(aae.Amount); } } }
private void _exportDatButton_Click(object sender, RoutedEventArgs e) { // Show save file dialog var saveFileDialog = new System.Windows.Forms.SaveFileDialog { Filter = "Genie database files (*.dat)|*.dat", Title = "Export DAT file..." }; if (saveFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) { return; } // Catch errors on export process try { // Reload internal genie file, apply changes and save GenieLibrary.GenieFile exportFile = new GenieLibrary.GenieFile(GenieLibrary.GenieFile.DecompressData(new IORAMHelper.RAMBuffer(_currentFileSelectionWindow.BaseGenieFilePath))); BalancingFile.WriteChangesToGenieFile(exportFile); IORAMHelper.RAMBuffer exportFileBuffer = new IORAMHelper.RAMBuffer(); exportFile.WriteData(exportFileBuffer); GenieLibrary.GenieFile.CompressData(exportFileBuffer).Save(saveFileDialog.FileName); } catch (IOException ex) { // Error MessageBox.Show($"Unable to export modified DAT file: {ex.Message}"); } }
/// <summary> /// Saves the whole research entry into the given buffer. /// </summary> /// <param name="buffer">The buffer for the members to written to.</param> public void Save(IORAMHelper.RAMBuffer buffer) { // Write members SaveMember(buffer, ResearchTime); SaveMember(buffer, Cost1); SaveMember(buffer, Cost2); SaveMember(buffer, Cost3); }
/// <summary> /// Reads the whole research entry from the given buffer. /// </summary> /// <param name="buffer">The buffer containing the research entry data.</param> public void Read(IORAMHelper.RAMBuffer buffer) { // Reset counter ModifiedFieldsCount = 0; // Read members ReadMember(buffer, ResearchTime); ReadMember(buffer, Cost1); ReadMember(buffer, Cost2); ReadMember(buffer, Cost3); }
/// <summary> /// Reads a short member from the given buffer. /// The modification flag is read also. /// </summary> /// <param name="buffer">The buffer where the member shall be read from.</param> /// <param name="member">The member where the read data shall be stored.</param> protected static void ReadMember(IORAMHelper.RAMBuffer buffer, DiffElement <short> member) { // Member must be defined if (member == null) { return; } // Read member if modified if (buffer.ReadByte() == 1) { member.Value = buffer.ReadShort(); } }
/// <summary> /// Reads a resource cost member from the given buffer. /// The modification flag is read also. /// </summary> /// <param name="buffer">The buffer where the member shall be read from.</param> /// <param name="member">The member where the read data shall be stored.</param> protected static void ReadMember(IORAMHelper.RAMBuffer buffer, DiffElement <ResourceCostEntry> member) { // Member must be defined if (member == null) { return; } // Read member if modified if (buffer.ReadByte() == 1) { member.Value = new ResourceCostEntry(buffer.ReadShort(), buffer.ReadShort(), buffer.ReadByte()); } }
/// <summary> /// Writes the mapping data into the given buffer. /// </summary> /// <param name="buffer">The buffer the mapping data shall be written to.</param> public void WriteData(IORAMHelper.RAMBuffer buffer) { buffer.Write(Hash); buffer.WriteInteger(UnitMapping.Count); foreach (var m in UnitMapping) { buffer.WriteShort(m.Key); buffer.WriteShort(m.Value); } buffer.WriteInteger(ResearchMapping.Count); foreach (var m in ResearchMapping) { buffer.WriteShort(m.Key); buffer.WriteShort(m.Value); } }
/// <summary> /// Saves the given floating point member into the given buffer. /// The modification flag is written also. /// </summary> /// <param name="buffer">The buffer for the member to written to.</param> /// <param name="member">The member to be written.</param> protected static void SaveMember(IORAMHelper.RAMBuffer buffer, DiffElement <float> member) { // Member must be defined if (member == null) { return; } // Write modification flag buffer.WriteByte((byte)(member.Modified ? 1 : 0)); // Write member if (member.Modified) { buffer.WriteFloat(member); } }
/// <summary> /// Reads the whole unit entry from the given buffer. /// </summary> /// <param name="buffer">The buffer containing the unit entry data.</param> public void Read(IORAMHelper.RAMBuffer buffer) { // Reset counter ModifiedFieldsCount = 0; // Read members ReadMember(buffer, HitPoints); ReadMember(buffer, Speed); ReadMember(buffer, RotationSpeed); ReadMember(buffer, LineOfSight); ReadMember(buffer, SearchRadius); ReadMember(buffer, MinRange); ReadMember(buffer, MaxRange); ReadMember(buffer, DisplayedRange); ReadMember(buffer, ReloadTime); ReadMember(buffer, DisplayedReloadTime); ReadMember(buffer, BlastRadius); ReadMember(buffer, Attacks); ReadMember(buffer, DisplayedAttack); ReadMember(buffer, ProjectileCount); ReadMember(buffer, ProjectileCountOnFullGarrison); ReadMember(buffer, ProjectileFrameDelay); ReadMember(buffer, ProjectileAccuracyPercent); ReadMember(buffer, ProjectileDispersion); ReadMember(buffer, ProjectileGraphicDisplacementX); ReadMember(buffer, ProjectileGraphicDisplacementY); ReadMember(buffer, ProjectileGraphicDisplacementZ); ReadMember(buffer, ProjectileSpawningAreaWidth); ReadMember(buffer, ProjectileSpawningAreaHeight); ReadMember(buffer, ProjectileSpawningAreaRandomness); ReadMember(buffer, Armors); ReadMember(buffer, DisplayedMeleeArmor); ReadMember(buffer, DisplayedPierceArmor); ReadMember(buffer, GarrisonCapacity); ReadMember(buffer, GarrisonHealRateFactor); ReadMember(buffer, TrainTime); ReadMember(buffer, Cost1); ReadMember(buffer, Cost2); ReadMember(buffer, Cost3); }
/// <summary> /// Saves the given resource cost member into the given buffer. /// The modification flag is written also. /// </summary> /// <param name="buffer">The buffer for the member to written to.</param> /// <param name="member">The member to be written.</param> protected static void SaveMember(IORAMHelper.RAMBuffer buffer, ResourceCostEntryDiffElement member) { // Member must be defined if (member == null) { return; } // Write modification flag buffer.WriteByte((byte)(member.Modified ? 1 : 0)); // Write member if (member.Modified) { // Write member fields buffer.WriteShort(member.Value.ResourceType); buffer.WriteShort(member.Value.Amount); buffer.WriteByte(member.Value.Paid); } }
/// <summary> /// Reads mapping data from the given buffer. /// </summary> /// <param name="buffer">The buffer containing the mapping data.</param> public MappingFile(IORAMHelper.RAMBuffer buffer) { // Read hash Hash = buffer.ReadByteArray(16); // 128 Bit = 16 Byte // Read unit IDs int count = buffer.ReadInteger(); UnitMapping = new Dictionary <short, short>(count); for (int i = 0; i < count; ++i) { UnitMapping.Add(buffer.ReadShort(), buffer.ReadShort()); } // Read research IDs count = buffer.ReadInteger(); ResearchMapping = new Dictionary <short, short>(count); for (int i = 0; i < count; ++i) { ResearchMapping.Add(buffer.ReadShort(), buffer.ReadShort()); } }
/// <summary> /// Saves the balancing file at the given path. /// </summary> /// <param name="path">The path where the balancing file shall be saved.</param> public void Save(string path) { // Create buffer IORAMHelper.RAMBuffer buffer = new IORAMHelper.RAMBuffer(); // Write version buffer.WriteInteger(Version); // Write mapping data, if existing if (_mappingFile == null) { buffer.WriteByte(0); } else { buffer.WriteByte(1); _mappingFile.WriteData(buffer); } // Run through unit list and save unit entries int unitEntryCount = 0; int unitEntryCountOffset = buffer.Position; buffer.WriteInteger(unitEntryCount); // Placeholder foreach (KeyValuePair <short, UnitEntry> ue in UnitEntries) { // Are there any changes? => Omit units with no modifications if (ue.Value.ModifiedFieldsCount == 0) { continue; } // Save ID buffer.WriteShort(ue.Key); // Save entry data ue.Value.Save(buffer); ++unitEntryCount; } // Run through research list and save research entries int researchEntryCount = 0; int researchEntryCountOffset = buffer.Position; buffer.WriteInteger(researchEntryCount); // Placeholder foreach (KeyValuePair <short, ResearchEntry> re in ResearchEntries) { // Are there any changes? => Omit researches with no modifications if (re.Value.ModifiedFieldsCount == 0) { continue; } // Save ID buffer.WriteShort(re.Key); // Save entry data re.Value.Save(buffer); ++researchEntryCount; } // Write unit entry count buffer.Position = unitEntryCountOffset; buffer.WriteInteger(unitEntryCount); // Write research entry count buffer.Position = researchEntryCountOffset; buffer.WriteInteger(researchEntryCount); // Save buffer buffer.Save(path); }
/// <summary> /// Loads the balancing file at the given path. /// </summary> /// <param name="genieFile">The genie file containing the base values the diffs are build upon.</param> /// <param name="path">The path to the balancing file.</param> /// <param name="languageFiles">The language DLL files, sorted by priority, descending. Used for proper name retrieval.</param> /// <param name="mappingFile">Optional. ID mapping file.</param> public BalancingFile(GenieLibrary.GenieFile genieFile, string path, string[] languageFiles, MappingFile mappingFile = null) : this(genieFile, languageFiles) { // Load file into buffer IORAMHelper.RAMBuffer buffer = new IORAMHelper.RAMBuffer(path); // Check version int version = buffer.ReadInteger(); if (version > Version) { throw new ArgumentException("The given file was created with a newer version of this program, please consider updating."); } // Check for embedded mapping file, and create ID conversion functions if necessary Func <short, short> ConvertUnitId = null; Func <short, short> ConvertResearchId = null; MappingFile embeddedMapping = null; if (buffer.ReadByte() == 1) { // Read embedded file embeddedMapping = new MappingFile(buffer); if (mappingFile == null || mappingFile.Hash.SequenceEqual(embeddedMapping.Hash)) { // Use embedded file, no conversion required _mappingFile = embeddedMapping; ConvertUnitId = (id) => id; ConvertResearchId = (id) => id; } else { // Use new mapping file, create conversion functions (old DAT ID -> Editor ID -> new DAT ID) _mappingFile = mappingFile; ConvertUnitId = (id) => _mappingFile.UnitMapping.FirstOrDefault(m => m.Value == embeddedMapping.UnitMapping[id]).Key; ConvertResearchId = (id) => _mappingFile.ResearchMapping.FirstOrDefault(m => m.Value == embeddedMapping.ResearchMapping[id]).Key; } } else if (mappingFile != null) { throw new ArgumentException("A mapping cannot be added to an existing file. Create a new balancing file instead."); } // Read unit entries int unitEntryCount = buffer.ReadInteger(); for (int i = 0; i < unitEntryCount; ++i) { // Read entry and merge with existing entry short unitId = ConvertUnitId(buffer.ReadShort()); UnitEntries[unitId].Read(buffer); } // Read research entries int researchEntryCount = buffer.ReadInteger(); for (int i = 0; i < researchEntryCount; ++i) { // Read entry and merge with existing entry short researchId = ConvertResearchId(buffer.ReadShort()); ResearchEntries[researchId].Read(buffer); } }