/// <summary>
        /// Search for an entry that contains either a monster or an item with the given id, returns the index, or -1
        /// if such an entry does not exist. Optionally include an offsets to begin the search at.
        /// </summary>
        /// <param name="id">The id to search for.</param>
        /// <param name="entryOffset">Only search entries with index >= this offset.</param>
        /// <param name="monsterOffset">Only search monsters with index >= this offset.</param>
        /// <param name="itemOffset">Only search items with index >= this offset.</param>
        /// <returns>A tuple containing first the index of the entry, then the index of the monster, then the index of
        /// the item, or -1 if it doesn't exist.</returns>
        public Tuple <int, int, int> FindEntry(long id, int entryOffset, int monsterOffset, int itemOffset)
        {
            List <ExtraDropEntry> offsetEntries = Entries.Skip(entryOffset).ToList();

            for (int i = 0; i < offsetEntries.Count; ++i)
            {
                ExtraDropEntry entry = offsetEntries[i];

                // The problem here is that item ids are uint while monster ids are regular int. So we instead read it
                // as a long to be able to store both values and then cast it to either an int or uint. We can simply
                // discard the most significant bits since they really shouldn't have been specified anyway.
                int monsterIndex = entry.FindMonster(unchecked ((int)id), monsterOffset);
                int itemIndex    = entry.FindItem(unchecked ((uint)id), itemOffset);

                if (monsterIndex > -1 || itemIndex > -1)
                {
                    return(Tuple.Create(i + entryOffset, monsterIndex, itemIndex));
                }

                // It only makes sense to check the offset the first time because we're still in the same entry.
                // However, when we move to the next entry, it makes sense to set it to 0.
                monsterOffset = 0;
                itemOffset    = 0;
            }

            return(Tuple.Create(-1, -1, -1));
        }
        /// <summary>
        /// Construct the extra drops table by deserializing from a stream.
        /// </summary>
        /// <param name="input">The input stream to deserialize from.</param>
        public ExtraDropTable(Stream input)
        {
            BinaryReader reader = new BinaryReader(input);

            // The first 4 bytes is believed to be the version number, although this isn't 100% confirmed. We will only
            // support version 1 for now, because other versions may have unknown structure.
            int version = reader.ReadInt32();

            if (version != 1)
            {
                throw new System.NotSupportedException(version.ToString());
            }
            Version = version;

            // The number of ExtraDropEntry that exists in this table.
            int numEntries = reader.ReadInt32();

            Entries.Capacity = numEntries;

            for (int i = 0; i < numEntries; ++i)
            {
                ExtraDropEntry entry = new ExtraDropEntry(input);
                Entries.Add(entry);
            }
        }
        /// <summary>
        /// Clones an existing entry and add it to the list of entries and returns it.
        /// </summary>
        /// <param name="index">The index of the entry to clone.</param>
        /// <returns>The cloned entry.</returns>
        public ExtraDropEntry CloneEntry(int index)
        {
            ExtraDropEntry entry = new ExtraDropEntry(Entries[index]);

            Entries.Add(entry);

            return(entry);
        }
        /// <summary>
        /// Adds a new blank entry to the list of entries and returns it.
        /// </summary>
        /// <returns>A blank entry.</returns>
        public ExtraDropEntry NewEntry()
        {
            ExtraDropEntry entry = new ExtraDropEntry();

            Entries.Add(entry);

            return(entry);
        }
Example #5
0
        /// <summary>
        /// Constructs a new entry by cloning an existing entry.
        /// </summary>
        /// <param name="entry">The entry to clone.</param>
        public ExtraDropEntry(ExtraDropEntry entry)
        {
            Name = entry.Name;
            Type = entry.Type;
            
            // There are always 8 probabilities based on the EXTRADROPTABLE.h struct that Teemo Cell extracted from the 
            // gs.
            for (int i = 0; i < 8; ++i)
            {
                _dropNumProbabilities[i] = entry._dropNumProbabilities[i];
            }

            foreach (int monsterId in entry.Monsters)
            {
                Monsters.Add(monsterId);
            }

            foreach (ExtraDropItem item in entry.DropItems)
            {
                DropItems.Add(new ExtraDropItem(item));
            }
        }