Пример #1
0
        private dynamic ReadDefinition(BinaryReader reader)
        {
            switch (type)
            {
            case field_type._field_block:
                return(reader.ReadFieldDefinition <TagBlockDefinition>(this));

            case field_type._field_struct:
                return(reader.ReadFieldDefinition <tag_struct_definition>(this));

            case field_type._field_char_enum:
            case field_type._field_enum:
            case field_type._field_long_enum:
            case field_type._field_byte_flags:
            case field_type._field_word_flags:
            case field_type._field_long_flags:
                return(reader.ReadFieldDefinition <enum_definition>(this));

            case field_type._field_tag_reference:
                return(reader.ReadFieldDefinition <tag_reference_definition>(this));

            case field_type._field_data:
                return(reader.ReadFieldDefinition <tag_data_definition>(this));

            case field_type._field_explanation:
            {
                var value = Guerilla.ReadString(reader, definition);
                return(value);
            }

            default:
                return(definition);
            }
        }
Пример #2
0
        public void Read(IntPtr h2LangLib, BinaryReader reader)
        {
            // Read all the fields from the stream.
            this.type         = (field_type)reader.ReadInt16();
            this.padding      = reader.ReadInt16();
            this.name_address = reader.ReadInt32();
            this.definition   = reader.ReadInt32();
            this.group_tag    = reader.ReadInt32();

            // Read Properties
            this.Name       = Guerilla.ReadString(reader, this.name_address);
            this.Definition = ReadDefinition(reader);
        }
Пример #3
0
        public MoonfishTagDefinition(TagBlockDefinition definition)
            : this()
        {
            Name                = definition.Name;
            DisplayName         = definition.DisplayName;
            MaximumElementCount = definition.maximum_element_count;
            Alignment           = definition.LatestFieldSet.Alignment;

            var definitionFields = definition.LatestFieldSet.Fields;

            Fields = new List <MoonfishTagField>(definitionFields.Count);
            foreach (var field in definitionFields)
            {
                var moonfishField = new MoonfishTagField((MoonfishFieldType)field.type, field.Name);

                moonfishField.AssignCount(field.definition);

                if (field.Definition is TagBlockDefinition)
                {
                    var fieldDefinition = (TagBlockDefinition)field.Definition;
                    moonfishField.AssignDefinition(new MoonfishTagDefinition(fieldDefinition));
                }
                if (field.Definition is enum_definition)
                {
                    var fieldDefinition = (enum_definition)field.Definition;
                    moonfishField.AssignDefinition(new MoonfishTagEnumDefinition(fieldDefinition));
                }
                if (field.Definition is tag_struct_definition)
                {
                    var fieldDefinition = (tag_struct_definition)field.Definition;
                    moonfishField.AssignDefinition(new MoonfishTagStruct(fieldDefinition));
                }
                if (field.Definition is tag_data_definition)
                {
                    var fieldDefinition = (tag_data_definition)field.Definition;
                    moonfishField.AssignDefinition(new MoonfishTagDataDefinition(fieldDefinition));
                }
                if (field.Definition is tag_reference_definition)
                {
                    var fieldDefinition = (tag_reference_definition)field.Definition;
                    moonfishField.AssignDefinition(new MoonfishTagReferenceDefinition(fieldDefinition));
                }
                if (field.Definition is string)
                {
                    moonfishField.AssignDefinition((string)field.Definition);
                }

                Fields.Add(moonfishField);
            }
            Fields = new List <MoonfishTagField>(Guerilla.PostProcess(Name, Fields));
        }
