/// <summary> /// класс представления единицы курса /// </summary> /// <exception cref="ArgumentNullException"></exception> public ItemViewModel(IItemModel _item, IItemViewModel _parent) { if (_item == null) throw new ArgumentNullException(); Id = _item.Id; Name = _item.Title; Parent = _parent; InitChildren(_item); CacherChangeChildProperty(); }
/// <summary> /// инициализировать представления /// дочерних элементов /// </summary> private void InitChildren(IItemModel _item) { Children = new List <IItemViewModel>(); if (_item.Items == null) { return; } IItemViewModel tmp = null; foreach (IItemModel im in _item.Items) { tmp = new ItemViewModel(im, this); Children.Add(tmp); } IsInitiallySelected = true; }
/// <summary> /// Exports each mesh as an obj file /// </summary> /// <param name="item">The item to be exported</param> /// <param name="xivMdl">The XivMdl model data</param> /// <param name="saveLocation">The location in which to save the obj file</param> public void ExportObj(IItemModel item, XivMdl xivMdl, DirectoryInfo saveLocation, XivRace race) { var meshes = xivMdl.LoDList[0].MeshDataList; var path = $"{IOUtil.MakeItemSavePath(item, saveLocation, race)}\\3D"; Directory.CreateDirectory(path); var meshNum = 0; foreach (var meshData in meshes) { var modelName = $"{Path.GetFileNameWithoutExtension(xivMdl.MdlPath.File)}_{meshNum}"; var savePath = Path.Combine(path, modelName) + ".obj"; meshNum++; File.WriteAllText(savePath, ExportObj(meshData)); } }
//// /// <summary> //// /// Gets/sets whether the <see cref="DisplayName"/> of this treeview item //// /// can be edit by the user or not. //// /// </summary> //// public bool IsReadOnly { get; set; } /*/ <summary> * /// Gets a description of the item - for usage in tool tip etc.. * /// </summary> * public string Description { get; set; } ***/ //// /// <summary> //// /// Gets the parent object where this object is the child in the treeview. //// /// </summary> //// public SolutionItem_Model Parent { get; set; } //// /// <summary> //// /// Gets/sets whether this treeview item is expanded or not. //// /// </summary> //// public bool IsItemExpanded { get; set; } //// //// /// <summary> //// /// Gets/sets whether this treeview item is selected or not. //// /// </summary> //// public bool IsItemSelected { get; set; } #endregion properties #region methods /// <summary> /// Returns the string path either: /// 1) for the <paramref name="current"/> item or /// 2) for this item (if optional parameter <paramref name="current"/> is not set). /// </summary> /// <param name="current"></param> /// <returns></returns> public string GetStackPath(IItemModel current = null) { if (current == null) { current = this; } string result = string.Empty; // Traverse the list of parents backwards and // add each child to the path while (current != null) { result = "/" + current.DisplayName + result; current = current.Parent; } return(result); }
public async Task CreateOrUpdateItem(IItemModel item) { if (_isDataInitialized == false) { InitializeData(); } IItemModel NewItem = item; foreach (IItemModel WorkItem in _items) { if (WorkItem.ItemNum == item.ItemNum) { _items.Remove(NewItem); } } item.Id = _nextId++; _items.Add(item); await Task.Delay(0); }
/// <summary> /// Spawns the import model dialog and walks through the full steps to import a model, /// with user interaction. /// </summary> /// <param name="item">Item to import to</param> /// <param name="race">Race to import to</param> /// <param name="windowOwner">Window parent, default uses TexTools main window.</param> /// <param name="onComplete">Function to be called after import completes, but before user has closed the window. (Task handler returns when window is closed)</param> /// <param name="dataOnly">If this should be just load the data to memory and not import the resultant MDL. Data can be accessed with ImportModelView.GetData()</param> /// <returns></returns> public static async Task <bool> ImportModel(IItemModel item, XivRace race, string submeshId = null, Window windowOwner = null, Action onComplete = null, bool dataOnly = false) { if (windowOwner == null) { // Default to the main root window if we don't have an owner. windowOwner = MainWindow.GetMainWindow(); } var imView = new ImportModelView(item, race, onComplete, submeshId, dataOnly) { Owner = windowOwner }; // This blocks until the dialog closes. var result = imView.ShowDialog(); // Coalesce bool ret = result == true ? true : false; return(ret); }
/// <summary> /// A simple function that retrieves the material set ID of an item, /// whether via IMC or default value. /// /// A value of -1 indicates that material sets are not used at all on this item. /// </summary> /// <param name="item"></param> /// <returns></returns> public async Task <int> GetMaterialSetId(IItemModel item) { var root = item.GetRoot(); if (root == null) { return(-1); } if (root.Info.PrimaryType == XivItemType.human) { if (root.Info.SecondaryType == XivItemType.hair || root.Info.SecondaryType == XivItemType.tail || root.Info.SecondaryType == XivItemType.body) { // These use material sets (always set 1), but have no IMC file. return(1); } else { return(-1); } } else if (root.Info.PrimaryType == XivItemType.indoor || root.Info.PrimaryType == XivItemType.outdoor) { return(-1); } else { try { var entry = await GetImcInfo(item); return(entry.MaterialSet); } catch { return(-1); } } }
public async Task <List <IItemModel> > GetSameModelList(IItemModel item) { var sameModelItems = new List <IItemModel>(); //gear if (item.PrimaryCategory.Equals(XivStrings.Gear)) { sameModelItems.AddRange( (await GetGearList()) .Where(it => it.ModelInfo.PrimaryID == item.ModelInfo.PrimaryID && it.ModelInfo.SecondaryID == item.ModelInfo.SecondaryID && it.SecondaryCategory == item.SecondaryCategory).Select(it => it as IItemModel).ToList() ); } else { //character sameModelItems.Add((IItemModel)item.Clone()); } return(sameModelItems); }
public void EditItem(IItemModel item) { using (IDbConnection connection = new System.Data.SqlClient.SqlConnection(GlobalConfig.CnnVal(db))) { //var p = new DynamicParameters(); p.Add("@ItemID", item.ItemID); p.Add("@Title", item.Title); p.Add("@Author", item.Author); p.Add("@Description", item.Description); p.Add("@Year", item.Year); p.Add("@CategoryID", item.CategoryID); p.Add("@Quantity", item.Quantity); p.Add("@Location", item.Location); p.Add("@ISBN", item.ISBN); p.Add("@ItemTypeID", item.ItemTypeID); //p.Add("@ItemID", 0, dbType: DbType.Int32, direction: ParameterDirection.Output); connection.Execute("spEditItem", p, commandType: CommandType.StoredProcedure); //item.ItemID = p.Get<int>("@itemID"); } }
public async Task SaveFullImcInfo(FullImcInfo info, IItemModel item) { try { var imcPath = GetImcPath(item); var path = imcPath.Folder + "/" + imcPath.File; await SaveFullImcInfo(info, path); } catch { // Some dual wield items don't have a second IMC, and just default to the first. var gear = (XivGear)item; if (gear != null && gear.PairedItem != null) { var pair = gear.PairedItem; var imcPath = GetImcPath(pair); var path = imcPath.Folder + "/" + imcPath.File; await(SaveFullImcInfo(info, path)); } } return; }
/// <summary> /// Gets the IMC internal path for the given model info /// </summary> /// <param name="modelInfo">The model info of the item</param> /// <param name="itemType">The type of the item</param> /// <returns>A touple containing the Folder and File strings</returns> private static (string Folder, string File) GetImcPath(IItemModel item) { string imcFolder = item.GetItemRootFolder(); string imcFile; var primaryId = item.ModelInfo.PrimaryID.ToString().PadLeft(4, '0'); var secondaryId = item.ModelInfo.SecondaryID.ToString().PadLeft(4, '0'); var itemType = item.GetPrimaryItemType(); switch (itemType) { case XivItemType.equipment: imcFile = $"e{primaryId}{ImcExtension}"; break; case XivItemType.accessory: imcFile = $"a{primaryId}{ImcExtension}"; break; case XivItemType.weapon: imcFile = $"b{secondaryId}{ImcExtension}"; break; case XivItemType.monster: imcFile = $"b{secondaryId}{ImcExtension}"; break; case XivItemType.demihuman: imcFile = $"e{secondaryId}{ImcExtension}"; break; default: imcFolder = ""; imcFile = ""; break; } return(imcFolder, imcFile); }
/// <summary> /// Gets the MTRL data for the given item /// </summary> /// <remarks> /// It requires a race (The default is usually <see cref="XivRace.Hyur_Midlander_Male"/>) /// It also requires an mtrl part <see cref="GearInfo.GetPartList(IItemModel, XivRace)"/> (default is 'a') /// </remarks> /// <param name="itemModel">Item that contains model data</param> /// <param name="race">The race for the requested data</param> /// <param name="part">The Mtrl part </param> /// <returns>XivMtrl containing all the mtrl data</returns> public XivMtrl GetMtrlData(IItemModel itemModel, XivRace race, char part, int dxVersion) { var index = new Index(_gameDirectory); var itemType = ItemType.GetItemType(itemModel); // Get mtrl path var mtrlPath = GetMtrlPath(itemModel, race, part, itemType); var mtrlStringPath = $"{mtrlPath.Folder}/{mtrlPath.File}"; // Get mtrl offset var mtrlOffset = index.GetDataOffset(HashGenerator.GetHash(mtrlPath.Folder), HashGenerator.GetHash(mtrlPath.File), _dataFile); if (mtrlOffset == 0 && itemType == XivItemType.furniture) { mtrlPath.File = mtrlPath.File.Replace("_0", "_1"); mtrlStringPath = $"{mtrlPath.Folder}/{mtrlPath.File}"; // Get mtrl offset mtrlOffset = index.GetDataOffset(HashGenerator.GetHash(mtrlPath.Folder), HashGenerator.GetHash(mtrlPath.File), _dataFile); } if (mtrlOffset == 0) { throw new Exception($"Could not find offest for {mtrlStringPath}"); } var mtrlData = GetMtrlData(mtrlOffset, mtrlStringPath, dxVersion); if (mtrlPath.HasVfx) { var atex = new ATex(_gameDirectory, _dataFile); mtrlData.TextureTypePathList.AddRange(atex.GetAtexPaths(itemModel)); } return(mtrlData); }
/// <summary> /// Gets the type of the item /// </summary> /// <remarks> /// The item type is determined by its ItemCategory /// </remarks> /// <see cref="XivItemType"/> /// <param name="item">The item to get the type for</param> /// <returns>The XivItemType containing the type of the item</returns> public static XivItemType GetItemType(IItemModel item) { XivItemType itemType; if (item.ItemCategory.Equals(XivStrings.Main_Hand) || item.ItemCategory.Equals(XivStrings.Off_Hand) || item.ItemCategory.Equals(XivStrings.Main_Off) || item.ItemCategory.Equals(XivStrings.Two_Handed) || item.ItemCategory.Equals(XivStrings.Food)) { itemType = XivItemType.weapon; } else if (item.ItemCategory.Equals(XivStrings.Ears) || item.ItemCategory.Equals(XivStrings.Neck) || item.ItemCategory.Equals(XivStrings.Wrists) || item.ItemCategory.Equals(XivStrings.Rings)) { itemType = XivItemType.accessory; } else if (item.ItemCategory.Equals(XivStrings.Mounts) || item.ItemCategory.Equals(XivStrings.Minions) || item.ItemCategory.Equals(XivStrings.Pets) || item.ItemCategory.Equals(XivStrings.Monster)) { itemType = item.PrimaryModelInfo.ModelType; } else if (item.ItemCategory.Equals(XivStrings.DemiHuman)) { itemType = XivItemType.demihuman; } else if (item.Category.Equals(XivStrings.Character)) { itemType = XivItemType.human; } else if (item.ItemCategory.Equals("UI")) { itemType = XivItemType.ui; } else { itemType = XivItemType.equipment; } return(itemType); }
public async Task <List <string> > GetDemiHumanMountModelEquipPartList(IItemModel itemModel) { var equipPartList = new List <string>(); var index = new Index(_gameDirectory); var id = itemModel.ModelInfo.PrimaryID.ToString().PadLeft(4, '0'); var bodyVer = itemModel.ModelInfo.SecondaryID.ToString().PadLeft(4, '0'); var root = itemModel.GetRoot(); var mdlFolder = $"chara/demihuman/d{id}/obj/equipment/e{bodyVer}/model"; var files = await index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mdlFolder), XivDataFile._04_Chara); if (root == null || root.Info.Slot == null) { foreach (var slotAbr in SlotAbbreviationDictionary) { var mdlFile = $"d{id}e{bodyVer}_{slotAbr.Value}.mdl"; if (files.Contains(HashGenerator.GetHash(mdlFile))) { equipPartList.Add(slotAbr.Key); } } } else { var niceSlotName = SlotAbbreviationDictionary.FirstOrDefault(x => x.Value == root.Info.Slot).Key; if (!string.IsNullOrEmpty(niceSlotName)) { equipPartList.Add(niceSlotName); } } return(equipPartList); }
public async Task <List <string> > GetDemiHumanMountModelEquipPartList(IItemModel itemModel) { var equipPartList = new List <string>(); var id = itemModel.ModelInfo.ModelID.ToString().PadLeft(4, '0'); var bodyVer = itemModel.ModelInfo.Body.ToString().PadLeft(4, '0'); var mdlFolder = $"chara/demihuman/d{id}/obj/equipment/e{bodyVer}/model"; var files = await _modding.Index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mdlFolder), XivDataFile._04_Chara); foreach (var slotAbr in SlotAbbreviationDictionary) { var mdlFile = $"d{id}e{bodyVer}_{slotAbr.Value}.mdl"; if (files.Contains(HashGenerator.GetHash(mdlFile))) { equipPartList.Add(slotAbr.Key); } } return(equipPartList); }
/// <summary> /// загрузка единиц курса /// </summary> /// <exception cref="AppException"> /// Возникает в случае ошибки загрузки единиц курса /// (возможно ранее не был указан путь)</exception> void LoadCourseItems() { try { IItemModel im = null; items = new ObservableCollection <IItemModel>(); bool validCreating = false; foreach (AbstractLearningItem item in Course) { if ((item.isReferenced) && (!item.isLoaded)) { item.LoadFromPath(CourseLoadType.Full); } } foreach (AbstractLearningItem item in Course.childs) { im = itemsFactory.Create(item, out validCreating); if (!validCreating) { throw new Exception(item.identifier + ": неопределенный тип элемента курса: " + item.GetType()); } if (im != null) { items.Add(im); } } isItemsLoad = true; } catch (Exception ex) { throw new Exception("Ошибка загрузки единиц курса." + "/n" + ex.Message); } }
public async Task <FullImcInfo> GetFullImcInfo(IItemModel item) { FullImcInfo info = null; try { var imcPath = GetImcPath(item); var path = imcPath.Folder + "/" + imcPath.File; info = await GetFullImcInfo(path); } catch { // Some dual wield items don't have a second IMC, and just default to the first. var gear = (XivGear)item; if (gear != null && gear.PairedItem != null) { var pair = gear.PairedItem; var imcPath = GetImcPath(pair); var path = imcPath.Folder + "/" + imcPath.File; return(await(GetFullImcInfo(path))); } } return(info); }
public void UpdateItem(IItemModel t) { try { using (ItemEntities context = ItemEntities.Instance()) { System.Data.EntityKey pKey = ((Item)t).EntityKey; if (pKey != null) { object pObject; if (context.TryGetObjectByKey(pKey, out pObject)) { context.ApplyPropertyChanges(pKey.EntitySetName, (Item)t); } } context.SaveChanges(); } DataCache.RemoveCache(itemCacheKey(t.ModuleId)); } catch (Exception ex) { Exceptions.LogException(ex); } }
private static void CreateActionListController(IItemView view, IGTDWindow window, IItemModel<ActionItem> model) { new ActionsListController(view, window, model, MockRepository.GenerateStub<IPublishKeyEvents>()); }
/// <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 <Dictionary <string, string> > GetFurnitureModelParts(IItemModel itemModel) { return(await GetFurnitureModelParts(itemModel.ModelInfo.PrimaryID, itemModel.SecondaryCategory)); }
/// <summary> /// Parameterized constructor for normal usage when new elements are created /// via other viewmodels through the UI. /// </summary> /// <param name="parent"></param> /// <param name="displayName"></param> public FileItemModel(IItemModel parent, string displayName) : base(parent, displayName, Enums.SolutionModelItemType.File) { }
private void PutInto(int slot, IItemModel model, int amount) { var cursor = _container.GetCursor(slot); _container.Put(cursor, new InventoryStack(model, amount)); }
public ItemProcessor(IItemModel model, float advanceTime) { _model = model; _advanceTimer = 0.0f; _advanceTime = advanceTime; }
public ItemConverter(IItemModel<InBoxItem> inbox_model, IItemModel<ActionItem> actions_list_model) { _inbox_model = inbox_model; _actions_list_model = actions_list_model; }
public ItemEventArgs(IItemModel _item) { Item = _item; }
/// <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); }
/// <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, XivModelInfo modelInfo) { var xivImc = new XivImc(); // These are the offsets to relevant data // These will need to be changed if data gets added or removed with a patch const int headerLength = 4; const int variantLength = 6; const int variantSetLength = 30; var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var itemType = ItemType.GetItemType(item); var imcPath = GetImcPath(modelInfo, itemType); var imcOffset = await index.GetDataOffset(HashGenerator.GetHash(imcPath.Folder), HashGenerator.GetHash(imcPath.File), _dataFile); if (imcOffset == 0) { throw new Exception($"Could not find offset for {imcPath.Folder}/{imcPath.File}"); } var imcData = await dat.GetType2Data(imcOffset, _dataFile); await Task.Run(() => { using (var br = new BinaryReader(new MemoryStream(imcData))) { int variantOffset; if (itemType == XivItemType.weapon || itemType == XivItemType.monster) { // weapons and monsters do not have variant sets variantOffset = (modelInfo.Variant *variantLength) + headerLength; // use default if offset is out of range if (variantOffset >= imcData.Length) { variantOffset = headerLength; } } else { // Variant Sets contain 5 variants for each slot // These can be Head, Body, Hands, Legs, Feet or Ears, Neck, Wrists, LRing, RRing // This skips to the correct variant set, then to the correct slot within that set for the item variantOffset = (modelInfo.Variant *variantSetLength) + (_slotOffsetDictionary[item.ItemCategory] * variantLength) + headerLength; // use defalut if offset is out of range if (variantOffset >= imcData.Length) { variantOffset = (_slotOffsetDictionary[item.ItemCategory] * variantLength) + headerLength; } } br.BaseStream.Seek(variantOffset, SeekOrigin.Begin); // if(variantOffset) xivImc.Version = br.ReadByte(); var unknown = br.ReadByte(); xivImc.Mask = br.ReadUInt16(); xivImc.Vfx = br.ReadByte(); var unknown1 = br.ReadByte(); } }); return(xivImc); }
/// <summary> /// инициализировать представления /// дочерних элементов /// </summary> private void InitChildren(IItemModel _item) { Children = new List<IItemViewModel>(); if (_item.Items == null) return; IItemViewModel tmp = null; foreach(IItemModel im in _item.Items) { tmp = new ItemViewModel(im,this); Children.Add(tmp); } IsInitiallySelected = true; }
public async Task <bool> SetMaterial(XivMtrl material, IItemModel item, MaterialEditorMode mode) { if (material == null) { return(false); } _mode = mode; _material = material; _item = item; var gameDirectory = new DirectoryInfo(Properties.Settings.Default.FFXIV_Directory); _mtrl = new Mtrl(gameDirectory, item.DataFile, GetLanguage()); _index = new Index(gameDirectory); _modding = new Modding(gameDirectory); _gear = new Gear(gameDirectory, GetLanguage()); // Drop the multi functions down to singles if they only have one Material to edit anyways. if (_mode == MaterialEditorMode.EditMulti || _mode == MaterialEditorMode.NewMulti) { // This isn't an actual perfect check for if there's only one Variant, but doing so // would be a bit expensive here, and passing it through EditMulti isn't harmful anyways. var sameModelItems = await _item.GetSharedModelItems(); if (sameModelItems.Count == 1) { if (_mode == MaterialEditorMode.EditMulti) { _mode = MaterialEditorMode.EditSingle; } else { _mode = MaterialEditorMode.NewSingle; } } } /* * // Debug code for finding unknown Shader Parameters. * var unknowns = new List<ShaderParameterStruct>(); * foreach(var sp in material.ShaderParameterList) * { * if (!Enum.IsDefined(typeof(MtrlShaderParameterId), sp.ParameterID)) * { * unknowns.Add(sp); * } * } * if(unknowns.Count > 0) * { * // Debug line * var json = JsonConvert.SerializeObject(unknowns.ToArray()); * } */ // Update to new material name switch (_mode) { case MaterialEditorMode.EditSingle: _view.MaterialPathLabel.Text = _material.MTRLPath; break; case MaterialEditorMode.EditMulti: _view.MaterialPathLabel.Text = "Editing Multiple Materials: Material " + _material.GetMaterialIdentifier(); break; case MaterialEditorMode.NewSingle: _view.MaterialPathLabel.Text = "New Material"; break; case MaterialEditorMode.NewMulti: _view.MaterialPathLabel.Text = "New Materials"; break; } var shader = _material.GetShaderInfo(); var normal = _material.GetMapInfo(XivTexType.Normal); var diffuse = _material.GetMapInfo(XivTexType.Diffuse); var specular = _material.GetMapInfo(XivTexType.Specular); var multi = _material.GetMapInfo(XivTexType.Multi); var reflection = _material.GetMapInfo(XivTexType.Reflection); // Show Paths _view.NormalTextBox.Text = normal == null ? "" : normal.path; _view.SpecularTextBox.Text = specular == null ? "" : specular.path; _view.SpecularTextBox.Text = multi == null ? _view.SpecularTextBox.Text : multi.path; _view.DiffuseTextBox.Text = diffuse == null ? "" : diffuse.path; _view.DiffuseTextBox.Text = reflection == null ? _view.DiffuseTextBox.Text : reflection.path; // Add Other option if needed. if (shader.Shader == MtrlShader.Other) { _view.ShaderSource.Add(new KeyValuePair <MtrlShader, string>(MtrlShader.Other, "Other")); } // Show Settings _view.TransparencyComboBox.SelectedValue = shader.TransparencyEnabled; _view.BackfacesComboBox.SelectedValue = shader.RenderBackfaces; _view.ColorsetComboBox.SelectedValue = shader.HasColorset; _view.ShaderComboBox.SelectedValue = shader.Shader; _view.PresetComboBox.SelectedValue = shader.Preset; if (_mode == MaterialEditorMode.NewMulti) { // Bump up the material identifier letter. _newMaterialIdentifier = await GetNewMaterialIdentifier(); _view.MaterialPathLabel.Text = "New Materials: Material " + _newMaterialIdentifier; } else if (_mode == MaterialEditorMode.NewSingle) { _newMaterialIdentifier = await GetNewMaterialIdentifier(); _view.MaterialPathLabel.Text = "New Material: Material " + _newMaterialIdentifier; } // Get the mod entry. if (_mode == MaterialEditorMode.EditSingle || _mode == MaterialEditorMode.EditMulti) { var mod = await _modding.TryGetModEntry(_material.MTRLPath); if (mod != null && mod.enabled) { _view.DisableButton.IsEnabled = true; _view.DisableButton.Visibility = System.Windows.Visibility.Visible; } } return(true); }
/// <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()); }
public async Task <Dictionary <string, char[]> > GetDemiHumanMountTextureEquipPartList(IItemModel itemModel) { var parts = new[] { 'a', 'b', 'c', 'd', 'e', 'f' }; var equipPartDictionary = new Dictionary <string, char[]>(); var index = new Index(_gameDirectory); var imc = new Imc(_gameDirectory, XivDataFile._04_Chara); var version = (await imc.GetImcInfo(itemModel, itemModel.ModelInfo)).Version.ToString().PadLeft(4, '0'); var id = itemModel.ModelInfo.ModelID.ToString().PadLeft(4, '0'); var bodyVer = itemModel.ModelInfo.Body.ToString().PadLeft(4, '0'); var mtrlFolder = $"chara/demihuman/d{id}/obj/equipment/e{bodyVer}/material/v{version}"; var files = await index.GetAllHashedFilesInFolder(HashGenerator.GetHash(mtrlFolder), XivDataFile._04_Chara); foreach (var slotAbr in SlotAbbreviationDictionary) { var charList = (from part in parts let mtrlFile = $"mt_d{id}e{bodyVer}_{slotAbr.Value}_{part}.mtrl" where files.Contains(HashGenerator.GetHash(mtrlFile)) select part).ToList(); if (charList.Count > 0) { equipPartDictionary.Add(slotAbr.Key, charList.ToArray()); } } return(equipPartDictionary); }
/// <summary> /// Gets the full IMC information for a given item /// </summary> /// <param name="item"></param> /// <param name="modelInfo"></param> /// <returns>The ImcData data</returns> public async Task <ImcData> GetFullImcInfo(IItemModel item, XivModelInfo modelInfo) { var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var itemType = ItemType.GetItemType(item); var imcPath = GetImcPath(modelInfo, itemType); var imcOffset = await index.GetDataOffset(HashGenerator.GetHash(imcPath.Folder), HashGenerator.GetHash(imcPath.File), _dataFile); if (imcOffset == 0) { throw new Exception($"Could not find offset for {imcPath.Folder}/{imcPath.File}"); } var imcByteData = await dat.GetType2Data(imcOffset, _dataFile); return(await Task.Run(() => { using (var br = new BinaryReader(new MemoryStream(imcByteData))) { var imcData = new ImcData() { VariantCount = br.ReadInt16(), Unknown = br.ReadInt16(), GearVariantList = new List <VariantSet>() }; //weapons and monsters do not have variant sets if (itemType == XivItemType.weapon || itemType == XivItemType.monster) { imcData.OtherVariantList = new List <XivImc>(); imcData.DefaultVariant = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }; for (var i = 0; i < imcData.VariantCount; i++) { imcData.OtherVariantList.Add(new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }); } } else { imcData.GearVariantList = new List <VariantSet>(); imcData.DefaultVariantSet = new VariantSet { Slot1 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot2 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot3 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot4 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot5 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, }; for (var i = 0; i < imcData.VariantCount; i++) { // gets the data for each slot in the current variant set var imcGear = new VariantSet { Slot1 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot2 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot3 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot4 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, Slot5 = new XivImc { Version = br.ReadUInt16(), Mask = br.ReadUInt16(), Vfx = br.ReadUInt16() }, }; imcData.GearVariantList.Add(imcGear); } } return imcData; } })); }
public ItemSQLConnections(IMemberModel memberModel, IItemModel itemModel, ICheckoutModel checkoutModel) { _memberModel = memberModel; _itemModel = itemModel; _checkoutModel = checkoutModel; }
/// <summary> /// Updates or Adds the Model to the viewport /// </summary> /// <param name="model">The TexTools Model</param> /// <param name="textureDataDictionary">The textures associated with the model</param> /// <param name="item">The item for the model</param> /// <param name="modelRace">The race of the model</param> /// <param name="targetRace">The target race the model should be</param> public void UpdateModel(TTModel model, Dictionary <int, ModelTextureData> textureDataDictionary, IItemModel item, XivRace modelRace, XivRace targetRace) { _targetRace = targetRace; var itemType = $"{item.PrimaryCategory}_{item.SecondaryCategory}"; // If target race is different than the model race Apply racial deforms if (modelRace != targetRace) { ApplyDeformers(model, itemType, modelRace, targetRace); } SharpDX.BoundingBox?boundingBox = null; ModelModifiers.CalculateTangents(model); // Remove any existing models of the same item type RemoveModel(itemType); var totalMeshCount = model.MeshGroups.Count; for (var i = 0; i < totalMeshCount; i++) { var meshGeometry3D = GetMeshGeometry(model, i); var textureData = textureDataDictionary[model.GetMaterialIndex(i)]; Stream diffuse = null, specular = null, normal = null, alpha = null, emissive = null; if (textureData.Diffuse != null && textureData.Diffuse.Length > 0) { using (var img = Image.LoadPixelData <Rgba32>(textureData.Diffuse, textureData.Width, textureData.Height)) { diffuse = new MemoryStream(); img.Save(diffuse, new PngEncoder()); } streamList.Add(diffuse); } if (textureData.Specular != null && textureData.Specular.Length > 0) { using (var img = Image.LoadPixelData <Rgba32>(textureData.Specular, textureData.Width, textureData.Height)) { specular = new MemoryStream(); img.Save(specular, new PngEncoder()); } streamList.Add(specular); } if (textureData.Normal != null && textureData.Normal.Length > 0) { using (var img = Image.LoadPixelData <Rgba32>(textureData.Normal, textureData.Width, textureData.Height)) { normal = new MemoryStream(); img.Save(normal, new PngEncoder()); } streamList.Add(normal); } if (textureData.Alpha != null && textureData.Alpha.Length > 0) { using (var img = Image.LoadPixelData <Rgba32>(textureData.Alpha, textureData.Width, textureData.Height)) { alpha = new MemoryStream(); img.Save(alpha, new PngEncoder()); } streamList.Add(alpha); } if (textureData.Emissive != null && textureData.Emissive.Length > 0) { using (var img = Image.LoadPixelData <Rgba32>(textureData.Emissive, textureData.Width, textureData.Height)) { emissive = new MemoryStream(); img.Save(emissive, new PngEncoder()); } streamList.Add(emissive); } var material = new PhongMaterial { DiffuseColor = PhongMaterials.ToColor(1, 1, 1, 1), SpecularShininess = 1f, DiffuseMap = diffuse, DiffuseAlphaMap = alpha, SpecularColorMap = specular, NormalMap = normal, EmissiveMap = emissive }; // Geometry that contains skeleton data var smgm3d = new CustomBoneSkinMeshGeometry3D { Geometry = meshGeometry3D, Material = material, ItemType = itemType, BoneMatrices = GetMatrices(targetRace), BoneList = model.Bones }; // Keep track of what bones are showing in the view foreach (var modelBone in model.Bones) { if (!shownBonesList.Contains(modelBone)) { shownBonesList.Add(modelBone); } } boundingBox = meshGeometry3D.Bound; smgm3d.CullMode = Properties.Settings.Default.Cull_Mode.Equals("None") ? CullMode.None : CullMode.Back; Models.Add(smgm3d); } SpecularShine = 1; var center = boundingBox.GetValueOrDefault().Center; _lightX = center.X; _lightY = center.Y; _lightZ = center.Z; Light3Direction = new Vector3D(_lightX, _lightY, _lightZ); Camera.UpDirection = new Vector3D(0, 1, 0); Camera.CameraInternal.PropertyChanged += CameraInternal_PropertyChanged; // Add the skeleton node for the target race AddSkeletonNode(targetRace); // Keep track of the models displayed in the viewport shownModels.Add(itemType, new DisplayedModelData { TtModel = model, ItemModel = item, ModelTextureData = textureDataDictionary }); }
private InBoxController CreateInboxController(IItemModel<InBoxItem> model) { var window = MockRepository.GenerateStub<IGTDWindow>(); return new InBoxController(_view, window, model, _converter, MockRepository.GenerateStub<IPublishKeyEvents>()); }