diff options
author | Wyrserth <43747507+Wyrserth@users.noreply.github.com> | 2019-06-15 14:17:29 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-12-11 13:06:25 +0100 |
commit | 7b346bcf8d4c4b39685a46ef09f389c8a317b566 (patch) | |
tree | cec711fd00c6174817101c260d51626ec6b60192 | |
parent | 4e7727d575f2c22dddc6327d89e0cfecb9b9748e (diff) |
Core/Loot: fix some issues with master loot and don't allow players to see soulbound recipes that they already learned in the loot window. (#23410)
(cherry picked from commit e6ad9b10cf381625ca1955cf6081ea1a8b14de11)
-rw-r--r-- | src/server/game/Handlers/LootHandler.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Loot/Loot.cpp | 45 | ||||
-rw-r--r-- | src/server/game/Loot/Loot.h | 2 |
3 files changed, 42 insertions, 9 deletions
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index f2c5ad4f15c..562403933a6 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -516,7 +516,7 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPackets::Loot::MasterLootItem ItemPosCountVec dest; InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count); - if (item.follow_loot_rules && !item.AllowedForPlayer(target)) + if (!item.AllowedForPlayer(target, true)) msg = EQUIP_ERR_CANT_EQUIP_EVER; if (msg != EQUIP_ERR_OK) { @@ -526,8 +526,6 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPackets::Loot::MasterLootItem _player->SendLootError(req.Object, ObjectGuid::Empty, LOOT_ERROR_MASTER_INV_FULL); else _player->SendLootError(req.Object, ObjectGuid::Empty, LOOT_ERROR_MASTER_OTHER); - - target->SendEquipError(msg, nullptr, nullptr, item.itemid); return; } diff --git a/src/server/game/Loot/Loot.cpp b/src/server/game/Loot/Loot.cpp index 73ccbca886e..5132a4b4e52 100644 --- a/src/server/game/Loot/Loot.cpp +++ b/src/server/game/Loot/Loot.cpp @@ -57,7 +57,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) const +bool LootItem::AllowedForPlayer(Player const* player, bool isGivenByMasterLooter) const { // DB conditions check if (!sConditionMgr->IsObjectMeetToConditions(const_cast<Player*>(player), conditions)) @@ -67,10 +67,6 @@ bool LootItem::AllowedForPlayer(Player const* player) const if (!pProto) return false; - // not show loot for players without profession or those who already know the recipe - if ((pProto->GetFlags() & ITEM_FLAG_HIDE_UNUSABLE_RECIPE) && (!player->HasSkill(pProto->GetRequiredSkill()) || player->HasSpell(pProto->Effects[1]->SpellID))) - return false; - // not show loot for not own team if ((pProto->GetFlags2() & ITEM_FLAG2_FACTION_HORDE) && player->GetTeam() != HORDE) return false; @@ -78,6 +74,45 @@ bool LootItem::AllowedForPlayer(Player const* player) const if ((pProto->GetFlags2() & ITEM_FLAG2_FACTION_ALLIANCE) && player->GetTeam() != ALLIANCE) return false; + // Master looter can see certain items even if the character can't loot them + if (!isGivenByMasterLooter && player->GetGroup() && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID()) + { + // check quest requirements + if (!(pProto->FlagsCu & ITEM_FLAGS_CU_IGNORE_QUEST_STATUS) && (needs_quest || pProto->GetStartQuest())) + return false; + + return true; + } + + // Don't allow loot for players without profession or those who already know the recipe + if (pProto->GetFlags() & ITEM_FLAG_HIDE_UNUSABLE_RECIPE) + { + if (!player->HasSkill(pProto->GetRequiredSkill())) + return false; + + for (ItemEffectEntry const* itemEffect : pProto->Effects) + { + if (itemEffect->TriggerType != ITEM_SPELLTRIGGER_LEARN_SPELL_ID) + continue; + + if (player->HasSpell(itemEffect->SpellID)) + return false; + } + } + + // Don't allow to loot soulbound recipes that the player has already learned + if (pProto->GetClass() == ITEM_CLASS_RECIPE && pProto->GetBonding() == BIND_ON_ACQUIRE) + { + for (ItemEffectEntry const* itemEffect : pProto->Effects) + { + if (itemEffect->TriggerType != ITEM_SPELLTRIGGER_LEARN_SPELL_ID) + continue; + + if (player->HasSpell(itemEffect->SpellID)) + return false; + } + } + // check quest requirements if (!(pProto->FlagsCu & ITEM_FLAGS_CU_IGNORE_QUEST_STATUS) && ((needs_quest || (pProto->GetStartQuest() && player->GetQuestStatus(pProto->GetStartQuest()) != QUEST_STATUS_NONE)) && !player->HasQuestForItem(itemid))) return false; diff --git a/src/server/game/Loot/Loot.h b/src/server/game/Loot/Loot.h index 1ffca758e73..99edb8ac009 100644 --- a/src/server/game/Loot/Loot.h +++ b/src/server/game/Loot/Loot.h @@ -158,7 +158,7 @@ struct TC_GAME_API LootItem freeforall(false), is_underthreshold(false), is_counted(false), needs_quest(false), follow_loot_rules(false) { }; // Basic checks for player/item compatibility - if false no chance to see the item in the loot - bool AllowedForPlayer(Player const* player) const; + bool AllowedForPlayer(Player const* player, bool isGivenByMasterLooter = false) const; void AddAllowedLooter(Player const* player); GuidSet const& GetAllowedLooters() const { return allowedGUIDs; } }; |