/// <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());
            }
        }
예제 #8
0
 /// <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);
            }
        }
예제 #12
0
        /// <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());
            }
        }
예제 #13
0
        /// <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);
        }
예제 #14
0
        /// <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);
            }
        }