/// <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()); }
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}"); }
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}"); }
/// <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()); }
/// <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; } else if (charaItem.ItemCategory == XivStrings.Ears) { folder = string.Format(XivStrings.EarsMDLFolder, race.GetRaceCode(), num.ToString().PadLeft(4, '0')); typeDict = EarsSlotAbbreviationDictionary; file = XivStrings.EarsMDLFile; } 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); }
/// <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); }
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); }
/// <summary> /// Gets the Races and Numbers available for models in the given Character Item /// </summary> /// <remarks> /// This gives you the race and the numbers available for it /// <example> /// Body, [Hyur Midlander Male, int[] {1, 2, 3, 5, 6} /// </example> /// This means there is 5 body models for Hyur Midlander Male with those numbers /// </remarks> /// <param name="charaItem">The Character Item</param> /// <returns>A Dictionary containing the race and the numbers available for it</returns> public async Task <Dictionary <XivRace, int[]> > GetRacesAndNumbersForModels(XivCharacter charaItem) { var availableRacesAndNumbers = new Dictionary <XivRace, int[]>(); var folder = ""; if (charaItem.ItemCategory == XivStrings.Hair) { folder = XivStrings.HairMDLFolder; } else if (charaItem.ItemCategory == XivStrings.Face) { folder = XivStrings.FaceMDLFolder; } else if (charaItem.ItemCategory == XivStrings.Body) { folder = XivStrings.BodyMDLFolder; } else if (charaItem.ItemCategory == XivStrings.Tail) { folder = XivStrings.TailMDLFolder; } else if (charaItem.ItemCategory == XivStrings.Ears) { folder = XivStrings.EarsMDLFolder; } foreach (var race in IDRaceDictionary) { var testDictionary = new Dictionary <int, int>(); for (var i = 1; i <= 300; i++) { var mtrl = string.Format(folder, race.Key, i.ToString().PadLeft(4, '0')); testDictionary.Add(HashGenerator.GetHash(mtrl), i); } var numList = await _index.GetFolderExistsList(testDictionary, XivDataFile._04_Chara); if (numList.Count > 0) { availableRacesAndNumbers.Add(race.Value, numList.ToArray()); } } return(availableRacesAndNumbers); }
/// <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 = new[] { 'a', 'b', 'c', 'd', 'e', 'f' }; if (charaItem.ItemCategory == XivStrings.Body) { if (_language != XivLanguage.Korean) { folder = string.Format(XivStrings.BodyMtrlFolderVar, race.GetRaceCode(), num.ToString().PadLeft(4, '0'), variant.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) { 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; } else if (charaItem.ItemCategory == XivStrings.Ears) { 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()); }
public async Task <int[]> GetNumbersForCharacterItem(XivCharacter charaItem, bool materials = true) { var race = charaItem.ModelInfo.PrimaryID.ToString().PadLeft(4, '0'); var availableRacesAndNumbers = new Dictionary <XivRace, int[]>(); var folder = ""; if (charaItem.SecondaryCategory == XivStrings.Hair) { folder = materials ? XivStrings.HairMtrlFolder : XivStrings.HairMDLFolder; } else if (charaItem.SecondaryCategory == XivStrings.Face) { folder = materials ? XivStrings.FaceMtrlFolder : XivStrings.FaceMDLFolder; } else if (charaItem.SecondaryCategory == XivStrings.Body) { folder = materials ? XivStrings.BodyMtrlFolder : XivStrings.BodyMDLFolder; } else if (charaItem.SecondaryCategory == XivStrings.Tail) { folder = materials ? XivStrings.TailMtrlFolder : XivStrings.TailMDLFolder; } else if (charaItem.SecondaryCategory == XivStrings.Ear) { folder = materials ? XivStrings.EarsMtrlFolder : XivStrings.EarsMDLFolder; } var testDictionary = new Dictionary <int, int>(); for (var i = 1; i <= 300; i++) { var mtrl = string.Format(folder, race, i.ToString().PadLeft(4, '0')); testDictionary.Add(HashGenerator.GetHash(mtrl), i); } var numList = await _index.GetFolderExistsList(testDictionary, XivDataFile._04_Chara); numList.Sort(); return(numList.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}"); }
/// <summary> /// Gets the List to be displayed under the Character category /// </summary> /// <returns>A list containing XivCharacter data</returns> public Task <List <XivCharacter> > GetUnCachedCharacterList() { return(Task.Run(async() => { var races = Eqp.PlayableRacesWithNPCs; races = races.OrderBy(x => x.GetRaceCodeInt()).ToList(); // A simple method to check what face/hair/etc. numbers exist is just to see if their texture folders exist. var characterList = new List <XivCharacter>(); foreach (var race in races) { var raceCode = race.GetRaceCodeInt(); var c = new XivCharacter { Name = race.GetDisplayName(), PrimaryCategory = XivStrings.Character, SecondaryCategory = XivStrings.Body }; c.ModelInfo = new XivModelInfo(); c.ModelInfo.PrimaryID = raceCode; c.ModelInfo.SecondaryID = 0; // Only add to this listing if there is any data. var matNumbers = await GetNumbersForCharacterItem(c); if (matNumbers.Length > 0) { characterList.Add(c); } else { var mdlNumbers = await GetNumbersForCharacterItem(c, false); if (mdlNumbers.Length > 0) { characterList.Add(c); } } c = new XivCharacter { Name = race.GetDisplayName(), PrimaryCategory = XivStrings.Character, SecondaryCategory = XivStrings.Face }; c.ModelInfo = new XivModelInfo(); c.ModelInfo.PrimaryID = raceCode; c.ModelInfo.SecondaryID = 0; matNumbers = await GetNumbersForCharacterItem(c); if (matNumbers.Length > 0) { characterList.Add(c); } else { var mdlNumbers = await GetNumbersForCharacterItem(c, false); if (mdlNumbers.Length > 0) { characterList.Add(c); } } c = new XivCharacter { Name = race.GetDisplayName(), PrimaryCategory = XivStrings.Character, SecondaryCategory = XivStrings.Hair }; c.ModelInfo = new XivModelInfo(); c.ModelInfo.PrimaryID = raceCode; c.ModelInfo.SecondaryID = 0; matNumbers = await GetNumbersForCharacterItem(c); if (matNumbers.Length > 0) { characterList.Add(c); } else { var mdlNumbers = await GetNumbersForCharacterItem(c, false); if (mdlNumbers.Length > 0) { characterList.Add(c); } } c = new XivCharacter { Name = race.GetDisplayName(), PrimaryCategory = XivStrings.Character, SecondaryCategory = XivStrings.Tail }; c.ModelInfo = new XivModelInfo(); c.ModelInfo.PrimaryID = raceCode; c.ModelInfo.SecondaryID = 0; matNumbers = await GetNumbersForCharacterItem(c); if (matNumbers.Length > 0) { characterList.Add(c); } else { var mdlNumbers = await GetNumbersForCharacterItem(c, false); if (mdlNumbers.Length > 0) { characterList.Add(c); } } c = new XivCharacter { Name = race.GetDisplayName(), PrimaryCategory = XivStrings.Character, SecondaryCategory = XivStrings.Ear }; c.ModelInfo = new XivModelInfo(); c.ModelInfo.PrimaryID = raceCode; c.ModelInfo.SecondaryID = 0; matNumbers = await GetNumbersForCharacterItem(c); if (matNumbers.Length > 0) { characterList.Add(c); } else { var mdlNumbers = await GetNumbersForCharacterItem(c, false); if (mdlNumbers.Length > 0) { characterList.Add(c); } } } characterList.Add(new XivCharacter { Name = XivStrings.Face_Paint, PrimaryCategory = XivStrings.Character, SecondaryCategory = XivStrings.Face_Paint }); characterList.Add(new XivCharacter { Name = XivStrings.Equipment_Decals, PrimaryCategory = XivStrings.Character, SecondaryCategory = XivStrings.Equipment_Decals }); return characterList; })); }