/// <summary> /// Gets the avfx path /// </summary> /// <param name="itemModel">The item to get the avfx path for</param> /// <param name="itemType">The type of the item</param> /// <returns>A tuple containing the path folder and file</returns> private async Task <(string Folder, string File)> GetVfxPath(IItemModel itemModel, XivItemType itemType) { // get the vfx version from the imc file var imc = new Imc(_gameDirectory, _dataFile); var imcInfo = await imc.GetImcInfo(itemModel, itemModel.ModelInfo); int vfx = imcInfo.Vfx; var id = itemModel.ModelInfo.ModelID.ToString().PadLeft(4, '0'); var bodyVer = itemModel.ModelInfo.Body.ToString().PadLeft(4, '0'); string vfxFolder, vfxFile; switch (itemType) { case XivItemType.equipment: vfxFolder = $"chara/{itemType}/e{id}/vfx/eff"; vfxFile = $"ve{vfx.ToString().PadLeft(4, '0')}.avfx"; break; case XivItemType.weapon: vfxFolder = $"chara/{itemType}/w{id}/obj/body/b{bodyVer}/vfx/eff"; vfxFile = $"vw{vfx.ToString().PadLeft(4, '0')}.avfx"; break; case XivItemType.monster: vfxFolder = $"chara/{itemType}/m{id}/obj/body/b{bodyVer}/vfx/eff"; vfxFile = $"vm{vfx.ToString().PadLeft(4, '0')}.avfx"; break; case XivItemType.demihuman: vfxFolder = $"chara/{itemType}/d{id}/obj/equipment/e{bodyVer}/vfx/eff"; vfxFile = $"ve{vfx.ToString().PadLeft(4, '0')}.avfx"; break; default: vfxFolder = ""; vfxFile = ""; break; } return(vfxFolder, vfxFile); }
/// <summary> /// Searches for housing items given a model ID /// </summary> /// <param name="modelID">The Model ID of the housing item</param> /// <param name="type">The type of housing item to search for</param> /// <returns>A list of Search Results</returns> public async Task <List <SearchResults> > SearchHousingByModelID(int modelID, XivItemType type) { var searchResultsList = new List <SearchResults>(); var index = new Index(_gameDirectory); var id = modelID.ToString().PadLeft(4, '0'); var folder = ""; if (type == XivItemType.furniture) { folder = $"bgcommon/hou/indoor/general/{id}/material"; } if (await index.FolderExists(HashGenerator.GetHash(folder), XivDataFile._01_Bgcommon)) { var searchResults = new SearchResults { Body = "-", Slot = XivStrings.Furniture_Indoor, Variant = int.Parse(id) }; searchResultsList.Add(searchResults); } folder = $"bgcommon/hou/outdoor/general/{id}/material"; if (await index.FolderExists(HashGenerator.GetHash(folder), XivDataFile._01_Bgcommon)) { var searchResults = new SearchResults { Body = "-", Slot = XivStrings.Furniture_Outdoor, Variant = int.Parse(id) }; searchResultsList.Add(searchResults); } searchResultsList.Sort(); return(searchResultsList); }
/// <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</returns> private (string Folder, string File) GetMtrlPath(IItemModel itemModel, XivRace xivRace, char part, XivItemType itemType) { // The default version number var version = "0001"; if (itemType != XivItemType.human) { // get the items version from the imc file var imc = new Imc(_gameDirectory, _dataFile); 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 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; default: mtrlFolder = ""; mtrlFile = ""; break; } return(mtrlFolder, mtrlFile); }
public async Task <Dictionary <string, string> > GetFurnitureModelParts(int modelID, XivItemType type) { var cat = type == XivItemType.indoor ? XivStrings.Furniture_Indoor : XivStrings.Furniture_Outdoor; return(await GetFurnitureModelParts(modelID, cat)); }
/// <summary> /// Searches for monsters with the given model ID /// </summary> /// <param name="modelID">The ID of the monster model</param> /// <param name="type">The type of monster to look for</param> /// <returns>A list of Search Results</returns> public async Task <List <SearchResults> > SearchMonstersByModelID(int modelID, XivItemType type) { var monsterSearchLock = new object(); var monsterSearchLock1 = new object(); var searchResultsList = new List <SearchResults>(); var index = new Index(_gameDirectory); var id = modelID.ToString().PadLeft(4, '0'); var bodyVariantDictionary = new Dictionary <int, List <int> >(); if (type == XivItemType.monster) { var folder = $"chara/monster/m{id}/obj/body/b"; await Task.Run(() => Parallel.For(0, 100, (i) => { var folderHashDictionary = new Dictionary <int, int>(); var mtrlFolder = $"{folder}{i.ToString().PadLeft(4, '0')}/material/v"; for (var j = 1; j < 100; j++) { lock (monsterSearchLock) { folderHashDictionary.Add(HashGenerator.GetHash($"{mtrlFolder}{j.ToString().PadLeft(4, '0')}"), j); } } var variantList = index.GetFolderExistsList(folderHashDictionary, XivDataFile._04_Chara).Result; if (variantList.Count > 0) { lock (monsterSearchLock1) { variantList.Sort(); bodyVariantDictionary.Add(i, variantList); } } })); } else if (type == XivItemType.demihuman) { var folder = $"chara/demihuman/d{id}/obj/equipment/e"; await Task.Run(() => Parallel.For(0, 100, (i) => { var folderHashDictionary = new Dictionary <int, int>(); var mtrlFolder = $"{folder}{i.ToString().PadLeft(4, '0')}/material/v"; for (var j = 1; j < 100; j++) { lock (monsterSearchLock) { folderHashDictionary.Add(HashGenerator.GetHash($"{mtrlFolder}{j.ToString().PadLeft(4, '0')}"), j); } } var variantList = index.GetFolderExistsList(folderHashDictionary, XivDataFile._04_Chara).Result; if (variantList.Count > 0) { lock (monsterSearchLock1) { variantList.Sort(); bodyVariantDictionary.Add(i, variantList); } } })); } foreach (var bodyVariant in bodyVariantDictionary) { foreach (var variant in bodyVariant.Value) { searchResultsList.Add(new SearchResults { Body = bodyVariant.Key.ToString(), Slot = XivStrings.Monster, Variant = variant }); } } searchResultsList.Sort(); return(searchResultsList); }