/// <summary>
        /// Gets the list to be displayed in the Minion category
        /// </summary>
        /// <remarks>
        /// The model data for the minion is held separately in modelchara_0.exd
        /// The data within companion_0 exd contains a reference to the index for lookup in modelchara
        /// </remarks>
        /// <returns>A list containing XivMinion data</returns>
        public List <XivMinion> GetMinionList()
        {
            var minionList = new List <XivMinion>();

            // 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            = 48;
            const int nameDataOffset        = 6;
            const int modelCharaIndexOffset = 16;

            var ex       = new Ex(_gameDirectory, _xivLanguage);
            var minionEx = ex.ReadExData(XivEx.companion);

            // Loops through all available minions in the companion exd files
            // At present only one file exists (companion_0)
            foreach (var minion in minionEx.Values)
            {
                var xivMinion = new XivMinion
                {
                    Category     = XivStrings.Companions,
                    ItemCategory = XivStrings.Minions
                };

                int modelCharaIndex;

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(minion)))
                {
                    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", ""));
                    xivMinion.Name = new string(nameString.Where(c => !char.IsControl(c)).ToArray());
                }

                if (modelCharaIndex == 0)
                {
                    continue;
                }

                // This will get the model data using the index obtained for the current minion
                xivMinion.PrimaryModelInfo = XivModelChara.GetModelInfo(_gameDirectory, modelCharaIndex);

                minionList.Add(xivMinion);
            }

            minionList.Sort();

            return(minionList);
        }
Example #2
0
        /// <summary>
        /// Get the minions entries list, optionally with a substring filter.
        /// </summary>
        /// <param name="substring"></param>
        /// <returns></returns>
        public async Task <List <XivMinion> > GetCachedMinionsList(string substring = null)
        {
            var where = new WhereClause();

            var minionClause = new WhereClause();

            minionClause.Column   = "category";
            minionClause.Value    = XivStrings.Minions;
            minionClause.Join     = WhereClause.JoinType.And;
            minionClause.Comparer = WhereClause.ComparisonType.Equal;
            where.Inner.Add(minionClause);

            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 XivMinion
                    {
                        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;
            }
        }
Example #3
0
        /// <summary>
        /// Gets the list to be displayed in the Minion category
        /// </summary>
        /// <remarks>
        /// The model data for the minion is held separately in modelchara_0.exd
        /// The data within companion_0 exd contains a reference to the index for lookup in modelchara
        /// </remarks>
        /// <returns>A list containing XivMinion data</returns>
        public async Task <List <XivMinion> > GetUncachedMinionList()
        {
            var minionLock = new object();
            var minionList = new List <XivMinion>();

            // 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            = 48;
            const int nameDataOffset        = 6;
            const int modelCharaIndexOffset = 16;

            var minionEx = await _ex.ReadExData(XivEx.companion);

            var modelCharaEx = await XivModelChara.GetModelCharaData(_gameDirectory);

            // Loops through all available minions in the companion exd files
            // At present only one file exists (companion_0)
            await Task.Run(() => Parallel.ForEach(minionEx.Values, (minion) =>
            {
                var xivMinion = new XivMinion
                {
                    PrimaryCategory   = XivStrings.Companions,
                    SecondaryCategory = XivStrings.Minions
                };

                int modelCharaIndex;

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(minion)))
                {
                    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", ""));
                    xivMinion.Name = new string(nameString.Where(c => !char.IsControl(c)).ToArray());
                }

                if (modelCharaIndex == 0)
                {
                    return;
                }

                // This will get the model data using the index obtained for the current minion
                xivMinion.ModelInfo = XivModelChara.GetModelInfo(modelCharaEx, modelCharaIndex);

                lock (minionLock)
                {
                    minionList.Add(xivMinion);
                }
            }));

            minionList.Sort();

            return(minionList);
        }