Ejemplo n.º 1
0
        /// <summary>
        /// Gets the Part for a given Character Item
        /// </summary>
        /// <remarks>
        /// For Body and Tail Character Items since they don't have Types
        /// </remarks>
        /// <param name="charaItem">The character item</param>
        /// <param name="race">The race</param>
        /// <param name="num">The character item number</param>
        /// <param name="variant">the variant for the mtrl folder</param>
        /// <returns>An array of characters containing the parts for the texture</returns>
        public async Task <char[]> GetPartForTextures(XivCharacter charaItem, XivRace race, int num, int variant = 1)
        {
            var folder = "";
            var file   = "";

            var parts = Constants.Alphabet;

            if (charaItem.SecondaryCategory == XivStrings.Body)
            {
                folder = string.Format(XivStrings.BodyMtrlFolderVar, race.GetRaceCode(), num.ToString().PadLeft(4, '0'), variant.ToString().PadLeft(4, '0'));
                file   = XivStrings.BodyMtrlFile;
            }
            else if (charaItem.SecondaryCategory == XivStrings.Tail)
            {
                folder = string.Format(XivStrings.TailMtrlFolder, race.GetRaceCode(), num.ToString().PadLeft(4, '0'));
                file   = XivStrings.TailMtrlFile;
            }
            else if (charaItem.SecondaryCategory == XivStrings.Ear)
            {
                folder = string.Format(XivStrings.EarsMtrlFolder, race.GetRaceCode(), num.ToString().PadLeft(4, '0'));

                file = XivStrings.EarsMtrlFile;
            }

            var fileList = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(folder), XivDataFile._04_Chara);

            return((from part in parts
                    let mtrlFile = string.Format(file, race.GetRaceCode(), num.ToString().PadLeft(4, '0'), part)
                                   where fileList.Contains(HashGenerator.GetHash(mtrlFile))
                                   select part).ToArray());
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets the Part for a given Character Item
        /// </summary>
        /// <remarks>
        /// For Body and Tail Character Items since they don't have Types
        /// </remarks>
        /// <param name="charaItem">The character item</param>
        /// <param name="race">The race</param>
        /// <param name="num">The character item number</param>
        /// <returns>A dictionary containging [</returns>
        public char[] GetPartForTextures(XivCharacter charaItem, XivRace race, int num)
        {
            var index = new Index(_gameDirectory);

            var folder = "";
            var file   = "";

            var parts = new[] { 'a', 'b', 'c', 'd', 'e', 'f' };

            if (charaItem.ItemCategory == XivStrings.Body)
            {
                folder = string.Format(XivStrings.BodyMtrlFolder, race.GetRaceCode(), num.ToString().PadLeft(4, '0'));
                file   = XivStrings.BodyMtrlFile;
            }
            else if (charaItem.ItemCategory == XivStrings.Tail)
            {
                folder = string.Format(XivStrings.TailMtrlFolder, race.GetRaceCode(), num.ToString().PadLeft(4, '0'));
                file   = XivStrings.TailMtrlFile;
            }

            var fileList = index.GetAllHashedFilesInFolder(HashGenerator.GetHash(folder), XivDataFile._04_Chara);

            return((from part in parts let mtrlFile = string.Format(file, race.GetRaceCode(), num.ToString().PadLeft(4, '0'), part)
                                                      where fileList.Contains(HashGenerator.GetHash(mtrlFile)) select part).ToArray());
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the Type and Part for a given Character Item
        /// </summary>
        /// <remarks>
        /// Only Hair and Face Character Items have Types
        /// </remarks>
        /// <param name="charaItem">The character item</param>
        /// <param name="race">The race</param>
        /// <param name="num">The character item number</param>
        /// <returns>A dictionary containing</returns>
        public async Task <Dictionary <string, char[]> > GetTypePartForTextures(XivCharacter charaItem, XivRace race, int num)
        {
            var typePartDictionary = new Dictionary <string, char[]>();

            var folder   = "";
            var file     = "";
            var typeDict = HairSlotAbbreviationDictionary;

            var parts = new[] { 'a', 'b', 'c', 'd', 'e', 'f' };

            if (charaItem.ItemCategory == XivStrings.Hair)
            {
                folder = string.Format(XivStrings.HairMtrlFolder, race.GetRaceCode(),
                                       num.ToString().PadLeft(4, '0'));
                file = XivStrings.HairMtrlFile;
            }
            else if (charaItem.ItemCategory == XivStrings.Face)
            {
                folder = string.Format(XivStrings.FaceMtrlFolder, race.GetRaceCode(),
                                       num.ToString().PadLeft(4, '0'));
                typeDict = FaceSlotAbbreviationDictionary;
                file     = XivStrings.FaceMtrlFile;
            }
            else if (charaItem.ItemCategory == XivStrings.Ears)
            {
                folder = string.Format(XivStrings.EarsMtrlFolder, race.GetRaceCode(),
                                       num.ToString().PadLeft(4, '0'));
                typeDict = EarsSlotAbbreviationDictionary;
                file     = XivStrings.EarsMtrlFile;
            }

            var fileList = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(folder), XivDataFile._04_Chara);

            foreach (var type in typeDict)
            {
                var partList = new List <char>();

                foreach (var part in parts)
                {
                    var mtrlFile = string.Format(file, race.GetRaceCode(), num.ToString().PadLeft(4, '0'),
                                                 type.Value, part);

                    if (fileList.Contains(HashGenerator.GetHash(mtrlFile)))
                    {
                        partList.Add(part);
                    }
                }

                if (partList.Count > 0)
                {
                    typePartDictionary.Add(type.Key, partList.ToArray());
                }
            }

            return(typePartDictionary);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets the Type of models for a given Character Item
        /// </summary>
        /// <param name="charaItem">The character item</param>
        /// <param name="race">The race</param>
        /// <param name="num">The character item number</param>
        /// <returns>A dictionary containging [</returns>
        public async Task <List <string> > GetTypeForModels(XivCharacter charaItem, XivRace race, int num)
        {
            var folder   = "";
            var file     = "";
            var typeDict = HairSlotAbbreviationDictionary;

            if (charaItem.ItemCategory == XivStrings.Body)
            {
                folder = string.Format(XivStrings.BodyMDLFolder, race.GetRaceCode(),
                                       num.ToString().PadLeft(4, '0'));
                typeDict = BodySlotAbbreviationDictionary;
                file     = XivStrings.BodyMDLFile;
            }
            else if (charaItem.ItemCategory == XivStrings.Hair)
            {
                folder = string.Format(XivStrings.HairMDLFolder, race.GetRaceCode(),
                                       num.ToString().PadLeft(4, '0'));
                typeDict = HairSlotAbbreviationDictionary;
                file     = XivStrings.HairMDLFile;
            }
            else if (charaItem.ItemCategory == XivStrings.Face)
            {
                folder = string.Format(XivStrings.FaceMDLFolder, race.GetRaceCode(),
                                       num.ToString().PadLeft(4, '0'));
                typeDict = FaceSlotAbbreviationDictionary;
                file     = XivStrings.FaceMDLFile;
            }
            else if (charaItem.ItemCategory == XivStrings.Tail)
            {
                folder = string.Format(XivStrings.TailMDLFolder, race.GetRaceCode(),
                                       num.ToString().PadLeft(4, '0'));
                typeDict = TailSlotAbbreviationDictionary;
                file     = XivStrings.TailMDLFile;
            }

            var fileList = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(folder), XivDataFile._04_Chara);

            var typeList = new List <string>();

            foreach (var type in typeDict)
            {
                var mdlFile = string.Format(file, race.GetRaceCode(), num.ToString().PadLeft(4, '0'), type.Value);

                if (fileList.Contains(HashGenerator.GetHash(mdlFile)))
                {
                    typeList.Add(type.Key);
                }
            }

            return(typeList);
        }