Пример #4
0
        private void ProcessFields(IList <tag_field> fields, ElementArray elementArray, ref int i, ref int offset)
        {
            for (; i < fields.Count; ++i)
            {
                var field = fields[i];
                // Check the field type.
                switch (field.type)
                {
                case field_type._field_block:
                {
                    var childElementArray = ProcessTagBlockDefinition(elementArray, field.Definition, ref offset);
                    elementArray.Children.Add(childElementArray);
                    break;
                }

                case field_type._field_struct:
                {
                    var struct_definition = (tag_struct_definition)field.Definition;
                    var structOffset      = offset;
                    var childElementArray = ProcessTagStructDefinition(elementArray, struct_definition.Definition, ref structOffset);
                    elementArray.Children.AddRange(childElementArray);

                    break;
                }

                case field_type._field_data:
                {
                    var data_definition   = (tag_data_definition)field.Definition;
                    var childElementArray = new ElementArray()
                    {
                        ElementSize = 1, Name = data_definition.Name, Address = offset, Parent = elementArray, Alignment = data_definition.Alignment
                    };
                    elementArray.Children.Add(childElementArray);
                    break;
                }

                case field_type._field_array_start:
                {
                    ProcessArrayFields(fields, elementArray, ref field, ref i, ref offset);
                    break;
                }

                case field_type._field_array_end:
                {
                    return;
                }
                }
                offset += Guerilla.CalculateSizeOfField(field);
            }
        }
Пример #5
0
        public void Read(BinaryReader reader)
        {
            // Read all the fields from the stream.
            nameAddress              = reader.ReadInt32();
            flags                    = reader.ReadInt32();
            alignmentBit             = reader.ReadInt32();
            maximumSize              = reader.ReadInt32();
            maximumSizeStringAddress = reader.ReadInt32();
            byteswapFunction         = reader.ReadInt32();
            copyFunction             = reader.ReadInt32();

            // Read the strings.
            name = Guerilla.ReadString(reader, nameAddress);
            maximum_size_string = Guerilla.ReadString(reader, maximumSizeStringAddress);
        }
Пример #6
0
        public tag_field_set(BinaryReader reader, Action <BinaryReader, IList <tag_field> > postprocessFunction = null)
            : this()
        {
            version              = reader.ReadFieldDefinition <s_tag_field_set_version>();
            size                 = reader.ReadInt32();
            alignment_bit        = reader.ReadInt32();
            parent_version_index = reader.ReadInt32();
            fields_address       = reader.ReadInt32();
            size_string_address  = reader.ReadInt32();

            // Read the size_of string.
            size_string = Guerilla.ReadString(reader, size_string_address);

            ReadFields(reader, postprocessFunction);
        }
Пример #7
0
        public void Read(IntPtr h2LangLib, BinaryReader reader)
        {
            // Read all the fields from the stream.
            this.nameAddress              = reader.ReadInt32();
            this.flags                    = reader.ReadInt32();
            this.alignmentBit             = reader.ReadInt32();
            this.maximumSize              = reader.ReadInt32();
            this.maximumSizeStringAddress = reader.ReadInt32();
            this.byteswapFunction         = reader.ReadInt32();
            this.copyFunction             = reader.ReadInt32();

            // Read the strings.
            this.name = Guerilla.ReadString(reader, this.nameAddress);
            this.maximum_size_string = Guerilla.ReadString(reader, this.maximumSizeStringAddress);
        }
Пример #8
0
        public tag_struct_definition(BinaryReader reader)
            : this()
        {
            // Read all the fields from the stream.
            name_address             = reader.ReadInt32();
            group_tag                = reader.ReadInt32();
            display_name_address     = reader.ReadInt32();
            block_definition_address = reader.ReadInt32();

            displayName = Guerilla.ReadString(reader, display_name_address);
            name        = Guerilla.ReadString(reader, name_address);

            reader.BaseStream.Seek(block_definition_address, SeekOrigin.Begin);
            Definition = reader.ReadFieldDefinition <TagBlockDefinition>();
        }
Пример #9
0
        public void Read(BinaryReader reader)
        {
            // Read all the fields from the stream.
            type = (field_type)reader.ReadInt16();
            if (type == field_type._field_rgb_color)
            {
            }
            padding      = reader.ReadInt16();
            name_address = reader.ReadInt32();
            definition   = reader.ReadInt32();
            group_tag    = reader.ReadInt32();

            // Read Properties
            Name       = Guerilla.ReadString(reader, name_address);
            Definition = ReadDefinition(reader);
        }
