/// <summary> /// Gets the list to be displayed in the Mounts category /// </summary> /// <remarks> /// The model data for the minion is held separately in modelchara_0.exd /// The data within mount_0 exd contains a reference to the index for lookup in modelchara /// </remarks> /// <returns>A list containing XivMount data</returns> public List <XivMount> GetMountList() { var mountList = new List <XivMount>(); // These are the offsets to relevant data // These will need to be changed if data gets added or removed with a patch const int dataLength = 76; const int nameDataOffset = 6; const int modelCharaIndexOffset = 30; var ex = new Ex(_gameDirectory, _xivLanguage); var mountEx = ex.ReadExData(XivEx.mount); // Loops through all available mounts in the mount exd files // At present only one file exists (mount_0) foreach (var mount in mountEx.Values) { var xivMount = new XivMount { Category = XivStrings.Companions, ItemCategory = XivStrings.Mounts, }; int modelCharaIndex; //Big Endian Byte Order using (var br = new BinaryReaderBE(new MemoryStream(mount))) { br.BaseStream.Seek(nameDataOffset, SeekOrigin.Begin); var nameOffset = br.ReadInt16(); br.BaseStream.Seek(modelCharaIndexOffset, SeekOrigin.Begin); modelCharaIndex = br.ReadInt16(); br.BaseStream.Seek(dataLength, SeekOrigin.Begin); var nameString = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Encoding.UTF8.GetString(br.ReadBytes(nameOffset)).Replace("\0", "")); xivMount.Name = new string(nameString.Where(c => !char.IsControl(c)).ToArray()); } if (modelCharaIndex == 0 || xivMount.Name.Equals("")) { continue; } // This will get the model data using the index obtained for the current mount xivMount.PrimaryModelInfo = XivModelChara.GetModelInfo(_gameDirectory, modelCharaIndex); mountList.Add(xivMount); } mountList.Sort(); return(mountList); }
/// <summary> /// Get the mounts entries list, optionally with a substring filter. /// </summary> /// <param name="substring"></param> /// <returns></returns> public async Task <List <XivMount> > GetCachedMountList(string substring = null, string category = null) { var where = new WhereClause(); if (category != null) { var categoryClause = new WhereClause(); categoryClause.Column = "category"; categoryClause.Value = category; categoryClause.Join = WhereClause.JoinType.And; categoryClause.Comparer = WhereClause.ComparisonType.Equal; where.Inner.Add(categoryClause); } if (substring != null) { var w = new WhereClause(); w.Comparer = WhereClause.ComparisonType.Like; w.Join = WhereClause.JoinType.And; w.Column = "name"; w.Value = "%" + substring + "%"; where.Inner.Add(w); } try { return(await BuildListFromTable("monsters", where, async (reader) => { var item = new XivMount { PrimaryCategory = XivStrings.Companions, SecondaryCategory = reader.GetString("category"), Name = reader.GetString("name"), ModelInfo = new XivMonsterModelInfo { ModelType = (XivItemType)Enum.Parse(typeof(XivItemType), reader.GetString("model_type")), PrimaryID = reader.GetInt32("primary_id"), SecondaryID = reader.GetInt32("secondary_id"), ImcSubsetID = reader.GetInt32("imc_variant"), } }; return item; })); } catch (Exception ex) { throw ex; } }
/// <summary> /// Gets the list to be displayed in the Ornaments category /// </summary> /// <remarks> /// The model data for the ornament is held separately in modelchara_0.exd /// The data within Ornament exd contains a reference to the index for lookup in modelchara /// The data format used by Ornaments is identical to mounts so XivMount can be used to store the data /// </remarks> /// <returns>A list containing XivMount data</returns> public async Task <List <XivMount> > GetUncachedOrnamentList() { var mountLock = new object(); var ornamentList = new List <XivMount>(); // These are the offsets to relevant data // These will need to be changed if data gets added or removed with a patch const int dataLength = 28; const int nameDataOffset = 6; const int modelCharaIndexOffset = 16; var ornamentEx = await _ex.ReadExData(XivEx.ornament); var modelCharaEx = await XivModelChara.GetModelCharaData(_gameDirectory); // Loops through all available mounts in the mount exd files // At present only one file exists (mount_0) await Task.Run(() => Parallel.ForEach(ornamentEx.Values, (ornament) => { var xivOrnament = new XivMount { PrimaryCategory = XivStrings.Companions, SecondaryCategory = XivStrings.Ornaments, }; int modelCharaIndex; //Big Endian Byte Order using (var br = new BinaryReaderBE(new MemoryStream(ornament))) { br.BaseStream.Seek(nameDataOffset, SeekOrigin.Begin); var nameOffset = br.ReadInt16(); br.BaseStream.Seek(modelCharaIndexOffset, SeekOrigin.Begin); modelCharaIndex = br.ReadInt16(); br.BaseStream.Seek(dataLength, SeekOrigin.Begin); var nameString = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Encoding.UTF8 .GetString(br.ReadBytes(nameOffset)).Replace("\0", "")); xivOrnament.Name = new string(nameString.Where(c => !char.IsControl(c)).ToArray()); } if (modelCharaIndex == 0 || xivOrnament.Name.Equals("")) { return; } // This will get the model data using the index obtained for the current mount xivOrnament.ModelInfo = XivModelChara.GetModelInfo(modelCharaEx, modelCharaIndex); lock (mountLock) { ornamentList.Add(xivOrnament); } })); ornamentList.Sort(); return(ornamentList); }