Exemple #1
0
        /// <summary>
        /// Gets the version of the selected item.
        /// </summary>
        /// <param name="selectedCategory">The category which contains the selected item </param>
        /// <param name="item">The selected items data</param>
        /// <param name="isSecondary">Use secondary item data</param>
        /// <returns>The version of the selected item</returns>
        public static Tuple <string, string> GetVersion(string selectedCategory, ItemData item, bool isSecondary)
        {
            if (int.Parse(item.ItemCategory) < 22 || selectedCategory.Equals(Strings.Pets) || selectedCategory.Equals(Strings.Mounts) ||
                selectedCategory.Equals(Strings.Minions) || selectedCategory.Equals(Strings.Monster) || selectedCategory.Equals(Strings.DemiHuman))
            {
                var    slotID = Info.slotID[selectedCategory];
                var    type = Helper.GetCategoryType(selectedCategory);
                string itemID, body, variant;

                if (isSecondary)
                {
                    itemID  = item.SecondaryModelID;
                    body    = item.SecondaryModelBody;
                    variant = item.SecondaryModelVariant;
                }
                else
                {
                    itemID  = item.PrimaryModelID;
                    body    = item.PrimaryModelBody;
                    variant = item.PrimaryModelVariant;
                }

                int offset = 0;
                if (type.Equals("monster"))
                {
                    offset = Helper.GetDataOffset(FFCRC.GetHash(string.Format(Strings.MonsterIMCFolder, itemID, body)), FFCRC.GetHash(string.Format(Strings.MonsterIMCFile, body)), Strings.ItemsDat);
                }
                else if (type.Equals("food") || type.Equals("weapon"))
                {
                    offset = Helper.GetDataOffset(FFCRC.GetHash(string.Format(Strings.WeapIMCFolder, itemID, body)), FFCRC.GetHash(string.Format(Strings.WeapIMCFile, body)), Strings.ItemsDat);
                }
                else if (type.Equals("equipment"))
                {
                    offset = Helper.GetDataOffset(FFCRC.GetHash(string.Format(Strings.EquipIMCFolder, itemID)), FFCRC.GetHash(string.Format(Strings.EquipIMCFile, itemID)), Strings.ItemsDat);
                }
                else if (type.Equals("accessory"))
                {
                    offset = Helper.GetDataOffset(FFCRC.GetHash(string.Format(Strings.AccIMCFolder, itemID)), FFCRC.GetHash(string.Format(Strings.AccIMCFile, itemID)), Strings.ItemsDat);
                }
                else
                {
                    offset = Helper.GetDataOffset(FFCRC.GetHash("chara/" + type + "/" + type.Substring(0, 1) + itemID), FFCRC.GetHash(type.Substring(0, 1) + itemID + ".imc"), Strings.ItemsDat);
                }

                if (offset != 0)
                {
                    return(FindVersion(offset, slotID, variant, type));
                }
                else
                {
                    return(new Tuple <string, string>("0001", "0000"));
                }
            }
            else
            {
                return(new Tuple <string, string>("0001", "0000"));
            }
        }
        /// <summary>
        /// Parses the MTRL file for items that contains types
        /// </summary>
        /// <param name="item">currently selected item</param>
        /// <param name="race">currently selected race</param>
        /// <param name="part">currently selected part</param>
        /// <param name="type">currently selected type</param>
        /// <param name="IMCVersion">version of the selected item</param>
        /// <param name="selectedCategory">The category of the item</param>
        /// <returns>A tuple containing the MTRLInfo and Observable Collection containing texture map names</returns>
        public static Tuple <MTRLData, ObservableCollection <ComboBoxInfo> > GetMTRLDatafromType(ItemData item, ComboBoxInfo race, string part, string type, string IMCVersion, string selectedCategory)
        {
            string MTRLFolder, MTRLFile;
            string MTRLPath       = "";
            bool   isUncompressed = true;
            int    offset         = 0;

            if (item.ItemName.Equals(Strings.Face))
            {
                MTRLFolder = String.Format(Strings.FaceMtrlFolder, race.ID, part.PadLeft(4, '0'));
                MTRLFile   = String.Format(Strings.FaceMtrlFile, race.ID, part.PadLeft(4, '0'), Info.FaceTypes[type]);
                offset     = Helper.GetItemOffset(FFCRC.GetHash(MTRLFolder), FFCRC.GetHash(MTRLFile));
                MTRLPath   = MTRLFolder + "/" + MTRLFile;

                isUncompressed = true;
            }
            else if (item.ItemName.Equals(Strings.Hair))
            {
                MTRLFolder     = String.Format(Strings.HairMtrlFolder, race.ID, part.PadLeft(4, '0'));
                isUncompressed = true;

                if (type.Equals(Strings.Accessory))
                {
                    MTRLFile = String.Format(Strings.HairMtrlFile, race.ID, part.PadLeft(4, '0'), Info.HairTypes[type], "b");
                }
                else
                {
                    MTRLFile = String.Format(Strings.HairMtrlFile, race.ID, part.PadLeft(4, '0'), Info.HairTypes[type], "a");
                }

                MTRLPath = MTRLFolder + "/" + MTRLFile;
                offset   = Helper.GetItemOffset(FFCRC.GetHash(MTRLFolder), FFCRC.GetHash(MTRLFile));
            }
            else if (selectedCategory.Equals(Strings.Mounts))
            {
                isUncompressed = false;

                if (item.PrimaryMTRLFolder.Contains("demihuman"))
                {
                    MTRLFile = String.Format(Strings.DemiMtrlFile, item.PrimaryModelID.PadLeft(4, '0'), item.PrimaryModelBody.PadLeft(4, '0'), type);
                }
                else
                {
                    MTRLFile = String.Format(Strings.MonsterMtrlFile, item.PrimaryModelID.PadLeft(4, '0'), item.PrimaryModelBody.PadLeft(4, '0'), part);
                }

                MTRLPath = item.PrimaryMTRLFolder + IMCVersion + "/" + MTRLFile;

                offset = Helper.GetItemOffset(FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion), FFCRC.GetHash(MTRLFile));
            }

            var mtrlInfo = GetMTRLInfo(offset, isUncompressed);

            mtrlInfo.MTRLPath   = MTRLPath;
            mtrlInfo.MTRLOffset = offset;

            return(new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, mtrlInfo.TextureMaps));
        }
Exemple #3
0
        /// <summary>
        /// Modifies the offset for a particular texture in the .index file
        /// </summary>
        /// <param name="newOffset">The new offset to be writen</param>
        /// <param name="texName">Name of the currently selected texture</param>
        /// <param name="mFolderHex">the Folder Name CRC</param>
        public void modifyIndexOffset(int newOffset, string texName, string mFolderHex)
        {
            FFCRC  crc = new FFCRC();
            string fileCRC;

            fileCRC = crc.text(texName).PadLeft(8, '0');

            using (FileStream fs = new FileStream(Properties.Settings.Default.DefaultDir + "/040000.win32.index", FileMode.Open, FileAccess.ReadWrite))
            {
                using (BinaryReader b = new BinaryReader(fs))
                {
                    using (BinaryWriter bw = new BinaryWriter(fs))
                    {
                        b.BaseStream.Seek(1036, SeekOrigin.Begin);
                        int totalFiles = b.ReadInt32();


                        b.BaseStream.Seek(2048, SeekOrigin.Begin);
                        for (int i = 0; i < totalFiles; b.ReadBytes(4), i += 16)
                        {
                            int    fileHex1 = b.ReadInt32();
                            string fHex     = fileHex1.ToString("X").PadLeft(8, '0');

                            if (fHex.Equals(fileCRC))
                            {
                                if (!texName.Contains("mt_"))
                                {
                                    bw.BaseStream.Seek(2056 + i, SeekOrigin.Begin);
                                    bw.Write(newOffset / 8);
                                    break;
                                }
                                else
                                {
                                    int    folderHex = b.ReadInt32();
                                    string fohex     = folderHex.ToString("X").PadLeft(8, '0');

                                    if (fohex.Equals(mFolderHex))
                                    {
                                        bw.BaseStream.Seek(2056 + i, SeekOrigin.Begin);
                                        bw.Write(newOffset / 8);
                                        break;
                                    }
                                    b.ReadBytes(4);
                                }
                            }
                            else
                            {
                                b.ReadBytes(8);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Gets the MTRL offset of decal files
        /// </summary>
        /// <param name="decalType">Type of decal</param>
        /// <param name="decalNum">The decal number</param>
        /// <returns>The mtrl offset of the decal file</returns>
        public static int GetDecalOffset(string decalType, string decalNum)
        {
            string decalFolder, decalFile;

            if (decalType.Equals(Strings.Face_Paint))
            {
                decalFolder = Strings.FacePaintFolder;
                decalFile   = String.Format(Strings.FacePaintFile, decalNum);
            }
            else
            {
                decalFolder = Strings.EquipDecalFolder;
                decalFile   = String.Format(Strings.EquipDecalFile, decalNum.PadLeft(3, '0'));
            }

            return(Helper.GetItemOffset(FFCRC.GetHash(decalFolder), FFCRC.GetHash(decalFile)));
        }
Exemple #5
0
        /// <summary>
        /// Gets the MTRL data of the given mesh
        /// </summary>
        /// <param name="mesh">The mesh to obtain the data from</param>
        /// <returns>The MTRLData of the given mesh</returns>
        public MTRLData MTRL3D(int mesh)
        {
            MTRLData mtrlData    = null;
            bool     isDemiHuman = false;

            if (selectedItem.PrimaryMTRLFolder != null)
            {
                isDemiHuman = selectedItem.PrimaryMTRLFolder.Contains("demihuman");
            }

            var itemVersion = IMC.GetVersion(selectedCategory, selectedItem, false).Item1;
            var itemType    = Helper.GetCategoryType(selectedCategory);

            try
            {
                if (selectedItem.ItemName.Equals(Strings.Face) || selectedItem.ItemName.Equals(Strings.Hair) || isDemiHuman)
                {
                    string slotAbr;

                    if (isDemiHuman)
                    {
                        slotAbr = Info.slotAbr[SelectedPart.Name];
                    }
                    else if (selectedCategory.Equals(Strings.Character))
                    {
                        var race = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("c") + 1, 4);

                        if (materialStrings[mesh].Contains("h00"))
                        {
                            var hairNum    = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("h00") + 1, 4);
                            var mtrlFolder = string.Format(Strings.HairMtrlFolder, race, hairNum);
                            slotAbr = materialStrings[mesh].Substring(materialStrings[mesh].LastIndexOf("_") - 3, 3);
                            slotAbr = Info.HairTypes.FirstOrDefault(x => x.Value == slotAbr).Key;

                            var hairInfo = MTRL.GetMTRLDatafromType(selectedItem, SelectedRace, hairNum, slotAbr, itemVersion, selectedCategory);
                            return(hairInfo.Item1);
                        }
                        else if (materialStrings[mesh].Contains("f00"))
                        {
                            var faceNum    = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("f00") + 1, 4);
                            var mtrlFolder = string.Format(Strings.FaceMtrlFolder, race, faceNum);
                            slotAbr = materialStrings[mesh].Substring(materialStrings[mesh].LastIndexOf("_") - 3, 3);
                            slotAbr = Info.FaceTypes.FirstOrDefault(x => x.Value == slotAbr).Key;

                            var faceInfo = MTRL.GetMTRLDatafromType(selectedItem, SelectedRace, faceNum, slotAbr, itemVersion, selectedCategory);
                            return(faceInfo.Item1);
                        }
                        else
                        {
                            slotAbr = selectedPart.Name;
                        }
                    }
                    else
                    {
                        slotAbr = selectedPart.Name;
                    }

                    var info = MTRL.GetMTRLDatafromType(selectedItem, SelectedRace, selectedPart.Name, slotAbr, itemVersion, selectedCategory);
                    mtrlData = info.Item1;
                }
                else
                {
                    Tuple <MTRLData, ObservableCollection <ComboBoxInfo> > info;

                    if (itemType.Equals("character") || itemType.Equals("equipment"))
                    {
                        try
                        {
                            if (materialStrings[mesh].Contains("b00") || materialStrings[mesh].Contains("t00") || materialStrings[mesh].Contains("h00"))
                            {
                                if (materialStrings[mesh].Contains("mt_c"))
                                {
                                    var mtrlFolder = "";
                                    var race       = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("c") + 1, 4);

                                    if (materialStrings[mesh].Contains("b00"))
                                    {
                                        mtrlFolder = string.Format(Strings.BodyMtrlFolder, race, materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("b00") + 1, 4));
                                    }
                                    else if (materialStrings[mesh].Contains("t00"))
                                    {
                                        mtrlFolder = string.Format(Strings.TailMtrlFolder, race, materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("t00") + 1, 4));
                                    }
                                    else if (materialStrings[mesh].Contains("h00"))
                                    {
                                        mtrlFolder = string.Format(Strings.HairMtrlFolder, race, materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("h00") + 1, 4));
                                    }

                                    var mtrlFile = materialStrings[mesh].Substring(1);

                                    return(MTRL.GetMTRLInfo(Helper.GetItemOffset(FFCRC.GetHash(mtrlFolder), FFCRC.GetHash(mtrlFile)), true));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.Message);
                            Debug.WriteLine(ex.StackTrace);
                        }
                    }
                    else
                    {
                        info = MTRL.GetMTRLData(selectedItem, SelectedRace.ID, selectedCategory, SelectedPart.Name, itemVersion, "", "", "0000");
                    }

                    if (SelectedPart.Name.Equals("Secondary"))
                    {
                        info = MTRL.GetMTRLData(selectedItem, SelectedRace.ID, selectedCategory, SelectedPart.Name, itemVersion, "Secondary", "", "0000");
                    }
                    else
                    {
                        string part   = "a";
                        string itemID = selectedItem.PrimaryModelID;

                        if (materialStrings.Count > 1)
                        {
                            try
                            {
                                part   = materialStrings[mesh].Substring(materialStrings[mesh].LastIndexOf("_") + 1, 1);
                                itemID = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("_") + 2, 4);
                            }
                            catch (Exception ex)
                            {
                                Debug.WriteLine(ex.Message);
                                Debug.WriteLine(ex.StackTrace);
                            }
                        }

                        if (selectedCategory.Equals(Strings.Pets))
                        {
                            part = "1";
                        }

                        info = MTRL.GetMTRLData(selectedItem, SelectedRace.ID, selectedCategory, part, itemVersion, "", itemID, "0000");
                    }

                    if (info != null)
                    {
                        mtrlData = info.Item1;
                    }
                    else
                    {
                        var combo = new ComboBoxInfo()
                        {
                            Name = "Default", ID = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("c") + 1, 4), IsNum = false
                        };

                        if (SelectedPart.Name.Equals("-"))
                        {
                            info = MTRL.GetMTRLData(selectedItem, combo.ID, selectedCategory, "a", itemVersion, "", "", "0000");
                        }
                        else
                        {
                            info = MTRL.GetMTRLData(selectedItem, combo.ID, selectedCategory, SelectedPart.Name, itemVersion, "", "", "0000");
                        }

                        mtrlData = info.Item1;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex.StackTrace);
                return(null);
            }

            return(mtrlData);
        }
Exemple #6
0
        /// <summary>
        /// Sets the data for the body combo box
        /// </summary>
        private void RaceComboBoxChanged()
        {
            is3DLoaded = false;

            if (CompositeVM != null && !disposing)
            {
                disposing = true;
                CompositeVM.Dispose();
            }

            List <ComboBoxInfo> cbi = new List <ComboBoxInfo>();
            string categoryType     = Helper.GetCategoryType(selectedCategory);
            string MDLFolder        = "";

            if (categoryType.Equals("weapon"))
            {
                cbi.Add(new ComboBoxInfo()
                {
                    Name = selectedItem.PrimaryModelBody, ID = selectedItem.PrimaryModelBody, IsNum = false
                });
            }
            else if (categoryType.Equals("food"))
            {
                cbi.Add(new ComboBoxInfo()
                {
                    Name = selectedItem.PrimaryModelBody, ID = selectedItem.PrimaryModelBody, IsNum = false
                });
            }
            else if (categoryType.Equals("accessory"))
            {
                cbi.Add(new ComboBoxInfo()
                {
                    Name = "-", ID = "-", IsNum = false
                });
            }
            else if (categoryType.Equals("character"))
            {
                if (selectedItem.ItemName.Equals(Strings.Body))
                {
                    MDLFolder = string.Format(Strings.BodyMDLFolder, SelectedRace.ID, "{0}");
                }
                else if (selectedItem.ItemName.Equals(Strings.Face))
                {
                    MDLFolder = string.Format(Strings.FaceMDLFolder, SelectedRace.ID, "{0}");
                }
                else if (selectedItem.ItemName.Equals(Strings.Hair))
                {
                    MDLFolder = string.Format(Strings.HairMDLFolder, SelectedRace.ID, "{0}");
                }
                else if (selectedItem.ItemName.Equals(Strings.Tail))
                {
                    MDLFolder = string.Format(Strings.TailMDLFolder, SelectedRace.ID, "{0}");
                }
            }
            else if (categoryType.Equals("monster"))
            {
                cbi.Add(new ComboBoxInfo()
                {
                    Name = selectedItem.PrimaryModelBody, ID = selectedItem.PrimaryModelBody, IsNum = false
                });
            }
            else
            {
                cbi.Add(new ComboBoxInfo()
                {
                    Name = "-", ID = "-", IsNum = false
                });
            }


            if (categoryType.Equals("character"))
            {
                for (int i = 0; i < 50; i++)
                {
                    string folder = String.Format(MDLFolder, i.ToString().PadLeft(4, '0'));

                    if (Helper.FolderExists(FFCRC.GetHash(folder)))
                    {
                        cbi.Add(new ComboBoxInfo()
                        {
                            Name = i.ToString(), ID = i.ToString(), IsNum = true
                        });

                        if (selectedItem.ItemName.Equals(Strings.Body))
                        {
                            break;
                        }
                    }
                }
            }

            BodyComboBox = new ObservableCollection <ComboBoxInfo>(cbi);
            BodyIndex    = 0;

            if (cbi.Count <= 1)
            {
                BodyEnabled = false;
            }
            else
            {
                BodyEnabled = true;
            }
        }
Exemple #7
0
        /// <summary>
        /// Sets the data for the part combo box
        /// </summary>
        private void BodyComboBoxChanged()
        {
            is3DLoaded = false;
            bool isDemiHuman = false;

            if (CompositeVM != null && !disposing)
            {
                disposing = true;
                CompositeVM.Dispose();
            }

            if (selectedItem.PrimaryMTRLFolder != null && selectedItem.PrimaryMTRLFolder.Contains("demihuman"))
            {
                isDemiHuman = true;
            }

            List <ComboBoxInfo> cbi = new List <ComboBoxInfo>();
            string type             = Helper.GetCategoryType(selectedCategory);

            string MDLFolder = "";
            string MDLFile   = "";

            string[] abrParts = null;

            if (type.Equals("character"))
            {
                if (selectedItem.ItemName.Equals(Strings.Body))
                {
                    MDLFolder = string.Format(Strings.BodyMDLFolder, SelectedRace.ID, SelectedBody.ID.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.BodyMDLFile, SelectedRace.ID, SelectedBody.ID.PadLeft(4, '0'), "{0}");

                    abrParts = new string[5] {
                        "met", "glv", "dwn", "sho", "top"
                    };
                }
                else if (selectedItem.ItemName.Equals(Strings.Face))
                {
                    MDLFolder = string.Format(Strings.FaceMDLFolder, SelectedRace.ID, SelectedBody.ID.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.FaceMDLFile, SelectedRace.ID, SelectedBody.ID.PadLeft(4, '0'), "{0}");

                    abrParts = new string[3] {
                        "fac", "iri", "etc"
                    };
                }
                else if (selectedItem.ItemName.Equals(Strings.Hair))
                {
                    MDLFolder = string.Format(Strings.HairMDLFolder, SelectedRace.ID, SelectedBody.ID.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.HairMDLFile, SelectedRace.ID, SelectedBody.ID.PadLeft(4, '0'), "{0}");

                    abrParts = new string[2] {
                        "hir", "acc"
                    };
                }
                else if (selectedItem.ItemName.Equals(Strings.Tail))
                {
                    MDLFolder = string.Format(Strings.TailMDLFolder, SelectedRace.ID, SelectedBody.ID.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.TailMDLFile, SelectedRace.ID, SelectedBody.ID.PadLeft(4, '0'), "{0}");

                    abrParts = new string[1] {
                        "til"
                    };
                }

                var fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(MDLFolder));

                foreach (string abrPart in abrParts)
                {
                    var file = String.Format(MDLFile, abrPart);

                    if (fileHashList.Contains(FFCRC.GetHash(file)))
                    {
                        if (selectedItem.ItemName.Equals(Strings.Body))
                        {
                            cbi.Add(new ComboBoxInfo()
                            {
                                Name = Info.slotAbr.FirstOrDefault(x => x.Value == abrPart).Key, ID = abrPart, IsNum = false
                            });
                        }
                        else if (selectedItem.ItemName.Equals(Strings.Face))
                        {
                            cbi.Add(new ComboBoxInfo()
                            {
                                Name = Info.FaceTypes.FirstOrDefault(x => x.Value == abrPart).Key, ID = abrPart, IsNum = false
                            });
                        }
                        else if (selectedItem.ItemName.Equals(Strings.Hair))
                        {
                            cbi.Add(new ComboBoxInfo()
                            {
                                Name = Info.HairTypes.FirstOrDefault(x => x.Value == abrPart).Key, ID = abrPart, IsNum = false
                            });
                        }
                        else if (selectedItem.ItemName.Equals(Strings.Tail))
                        {
                            cbi.Add(new ComboBoxInfo()
                            {
                                Name = Strings.Tail, ID = abrPart, IsNum = false
                            });
                        }
                    }
                }
            }
            else if (isDemiHuman)
            {
                MDLFolder = string.Format(Strings.DemiMDLFolder, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody);
                MDLFile   = string.Format(Strings.DemiMDLFile, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody, "{0}");

                abrParts = new string[5] {
                    "met", "glv", "dwn", "sho", "top"
                };

                var fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(MDLFolder));

                foreach (string abrPart in abrParts)
                {
                    var file = String.Format(MDLFile, abrPart);

                    if (fileHashList.Contains(FFCRC.GetHash(file)))
                    {
                        cbi.Add(new ComboBoxInfo()
                        {
                            Name = Info.slotAbr.FirstOrDefault(x => x.Value == abrPart).Key, ID = abrPart, IsNum = false
                        });
                    }
                }
            }
            else if (type.Equals("weapon"))
            {
                if (selectedItem.SecondaryModelID != null)
                {
                    cbi.Add(new ComboBoxInfo()
                    {
                        Name = "Primary", ID = "Primary", IsNum = false
                    });
                    cbi.Add(new ComboBoxInfo()
                    {
                        Name = "Secondary", ID = "Secondary", IsNum = false
                    });
                }
                else
                {
                    cbi.Add(new ComboBoxInfo()
                    {
                        Name = "Primary", ID = "Primary", IsNum = false
                    });
                }
            }
            else if (type.Equals("monster"))
            {
                cbi.Add(new ComboBoxInfo()
                {
                    Name = "1", ID = "1", IsNum = false
                });
            }
            else
            {
                cbi.Add(new ComboBoxInfo()
                {
                    Name = "-", ID = "-", IsNum = false
                });
            }

            PartComboBox = new ObservableCollection <ComboBoxInfo>(cbi);
            PartIndex    = 0;

            if (cbi.Count <= 1)
            {
                PartEnabled = false;
            }
            else
            {
                PartEnabled = true;
            }
        }