Пример #10
0
        public tag_group(BinaryReader reader)
            : this()
        {
            var stream = reader.BaseStream;

            this.name_address     = reader.ReadInt32();
            this.flags            = reader.ReadInt32();
            this.group_tag        = reader.ReadInt32();
            this.parent_group_tag = reader.ReadInt32();
            this.version          = reader.ReadInt16();
            this.initialized      = reader.ReadByte();

            stream.Seek(1, SeekOrigin.Current);

            this.postprocess_proc          = reader.ReadInt32();
            this.save_postprocess_proc     = reader.ReadInt32();
            this.postprocess_for_sync_proc = reader.ReadInt32();

            stream.Seek(4, SeekOrigin.Current);

            this.definition_address = reader.ReadInt32();
            this.child_group_tags   = new int[16];
            for (int i = 0; i < 16; i++)
            {
                this.child_group_tags[i] = reader.ReadInt32();
            }
            this.childs_count = reader.ReadInt16();

            stream.Seek(2, SeekOrigin.Current);

            this.default_tag_path_address = reader.ReadInt32();


            this.text = Guerilla.ReadString(reader, this.name_address);

            DefaultPath = Guerilla.ReadString(reader, this.default_tag_path_address);
            stream.Seek(this.definition_address, SeekOrigin.Begin);
            if (Class.ToString() == "snd!")
            {
                Definition = reader.ReadFieldDefinition <TagBlockDefinition>();
            }
            else
            {
                Definition = reader.ReadFieldDefinition <TagBlockDefinition>();
            }
        }
Пример #11
0
        public void Read(BinaryReader reader)
        {
            // Read all the fields from the stream.
            option_count    = reader.ReadInt32();
            options_address = reader.ReadInt32();
            flags           = reader.ReadInt32();

            Options = new List <string>(option_count);
            for (var i = 0; i < option_count; ++i)
            {
                // Seek to the next option name address.
                reader.BaseStream.Position = options_address + (i * 4);

                // Read the string from the stream.
                int string_address = reader.ReadInt32();
                var option         = Guerilla.ReadString(reader, string_address);
                Options.Add(option);
            }
        }
Пример #12
0
        private IEnumerable <ElementArray> ProcessTagStructDefinition(ElementArray parent, TagBlockDefinition definition, ref int offset)
        {
            var size = Guerilla.CalculateSizeOfFieldSet(definition.LatestFieldSet.Fields);

            var blockElementArray = new ElementArray()
            {
                Name            = definition.Name,
                ElementSize     = size,
                Address         = offset,
                Parent          = parent,
                MaxElementCount = definition.maximum_element_count,
                Alignment       = definition.LatestFieldSet.Alignment,
            };

            var i = 0;

            ProcessFields(definition.LatestFieldSet.Fields, blockElementArray, ref i, ref offset);
            return(blockElementArray.Children);
        }
Пример #13
0
        private void Read(BinaryReader reader)
        {
            var stream = reader.BaseStream;

            nameAddress    = reader.ReadInt32();
            flags          = reader.ReadInt32();
            groupTag       = reader.ReadInt32();
            parentGroupTag = reader.ReadInt32();
            version        = reader.ReadInt16();
            initialized    = reader.ReadByte();

            stream.Seek(1, SeekOrigin.Current);

            postprocessProc        = reader.ReadInt32();
            savePostprocessProc    = reader.ReadInt32();
            postprocessForSyncProc = reader.ReadInt32();

            stream.Seek(4, SeekOrigin.Current);

            definitionAddress = reader.ReadInt32();
            childGroupTags    = new int[16];
            for (var i = 0; i < 16; i++)
            {
                childGroupTags[i] = reader.ReadInt32();
            }
            childsCount = reader.ReadInt16();

            stream.Seek(2, SeekOrigin.Current);

            defaultTagPathAddress = reader.ReadInt32();


            Name = Guerilla.ReadString(reader, nameAddress);

            DefaultPath = Guerilla.ReadString(reader, defaultTagPathAddress);
            stream.Seek(definitionAddress, SeekOrigin.Begin);
            Definition = reader.ReadFieldDefinition <TagBlockDefinition>();
        }
