diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index c45c86b5c..6e5d25669 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -405,7 +405,7 @@ LootItem::LootItem(LootStoreItem const& li) } // Basic checks for player/item compatibility - if false no chance to see the item in the loot -bool LootItem::AllowedForPlayer(Player const* player, bool isGivenByMasterLooter /*= false*/, bool allowQuestLoot /*= true*/, ObjectGuid source) const +bool LootItem::AllowedForPlayer(Player const* player, ObjectGuid source) const { ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid); if (!pProto) @@ -419,7 +419,7 @@ bool LootItem::AllowedForPlayer(Player const* player, bool isGivenByMasterLooter if (!sConditionMgr->IsObjectMeetToConditions(const_cast(player), conditions)) { // Master Looter can see conditioned recipes - if (!isGivenByMasterLooter && isMasterLooter) + if (isMasterLooter && follow_loot_rules && !is_underthreshold) { if ((pProto->Flags & ITEM_FLAG_HIDE_UNUSABLE_RECIPE) || (pProto->Class == ITEM_CLASS_RECIPE && pProto->Bonding == BIND_WHEN_PICKED_UP && pProto->Spells[1].SpellId != 0)) { @@ -442,7 +442,7 @@ bool LootItem::AllowedForPlayer(Player const* player, bool isGivenByMasterLooter } // Master looter can see all items even if the character can't loot them - if (!isGivenByMasterLooter && isMasterLooter && allowQuestLoot) + if (isMasterLooter && follow_loot_rules && !is_underthreshold) { return true; } @@ -661,26 +661,35 @@ QuestItemList* Loot::FillQuestLoot(Player* player) QuestItemList* ql = new QuestItemList(); + Player* lootOwner = (roundRobinPlayer) ? ObjectAccessor::FindPlayer(roundRobinPlayer) : player; + for (uint8 i = 0; i < quest_items.size(); ++i) { LootItem& item = quest_items[i]; - if (!item.is_looted && (item.AllowedForPlayer(player, false, false) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT )))) + // Quest item is not free for all and is already assigned to another player + // or player doesn't need it + if (item.is_blocked || !item.AllowedForPlayer(player, sourceWorldObjectGUID)) { - ql->push_back(QuestItem(i)); - - // quest items get blocked when they first appear in a - // player's quest vector - // - // increase once if one looter only, looter-times if free for all - if (item.freeforall || !item.is_blocked) - ++unlootedCount; - if (!player->GetGroup() || (player->GetGroup()->GetLootMethod() != GROUP_LOOT && player->GetGroup()->GetLootMethod() != ROUND_ROBIN)) - item.is_blocked = true; - - if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS) - break; + continue; } + + // Player is not the loot owner, and loot owner still needs this quest item + if (!item.freeforall && lootOwner != player && item.AllowedForPlayer(lootOwner, sourceWorldObjectGUID)) + { + continue; + } + + ql->push_back(QuestItem(i)); + ++unlootedCount; + + if (!item.freeforall) + { + item.is_blocked = true; + } + + if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS) + break; } if (ql->empty()) { @@ -699,7 +708,8 @@ QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player) for (uint8 i = 0; i < items.size(); ++i) { LootItem& item = items[i]; - if (!item.is_looted && !item.freeforall && (item.AllowedForPlayer(player, sourceWorldObjectGUID) || (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, sourceWorldObjectGUID)) { item.AddAllowedLooter(player); diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index 74bc9d20c..b21cfcdbd 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -177,8 +177,7 @@ struct LootItem LootItem() = default; // Basic checks for player/item compatibility - if false no chance to see the item in the loot - bool AllowedForPlayer(Player const* player, bool isGivenByMasterLooter = false, bool allowQuestLoot = true, ObjectGuid source = ObjectGuid::Empty) const; - bool AllowedForPlayer(Player const* player, ObjectGuid source) { return AllowedForPlayer(player, false, true, source); }; + bool AllowedForPlayer(Player const* player, ObjectGuid source) const; void AddAllowedLooter(Player const* player); [[nodiscard]] const AllowedLooterSet& GetAllowedLooters() const { return allowedGUIDs; } };