diff options
author | Richard <rblee88@gmail.com> | 2016-11-04 22:20:47 +1100 |
---|---|---|
committer | Aokromes <Aokromes@users.noreply.github.com> | 2016-11-04 12:20:47 +0100 |
commit | f5d3343f27f68c7837152fc592310397a686a83e (patch) | |
tree | dd303065412f3c458c4e4fe9320f36203dfd7249 /src | |
parent | 6214c7181dc55c1b1076c4413d8ecd09d57a3460 (diff) |
[3.3.5] Core/Loot: Fix conditional Master Loot (#17943)
* Core/Loot: Fix master looting of conditional items
follow_loot_rules was a flag intended to force certain quest items to be
master looted. It should not be used for the
NonQuestNonFFAConditionalLoot.
The flag was originally introduced in 869ea349
"Core/Loot: fix the way quest items are handled. so far ive only found 3
quest items that should be able to be masterlooted. added a new flag to
item_template.flagsCustom to allow for making a quest item always follow
loot rules. a bonus may be the fix of the handlelootmasteropcode crash!"
* Core/Loot: Rename QuestItem to NotNormalItem
QuestItem struct was being used for quest items, ffa items, and
conditional items. Renaming it to avoid confusion when working with ffa
and conditional items
* Core/Loot: Use existing AddAllowedLooter rather than reaching into allowedGUIDs directly
* Core/Loot: Rename NotNormalItem to NotNormalLootItem
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Loot/LootMgr.cpp | 133 | ||||
-rw-r--r-- | src/server/game/Loot/LootMgr.h | 38 |
4 files changed, 87 insertions, 92 deletions
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 3946e110c26..9d60eb62be6 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -1346,7 +1346,7 @@ bool Item::ItemContainerLoadLootFromDB() // If container item is in a bag, add that player as an allowed looter if (GetBagSlot()) - loot_item.allowedGUIDs.insert(GetOwner()->GetGUID().GetCounter()); + loot_item.AddAllowedLooter(GetOwner()); // Finally add the LootItem to the container loot.items.push_back(loot_item); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 8c2ae863584..41d9bf7b2b2 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -24638,9 +24638,9 @@ void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore cons void Player::StoreLootItem(uint8 lootSlot, Loot* loot) { - QuestItem* qitem = nullptr; - QuestItem* ffaitem = nullptr; - QuestItem* conditem = nullptr; + NotNormalLootItem* qitem = nullptr; + NotNormalLootItem* ffaitem = nullptr; + NotNormalLootItem* conditem = nullptr; LootItem* item = loot->LootItemInSlot(lootSlot, this, &qitem, &ffaitem, &conditem); diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 9686fb9622f..b69bb41d3ad 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -483,7 +483,7 @@ void Loot::FillNotNormalLootFor(Player* player, bool presentAtLooting) { ObjectGuid::LowType plguid = player->GetGUID().GetCounter(); - QuestItemMap::const_iterator qmapitr = PlayerQuestItems.find(plguid); + NotNormalLootItemMap::const_iterator qmapitr = PlayerQuestItems.find(plguid); if (qmapitr == PlayerQuestItems.end()) FillQuestLoot(player); @@ -517,16 +517,16 @@ void Loot::FillNotNormalLootFor(Player* player, bool presentAtLooting) } } -QuestItemList* Loot::FillFFALoot(Player* player) +NotNormalLootItemList* Loot::FillFFALoot(Player* player) { - QuestItemList* ql = new QuestItemList(); + NotNormalLootItemList* ql = new NotNormalLootItemList(); for (uint8 i = 0; i < items.size(); ++i) { LootItem &item = items[i]; if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player)) { - ql->push_back(QuestItem(i)); + ql->push_back(NotNormalLootItem(i)); ++unlootedCount; } } @@ -540,12 +540,12 @@ QuestItemList* Loot::FillFFALoot(Player* player) return ql; } -QuestItemList* Loot::FillQuestLoot(Player* player) +NotNormalLootItemList* Loot::FillQuestLoot(Player* player) { if (items.size() == MAX_NR_LOOT_ITEMS) return NULL; - QuestItemList* ql = new QuestItemList(); + NotNormalLootItemList* ql = new NotNormalLootItemList(); for (uint8 i = 0; i < quest_items.size(); ++i) { @@ -553,7 +553,7 @@ QuestItemList* Loot::FillQuestLoot(Player* player) if (!item.is_looted && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT)))) { - ql->push_back(QuestItem(i)); + ql->push_back(NotNormalLootItem(i)); // quest items get blocked when they first appear in a // player's quest vector @@ -578,20 +578,20 @@ QuestItemList* Loot::FillQuestLoot(Player* player) return ql; } -QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player, bool presentAtLooting) +NotNormalLootItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player, bool presentAtLooting) { - QuestItemList* ql = new QuestItemList(); + NotNormalLootItemList* ql = new NotNormalLootItemList(); for (uint8 i = 0; i < items.size(); ++i) { LootItem &item = items[i]; - if (!item.is_looted && !item.freeforall && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT)))) + if (!item.is_looted && !item.freeforall && (item.AllowedForPlayer(player))) { if (presentAtLooting) item.AddAllowedLooter(player); if (!item.conditions.empty()) { - ql->push_back(QuestItem(i)); + ql->push_back(NotNormalLootItem(i)); if (!item.is_counted) { ++unlootedCount; @@ -657,11 +657,11 @@ void Loot::NotifyQuestItemRemoved(uint8 questIndex) ++i_next; if (Player* player = ObjectAccessor::FindPlayer(*i)) { - QuestItemMap::const_iterator pq = PlayerQuestItems.find(player->GetGUID().GetCounter()); + NotNormalLootItemMap::const_iterator pq = PlayerQuestItems.find(player->GetGUID().GetCounter()); if (pq != PlayerQuestItems.end() && pq->second) { // find where/if the player has the given item in it's vector - QuestItemList& pql = *pq->second; + NotNormalLootItemList& pql = *pq->second; uint8 j; for (j = 0; j < pql.size(); ++j) @@ -717,17 +717,17 @@ void Loot::DeleteLootMoneyFromContainerItemDB() CharacterDatabase.Execute(stmt); } -LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem* *qitem, QuestItem* *ffaitem, QuestItem* *conditem) +LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, NotNormalLootItem* *qitem, NotNormalLootItem* *ffaitem, NotNormalLootItem* *conditem) { LootItem* item = NULL; bool is_looted = true; if (lootSlot >= items.size()) { uint32 questSlot = lootSlot - items.size(); - QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID().GetCounter()); + NotNormalLootItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID().GetCounter()); if (itr != PlayerQuestItems.end() && questSlot < itr->second->size()) { - QuestItem* qitem2 = &itr->second->at(questSlot); + NotNormalLootItem* qitem2 = &itr->second->at(questSlot); if (qitem) *qitem = qitem2; item = &quest_items[qitem2->index]; @@ -740,13 +740,13 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem* *qite is_looted = item->is_looted; if (item->freeforall) { - QuestItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUID().GetCounter()); + NotNormalLootItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUID().GetCounter()); if (itr != PlayerFFAItems.end()) { - for (QuestItemList::const_iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter) + for (NotNormalLootItemList::const_iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter) if (iter->index == lootSlot) { - QuestItem* ffaitem2 = (QuestItem*)&(*iter); + NotNormalLootItem* ffaitem2 = (NotNormalLootItem*)&(*iter); if (ffaitem) *ffaitem = ffaitem2; is_looted = ffaitem2->is_looted; @@ -756,14 +756,14 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem* *qite } else if (!item->conditions.empty()) { - QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUID().GetCounter()); + NotNormalLootItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUID().GetCounter()); if (itr != PlayerNonQuestNonFFAConditionalItems.end()) { - for (QuestItemList::const_iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter) + for (NotNormalLootItemList::const_iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter) { if (iter->index == lootSlot) { - QuestItem* conditem2 = (QuestItem*)&(*iter); + NotNormalLootItem* conditem2 = (NotNormalLootItem*)&(*iter); if (conditem) *conditem = conditem2; is_looted = conditem2->is_looted; @@ -782,7 +782,7 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem* *qite uint32 Loot::GetMaxSlotInLootFor(Player* player) const { - QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID().GetCounter()); + NotNormalLootItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID().GetCounter()); return items.size() + (itr != PlayerQuestItems.end() ? itr->second->size() : 0); } @@ -802,12 +802,12 @@ bool Loot::hasItemForAll() const // return true if there is any FFA, quest or conditional item for the player. bool Loot::hasItemFor(Player* player) const { - QuestItemMap const& lootPlayerQuestItems = GetPlayerQuestItems(); - QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUID().GetCounter()); + NotNormalLootItemMap const& lootPlayerQuestItems = GetPlayerQuestItems(); + NotNormalLootItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUID().GetCounter()); if (q_itr != lootPlayerQuestItems.end()) { - QuestItemList* q_list = q_itr->second; - for (QuestItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi) + NotNormalLootItemList* q_list = q_itr->second; + for (NotNormalLootItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi) { const LootItem &item = quest_items[qi->index]; if (!qi->is_looted && !item.is_looted) @@ -815,12 +815,12 @@ bool Loot::hasItemFor(Player* player) const } } - QuestItemMap const& lootPlayerFFAItems = GetPlayerFFAItems(); - QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(player->GetGUID().GetCounter()); + NotNormalLootItemMap const& lootPlayerFFAItems = GetPlayerFFAItems(); + NotNormalLootItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(player->GetGUID().GetCounter()); if (ffa_itr != lootPlayerFFAItems.end()) { - QuestItemList* ffa_list = ffa_itr->second; - for (QuestItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi) + NotNormalLootItemList* ffa_list = ffa_itr->second; + for (NotNormalLootItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi) { const LootItem &item = items[fi->index]; if (!fi->is_looted && !item.is_looted) @@ -828,12 +828,12 @@ bool Loot::hasItemFor(Player* player) const } } - QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems(); - QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(player->GetGUID().GetCounter()); + NotNormalLootItemMap const& lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems(); + NotNormalLootItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(player->GetGUID().GetCounter()); if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end()) { - QuestItemList* conditional_list = nn_itr->second; - for (QuestItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci) + NotNormalLootItemList* conditional_list = nn_itr->second; + for (NotNormalLootItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci) { const LootItem &item = items[ci->index]; if (!ci->is_looted && !item.is_looted) @@ -976,12 +976,12 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) } LootSlotType slotType = lv.permission == OWNER_PERMISSION ? LOOT_SLOT_TYPE_OWNER : LOOT_SLOT_TYPE_ALLOW_LOOT; - QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems(); - QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUID().GetCounter()); + NotNormalLootItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems(); + NotNormalLootItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUID().GetCounter()); if (q_itr != lootPlayerQuestItems.end()) { - QuestItemList* q_list = q_itr->second; - for (QuestItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi) + NotNormalLootItemList* q_list = q_itr->second; + for (NotNormalLootItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi) { LootItem &item = l.quest_items[qi->index]; if (!qi->is_looted && !item.is_looted) @@ -1017,12 +1017,12 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) } } - QuestItemMap const& lootPlayerFFAItems = l.GetPlayerFFAItems(); - QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUID().GetCounter()); + NotNormalLootItemMap const& lootPlayerFFAItems = l.GetPlayerFFAItems(); + NotNormalLootItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUID().GetCounter()); if (ffa_itr != lootPlayerFFAItems.end()) { - QuestItemList* ffa_list = ffa_itr->second; - for (QuestItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi) + NotNormalLootItemList* ffa_list = ffa_itr->second; + for (NotNormalLootItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi) { LootItem &item = l.items[fi->index]; if (!fi->is_looted && !item.is_looted) @@ -1035,42 +1035,37 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) } } - QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems(); - QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUID().GetCounter()); + NotNormalLootItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems(); + NotNormalLootItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUID().GetCounter()); if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end()) { - QuestItemList* conditional_list = nn_itr->second; - for (QuestItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci) + NotNormalLootItemList* conditional_list = nn_itr->second; + for (NotNormalLootItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci) { LootItem &item = l.items[ci->index]; if (!ci->is_looted && !item.is_looted) { b << uint8(ci->index); b << item; - if (item.follow_loot_rules) + switch (lv.permission) { - switch (lv.permission) - { - case MASTER_PERMISSION: - b << uint8(LOOT_SLOT_TYPE_MASTER); - break; - case RESTRICTED_PERMISSION: - b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType)); - break; - case GROUP_PERMISSION: - case ROUND_ROBIN_PERMISSION: - if (!item.is_blocked) - b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT); - else - b << uint8(LOOT_SLOT_TYPE_ROLL_ONGOING); - break; - default: - b << uint8(slotType); - break; - } - } - else + case MASTER_PERMISSION: + b << uint8(LOOT_SLOT_TYPE_MASTER); + break; + case RESTRICTED_PERMISSION: + b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType)); + break; + case GROUP_PERMISSION: + case ROUND_ROBIN_PERMISSION: + if (!item.is_blocked) + b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT); + else + b << uint8(LOOT_SLOT_TYPE_ROLL_ONGOING); + break; + default: b << uint8(slotType); + break; + } ++itemsShown; } } diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index bca5cde1fa5..ecfb864823f 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -180,24 +180,24 @@ struct TC_GAME_API LootItem const AllowedLooterSet & GetAllowedLooters() const { return allowedGUIDs; } }; -struct QuestItem +struct NotNormalLootItem { - uint8 index; // position in quest_items; + uint8 index; // position in quest_items or items; bool is_looted; - QuestItem() + NotNormalLootItem() : index(0), is_looted(false) { } - QuestItem(uint8 _index, bool _islooted = false) + NotNormalLootItem(uint8 _index, bool _islooted = false) : index(_index), is_looted(_islooted) { } }; struct Loot; class LootTemplate; -typedef std::vector<QuestItem> QuestItemList; +typedef std::vector<NotNormalLootItem> NotNormalLootItemList; typedef std::vector<LootItem> LootItemList; -typedef std::map<uint32, QuestItemList*> QuestItemMap; +typedef std::map<uint32, NotNormalLootItemList*> NotNormalLootItemMap; typedef std::list<LootStoreItem*> LootStoreItemList; typedef std::unordered_map<uint32, LootTemplate*> LootTemplateMap; @@ -308,9 +308,9 @@ struct TC_GAME_API Loot { friend ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv); - QuestItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; } - QuestItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; } - QuestItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return PlayerNonQuestNonFFAConditionalItems; } + NotNormalLootItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; } + NotNormalLootItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; } + NotNormalLootItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return PlayerNonQuestNonFFAConditionalItems; } std::vector<LootItem> items; std::vector<LootItem> quest_items; @@ -340,15 +340,15 @@ struct TC_GAME_API Loot // void clear(); void clear() { - for (QuestItemMap::const_iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr) + for (NotNormalLootItemMap::const_iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr) delete itr->second; PlayerQuestItems.clear(); - for (QuestItemMap::const_iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr) + for (NotNormalLootItemMap::const_iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr) delete itr->second; PlayerFFAItems.clear(); - for (QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr) + for (NotNormalLootItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr) delete itr->second; PlayerNonQuestNonFFAConditionalItems.clear(); @@ -377,7 +377,7 @@ struct TC_GAME_API Loot // Inserts the item into the loot (called by LootTemplate processors) void AddItem(LootStoreItem const & item); - LootItem* LootItemInSlot(uint32 lootslot, Player* player, QuestItem** qitem = NULL, QuestItem** ffaitem = NULL, QuestItem** conditem = NULL); + LootItem* LootItemInSlot(uint32 lootslot, Player* player, NotNormalLootItem** qitem = NULL, NotNormalLootItem** ffaitem = NULL, NotNormalLootItem** conditem = NULL); uint32 GetMaxSlotInLootFor(Player* player) const; bool hasItemForAll() const; bool hasItemFor(Player* player) const; @@ -385,14 +385,14 @@ struct TC_GAME_API Loot private: void FillNotNormalLootFor(Player* player, bool presentAtLooting); - QuestItemList* FillFFALoot(Player* player); - QuestItemList* FillQuestLoot(Player* player); - QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player, bool presentAtLooting); + NotNormalLootItemList* FillFFALoot(Player* player); + NotNormalLootItemList* FillQuestLoot(Player* player); + NotNormalLootItemList* FillNonQuestNonFFAConditionalLoot(Player* player, bool presentAtLooting); GuidSet PlayersLooting; - QuestItemMap PlayerQuestItems; - QuestItemMap PlayerFFAItems; - QuestItemMap PlayerNonQuestNonFFAConditionalItems; + NotNormalLootItemMap PlayerQuestItems; + NotNormalLootItemMap PlayerFFAItems; + NotNormalLootItemMap PlayerNonQuestNonFFAConditionalItems; // All rolls are registered here. They need to know, when the loot is not valid anymore LootValidatorRefManager i_LootValidatorRefManager; |