Пример #14
0
        private ElementArray ProcessTagBlockDefinition(ElementArray parent, TagBlockDefinition tagBlock, ref int offset, bool inline = false, string group_tag = "")
        {
            var size = Guerilla.CalculateSizeOfFieldSet(tagBlock.LatestFieldSet.Fields);

            var blockElementArray = new ElementArray()
            {
                Name            = tagBlock.Name,
                ElementSize     = size,
                Address         = offset,
                Parent          = parent,
                MaxElementCount = tagBlock.maximum_element_count,
                Alignment       = tagBlock.LatestFieldSet.Alignment,
            };

            var i           = 0;
            int blockOffset = inline ? offset : 0;

            ProcessFields(tagBlock.LatestFieldSet.Fields, blockElementArray, ref i, ref blockOffset);
            if (inline)
            {
                offset = blockOffset;
            }
            return(blockElementArray);
        }
Пример #15
0
        public GuerillaToEnt(string guerillaExecutablePath)
            : base(guerillaExecutablePath)
        {
            valueTypeDictionary = new Dictionary <field_type, Tuple <Type, int> >();
            valueTypeDictionary.Add(field_type._field_angle, new Tuple <Type, int>(typeof(float), 1));
            valueTypeDictionary.Add(field_type._field_angle_bounds, new Tuple <Type, int>(typeof(float), 2));
            valueTypeDictionary.Add(field_type._field_argb_color, new Tuple <Type, int>(typeof(byte), 4));
            valueTypeDictionary.Add(field_type._field_array_end, new Tuple <Type, int>(null, 0));
            valueTypeDictionary.Add(field_type._field_array_start, new Tuple <Type, int>(null, 0));
            valueTypeDictionary.Add(field_type._field_block, new Tuple <Type, int>(null, 8));
            valueTypeDictionary.Add(field_type._field_byte_block_flags, new Tuple <Type, int>(typeof(byte), 1));
            valueTypeDictionary.Add(field_type._field_byte_flags, new Tuple <Type, int>(typeof(byte), 1));
            valueTypeDictionary.Add(field_type._field_char_block_index1, new Tuple <Type, int>(typeof(byte), 1));
            valueTypeDictionary.Add(field_type._field_char_block_index2, new Tuple <Type, int>(typeof(byte), 1));
            valueTypeDictionary.Add(field_type._field_char_enum, new Tuple <Type, int>(typeof(byte), 1));
            valueTypeDictionary.Add(field_type._field_char_integer, new Tuple <Type, int>(typeof(byte), 1));
            valueTypeDictionary.Add(field_type._field_custom, new Tuple <Type, int>(null, 0));
            valueTypeDictionary.Add(field_type._field_data, new Tuple <Type, int>(typeof(byte), 8));
            valueTypeDictionary.Add(field_type._field_enum, new Tuple <Type, int>(typeof(short), 1));
            valueTypeDictionary.Add(field_type._field_explanation, new Tuple <Type, int>(null, 0));
            valueTypeDictionary.Add(field_type._field_long_block_flags, new Tuple <Type, int>(typeof(int), 1));
            valueTypeDictionary.Add(field_type._field_long_block_index1, new Tuple <Type, int>(typeof(int), 1));
            valueTypeDictionary.Add(field_type._field_long_block_index2, new Tuple <Type, int>(typeof(int), 1));
            valueTypeDictionary.Add(field_type._field_long_enum, new Tuple <Type, int>(typeof(int), 1));
            valueTypeDictionary.Add(field_type._field_long_flags, new Tuple <Type, int>(typeof(int), 1));
            valueTypeDictionary.Add(field_type._field_long_integer, new Tuple <Type, int>(typeof(int), 1));
            valueTypeDictionary.Add(field_type._field_long_string, new Tuple <Type, int>(typeof(byte), 256));
            valueTypeDictionary.Add(field_type._field_old_string_id, new Tuple <Type, int>(typeof(Moonfish.Tags.StringID), 1));
            valueTypeDictionary.Add(field_type._field_point_2d, new Tuple <Type, int>(typeof(short), 2));
            valueTypeDictionary.Add(field_type._field_real, new Tuple <Type, int>(typeof(float), 1));
            valueTypeDictionary.Add(field_type._field_real_ahsv_color, new Tuple <Type, int>(typeof(float), 4));
            valueTypeDictionary.Add(field_type._field_real_argb_color, new Tuple <Type, int>(typeof(float), 4));
            valueTypeDictionary.Add(field_type._field_real_bounds, new Tuple <Type, int>(typeof(float), 2));
            valueTypeDictionary.Add(field_type._field_real_euler_angles_2d, new Tuple <Type, int>(typeof(float), 2));
            valueTypeDictionary.Add(field_type._field_real_euler_angles_3d, new Tuple <Type, int>(typeof(float), 3));
            valueTypeDictionary.Add(field_type._field_real_fraction, new Tuple <Type, int>(typeof(float), 1));
            valueTypeDictionary.Add(field_type._field_real_fraction_bounds, new Tuple <Type, int>(typeof(float), 2));
            valueTypeDictionary.Add(field_type._field_real_hsv_color, new Tuple <Type, int>(typeof(float), 3));
            valueTypeDictionary.Add(field_type._field_real_plane_2d, new Tuple <Type, int>(typeof(float), 3));
            valueTypeDictionary.Add(field_type._field_real_plane_3d, new Tuple <Type, int>(typeof(float), 4));
            valueTypeDictionary.Add(field_type._field_real_point_2d, new Tuple <Type, int>(typeof(float), 2));
            valueTypeDictionary.Add(field_type._field_real_point_3d, new Tuple <Type, int>(typeof(float), 3));
            valueTypeDictionary.Add(field_type._field_real_quaternion, new Tuple <Type, int>(typeof(float), 4));
            valueTypeDictionary.Add(field_type._field_real_rgb_color, new Tuple <Type, int>(typeof(float), 3));
            valueTypeDictionary.Add(field_type._field_real_vector_2d, new Tuple <Type, int>(typeof(float), 2));
            valueTypeDictionary.Add(field_type._field_real_vector_3d, new Tuple <Type, int>(typeof(float), 3));
            valueTypeDictionary.Add(field_type._field_rectangle_2d, new Tuple <Type, int>(typeof(short), 4));
            valueTypeDictionary.Add(field_type._field_rgb_color, new Tuple <Type, int>(typeof(byte), 3));
            valueTypeDictionary.Add(field_type._field_short_block_index1, new Tuple <Type, int>(typeof(short), 1));
            valueTypeDictionary.Add(field_type._field_short_block_index2, new Tuple <Type, int>(typeof(short), 1));
            valueTypeDictionary.Add(field_type._field_short_bounds, new Tuple <Type, int>(typeof(short), 2));
            valueTypeDictionary.Add(field_type._field_short_integer, new Tuple <Type, int>(typeof(short), 1));
            valueTypeDictionary.Add(field_type._field_string, new Tuple <Type, int>(typeof(byte), 32));
            valueTypeDictionary.Add(field_type._field_string_id, new Tuple <Type, int>(typeof(Moonfish.Tags.StringID), 1));
            valueTypeDictionary.Add(field_type._field_tag, new Tuple <Type, int>(typeof(byte), 4));
            valueTypeDictionary.Add(field_type._field_tag_reference, new Tuple <Type, int>(typeof(int), 2));
            valueTypeDictionary.Add(field_type._field_vertex_buffer, new Tuple <Type, int>(typeof(byte), 32));
            valueTypeDictionary.Add(field_type._field_word_block_flags, new Tuple <Type, int>(typeof(short), 1));
            valueTypeDictionary.Add(field_type._field_word_flags, new Tuple <Type, int>(typeof(short), 1));
            valueTypeDictionary.Add(field_type._field_terminator, new Tuple <Type, int>(null, 0));
            valueTypeDictionary.Add(field_type._field_useless_pad, new Tuple <Type, int>(null, 0));

            valueTypeDictionary.Add(field_type._field_moonfish_ident, new Tuple <Type, int>(typeof(int), 1));
            foreach (var value in valueTypeDictionary)
            {
                if (value.Value.Item1 == null)
                {
                    continue;
                }
                var fieldSize = Marshal.SizeOf(value.Value.Item1) * value.Value.Item2;
                if (Guerilla.GetFieldSize(value.Key) != fieldSize)
                {
                    throw new InvalidDataException();
                }
            }
        }
