Dictionary <int, extended_meta> list_extended; //<mem_off,extended_meta obj>,a dictionary containing the extended meta by their memory address to prevent redundancy.

        /// <summary>
        /// use to read meta data from a map file
        /// </summary>
        /// <param name="datum_index">the datum index of the tag</param>
        /// <param name="sr">the path of the tag.eg: characters/elite/elite_mp</param>
        /// <param name="sr">the stream object</param>
        public meta(int datum_index, string path, StreamReader sr)
        {
            //initialise some stuff
            this.datum_index = datum_index;
            this.path        = path;
            map_stream       = sr;

            //some meta reading prologue
            int table_off    = DATA_READ.ReadINT_LE(0x10, map_stream);
            int table_size   = DATA_READ.ReadINT_LE(0x14, map_stream);
            int table_start  = table_off + 0xC * DATA_READ.ReadINT_LE(table_off + 4, map_stream) + 0x20;
            int scnr_off     = table_off + table_size;
            int scnr_memaddr = DATA_READ.ReadINT_LE(table_start + 0x8, map_stream);//scnr tag index is 0x0(mostly)

            //steps concerned with the specified meta
            type    = DATA_READ.ReadTAG_TYPE(table_start + (0xFFFF & datum_index) * 0x10, map_stream);
            mem_off = DATA_READ.ReadINT_LE(table_start + ((0xFFFF & datum_index) * 0x10) + 0x8, map_stream);

            size = DATA_READ.ReadINT_LE(table_start + ((0xFFFF & datum_index) * 0x10) + 0xC, map_stream);

            //read the meta from the map
            data = new byte[size];

            if (!DATA_READ.Check_shared(sr))
            {
                //normal map
                map_stream.BaseStream.Position = scnr_off + (mem_off - scnr_memaddr);
            }
            else
            {
                //shared map
                map_stream.BaseStream.Position = scnr_off + (mem_off - 0x3c000);
                //0x3c000 is a hardcoded value in blam engine
            }

            map_stream.BaseStream.Read(data, 0, size);

            //read and store the plugin structure
            plugin = DATA_READ.Get_Tag_stucture_from_plugin(type);

            //lets initialise some lists and dictionaries
            ref_data      = new List <int>();
            ref_tags      = new List <int>();
            ref_reflexive = new List <int>();
            ref_stringID  = new List <int>();
            ref_extended  = new Dictionary <int, int>();
            list_extended = new Dictionary <int, extended_meta>();
            ref_WCtags    = new List <int>();


            //now lets search for all kinds of stuff
            List_deps(0x0, plugin);
        }
        Dictionary <int, extended_meta> list_extended; //<mem_off,extended_meta obj>,a dictionary containing the extended meta by their memory address to prevent redundancy.

        /// <summary>
        /// extended meta is similar to the meta
        /// </summary>
        /// <param name="mem_address"></param>
        /// <param name="size">the total size of the extended meta containg all occurences</param>
        /// <param name="count"></param>
        /// <param name="plugin"></param>
        /// <param name="sr"></param>
        public extended_meta(int mem_address, int size, int count, plugins_field plugin, StreamReader sr)
        {
            this.mem_off    = mem_address;
            this.size       = size;
            this.plugin     = plugin;
            this.map_stream = sr;
            this.entry_size = size / count;

            //some meta reading prologue
            int table_off    = DATA_READ.ReadINT_LE(0x10, map_stream);
            int table_size   = DATA_READ.ReadINT_LE(0x14, map_stream);
            int table_start  = table_off + 0xC * DATA_READ.ReadINT_LE(table_off + 4, map_stream) + 0x20;
            int scnr_off     = table_off + table_size;
            int scnr_memaddr = DATA_READ.ReadINT_LE(table_start + 0x8, map_stream);//scnr tag index is 0x0(mostly)

            //read the extended_meta from the map
            data = new byte[this.size];

            if (!DATA_READ.Check_shared(sr))
            {
                //normal map
                map_stream.BaseStream.Position = scnr_off + (mem_off - scnr_memaddr);
            }
            else
            {
                //shared map
                map_stream.BaseStream.Position = scnr_off + (mem_off - 0x3c000);
                //0x3c000 is a hardcoded value in blam engine
            }

            map_stream.BaseStream.Read(data, 0, this.size);

            //lets initialise some lists and dictionaries
            ref_data      = new List <int>();
            ref_tags      = new List <int>();
            ref_stringID  = new List <int>();
            ref_reflexive = new List <int>();
            ref_extended  = new Dictionary <int, int>();
            list_extended = new Dictionary <int, extended_meta>();
            ref_WCtags    = new List <int>();

            //we we have loop through the extended meta stuff
            for (int i = 0; i < count; i++)
            {
                List_deps(i * entry_size, plugin);
            }
        }
        /// <summary>
        /// used to read meta data from a meta file along with ability to modify mem_off
        /// </summary>
        /// <param name="meta"></param>
        /// <param name="type"></param>
        /// <param name="size"></param>
        /// <param name="path"></param>
        /// <param name="mem_off"></param>
        public meta(byte[] meta, string type, int size, string path, int mem_off)
        {
            data         = meta;
            this.type    = type;
            this.size    = size;
            this.path    = path;
            this.mem_off = mem_off;//this is for awkward cases when i rebase the meta to some other shit

            //lets initialise some lists and dictionaries
            ref_data      = new List <int>();
            ref_tags      = new List <int>();
            ref_reflexive = new List <int>();
            ref_stringID  = new List <int>();
            ref_WCtags    = new List <int>();
            //while extracting the meta ,i fix all the extended meta stuff so we dont need it now

            plugin = DATA_READ.Get_Tag_stucture_from_plugin(type);

            List_deps(0x0, plugin);
        }
        /// <summary>
        /// used to read meta data from a meta file
        /// </summary>
        /// <param name="meta"></param>
        /// <param name="type"></param>
        /// <param name="size"></param>
        /// <param name="path"></param>
        public meta(byte[] meta, string type, int size, string path)
        {
            data         = meta;
            this.type    = type;
            this.size    = size;
            this.path    = path;
            this.mem_off = 0x0;//i usually rebase meta to 0x0 when extracting

            //lets initialise some lists and dictionaries
            ref_data      = new List <int>();
            ref_tags      = new List <int>();
            ref_reflexive = new List <int>();
            ref_stringID  = new List <int>();
            ref_WCtags    = new List <int>();
            //while extracting the meta ,i fix all the extended meta stuff so we dont need it now

            //plugin
            plugin = DATA_READ.Get_Tag_stucture_from_plugin(type);

            List_deps(0x0, plugin);
        }
 public void Add_field(plugins_field field)
 {
     reflexive.Add(field);
 }
        /// <summary>
        /// a function to fill in all the Lists and Dictionaries
        /// </summary>
        /// <param name="off">the starting offset where the stuff is being read</param>
        /// <param name="fields">the concerned field(s) in that section</param>
        void List_deps(int off, plugins_field fields)
        {
            List <int> temp = fields.Get_tag_ref_list();

            //first we look for tag_refs and add them
            foreach (int i in temp)
            {
                int Toff = off + i;//it contains type
                //we add this off to the list if it doesnt contain the off already
                if (!ref_tags.Contains(Toff))
                {
                    ref_tags.Add(Toff);
                }
            }
            //then we look for data_refs and add them
            temp = fields.Get_data_ref_list();
            foreach (int i in temp)
            {
                int Toff = off + i;
                //we add this off to the list if it doesnt contain the off already
                if (!ref_data.Contains(Toff))
                {
                    ref_data.Add(Toff);
                }
            }
            //then we look for stringId refs and add them
            temp = fields.Get_stringID_ref_list();
            foreach (int i in temp)
            {
                int Toff = off + i;
                //we add this off to the list if it doesnt contain the off already
                if (!ref_stringID.Contains(Toff))
                {
                    ref_stringID.Add(Toff);
                }
            }
            //now we look into reflexive fields and extended meta and add them accordingly
            List <plugins_field> Ptemp = fields.Get_reflexive_list();

            foreach (plugins_field i_Pfield in Ptemp)
            {
                int Toff = off + i_Pfield.Get_offset();//field table off contains count

                int count         = DATA_READ.ReadINT_LE(Toff, data);
                int field_memaddr = DATA_READ.ReadINT_LE(Toff + 4, data);
                int entry_size    = i_Pfield.Get_entry_size(); //entry_size

                int field_off = field_memaddr - mem_off;       //its the offset of the field from the starting of the meta data

                if (count > 0)
                {
                    //now we check whether its inside meta or a case of extended meta
                    if ((field_memaddr >= mem_off) && (field_off < size))
                    {
                        //inside meta
                        //we add this off which contains reflexive table to the list if it doesnt contain the off already
                        if (!ref_reflexive.Contains(Toff))
                        {
                            ref_reflexive.Add(Toff);
                            //after adding it to the list we look into them,recursively
                            for (int j = 0; j < count; j++)
                            {
                                List_deps(field_off + j * entry_size, i_Pfield);
                            }
                        }
                    }
                    else
                    {
                        //extended meta(IN SUCCESSFULL RUN ,EXTENDED META ONLY APPEARS ONLY WHEN WE READ FROM A MAP)

                        //but first we check whether we are reading meta from a map,or an exracted file,its rather easy
                        if (list_extended != null)
                        {
                            //we add this off to the list if it doesnt contain the off already
                            if (!ref_extended.ContainsKey(Toff))
                            {
                                ref_extended.Add(Toff, field_memaddr);
                                //now we create and add extended_meta to the list if it isnt already there
                                if (!list_extended.ContainsKey(field_memaddr))
                                {
                                    extended_meta temp_extend = new extended_meta(field_memaddr, entry_size * count, count, i_Pfield, map_stream);
                                    list_extended.Add(field_memaddr, temp_extend);
                                }
                                //we dont need to look into them as extended meta does it for us
                            }
                        }
                        else
                        {
                            //the program will only reach here when u try to use an extended meta on meta file.
                            //any meta which i extract from a map file have all issues of extended_meta fixed.
                            throw new Exception("Meta file " + path + "." + type + " is broken.\nEither debug the extraction proceedure or fix the meta file");
                        }
                    }
                }
            }
            //now we go for withClass attribute tagRefs,they are a bit different as they only contain the datum index of the refered tag
            temp = fields.Get_WCtag_ref_list();
            foreach (int i in temp)
            {
                int Toff = off + i;
                //we add this off to the list if it doesnt contain the off already
                if (!ref_WCtags.Contains(Toff))
                {
                    ref_WCtags.Add(Toff);
                }
            }
        }
        /// <summary>
        /// a function to fill in all the Lists and Dictionaries
        /// </summary>
        /// <param name="off">the starting offset where the stuff is being read</param>
        /// <param name="fields">the concerned field(s) in that section</param>
        void List_deps(int off, plugins_field fields)
        {
            List <int> temp = fields.Get_tag_ref_list();

            //first we look for tag_refs and add them
            foreach (int i in temp)
            {
                int Toff = off + i;//it contains type
                //we add this off to the list if it doesnt contain the off already
                if (!ref_tags.Contains(Toff))
                {
                    ref_tags.Add(Toff);
                }
            }
            //then we look for data_refs and add them
            temp = fields.Get_data_ref_list();
            foreach (int i in temp)
            {
                int Toff = off + i;
                //we add this off to the list if it doesnt contain the off already
                if (!ref_data.Contains(Toff))
                {
                    ref_data.Add(Toff);
                }
            }
            //then we look for stringId refs and add them
            temp = fields.Get_stringID_ref_list();
            foreach (int i in temp)
            {
                int Toff = off + i;
                //we add this off to the list if it doesnt contain the off already
                if (!ref_stringID.Contains(Toff))
                {
                    ref_stringID.Add(Toff);
                }
            }
            //now we look into reflexive fields and extended meta and add them accordingly
            List <plugins_field> Ptemp = fields.Get_reflexive_list();

            foreach (plugins_field i_Pfield in Ptemp)
            {
                int Toff = off + i_Pfield.Get_offset();//field table off contains count

                int count         = DATA_READ.ReadINT_LE(Toff, data);
                int field_memaddr = DATA_READ.ReadINT_LE(Toff + 4, data);
                int entry_size    = i_Pfield.Get_entry_size(); //entry_size

                int field_off = field_memaddr - mem_off;       //its the offset of the field from the starting of the meta data

                if (count > 0)
                {
                    //now we check whether its inside meta or a case of extended meta
                    if ((field_memaddr >= mem_off) && (field_off < size))
                    {
                        //inside meta
                        //we add this off which contains reflexive table to the list if it doesnt contain the off already
                        if (!ref_reflexive.Contains(Toff))
                        {
                            ref_reflexive.Add(Toff);
                            //after adding it to the list we look into them,recursively
                            for (int j = 0; j < count; j++)
                            {
                                List_deps(field_off + j * entry_size, i_Pfield);
                            }
                        }
                    }
                    else
                    {
                        //extended meta
                        //we add this off to the list if it doesnt contain the off already
                        if (!ref_extended.ContainsKey(Toff))
                        {
                            ref_extended.Add(Toff, field_memaddr);
                            //now we create and add extended_meta to the list if it isnt already there
                            if (!list_extended.ContainsKey(field_memaddr))
                            {
                                extended_meta temp_extend = new extended_meta(field_memaddr, entry_size * count, count, i_Pfield, map_stream);
                                list_extended.Add(field_memaddr, temp_extend);
                            }
                            //we dont need to look into them as extended meta does it for us
                        }
                    }
                }
            }
            //now we go for withClass attribute tagRefs,they are a bit different as they only contain the datum index of the refered tag
            temp = fields.Get_WCtag_ref_list();
            foreach (int i in temp)
            {
                int Toff = off + i;
                //we add this off to the list if it doesnt contain the off already
                if (!ref_WCtags.Contains(Toff))
                {
                    ref_WCtags.Add(Toff);
                }
            }
        }