/// <summary> /// Whether the given lootable contains quest items for the given Character when looting with the given type /// </summary> public static bool ContainsQuestItemsFor(this ILootable lootable, Character chr, LootEntryType type) { Asda2Loot loot = lootable.Loot; if (loot != null) { return(((IEnumerable <Asda2LootItem>)loot.Items).Any <Asda2LootItem>((Func <Asda2LootItem, bool>)(item => { if (item.Template.HasQuestRequirements) { return item.Template.CheckQuestConstraints(chr); } return false; }))); } ResolvedLootItemList entries = lootable.GetEntries(type); if (entries != null) { return(entries.Any <LootEntity>((Func <LootEntity, bool>)(entry => { if (entry.ItemTemplate.HasQuestRequirements) { return entry.ItemTemplate.CheckQuestConstraints(chr); } return false; }))); } return(false); }
static LootMgr() { LootEntries[2] = new ResolvedLootItemList[2000]; LootEntries[3] = new ResolvedLootItemList[2000]; LootEntries[4] = new ResolvedLootItemList[5000]; LootEntries[5] = new ResolvedLootItemList[5000]; LootEntries[1] = new ResolvedLootItemList[330000]; LootEntries[6] = new ResolvedLootItemList[10000]; LootEntries[7] = new ResolvedLootItemList[20]; LootEntries[8] = new ResolvedLootItemList[400]; LootEntries[9] = new ResolvedLootItemList[400]; LootEntries[11] = new ResolvedLootItemList[10000]; }
static void LookupRef(ResolvedLootItemList list, LootItemEntry entry) { // TODO: Loot groups (see http://udbwiki.no-ip.org/index.php/Gameobject_loot_template#groupid) var referencedEntries = GetEntries(LootEntryType.Reference, entry.ReferencedEntryId); if (referencedEntries != null) { if (referencedEntries.ResolveStatus < 1) { // first step referencedEntries.ResolveStatus = 1; foreach (var refEntry in referencedEntries) { if (refEntry is LootItemEntry) { var itemEntry = (LootItemEntry)refEntry; if (itemEntry.ReferencedEntryId > 0) { LookupRef(list, itemEntry); continue; } } AddRef(list, refEntry); } referencedEntries.ResolveStatus = 2; } else if (list.ResolveStatus == 1) { // list is already being resolved LogManager.GetCurrentClassLogger().Warn("Infinite loop in Loot references detected in: " + entry); } else { // second step foreach (var refEntry in referencedEntries) { AddRef(list, refEntry); } } } }
private static void LookupRef(ResolvedLootItemList list, LootItemEntry entry) { ResolvedLootItemList entries = LootMgr.GetEntries(LootEntryType.Reference, entry.ReferencedEntryId); if (entries == null) { return; } if (entries.ResolveStatus < (byte)1) { entries.ResolveStatus = (byte)1; foreach (LootEntity ent in (List <LootEntity>)entries) { if (ent is LootItemEntry) { LootItemEntry entry1 = (LootItemEntry)ent; if (entry1.ReferencedEntryId > 0U) { LootMgr.LookupRef(list, entry1); continue; } } LootMgr.AddRef(list, ent); } entries.ResolveStatus = (byte)2; } else if (list.ResolveStatus == (byte)1) { LogManager.GetCurrentClassLogger() .Warn("Infinite loop in Loot references detected in: " + (object)entry); } else { foreach (LootEntity ent in (List <LootEntity>)entries) { LootMgr.AddRef(list, ent); } } }
/// <summary> /// Adds the new LootItemEntry to the global container. /// Keeps the set of entries sorted by rarity. /// </summary> public static void AddEntry(LootItemEntry entry) { var entries = LootEntries[(uint)entry.LootType]; if (entry.EntryId >= entries.Length) { ArrayUtil.EnsureSize(ref entries, (int)(entry.EntryId * ArrayUtil.LoadConstant) + 1); LootEntries[(uint)entry.LootType] = entries; } var list = entries[entry.EntryId]; if (list == null) { entries[entry.EntryId] = list = new ResolvedLootItemList(); } if (entry.ReferencedEntryId > 0 || entry.GroupId > 0) { ReferenceEntries.Add(new KeyValuePair <ResolvedLootItemList, LootItemEntry>(list, entry)); } // add entry sorted var added = false; for (var i = 0; i < list.Count; i++) { var ent = list[i]; if (ent.DropChance > entry.DropChance) { added = true; list.Insert(i, entry); break; } } if (!added) { list.Add(entry); } }
/// <summary> /// Returns all Items that can be looted off the given lootable /// </summary> public static LootItem[] CreateLootItems(uint lootId, LootEntryType type, bool heroic, IList <LooterEntry> looters) { ResolvedLootItemList entries = LootMgr.GetEntries(type, lootId); if (entries == null) { return(LootItem.EmptyArray); } LootItem[] array = new LootItem[Math.Min(15, entries.Count)]; int newSize = 0; foreach (LootEntity lootEntity in (List <LootEntity>)entries) { if (100.0 * (double)Utility.RandomFloat() < (double)lootEntity.DropChance) { ItemTemplate template = lootEntity.ItemTemplate; if (template != null && looters.Any <LooterEntry>((Func <LooterEntry, bool>)(looter => template.CheckLootConstraints(looter.Owner)))) { array[newSize] = new LootItem(template, Utility.Random(lootEntity.MinAmount, lootEntity.MaxAmount), (uint)newSize, template.RandomPropertiesId); ++newSize; if (newSize == 15) { break; } } } } if (newSize == 0) { return(LootItem.EmptyArray); } Array.Resize <LootItem>(ref array, newSize); return(array); }
/// <summary> /// Adds the new LootItemEntry to the global container. /// Keeps the set of entries sorted by rarity. /// </summary> public static void AddEntry(LootItemEntry entry) { ResolvedLootItemList[] lootEntry = LootMgr.LootEntries[(uint)entry.LootType]; if ((long)entry.EntryId >= (long)lootEntry.Length) { ArrayUtil.EnsureSize <ResolvedLootItemList>(ref lootEntry, (int)((double)entry.EntryId * 1.5) + 1); LootMgr.LootEntries[(uint)entry.LootType] = lootEntry; } ResolvedLootItemList key = lootEntry[entry.EntryId]; if (key == null) { lootEntry[entry.EntryId] = key = new ResolvedLootItemList(); } if (entry.ReferencedEntryId > 0U || entry.GroupId > 0U) { LootMgr.ReferenceEntries.Add(new KeyValuePair <ResolvedLootItemList, LootItemEntry>(key, entry)); } bool flag = false; for (int index = 0; index < key.Count; ++index) { if ((double)key[index].DropChance > (double)entry.DropChance) { flag = true; key.Insert(index, (LootEntity)entry); break; } } if (flag) { return; } key.Add((LootEntity)entry); }
private static void AddRef(ResolvedLootItemList list, LootEntity ent) { list.Add(ent); }