Пример #16
0
        public TagBlockDefinition(BinaryReader reader)
            : this()
        {
            // Read all the fields from the stream.
            this.display_name_address = reader.ReadInt32();
            this.name_address         = reader.ReadInt32();
            this.flags = reader.ReadInt32();
            this.maximum_element_count = reader.ReadInt32();
            this.maximum_element_count_string_address = reader.ReadInt32();
            this.field_sets_address       = reader.ReadInt32();
            this.field_set_count          = reader.ReadInt32();
            this.field_set_latest_address = reader.ReadInt32();
            reader.BaseStream.Position   += 4;
            this.postprocess_proc         = reader.ReadInt32();
            this.format_proc           = reader.ReadInt32();
            this.generate_default_proc = reader.ReadInt32();
            this.dispose_element_proc  = reader.ReadInt32();

            // Read the display name and name strings.
            this.display_name = Guerilla.ReadString(reader, this.display_name_address);
            this.name         = Guerilla.ReadString(reader, this.name_address);
            this.maximum_element_count_str = Guerilla.ReadString(reader, this.maximum_element_count_string_address);
            if (name == "sound_block")
            {
                this.field_sets_address = 0x957870;

                FieldSets = new List <tag_field_set>(1);
                var fieldSet = new tag_field_set();

                //definition.field_set_latest_address = 0x906178;
                fieldSet.version.fields_address = 0x906178;
                fieldSet.version.index          = 0;
                fieldSet.version.upgrade_proc   = 0;
                fieldSet.version.size_of        = -1;
                fieldSet.size                 = 172;
                fieldSet.alignment_bit        = 0;
                fieldSet.parent_version_index = -1;
                fieldSet.fields_address       = 0x906178;
                fieldSet.size_string_address  = 0x00795330;
                fieldSet.size_string          = "sizeof(sound_definition)";

                var definitionName = this.name;
                fieldSet.ReadFields(reader, Guerilla.PostprocessFunctions.Where(x => x.Key == definitionName).Select(x => x.Value).FirstOrDefault());
                LatestFieldSet = fieldSet;
                FieldSets.Add(fieldSet);
            }
            else
            {
                FieldSets = new List <tag_field_set>(field_set_count);
                var definitionName = this.name;
                var address        = field_sets_address;
                for (var i = 0; i < field_set_count; ++i)
                {
                    reader.BaseStream.Seek(address, SeekOrigin.Begin);
                    var fieldSet = new tag_field_set(reader);
                    FieldSets.Add(fieldSet);
                    address += tag_field_set.Size;
                }
                if (this.name == "sound_promotion_parameters_struct_block")
                {
                    LatestFieldSet = FieldSets[0];
                }
                else
                {
                    reader.BaseStream.Seek(this.field_set_latest_address, SeekOrigin.Begin);
                    var latestFieldSet = new tag_field_set(reader, Guerilla.PostprocessFunctions.Where(x => x.Key == definitionName).Select(x => x.Value).FirstOrDefault());
                    LatestFieldSet = latestFieldSet;
                }
            }
        }
