From 5816918c132fb7b6fd69f26b70bb95a0e83ae0cb Mon Sep 17 00:00:00 2001 From: Wyrserth <43747507+Wyrserth@users.noreply.github.com> Date: Sat, 24 Oct 2020 09:57:29 +0200 Subject: [PATCH] Core/Loot: make Loot::AddItem() honor LootItem::AllowedForPlayer() so that items that cannot be looted don't prevent skinning. --- src/server/game/Loot/Loot.cpp | 38 +++++++++++++++++++++++++++++++++++ src/server/game/Loot/Loot.h | 1 + 2 files changed, 39 insertions(+) diff --git a/src/server/game/Loot/Loot.cpp b/src/server/game/Loot/Loot.cpp index 5503a5dbe1d..dcd10f3d61d 100644 --- a/src/server/game/Loot/Loot.cpp +++ b/src/server/game/Loot/Loot.cpp @@ -133,6 +133,24 @@ void Loot::AddItem(LootStoreItem const& item) lootItems.push_back(generatedLoot); count -= currency->MaxQty; + // In some cases, a dropped item should be visible/lootable only for some players in group + bool canSeeItemInLootWindow = false; + if (Player* player = ObjectAccessor::FindPlayer(lootOwnerGUID)) + { + if (Group* group = player->GetGroup()) + { + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) + if (Player* member = itr->GetSource()) + if (generatedLoot.AllowedForPlayer(member)) + canSeeItemInLootWindow = true; + } + else if (generatedLoot.AllowedForPlayer(player)) + canSeeItemInLootWindow = true; + } + + if (!canSeeItemInLootWindow) + continue; + // Never seen a currency that needs a quest but just in case if (!item.needs_quest) ++unlootedCount; @@ -154,6 +172,24 @@ void Loot::AddItem(LootStoreItem const& item) lootItems.push_back(generatedLoot); count -= proto->GetMaxStackSize(); + // In some cases, a dropped item should be visible/lootable only for some players in group + bool canSeeItemInLootWindow = false; + if (Player* player = ObjectAccessor::FindPlayer(lootOwnerGUID)) + { + if (Group* group = player->GetGroup()) + { + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) + if (Player* member = itr->GetSource()) + if (generatedLoot.AllowedForPlayer(member)) + canSeeItemInLootWindow = true; + } + else if (generatedLoot.AllowedForPlayer(player)) + canSeeItemInLootWindow = true; + } + + if (!canSeeItemInLootWindow) + continue; + // non-conditional one-player only items are counted here, // free for all items are counted in FillFFALoot(), // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot() @@ -185,6 +221,8 @@ bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bo if (!lootOwner) return false; + lootOwnerGUID = lootOwner->GetGUID(); + LootTemplate const* tab = store.GetLootFor(lootId); if (!tab) diff --git a/src/server/game/Loot/Loot.h b/src/server/game/Loot/Loot.h index c2828cf571c..e9fa8e309ce 100644 --- a/src/server/game/Loot/Loot.h +++ b/src/server/game/Loot/Loot.h @@ -219,6 +219,7 @@ struct TC_GAME_API Loot uint32 gold; uint8 unlootedCount; ObjectGuid roundRobinPlayer; // GUID of the player having the Round-Robin ownership for the loot. If 0, round robin owner has released. + ObjectGuid lootOwnerGUID; LootType loot_type; // required for achievement system uint8 maxDuplicates; // Max amount of items with the same entry that can drop (default is 1; on 25 man raid mode 3)