// Calls processor of corresponding LootTemplate (which handles everything including references) public bool FillLoot(uint lootId, LootStore store, Player lootOwner, bool personal, bool noEmptyError = false, LootModes lootMode = LootModes.Default) { // Must be provided if (lootOwner == null) { return(false); } LootTemplate tab = store.GetLootFor(lootId); if (tab == null) { if (!noEmptyError) { Log.outError(LogFilter.Sql, "Table '{0}' loot id #{1} used but it doesn't have records.", store.GetName(), lootId); } return(false); } _itemContext = lootOwner.GetMap().GetDifficultyLootItemContext(); tab.Process(this, store.IsRatesAllowed(), (byte)lootMode); // Processing is done there, callback via Loot.AddItem() // Setting access rights for group loot case Group group = lootOwner.GetGroup(); if (!personal && group != null) { roundRobinPlayer = lootOwner.GetGUID(); for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.next()) { Player player = refe.GetSource(); if (player) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter { FillNotNormalLootFor(player, player.IsAtGroupRewardDistance(lootOwner)); } } for (byte i = 0; i < items.Count; ++i) { ItemTemplate proto = Global.ObjectMgr.GetItemTemplate(items[i].itemid); if (proto != null) { if (proto.GetQuality() < group.GetLootThreshold()) { items[i].is_underthreshold = true; } } } } // ... for personal loot else { FillNotNormalLootFor(lootOwner, true); } return(true); }
public void Process(Loot loot, bool rate, ushort lootMode, byte groupId = 0) { if (groupId != 0) // Group reference uses own processing of the group { if (groupId > Groups.Count) { return; // Error message already printed at loading stage } if (Groups[groupId - 1] == null) { return; } Groups[groupId - 1].Process(loot, lootMode); return; } // Rolling non-grouped items foreach (var item in Entries) { if (!Convert.ToBoolean(item.lootmode & lootMode)) // Do not add if mode mismatch { continue; } if (!item.Roll(rate)) { continue; // Bad luck for the entry } if (item.reference > 0) // References processing { LootTemplate Referenced = LootStorage.Reference.GetLootFor(item.reference); if (Referenced == null) { continue; // Error message already printed at loading stage } uint maxcount = (uint)(item.maxcount * WorldConfig.GetFloatValue(WorldCfg.RateDropItemReferencedAmount)); for (uint loop = 0; loop < maxcount; ++loop) // Ref multiplicator { Referenced.Process(loot, rate, lootMode, item.groupid); } } else // Plain entries (not a reference, not grouped) { loot.AddItem(item); // Chance is already checked, just add } } // Now processing groups foreach (var group in Groups.Values) { if (group != null) { group.Process(loot, lootMode); } } }
public bool LoadStoredLoot(Item item, Player player) { Loot loot = item.loot; if (!_lootItemStorage.ContainsKey(loot.containerID.GetCounter())) { return(false); } var container = _lootItemStorage[loot.containerID.GetCounter()]; loot.gold = container.GetMoney(); LootTemplate lt = LootStorage.Items.GetLootFor(item.GetEntry()); if (lt != null) { foreach (var storedItemPair in container.GetLootItems()) { LootItem li = new(); li.itemid = storedItemPair.Key; li.count = (byte)storedItemPair.Value.Count; li.follow_loot_rules = storedItemPair.Value.FollowRules; li.freeforall = storedItemPair.Value.FFA; li.is_blocked = storedItemPair.Value.Blocked; li.is_counted = storedItemPair.Value.Counted; li.is_underthreshold = storedItemPair.Value.UnderThreshold; li.needs_quest = storedItemPair.Value.NeedsQuest; li.randomBonusListId = storedItemPair.Value.RandomBonusListId; li.context = storedItemPair.Value.Context; li.BonusListIDs = storedItemPair.Value.BonusListIDs; // Copy the extra loot conditions from the item in the loot template lt.CopyConditions(li); // If container item is in a bag, add that player as an allowed looter if (item.GetBagSlot() != 0) { li.AddAllowedLooter(player); } // Finally add the LootItem to the container loot.items.Add(li); // Increment unlooted count ++loot.unlootedCount; } } // Mark the item if it has loot so it won't be generated again on open item.m_lootGenerated = true; return(true); }