Пример #17
0
 public new static string ToTypeName(string value)
 {
     return(Guerilla.ToTypeName(value));
 }
Пример #18
0
        public TagBlockDefinition(BinaryReader reader)
            : this()
        {
            // Read all the fields from the stream.
            display_name_address = reader.ReadInt32();
            name_address         = reader.ReadInt32();
            flags = reader.ReadInt32();
            maximum_element_count = reader.ReadInt32();
            maximum_element_count_string_address = reader.ReadInt32();
            field_sets_address          = reader.ReadInt32();
            field_set_count             = reader.ReadInt32();
            field_set_latest_address    = reader.ReadInt32();
            reader.BaseStream.Position += 4;
            postprocess_proc            = reader.ReadInt32();
            format_proc           = reader.ReadInt32();
            generate_default_proc = reader.ReadInt32();
            dispose_element_proc  = reader.ReadInt32();

            // Read the display name and name strings.
            display_name = Guerilla.ReadString(reader, display_name_address);
            name         = Guerilla.ReadString(reader, name_address);
            maximum_element_count_str = Guerilla.ReadString(reader, maximum_element_count_string_address);
            if (name == "sound_block")
            {
                field_sets_address       = 0x957870;
                field_set_latest_address = 0x906178;

                FieldSets = new List <tag_field_set>(1);
                var fieldSet = new tag_field_set
                {
                    version              = { fields_address = 0x906178, index = 0, upgrade_proc = 0, size_of = -1 },
                    size                 = 172,
                    alignment_bit        = 0,
                    parent_version_index = -1,
                    fields_address       = 0x906178,
                    size_string_address  = 0x00795330,
                    size_string          = "sizeof(sound_definition)"
                };


                var definitionName = name;
                fieldSet.ReadFields(reader,
                                    Guerilla.PostprocessFunctions.Where(x => x.Key == definitionName)
                                    .Select(x => x.Value)
                                    .FirstOrDefault());
                LatestFieldSet = fieldSet;
                FieldSets.Add(fieldSet);
            }
            else
            {
                FieldSets = new List <tag_field_set>(field_set_count);
                var definitionName = name;
                var address        = field_sets_address;
                for (var i = 0; i < field_set_count; ++i)
                {
                    reader.BaseStream.Seek(address, SeekOrigin.Begin);
                    var fieldSet = new tag_field_set(reader);
                    FieldSets.Add(fieldSet);
                    address += tag_field_set.Size;
                }
                switch (name)
                {
                case "materials_block":
                    LatestFieldSet = FieldSets[0];
                    if (LatestFieldSet.Fields.Count == 5)
                    {
                        name           = "phmo_materials_block";
                        definitionName = "phmo_materials_block";
                    }
                    break;

                case "hud_globals_block":
                    LatestFieldSet = FieldSets[0];
                    break;

                case "global_new_hud_globals_struct_block":
                    LatestFieldSet = FieldSets[0];
                    break;

                case "sound_promotion_parameters_struct_block":
                    LatestFieldSet = FieldSets[0];
                    break;

                case "animation_pool_block":
                    LatestFieldSet = FieldSets[4];
                    break;

                case "sound_gestalt_promotions_block":
                    LatestFieldSet = FieldSets[0];
                    break;

                case "sound_block":
                    LatestFieldSet = FieldSets[0];
                    break;

                case "tag_block_index_struct_block":
                    LatestFieldSet = FieldSets[0];
                    break;

                case "vertex_shader_classification_block":
                    LatestFieldSet = FieldSets[0];
                    break;

                default:
                    reader.BaseStream.Seek(field_set_latest_address, SeekOrigin.Begin);
                    var latestFieldSet = new tag_field_set(reader,
                                                           Guerilla.PostprocessFunctions.Where(x => x.Key == definitionName)
                                                           .Select(x => x.Value)
                                                           .FirstOrDefault());
                    LatestFieldSet = latestFieldSet;
                    break;
                }
            }
        }