Exemple #8
0
        public ModListModel ParseEntry(JsonEntry entry)
        {
            ModListModel mlm = new ModListModel();
            string       race, map, part, type;

            if (entry.fullPath.Contains("mt_"))
            {
                Debug.WriteLine(entry.fullPath);
            }

            if (entry.fullPath.Contains("weapon") || entry.fullPath.Contains("accessory") || entry.fullPath.Contains("decal") || entry.fullPath.Contains("vfx") || entry.fullPath.Contains("ui/"))
            {
                race = Strings.All;
            }
            else if (entry.fullPath.Contains("monster") || entry.fullPath.Contains("demihuman"))
            {
                race = Strings.Monster;
            }
            else
            {
                race = entry.fullPath.Substring(entry.fullPath.LastIndexOf('/'));
                if (entry.fullPath.Contains("mt_") && entry.fullPath.Contains("_acc_"))
                {
                    race = race.Substring(race.IndexOf("_") + 2, 4);
                }
                else if ((entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_")) && Properties.Settings.Default.DX_Ver.Equals(Strings.DX11))
                {
                    race = race.Substring(race.LastIndexOf("--c") + 3, 4);
                }
                else if (entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_"))
                {
                    race = race.Substring(race.LastIndexOf("/c") + 2, 4);
                }
                else if (entry.fullPath.Contains("_c_"))
                {
                    race = race.Substring(race.IndexOf("_c") + 2, 4);
                }
                else
                {
                    if (entry.fullPath.Contains(".mdl") && entry.fullPath.Contains("_fac"))
                    {
                        race = race.Substring(race.IndexOf('c') + 1, 4);
                    }
                    else
                    {
                        race = race.Substring(race.LastIndexOf('c') + 1, 4);
                    }
                }

                if (entry.fullPath.Contains("mt_"))
                {
                    Debug.WriteLine(race + "\n");
                }

                race = Info.IDRace[race];
            }

            mlm.Race = race;


            if (entry.fullPath.Contains("_d."))
            {
                map = Strings.Diffuse;
            }
            else if (entry.fullPath.Contains("_n."))
            {
                map = Strings.Normal;
            }
            else if (entry.fullPath.Contains("_s."))
            {
                map = Strings.Specular;
            }
            else if (entry.fullPath.Contains("material"))
            {
                map = Strings.ColorSet;
            }
            else if (entry.fullPath.Contains("model"))
            {
                map = "3D";
            }
            else if (entry.fullPath.Contains("ui/"))
            {
                map = "UI";
            }
            else
            {
                map = Strings.Mask;
            }

            mlm.Map = map;


            if (entry.fullPath.Contains("_b_"))
            {
                part = "b";
            }
            else if (entry.fullPath.Contains("_c_"))
            {
                part = "c";
            }
            else if (entry.fullPath.Contains("_d_"))
            {
                part = "d";
            }
            else if (entry.fullPath.Contains("decal"))
            {
                part = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') + 1, entry.fullPath.LastIndexOf('.') - (entry.fullPath.LastIndexOf('_') + 1));
            }
            else
            {
                part = "a";
            }

            mlm.Part = part;


            if (entry.fullPath.Contains("_iri_"))
            {
                type = "Iris";
            }
            else if (entry.fullPath.Contains("_etc_"))
            {
                type = "Etc.";
            }
            else if (entry.fullPath.Contains("_fac_"))
            {
                type = "Face";
            }
            else if (entry.fullPath.Contains("_hir_"))
            {
                type = "Hair";
            }
            else if (entry.fullPath.Contains("_acc_"))
            {
                type = "Accessory";
            }
            else if (entry.fullPath.Contains("demihuman"))
            {
                type = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') - 3, 3);
                type = (Info.slotAbr).FirstOrDefault(x => x.Value == type).Key;
            }
            else
            {
                type = "-";
            }

            mlm.Type = type;

            if (entry.fullPath.Contains("material"))
            {
                var info = MTRL.GetMTRLInfo(entry.modOffset, false);

                using (var bitmap = TEX.ColorSetToBitmap(info.ColorData))
                    mlm.BMP = TexHelper.CreateBitmapSource(bitmap);
                mlm.BMP.Freeze();
            }
            else if (entry.fullPath.Contains("model"))
            {
                mlm.BMP = new BitmapImage(new Uri("pack://application:,,,/FFXIV TexTools 2;component/Resources/3DModel.png"));
            }
            else
            {
                TEXData texData;

                if (entry.fullPath.Contains("vfx"))
                {
                    texData = TEX.GetVFX(entry.modOffset, entry.datFile);
                }
                else
                {
                    if (entry.fullPath.Contains("icon"))
                    {
                        texData = TEX.GetTex(entry.modOffset, entry.datFile);
                    }
                    else
                    {
                        texData = TEX.GetTex(entry.modOffset, entry.datFile);
                    }
                }

                var scale = 1;

                if (texData.Width >= 4096 || texData.Height >= 4096)
                {
                    scale = 16;
                }
                else if (texData.Width >= 2048 || texData.Height >= 2048)
                {
                    scale = 8;
                }
                else if (texData.Width >= 1024 || texData.Height >= 1024)
                {
                    scale = 4;
                }

                var nWidth  = texData.Width / scale;
                var nHeight = texData.Height / scale;

                var resizedImage = TexHelper.CreateResizedImage(texData.BMPSouceNoAlpha, nWidth, nHeight);
                mlm.BMP = (BitmapSource)resizedImage;
                mlm.BMP.Freeze();
            }

            var offset = Helper.GetDataOffset(FFCRC.GetHash(entry.fullPath.Substring(0, entry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(entry.fullPath)), entry.datFile);

            if (offset == entry.modOffset)
            {
                mlm.ActiveBorder  = Brushes.Green;
                mlm.Active        = Brushes.Transparent;
                mlm.ActiveOpacity = 1;
            }
            else if (offset == entry.originalOffset)
            {
                mlm.ActiveBorder  = Brushes.Red;
                mlm.Active        = Brushes.Gray;
                mlm.ActiveOpacity = 0.5f;
            }
            else
            {
                mlm.ActiveBorder  = Brushes.Red;
                mlm.Active        = Brushes.Red;
                mlm.ActiveOpacity = 1;
            }

            mlm.Entry = entry;

            return(mlm);
        }
Exemple #9
0
        /// <summary>
        /// View Model for model view.
        /// </summary>
        /// <param name="item">the currently selcted item.</param>
        /// <param name="category">The category of the item.</param>
        public ModelViewModel(ItemData item, string category)
        {
            selectedItem     = item;
            selectedCategory = category;

            try
            {
                string categoryType     = Helper.GetCategoryType(selectedCategory);
                List <ComboBoxInfo> cbi = new List <ComboBoxInfo>();
                string MDLFolder        = "";
                string MDLFile          = "";

                if (categoryType.Equals("weapon") || categoryType.Equals("food"))
                {
                    MDLFolder = "";
                    cbi.Add(new ComboBoxInfo()
                    {
                        Name = Strings.All, ID = Strings.All, IsNum = false
                    });
                }
                else if (categoryType.Equals("accessory"))
                {
                    MDLFolder = string.Format(Strings.AccMDLFolder, selectedItem.PrimaryModelID);
                    MDLFile   = string.Format(Strings.AccMDLFile, "{0}", selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
                }
                else if (categoryType.Equals("character"))
                {
                    if (selectedItem.ItemName.Equals(Strings.Body))
                    {
                        MDLFolder = Strings.BodyMDLFolder;
                    }
                    else if (selectedItem.ItemName.Equals(Strings.Face))
                    {
                        MDLFolder = Strings.FaceMDLFolder;
                    }
                    else if (selectedItem.ItemName.Equals(Strings.Hair))
                    {
                        MDLFolder = Strings.HairMDLFolder;
                    }
                    else if (selectedItem.ItemName.Equals(Strings.Tail))
                    {
                        MDLFolder = Strings.TailMDLFolder;
                    }
                }
                else if (categoryType.Equals("monster"))
                {
                    cbi.Add(new ComboBoxInfo()
                    {
                        Name = Strings.All, ID = Strings.All, IsNum = false
                    });
                }
                else
                {
                    MDLFolder = string.Format(Strings.EquipMDLFolder, selectedItem.PrimaryModelID);
                    MDLFile   = string.Format(Strings.EquipMDLFile, "{0}", selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
                }

                var fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(MDLFolder));

                if (!categoryType.Equals("weapon") && !categoryType.Equals("monster"))
                {
                    foreach (string raceID in Info.IDRace.Keys)
                    {
                        if (categoryType.Equals("character"))
                        {
                            for (int i = 0; i < 3; i++)
                            {
                                var mdlFolder = String.Format(MDLFolder, raceID, i.ToString().PadLeft(4, '0'));

                                if (Helper.FolderExists(FFCRC.GetHash(mdlFolder)))
                                {
                                    cbi.Add(new ComboBoxInfo()
                                    {
                                        Name = Info.IDRace[raceID], ID = raceID, IsNum = false
                                    });
                                    break;
                                }
                            }
                        }
                        else
                        {
                            var mdlFile  = String.Format(MDLFile, raceID);
                            var fileHash = FFCRC.GetHash(mdlFile);

                            if (fileHashList.Contains(fileHash))
                            {
                                cbi.Add(new ComboBoxInfo()
                                {
                                    Name = Info.IDRace[raceID], ID = raceID, IsNum = false
                                });
                            }
                        }
                    }
                }

                RaceComboBox = new ObservableCollection <ComboBoxInfo>(cbi);
                RaceIndex    = 0;

                if (cbi.Count <= 1)
                {
                    RaceEnabled = false;
                }
                else
                {
                    RaceEnabled = true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("[Main] tab 3D Error \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Exemple #10
0
        /// <summary>
        /// Parses the MDL file to obtain model information
        /// </summary>
        /// <param name="selectedItem">The currently selected item</param>
        /// <param name="selectedRace">The currently selected race</param>
        /// <param name="selectedBody">The currently selected body</param>
        /// <param name="selectedPart">The currently selected part</param>
        /// <param name="selectedCategory">The items category </param>
        public MDL(ItemData selectedItem, string selectedCategory, string selectedRace, string selectedBody, string selectedPart)
        {
            string itemType  = Helper.GetCategoryType(selectedCategory);
            string MDLFolder = "";

            if (itemType.Equals("weapon") || itemType.Equals("food"))
            {
                if (selectedPart.Equals("Secondary"))
                {
                    MDLFolder = string.Format(Strings.WeapMDLFolder, selectedItem.SecondaryModelID, selectedItem.SecondaryModelBody);
                    MDLFile   = string.Format(Strings.WeapMDLFile, selectedItem.SecondaryModelID, selectedItem.SecondaryModelBody);
                }
                else
                {
                    MDLFolder = string.Format(Strings.WeapMDLFolder, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody);
                    MDLFile   = string.Format(Strings.WeapMDLFile, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody);
                }
            }
            else if (itemType.Equals("accessory"))
            {
                MDLFolder = string.Format(Strings.AccMDLFolder, selectedItem.PrimaryModelID);
                MDLFile   = string.Format(Strings.AccMDLFile, selectedRace, selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
            }
            else if (itemType.Equals("character"))
            {
                if (selectedItem.ItemName.Equals(Strings.Body))
                {
                    MDLFolder = string.Format(Strings.BodyMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.BodyMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Face))
                {
                    MDLFolder = string.Format(Strings.FaceMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.FaceMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Hair))
                {
                    MDLFolder = string.Format(Strings.HairMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.HairMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Tail))
                {
                    MDLFolder = string.Format(Strings.TailMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.TailMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
            }
            else if (itemType.Equals("monster"))
            {
                bool isDemiHuman = false;
                if (selectedItem.PrimaryMTRLFolder != null)
                {
                    isDemiHuman = selectedItem.PrimaryMTRLFolder.Contains("demihuman");
                }

                string ID   = "";
                string body = "";

                if (selectedCategory.Equals(Strings.Pets))
                {
                    int part = 1;

                    if (selectedItem.ItemName.Equals(Strings.Selene) || selectedItem.ItemName.Equals(Strings.Bishop_Autoturret))
                    {
                        part = 2;
                    }

                    ID   = Info.petID[selectedItem.ItemName];
                    body = part.ToString().PadLeft(4, '0');
                }
                else
                {
                    ID   = selectedItem.PrimaryModelID.PadLeft(4, '0');
                    body = selectedItem.PrimaryModelBody;
                }

                if (isDemiHuman)
                {
                    MDLFolder = string.Format(Strings.DemiMDLFolder, ID, body);
                    MDLFile   = string.Format(Strings.DemiMDLFile, ID, body, selectedPart);
                }
                else
                {
                    MDLFolder = string.Format(Strings.MonsterMDLFolder, ID, body);
                    MDLFile   = string.Format(Strings.MonsterMDLFile, ID, body);
                }
            }
            else
            {
                MDLFolder = string.Format(Strings.EquipMDLFolder, selectedItem.PrimaryModelID);

                if (selectedPart.Equals("-"))
                {
                    MDLFile = string.Format(Strings.EquipMDLFile, selectedRace, selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
                }
                else
                {
                    MDLFile = string.Format(Strings.EquipMDLFile, selectedRace, selectedItem.PrimaryModelID, selectedPart);
                }
            }

            fullPath = MDLFolder + "/" + MDLFile;
            int offset = Helper.GetDataOffset(FFCRC.GetHash(MDLFolder), FFCRC.GetHash(MDLFile), Strings.ItemsDat);

            if (offset == 0)
            {
                if (itemType.Equals("weapon"))
                {
                    if (selectedPart.Equals("Secondary"))
                    {
                        MDLFolder = string.Format(Strings.EquipMDLFolder, selectedItem.SecondaryModelID);
                        MDLFile   = string.Format(Strings.EquipMDLFile, "0101", selectedItem.SecondaryModelID, Info.slotAbr[Strings.Hands]);

                        offset = Helper.GetDataOffset(FFCRC.GetHash(MDLFolder), FFCRC.GetHash(MDLFile), Strings.ItemsDat);
                    }
                }
            }

            int datNum = ((offset / 8) & 0x000f) / 2;

            var MDLDatData = Helper.GetType3DecompressedData(offset, datNum, Strings.ItemsDat);

            using (BinaryReader br = new BinaryReader(new MemoryStream(MDLDatData.Item1)))
            {
                // The size of the header + (size of the mesh information block (136 bytes) * the number of meshes) + padding
                br.BaseStream.Seek(64 + 136 * MDLDatData.Item2 + 4, SeekOrigin.Begin);

                var modelStringCount = br.ReadInt32();
                var stringBlockSize  = br.ReadInt32();
                var stringBlock      = br.ReadBytes(stringBlockSize);

                var unknown = br.ReadBytes(4);

                var totalMeshCount       = br.ReadInt16();
                var attributeStringCount = br.ReadInt16();
                var meshPartsCount       = br.ReadInt16();
                var materialStringCount  = br.ReadInt16();
                var boneStringCount      = br.ReadInt16();
                var boneListCount        = br.ReadInt16();

                var unknown1 = br.ReadInt16();
                var unknown2 = br.ReadInt16();
                var unknown3 = br.ReadInt16();
                var unknown4 = br.ReadInt16();
                var unknown5 = br.ReadInt16();
                var unknown6 = br.ReadInt16();

                br.ReadBytes(10);

                var unknown7 = br.ReadInt16();

                br.ReadBytes(16);

                using (BinaryReader br1 = new BinaryReader(new MemoryStream(stringBlock)))
                {
                    br1.BaseStream.Seek(0, SeekOrigin.Begin);

                    for (int i = 0; i < attributeStringCount; i++)
                    {
                        while (br1.ReadByte() != 0)
                        {
                            //extract each atribute string here
                        }
                    }

                    for (int i = 0; i < boneStringCount; i++)
                    {
                        byte        b;
                        List <byte> boneName = new List <byte>();
                        while ((b = br1.ReadByte()) != 0)
                        {
                            boneName.Add(b);
                        }
                        string bone = Encoding.ASCII.GetString(boneName.ToArray());
                        bone = bone.Replace("\0", "");

                        boneStrings.Add(bone);
                    }

                    for (int i = 0; i < materialStringCount; i++)
                    {
                        byte        b;
                        List <byte> name = new List <byte>();
                        while ((b = br1.ReadByte()) != 0)
                        {
                            name.Add(b);
                        }
                        string material = Encoding.ASCII.GetString(name.ToArray());
                        material = material.Replace("\0", "");

                        materialStrings.Add(material);
                    }
                }

                br.ReadBytes(32 * unknown5);

                for (int i = 0; i < 3; i++)
                {
                    LevelOfDetail LoD = new LevelOfDetail();
                    LoD.MeshOffset = br.ReadInt16();
                    LoD.MeshCount  = br.ReadInt16();

                    br.ReadBytes(40);

                    LoD.VertexDataSize = br.ReadInt32();
                    LoD.IndexDataSize  = br.ReadInt32();
                    LoD.VertexOffset   = br.ReadInt32();
                    LoD.IndexOffset    = br.ReadInt32();

                    modelData.LoD.Add(LoD);
                }

                var savePos = br.BaseStream.Position;

                for (int i = 0; i < modelData.LoD.Count; i++)
                {
                    List <MeshDataInfo> meshInfoList = new List <MeshDataInfo>();

                    for (int j = 0; j < modelData.LoD[i].MeshCount; j++)
                    {
                        modelData.LoD[i].MeshList.Add(new Mesh());
                        meshInfoList.Clear();

                        br.BaseStream.Seek((i * 136) + 68, SeekOrigin.Begin);
                        var dataBlockNum = br.ReadByte();

                        while (dataBlockNum != 255)
                        {
                            MeshDataInfo meshInfo = new MeshDataInfo()
                            {
                                VertexDataBlock = dataBlockNum,
                                Offset          = br.ReadByte(),
                                DataType        = br.ReadByte(),
                                UseType         = br.ReadByte()
                            };

                            meshInfoList.Add(meshInfo);

                            br.ReadBytes(4);

                            dataBlockNum = br.ReadByte();
                        }

                        modelData.LoD[i].MeshList[j].MeshDataInfoList = meshInfoList.ToArray();
                    }
                }

                br.BaseStream.Seek(savePos, SeekOrigin.Begin);

                for (int x = 0; x < modelData.LoD.Count; x++)
                {
                    for (int i = 0; i < modelData.LoD[x].MeshCount; i++)
                    {
                        MeshInfo meshInfo = new MeshInfo()
                        {
                            VertexCount     = br.ReadInt32(),
                            IndexCount      = br.ReadInt32(),
                            MaterialNum     = br.ReadInt16(),
                            MeshPartOffset  = br.ReadInt16(),
                            MeshPartCount   = br.ReadInt16(),
                            BoneListIndex   = br.ReadInt16(),
                            IndexDataOffset = br.ReadInt32()
                        };

                        for (int j = 0; j < 3; j++)
                        {
                            meshInfo.VertexDataOffsets.Add(br.ReadInt32());
                        }

                        for (int k = 0; k < 3; k++)
                        {
                            meshInfo.VertexSizes.Add(br.ReadByte());
                        }

                        meshInfo.VertexDataBlockCount = br.ReadByte();

                        modelData.LoD[x].MeshList[i].MeshInfo = meshInfo;
                    }
                }

                br.ReadBytes(attributeStringCount * 4);
                br.ReadBytes(unknown6 * 20);

                for (int i = 0; i < modelData.LoD.Count; i++)
                {
                    foreach (var mesh in modelData.LoD[i].MeshList)
                    {
                        for (int j = 0; j < mesh.MeshInfo.MeshPartCount; j++)
                        {
                            MeshPart meshPart = new MeshPart()
                            {
                                IndexOffset = br.ReadInt32(),
                                IndexCount  = br.ReadInt32(),
                                Attributes  = br.ReadInt32(),
                                BoneOffset  = br.ReadInt16(),
                                BoneCount   = br.ReadInt16()
                            };

                            mesh.MeshPartList.Add(meshPart);
                        }
                    }
                }

                br.ReadBytes(unknown7 * 12);
                br.ReadBytes(materialStringCount * 4);
                br.ReadBytes(boneStringCount * 4);

                for (int i = 0; i < boneListCount; i++)
                {
                    Bones bones = new Bones();

                    for (int j = 0; j < 64; j++)
                    {
                        bones.BoneData.Add(br.ReadInt16());
                    }

                    bones.BoneCount = br.ReadInt32();

                    modelData.BoneSet.Add(bones);
                }

                //br.ReadBytes(unknown1 * 16);

                Dictionary <int, int>         indexMin     = new Dictionary <int, int>();
                Dictionary <int, List <int> > extraIndices = new Dictionary <int, List <int> >();
                List <ExtraIndex>             indexCounts  = new List <ExtraIndex>();

                var pCount  = 0;
                var pCount1 = 0;
                var pCount2 = 0;

                if (unknown1 > 0)
                {
                    for (int i = 0; i < unknown1; i++)
                    {
                        //not sure
                        br.ReadBytes(4);

                        //LoD[0] Extra Data Index
                        var p1 = br.ReadUInt16();

                        //LoD[1] Extra Data Index
                        var p2 = br.ReadUInt16();

                        //LoD[2] Extra Data Index
                        var p3 = br.ReadUInt16();


                        //LoD[0] Extra Data Part Count
                        var p1n = br.ReadUInt16();
                        pCount += p1n;

                        //LoD[1] Extra Data Part Count
                        var p2n = br.ReadUInt16();
                        pCount1 += p2n;

                        //LoD[2] Extra Data Part Count
                        var p3n = br.ReadUInt16();
                        pCount2 += p3n;
                    }
                }

                Dictionary <int, int> indexLoc = new Dictionary <int, int>();

                if (unknown1 > 0)
                {
                    for (int i = 0; i < modelData.LoD[0].MeshCount; i++)
                    {
                        var ido = modelData.LoD[0].MeshList[i].MeshInfo.IndexDataOffset;
                        indexLoc.Add(ido, i);
                    }
                }


                List <int>            maskCounts       = new List <int>();
                Dictionary <int, int> totalExtraCounts = new Dictionary <int, int>();
                if (unknown2 > 0)
                {
                    for (int i = 0; i < pCount; i++)
                    {
                        //Index Offset Start
                        var m1   = br.ReadInt32();
                        var iLoc = 0;
                        if (indexLoc.ContainsKey(m1))
                        {
                            iLoc = indexLoc[m1];
                        }

                        //index count
                        var mCount = br.ReadInt32();

                        //index offset in unk3
                        var mOffset = br.ReadInt32();

                        indexCounts.Add(new ExtraIndex()
                        {
                            IndexLocation = iLoc, IndexCount = mCount
                        });
                        maskCounts.Add(mCount);
                    }

                    br.ReadBytes((pCount1 + pCount2) * 12);
                }

                int totalLoD0MaskCount = 0;

                if (unknown2 > 0)
                {
                    for (int i = 0; i < pCount; i++)
                    {
                        totalLoD0MaskCount += maskCounts[i];
                    }
                }

                if (unknown3 > 0)
                {
                    var unk3Remainder = (unknown3 * 4) - (totalLoD0MaskCount * 4);

                    foreach (var ic in indexCounts)
                    {
                        HashSet <int> mIndexList = new HashSet <int>();

                        for (int i = 0; i < ic.IndexCount; i++)
                        {
                            //index its replacing? attatched to?
                            br.ReadBytes(2);
                            //extra index following last equipment index
                            var mIndex = br.ReadInt16();
                            mIndexList.Add(mIndex);

                            if (extraIndices.ContainsKey(ic.IndexLocation))
                            {
                                extraIndices[ic.IndexLocation].Add(mIndex);
                            }
                            else
                            {
                                extraIndices.Add(ic.IndexLocation, new List <int>()
                                {
                                    mIndex
                                });
                            }
                        }

                        if (totalExtraCounts.ContainsKey(ic.IndexLocation))
                        {
                            totalExtraCounts[ic.IndexLocation] += mIndexList.Count;
                        }
                        else
                        {
                            totalExtraCounts.Add(ic.IndexLocation, mIndexList.Count);
                        }
                    }
                    //the rest of unk3
                    br.ReadBytes(unk3Remainder);
                }



                if (unknown3 > 0)
                {
                    foreach (var ei in extraIndices)
                    {
                        indexMin.Add(ei.Key, ei.Value.Min());
                    }

                    extraIndexData.indexCounts      = indexCounts;
                    extraIndexData.indexMin         = indexMin;
                    extraIndexData.totalExtraCounts = totalExtraCounts;
                    extraIndexData.extraIndices     = extraIndices;

                    modelData.ExtraData = extraIndexData;
                }

                //br.ReadBytes(unknown3 * 4);

                var boneIndexSize = br.ReadInt32();

                for (int i = 0; i < boneIndexSize / 2; i++)
                {
                    modelData.BoneIndicies.Add(br.ReadInt16());
                }

                int padding = br.ReadByte();
                br.ReadBytes(padding);

                for (int i = 0; i < 4; i++)
                {
                    ModelMaterial.BoundingBox boundingBox = new ModelMaterial.BoundingBox();
                    for (int j = 0; j < 4; j++)
                    {
                        boundingBox.PointA.Add(br.ReadSingle());
                    }
                    for (int k = 0; k < 4; k++)
                    {
                        boundingBox.PointB.Add(br.ReadSingle());
                    }

                    modelData.BoundingBoxes.Add(boundingBox);
                }

                //float4x4
                for (int i = 0; i < boneStringCount; i++)
                {
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());

                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                }

                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < modelData.LoD[i].MeshCount; j++)
                    {
                        Mesh mesh = modelData.LoD[i].MeshList[j];

                        for (int k = 0; k < mesh.MeshInfo.VertexDataBlockCount; k++)
                        {
                            br.BaseStream.Seek(modelData.LoD[i].VertexOffset + mesh.MeshInfo.VertexDataOffsets[k], SeekOrigin.Begin);

                            mesh.MeshVertexData.Add(br.ReadBytes(mesh.MeshInfo.VertexSizes[k] * mesh.MeshInfo.VertexCount));
                        }

                        br.BaseStream.Seek(modelData.LoD[i].IndexOffset + (mesh.MeshInfo.IndexDataOffset * 2), SeekOrigin.Begin);

                        mesh.IndexData = br.ReadBytes(2 * mesh.MeshInfo.IndexCount);
                    }
                }

                int vertex = 0, coordinates = 0, normals = 0, tangents = 0, colors = 0, blendWeights = 0, blendIndices = 0;

                for (int i = 0; i < modelData.LoD[0].MeshCount; i++)
                {
                    objBytes.Clear();

                    var vertexList        = new Vector3Collection();
                    var texCoordList      = new Vector2Collection();
                    var texCoordList2     = new Vector2Collection();
                    var normalList        = new Vector3Collection();
                    var tangentList       = new Vector3Collection();
                    var colorsList        = new Color4Collection();
                    var indexList         = new IntCollection();
                    var blendWeightList   = new List <float>();
                    var blendWeightList2  = new List <float[]>();
                    var blendIndicesList  = new List <int>();
                    var blendIndicesList2 = new List <int[]>();
                    var weightCounts      = new List <int>();


                    Mesh mesh = modelData.LoD[0].MeshList[i];

                    MeshDataInfo[] meshDataInfoList = mesh.MeshDataInfoList;

                    int c = 0;
                    foreach (var meshDataInfo in meshDataInfoList)
                    {
                        if (meshDataInfo.UseType == 0)
                        {
                            vertex = c;
                        }
                        else if (meshDataInfo.UseType == 1)
                        {
                            blendWeights = c;
                        }
                        else if (meshDataInfo.UseType == 2)
                        {
                            blendIndices = c;
                        }
                        else if (meshDataInfo.UseType == 3)
                        {
                            normals = c;
                        }
                        else if (meshDataInfo.UseType == 4)
                        {
                            coordinates = c;
                        }
                        else if (meshDataInfo.UseType == 6)
                        {
                            tangents = c;
                        }
                        else if (meshDataInfo.UseType == 7)
                        {
                            colors = c;
                        }

                        c++;
                    }

                    /*
                     * -----------------
                     * Vertex
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[vertex].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[vertex].VertexDataBlock] + meshDataInfoList[vertex].Offset, SeekOrigin.Begin);

                            Vector3 vVector = new Vector3();
                            if (meshDataInfoList[vertex].DataType == 13 || meshDataInfoList[vertex].DataType == 14)
                            {
                                System.Half h1 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h2 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h3 = System.Half.ToHalf((ushort)br1.ReadInt16());

                                float x = HalfHelper.HalfToSingle(h1);
                                float y = HalfHelper.HalfToSingle(h2);
                                float z = HalfHelper.HalfToSingle(h3);

                                vVector = new Vector3(x, y, z);
                                objBytes.Add("v " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                            }
                            else if (meshDataInfoList[vertex].DataType == 2)
                            {
                                var x = BitConverter.ToSingle(br1.ReadBytes(4), 0);
                                var y = BitConverter.ToSingle(br1.ReadBytes(4), 0);
                                var z = BitConverter.ToSingle(br1.ReadBytes(4), 0);

                                vVector = new Vector3(x, y, z);
                                objBytes.Add("v " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                            }

                            vertexList.Add(vVector);
                        }
                    }


                    /*
                     * -----------------
                     * Blend Weight
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[blendWeights].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[blendWeights].VertexDataBlock] + meshDataInfoList[blendWeights].Offset, SeekOrigin.Begin);

                            float x = br1.ReadByte() / 255.0f;
                            float y = br1.ReadByte() / 255.0f;
                            float z = br1.ReadByte() / 255.0f;
                            float w = br1.ReadByte() / 255.0f;

                            int count = 0;
                            if (x != 0)
                            {
                                blendWeightList.Add(x);
                                count++;

                                if (y != 0)
                                {
                                    blendWeightList.Add(y);
                                    count++;

                                    if (z != 0)
                                    {
                                        blendWeightList.Add(z);
                                        count++;

                                        if (w != 0)
                                        {
                                            blendWeightList.Add(w);
                                            count++;
                                        }
                                    }
                                }
                            }

                            if (count == 1)
                            {
                                blendWeightList2.Add(new float[] { x });
                            }
                            else if (count == 2)
                            {
                                blendWeightList2.Add(new float[] { x, y });
                            }
                            else if (count == 3)
                            {
                                blendWeightList2.Add(new float[] { x, y, z });
                            }
                            else if (count == 4)
                            {
                                blendWeightList2.Add(new float[] { x, y, z, w });
                            }

                            weightCounts.Add(count);
                        }
                    }


                    /*
                     * -----------------
                     * Blend Index
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[blendIndices].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[blendIndices].VertexDataBlock] + meshDataInfoList[blendIndices].Offset, SeekOrigin.Begin);

                            int x = br1.ReadByte();
                            int y = br1.ReadByte();
                            int z = br1.ReadByte();
                            int w = br1.ReadByte();

                            if (weightCounts[j] == 1)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList2.Add(new int[] { x });
                            }
                            else if (weightCounts[j] == 2)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList.Add(y);
                                blendIndicesList2.Add(new int[] { x, y });
                            }
                            else if (weightCounts[j] == 3)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList.Add(y);
                                blendIndicesList.Add(z);
                                blendIndicesList2.Add(new int[] { x, y, z });
                            }
                            else if (weightCounts[j] == 4)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList.Add(y);
                                blendIndicesList.Add(z);
                                blendIndicesList.Add(w);
                                blendIndicesList2.Add(new int[] { x, y, z, w });
                            }
                        }
                    }


                    /*
                     * -----------------
                     * Texture Coordinates
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[coordinates].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[coordinates].VertexDataBlock] + meshDataInfoList[coordinates].Offset, SeekOrigin.Begin);

                            float x = 0;
                            float y = 0;
                            float z = 0;
                            float w = 0;
                            if (meshDataInfoList[coordinates].DataType == 13 || meshDataInfoList[coordinates].DataType == 14)
                            {
                                var sx = (ushort)br1.ReadInt16();
                                var sy = (ushort)br1.ReadInt16();
                                var sz = (ushort)br1.ReadInt16();
                                var sw = (ushort)br1.ReadInt16();

                                var h1 = new SharpDX.Half(sx);
                                var h2 = new SharpDX.Half(sy);
                                var h3 = new SharpDX.Half(sz);
                                var h4 = new SharpDX.Half(sw);

                                x = h1;
                                y = h2;
                                z = h3;
                                w = h4;
                            }
                            else if (meshDataInfoList[coordinates].DataType == 1)
                            {
                                x = br1.ReadSingle();
                                y = br1.ReadSingle();
                            }
                            else
                            {
                                x = br1.ReadSingle();
                                y = br1.ReadSingle();
                                z = br1.ReadSingle();
                                w = br1.ReadSingle();
                            }


                            var ox = x - Math.Truncate(x);
                            var oy = y - Math.Truncate(y);

                            objBytes.Add("vt " + ox.ToString("N5") + " " + (1 - y).ToString("N5") + " ");
                            texCoordList.Add(new Vector2(x, y));
                            texCoordList2.Add(new Vector2(z, w));
                        }
                    }



                    /*
                     * -----------------
                     * Normals
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[normals].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[normals].VertexDataBlock] + meshDataInfoList[normals].Offset, SeekOrigin.Begin);

                            float x = 0;
                            float y = 0;
                            float z = 0;
                            float w = 0;

                            if (meshDataInfoList[normals].DataType == 13 || meshDataInfoList[normals].DataType == 14)
                            {
                                System.Half h1 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h2 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h3 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h4 = System.Half.ToHalf((ushort)br1.ReadInt16());

                                x = HalfHelper.HalfToSingle(h1);
                                y = HalfHelper.HalfToSingle(h2);
                                z = HalfHelper.HalfToSingle(h3);
                                w = HalfHelper.HalfToSingle(h4);
                            }
                            else
                            {
                                x = br1.ReadSingle();
                                y = br1.ReadSingle();
                                z = br1.ReadSingle();
                            }

                            var nv = new Vector3(x, y, z);

                            objBytes.Add("vn " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                            normalList.Add(nv);
                        }
                    }


                    /*
                     * -----------------
                     * Tangents
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[tangents].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[tangents].VertexDataBlock] + meshDataInfoList[tangents].Offset, SeekOrigin.Begin);

                            int x = br1.ReadByte();
                            int y = br1.ReadByte();
                            int z = br1.ReadByte();
                            int w = br1.ReadByte();

                            var x1 = x * 2 / 255f - 1f;
                            var y1 = y * 2 / 255f - 1f;
                            var z1 = z * 2 / 255f - 1f;
                            var w1 = w * 2 / 255f - 1f;


                            var nv = new Vector3(x1, y1, z1);

                            tangentList.Add(nv);
                        }
                    }


                    /*
                     * -----------------
                     * Vertex Color
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[colors].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[colors].VertexDataBlock] + meshDataInfoList[colors].Offset, SeekOrigin.Begin);

                            int a = br1.ReadByte();
                            int r = br1.ReadByte();
                            int g = br1.ReadByte();
                            int b = br1.ReadByte();

                            colorsList.Add(new Color4(r, g, b, a));
                        }
                    }


                    /*
                     * -----------------
                     * Index
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.IndexData)))
                    {
                        for (int j = 0; j < mesh.MeshInfo.IndexCount; j += 3)
                        {
                            int i1 = br1.ReadInt16();
                            int i2 = br1.ReadInt16();
                            int i3 = br1.ReadInt16();

                            objBytes.Add("f " + (i1 + 1) + "/" + (i1 + 1) + "/" + (i1 + 1) + " " + (i2 + 1) + "/" + (i2 + 1) + "/" + (i2 + 1) + " " + (i3 + 1) + "/" + (i3 + 1) + "/" + (i3 + 1) + " ");

                            indexList.Add(i1);
                            indexList.Add(i2);
                            indexList.Add(i3);
                        }
                    }

                    ModelMeshData modelMeshData = new ModelMeshData()
                    {
                        Vertices              = vertexList,
                        Normals               = normalList,
                        TextureCoordinates    = texCoordList,
                        TextureCoordinates2   = texCoordList2,
                        BiTangents            = tangentList,
                        Indices               = indexList,
                        VertexColors          = colorsList,
                        OBJFileData           = objBytes.ToArray(),
                        BoneStrings           = boneStrings,
                        BoneIndices           = modelData.BoneIndicies,
                        BoneTransforms        = boneTransforms,
                        BlendWeights          = blendWeightList,
                        BlendIndices          = blendIndicesList,
                        WeightCounts          = weightCounts,
                        MeshPartList          = mesh.MeshPartList,
                        BlendIndicesArrayList = blendIndicesList2,
                        BlendWeightsArrayList = blendWeightList2,
                        MaterialNum           = mesh.MeshInfo.MaterialNum,
                        MeshPartCount         = mesh.MeshInfo.MeshPartCount,
                        MeshPartOffset        = mesh.MeshInfo.MeshPartOffset
                    };

                    meshList.Add(modelMeshData);
                }
            }
        }
Exemple #11
0
        /// <summary>
        /// Dialog for Mod List
        /// </summary>
        public ModListForm()
        {
            InitializeComponent();
            listView1.View      = View.Details;
            listView1.GridLines = true;
            FFCRC crc = new FFCRC();

            Dictionary <string, string> raceIDDict = new Dictionary <string, string>();

            raceIDDict.Add("0101", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Male);
            raceIDDict.Add("0104", Resources.strings.Hyur + " " + Resources.strings.Male + " NPC");
            raceIDDict.Add("0201", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Female);
            raceIDDict.Add("0204", Resources.strings.Hyur + " " + Resources.strings.Female + " NPC");
            raceIDDict.Add("0301", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Male);
            raceIDDict.Add("0401", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Female);
            raceIDDict.Add("0501", Resources.strings.Elezen + " " + Resources.strings.Male);
            raceIDDict.Add("0504", Resources.strings.Elezen + " " + Resources.strings.Male + " NPC");
            raceIDDict.Add("0601", Resources.strings.Elezen + " " + Resources.strings.Female);
            raceIDDict.Add("0604", Resources.strings.Elezen + " " + Resources.strings.Female + " NPC");
            raceIDDict.Add("0701", Resources.strings.Miqote + " " + Resources.strings.Male);
            raceIDDict.Add("0801", Resources.strings.Miqote + " " + Resources.strings.Female);
            raceIDDict.Add("0804", Resources.strings.Miqote + " " + Resources.strings.Female + " NPC");
            raceIDDict.Add("0901", Resources.strings.Roegadyn + " " + Resources.strings.Male);
            raceIDDict.Add("1001", Resources.strings.Roegadyn + " " + Resources.strings.Female);
            raceIDDict.Add("1101", Resources.strings.Lalafell + " " + Resources.strings.Male);
            raceIDDict.Add("1201", Resources.strings.Lalafell + " " + Resources.strings.Female);
            raceIDDict.Add("1301", Resources.strings.Au_Ra + " " + Resources.strings.Male);
            raceIDDict.Add("1401", Resources.strings.Au_Ra + " " + Resources.strings.Female);
            raceIDDict.Add("9104", "NPC " + Resources.strings.Male);
            raceIDDict.Add("9204", "NPC " + Resources.strings.Female);

            string isActive, partName = "", partNum = "", race;

            listView1.Columns.Add("Name", -2, HorizontalAlignment.Left);
            listView1.Columns.Add("Race", -2, HorizontalAlignment.Left);
            listView1.Columns.Add("Map", -2, HorizontalAlignment.Left);
            listView1.Columns.Add("Part", -2, HorizontalAlignment.Left);
            listView1.Columns.Add("Part 2", -2, HorizontalAlignment.Left);
            listView1.Columns.Add("Active", -2, HorizontalAlignment.Left);

            foreach (string line in File.ReadLines(Properties.Settings.Default.DefaultDir + "/040000.modlist"))
            {
                jModEntry modEntry = JsonConvert.DeserializeObject <jModEntry>(line);
                modList.Add(modEntry);

                if (!modEntry.name.Contains("decal") && !modEntry.name.Contains("mt_m") && !modEntry.name.Contains("1_m") && !modEntry.name.Contains("2_m") &&
                    !modEntry.name.Contains("1_d"))
                {
                    string sName = modEntry.name;
                    race = raceIDDict[sName.Substring(sName.IndexOf('c') + 1, 4)];
                    if (race == null && sName.Contains("_w"))
                    {
                        race = "ALL";
                    }
                }
                else if (modEntry.name.Contains("decal"))
                {
                    race = "ALL";
                }
                else
                {
                    race = "Monsters";
                }

                if (modEntry.textureName == null)
                {
                    isActive = "Unknown";
                }
                else
                {
                    IOHelper ioHelper = new IOHelper();
                    if (!modEntry.name.Contains("mt_"))
                    {
                        isActive = ioHelper.isActive(crc.text(modEntry.name + ".tex"), modEntry.folder, modEntry.modOffset).ToString();
                    }
                    else
                    {
                        isActive = ioHelper.isActive(crc.text(modEntry.name + ".mtrl"), modEntry.folder, modEntry.modOffset).ToString();
                    }
                }

                if (modEntry.textureName == null)
                {
                    canGo = false;
                    modEntry.textureName = modEntry.name;
                }
                else
                {
                    canGo = true;
                }

                if (modEntry.name.Contains("f0"))
                {
                    string sName = modEntry.name;
                    int    val   = int.Parse(sName.Substring(sName.IndexOf('f') + 1, 4));
                    partName = val.ToString();;
                }
                else if (modEntry.name.Contains("b0"))
                {
                    string sName = modEntry.name;
                    int    val   = int.Parse(sName.Substring(sName.IndexOf('b') + 1, 4));
                    partName = val.ToString();;
                }
                else if (modEntry.name.Contains("h0"))
                {
                    string sName = modEntry.name;
                    int    val   = int.Parse(sName.Substring(sName.IndexOf('h') + 1, 4));
                    partName = val.ToString();;
                }
                else if (modEntry.name.Contains("t0"))
                {
                    string sName = modEntry.name;
                    int    val   = int.Parse(sName.Substring(sName.IndexOf('t') + 1, 4));
                    partName = val.ToString();;
                }
                else if (modEntry.name.Contains("decal"))
                {
                    string sName = modEntry.name;
                    int    val   = int.Parse(sName.Substring(sName.LastIndexOf('_') + 1));
                    partName = val.ToString();;
                }
                else if (modEntry.name.Contains("mt"))
                {
                    string sName = modEntry.name;
                    partName = sName.Substring(sName.LastIndexOf('_') + 1);
                }
                else if (modEntry.name.Contains("1_d"))
                {
                    string sName = modEntry.name;
                    partName = sName.Substring(sName.LastIndexOf('_') - 3, 3);
                }
                else
                {
                    partName = "a";
                }

                if (modEntry.name.Contains("f0"))
                {
                    if (modEntry.name.Contains("_fac"))
                    {
                        partNum = "Face";
                    }
                    else if (modEntry.name.Contains("_iri"))
                    {
                        partNum = "Iris";
                    }
                    else if (modEntry.name.Contains("_etc"))
                    {
                        partNum = "Etc";
                    }
                }
                else if (modEntry.name.Contains("h0"))
                {
                    if (modEntry.name.Contains("_hir"))
                    {
                        partNum = "Hair";
                    }
                    if (modEntry.name.Contains("_acc"))
                    {
                        partNum = "Accessory";
                    }
                }
                else
                {
                    partNum = "";
                }

                ListViewItem itemsList = new ListViewItem(modEntry.textureName);
                itemsList.SubItems.Add(race);
                itemsList.SubItems.Add(texMap(modEntry.name));
                itemsList.SubItems.Add(partName);
                itemsList.SubItems.Add(partNum);
                itemsList.SubItems.Add(isActive);

                listView1.Items.Add(itemsList);
            }
            modGoToButton.Enabled = false;
            switchButton.Enabled  = false;
        }
Exemple #12
0
        /// <summary>
        /// Parses the MDL file to obtain model information
        /// </summary>
        /// <param name="selectedItem">The currently selected item</param>
        /// <param name="selectedRace">The currently selected race</param>
        /// <param name="selectedBody">The currently selected body</param>
        /// <param name="selectedPart">The currently selected part</param>
        /// <param name="selectedCategory">The items category </param>
        public MDL(ItemData selectedItem, string selectedCategory, string selectedRace, string selectedBody, string selectedPart)
        {
            string itemType  = Helper.GetCategoryType(selectedCategory);
            string MDLFolder = "";

            if (itemType.Equals("weapon") || itemType.Equals("food"))
            {
                if (selectedPart.Equals("Secondary"))
                {
                    MDLFolder = string.Format(Strings.WeapMDLFolder, selectedItem.SecondaryModelID, selectedItem.SecondaryModelBody);
                    MDLFile   = string.Format(Strings.WeapMDLFile, selectedItem.SecondaryModelID, selectedItem.SecondaryModelBody);
                }
                else
                {
                    MDLFolder = string.Format(Strings.WeapMDLFolder, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody);
                    MDLFile   = string.Format(Strings.WeapMDLFile, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody);
                }
            }
            else if (itemType.Equals("accessory"))
            {
                MDLFolder = string.Format(Strings.AccMDLFolder, selectedItem.PrimaryModelID);
                MDLFile   = string.Format(Strings.AccMDLFile, selectedRace, selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
            }
            else if (itemType.Equals("character"))
            {
                if (selectedItem.ItemName.Equals(Strings.Body))
                {
                    MDLFolder = string.Format(Strings.BodyMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.BodyMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Face))
                {
                    MDLFolder = string.Format(Strings.FaceMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.FaceMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Hair))
                {
                    MDLFolder = string.Format(Strings.HairMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.HairMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Tail))
                {
                    MDLFolder = string.Format(Strings.TailMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.TailMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
            }
            else if (itemType.Equals("monster"))
            {
                bool isDemiHuman = false;
                if (selectedItem.PrimaryMTRLFolder != null)
                {
                    isDemiHuman = selectedItem.PrimaryMTRLFolder.Contains("demihuman");
                }

                if (isDemiHuman)
                {
                    MDLFolder = string.Format(Strings.DemiMDLFolder, selectedItem.PrimaryModelID.PadLeft(4, '0'), selectedItem.PrimaryModelBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.DemiMDLFile, selectedItem.PrimaryModelID.PadLeft(4, '0'), selectedItem.PrimaryModelBody, selectedPart);
                }
                else
                {
                    MDLFolder = string.Format(Strings.MonsterMDLFolder, selectedItem.PrimaryModelID.PadLeft(4, '0'), selectedItem.PrimaryModelBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.MonsterMDLFile, selectedItem.PrimaryModelID.PadLeft(4, '0'), selectedItem.PrimaryModelBody.PadLeft(4, '0'));
                }
            }
            else
            {
                MDLFolder = string.Format(Strings.EquipMDLFolder, selectedItem.PrimaryModelID);

                if (selectedPart.Equals("-"))
                {
                    MDLFile = string.Format(Strings.EquipMDLFile, selectedRace, selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
                }
                else
                {
                    MDLFile = string.Format(Strings.EquipMDLFile, selectedRace, selectedItem.PrimaryModelID, selectedPart);
                }
            }

            fullPath = MDLFolder + "/" + MDLFile;
            int offset = Helper.GetDataOffset(FFCRC.GetHash(MDLFolder), FFCRC.GetHash(MDLFile), Strings.ItemsDat);

            if (offset == 0)
            {
                if (itemType.Equals("weapon"))
                {
                    if (selectedPart.Equals("Secondary"))
                    {
                        MDLFolder = string.Format(Strings.EquipMDLFolder, selectedItem.SecondaryModelID);
                        MDLFile   = string.Format(Strings.EquipMDLFile, "0101", selectedItem.SecondaryModelID, Info.slotAbr[Strings.Hands]);

                        offset = Helper.GetDataOffset(FFCRC.GetHash(MDLFolder), FFCRC.GetHash(MDLFile), Strings.ItemsDat);
                    }
                }
            }

            int datNum = ((offset / 8) & 0x000f) / 2;

            var MDLDatData = Helper.GetType3DecompressedData(offset, datNum, Strings.ItemsDat);

            using (BinaryReader br = new BinaryReader(new MemoryStream(MDLDatData.Item1)))
            {
                // The size of the header + (size of the mesh information block (136 bytes) * the meshes) + padding
                br.BaseStream.Seek(64 + 136 * MDLDatData.Item2 + 4, SeekOrigin.Begin);

                var modelStringCount = br.ReadInt32();
                var stringBlockSize  = br.ReadInt32();
                var stringBlock      = br.ReadBytes(stringBlockSize);

                var unknown = br.ReadBytes(4);

                var totalMeshCount       = br.ReadInt16();
                var attributeStringCount = br.ReadInt16();
                var meshPartsCount       = br.ReadInt16();
                var materialStringCount  = br.ReadInt16();
                var boneStringCount      = br.ReadInt16();
                var boneListCount        = br.ReadInt16();


                //Has something to do with amount of extra vertex data.
                var unknown1 = br.ReadInt16();

                //Has something to do with amount of extra vertex data.
                var unknown2 = br.ReadInt16();


                var unknown3 = br.ReadInt16();

                // Seems to always be 1027
                var unknown4 = br.ReadInt16();


                var unknown5 = br.ReadInt16();
                var unknown6 = br.ReadInt16();

                br.ReadBytes(10);

                var unknown7 = br.ReadInt16();

                br.ReadBytes(16);

                using (BinaryReader br1 = new BinaryReader(new MemoryStream(stringBlock)))
                {
                    br1.BaseStream.Seek(0, SeekOrigin.Begin);

                    for (int i = 0; i < attributeStringCount; i++)
                    {
                        byte        a;
                        List <byte> atrName = new List <byte>();
                        while ((a = br1.ReadByte()) != 0)
                        {
                            atrName.Add(a);
                        }
                        string atr = Encoding.ASCII.GetString(atrName.ToArray());
                        atr = atr.Replace("\0", "");

                        modelData.Attributes.Add(atr);
                        atrStrings.Add(atr);
                    }

                    for (int i = 0; i < boneStringCount; i++)
                    {
                        byte        b;
                        List <byte> boneName = new List <byte>();
                        while ((b = br1.ReadByte()) != 0)
                        {
                            boneName.Add(b);
                        }
                        string bone = Encoding.ASCII.GetString(boneName.ToArray());
                        bone = bone.Replace("\0", "");

                        modelData.Bones.Add(bone);
                        boneStrings.Add(bone);
                    }

                    for (int i = 0; i < materialStringCount; i++)
                    {
                        byte        b;
                        List <byte> name = new List <byte>();
                        while ((b = br1.ReadByte()) != 0)
                        {
                            name.Add(b);
                        }
                        string material = Encoding.ASCII.GetString(name.ToArray());
                        material = material.Replace("\0", "");

                        modelData.Materials.Add(material);
                        materialStrings.Add(material);
                    }
                }

                byte[] unknown5Bytes = br.ReadBytes(32 * unknown5);

                for (int i = 0; i < 3; i++)
                {
                    LevelOfDetail LoD = new LevelOfDetail();
                    LoD.MeshOffset = br.ReadInt16();
                    LoD.MeshCount  = br.ReadInt16();

                    br.ReadBytes(40);

                    LoD.VertexDataSize = br.ReadInt32();
                    LoD.IndexDataSize  = br.ReadInt32();
                    LoD.VertexOffset   = br.ReadInt32();
                    LoD.IndexOffset    = br.ReadInt32();

                    modelData.LoD.Add(LoD);
                }

                var savePos      = br.BaseStream.Position;
                var lodStructPos = 68;

                for (int i = 0; i < modelData.LoD.Count; i++)
                {
                    List <MeshDataInfo> meshInfoList = new List <MeshDataInfo>();

                    for (int j = 0; j < modelData.LoD[i].MeshCount; j++)
                    {
                        modelData.LoD[i].MeshList.Add(new Mesh());
                        meshInfoList.Clear();

                        br.BaseStream.Seek((j * 136) + lodStructPos, SeekOrigin.Begin);
                        var dataBlockNum = br.ReadByte();

                        while (dataBlockNum != 255)
                        {
                            MeshDataInfo meshInfo = new MeshDataInfo()
                            {
                                VertexDataBlock = dataBlockNum,
                                Offset          = br.ReadByte(),
                                DataType        = br.ReadByte(),
                                UseType         = br.ReadByte()
                            };

                            meshInfoList.Add(meshInfo);

                            br.ReadBytes(4);

                            dataBlockNum = br.ReadByte();
                        }

                        modelData.LoD[i].MeshList[j].MeshDataInfoList = meshInfoList.ToArray();
                    }
                    lodStructPos += 136 * modelData.LoD[i].MeshCount;
                }

                br.BaseStream.Seek(savePos, SeekOrigin.Begin);

                for (int x = 0; x < modelData.LoD.Count; x++)
                {
                    for (int i = 0; i < modelData.LoD[x].MeshCount; i++)
                    {
                        MeshInfo meshInfo = new MeshInfo()
                        {
                            VertexCount     = br.ReadInt32(),
                            IndexCount      = br.ReadInt32(),
                            MaterialNum     = br.ReadInt16(),
                            MeshPartOffset  = br.ReadInt16(),
                            MeshPartCount   = br.ReadInt16(),
                            BoneListIndex   = br.ReadInt16(),
                            IndexDataOffset = br.ReadInt32()
                        };

                        modelData.LoD[x].MeshList[i].MaterialId = meshInfo.MaterialNum;
                        var typeChar = materialStrings[meshInfo.MaterialNum][4].ToString() + materialStrings[meshInfo.MaterialNum][9].ToString();

                        modelData.LoD[x].MeshList[i].BoneListIndex = meshInfo.BoneListIndex;
                        if (typeChar.Equals("cb"))
                        {
                            modelData.LoD[x].MeshList[i].IsBody = true;
                        }

                        for (int j = 0; j < 3; j++)
                        {
                            meshInfo.VertexDataOffsets.Add(br.ReadInt32());
                        }

                        for (int k = 0; k < 3; k++)
                        {
                            meshInfo.VertexSizes.Add(br.ReadByte());
                        }

                        meshInfo.VertexDataBlockCount = br.ReadByte();

                        modelData.LoD[x].MeshList[i].MeshInfo = meshInfo;
                    }
                }

                byte[] attributeOffsetBytes = br.ReadBytes(attributeStringCount * 4);
                br.ReadBytes(unknown6 * 20);

                for (int i = 0; i < modelData.LoD.Count; i++)
                {
                    foreach (var mesh in modelData.LoD[i].MeshList)
                    {
                        for (int j = 0; j < mesh.MeshInfo.MeshPartCount; j++)
                        {
                            MeshPart meshPart = new MeshPart()
                            {
                                IndexOffset = br.ReadInt32(),
                                IndexCount  = br.ReadInt32(),
                                Attributes  = br.ReadInt32(),
                                BoneOffset  = br.ReadInt16(),
                                BoneCount   = br.ReadInt16()
                            };

                            mesh.MeshPartList.Add(meshPart);
                        }
                    }
                }

                br.ReadBytes(unknown7 * 12);
                br.ReadBytes(materialStringCount * 4);

                List <int> boneIncrements = new List <int>();

                // Loop through the increments and save their data.
                for (int i = 0; i < boneStringCount; i++)
                {
                    int increment = br.ReadInt32();
                    boneIncrements.Add(increment);
                }


                for (int i = 0; i < boneListCount; i++)
                {
                    Bones bones = new Bones();

                    for (int j = 0; j < 64; j++)
                    {
                        bones.BoneData.Add(br.ReadInt16());
                    }

                    bones.BoneCount = br.ReadInt32();

                    modelData.BoneSet.Add(bones);
                }

                //br.ReadBytes(unknown1 * 16);

                Dictionary <int, int>         indexMin      = new Dictionary <int, int>();
                Dictionary <int, List <int> > extraIndices  = new Dictionary <int, List <int> >();
                Dictionary <int, List <int> > extraIndices2 = new Dictionary <int, List <int> >();
                var indexCounts = new List <List <ExtraIndex> >();

                // One for each LoD level.
                indexCounts.Add(new List <ExtraIndex>());
                indexCounts.Add(new List <ExtraIndex>());
                indexCounts.Add(new List <ExtraIndex>());

                var pCounts = new int[3];

                if (unknown1 > 0)
                {
                    for (int i = 0; i < unknown1; i++)
                    {
                        //not sure
                        br.ReadBytes(4);

                        //LoD[0] Extra Data Index
                        var p1 = br.ReadUInt16();

                        //LoD[1] Extra Data Index
                        var p2 = br.ReadUInt16();

                        //LoD[2] Extra Data Index
                        var p3 = br.ReadUInt16();


                        //LoD[0] Extra Data Part Count
                        var p1n = br.ReadUInt16();
                        pCounts[0] += p1n;

                        //LoD[1] Extra Data Part Count
                        var p2n = br.ReadUInt16();
                        pCounts[1] += p2n;

                        //LoD[2] Extra Data Part Count
                        var p3n = br.ReadUInt16();
                        pCounts[2] += p3n;
                    }
                }

                Dictionary <int, int> indexLoc = new Dictionary <int, int>();

                if (unknown1 > 0)
                {
                    for (int i = 0; i < modelData.LoD[LoDViewLevel].MeshCount; i++)
                    {
                        var ido = modelData.LoD[LoDViewLevel].MeshList[i].MeshInfo.IndexDataOffset;

                        if (!indexLoc.ContainsKey(ido))
                        {
                            indexLoc.Add(ido, i);
                        }
                    }
                }


                var totalMaskCounts = new int[3];
                Dictionary <int, int> totalExtraCounts = new Dictionary <int, int>();
                if (unknown2 > 0)
                {
                    for (int x = 0; x < pCounts.Length; x++)
                    {
                        for (int i = 0; i < pCounts[x]; i++)
                        {
                            //Index Offset Start
                            var m1 = br.ReadInt32();

                            //index count
                            var mCount = br.ReadInt32();

                            //index offset in unk3
                            var mOffset = br.ReadInt32();

                            var iLoc = 0;
                            if (indexLoc.ContainsKey(m1))
                            {
                                iLoc = indexLoc[m1];
                            }

                            indexCounts[x].Add(new ExtraIndex()
                            {
                                IndexLocation = iLoc, IndexCount = mCount
                            });
                            totalMaskCounts[x] += mCount;
                        }
                    }
                }


                if (unknown3 > 0)
                {
                    //var unk3Remainder = (unknown3 * 4) - (totalLoD0MaskCount * 4);
                    var c = 0;
                    for (int l = 0; l < indexCounts.Count; l++)
                    {
                        foreach (var ic in indexCounts[l])
                        {
                            HashSet <int> mIndexList = new HashSet <int>();

                            for (int i = 0; i < ic.IndexCount; i++)
                            {
                                //index its replacing? attatched to?
                                var oIndex = br.ReadUInt16();

                                //extra index following last equipment index
                                var mIndex = br.ReadUInt16();

                                if (l == LoDViewLevel)
                                {
                                    mIndexList.Add(mIndex);

                                    if (extraIndices.ContainsKey(ic.IndexLocation))
                                    {
                                        extraIndices[ic.IndexLocation].Add(mIndex);
                                        extraIndices2[ic.IndexLocation].Add(oIndex);
                                    }
                                    else
                                    {
                                        extraIndices.Add(ic.IndexLocation, new List <int>()
                                        {
                                            mIndex
                                        });
                                        extraIndices2.Add(ic.IndexLocation, new List <int>()
                                        {
                                            oIndex
                                        });
                                    }
                                }
                            }

                            if (l == LoDViewLevel)
                            {
                                if (totalExtraCounts.ContainsKey(ic.IndexLocation))
                                {
                                    totalExtraCounts[ic.IndexLocation] += mIndexList.Count;
                                }
                                else
                                {
                                    totalExtraCounts.Add(ic.IndexLocation, mIndexList.Count);
                                }
                            }
                            c++;
                        }
                    }

                    //the rest of unk3
                    //br.ReadBytes(unk3Remainder);

                    foreach (var ei in extraIndices)
                    {
                        indexMin.Add(ei.Key, ei.Value.Min());
                    }

                    extraIndexData.indexCounts      = indexCounts[LoDViewLevel];
                    extraIndexData.indexMin         = indexMin;
                    extraIndexData.totalExtraCounts = totalExtraCounts;
                    extraIndexData.extraIndices     = extraIndices;
                    extraIndexData.extraIndices2    = extraIndices2;

                    modelData.ExtraData = extraIndexData;
                }

                //br.ReadBytes(unknown3 * 4);

                var boneIndexSize = br.ReadInt32();

                for (int i = 0; i < boneIndexSize / 2; i++)
                {
                    modelData.BoneIndicies.Add(br.ReadUInt16());
                }

                int padding = br.ReadByte();
                br.ReadBytes(padding);

                for (int i = 0; i < 4; i++)
                {
                    ModelMaterial.BoundingBox boundingBox = new ModelMaterial.BoundingBox();
                    for (int j = 0; j < 4; j++)
                    {
                        boundingBox.PointA.Add(br.ReadSingle());
                    }
                    for (int k = 0; k < 4; k++)
                    {
                        boundingBox.PointB.Add(br.ReadSingle());
                    }

                    modelData.BoundingBoxes.Add(boundingBox);
                }

                //float4x4
                for (int i = 0; i < boneStringCount; i++)
                {
                    string boneName = boneStrings[i];

                    Vector4 transform1 = new Vector4();
                    Vector4 transform2 = new Vector4();

                    transform1.X = br.ReadSingle();
                    transform1.Y = br.ReadSingle();
                    transform1.Z = br.ReadSingle();
                    transform1.W = br.ReadSingle();

                    transform2.X = br.ReadSingle();
                    transform2.Y = br.ReadSingle();
                    transform2.Z = br.ReadSingle();
                    transform2.W = br.ReadSingle();

                    boneTransforms.Add(transform1.X);
                    boneTransforms.Add(transform1.Y);
                    boneTransforms.Add(transform1.Z);
                    boneTransforms.Add(transform1.W);

                    boneTransforms.Add(transform2.X);
                    boneTransforms.Add(transform2.Y);
                    boneTransforms.Add(transform2.Z);
                    boneTransforms.Add(transform2.W);
                }

                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < modelData.LoD[i].MeshCount; j++)
                    {
                        Mesh mesh = modelData.LoD[i].MeshList[j];

                        for (int k = 0; k < mesh.MeshInfo.VertexDataBlockCount; k++)
                        {
                            br.BaseStream.Seek(modelData.LoD[i].VertexOffset + mesh.MeshInfo.VertexDataOffsets[k], SeekOrigin.Begin);

                            mesh.MeshVertexData.Add(br.ReadBytes(mesh.MeshInfo.VertexSizes[k] * mesh.MeshInfo.VertexCount));
                        }

                        br.BaseStream.Seek(modelData.LoD[i].IndexOffset + (mesh.MeshInfo.IndexDataOffset * 2), SeekOrigin.Begin);

                        mesh.IndexData = br.ReadBytes(2 * mesh.MeshInfo.IndexCount);
                    }
                }



                int vertex = 0, coordinates = 0, normals = 0, tangents = 0, colors = 0, blendWeights = 0, blendIndices = 0;

                for (int i = 0; i < modelData.LoD[LoDViewLevel].MeshCount; i++)
                {
                    objBytes.Clear();

                    var vertexList        = new Vector3Collection();
                    var texCoordList      = new Vector2Collection();
                    var texCoordList2     = new Vector2Collection();
                    var normalList        = new Vector3Collection();
                    var tangentList       = new Vector3Collection();
                    var colorsList        = new Color4Collection();
                    var indexList         = new IntCollection();
                    var blendWeightList   = new List <float>();
                    var blendWeightList2  = new List <float[]>();
                    var blendIndicesList  = new List <int>();
                    var blendIndicesList2 = new List <int[]>();
                    var weightCounts      = new List <int>();
                    var extraVerts        = new HashSet <Vector3>();
                    Dictionary <int, Vector3> extraVertDict = new Dictionary <int, Vector3>();


                    Mesh mesh = modelData.LoD[LoDViewLevel].MeshList[i];

                    MeshDataInfo[] meshDataInfoList = mesh.MeshDataInfoList;

                    int c = 0;
                    foreach (var meshDataInfo in meshDataInfoList)
                    {
                        if (meshDataInfo.UseType == 0)
                        {
                            vertex = c;
                        }
                        else if (meshDataInfo.UseType == 1)
                        {
                            blendWeights = c;
                        }
                        else if (meshDataInfo.UseType == 2)
                        {
                            blendIndices = c;
                        }
                        else if (meshDataInfo.UseType == 3)
                        {
                            normals = c;
                        }
                        else if (meshDataInfo.UseType == 4)
                        {
                            coordinates = c;
                        }
                        else if (meshDataInfo.UseType == 6)
                        {
                            tangents = c;
                        }
                        else if (meshDataInfo.UseType == 7)
                        {
                            colors = c;
                        }

                        c++;
                    }

                    /*
                     * -----------------
                     * Vertex
                     * -----------------
                     */

                    // Only actually read the buffers if they have data in them.
                    if (mesh.MeshVertexData.Count > 0)
                    {
                        using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[vertex].VertexDataBlock])))
                        {
                            for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                            {
                                br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[vertex].VertexDataBlock] + meshDataInfoList[vertex].Offset, SeekOrigin.Begin);

                                Vector3 vVector = new Vector3();
                                if (meshDataInfoList[vertex].DataType == 13 || meshDataInfoList[vertex].DataType == 14)
                                {
                                    System.Half h1 = System.Half.ToHalf(br1.ReadUInt16());
                                    System.Half h2 = System.Half.ToHalf(br1.ReadUInt16());
                                    System.Half h3 = System.Half.ToHalf(br1.ReadUInt16());

                                    float x = HalfHelper.HalfToSingle(h1);
                                    float y = HalfHelper.HalfToSingle(h2);
                                    float z = HalfHelper.HalfToSingle(h3);

                                    vVector = new Vector3(x, y, z);
                                    objBytes.Add("v " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                                }
                                else if (meshDataInfoList[vertex].DataType == 2)
                                {
                                    var x = BitConverter.ToSingle(br1.ReadBytes(4), 0);
                                    var y = BitConverter.ToSingle(br1.ReadBytes(4), 0);
                                    var z = BitConverter.ToSingle(br1.ReadBytes(4), 0);

                                    vVector = new Vector3(x, y, z);
                                    objBytes.Add("v " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                                }

                                vertexList.Add(vVector);
                            }
                        }


                        /*
                         * -----------------
                         * Blend Weight
                         * -----------------
                         */
                        using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[blendWeights].VertexDataBlock])))
                        {
                            for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                            {
                                br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[blendWeights].VertexDataBlock] + meshDataInfoList[blendWeights].Offset, SeekOrigin.Begin);

                                float x = br1.ReadByte() / 255.0f;
                                float y = br1.ReadByte() / 255.0f;
                                float z = br1.ReadByte() / 255.0f;
                                float w = br1.ReadByte() / 255.0f;

                                int count = 0;
                                if (x != 0)
                                {
                                    blendWeightList.Add(x);
                                    count++;

                                    if (y != 0)
                                    {
                                        blendWeightList.Add(y);
                                        count++;

                                        if (z != 0)
                                        {
                                            blendWeightList.Add(z);
                                            count++;

                                            if (w != 0)
                                            {
                                                blendWeightList.Add(w);
                                                count++;
                                            }
                                        }
                                    }
                                }

                                if (count == 1)
                                {
                                    blendWeightList2.Add(new float[] { x });
                                }
                                else if (count == 2)
                                {
                                    blendWeightList2.Add(new float[] { x, y });
                                }
                                else if (count == 3)
                                {
                                    blendWeightList2.Add(new float[] { x, y, z });
                                }
                                else if (count == 4)
                                {
                                    blendWeightList2.Add(new float[] { x, y, z, w });
                                }

                                weightCounts.Add(count);
                            }
                        }


                        /*
                         * -----------------
                         * Blend Index
                         * -----------------
                         */
                        using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[blendIndices].VertexDataBlock])))
                        {
                            for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                            {
                                br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[blendIndices].VertexDataBlock] + meshDataInfoList[blendIndices].Offset, SeekOrigin.Begin);

                                int x = br1.ReadByte();
                                int y = br1.ReadByte();
                                int z = br1.ReadByte();
                                int w = br1.ReadByte();

                                if (weightCounts[j] == 1)
                                {
                                    blendIndicesList.Add(x);
                                    blendIndicesList2.Add(new int[] { x });
                                }
                                else if (weightCounts[j] == 2)
                                {
                                    blendIndicesList.Add(x);
                                    blendIndicesList.Add(y);
                                    blendIndicesList2.Add(new int[] { x, y });
                                }
                                else if (weightCounts[j] == 3)
                                {
                                    blendIndicesList.Add(x);
                                    blendIndicesList.Add(y);
                                    blendIndicesList.Add(z);
                                    blendIndicesList2.Add(new int[] { x, y, z });
                                }
                                else if (weightCounts[j] == 4)
                                {
                                    blendIndicesList.Add(x);
                                    blendIndicesList.Add(y);
                                    blendIndicesList.Add(z);
                                    blendIndicesList.Add(w);
                                    blendIndicesList2.Add(new int[] { x, y, z, w });
                                }
                            }
                        }

                        /*
                         * -----------------
                         * Texture Coordinates
                         * -----------------
                         */
                        using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[coordinates].VertexDataBlock])))
                        {
                            for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                            {
                                br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[coordinates].VertexDataBlock] + meshDataInfoList[coordinates].Offset, SeekOrigin.Begin);

                                float x = 0;
                                float y = 0;
                                float z = 0;
                                float w = 0;
                                if (meshDataInfoList[coordinates].DataType == 13 || meshDataInfoList[coordinates].DataType == 14)
                                {
                                    var sx = br1.ReadUInt16();
                                    var sy = br1.ReadUInt16();
                                    var sz = br1.ReadUInt16();
                                    var sw = br1.ReadUInt16();

                                    var h1 = new SharpDX.Half(sx);
                                    var h2 = new SharpDX.Half(sy);
                                    var h3 = new SharpDX.Half(sz);
                                    var h4 = new SharpDX.Half(sw);

                                    x = h1;
                                    y = h2;
                                    z = h3;
                                    w = h4;
                                }
                                else if (meshDataInfoList[coordinates].DataType == 1)
                                {
                                    x = br1.ReadSingle();
                                    y = br1.ReadSingle();
                                }
                                else
                                {
                                    x = br1.ReadSingle();
                                    y = br1.ReadSingle();
                                    z = br1.ReadSingle();
                                    w = br1.ReadSingle();
                                }


                                var ox = x - Math.Truncate(x);
                                var oy = y - Math.Truncate(y);

                                objBytes.Add("vt " + ox.ToString("N5") + " " + (1 - y).ToString("N5") + " ");
                                texCoordList.Add(new Vector2(x, y));
                                texCoordList2.Add(new Vector2(z, w));
                            }
                        }



                        /*
                         * -----------------
                         * Normals
                         * -----------------
                         */
                        using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[normals].VertexDataBlock])))
                        {
                            for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                            {
                                br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[normals].VertexDataBlock] + meshDataInfoList[normals].Offset, SeekOrigin.Begin);

                                float x = 0;
                                float y = 0;
                                float z = 0;
                                float w = 0;

                                if (meshDataInfoList[normals].DataType == 13 || meshDataInfoList[normals].DataType == 14)
                                {
                                    System.Half h1 = System.Half.ToHalf(br1.ReadUInt16());
                                    System.Half h2 = System.Half.ToHalf(br1.ReadUInt16());
                                    System.Half h3 = System.Half.ToHalf(br1.ReadUInt16());
                                    System.Half h4 = System.Half.ToHalf(br1.ReadUInt16());

                                    x = HalfHelper.HalfToSingle(h1);
                                    y = HalfHelper.HalfToSingle(h2);
                                    z = HalfHelper.HalfToSingle(h3);
                                    w = HalfHelper.HalfToSingle(h4);
                                }
                                else
                                {
                                    x = br1.ReadSingle();
                                    y = br1.ReadSingle();
                                    z = br1.ReadSingle();
                                }

                                var nv = new Vector3(x, y, z);

                                objBytes.Add("vn " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                                normalList.Add(nv);
                            }
                        }


                        /*
                         * -----------------
                         * Tangents
                         * -----------------
                         */
                        using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[tangents].VertexDataBlock])))
                        {
                            for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                            {
                                br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[tangents].VertexDataBlock] + meshDataInfoList[tangents].Offset, SeekOrigin.Begin);

                                int x = br1.ReadByte();
                                int y = br1.ReadByte();
                                int z = br1.ReadByte();
                                int w = br1.ReadByte();

                                var x1 = x * 2 / 255f - 1f;
                                var y1 = y * 2 / 255f - 1f;
                                var z1 = z * 2 / 255f - 1f;
                                var w1 = w * 2 / 255f - 1f;


                                var nv = new Vector3(x1, y1, z1);

                                tangentList.Add(nv);
                            }
                        }


                        /*
                         * -----------------
                         * Vertex Color
                         * -----------------
                         */
                        using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[colors].VertexDataBlock])))
                        {
                            for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                            {
                                br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[colors].VertexDataBlock] + meshDataInfoList[colors].Offset, SeekOrigin.Begin);

                                int a = br1.ReadByte();
                                int r = br1.ReadByte();
                                int g = br1.ReadByte();
                                int b = br1.ReadByte();

                                colorsList.Add(new Color4(r, g, b, a));
                            }
                        }
                    }


                    /*
                     * -----------------
                     * Index
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.IndexData)))
                    {
                        for (int j = 0; j < mesh.MeshInfo.IndexCount; j += 3)
                        {
                            int i1 = br1.ReadUInt16();
                            int i2 = br1.ReadUInt16();
                            int i3 = br1.ReadUInt16();

                            objBytes.Add("f " + (i1 + 1) + "/" + (i1 + 1) + "/" + (i1 + 1) + " " + (i2 + 1) + "/" + (i2 + 1) + "/" + (i2 + 1) + " " + (i3 + 1) + "/" + (i3 + 1) + "/" + (i3 + 1) + " ");

                            indexList.Add(i1);
                            indexList.Add(i2);
                            indexList.Add(i3);
                        }
                    }

                    ModelMeshData modelMeshData = new ModelMeshData()
                    {
                        Vertices              = vertexList,
                        Normals               = normalList,
                        TextureCoordinates    = texCoordList,
                        TextureCoordinates2   = texCoordList2,
                        BiTangents            = tangentList,
                        Indices               = indexList,
                        VertexColors          = colorsList,
                        OBJFileData           = objBytes.ToArray(),
                        BoneStrings           = boneStrings,
                        AttributeStrings      = atrStrings,
                        BoneIndices           = modelData.BoneIndicies,
                        BoneTransforms        = boneTransforms,
                        BlendWeights          = blendWeightList,
                        BlendIndices          = blendIndicesList,
                        WeightCounts          = weightCounts,
                        MeshPartList          = mesh.MeshPartList,
                        BlendIndicesArrayList = blendIndicesList2,
                        BlendWeightsArrayList = blendWeightList2,
                        MaterialNum           = mesh.MeshInfo.MaterialNum,
                        MeshPartCount         = mesh.MeshInfo.MeshPartCount,
                        MeshPartOffset        = mesh.MeshInfo.MeshPartOffset
                    };

                    if (extraIndices2.ContainsKey(i))
                    {
                        foreach (var id in extraIndices2[i])
                        {
                            if (!extraVertDict.ContainsKey(id))
                            {
                                if (modelMeshData.Indices.Count >= id)
                                {
                                    var v = 0;
                                    try
                                    {
                                        v = modelMeshData.Indices[id];
                                    }
                                    catch
                                    {
                                        v = 0;
                                    }

                                    extraVertDict.Add(id, modelMeshData.Vertices[v]);
                                }
                                else
                                {
                                    //new Thread(() => MessageBox.Show("There was an error reading the models extra data.\n\n" +
                                    //    "Mesh " + i + " Index " + id + "\n\n" +
                                    //    "This is likely caused by parts of a mesh being deleted and may cause crashes in-game.\n\n" +
                                    //    "Consider using Advanced Import to Fix or Disable Hiding for the above mesh.",
                                    //    "Extra Data Warning" + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Warning)).Start();
                                    new Thread(() => MessageBox.Show(string.Format(Dialogs.MDLExtraDataWarning, i, id),
                                                                     Dialogs.ExtraDataWarning + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Warning)).Start();

                                    break;
                                }
                            }
                        }
                    }


                    mesh.extraVertDict = extraVertDict;

                    meshList.Add(modelMeshData);
                }
            }
        }
Exemple #13
0
        /// <summary>
        /// Gets the texture data and displays it for the currently selected item given a specified race, part, type(if applicable), and map
        /// </summary>
        private void MapComboBoxChanged()
        {
            if (saveClone != null)
            {
                //saveClone.UnlockBits(cloneLock);
                saveClone.Dispose();
            }

            Bitmap colorBmp = null;
            int    offset   = 0;
            bool   isVFX    = false;
            bool   isUI     = false;

            if (selectedMap.Name.Equals(Strings.Normal))
            {
                fullPath       = mtrlData.NormalPath;
                offset         = mtrlData.NormalOffset;
                FullPathString = fullPath;
            }
            else if (selectedMap.Name.Equals(Strings.Specular))
            {
                fullPath       = mtrlData.SpecularPath;
                offset         = mtrlData.SpecularOffset;
                FullPathString = fullPath;
            }
            else if (selectedMap.Name.Equals(Strings.Diffuse))
            {
                fullPath       = mtrlData.DiffusePath;
                offset         = mtrlData.DiffuseOffset;
                FullPathString = fullPath;
            }
            else if (selectedMap.Name.Equals(Strings.Mask) || selectedMap.Name.Equals(Strings.Skin))
            {
                if (selectedItem.ItemName.Equals(Strings.Face_Paint) || selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                {
                    string part;
                    if (selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                    {
                        if (!SelectedPart.Name.Contains("stigma"))
                        {
                            part = selectedPart.Name.PadLeft(3, '0');
                        }
                        else
                        {
                            part = SelectedPart.Name;
                        }
                    }
                    else
                    {
                        part = selectedPart.Name;
                    }

                    fullPath = String.Format(mtrlData.MaskPath, part);
                    offset   = MTRL.GetDecalOffset(selectedItem.ItemName, selectedPart.Name);
                }
                else
                {
                    fullPath = mtrlData.MaskPath;
                    offset   = mtrlData.MaskOffset;
                }
                FullPathString = fullPath;
            }
            else if (selectedMap.Name.Equals(Strings.ColorSet))
            {
                colorBmp       = TEX.TextureToBitmap(mtrlData.ColorData, 9312, 4, 16);
                fullPath       = mtrlData.MTRLPath;
                FullPathString = fullPath;
            }
            else if (SelectedMap.Name.Contains("Icon"))
            {
                if (SelectedMap.Name.Contains("HQ"))
                {
                    fullPath = mtrlData.UIHQPath;
                    offset   = mtrlData.UIHQOffset;
                }
                else
                {
                    fullPath = mtrlData.UIPath;
                    offset   = mtrlData.UIOffset;
                }
                FullPathString = fullPath;
                isUI           = true;
            }
            else if (selectedItem.ItemCategory.Equals(Strings.Maps))
            {
                if (selectedMap.Name.Contains("HighRes Map"))
                {
                    fullPath = string.Format(mtrlData.UIPath, "_m");
                    offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                }
                else if (selectedMap.Name.Contains("LowRes Map"))
                {
                    fullPath = string.Format(mtrlData.UIPath, "_s");
                    offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                }
                else if (selectedMap.Name.Contains("PoI"))
                {
                    fullPath = string.Format(mtrlData.UIPath, "d");
                    offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                }
                else if (selectedMap.Name.Contains("HighRes Mask"))
                {
                    fullPath = string.Format(mtrlData.UIPath, "m_m");
                    offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                }
                else if (selectedMap.Name.Contains("LowRes Mask"))
                {
                    fullPath = string.Format(mtrlData.UIPath, "m_s");
                    offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                }
                FullPathString = fullPath;
                isUI           = true;
            }
            else if (selectedItem.ItemCategory.Equals("HUD") || selectedItem.ItemCategory.Equals("LoadingImage"))
            {
                fullPath       = mtrlData.UIPath;
                offset         = mtrlData.UIOffset;
                FullPathString = fullPath;

                isUI = true;
            }
            else
            {
                fullPath = SelectedMap.ID;
                var VFXFolder = fullPath.Substring(0, fullPath.LastIndexOf("/"));
                var VFXFile   = fullPath.Substring(fullPath.LastIndexOf("/") + 1);

                offset = Helper.GetDataOffset(FFCRC.GetHash(VFXFolder), FFCRC.GetHash(VFXFile), Strings.ItemsDat);

                FullPathString = fullPath;

                isVFX = true;
            }

            string    line;
            JsonEntry modEntry  = null;
            bool      inModList = false;

            try
            {
                using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory))
                {
                    while ((line = sr.ReadLine()) != null)
                    {
                        modEntry = JsonConvert.DeserializeObject <JsonEntry>(line);
                        if (modEntry.fullPath.Equals(fullPath))
                        {
                            inModList = true;
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("[TVM] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            if (inModList)
            {
                var currOffset = Helper.GetDataOffset(FFCRC.GetHash(modEntry.fullPath.Substring(0, modEntry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(modEntry.fullPath)), modEntry.datFile);

                if (currOffset == modEntry.modOffset)
                {
                    ActiveToggle = "Disable";
                }
                else if (currOffset == modEntry.originalOffset)
                {
                    ActiveToggle = "Enable";
                }
                else
                {
                    ActiveToggle = "Error";
                }

                ActiveEnabled = true;
            }
            else
            {
                ActiveEnabled = false;
                ActiveToggle  = "Enable/Disable";
            }

            if (offset == 0)
            {
                TextureType = "Type: 16.16.16.16f ABGR\nMipMaps: None";

                TextureDimensions = "(4 x 16)";

                alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(colorBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                alphaBitmap.Freeze();

                var removeAlphaBitmap = SetAlpha(colorBmp, 255);

                noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                noAlphaBitmap.Freeze();

                colorBmp.Dispose();
                removeAlphaBitmap.Dispose();
            }
            else
            {
                if (!isVFX)
                {
                    if (!isUI)
                    {
                        texData = TEX.GetTex(offset, Strings.ItemsDat);
                    }
                    else
                    {
                        texData = TEX.GetTex(offset, Strings.UIDat);
                    }
                }
                else
                {
                    texData = TEX.GetVFX(offset, Strings.ItemsDat);
                }

                string mipMaps = "Yes (" + texData.MipCount + ")";
                if (texData.MipCount < 1)
                {
                    mipMaps = "None";
                }
                TextureType = "Type: " + texData.TypeString + "\nMipMaps: " + mipMaps;

                TextureDimensions = "(" + texData.Width + " x " + texData.Height + ")";

                var clonerect = new Rectangle(0, 0, texData.Width, texData.Height);
                saveClone = texData.BMP.Clone(new Rectangle(0, 0, texData.Width, texData.Height), PixelFormat.Format32bppArgb);

                alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(texData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                alphaBitmap.Freeze();

                if (!isUI)
                {
                    var removeAlphaBitmap = SetAlpha(texData.BMP, 255);

                    noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                    noAlphaBitmap.Freeze();

                    removeAlphaBitmap.Dispose();
                }
            }


            try
            {
                ImageEffect = new ColorChannels()
                {
                    Channel = new System.Windows.Media.Media3D.Point4D(1.0f, 1.0f, 1.0f, 0.0f)
                };
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.StackTrace);
            }

            if (!isUI)
            {
                ImageSource = noAlphaBitmap;

                SetColorChannelFilter(imageEffect);

                ChannelsEnabled = true;
            }
            else
            {
                ImageSource = alphaBitmap;

                SetColorChannelFilter(imageEffect);

                ChannelsEnabled = true;
            }

            SaveEnabled = true;

            texData.Dispose();

            string dxPath = Path.GetFileNameWithoutExtension(fullPath);

            string savePath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemName + "/" + dxPath + ".dds";

            if (selectedCategory.Equals("UI"))
            {
                savePath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemCategory + "/" + dxPath + ".dds";
            }

            if (File.Exists(savePath))
            {
                ImportEnabled = true;
            }
            else
            {
                ImportEnabled = false;
            }

            string folderPath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemName;

            if (selectedCategory.Equals("UI"))
            {
                folderPath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemCategory;
            }

            if (Directory.Exists(folderPath))
            {
                OpenEnabled = true;
            }
            else
            {
                OpenEnabled = false;
            }
        }
Exemple #14
0
        /// <summary>
        /// Gets the races that have an mtrl file for the given item
        /// </summary>
        /// <remarks>
        /// Goes through a list of all races to see if an mtrl file exists within the items material folder
        /// </remarks>
        /// <param name="item">Selected item to check</param>
        /// <param name="selectedCategory">The category of the selected item</param>
        /// <param name="IMCVersion">The items version from its imc file</param>
        /// <returns>ObservableCollection of ComboBoxInfo classes containing race and race ID</returns>
        public static ObservableCollection <ComboBoxInfo> GetMTRLRaces(ItemData item, string selectedCategory, string IMCVersion)
        {
            ObservableCollection <ComboBoxInfo> cbiList;
            Dictionary <int, string>            racesDict = new Dictionary <int, string>();
            string MTRLFolder;

            if (item.ItemName.Equals(Strings.Body))
            {
                foreach (string race in Info.IDRace.Keys)
                {
                    MTRLFolder = String.Format(Strings.BodyMtrlFolder, race, "0001");

                    racesDict.Add(FFCRC.GetHash(MTRLFolder), race);
                }

                cbiList = new ObservableCollection <ComboBoxInfo>(Helper.FolderExistsListRace(racesDict));
            }
            else if (item.ItemName.Equals(Strings.Face))
            {
                foreach (string race in Info.IDRace.Keys)
                {
                    MTRLFolder = String.Format(Strings.FaceMtrlFolder, race, "0001");

                    racesDict.Add(FFCRC.GetHash(MTRLFolder), race);
                }

                cbiList = new ObservableCollection <ComboBoxInfo>(Helper.FolderExistsListRace(racesDict));
            }
            else if (item.ItemName.Equals(Strings.Hair))
            {
                foreach (string race in Info.IDRace.Keys)
                {
                    MTRLFolder = String.Format(Strings.HairMtrlFolder, race, "0001");

                    racesDict.Add(FFCRC.GetHash(MTRLFolder), race);
                }

                cbiList = new ObservableCollection <ComboBoxInfo>(Helper.FolderExistsListRace(racesDict));
            }
            else if (item.ItemName.Equals(Strings.Tail))
            {
                foreach (string race in Info.IDRace.Keys)
                {
                    MTRLFolder = String.Format(Strings.TailMtrlFolder, race, "0001");

                    racesDict.Add(FFCRC.GetHash(MTRLFolder), race);
                }

                cbiList = new ObservableCollection <ComboBoxInfo>(Helper.FolderExistsListRace(racesDict));
            }
            else if (item.ItemName.Equals(Strings.Face_Paint) || item.ItemName.Equals(Strings.Equipment_Decals) || item.ItemCategory.Equals("9901"))
            {
                cbiList = new ObservableCollection <ComboBoxInfo>();
                ComboBoxInfo cbi = new ComboBoxInfo()
                {
                    Name = Strings.All, ID = "0", IsNum = true
                };
                cbiList.Add(cbi);
            }
            else if (selectedCategory.Equals(Strings.Pets) || selectedCategory.Equals(Strings.Mounts) || selectedCategory.Equals(Strings.Minions))
            {
                cbiList = new ObservableCollection <ComboBoxInfo>();
                ComboBoxInfo cbi = new ComboBoxInfo()
                {
                    Name = Strings.Monster, ID = "0", IsNum = true
                };
                cbiList.Add(cbi);
            }
            else
            {
                string type = Helper.GetCategoryType(selectedCategory);

                ObservableCollection <ComboBoxInfo> cbiInfo = new ObservableCollection <ComboBoxInfo>();

                var fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion));

                if (type.Equals("weapon") || type.Equals("accessory") || type.Equals("food"))
                {
                    cbiInfo.Add(new ComboBoxInfo()
                    {
                        Name = Strings.All, ID = Strings.All, IsNum = false
                    });
                }
                else
                {
                    foreach (string raceID in Info.raceID.Values)
                    {
                        Console.WriteLine(selectedCategory);
                        var MTRLFile = String.Format(Strings.EquipMtrlFile, raceID, item.PrimaryModelID, Info.slotAbr[selectedCategory], "a");

                        var fileHash = FFCRC.GetHash(MTRLFile);

                        if (fileHashList.Contains(fileHash))
                        {
                            cbiInfo.Add(new ComboBoxInfo()
                            {
                                Name = Info.IDRace[raceID], ID = raceID, IsNum = false
                            });
                        }
                    }
                }

                cbiList = cbiInfo;
            }
            return(cbiList);
        }
Exemple #15
0
        /// <summary>
        /// Parses the data of the items MTRL file
        /// </summary>
        /// <param name="item">currently selected item</param>
        /// <param name="raceID">currently selected race</param>
        /// <param name="selectedCategory">the category of the item</param>
        /// <param name="part">currently selected part</param>
        /// <param name="IMCVersion">version of selected item</param>
        /// <param name="type">the items type</param>
        /// <returns>A tuple containing the MTRLInfo and Observable Collection containing texture map names</returns>
        public static Tuple <MTRLData, ObservableCollection <ComboBoxInfo> > GetMTRLData(ItemData item, string raceID, string selectedCategory, string part, string IMCVersion, string type, string modelID, string VFXVersion)
        {
            string MTRLFolder = "";
            string MTRLFile   = "";
            int    offset;
            ObservableCollection <ComboBoxInfo> cbiList;
            Tuple <MTRLData, ObservableCollection <ComboBoxInfo> > info;
            MTRLData mtrlInfo = null;

            if (item.ItemName.Equals(Strings.Face))
            {
                MTRLFolder = String.Format(Strings.FaceMtrlFolder, raceID, part.PadLeft(4, '0'));

                var fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(MTRLFolder));

                cbiList = new ObservableCollection <ComboBoxInfo>();

                if (fileHashList.Contains(FFCRC.GetHash(String.Format(Strings.FaceMtrlFile, raceID, part.PadLeft(4, '0'), "fac"))))
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = Strings.Face, ID = "", IsNum = false
                    });
                }

                if (fileHashList.Contains(FFCRC.GetHash(String.Format(Strings.FaceMtrlFile, raceID, part.PadLeft(4, '0'), "iri"))))
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = Strings.Iris, ID = "", IsNum = false
                    });
                }

                if (fileHashList.Contains(FFCRC.GetHash(String.Format(Strings.FaceMtrlFile, raceID, part.PadLeft(4, '0'), "etc"))))
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = Strings.Etc, ID = "", IsNum = false
                    });
                }

                info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, cbiList);
            }
            else if (item.ItemName.Equals(Strings.Body))
            {
                MTRLFolder = String.Format(Strings.BodyMtrlFolder, raceID, part.PadLeft(4, '0'));
                MTRLFile   = String.Format(Strings.BodyMtrlFile, raceID, part.PadLeft(4, '0'));

                if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(MTRLFolder)))
                {
                    offset = Helper.GetItemOffset(FFCRC.GetHash(MTRLFolder), FFCRC.GetHash(MTRLFile));

                    mtrlInfo = GetMTRLInfo(offset, true);

                    info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, mtrlInfo.TextureMaps);
                }
                else
                {
                    return(null);
                }
            }
            else if (item.ItemName.Equals(Strings.Hair))
            {
                MTRLFolder = String.Format(Strings.HairMtrlFolder, raceID, part.PadLeft(4, '0'));

                var fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(MTRLFolder));

                cbiList = new ObservableCollection <ComboBoxInfo>();

                if (fileHashList.Contains(FFCRC.GetHash(String.Format(Strings.HairMtrlFile, raceID, part.PadLeft(4, '0'), "hir", "a"))))
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = Strings.Hair, ID = "", IsNum = false
                    });
                }

                if (fileHashList.Contains(FFCRC.GetHash(String.Format(Strings.HairMtrlFile, raceID, part.PadLeft(4, '0'), "acc", "b"))))
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = Strings.Accessory, ID = "", IsNum = false
                    });
                }

                info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, cbiList);
            }
            else if (item.ItemName.Equals(Strings.Face_Paint) || item.ItemName.Equals(Strings.Equipment_Decals))
            {
                string texPath = "chara/common/texture/";

                if (item.ItemName.Equals(Strings.Face_Paint))
                {
                    texPath = texPath + "decal_face/_decal_{0}.tex";
                }
                else
                {
                    texPath = texPath + "decal_equip/-decal_{0}.tex";
                }

                cbiList = new ObservableCollection <ComboBoxInfo>
                {
                    new ComboBoxInfo()
                    {
                        Name = Strings.Mask, ID = "", IsNum = false
                    }
                }
                ;
                mtrlInfo = new MTRLData()
                {
                    MaskPath = texPath
                };
                info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, cbiList);
            }
            else if (item.ItemName.Equals(Strings.Tail))
            {
                MTRLFolder = String.Format(Strings.TailMtrlFolder, raceID, part.PadLeft(4, '0'));
                MTRLFile   = string.Format(Strings.TailMtrlFile, raceID, part.PadLeft(4, '0'));

                if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(MTRLFolder)))
                {
                    offset = Helper.GetItemOffset(FFCRC.GetHash(MTRLFolder), FFCRC.GetHash(MTRLFile));

                    mtrlInfo = GetMTRLInfo(offset, true);

                    info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, mtrlInfo.TextureMaps);
                }
                else
                {
                    return(null);
                }
            }
            else if (selectedCategory.Equals(Strings.Pets))
            {
                int p = 1;

                if (item.ItemName.Equals(Strings.Selene) || item.ItemName.Equals(Strings.Bishop_Autoturret))
                {
                    p = 2;
                }

                MTRLFolder = String.Format(Strings.MonsterMtrlFolder, Info.petID[item.ItemName], p.ToString().PadLeft(4, '0')) + part.PadLeft(4, '0');
                MTRLFile   = String.Format(Strings.MonsterMtrlFile, Info.petID[item.ItemName], p.ToString().PadLeft(4, '0'), "a");

                if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(MTRLFolder)))
                {
                    offset = Helper.GetItemOffset(FFCRC.GetHash(MTRLFolder), FFCRC.GetHash(MTRLFile));

                    mtrlInfo            = GetMTRLInfo(offset, false);
                    mtrlInfo.MTRLPath   = MTRLFolder + "/" + MTRLFile;
                    mtrlInfo.MTRLOffset = offset;

                    info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, mtrlInfo.TextureMaps);
                }
                else
                {
                    return(null);
                }
            }
            else if (selectedCategory.Equals(Strings.Mounts))
            {
                if (item.PrimaryMTRLFolder.Contains("demihuman"))
                {
                    SortedSet <ComboBoxInfo> typeSet = new SortedSet <ComboBoxInfo>();

                    var fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion));

                    foreach (string abr in Info.slotAbr.Values)
                    {
                        MTRLFile = String.Format(Strings.DemiMtrlFile, item.PrimaryModelID.PadLeft(4, '0'), item.PrimaryModelBody.PadLeft(4, '0'), abr);

                        if (fileHashList.Contains(FFCRC.GetHash(MTRLFile)))
                        {
                            typeSet.Add(new ComboBoxInfo()
                            {
                                Name = Info.slotAbr.FirstOrDefault(x => x.Value == abr).Key, ID = "", IsNum = false
                            });
                        }
                    }
                    info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, new ObservableCollection <ComboBoxInfo>(typeSet.ToList()));
                }
                else
                {
                    MTRLFile = String.Format(Strings.MonsterMtrlFile, item.PrimaryModelID.PadLeft(4, '0'), item.PrimaryModelBody.PadLeft(4, '0'), part);

                    if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion)))
                    {
                        offset              = Helper.GetItemOffset(FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion), FFCRC.GetHash(MTRLFile));
                        mtrlInfo            = GetMTRLInfo(offset, false);
                        mtrlInfo.MTRLPath   = item.PrimaryMTRLFolder + IMCVersion + "/" + MTRLFile;
                        mtrlInfo.MTRLOffset = offset;

                        info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, mtrlInfo.TextureMaps);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
            else if (selectedCategory.Equals(Strings.Minions))
            {
                MTRLFile = String.Format(Strings.MonsterMtrlFile, item.PrimaryModelID.PadLeft(4, '0'), item.PrimaryModelBody.PadLeft(4, '0'), part);

                if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion)))
                {
                    offset              = Helper.GetItemOffset(FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion), FFCRC.GetHash(MTRLFile));
                    mtrlInfo            = GetMTRLInfo(offset, false);
                    mtrlInfo.MTRLPath   = item.PrimaryMTRLFolder + IMCVersion + "/" + MTRLFile;
                    mtrlInfo.MTRLOffset = offset;

                    info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, mtrlInfo.TextureMaps);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                var    categoryType = Helper.GetCategoryType(selectedCategory);
                string imcVersion   = IMCVersion;
                MTRLFolder = item.PrimaryMTRLFolder;

                if (categoryType.Equals("weapon"))
                {
                    if (!modelID.Equals(""))
                    {
                        MTRLFile   = String.Format(Strings.WeapMtrlFile, modelID, item.PrimaryModelBody, part);
                        MTRLFolder = item.PrimaryMTRLFolder.Substring(0, 14) + modelID + item.PrimaryMTRLFolder.Substring(18);
                    }
                    else
                    {
                        MTRLFile = String.Format(Strings.WeapMtrlFile, item.PrimaryModelID, item.PrimaryModelBody, part);
                    }

                    if (part.Equals("s") || type.Equals("Secondary"))
                    {
                        MTRLFolder = item.SecondaryMTRLFolder;
                        imcVersion = IMC.GetVersion(selectedCategory, item, true).Item1;
                        MTRLFile   = String.Format(Strings.WeapMtrlFile, item.SecondaryModelID, item.SecondaryModelBody, "a");
                    }
                }
                else if (categoryType.Equals("accessory"))
                {
                    MTRLFile = String.Format(Strings.AccMtrlFile, item.PrimaryModelID, Info.slotAbr[selectedCategory], part);
                }
                else if (categoryType.Equals("food"))
                {
                    MTRLFile = String.Format(Strings.WeapMtrlFile, item.PrimaryModelID, item.PrimaryModelBody, "a");
                }
                else
                {
                    MTRLFile = String.Format(Strings.EquipMtrlFile, raceID, item.PrimaryModelID, Info.slotAbr[selectedCategory], part);
                }

                string VFXFolder = "";
                string VFXFile   = "";

                ObservableCollection <ComboBoxInfo> cbi = new ObservableCollection <ComboBoxInfo>();

                if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(MTRLFolder + imcVersion)))
                {
                    offset = Helper.GetItemOffset(FFCRC.GetHash(MTRLFolder + imcVersion), FFCRC.GetHash(MTRLFile));

                    mtrlInfo            = GetMTRLInfo(offset, false);
                    mtrlInfo.MTRLPath   = MTRLFolder + imcVersion + "/" + MTRLFile;
                    mtrlInfo.MTRLOffset = offset;

                    foreach (var texMap in mtrlInfo.TextureMaps)
                    {
                        cbi.Add(texMap);
                    }
                }
                else
                {
                    return(null);
                }

                if (!VFXVersion.Equals("0000"))
                {
                    if (categoryType.Equals("equipment"))
                    {
                        VFXFolder = string.Format(Strings.EquipVFXFolder, item.PrimaryModelID);
                        VFXFile   = string.Format(Strings.EquipVFXFile, VFXVersion);
                    }
                    else if (categoryType.Equals("weapon"))
                    {
                        VFXFolder = string.Format(Strings.WeapVFXFolder, item.PrimaryModelID, item.PrimaryModelBody);
                        VFXFile   = string.Format(Strings.WeapVFXFile, VFXVersion);
                    }

                    if (Helper.FileExists(FFCRC.GetHash(VFXFile), FFCRC.GetHash(VFXFolder)))
                    {
                        offset = Helper.GetItemOffset(FFCRC.GetHash(VFXFolder), FFCRC.GetHash(VFXFile));

                        var vfxData = GetVFXData(offset);

                        foreach (var vfx in vfxData.VFXPaths)
                        {
                            cbi.Add(new ComboBoxInfo()
                            {
                                Name = Path.GetFileNameWithoutExtension(vfx), ID = vfx, IsNum = false
                            });
                        }
                    }
                }

                info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, cbi);
            }

            return(info);
        }
Exemple #16
0
        /// <summary>
        /// Gets the parts for the selected item
        /// </summary>
        /// <param name="item">currently selected item</param>
        /// <param name="raceID">currently selected race</param>
        /// <param name="IMCVersion">version of selected item</param>
        /// <param name="selectedCategory">The category of the selected item</param>
        /// <returns></returns>
        public static ObservableCollection <ComboBoxInfo> GetMTRLParts(ItemData item, string raceID, string IMCVersion, string selectedCategory)
        {
            Dictionary <int, int> MTRLDict = new Dictionary <int, int>();
            List <ComboBoxInfo>   cbiList;
            List <int>            fileHashList;
            string MTRLFolder;

            if (item.ItemName.Equals(Strings.Body))
            {
                for (int i = 1; i < 251; i++)
                {
                    MTRLFolder = String.Format(Strings.BodyMtrlFolder, raceID, i.ToString().PadLeft(4, '0'));

                    MTRLDict.Add(FFCRC.GetHash(MTRLFolder), i);
                }

                cbiList = new List <ComboBoxInfo>(Helper.FolderExistsList(MTRLDict));
            }
            else if (item.ItemName.Equals(Strings.Face))
            {
                for (int i = 1; i < 251; i++)
                {
                    MTRLFolder = String.Format(Strings.FaceMtrlFolder, raceID, i.ToString().PadLeft(4, '0'));

                    MTRLDict.Add(FFCRC.GetHash(MTRLFolder), i);
                }

                cbiList = new List <ComboBoxInfo>(Helper.FolderExistsList(MTRLDict));
            }
            else if (item.ItemName.Equals(Strings.Hair))
            {
                for (int i = 1; i < 251; i++)
                {
                    MTRLFolder = String.Format(Strings.HairMtrlFolder, raceID, i.ToString().PadLeft(4, '0'));

                    MTRLDict.Add(FFCRC.GetHash(MTRLFolder), i);
                }

                cbiList = new List <ComboBoxInfo>(Helper.FolderExistsList(MTRLDict));
            }
            else if (item.ItemName.Equals(Strings.Tail))
            {
                for (int i = 1; i < 251; i++)
                {
                    MTRLFolder = String.Format(Strings.TailMtrlFolder, raceID, i.ToString().PadLeft(4, '0'));

                    MTRLDict.Add(FFCRC.GetHash(MTRLFolder), i);
                }

                cbiList = new List <ComboBoxInfo>(Helper.FolderExistsList(MTRLDict));
            }
            else if (item.ItemName.Equals(Strings.Face_Paint))
            {
                fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(Strings.FacePaintFolder));
                cbiList      = new List <ComboBoxInfo>();

                for (int i = 1; i < 100; i++)
                {
                    MTRLFolder = String.Format(Strings.FacePaintFile, i);

                    if (fileHashList.Contains(FFCRC.GetHash(MTRLFolder)))
                    {
                        cbiList.Add(new ComboBoxInfo()
                        {
                            Name = i.ToString(), ID = i.ToString(), IsNum = true
                        });
                    }
                }
            }
            else if (item.ItemName.Equals(Strings.Equipment_Decals))
            {
                fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(Strings.EquipDecalFolder));
                cbiList      = new List <ComboBoxInfo>();

                for (int i = 1; i < 300; i++)
                {
                    MTRLFolder = String.Format(Strings.EquipDecalFile, i.ToString().PadLeft(3, '0'));

                    if (fileHashList.Contains(FFCRC.GetHash(MTRLFolder)))
                    {
                        cbiList.Add(new ComboBoxInfo()
                        {
                            Name = i.ToString(), ID = i.ToString(), IsNum = true
                        });
                    }
                }
            }
            else if (selectedCategory.Equals(Strings.Pets))
            {
                int part = 1;

                if (item.ItemName.Equals(Strings.Selene) || item.ItemName.Equals(Strings.Bishop_Autoturret))
                {
                    part = 2;
                }

                for (int i = 1; i < 20; i++)
                {
                    MTRLFolder = String.Format(Strings.MonsterMtrlFolder, Info.petID[item.ItemName], part.ToString().PadLeft(4, '0')) + i.ToString().PadLeft(4, '0');

                    MTRLDict.Add(FFCRC.GetHash(MTRLFolder), i);
                }

                cbiList = new List <ComboBoxInfo>(Helper.FolderExistsList(MTRLDict));
            }
            else if (selectedCategory.Equals(Strings.Mounts))
            {
                cbiList = new List <ComboBoxInfo>();

                if (item.PrimaryMTRLFolder.Contains("demihuman"))
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = "a", ID = "a", IsNum = false
                    });
                }
                else
                {
                    Dictionary <string, int> mountMTRLDict = new Dictionary <string, int>();
                    string[] parts = { "a", "b", "c", "d", "e" };

                    fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion));

                    foreach (string c in parts)
                    {
                        MTRLFolder = String.Format(Strings.MonsterMtrlFile, item.PrimaryModelID.PadLeft(4, '0'), item.PrimaryModelBody.PadLeft(4, '0'), c);

                        if (fileHashList.Contains(FFCRC.GetHash(MTRLFolder)))
                        {
                            cbiList.Add(new ComboBoxInfo()
                            {
                                Name = c, ID = c, IsNum = false
                            });
                        }
                    }
                }
            }
            else if (selectedCategory.Equals(Strings.Minions))
            {
                Dictionary <string, int> minionMTRLDict = new Dictionary <string, int>();
                string[] parts = { "a", "b", "c", "d", "e" };
                cbiList = new List <ComboBoxInfo>();

                fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion));

                foreach (string c in parts)
                {
                    MTRLFolder = String.Format(Strings.MonsterMtrlFile, item.PrimaryModelID.PadLeft(4, '0'), item.PrimaryModelBody.PadLeft(4, '0'), c);

                    if (fileHashList.Contains(FFCRC.GetHash(MTRLFolder)))
                    {
                        cbiList.Add(new ComboBoxInfo()
                        {
                            Name = c, ID = c, IsNum = false
                        });
                    }
                }
            }
            else
            {
                string   type  = Helper.GetCategoryType(selectedCategory);
                string[] parts = { "a", "b", "c", "d", "e" };
                cbiList = new List <ComboBoxInfo>();

                fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion));

                foreach (string part in parts)
                {
                    if (type.Equals("weapon") || type.Equals("food"))
                    {
                        MTRLFolder = String.Format(Strings.WeapMtrlFile, item.PrimaryModelID, item.PrimaryModelBody, part);
                    }
                    else if (type.Equals("accessory"))
                    {
                        MTRLFolder = String.Format(Strings.AccMtrlFile, item.PrimaryModelID, Info.slotAbr[selectedCategory], part);
                    }
                    else
                    {
                        MTRLFolder = String.Format(Strings.EquipMtrlFile, raceID, item.PrimaryModelID, Info.slotAbr[selectedCategory], part);
                    }

                    if (fileHashList.Contains(FFCRC.GetHash(MTRLFolder)))
                    {
                        cbiList.Add(new ComboBoxInfo()
                        {
                            Name = part, ID = part, IsNum = false
                        });
                    }
                }

                if (item.SecondaryModelID != null)
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = "s", ID = "s", IsNum = false
                    });
                }

                cbiList.Sort();
            }

            return(new ObservableCollection <ComboBoxInfo>(cbiList));
        }
        /// <summary>
        /// Creates a list of minions contained in companion_(num)_(language).exd
        /// </summary>
        /// <returns>List<Items> Items:Item data associated with Minion</returns>
        public static List <ItemData> MakeMinionsList()
        {
            string minionFile = String.Format(Strings.MinionFile, Strings.Language);

            byte[] minionsBytes = Helper.GetDecompressedEXDData(Helper.GetEXDOffset(FFCRC.GetHash(Strings.ExdFolder), FFCRC.GetHash(minionFile)));
            byte[] modelChara   = Helper.GetDecompressedEXDData(Helper.GetEXDOffset(FFCRC.GetHash(Strings.ExdFolder), FFCRC.GetHash(Strings.ModelCharaFile)));

            List <ItemData> minionsDict = new List <ItemData>();

            using (BinaryReader br = new BinaryReader(new MemoryStream(minionsBytes)))
            {
                using (BinaryReader br1 = new BinaryReader(new MemoryStream(modelChara)))
                {
                    br.ReadBytes(8);
                    int offsetTableSize = BitConverter.ToInt32(br.ReadBytes(4).Reverse().ToArray(), 0);

                    br1.ReadBytes(8);
                    int offsetTableSize1 = BitConverter.ToInt32(br1.ReadBytes(4).Reverse().ToArray(), 0);

                    for (int i = 0; i < offsetTableSize; i += 8)
                    {
                        br.BaseStream.Seek(i + 32, SeekOrigin.Begin);
                        int index       = BitConverter.ToInt32(br.ReadBytes(4).Reverse().ToArray(), 0);
                        int tableOffset = BitConverter.ToInt32(br.ReadBytes(4).Reverse().ToArray(), 0);

                        br.BaseStream.Seek(tableOffset, SeekOrigin.Begin);

                        br.ReadBytes(13);

                        int firstText = br.ReadByte();

                        if (firstText >= 2)
                        {
                            ItemData item = new ItemData();

                            br.ReadBytes(8);

                            uint modelIndex = BitConverter.ToUInt16(br.ReadBytes(2).Reverse().ToArray(), 0);

                            br.ReadBytes(30);

                            byte[] minionNameBytes = br.ReadBytes(firstText - 1);
                            item.ItemName     = Helper.ToTitleCase((Encoding.UTF8.GetString(minionNameBytes)).Replace("\0", ""));
                            item.ItemCategory = Strings.Minion_Category;

                            for (int j = 0; j < offsetTableSize1; j += 8)
                            {
                                br1.BaseStream.Seek(j + 32, SeekOrigin.Begin);

                                uint index1 = BitConverter.ToUInt32(br1.ReadBytes(4).Reverse().ToArray(), 0);

                                if (index1 == modelIndex)
                                {
                                    int tableOffset1 = BitConverter.ToInt32(br1.ReadBytes(4).Reverse().ToArray(), 0);

                                    br1.BaseStream.Seek(tableOffset1, SeekOrigin.Begin);

                                    br1.ReadBytes(6);

                                    item.PrimaryModelID = (BitConverter.ToInt16(br1.ReadBytes(2).Reverse().ToArray(), 0)).ToString().PadLeft(4, '0');
                                    br1.ReadBytes(3);
                                    item.PrimaryModelBody    = (br1.ReadByte()).ToString().PadLeft(4, '0');
                                    item.PrimaryModelVariant = (br1.ReadByte()).ToString();

                                    item.PrimaryMTRLFolder = string.Format(Strings.MonsterMtrlFolder, item.PrimaryModelID, item.PrimaryModelBody);

                                    if (!item.PrimaryModelID.Equals("0000"))
                                    {
                                        minionsDict.Add(item);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            return(minionsDict);
        }
        /// <summary>
        /// Creates a list of Items contained in item_(num)_(language).exd
        /// </summary>
        /// <returns>Dictionary<string, Items> String:Item Name  Items:Item data associated with Item</returns>
        public static List <ItemData> MakeItemsList()
        {
            List <ItemData> itemsDict      = new List <ItemData>();
            List <int>      itemOffsetList = new List <int>();

            var smallClothesMTRL = "chara/equipment/e0000/material/v";

            //smallclothes are not in the item list, so they are added manualy
            ItemData item = new ItemData()
            {
                ItemName            = "SmallClothes Body",
                ItemCategory        = "4",
                PrimaryModelID      = "0000",
                PrimaryModelVariant = "1",
                PrimaryMTRLFolder   = smallClothesMTRL
            };

            itemsDict.Add(item);

            item = new ItemData()
            {
                ItemName            = "SmallClothes Legs",
                ItemCategory        = "7",
                PrimaryModelID      = "0000",
                PrimaryModelVariant = "1",
                PrimaryMTRLFolder   = smallClothesMTRL
            };
            itemsDict.Add(item);

            item = new ItemData()
            {
                ItemName            = "SmallClothes Feet",
                ItemCategory        = "8",
                PrimaryModelID      = "0000",
                PrimaryModelVariant = "1",
                PrimaryMTRLFolder   = smallClothesMTRL
            };
            itemsDict.Add(item);

            //searches item files which increase in increments of 500 in 0a0000 index until one does not exist
            for (int i = 0; ; i += 500)
            {
                string itemExd = String.Format(Strings.itemFile, i, Strings.Language);

                int offset = Helper.GetEXDOffset(FFCRC.GetHash(Strings.ExdFolder), FFCRC.GetHash(itemExd));

                if (offset != 0)
                {
                    itemOffsetList.Add(offset);
                }
                else
                {
                    break;
                }
            }

            foreach (int offset in itemOffsetList)
            {
                using (BinaryReader br = new BinaryReader(new MemoryStream(Helper.GetDecompressedEXDData(offset))))
                {
                    br.ReadBytes(8);
                    int offsetTableSize = BitConverter.ToInt32(br.ReadBytes(4).Reverse().ToArray(), 0);

                    for (int i = 0; i < offsetTableSize; i += 8)
                    {
                        br.BaseStream.Seek(i + 32, SeekOrigin.Begin);
                        int index       = BitConverter.ToInt32(br.ReadBytes(4).Reverse().ToArray(), 0);
                        int tableOffset = BitConverter.ToInt32(br.ReadBytes(4).Reverse().ToArray(), 0);

                        br.BaseStream.Seek(tableOffset, SeekOrigin.Begin);
                        int entrySize = BitConverter.ToInt32(br.ReadBytes(4).Reverse().ToArray(), 0);
                        br.ReadBytes(16);
                        int lastText = BitConverter.ToInt16(br.ReadBytes(2).Reverse().ToArray(), 0);
                        br.ReadBytes(3);

                        if (lastText > 10)
                        {
                            item = new ItemData();

                            bool hasSecondary = false;
                            br.ReadBytes(7);
                            byte[] textureDetails = br.ReadBytes(4).ToArray();
                            int    itemCheck      = textureDetails[3];

                            if (itemCheck != 0)
                            {
                                int weaponCheck = textureDetails[1];
                                if (weaponCheck == 0)
                                {
                                    item.PrimaryModelVariant = textureDetails[3].ToString().PadLeft(2, '0');
                                }
                                else
                                {
                                    item.PrimaryModelVariant = weaponCheck.ToString().PadLeft(2, '0');
                                    item.PrimaryModelBody    = textureDetails[3].ToString().PadLeft(4, '0');
                                }

                                item.PrimaryModelID = BitConverter.ToInt16(br.ReadBytes(2).Reverse().ToArray(), 0).ToString().PadLeft(4, '0');
                                br.ReadBytes(2);

                                textureDetails = br.ReadBytes(4).ToArray();
                                int secondaryCheck = textureDetails[3];
                                if (secondaryCheck != 0)
                                {
                                    hasSecondary = true;
                                    weaponCheck  = textureDetails[1];
                                    if (weaponCheck == 0)
                                    {
                                        item.SecondaryModelVariant = textureDetails[3].ToString().PadLeft(2, '0');
                                    }
                                    else
                                    {
                                        item.SecondaryModelVariant = weaponCheck.ToString().PadLeft(2, '0');
                                        item.SecondaryModelBody    = textureDetails[3].ToString().PadLeft(4, '0');
                                    }

                                    item.SecondaryModelID = BitConverter.ToInt16(br.ReadBytes(2).Reverse().ToArray(), 0).ToString().PadLeft(4, '0');
                                    br.ReadBytes(2);
                                }

                                if (!hasSecondary)
                                {
                                    br.ReadBytes(110);
                                }
                                else
                                {
                                    br.ReadBytes(106);
                                }

                                byte[] slotBytes = br.ReadBytes(4).ToArray();
                                item.ItemCategory = slotBytes[0].ToString();

                                br.ReadBytes(lastText);

                                item.ItemName = Encoding.UTF8.GetString(br.ReadBytes(entrySize - (lastText + 152))).Replace("\0", "");


                                if (item.ItemCategory.Equals("0") || item.ItemCategory.Equals("1") || item.ItemCategory.Equals("2") || item.ItemCategory.Equals("13") || item.ItemCategory.Equals("14"))
                                {
                                    item.PrimaryMTRLFolder = String.Format(Strings.WeapMtrlFolder, item.PrimaryModelID, item.PrimaryModelBody);
                                    if (hasSecondary)
                                    {
                                        item.SecondaryMTRLFolder = String.Format(Strings.WeapMtrlFolder, item.SecondaryModelID, item.SecondaryModelBody);
                                    }
                                }
                                else if (item.ItemCategory.Equals("9") || item.ItemCategory.Equals("10") || item.ItemCategory.Equals("11") || item.ItemCategory.Equals("12"))
                                {
                                    item.PrimaryMTRLFolder = String.Format(Strings.AccMtrlFolder, item.PrimaryModelID);
                                }
                                else
                                {
                                    item.PrimaryMTRLFolder = String.Format(Strings.EquipMtrlFolder, item.PrimaryModelID);
                                }

                                try
                                {
                                    itemsDict.Add(item);
                                }
                                catch (Exception e)
                                {
                                    Debug.WriteLine("EXD_MakeItemListError " + e);
                                }
                            }
                        }
                    }
                }
            }

            return(itemsDict);
        }
Exemple #19
0
        public void SaveAllDDS()
        {
            foreach (var m in MapComboBox)
            {
                int offset = 0;

                if (m.Name.Equals(Strings.Normal))
                {
                    fullPath = mtrlData.NormalPath;
                    offset   = mtrlData.NormalOffset;
                }
                else if (m.Name.Equals(Strings.Specular))
                {
                    fullPath = mtrlData.SpecularPath;
                    offset   = mtrlData.SpecularOffset;
                }
                else if (m.Name.Equals(Strings.Diffuse))
                {
                    fullPath = mtrlData.DiffusePath;
                    offset   = mtrlData.DiffuseOffset;
                }
                else if (m.Name.Equals(Strings.Mask) || m.Name.Equals(Strings.Skin))
                {
                    if (selectedItem.ItemName.Equals(Strings.Face_Paint) || selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                    {
                        string part;
                        if (selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                        {
                            if (!SelectedPart.Name.Contains("stigma"))
                            {
                                part = selectedPart.Name.PadLeft(3, '0');
                            }
                            else
                            {
                                part = SelectedPart.Name;
                            }
                        }
                        else
                        {
                            part = selectedPart.Name;
                        }

                        fullPath = String.Format(mtrlData.MaskPath, part);
                        offset   = MTRL.GetDecalOffset(selectedItem.ItemName, selectedPart.Name);
                    }
                    else
                    {
                        fullPath = mtrlData.MaskPath;
                        offset   = mtrlData.MaskOffset;
                    }
                }
                else if (m.Name.Equals(Strings.ColorSet))
                {
                    fullPath = mtrlData.MTRLPath;
                }
                else if (m.Name.Contains("Icon"))
                {
                    if (m.Name.Contains("HQ"))
                    {
                        fullPath = mtrlData.UIHQPath;
                        offset   = mtrlData.UIHQOffset;
                    }
                    else
                    {
                        fullPath = mtrlData.UIPath;
                        offset   = mtrlData.UIOffset;
                    }
                }
                else if (selectedItem.ItemCategory.Equals(Strings.Maps))
                {
                    if (selectedMap.Name.Contains("HighRes Map"))
                    {
                        fullPath = string.Format(mtrlData.UIPath, "_m");
                        offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                    }
                    else if (selectedMap.Name.Contains("LowRes Map"))
                    {
                        fullPath = string.Format(mtrlData.UIPath, "_s");
                        offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                    }
                    else if (selectedMap.Name.Contains("PoI"))
                    {
                        fullPath = string.Format(mtrlData.UIPath, "d");
                        offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                    }
                    else if (selectedMap.Name.Contains("HighRes Mask"))
                    {
                        fullPath = string.Format(mtrlData.UIPath, "m_m");
                        offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                    }
                    else if (selectedMap.Name.Contains("LowRes Mask"))
                    {
                        fullPath = string.Format(mtrlData.UIPath, "m_s");
                        offset   = mtrlData.UIOffset = int.Parse(selectedMap.ID);
                    }
                }
                else if (selectedItem.ItemCategory.Equals("HUD"))
                {
                    fullPath = mtrlData.UIPath;
                    offset   = mtrlData.UIOffset;
                }
                else
                {
                    fullPath = SelectedMap.ID;
                    var VFXFolder = fullPath.Substring(0, fullPath.LastIndexOf("/"));
                    var VFXFile   = fullPath.Substring(fullPath.LastIndexOf("/") + 1);

                    offset = Helper.GetDataOffset(FFCRC.GetHash(VFXFolder), FFCRC.GetHash(VFXFile), Strings.ItemsDat);
                }

                if (offset != 0)
                {
                    if (m.ID.Contains("vfx"))
                    {
                        texData = TEX.GetVFX(offset, Strings.ItemsDat);
                    }
                    else
                    {
                        if (selectedCategory.Equals("UI"))
                        {
                            texData = TEX.GetTex(offset, Strings.UIDat);
                        }
                        else
                        {
                            texData = TEX.GetTex(offset, Strings.ItemsDat);
                        }
                    }
                }


                SaveTex.SaveDDS(selectedCategory, selectedItem.ItemName, fullPath, m.Name, mtrlData, texData, selectedItem.ItemCategory);
            }
        }
Exemple #20
0
        /// <summary>
        /// Gets the data from the MTRL file
        /// </summary>
        /// <param name="offset">MTRL file offset</param>
        /// <param name="isUncompressed">DX compression</param>
        /// <returns>Data from MTRL file</returns>
        public static MTRLData GetMTRLInfo(int offset, bool isUncompressed)
        {
            int datNum = ((offset / 8) & 0x000f) / 2;

            MTRLData mtrlInfo = new MTRLData();

            using (BinaryReader br = new BinaryReader(new MemoryStream(Helper.GetType2DecompressedData(offset, datNum))))
            {
                br.BaseStream.Seek(6, SeekOrigin.Begin);
                short colorDataSize   = br.ReadInt16();
                short textureNameSize = br.ReadInt16();
                br.ReadBytes(2);
                byte numOfTextures  = br.ReadByte();
                byte numOfMaps      = br.ReadByte();
                byte numOfColorSets = br.ReadByte();
                byte unknown        = br.ReadByte();

                int headerEnd = 16 + ((numOfTextures + numOfMaps + numOfColorSets) * 4);

                int[] texPathOffsets = new int[numOfTextures + 1];

                for (int i = 0; i < numOfTextures + 1; i++)
                {
                    texPathOffsets[i] = br.ReadInt16();
                    br.ReadBytes(2);
                }

                br.ReadBytes((numOfMaps - 1) * 4);

                for (int i = 0; i < numOfTextures; i++)
                {
                    br.BaseStream.Seek(headerEnd + texPathOffsets[i], SeekOrigin.Begin);

                    string fullPath = Encoding.ASCII.GetString(br.ReadBytes(texPathOffsets[i + 1] - texPathOffsets[i])).Replace("\0", "");

                    string fileName = fullPath.Substring(fullPath.LastIndexOf("/") + 1);

                    if (Properties.Settings.Default.DX_Ver.Equals("DX11") && isUncompressed)
                    {
                        if (textureNameSize > 50)
                        {
                            fileName = fileName.Insert(0, "--");

                            int mtrlOffset = Helper.GetItemOffset(FFCRC.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/"))), FFCRC.GetHash(fileName));

                            if (mtrlOffset == 0)
                            {
                                fileName = fileName.Substring(2);
                            }
                        }
                    }

                    int texHash = FFCRC.GetHash(fileName);

                    string mapName = GetMapName(fileName);

                    if (fileName.Contains("_s.tex"))
                    {
                        mtrlInfo.SpecularPath = fullPath.Substring(0, fullPath.LastIndexOf("/")) + "/" + fileName;
                        mtrlInfo.TextureMaps.Add(new ComboBoxInfo()
                        {
                            Name = mapName, ID = "", IsNum = false
                        });
                        mtrlInfo.SpecularOffset = Helper.GetItemOffset(FFCRC.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/"))), FFCRC.GetHash(fileName));
                    }
                    else if (fileName.Contains("_d.tex"))
                    {
                        mtrlInfo.DiffusePath = fullPath.Substring(0, fullPath.LastIndexOf("/")) + "/" + fileName;
                        mtrlInfo.TextureMaps.Add(new ComboBoxInfo()
                        {
                            Name = mapName, ID = "", IsNum = false
                        });
                        mtrlInfo.DiffuseOffset = Helper.GetItemOffset(FFCRC.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/"))), FFCRC.GetHash(fileName));
                    }
                    else if (fileName.Contains("_n.tex"))
                    {
                        mtrlInfo.NormalPath = fullPath.Substring(0, fullPath.LastIndexOf("/")) + "/" + fileName;
                        mtrlInfo.TextureMaps.Add(new ComboBoxInfo()
                        {
                            Name = mapName, ID = "", IsNum = false
                        });
                        mtrlInfo.NormalOffset = Helper.GetItemOffset(FFCRC.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/"))), FFCRC.GetHash(fileName));
                    }
                    else if (fileName.Contains("_m.tex"))
                    {
                        mtrlInfo.MaskPath = fullPath.Substring(0, fullPath.LastIndexOf("/")) + "/" + fileName;
                        mtrlInfo.TextureMaps.Add(new ComboBoxInfo()
                        {
                            Name = mapName, ID = "", IsNum = false
                        });
                        mtrlInfo.MaskOffset = Helper.GetItemOffset(FFCRC.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/"))), FFCRC.GetHash(fileName));
                    }
                }

                if (numOfColorSets > 0 && colorDataSize > 0)
                {
                    br.BaseStream.Seek((16 + (numOfTextures * 4) + (numOfMaps * 4) + (numOfColorSets * 4) + textureNameSize + 4), SeekOrigin.Begin);
                    mtrlInfo.TextureMaps.Add(new ComboBoxInfo()
                    {
                        Name = Strings.ColorSet, ID = "", IsNum = false
                    });

                    if (colorDataSize == 544)
                    {
                        mtrlInfo.ColorData  = br.ReadBytes(colorDataSize - 32);
                        mtrlInfo.ColorFlags = br.ReadBytes(32);
                    }
                    else
                    {
                        mtrlInfo.ColorData = br.ReadBytes(colorDataSize);
                    }
                }
            }

            return(mtrlInfo);
        }
        public ModListModel ParseEntry(JsonEntry entry)
        {
            ModListModel mlm = new ModListModel();
            string       race, map, part, type;

            if (entry.fullPath.Contains("weapon") || entry.fullPath.Contains("accessory") || entry.fullPath.Contains("decal") || entry.fullPath.Contains("vfx") || entry.fullPath.Contains("ui/"))
            {
                race = Strings.All;
            }
            else if (entry.fullPath.Contains("monster") || entry.fullPath.Contains("demihuman"))
            {
                race = Strings.Monster;
            }
            else
            {
                race = entry.fullPath.Substring(entry.fullPath.LastIndexOf('/'));

                if ((entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_")) && Properties.Settings.Default.DX_Ver.Equals(Strings.DX11))
                {
                    race = race.Substring(race.LastIndexOf("--c") + 3, 4);
                }
                else if (entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_"))
                {
                    race = race.Substring(race.LastIndexOf("/c") + 2, 4);
                }
                else if (entry.fullPath.Contains("_c_"))
                {
                    race = race.Substring(race.IndexOf("_c") + 2, 4);
                }
                else
                {
                    race = race.Substring(race.LastIndexOf('c') + 1, 4);
                }
                race = Info.IDRace[race];
            }

            mlm.Race = race;


            if (entry.fullPath.Contains("_d."))
            {
                map = Strings.Diffuse;
            }
            else if (entry.fullPath.Contains("_n."))
            {
                map = Strings.Normal;
            }
            else if (entry.fullPath.Contains("_s."))
            {
                map = Strings.Specular;
            }
            else if (entry.fullPath.Contains("material"))
            {
                map = Strings.ColorSet;
            }
            else if (entry.fullPath.Contains("model"))
            {
                map = "3D";
            }
            else if (entry.fullPath.Contains("ui/"))
            {
                map = "UI";
            }
            else
            {
                map = Strings.Mask;
            }

            mlm.Map = map;


            if (entry.fullPath.Contains("_b_"))
            {
                part = "b";
            }
            else if (entry.fullPath.Contains("_c_"))
            {
                part = "c";
            }
            else if (entry.fullPath.Contains("_d_"))
            {
                part = "d";
            }
            else if (entry.fullPath.Contains("decal"))
            {
                part = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') + 1, entry.fullPath.LastIndexOf('.') - (entry.fullPath.LastIndexOf('_') + 1));
            }
            else
            {
                part = "a";
            }

            mlm.Part = part;


            if (entry.fullPath.Contains("_iri_"))
            {
                type = "Iris";
            }
            else if (entry.fullPath.Contains("_etc_"))
            {
                type = "Etc.";
            }
            else if (entry.fullPath.Contains("_fac_"))
            {
                type = "Face";
            }
            else if (entry.fullPath.Contains("_hir_"))
            {
                type = "Hair";
            }
            else if (entry.fullPath.Contains("_acc_"))
            {
                type = "Accessory";
            }
            else if (entry.fullPath.Contains("demihuman"))
            {
                type = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') - 3, 3);
                type = (Info.slotAbr).FirstOrDefault(x => x.Value == type).Key;
            }
            else
            {
                type = "-";
            }

            mlm.Type = type;

            if (entry.fullPath.Contains("material"))
            {
                var info = MTRL.GetMTRLInfo(entry.modOffset, false);

                var bitmap = TEX.TextureToBitmap(info.ColorData, 9312, 4, 16);

                mlm.BMP = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            }
            else if (entry.fullPath.Contains("model"))
            {
                mlm.BMP = new BitmapImage(new Uri("pack://application:,,,/FFXIV TexTools 2;component/Resources/3DModel.png"));
            }
            else
            {
                TEXData texData;

                if (entry.fullPath.Contains("vfx"))
                {
                    texData = TEX.GetVFX(entry.modOffset, entry.datFile);
                }
                else
                {
                    if (entry.fullPath.Contains("icon"))
                    {
                        texData = TEX.GetTex(entry.modOffset, entry.datFile);
                    }
                    else
                    {
                        texData = TEX.GetTex(entry.modOffset, entry.datFile);
                    }
                }

                mlm.BMP = Imaging.CreateBitmapSourceFromHBitmap(texData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            }

            var offset = Helper.GetDataOffset(FFCRC.GetHash(entry.fullPath.Substring(0, entry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(entry.fullPath)), entry.datFile);

            if (offset == entry.modOffset)
            {
                mlm.ActiveBorder  = Brushes.Green;
                mlm.Active        = Brushes.Transparent;
                mlm.ActiveOpacity = 1;
            }
            else if (offset == entry.originalOffset)
            {
                mlm.ActiveBorder  = Brushes.Red;
                mlm.Active        = Brushes.Gray;
                mlm.ActiveOpacity = 0.5f;
            }
            else
            {
                mlm.ActiveBorder  = Brushes.Red;
                mlm.Active        = Brushes.Red;
                mlm.ActiveOpacity = 1;
            }

            mlm.Entry = entry;

            return(mlm);
        }
        /// <summary>
        /// Gets the texture data and displays it for the currently selected item given a specified race, part, type(if applicable), and map
        /// </summary>
        private void MapComboBoxChanged()
        {
            Bitmap colorBmp = null;
            int    offset   = 0;
            bool   isVFX    = false;

            if (selectedMap.Name.Equals(Strings.Normal))
            {
                fullPath       = mtrlData.NormalPath;
                offset         = mtrlData.NormalOffset;
                FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
            }
            else if (selectedMap.Name.Equals(Strings.Specular))
            {
                fullPath       = mtrlData.SpecularPath;
                offset         = mtrlData.SpecularOffset;
                FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
            }
            else if (selectedMap.Name.Equals(Strings.Diffuse))
            {
                fullPath       = mtrlData.DiffusePath;
                offset         = mtrlData.DiffuseOffset;
                FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
            }
            else if (selectedMap.Name.Equals(Strings.Mask) || selectedMap.Name.Equals(Strings.Skin))
            {
                if (selectedItem.ItemName.Equals(Strings.Face_Paint) || selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                {
                    string part;
                    if (selectedItem.ItemName.Equals(Strings.Equipment_Decals))
                    {
                        part = selectedPart.Name.PadLeft(3, '0');
                    }
                    else
                    {
                        part = selectedPart.Name;
                    }

                    fullPath       = String.Format(mtrlData.MaskPath, part);
                    offset         = MTRL.GetDecalOffset(selectedItem.ItemName, selectedPart.Name);
                    FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
                }
                else
                {
                    fullPath       = mtrlData.MaskPath;
                    offset         = mtrlData.MaskOffset;
                    FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
                }
            }
            else if (selectedMap.Name.Equals(Strings.ColorSet))
            {
                colorBmp       = TEX.TextureToBitmap(mtrlData.ColorData, 9312, 4, 16);
                fullPath       = mtrlData.MTRLPath;
                FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]";
            }
            else
            {
                fullPath = SelectedMap.ID;
                var VFXFolder = fullPath.Substring(0, fullPath.LastIndexOf("/"));
                var VFXFile   = fullPath.Substring(fullPath.LastIndexOf("/") + 1);

                offset = Helper.GetItemOffset(FFCRC.GetHash(VFXFolder), FFCRC.GetHash(VFXFile));

                FullPathString = fullPath;

                isVFX = true;
            }

            if (Properties.Settings.Default.Mod_List == 0)
            {
                string    line;
                JsonEntry modEntry  = null;
                bool      inModList = false;
                try
                {
                    using (StreamReader sr = new StreamReader(Info.modListDir))
                    {
                        while ((line = sr.ReadLine()) != null)
                        {
                            modEntry = JsonConvert.DeserializeObject <JsonEntry>(line);
                            if (modEntry.fullPath.Equals(fullPath))
                            {
                                inModList = true;
                                break;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("[Main] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }

                if (inModList)
                {
                    var currOffset = Helper.GetItemOffset(FFCRC.GetHash(modEntry.fullPath.Substring(0, modEntry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(modEntry.fullPath)));

                    if (currOffset == modEntry.modOffset)
                    {
                        ActiveToggle = "Disable";
                    }
                    else if (currOffset == modEntry.originalOffset)
                    {
                        ActiveToggle = "Enable";
                    }
                    else
                    {
                        ActiveToggle = "Error";
                    }

                    ActiveEnabled = true;
                }
                else
                {
                    ActiveEnabled = false;
                    ActiveToggle  = "Enable/Disable";
                }
            }
            else
            {
                ActiveEnabled = false;
                ActiveToggle  = "Enable/Disable";
            }

            if (offset == 0)
            {
                TextureType = "A16B16G16R16F";
                textureType = "A16B16G16R16F";

                TextureDimensions = "(4 x 16)";
                textureDimensions = "(4 x 16)";


                alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(colorBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                var removeAlphaBitmap = SetAlpha(colorBmp, 255);

                noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                colorBmp.Dispose();
                removeAlphaBitmap.Dispose();
            }
            else
            {
                if (!isVFX)
                {
                    texData = TEX.GetTex(offset);
                }
                else
                {
                    texData = TEX.GetVFX(offset);
                }

                TextureType = texData.TypeString;

                TextureDimensions = "(" + texData.Width + " x " + texData.Height + ")";

                alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(texData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                var removeAlphaBitmap = SetAlpha(texData.BMP, 255);

                noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                removeAlphaBitmap.Dispose();
            }

            try
            {
                ImageEffect = new ColorChannels()
                {
                    Channel = new System.Windows.Media.Media3D.Point4D(1.0f, 1.0f, 1.0f, 0.0f)
                };
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.StackTrace);
            }

            ImageSource = noAlphaBitmap;

            SetColorChannelFilter();

            SaveEnabled = true;

            texData.Dispose();

            string dxPath = Path.GetFileNameWithoutExtension(fullPath);

            if (File.Exists(Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemName + "/" + dxPath + ".dds"))
            {
                ImportEnabled = true;
            }
            else
            {
                ImportEnabled = false;
            }
        }
Exemple #23
0
        private void Bw_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            List <SearchItems> workList = new List <SearchItems>();

            string[]   eqSlots     = new string[] { "met", "glv", "dwn", "sho", "top", };
            string[]   acSlots     = new string[] { "ear", "nek", "rir", "wrs" };
            string[]   parts       = new string[] { "a", "b", "c", "d" };
            List <int> variantList = new List <int>();
            List <int> bodyList    = new List <int>();
            Dictionary <int, List <string> > slotList = new Dictionary <int, List <string> >();

            string folder = Strings.EquipMtrlFolder;
            string file   = Strings.EquipMtrlFile;

            if (SelectedType.Name.Equals(Strings.Weapon))
            {
                folder = Strings.WeapMtrlFolder;
                file   = Strings.WeapMtrlFile;
            }
            else if (SelectedType.Name.Equals(Strings.Accessory))
            {
                folder = Strings.AccMtrlFolder;
                file   = Strings.AccMtrlFile;
            }
            else if (SelectedType.Name.Equals(Strings.Monster))
            {
                folder = Strings.MonsterMtrlFolder;
                file   = Strings.MonsterMtrlFile;
            }
            else if (SelectedType.Name.Equals("DemiHuman"))
            {
                folder = Strings.DemiMtrlFolder;
                file   = Strings.DemiMtrlFile;
            }


            if (SelectedType.Name.Equals(Strings.Equipment) || SelectedType.Name.Equals(Strings.Accessory))
            {
                for (int i = 0; i <= 200; i++)
                {
                    var folderCheck = string.Format(folder, searchText.PadLeft(4, '0')) + i.ToString().PadLeft(4, '0');

                    if (Helper.FolderExists(FFCRC.GetHash(folderCheck), Strings.ItemsDat))
                    {
                        variantList.Add(i);
                    }
                    worker.ReportProgress(i / 2);
                    ProgressLabel = "Variant: " + i;
                }
                int var = 0;

                if (variantList.Count > 0)
                {
                    foreach (int v in variantList)
                    {
                        slotList.Add(v, new List <string>());
                        var eFolder = string.Format(folder, searchText.PadLeft(4, '0')) + v.ToString().PadLeft(4, '0');

                        var files = Helper.GetAllFilesInFolder(FFCRC.GetHash(eFolder), Strings.ItemsDat);

                        if (SelectedType.Name.Equals(Strings.Accessory))
                        {
                            foreach (var s in acSlots)
                            {
                                foreach (var p in parts)
                                {
                                    var aFile = string.Format(file, searchText.PadLeft(4, '0'), s, p);

                                    var fileHash = FFCRC.GetHash(aFile);
                                    if (files.Contains(fileHash))
                                    {
                                        workList.Add(new SearchItems()
                                        {
                                            Race = Info.IDRace["0101"], RaceID = "0101", Slot = accSlotDict[s], SlotAbr = s, SlotID = Info.IDSlot[accSlotDict[s]], Body = "-", Variant = v.ToString(), Part = p
                                        });
                                    }

                                    ProgressLabel = "Slot: " + s + "Part: " + p;
                                }
                            }
                        }
                        else
                        {
                            foreach (var r in Info.IDRace.Keys)
                            {
                                foreach (var s in eqSlots)
                                {
                                    foreach (var p in parts)
                                    {
                                        var eFile = string.Format(file, r, searchText.PadLeft(4, '0'), s, p);

                                        var fileHash = FFCRC.GetHash(eFile);
                                        if (files.Contains(fileHash))
                                        {
                                            if (!slotList[v].Contains(s))
                                            {
                                                slotList[v].Add(s);
                                                workList.Add(new SearchItems()
                                                {
                                                    Race = Info.IDRace[r], RaceID = r, Slot = equipSlotDict[s], SlotAbr = s, SlotID = Info.IDSlot[equipSlotDict[s]], Body = "-", Variant = v.ToString(), Part = p
                                                });
                                            }
                                        }
                                        ProgressLabel = "Race: " + r + " Slot: " + s + "Part: " + p;
                                    }
                                }
                            }
                        }
                        int prog = (int)(((double)var / Info.IDRace.Count) * 100f);
                        worker.ReportProgress(prog);
                        var++;
                    }
                }
                else
                {
                    folder = Strings.EquipMDLFolder;
                    file   = Strings.EquipMDLFile;

                    if (SelectedType.Name.Equals(Strings.Accessory))
                    {
                        folder = Strings.AccMDLFolder;
                        file   = Strings.AccMDLFile;
                    }

                    var folderCheck = string.Format(folder, searchText.PadLeft(4, '0'));

                    if (Helper.FolderExists(FFCRC.GetHash(folderCheck), Strings.ItemsDat))
                    {
                        variantList.Add(1);
                    }

                    slotList.Add(1, new List <string>());

                    var files = Helper.GetAllFilesInFolder(FFCRC.GetHash(folderCheck), Strings.ItemsDat);

                    if (SelectedType.Name.Equals(Strings.Accessory))
                    {
                        foreach (var s in acSlots)
                        {
                            var aFile = string.Format(file, "0101", searchText.PadLeft(4, '0'), s);

                            var fileHash = FFCRC.GetHash(aFile);
                            if (files.Contains(fileHash))
                            {
                                workList.Add(new SearchItems()
                                {
                                    Race = Info.IDRace["0101"], RaceID = "0101", Slot = accSlotDict[s], SlotAbr = s, SlotID = Info.IDSlot[accSlotDict[s]], Body = "-", Variant = "1", Part = "a"
                                });
                            }

                            ProgressLabel = "Slot: " + s;
                        }
                    }
                    else
                    {
                        foreach (var r in Info.IDRace.Keys)
                        {
                            foreach (var s in eqSlots)
                            {
                                var eFile = string.Format(file, r, searchText.PadLeft(4, '0'), s);

                                var fileHash = FFCRC.GetHash(eFile);
                                if (files.Contains(fileHash))
                                {
                                    workList.Add(new SearchItems()
                                    {
                                        Race = Info.IDRace[r], RaceID = r, Slot = equipSlotDict[s], SlotAbr = s, SlotID = Info.IDSlot[equipSlotDict[s]], Body = "-", Variant = "1", Part = "a"
                                    });
                                }
                                ProgressLabel = "Race: " + r + " Slot: " + s;
                            }
                        }
                    }
                }


                ProgressLabel = "Found: " + workList.Count;
            }
            else
            {
                if (!SelectedType.Name.Equals("DemiHuman"))
                {
                    string slotName = Strings.Main_Hand;

                    if (SelectedType.Name.Equals(Strings.Monster))
                    {
                        slotName = Strings.Mounts;
                    }



                    for (int i = 0; i <= 50; i++)
                    {
                        var folderCheck = string.Format(folder, searchText.PadLeft(4, '0'), i.ToString().PadLeft(4, '0')) + "0001";

                        if (Helper.FolderExists(FFCRC.GetHash(folderCheck), Strings.ItemsDat))
                        {
                            bodyList.Add(i);
                        }
                        ProgressLabel = "Body: " + i;
                        worker.ReportProgress(i * 2);
                    }

                    for (int i = 0; i < bodyList.Count; i++)
                    {
                        for (int j = 0; j <= 20; j++)
                        {
                            var wmFolder = string.Format(folder, searchText.PadLeft(4, '0'), bodyList[i].ToString().PadLeft(4, '0')) + j.ToString().PadLeft(4, '0');

                            var files = Helper.GetAllFilesInFolder(FFCRC.GetHash(wmFolder), Strings.ItemsDat);

                            foreach (var p in parts)
                            {
                                var wmFile = string.Format(file, searchText.PadLeft(4, '0'), bodyList[i].ToString().PadLeft(4, '0'), p);

                                var fileHash = FFCRC.GetHash(wmFile);
                                if (files.Contains(fileHash))
                                {
                                    workList.Add(new SearchItems()
                                    {
                                        Race = "-", Slot = slotName, SlotID = Info.IDSlot[slotName], Body = bodyList[i].ToString(), Variant = j.ToString(), Part = p
                                    });
                                }

                                ProgressLabel = "Body: " + bodyList[i] + " Variant: " + j + " Part: " + p;
                            }
                        }

                        int prog = (int)(((double)(i + 1) / bodyList.Count) * 100f);
                        worker.ReportProgress(prog);
                    }

                    ProgressLabel = "Found: " + workList.Count;
                }
                else
                {
                    string slotName = "DemiHuman";

                    for (int i = 0; i <= 100; i++)
                    {
                        var folderCheck = string.Format(folder, searchText.PadLeft(4, '0'), i.ToString().PadLeft(4, '0')) + "0001";

                        if (Helper.FolderExists(FFCRC.GetHash(folderCheck), Strings.ItemsDat))
                        {
                            bodyList.Add(i);
                        }
                        ProgressLabel = "Equipment: " + i;
                        worker.ReportProgress(i * 2);
                    }

                    for (int i = 0; i < bodyList.Count; i++)
                    {
                        for (int j = 0; j <= 20; j++)
                        {
                            var wmFolder = string.Format(folder, searchText.PadLeft(4, '0'), bodyList[i].ToString().PadLeft(4, '0')) + j.ToString().PadLeft(4, '0');

                            var files = Helper.GetAllFilesInFolder(FFCRC.GetHash(wmFolder), Strings.ItemsDat);

                            foreach (var eq in eqSlots)
                            {
                                var wmFile = string.Format(file, searchText.PadLeft(4, '0'), bodyList[i].ToString().PadLeft(4, '0'), eq);

                                var fileHash = FFCRC.GetHash(wmFile);
                                if (files.Contains(fileHash))
                                {
                                    workList.Add(new SearchItems()
                                    {
                                        Race = "-", Slot = equipSlotDict[eq], SlotID = Info.IDSlot[equipSlotDict[eq]], Body = bodyList[i].ToString(), Variant = j.ToString(), Part = eq
                                    });
                                }

                                ProgressLabel = "Body: " + bodyList[i] + " Variant: " + j;
                            }
                        }

                        int prog = (int)(((double)(i + 1) / bodyList.Count) * 100f);
                        worker.ReportProgress(prog);
                    }

                    ProgressLabel = "Found: " + workList.Count;
                }
            }
            e.Result = workList;
        }
Exemple #24
0
        /// <summary>
        /// Parses the MDL file to obtain model information
        /// </summary>
        /// <param name="selectedItem">The currently selected item</param>
        /// <param name="selectedRace">The currently selected race</param>
        /// <param name="selectedBody">The currently selected body</param>
        /// <param name="selectedPart">The currently selected part</param>
        /// <param name="selectedCategory">The items category </param>
        public MDL(ItemData selectedItem, string selectedCategory, string selectedRace, string selectedBody, string selectedPart)
        {
            string itemType  = Helper.GetCategoryType(selectedCategory);
            string MDLFolder = "";

            if (itemType.Equals("weapon") || itemType.Equals("food"))
            {
                if (selectedPart.Equals("Secondary"))
                {
                    MDLFolder = string.Format(Strings.WeapMDLFolder, selectedItem.SecondaryModelID, selectedItem.SecondaryModelBody);
                    MDLFile   = string.Format(Strings.WeapMDLFile, selectedItem.SecondaryModelID, selectedItem.SecondaryModelBody);
                }
                else
                {
                    MDLFolder = string.Format(Strings.WeapMDLFolder, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody);
                    MDLFile   = string.Format(Strings.WeapMDLFile, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody);
                }
            }
            else if (itemType.Equals("accessory"))
            {
                MDLFolder = string.Format(Strings.AccMDLFolder, selectedItem.PrimaryModelID);
                MDLFile   = string.Format(Strings.AccMDLFile, selectedRace, selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
            }
            else if (itemType.Equals("character"))
            {
                if (selectedItem.ItemName.Equals(Strings.Body))
                {
                    MDLFolder = string.Format(Strings.BodyMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.BodyMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Face))
                {
                    MDLFolder = string.Format(Strings.FaceMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.FaceMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Hair))
                {
                    MDLFolder = string.Format(Strings.HairMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.HairMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Tail))
                {
                    MDLFolder = string.Format(Strings.TailMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.TailMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
            }
            else if (itemType.Equals("monster"))
            {
                bool isDemiHuman = false;
                if (selectedItem.PrimaryMTRLFolder != null)
                {
                    isDemiHuman = selectedItem.PrimaryMTRLFolder.Contains("demihuman");
                }

                string ID   = "";
                string body = "";

                if (selectedCategory.Equals(Strings.Pets))
                {
                    ID   = Info.petID[selectedItem.ItemName];
                    body = "0001";
                }
                else
                {
                    ID   = selectedItem.PrimaryModelID.PadLeft(4, '0');
                    body = selectedItem.PrimaryModelBody;
                }

                if (isDemiHuman)
                {
                    MDLFolder = string.Format(Strings.DemiMDLFolder, ID, body);
                    MDLFile   = string.Format(Strings.DemiMDLFile, ID, body, selectedPart);
                }
                else
                {
                    MDLFolder = string.Format(Strings.MonsterMDLFolder, ID, body);
                    MDLFile   = string.Format(Strings.MonsterMDLFile, ID, body);
                }
            }
            else
            {
                MDLFolder = string.Format(Strings.EquipMDLFolder, selectedItem.PrimaryModelID);
                MDLFile   = string.Format(Strings.EquipMDLFile, selectedRace, selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
            }

            int offset = Helper.GetItemOffset(FFCRC.GetHash(MDLFolder), FFCRC.GetHash(MDLFile));

            int datNum = ((offset / 8) & 0x000f) / 2;

            offset = Helper.OffsetCorrection(datNum, offset);

            var MDLDatData = Helper.GetType3DecompressedData(offset, datNum);

            using (BinaryReader br = new BinaryReader(new MemoryStream(MDLDatData.Item1)))
            {
                ModelData modelData = new ModelData();

                // The size of the header + (size of the mesh information block (136 bytes) * the number of meshes) + padding
                br.BaseStream.Seek(64 + 136 * MDLDatData.Item2 + 4, SeekOrigin.Begin);

                var modelStringCount = br.ReadInt32();
                var stringBlockSize  = br.ReadInt32();
                var stringBlock      = br.ReadBytes(stringBlockSize);

                var unknown = br.ReadBytes(4);

                var totalMeshCount       = br.ReadInt16();
                var attributeStringCount = br.ReadInt16();
                var meshPartsCount       = br.ReadInt16();
                var materialStringCount  = br.ReadInt16();
                var boneStringCount      = br.ReadInt16();
                var boneListCount        = br.ReadInt16();

                var unknown1 = br.ReadInt16();
                var unknown2 = br.ReadInt16();
                var unknown3 = br.ReadInt16();
                var unknown4 = br.ReadInt16();
                var unknown5 = br.ReadInt16();
                var unknown6 = br.ReadInt16();

                br.ReadBytes(10);

                var unknown7 = br.ReadInt16();

                br.ReadBytes(16);

                using (BinaryReader br1 = new BinaryReader(new MemoryStream(stringBlock)))
                {
                    br1.BaseStream.Seek(0, SeekOrigin.Begin);

                    for (int i = 0; i < attributeStringCount; i++)
                    {
                        while (br1.ReadByte() != 0)
                        {
                            //extract each atribute string here
                        }
                    }

                    for (int i = 0; i < boneStringCount; i++)
                    {
                        while (br1.ReadByte() != 0)
                        {
                            //extact each bone string here
                        }
                    }

                    for (int i = 0; i < materialStringCount; i++)
                    {
                        byte        b;
                        List <byte> name = new List <byte>();
                        while ((b = br1.ReadByte()) != 0)
                        {
                            name.Add(b);
                        }
                        string material = Encoding.ASCII.GetString(name.ToArray());
                        material = material.Replace("\0", "");

                        materialStrings.Add(material);
                    }
                }

                br.ReadBytes(32 * unknown5);

                for (int i = 0; i < 3; i++)
                {
                    LevelOfDetail LoD = new LevelOfDetail();
                    LoD.MeshOffset = br.ReadInt16();
                    LoD.MeshCount  = br.ReadInt16();

                    br.ReadBytes(40);

                    LoD.VertexDataSize = br.ReadInt32();
                    LoD.IndexDataSize  = br.ReadInt32();
                    LoD.VertexOffset   = br.ReadInt32();
                    LoD.IndexOffset    = br.ReadInt32();

                    modelData.LoD.Add(LoD);
                }

                var savePos = br.BaseStream.Position;

                for (int i = 0; i < modelData.LoD.Count; i++)
                {
                    List <MeshDataInfo> meshInfoList = new List <MeshDataInfo>();

                    for (int j = 0; j < modelData.LoD[i].MeshCount; j++)
                    {
                        modelData.LoD[i].MeshList.Add(new Mesh());
                        meshInfoList.Clear();

                        br.BaseStream.Seek((i * 136) + 68, SeekOrigin.Begin);
                        var dataBlockNum = br.ReadByte();

                        while (dataBlockNum != 255)
                        {
                            MeshDataInfo meshInfo = new MeshDataInfo()
                            {
                                VertexDataBlock = dataBlockNum,
                                Offset          = br.ReadByte(),
                                DataType        = br.ReadByte(),
                                UseType         = br.ReadByte()
                            };

                            meshInfoList.Add(meshInfo);

                            br.ReadBytes(4);

                            dataBlockNum = br.ReadByte();
                        }

                        modelData.LoD[i].MeshList[j].MeshDataInfoList = meshInfoList.ToArray();
                    }
                }

                br.BaseStream.Seek(savePos, SeekOrigin.Begin);

                for (int x = 0; x < modelData.LoD.Count; x++)
                {
                    for (int i = 0; i < modelData.LoD[x].MeshCount; i++)
                    {
                        MeshInfo meshInfo = new MeshInfo()
                        {
                            VertexCount     = br.ReadInt32(),
                            IndexCount      = br.ReadInt32(),
                            MaterialNum     = br.ReadInt16(),
                            MeshPartOffset  = br.ReadInt16(),
                            MeshPartCount   = br.ReadInt16(),
                            BoneListIndex   = br.ReadInt16(),
                            IndexDataOffset = br.ReadInt32()
                        };

                        for (int j = 0; j < 3; j++)
                        {
                            meshInfo.VertexDataOffsets.Add(br.ReadInt32());
                        }

                        for (int k = 0; k < 3; k++)
                        {
                            meshInfo.VertexSizes.Add(br.ReadByte());
                        }

                        meshInfo.VertexDataBlockCount = br.ReadByte();

                        modelData.LoD[x].MeshList[i].MeshInfo = meshInfo;
                    }
                }

                br.ReadBytes(attributeStringCount * 4);
                br.ReadBytes(unknown6 * 20);

                for (int i = 0; i < modelData.LoD.Count; i++)
                {
                    foreach (var mesh in modelData.LoD[i].MeshList)
                    {
                        for (int j = 0; j < mesh.MeshInfo.MeshPartCount; j++)
                        {
                            MeshPart meshPart = new MeshPart()
                            {
                                IndexOffset = br.ReadInt32(),
                                IndexCount  = br.ReadInt32(),
                                Attributes  = br.ReadInt32(),
                                BoneOffset  = br.ReadInt16(),
                                BoneCount   = br.ReadInt16()
                            };

                            mesh.MeshPartList.Add(meshPart);
                        }
                    }
                }

                br.ReadBytes(unknown7 * 12);
                br.ReadBytes(materialStringCount * 4);
                br.ReadBytes(boneStringCount * 4);

                for (int i = 0; i < boneListCount; i++)
                {
                    Bones bones = new Bones();

                    for (int j = 0; j < 64; j++)
                    {
                        bones.BoneData.Add(br.ReadInt16());
                    }

                    bones.BoneCount = br.ReadInt32();

                    modelData.BoneSet.Add(bones);
                }

                br.ReadBytes(unknown1 * 16);
                br.ReadBytes(unknown2 * 12);
                br.ReadBytes(unknown3 * 4);

                var boneIndexSize = br.ReadInt32();

                for (int i = 0; i < boneIndexSize / 2; i++)
                {
                    modelData.BoneIndicies.Add(br.ReadInt16());
                }

                int padding = br.ReadByte();
                br.ReadBytes(padding);

                for (int i = 0; i < 4; i++)
                {
                    ModelMaterial.BoundingBox boundingBox = new ModelMaterial.BoundingBox();
                    for (int j = 0; j < 4; j++)
                    {
                        boundingBox.PointA.Add(br.ReadSingle());
                    }
                    for (int k = 0; k < 4; k++)
                    {
                        boundingBox.PointB.Add(br.ReadSingle());
                    }

                    modelData.BoundingBoxes.Add(boundingBox);
                }

                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < modelData.LoD[i].MeshCount; j++)
                    {
                        Mesh mesh = modelData.LoD[i].MeshList[j];

                        for (int k = 0; k < mesh.MeshInfo.VertexDataBlockCount; k++)
                        {
                            br.BaseStream.Seek(modelData.LoD[i].VertexOffset + mesh.MeshInfo.VertexDataOffsets[k], SeekOrigin.Begin);

                            mesh.MeshVertexData.Add(br.ReadBytes(mesh.MeshInfo.VertexSizes[k] * mesh.MeshInfo.VertexCount));
                        }

                        br.BaseStream.Seek(modelData.LoD[i].IndexOffset + (mesh.MeshInfo.IndexDataOffset * 2), SeekOrigin.Begin);

                        mesh.IndexData = br.ReadBytes(2 * mesh.MeshInfo.IndexCount);
                    }
                }

                int vertex = 0, coordinates = 0, normals = 0, tangents = 0, colors = 0;

                for (int i = 0; i < modelData.LoD[0].MeshCount; i++)
                {
                    objBytes.Clear();

                    var vertexList   = new Vector3Collection();
                    var texCoordList = new Vector2Collection();
                    var normalList   = new Vector3Collection();
                    var tangentList  = new Vector3Collection();
                    var colorsList   = new Color4Collection();
                    var indexList    = new IntCollection();

                    Mesh mesh = modelData.LoD[0].MeshList[i];

                    MeshDataInfo[] meshDataInfoList = mesh.MeshDataInfoList;

                    int c = 0;
                    foreach (var meshDataInfo in meshDataInfoList)
                    {
                        if (meshDataInfo.UseType == 0)
                        {
                            vertex = c;
                        }
                        else if (meshDataInfo.UseType == 3)
                        {
                            normals = c;
                        }
                        else if (meshDataInfo.UseType == 4)
                        {
                            coordinates = c;
                        }
                        else if (meshDataInfo.UseType == 6)
                        {
                            tangents = c;
                        }
                        else if (meshDataInfo.UseType == 7)
                        {
                            colors = c;
                        }

                        c++;
                    }

                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[vertex].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[vertex].VertexDataBlock] + meshDataInfoList[vertex].Offset, SeekOrigin.Begin);

                            if (meshDataInfoList[vertex].DataType == 13 || meshDataInfoList[vertex].DataType == 14)
                            {
                                System.Half h1 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h2 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h3 = System.Half.ToHalf((ushort)br1.ReadInt16());

                                float x = HalfHelper.HalfToSingle(h1);
                                float y = HalfHelper.HalfToSingle(h2);
                                float z = HalfHelper.HalfToSingle(h3);

                                objBytes.Add("v " + x.ToString() + " " + y.ToString() + " " + z.ToString() + " ");
                                vertexList.Add(new Vector3(x, y, z));
                            }
                            else if (meshDataInfoList[vertex].DataType == 2)
                            {
                                float x = br1.ReadSingle();
                                float y = br1.ReadSingle();
                                float z = br1.ReadSingle();

                                objBytes.Add("v " + x.ToString() + " " + y.ToString() + " " + z.ToString() + " ");
                                vertexList.Add(new Vector3(x, y, z));
                            }
                        }
                    }

                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[coordinates].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[coordinates].VertexDataBlock] + meshDataInfoList[coordinates].Offset, SeekOrigin.Begin);

                            System.Half h1 = System.Half.ToHalf((ushort)br1.ReadInt16());
                            System.Half h2 = System.Half.ToHalf((ushort)br1.ReadInt16());

                            float x = HalfHelper.HalfToSingle(h1);
                            float y = HalfHelper.HalfToSingle(h2);

                            objBytes.Add("vt " + x.ToString() + " " + (y * -1f).ToString() + " ");
                            texCoordList.Add(new Vector2(x, y));
                        }
                    }

                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[normals].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[normals].VertexDataBlock] + meshDataInfoList[normals].Offset, SeekOrigin.Begin);

                            System.Half h1 = System.Half.ToHalf((ushort)br1.ReadInt16());
                            System.Half h2 = System.Half.ToHalf((ushort)br1.ReadInt16());
                            System.Half h3 = System.Half.ToHalf((ushort)br1.ReadInt16());

                            objBytes.Add("vn " + HalfHelper.HalfToSingle(h1).ToString() + " " + HalfHelper.HalfToSingle(h2).ToString() + " " + HalfHelper.HalfToSingle(h3).ToString() + " ");
                            normalList.Add(new Vector3(HalfHelper.HalfToSingle(h1), HalfHelper.HalfToSingle(h2), HalfHelper.HalfToSingle(h3)));
                        }
                    }

                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[tangents].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[tangents].VertexDataBlock] + meshDataInfoList[tangents].Offset, SeekOrigin.Begin);

                            float x = br1.ReadByte() / 255f;
                            float y = br1.ReadByte() / 255f;
                            float z = br1.ReadByte() / 255f;

                            tangentList.Add(new Vector3(x, y, z));
                        }
                    }

                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[colors].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[colors].VertexDataBlock] + meshDataInfoList[colors].Offset, SeekOrigin.Begin);

                            int a = br1.ReadByte();
                            int r = br1.ReadByte();
                            int g = br1.ReadByte();
                            int b = br1.ReadByte();

                            colorsList.Add(new Color4(r, g, b, a));
                        }
                    }

                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.IndexData)))
                    {
                        for (int j = 0; j < mesh.MeshInfo.IndexCount; j += 3)
                        {
                            int i1 = br1.ReadInt16();
                            int i2 = br1.ReadInt16();
                            int i3 = br1.ReadInt16();

                            objBytes.Add("f " + (i1 + 1) + "/" + (i1 + 1) + "/" + (i1 + 1) + " " + (i2 + 1) + "/" + (i2 + 1) + "/" + (i2 + 1) + " " + (i3 + 1) + "/" + (i3 + 1) + "/" + (i3 + 1) + " ");

                            indexList.Add(i1);
                            indexList.Add(i2);
                            indexList.Add(i3);
                        }
                    }

                    ModelMeshData modelMeshData = new ModelMeshData()
                    {
                        Vertices           = vertexList,
                        Normals            = normalList,
                        TextureCoordinates = texCoordList,
                        Tangents           = tangentList,
                        Indices            = indexList,
                        VertexColors       = colorsList,
                        OBJFileData        = objBytes.ToArray()
                    };

                    meshList.Add(modelMeshData);
                }
            }
        }