aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Loot/LootMgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Loot/LootMgr.cpp')
-rw-r--r--src/server/game/Loot/LootMgr.cpp111
1 files changed, 36 insertions, 75 deletions
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 5a6d173487b..85f0cd869ee 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -37,18 +37,18 @@ static Rates const qualityToRate[MAX_ITEM_QUALITY] = {
RATE_DROP_ITEM_ARTIFACT, // ITEM_QUALITY_ARTIFACT
};
-LootStore LootTemplates_Creature("creature_loot_template", "creature entry", true, true);
-LootStore LootTemplates_Disenchant("disenchant_loot_template", "item disenchant id", true, false);
-LootStore LootTemplates_Fishing("fishing_loot_template", "area id", true, false);
-LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true, true);
-LootStore LootTemplates_Item("item_loot_template", "item entry", true, false);
-LootStore LootTemplates_Mail("mail_loot_template", "mail template id", false, false);
-LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true, false);
-LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template", "creature pickpocket lootid", true, false);
-LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true, false);
-LootStore LootTemplates_Reference("reference_loot_template", "reference id", false, false);
-LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true, false);
-LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false, false);
+LootStore LootTemplates_Creature("creature_loot_template", "creature entry", true);
+LootStore LootTemplates_Disenchant("disenchant_loot_template", "item disenchant id", true);
+LootStore LootTemplates_Fishing("fishing_loot_template", "area id", true);
+LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true);
+LootStore LootTemplates_Item("item_loot_template", "item entry", true);
+LootStore LootTemplates_Mail("mail_loot_template", "mail template id", false);
+LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true);
+LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template", "creature pickpocket lootid", true);
+LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true);
+LootStore LootTemplates_Reference("reference_loot_template", "reference id", false);
+LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true);
+LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false);
class LootTemplate::LootGroup // A set of loot definitions for items (refs are not allowed)
{
@@ -57,8 +57,7 @@ class LootTemplate::LootGroup // A set of loot def
bool HasQuestDrop() const; // True if group includes at least 1 quest drop entry
bool HasQuestDropForPlayer(Player const * player) const;
// The same for active quests of the player
- void Process(Loot& loot, Player* lootOwner, uint16 lootMode, bool autoProcessCurrency) const;
- // Rolls an item from the group (if any) and adds the item to the loot
+ void Process(Loot& loot, uint16 lootMode) const; // Rolls an item from the group (if any) and adds the item to the loot
float RawTotalChance() const; // Overall chance for the group (without equal chanced items)
float TotalChance() const; // Overall chance for the group
@@ -429,7 +428,7 @@ bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bo
items.reserve(MAX_NR_LOOT_ITEMS);
quest_items.reserve(MAX_NR_QUEST_ITEMS);
- tab->Process(*this, store, lootOwner, store.IsRatesAllowed(), lootMode); // Processing is done there, callback via Loot::AddItem()
+ tab->Process(*this, store, store.IsRatesAllowed(), lootMode); // Processing is done there, callback via Loot::AddItem()
// Setting access rights for group loot case
Group * pGroup = lootOwner->GetGroup();
@@ -470,6 +469,22 @@ void Loot::FillNotNormalLootFor(Player* pl)
qmapitr = PlayerNonQuestNonFFAConditionalItems.find(plguid);
if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
FillNonQuestNonFFAConditionalLoot(pl);
+
+ // Process currency items
+ uint32 max_slot = GetMaxSlotInLootFor(pl);
+ uint32 itemId = 0;
+ uint32 itemsSize = uint32(items.size());
+ for (uint32 i = 0; i < max_slot; ++i)
+ {
+ if (i < items.size())
+ itemId = items[i].itemid;
+ else
+ itemId = quest_items[i-itemsSize].itemid;
+
+ if (ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemId))
+ if (proto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ pl->StoreLootItem(i, this);
+ }
}
QuestItemList* Loot::FillFFALoot(Player* player)
@@ -992,7 +1007,7 @@ void LootTemplate::LootGroup::CopyConditions(ConditionList /*conditions*/)
}
// Rolls an item from the group (if any takes its chance) and adds the item to the loot
-void LootTemplate::LootGroup::Process(Loot& loot, Player* lootOwner, uint16 lootMode, bool autoProcessCurrency) const
+void LootTemplate::LootGroup::Process(Loot& loot, uint16 lootMode) const
{
// build up list of possible drops
LootStoreItemList EqualPossibleDrops = EqualChanced;
@@ -1048,16 +1063,8 @@ void LootTemplate::LootGroup::Process(Loot& loot, Player* lootOwner, uint16 loot
bool duplicate = false;
if (ItemPrototype const *_proto = sItemStorage.LookupEntry<ItemPrototype>(item->itemid))
{
- LootItemList::const_iterator _item = loot.items.begin();
- if (autoProcessCurrency)
- if (LootTemplate::ProcessCurrency(lootOwner, itr, _proto))
- {
- duplicate = true; // don't add to loot
- _item = loot.items.end(); // skip next loop
- }
-
uint8 _item_counter = 0;
- for (; _item != loot.items.end(); ++_item)
+ for (LootItemList::const_iterator _item = loot.items.begin(); _item != loot.items.end(); ++_item)
if (_item->itemid == item->itemid) // search through the items that have already dropped
{
++_item_counter;
@@ -1175,15 +1182,14 @@ void LootTemplate::CopyConditions(ConditionList conditions)
}
// Rolls for every item in the template and adds the rolled items the the loot
-void LootTemplate::Process(Loot& loot, LootStore const& store, Player* lootOwner, bool rate, uint16 lootMode, uint8 groupId) const
+void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint16 lootMode, uint8 groupId) const
{
- bool autoProcessCurrency = store.IsCurrencyAutoDistributed();
if (groupId) // Group reference uses own processing of the group
{
if (groupId > Groups.size())
return; // Error message already printed at loading stage
- Groups[groupId-1].Process(loot, lootOwner, lootMode, autoProcessCurrency);
+ Groups[groupId-1].Process(loot, lootMode);
return;
}
@@ -1198,10 +1204,6 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, Player* lootOwner
if (ItemPrototype const *_proto = sItemStorage.LookupEntry<ItemPrototype>(i->itemid))
{
- if (autoProcessCurrency)
- if (ProcessCurrency(lootOwner, i, _proto))
- continue; // don't add to loot
-
uint8 _item_counter = 0;
LootItemList::const_iterator _item = loot.items.begin();
for (; _item != loot.items.end(); ++_item)
@@ -1225,7 +1227,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, Player* lootOwner
continue; // Error message already printed at loading stage
for (uint32 loop = 0; loop < i->maxcount; ++loop) // Ref multiplicator
- Referenced->Process(loot, store, lootOwner, rate, lootMode, i->group);
+ Referenced->Process(loot, store, rate, lootMode, i->group);
}
else // Plain entries (not a reference, not grouped)
loot.AddItem(*i); // Chance is already checked, just add
@@ -1233,48 +1235,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, Player* lootOwner
// Now processing groups
for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i)
- i->Process(loot, lootOwner, lootMode, autoProcessCurrency);
-}
-
-bool LootTemplate::ProcessCurrency(Player* lootOwner, const LootStoreItemList::const_iterator& lootItem, ItemPrototype const* pProto)
-{
- uint32 itemId = lootItem->itemid;
- if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) // Tokens appear in currency of player and remove from drop
- {
- uint32 count = urand(lootItem->mincountOrRef, lootItem->maxcount);
- if (Group* pGroup = lootOwner->GetGroup())
- {
- for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
- {
- if (Player* pGroupGuy = itr->getSource())
- {
- if (!pGroupGuy->IsAtGroupRewardDistance(lootOwner))
- continue;
-
- ItemPosCountVec dest;
- uint8 msg = pGroupGuy->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count);
- if (msg == EQUIP_ERR_OK)
- {
- Item* pItem = pGroupGuy->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
- pGroupGuy->SendNewItem(pItem, count, true, false);
- }
- }
- }
- }
- else
- {
- ItemPosCountVec dest;
- uint8 msg = lootOwner->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count);
- if (msg == EQUIP_ERR_OK)
- {
- Item* pItem = lootOwner->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
- lootOwner->SendNewItem(pItem, count, true, false);
- }
- }
- return true;
- }
-
- return false;
+ i->Process(loot, lootMode);
}
// True if template includes at least 1 quest drop entry