Ejemplo n.º 5
0
        public async Task <List <int> > GetVariantsForTextures(XivCharacter charaItem, XivRace race, int num)
        {
            var variantList = new List <int>();

            if (charaItem.ItemCategory == XivStrings.Body)
            {
                if (_language != XivLanguage.Korean)
                {
                    var testDictionary = new Dictionary <int, int>();

                    for (var i = 0; i < 50; i++)
                    {
                        var folder = string.Format(XivStrings.BodyMtrlFolderVar, race.GetRaceCode(), num.ToString().PadLeft(4, '0'), i.ToString().PadLeft(4, '0'));
                        testDictionary.Add(HashGenerator.GetHash(folder), i);

                        variantList = await _index.GetFolderExistsList(testDictionary, XivDataFile._04_Chara);

                        variantList.Sort();
                    }
                }
                else
                {
                    variantList.Add(1);
                }
            }

            if (charaItem.ItemCategory == XivStrings.Tail)
            {
                if (_language != XivLanguage.Korean)
                {
                    var testDictionary = new Dictionary <int, int>();

                    for (var i = 0; i < 50; i++)
                    {
                        var folder = string.Format(XivStrings.TailMtrlFolderVar, race.GetRaceCode(), num.ToString().PadLeft(4, '0'), i.ToString().PadLeft(4, '0'));
                        testDictionary.Add(HashGenerator.GetHash(folder), i);

                        variantList = await _index.GetFolderExistsList(testDictionary, XivDataFile._04_Chara);

                        variantList.Sort();
                    }
                }
                else
                {
                    variantList.Add(1);
                }
            }

            return(variantList);
        }
        private static IItemModel GetFaceModel(XivRace race, byte head, byte eyebrows, byte eyes, byte nose, byte jaw, byte mouth)
        {
            int raceCode = int.Parse(race.GetRaceCode());

            foreach (IItem item in allItems)
            {
                if (item is IItemModel itemModel)
                {
                    if (item.PrimaryCategory != "Character")
                    {
                        continue;
                    }

                    if (item.SecondaryCategory != "Face")
                    {
                        continue;
                    }

                    if (itemModel.ModelInfo.PrimaryID != raceCode)
                    {
                        continue;
                    }

                    XivCharacter faceItem = (XivCharacter)itemModel.Clone();

                    faceItem.ModelInfo             = new XivModelInfo();
                    faceItem.ModelInfo.SecondaryID = head;
                    return(faceItem);
                }
            }

            throw new Exception($"Failed to find face model: {race}, {head}");
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Gets the raw equipment or accessory deformation parameters file for a given race.
        /// </summary>
        /// <returns></returns>
        private async Task <List <byte> > LoadEquipmentDeformationFile(XivRace race, bool accessory = false)
        {
            var rootPath = accessory ? AccessoryDeformerParameterRootPath : EquipmentDeformerParameterRootPath;
            var fileName = rootPath + "c" + race.GetRaceCode() + "." + EquipmentDeformerParameterExtension;

            return(new List <byte>(await _dat.GetType2Data(fileName, false)));
        }
        private static IItemModel GetHairModel(XivRace race, byte hair)
        {
            int raceCode = int.Parse(race.GetRaceCode());

            foreach (IItem item in allItems)
            {
                if (item is IItemModel itemModel)
                {
                    if (item.PrimaryCategory != "Character")
                    {
                        continue;
                    }

                    if (item.SecondaryCategory != "Hair")
                    {
                        continue;
                    }

                    if (itemModel.ModelInfo.PrimaryID != raceCode)
                    {
                        continue;
                    }

                    XivCharacter faceItem = (XivCharacter)itemModel.Clone();

                    faceItem.ModelInfo             = new XivModelInfo();
                    faceItem.ModelInfo.SecondaryID = hair;
                    return(faceItem);
                }
            }

            throw new Exception($"Failed to find hair model: {race}, {hair}");
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Retrieves the file path to the model's base skeleton file.
        /// </summary>
        /// <param name="fullMdlPath"></param>
        private static async Task <string> GetBaseSkelbPath(XivDependencyRootInfo root, XivRace race = XivRace.All_Races)
        {
            var skelFolder = "";
            var skelFile   = "";

            if (root.PrimaryType != XivItemType.human && root.PrimaryType != XivItemType.equipment && root.PrimaryType != XivItemType.accessory)
            {
                var typeName = XivItemTypes.GetSystemName(root.PrimaryType);
                var prefix   = XivItemTypes.GetSystemPrefix(root.PrimaryType);
                var id       = root.PrimaryId.ToString().PadLeft(4, '0');
                var bodyCode = "0001";
                var path     = $"chara/{typeName}/{prefix}{id}/skeleton/base/b{bodyCode}/skl_{prefix}{id}b{bodyCode}.sklb";
                return(path);
            }
            else
            {
                // Equipment and accessories need an external race passed in.
                var raceCode = race.GetRaceCode();
                if (root.PrimaryType == XivItemType.human && race != XivRace.All_Races)
                {
                    raceCode = root.PrimaryId.ToString().PadLeft(4, '0');
                }

                var bodyCode = "0001";
                skelFolder = $"chara/human/c{raceCode}/skeleton/base/b{bodyCode}";
                skelFile   = $"skl_c{raceCode}b{bodyCode}.sklb";
                return(skelFolder + "/" + skelFile);
            }
        }
        /// <summary>
        /// Gets the matrices for the bones used in the model
        /// </summary>
        /// <param name="boneList">List of bones used in the model</param>
        /// <param name="targetRace">Target Race to get the bone data for</param>
        /// <returns>A matrix array containing the pose data for each bone</returns>
        private Matrix[] GetMatrices(List <string> boneList, XivRace targetRace)
        {
            // Get the skeleton file for the target race
            var skeletonFile = Directory.GetCurrentDirectory() + $"/Skeletons/c{targetRace.GetRaceCode()}.skel";
            var skeletonData = File.ReadAllLines(skeletonFile);

            // Deserialize the skeleton json and create a dictionary of all bones
            var skelData = new Dictionary <string, SkeletonData>();

            foreach (var b in skeletonData)
            {
                if (b == "")
                {
                    continue;
                }
                var j = JsonConvert.DeserializeObject <SkeletonData>(b);

                skelData.Add(j.BoneName, j);
            }

            // Add matrices for bones in the model to a list
            // Add missing bones if they exist in the model but not in the target race
            var matrixList   = new List <Matrix>();
            var missingBones = new List <string>();

            foreach (var bone in boneList)
            {
                if (skelData.ContainsKey(bone))
                {
                    var matrix = new Matrix(skelData[bone].InversePoseMatrix);
                    matrix.Invert();

                    matrixList.Add(matrix);
                }
                else
                {
                    missingBones.Add(bone);
                }
            }

            // Show a warning when there is bones in the model that do not exist in the target race skeleton
            // The model will still be added, but with no bones animation will not work for that part
            if (missingBones.Count > 0)
            {
                var warning = new StringBuilder();
                warning.AppendLine();

                foreach (var bone in missingBones)
                {
                    warning.AppendLine(bone);
                }

                FlexibleMessageBox.Show(string.Format(UIMessages.MissingBones, targetRace, warning), UIMessages.MissingBonesTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            return(matrixList.ToArray());
        }
        /// <summary>
        /// Creates the Bones to be used in the format Helix Toolkit uses
        /// </summary>
        /// <param name="boneList">The list of bones in the model</param>
        /// <param name="targetRace">The target race to get the bones from</param>
        /// <returns>A list of Bone structures used by Helix Toolkit</returns>
        private List <Bone> MakeHelixBones(List <string> boneList, XivRace targetRace)
        {
            // Get the skeleton file for the target race
            var skeletonFile = Directory.GetCurrentDirectory() + $"/Skeletons/c{targetRace.GetRaceCode()}.skel";
            var skeletonData = File.ReadAllLines(skeletonFile);


            // Deserialize the skeleton json and create a dictionary of all bones
            var boneDict = new Dictionary <int, SkeletonData>();

            foreach (var b in skeletonData)
            {
                if (b == "")
                {
                    continue;
                }
                var j = JsonConvert.DeserializeObject <SkeletonData>(b);

                boneDict.Add(j.BoneNumber, j);
            }

            // Add only the bones that are contained in the model including all parent bones
            var bonesInModel = new List <SkeletonData>();

            foreach (var bone in boneDict)
            {
                if (!boneList.Contains(bone.Value.BoneName))
                {
                    continue;
                }

                bonesInModel.Add(bone.Value);

                AddBones(boneDict, bonesInModel, bone.Value);
            }

            // Create a bone list with the bones for the model in helix toolkit format
            var helixBoneList = new List <Bone>();

            foreach (var bone in bonesInModel)
            {
                var bp = new Matrix(bone.InversePoseMatrix);
                bp.Invert();

                helixBoneList.Add(new Bone
                {
                    BindPose    = bp,
                    Name        = bone.BoneName,
                    ParentIndex = bone.BoneParent
                });
            }

            return(helixBoneList);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Gets the Part for a given Character Item
        /// </summary>
        /// <remarks>
        /// For Body and Tail Character Items since they don't have Types
        /// </remarks>
        /// <param name="charaItem">The character item</param>
        /// <param name="race">The race</param>
        /// <param name="num">The character item number</param>
        /// <returns>A dictionary containging [</returns>
        public async Task <char[]> GetPartForTextures(XivCharacter charaItem, XivRace race, int num)
        {
            var folder = "";
            var file   = "";

            var parts = new[] { 'a', 'b', 'c', 'd', 'e', 'f' };

            if (charaItem.ItemCategory == XivStrings.Body)
            {
                if (_language != XivLanguage.Korean && _language != XivLanguage.Chinese)
                {
                    folder = string.Format(XivStrings.BodyMtrlFolder, race.GetRaceCode(), num.ToString().PadLeft(4, '0'));
                }
                else
                {
                    folder = string.Format(XivStrings.BodyMtrlFolderOld, race.GetRaceCode(), num.ToString().PadLeft(4, '0'));
                }
                file = XivStrings.BodyMtrlFile;
            }
            else if (charaItem.ItemCategory == XivStrings.Tail)
            {
                if (_language != XivLanguage.Korean && _language != XivLanguage.Chinese)
                {
                    folder = string.Format(XivStrings.TailMtrlFolder, race.GetRaceCode(), num.ToString().PadLeft(4, '0'));
                }
                else
                {
                    folder = string.Format(XivStrings.TailMtrlFolderOld, race.GetRaceCode(), num.ToString().PadLeft(4, '0'));
                }
                file = XivStrings.TailMtrlFile;
            }

            var fileList = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(folder), XivDataFile._04_Chara);

            return((from part in parts
                    let mtrlFile = string.Format(file, race.GetRaceCode(), num.ToString().PadLeft(4, '0'), part)
                                   where fileList.Contains(HashGenerator.GetHash(mtrlFile))
                                   select part).ToArray());
        }
        private static IItemModel GetEarsTailModel(XivRace race, byte id)
        {
            int raceCode = int.Parse(race.GetRaceCode());

            if (id == 0)
            {
                id = 1;
            }

            foreach (IItem item in allItems)
            {
                if (item is IItemModel itemModel)
                {
                    if (item.PrimaryCategory != "Character")
                    {
                        continue;
                    }

                    if (item.SecondaryCategory != "Ear" && item.SecondaryCategory != "Tail")
                    {
                        continue;
                    }

                    if (itemModel.ModelInfo.PrimaryID != raceCode)
                    {
                        continue;
                    }

                    XivCharacter earTailItem = (XivCharacter)itemModel.Clone();

                    earTailItem.ModelInfo             = new XivModelInfo();
                    earTailItem.ModelInfo.SecondaryID = id;
                    return(earTailItem);
                }
            }

            throw new Exception($"Failed to find Ears/Tail model: {race}, {id}");
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Gets the mtrl path for a given item
        /// </summary>
        /// <param name="itemModel">Item that contains model data</param>
        /// <param name="xivRace">The race for the requested data</param>
        /// <param name="part">The mtrl part <see cref="GearInfo.GetPartList(IItemModel, XivRace)"/></param>
        /// <param name="itemType">The type of the item</param>
        /// <returns>A tuple containing the mtrl folder and file, and whether it has a vfx</returns>
        private (string Folder, string File, bool HasVfx) GetMtrlPath(IItemModel itemModel, XivRace xivRace, char part, XivItemType itemType)
        {
            // The default version number
            var version = "0001";

            var hasVfx = false;

            if (itemType != XivItemType.human && itemType != XivItemType.furniture)
            {
                // get the items version from the imc file
                var imc     = new Imc(_gameDirectory, _dataFile);
                var imcInfo = imc.GetImcInfo(itemModel, itemModel.ModelInfo);
                version = imcInfo.Version.ToString().PadLeft(4, '0');

                if (imcInfo.Vfx > 0)
                {
                    hasVfx = true;
                }
            }

            var id      = itemModel.ModelInfo.ModelID.ToString().PadLeft(4, '0');
            var bodyVer = itemModel.ModelInfo.Body.ToString().PadLeft(4, '0');
            var race    = xivRace.GetRaceCode();

            string mtrlFolder = "", mtrlFile = "";

            switch (itemType)
            {
            case XivItemType.equipment:
                mtrlFolder = $"chara/{itemType}/e{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}e{id}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_{part}{MtrlExtension}";
                break;

            case XivItemType.accessory:
                mtrlFolder = $"chara/{itemType}/a{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}a{id}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_{part}{MtrlExtension}";
                break;

            case XivItemType.weapon:
                mtrlFolder = $"chara/{itemType}/w{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_w{id}b{bodyVer}_{part}{MtrlExtension}";
                break;

            case XivItemType.monster:
                mtrlFolder = $"chara/{itemType}/m{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_m{id}b{bodyVer}_{part}{MtrlExtension}";
                break;

            case XivItemType.demihuman:
                mtrlFolder = $"chara/{itemType}/d{id}/obj/equipment/e{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_d{id}e{bodyVer}_{SlotAbbreviationDictionary[itemModel.ItemSubCategory]}_{part}{MtrlExtension}";
                break;

            case XivItemType.human:
                if (itemModel.ItemCategory.Equals(XivStrings.Body))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/body/b{bodyVer}/material";
                    mtrlFile   = $"mt_c{race}b{bodyVer}_{part}{MtrlExtension}";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Hair))
                {
                    // Hair has a version number, but no IMC, so we leave it at the default 0001
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/hair/h{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{race}h{bodyVer}_{SlotAbbreviationDictionary[itemModel.ItemSubCategory]}_{part}{MtrlExtension}";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Face))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/face/f{bodyVer}/material";
                    mtrlFile   = $"mt_c{race}f{bodyVer}_{SlotAbbreviationDictionary[itemModel.ItemSubCategory]}_{part}{MtrlExtension}";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Tail))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/tail/t{bodyVer}/material";
                    mtrlFile   = $"mt_c{race}t{bodyVer}_{part}{MtrlExtension}";
                }
                break;

            case XivItemType.furniture:
                if (itemModel.ItemCategory.Equals(XivStrings.Furniture_Indoor))
                {
                    mtrlFolder = $"bgcommon/hou/indoor/general/{id}/material";
                    mtrlFile   = $"fun_b0_m{id}_0{part}{MtrlExtension}";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Furniture_Outdoor))
                {
                    mtrlFolder = $"bgcommon/hou/outdoor/general/{id}/material";
                    mtrlFile   = $"gar_b0_m{id}_0{part}{MtrlExtension}";
                }
                break;

            default:
                mtrlFolder = "";
                mtrlFile   = "";
                break;
            }

            return(mtrlFolder, mtrlFile, hasVfx);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Gets the list of available mtrl parts for a given item
        /// </summary>
        /// <param name="itemModel">An item that contains model data</param>
        /// <param name="xivRace">The race for the requested data</param>
        /// <returns>A list of part characters</returns>
        public async Task <List <string> > GetTexturePartList(IItemModel itemModel, XivRace xivRace, XivDataFile dataFile, string type = "Primary")
        {
            var itemType = ItemType.GetItemType(itemModel);

            var version = "0001";

            var id           = itemModel.ModelInfo.ModelID.ToString().PadLeft(4, '0');
            var bodyVer      = itemModel.ModelInfo.Body.ToString().PadLeft(4, '0');
            var itemCategory = itemModel.ItemCategory;

            if (type.Equals("Secondary"))
            {
                var xivGear = itemModel as XivGear;

                id      = xivGear.SecondaryModelInfo.ModelID.ToString().PadLeft(4, '0');
                bodyVer = xivGear.SecondaryModelInfo.Body.ToString().PadLeft(4, '0');

                var imc = new Imc(_gameDirectory, xivGear.DataFile);
                version = (await imc.GetImcInfo(itemModel, xivGear.SecondaryModelInfo)).Version.ToString().PadLeft(4, '0');

                if (imc.ChangedType)
                {
                    itemType     = XivItemType.equipment;
                    xivRace      = XivRace.Hyur_Midlander_Male;
                    itemCategory = XivStrings.Hands;
                }
            }
            else
            {
                if (itemType != XivItemType.human && itemType != XivItemType.furniture)
                {
                    // Get the mtrl version for the given item from the imc file
                    var imc = new Imc(_gameDirectory, dataFile);
                    version = (await imc.GetImcInfo(itemModel, itemModel.ModelInfo)).Version.ToString().PadLeft(4, '0');
                }
            }

            var parts = new[] { 'a', 'b', 'c', 'd', 'e', 'f' };
            var race  = xivRace.GetRaceCode();

            string mtrlFolder = "", mtrlFile = "";

            switch (itemType)
            {
            case XivItemType.equipment:
                mtrlFolder = $"chara/{itemType}/e{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}e{id}_{SlotAbbreviationDictionary[itemCategory]}_";
                break;

            case XivItemType.accessory:
                mtrlFolder = $"chara/{itemType}/a{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}a{id}_{SlotAbbreviationDictionary[itemCategory]}_";
                break;

            case XivItemType.weapon:
                mtrlFolder = $"chara/{itemType}/w{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_w{id}b{bodyVer}_";
                break;

            case XivItemType.monster:
                mtrlFolder = $"chara/{itemType}/m{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_m{id}b{bodyVer}_";
                break;

            case XivItemType.demihuman:
                mtrlFolder = $"chara/{itemType}/d{id}/obj/body/e{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_d{id}e{bodyVer}_";
                break;

            case XivItemType.human:
                if (itemCategory.Equals(XivStrings.Body))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/b{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}b{bodyVer}_";
                }
                else if (itemCategory.Equals(XivStrings.Hair))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/h{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}h{bodyVer}_{SlotAbbreviationDictionary[itemCategory]}_";
                }
                else if (itemCategory.Equals(XivStrings.Face))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/f{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}f{bodyVer}_{SlotAbbreviationDictionary[itemCategory]}_";
                }
                else if (itemCategory.Equals(XivStrings.Tail))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/t{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}t{bodyVer}_";
                }
                break;

            case XivItemType.furniture:
                if (itemCategory.Equals(XivStrings.Furniture_Indoor))
                {
                    mtrlFolder = $"bgcommon/hou/indoor/general/{id}/material";
                    mtrlFile   = $"fun_b0_m{id}_0";
                }
                else if (itemCategory.Equals(XivStrings.Furniture_Outdoor))
                {
                    mtrlFolder = $"bgcommon/hou/outdoor/general/{id}/material";
                    mtrlFile   = $"gar_b0_m{id}_0";
                }

                break;

            default:
                mtrlFolder = "";
                break;
            }

            // Get a list of hashed mtrl files that are in the given folder
            var files = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), dataFile);

            // append the part char to the mtrl file and see if its hashed value is within the files list
            var partList =
                (from part in parts
                 let mtrlCheck = mtrlFile + part + ".mtrl"
                                 where files.Contains(HashGenerator.GetHash(mtrlCheck))
                                 select part.ToString()).ToList();

            if (partList.Count < 1 && itemType == XivItemType.furniture)
            {
                if (itemCategory.Equals(XivStrings.Furniture_Indoor))
                {
                    mtrlFile = $"fun_b0_m{id}_1";
                }
                else if (itemCategory.Equals(XivStrings.Furniture_Outdoor))
                {
                    mtrlFile = $"gar_b0_m{id}_1";
                }

                // Get a list of hashed mtrl files that are in the given folder
                files = await _index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), dataFile);

                // append the part char to the mtrl file and see if its hashed value is within the files list
                partList =
                    (from part in parts
                     let mtrlCheck = mtrlFile + part + ".mtrl"
                                     where files.Contains(HashGenerator.GetHash(mtrlCheck))
                                     select part.ToString()).ToList();
            }

            // returns the list of parts that exist within the mtrl folder
            return(partList);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Gets the list of available mtrl parts for a given item
        /// </summary>
        /// <param name="itemModel">An item that contains model data</param>
        /// <param name="xivRace">The race for the requested data</param>
        /// <returns>A list of part characters</returns>
        public List <string> GetTexturePartList(IItemModel itemModel, XivRace xivRace, XivDataFile dataFile)
        {
            // Get the mtrl version for the given item from the imc file
            var imc     = new Imc(_gameDirectory, dataFile);
            var version = imc.GetImcInfo(itemModel, itemModel.PrimaryModelInfo).Version.ToString().PadLeft(4, '0');

            var id      = itemModel.PrimaryModelInfo.ModelID.ToString().PadLeft(4, '0');
            var bodyVer = itemModel.PrimaryModelInfo.Body.ToString().PadLeft(4, '0');
            var parts   = new[] { 'a', 'b', 'c', 'd', 'e', 'f' };
            var race    = xivRace.GetRaceCode();

            var index = new Index(_gameDirectory);

            var    itemType = ItemType.GetItemType(itemModel);
            string mtrlFolder = "", mtrlFile = "";

            switch (itemType)
            {
            case XivItemType.equipment:
                mtrlFolder = $"chara/{itemType}/e{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}e{id}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_";
                break;

            case XivItemType.accessory:
                mtrlFolder = $"chara/{itemType}/a{id}/material/v{version}";
                mtrlFile   = $"mt_c{race}a{id}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_";
                break;

            case XivItemType.weapon:
                mtrlFolder = $"chara/{itemType}/w{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_w{id}b{bodyVer}_";
                break;

            case XivItemType.monster:
                mtrlFolder = $"chara/{itemType}/m{id}/obj/body/b{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_m{id}b{bodyVer}_";
                break;

            case XivItemType.demihuman:
                mtrlFolder = $"chara/{itemType}/d{id}/obj/body/e{bodyVer}/material/v{version}";
                mtrlFile   = $"mt_d{id}e{bodyVer}_";
                break;

            case XivItemType.human:
                if (itemModel.ItemCategory.Equals(XivStrings.Body))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/b{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}b{bodyVer}_";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Hair))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/h{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}h{bodyVer}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Face))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/f{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}f{bodyVer}_{SlotAbbreviationDictionary[itemModel.ItemCategory]}_";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Tail))
                {
                    mtrlFolder = $"chara/{itemType}/c{id}/obj/body/t{bodyVer}/material/v{version}";
                    mtrlFile   = $"mt_c{id}t{bodyVer}_";
                }
                break;

            default:
                mtrlFolder = "";
                break;
            }

            // Get a list of hashed mtrl files that are in the given folder
            var files = index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), dataFile);

            // append the part char to the mtrl file and see if its hashed value is within the files list
            // returns the list of parts that exist within the mtrl folder
            return((from part in parts let mtrlCheck = mtrlFile + part + ".mtrl" where files.Contains(HashGenerator.GetHash(mtrlCheck)) select part.ToString()).ToList());
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Gets the materials for the model
        /// </summary>
        /// <returns>A dictionary containing the mesh number(key) and the associated texture data (value)</returns>
        public static Dictionary <int, ModelTextureData> GetMaterials(
            DirectoryInfo gameDirectory, IItemModel item, XivMdl mdlData, XivRace race)
        {
            var      textureDataDictionary = new Dictionary <int, ModelTextureData>();
            var      mtrlDictionary        = new Dictionary <int, XivMtrl>();
            var      mtrl                 = new Mtrl(gameDirectory, item.DataFile);
            var      mtrlFilePaths        = mdlData.PathData.MaterialList;
            var      hasColorChangeShader = false;
            Color?   customColor          = null;
            WinColor winColor;

            var materialNum = 0;

            foreach (var mtrlFilePath in mtrlFilePaths)
            {
                var mtrlItem = new XivGenericItemModel
                {
                    Category        = item.Category,
                    ItemCategory    = item.ItemCategory,
                    ItemSubCategory = item.ItemSubCategory,
                    ModelInfo       = new XivModelInfo
                    {
                        Body      = item.ModelInfo.Body,
                        ModelID   = item.ModelInfo.ModelID,
                        ModelType = item.ModelInfo.ModelType,
                        Variant   = item.ModelInfo.Variant
                    },
                    Name = item.Name
                };

                var modelID  = mtrlItem.ModelInfo.ModelID;
                var bodyID   = mtrlItem.ModelInfo.Body;
                var filePath = mtrlFilePath;

                if (!filePath.Contains("hou") && mtrlFilePath.Count(x => x == '/') > 1)
                {
                    filePath = mtrlFilePath.Substring(mtrlFilePath.LastIndexOf("/"));
                }

                var typeChar = $"{mtrlFilePath[4]}{mtrlFilePath[9]}";

                var raceString = "";
                switch (typeChar)
                {
                // Character Body
                case "cb":
                    var body = mtrlFilePath.Substring(mtrlFilePath.IndexOf("b") + 1, 4);
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    if (!raceString.Equals("0901") && !raceString.Equals("1001") && !raceString.Equals("1101"))
                    {
                        var gender = 0;
                        if (int.Parse(raceString.Substring(0, 2)) % 2 == 0)
                        {
                            gender = 1;
                        }

                        var settingsRace = GetSettingsRace(gender);

                        race = settingsRace.Race;

                        filePath = mtrlFilePath.Replace(raceString, race.GetRaceCode()).Replace(body, settingsRace.BodyID);

                        body = settingsRace.BodyID;
                    }


                    mtrlItem = new XivGenericItemModel
                    {
                        Category     = XivStrings.Character,
                        ItemCategory = XivStrings.Body,
                        Name         = XivStrings.Body,
                        ModelInfo    = new XivModelInfo
                        {
                            Body = int.Parse(body)
                        }
                    };

                    winColor    = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Skin_Color);
                    customColor = new Color(winColor.R, winColor.G, winColor.B, winColor.A);

                    break;

                // Face
                case "cf":
                    bodyID     = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("f") + 1, 4));
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    mtrlItem = new XivGenericItemModel
                    {
                        Category     = XivStrings.Character,
                        ItemCategory = XivStrings.Face,
                        Name         = XivStrings.Face,
                        ModelInfo    = new XivModelInfo
                        {
                            Body = bodyID
                        }
                    };

                    break;

                // Hair
                case "ch":
                    bodyID     = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("h") + 1, 4));
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    mtrlItem = new XivGenericItemModel
                    {
                        Category     = XivStrings.Character,
                        ItemCategory = XivStrings.Hair,
                        Name         = XivStrings.Hair,
                        ModelInfo    = new XivModelInfo
                        {
                            Body = bodyID
                        }
                    };

                    winColor    = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Hair_Color);
                    customColor = new Color(winColor.R, winColor.G, winColor.B, winColor.A);

                    break;

                // Tail
                case "ct":
                    var tempPath = mtrlFilePath.Substring(4);
                    bodyID     = int.Parse(tempPath.Substring(tempPath.IndexOf("t") + 1, 4));
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    mtrlItem = new XivGenericItemModel
                    {
                        Category     = XivStrings.Character,
                        ItemCategory = XivStrings.Tail,
                        Name         = XivStrings.Tail,
                        ModelInfo    = new XivModelInfo
                        {
                            Body = bodyID
                        }
                    };

                    winColor    = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Hair_Color);
                    customColor = new Color(winColor.R, winColor.G, winColor.B, winColor.A);

                    break;

                // Equipment
                case "ce":
                    modelID    = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("e") + 1, 4));
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    mtrlItem.ModelInfo.ModelID = modelID;
                    break;

                // Accessory
                case "ca":
                    modelID    = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("a") + 1, 4));
                    raceString = mtrlFilePath.Substring(mtrlFilePath.IndexOf("c") + 1, 4);
                    race       = XivRaces.GetXivRace(raceString);

                    mtrlItem.ModelInfo.ModelID = modelID;
                    break;

                // Weapon
                case "wb":
                    modelID = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("w") + 1, 4));
                    bodyID  = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("b") + 1, 4));
                    mtrlItem.ModelInfo.ModelID = modelID;
                    mtrlItem.ModelInfo.Body    = bodyID;
                    break;

                // Monster
                case "mb":
                    modelID = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("_m") + 2, 4));
                    bodyID  = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("b") + 1, 4));
                    mtrlItem.ModelInfo.ModelID = modelID;
                    mtrlItem.ModelInfo.Body    = bodyID;
                    break;

                // DemiHuman
                case "de":
                    modelID = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("d") + 1, 4));
                    bodyID  = int.Parse(mtrlFilePath.Substring(mtrlFilePath.IndexOf("e") + 1, 4));
                    mtrlItem.ModelInfo.ModelID = modelID;
                    mtrlItem.ModelInfo.Body    = bodyID;
                    break;

                default:
                    break;
                }

                var dxVersion = int.Parse(Settings.Default.DX_Version);

                var     mtrlFile = filePath.Remove(0, 1);
                XivMtrl mtrlData;
                try
                {
                    mtrlData = mtrl.GetMtrlData(mtrlItem, race, mtrlFile, dxVersion);
                }
                catch (Exception)
                {
                    if (mtrlItem.ModelInfo.ModelID == item.ModelInfo.ModelID)
                    {
                        throw;
                    }

                    // Fall back to material data from the primary model.
                    mtrlData = mtrl.GetMtrlData(item, race, mtrlFile, dxVersion);
                }


                if (mtrlData.Shader.Contains("colorchange"))
                {
                    hasColorChangeShader = true;
                }

                mtrlDictionary.Add(materialNum, mtrlData);

                materialNum++;
            }

            foreach (var xivMtrl in mtrlDictionary)
            {
                var modelTexture = new ModelTexture(gameDirectory, xivMtrl.Value);

                if (hasColorChangeShader)
                {
                    var modelMaps = modelTexture.GetModelMaps(null, true);

                    textureDataDictionary.Add(xivMtrl.Key, modelMaps);
                }
                else
                {
                    if (item.ItemCategory.Equals(XivStrings.Face))
                    {
                        var path = xivMtrl.Value.MTRLPath;

                        if (path.Contains("_iri_"))
                        {
                            winColor = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Iris_Color);
                        }
                        else if (path.Contains("_etc_"))
                        {
                            winColor = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Etc_Color);
                        }
                        else
                        {
                            winColor = (WinColor)ColorConverter.ConvertFromString(Settings.Default.Skin_Color);
                        }

                        customColor = new Color(winColor.R, winColor.G, winColor.B, winColor.A);
                    }

                    var modelMaps = modelTexture.GetModelMaps(customColor);

                    textureDataDictionary.Add(xivMtrl.Key, modelMaps);
                }
            }

            return(textureDataDictionary);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Gets the mtrl folder for a given item
        /// </summary>
        /// <param name="itemModel">Item that contains model data</param>
        /// <param name="xivRace">The race for the requested data</param>
        /// <param name="itemType">The type of the item</param>
        /// <returns>The mtrl Folder</returns>
        private string GetMtrlFolder(IItemModel itemModel, XivRace xivRace, XivItemType itemType)
        {
            // The default version number
            var version = "0001";

            if (itemType != XivItemType.human && itemType != XivItemType.furniture)
            {
                // get the items version from the imc file
                var imc     = new Imc(_gameDirectory, _dataFile);
                var imcInfo = imc.GetImcInfo(itemModel, itemModel.ModelInfo);
                version = imcInfo.Version.ToString().PadLeft(4, '0');
            }

            if (version.Equals("0000"))
            {
                version = "0001";
            }

            var id      = itemModel.ModelInfo.ModelID.ToString().PadLeft(4, '0');
            var bodyVer = itemModel.ModelInfo.Body.ToString().PadLeft(4, '0');
            var race    = xivRace.GetRaceCode();

            var mtrlFolder = "";

            switch (itemType)
            {
            case XivItemType.equipment:
                mtrlFolder = $"chara/{itemType}/e{id}/material/v{version}";
                break;

            case XivItemType.accessory:
                mtrlFolder = $"chara/{itemType}/a{id}/material/v{version}";
                break;

            case XivItemType.weapon:
                mtrlFolder = $"chara/{itemType}/w{id}/obj/body/b{bodyVer}/material/v{version}";
                break;

            case XivItemType.monster:
                mtrlFolder = $"chara/{itemType}/m{id}/obj/body/b{bodyVer}/material/v{version}";
                break;

            case XivItemType.demihuman:
                mtrlFolder = $"chara/{itemType}/d{id}/obj/equipment/e{bodyVer}/material/v{version}";
                break;

            case XivItemType.human:
                if (itemModel.ItemCategory.Equals(XivStrings.Body))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/body/b{bodyVer}/material";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Hair))
                {
                    // Hair has a version number, but no IMC, so we leave it at the default 0001
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/hair/h{bodyVer}/material/v{version}";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Face))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/face/f{bodyVer}/material";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Tail))
                {
                    mtrlFolder = $"chara/{itemType}/c{race}/obj/tail/t{bodyVer}/material";
                }
                break;

            case XivItemType.furniture:
                if (itemModel.ItemCategory.Equals(XivStrings.Furniture_Indoor))
                {
                    mtrlFolder = $"bgcommon/hou/indoor/general/{id}/material";
                }
                else if (itemModel.ItemCategory.Equals(XivStrings.Furniture_Outdoor))
                {
                    mtrlFolder = $"bgcommon/hou/outdoor/general/{id}/material";
                }
                break;

            default:
                mtrlFolder = "";
                break;
            }

            return(mtrlFolder);
        }