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