public async Task SaveImcInfo(XivImc info, IItemModel item) { var full = await GetFullImcInfo(item); full.SetEntry(info, item.ModelInfo.ImcSubsetID, item.GetItemSlotAbbreviation()); await SaveFullImcInfo(full, item); }
/// <summary> /// Gets the relevant IMC information for a given item /// </summary> /// <param name="item">The item to get the version for</param> /// <param name="modelInfo">The model info of the item</param> /// <returns>The XivImc Data</returns> public async Task <XivImc> GetImcInfo(IItemModel item) { var info = await GetFullImcInfo(item); var slot = item.GetItemSlotAbbreviation(); var result = info.GetEntry(item.ModelInfo.ImcSubsetID, slot); return(result); }
/// <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) { var itemType = ItemType.GetPrimaryItemType(itemModel); var version = "0001"; var id = itemModel.ModelInfo.PrimaryID.ToString().PadLeft(4, '0'); var bodyVer = itemModel.ModelInfo.SecondaryID.ToString().PadLeft(4, '0'); var itemCategory = itemModel.SecondaryCategory; if (itemType != XivItemType.human && itemType != XivItemType.furniture) { // Get the mtrl version for the given item from the imc file var imc = new Imc(_gameDirectory); version = (await imc.GetImcInfo(itemModel)).MaterialSet.ToString().PadLeft(4, '0'); } var parts = Constants.Alphabet; 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}_{itemModel.GetItemSlotAbbreviation()}_"; 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); }
/// <summary> /// Updates the View/ViewModel with a new selected base item. /// </summary> /// <param name="item"></param> /// <returns></returns> public async Task <bool> SetItem(IItem item, MainWindow mainWindow = null) { var gameDirectory = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); _imc = new Imc(gameDirectory, item.DataFile); _gear = new Gear(gameDirectory, XivLanguages.GetXivLanguage(Properties.Settings.Default.Application_Language)); if (mainWindow != null) { _mainWindow = mainWindow; } _item = item; _tree.Items.Clear(); IItemModel im = null; try { im = (IItemModel)item; } catch (Exception ex) { return(false); } if (im == null || im.ModelInfo == null) { return(false); } var topLevelItem = new TreeViewItem(); topLevelItem.Header = ""; if (im.ModelInfo.PrimaryID > 0) { topLevelItem.Header += CapFirst(item.GetPrimaryItemType().ToString()) + " #" + im.ModelInfo.PrimaryID.ToString().PadLeft(4, '0'); } else { topLevelItem.Header += CapFirst(item.GetPrimaryItemType().ToString()); } _tree.Items.Add(topLevelItem); var nextParent = topLevelItem; if (im.ModelInfo.SecondaryID > 0) { var nextNode = new TreeViewItem(); nextNode.Header += CapFirst(item.GetSecondaryItemType().ToString()) + " #" + im.ModelInfo.SecondaryID.ToString().PadLeft(4, '0'); nextParent.Items.Add(nextNode); nextParent.IsExpanded = true; nextParent = nextNode; } var abbreviation = _item.GetItemSlotAbbreviation(); if (abbreviation != "") { var nextNode = new TreeViewItem(); nextNode.Header = Mdl.SlotAbbreviationDictionary.First(x => x.Value == abbreviation).Key; nextParent.Items.Add(nextNode); nextParent.IsExpanded = true; nextParent = nextNode; } FullImcInfo fullInfo = null; try { fullInfo = await _imc.GetFullImcInfo(im); } catch (Exception ex) { // This item has no IMC file. var nextNode = new TreeViewItem(); nextNode.Header = im.Name; nextNode.DataContext = im; //nextNode.MouseDoubleClick += ItemNode_Activated; nextParent.Items.Add(nextNode); nextParent.IsExpanded = true; nextNode.IsSelected = true; nextParent = nextNode; // No shared items for things without IMC files, so just hide the view entirely? return(false); } var sharedList = await _gear.GetSameModelList(im); var myVariantNumber = fullInfo.GetEntry(im.ModelInfo.ImcSubsetID, im.GetItemSlotAbbreviation()).Variant; var myImcNumber = im.ModelInfo.ImcSubsetID; var materialVariantHeaders = new Dictionary <int, TreeViewItem>(); var imcVariantHeaders = new Dictionary <int, TreeViewItem>(); // TODO - // Add the Variant header nodes at the start, and only scan the IMC files when a TreeViewItem myMaterialHeader = null; TreeViewItem myImcHeader = null; TreeViewItem myNode = null; foreach (var i in sharedList) { // Get the Variant # information var info = fullInfo.GetEntry(i.ModelInfo.ImcSubsetID, i.GetItemSlotAbbreviation()); if (info == null) { // Invalid IMC Set ID for the item. continue; } if (!materialVariantHeaders.ContainsKey(info.Variant)) { materialVariantHeaders.Add(info.Variant, new TreeViewItem()); materialVariantHeaders[info.Variant].Header = "Material Variant #" + info.Variant; materialVariantHeaders[info.Variant].DataContext = info.Variant; } if (!imcVariantHeaders.ContainsKey(i.ModelInfo.ImcSubsetID)) { imcVariantHeaders.Add(i.ModelInfo.ImcSubsetID, new TreeViewItem()); imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header = "IMC Variant #" + i.ModelInfo.ImcSubsetID; imcVariantHeaders[i.ModelInfo.ImcSubsetID].DataContext = i.ModelInfo.ImcSubsetID; var hiddenParts = MaskToHidenParts(info.Mask); imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header += " - Hidden Parts: "; if (hiddenParts.Count > 0) { imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header += String.Join(",", hiddenParts); } else { imcVariantHeaders[i.ModelInfo.ImcSubsetID].Header += "None"; } materialVariantHeaders[info.Variant].Items.Add(imcVariantHeaders[i.ModelInfo.ImcSubsetID]); if (i.ModelInfo.ImcSubsetID == myImcNumber) { myImcHeader = imcVariantHeaders[i.ModelInfo.ImcSubsetID]; } } var nextNode = new TreeViewItem(); nextNode.Header = i.Name; nextNode.DataContext = i; imcVariantHeaders[i.ModelInfo.ImcSubsetID].Items.Add(nextNode); if (myMaterialHeader == null && info.Variant == myVariantNumber) { myMaterialHeader = materialVariantHeaders[info.Variant]; } if (i.Name == im.Name) { myNode = nextNode; } else { nextNode.MouseDoubleClick += ItemNode_Activated; } } var ordered = materialVariantHeaders.OrderBy(x => x.Key); foreach (var kv in ordered) { nextParent.Items.Add(kv.Value); } nextParent.IsExpanded = true; if (myMaterialHeader != null) { myMaterialHeader.IsExpanded = true; } if (myImcHeader != null) { myImcHeader.IsExpanded = true; } if (myNode != null) { myNode.IsSelected = true; } return(true); }
public async Task AsyncInit() { var root = _item.GetRoot(); if (root == null) { return; } var gd = XivCache.GameInfo.GameDirectory; var lang = XivCache.GameInfo.GameLanguage; var df = IOUtil.GetDataFileFromPath(root.Info.GetRootFile()); var _index = new Index(gd); var _mtrl = new Mtrl(XivCache.GameInfo.GameDirectory); var _mdl = new Mdl(gd, df); var _imc = new Imc(gd); var raceRegex = new Regex("c([0-9]{4})[^b]"); ItemNameBox.Text = _item.Name; var setName = root.Info.GetBaseFileName(false); SetLabel.Text = "Set: " + setName; if (!String.IsNullOrWhiteSpace(root.Info.Slot)) { var niceSlot = Mdl.SlotAbbreviationDictionary.FirstOrDefault(x => x.Value == root.Info.Slot); if (niceSlot.Key != null) { SlotLabel.Text = "Slot: " + niceSlot.Key + " (" + root.Info.Slot + ")"; } else { SlotLabel.Text = "Slot: Unknown (" + root.Info.Slot + ")"; } } else { SlotLabel.Text = "Slot: --"; } var usesImc = Imc.UsesImc(_item); if (usesImc) { VariantLabel.Text = "Variant: " + _item.ModelInfo.ImcSubsetID; } else { VariantLabel.Text = "Variant: --"; } var mSet = await _imc.GetMaterialSetId(_item); if (mSet > 0) { MaterialSetLabel.Text = "Material Set: " + mSet; } else { MaterialSetLabel.Text = "Material Set: --"; } var races = XivRaces.PlayableRaces; var models = await root.GetModelFiles(); var materials = await root.GetMaterialFiles(mSet); #region Race Chart var rowIdx = 1; foreach (var race in races) { var rCode = race.GetRaceCode(); var row = new RowDefinition(); row.Height = new GridLength(30); RacialGrid.RowDefinitions.Add(row); var lBase = new Label(); lBase.Content = race.GetDisplayName(); lBase.SetValue(Grid.RowProperty, rowIdx); RacialGrid.Children.Add(lBase); XivRace?usedMdlRace = race; string usedMdl = null;; if (race != XivRace.All_Races) { // Check if the race has a model. var mdl = models.FirstOrDefault(x => x.Contains("c" + rCode)); if (mdl == null) { // Gotta see which race they're shared from. var node = XivRaceTree.GetNode(race); var parent = node.Parent; while (parent != null) { var code = parent.Race.GetRaceCode(); mdl = models.FirstOrDefault(x => x.Contains("c" + code)); if (mdl != null) { usedMdlRace = parent.Race; usedMdl = mdl; break; } parent = parent.Parent; } if (mdl == null) { // No model exists for this item. usedMdlRace = null; } } else { usedMdl = mdl; } } var mdlRaceString = "None"; if (usedMdlRace == race) { mdlRaceString = "Own"; } else { if (usedMdlRace != null) { mdlRaceString = ((XivRace)usedMdlRace).GetDisplayName(); } } XivRace?usedMtrlRace = usedMdlRace; if (race != XivRace.All_Races) { if (usedMdlRace == null) { usedMtrlRace = null; } else { // Get the materials used by this racial's model. var mdl = usedMdl; var mdlMaterials = await XivCache.GetChildFiles(mdl); var mtrl = mdlMaterials.FirstOrDefault(x => raceRegex.IsMatch(x)); if (mtrl == null) { usedMtrlRace = null; } else { var code = raceRegex.Match(mtrl).Groups[1].Value; usedMtrlRace = XivRaces.GetXivRace(code); if (usedMtrlRace == XivRace.All_Races) { usedMtrlRace = null; } } } } var mtrlRaceString = "None"; if (usedMtrlRace == race) { mtrlRaceString = "Own"; } else { if (usedMtrlRace != null) { mtrlRaceString = ((XivRace)usedMtrlRace).GetDisplayName(); } } var lMdl = new Label(); lMdl.Content = mdlRaceString; lMdl.SetValue(Grid.RowProperty, rowIdx); lMdl.SetValue(Grid.ColumnProperty, 1); RacialGrid.Children.Add(lMdl); var lMtrl = new Label(); lMtrl.Content = mtrlRaceString; lMtrl.SetValue(Grid.RowProperty, rowIdx); lMtrl.SetValue(Grid.ColumnProperty, 2); RacialGrid.Children.Add(lMtrl); rowIdx++; } #endregion if (Imc.UsesImc(_item) && _item.ModelInfo != null) { var myImcSubsetId = _item.ModelInfo.ImcSubsetID; var allItems = await root.GetAllItems(); var fInfo = await _imc.GetFullImcInfo(_item); var entries = fInfo.GetAllEntries(_item.GetItemSlotAbbreviation(), true); foreach (var item in allItems) { SameModelItems.Add(new KeyValuePair <string, IItem>(item.Name, item)); if (entries.Count > item.ModelInfo.ImcSubsetID) { var imSet = entries[item.ModelInfo.ImcSubsetID].MaterialSet; if (mSet == imSet) { SameMSetItems.Add(new KeyValuePair <string, IItem>(item.Name, item)); } } if (item.ModelInfo.ImcSubsetID == myImcSubsetId) { SameVariantItems.Add(new KeyValuePair <string, IItem>(item.Name, item)); } } } }