/// <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); }
/// <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)); } }