mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-08 15:58:04 +00:00
fix(Core/Loot): Fix Master Loot visibility and assignment for quest i… (#24828)
Co-authored-by: sogla <sogladev@gmail.com> Co-authored-by: Ryan Turner <16946913+TheSCREWEDSoftware@users.noreply.github.com>
This commit is contained in:
@@ -418,83 +418,34 @@ bool LootItem::AllowedForPlayer(Player const* player, ObjectGuid source) const
|
|||||||
{
|
{
|
||||||
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid);
|
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid);
|
||||||
if (!pProto)
|
if (!pProto)
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_LOOT, itemid, nullptr))
|
if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_LOOT, itemid, nullptr))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
bool isMasterLooter = player->GetGroup() && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID();
|
|
||||||
bool itemVisibleForMasterLooter = !needs_quest && (!follow_loot_rules || !is_underthreshold);
|
|
||||||
|
|
||||||
// DB conditions check
|
|
||||||
if (!sConditionMgr->IsObjectMeetToConditions(const_cast<Player*>(player), conditions))
|
if (!sConditionMgr->IsObjectMeetToConditions(const_cast<Player*>(player), conditions))
|
||||||
{
|
|
||||||
// Master Looter can see conditioned recipes
|
|
||||||
if (isMasterLooter && itemVisibleForMasterLooter)
|
|
||||||
{
|
|
||||||
if (pProto->HasFlag(ITEM_FLAG_HIDE_UNUSABLE_RECIPE) || (pProto->Class == ITEM_CLASS_RECIPE && pProto->Bonding == BIND_WHEN_PICKED_UP && pProto->Spells[1].SpellId != 0))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// not show loot for not own team
|
// not show loot for not own team
|
||||||
if (pProto->HasFlag2(ITEM_FLAG2_FACTION_HORDE) && player->GetTeamId(true) != TEAM_HORDE)
|
if (pProto->HasFlag2(ITEM_FLAG2_FACTION_HORDE) && player->GetTeamId(true) != TEAM_HORDE)
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (pProto->HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE) && player->GetTeamId(true) != TEAM_ALLIANCE)
|
if (pProto->HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE) && player->GetTeamId(true) != TEAM_ALLIANCE)
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Master looter can see all items even if the character can't loot them
|
// profession / recipe checks
|
||||||
if (isMasterLooter && itemVisibleForMasterLooter)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't allow loot for players without profession or those who already know the recipe
|
|
||||||
if (pProto->HasFlag(ITEM_FLAG_HIDE_UNUSABLE_RECIPE) && (!player->HasSkill(pProto->RequiredSkill) || player->HasSpell(pProto->Spells[1].SpellId)))
|
if (pProto->HasFlag(ITEM_FLAG_HIDE_UNUSABLE_RECIPE) && (!player->HasSkill(pProto->RequiredSkill) || player->HasSpell(pProto->Spells[1].SpellId)))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Don't allow to loot soulbound recipes that the player has already learned
|
|
||||||
if (pProto->Class == ITEM_CLASS_RECIPE && pProto->Bonding == BIND_WHEN_PICKED_UP && pProto->Spells[1].SpellId != 0 && player->HasSpell(pProto->Spells[1].SpellId))
|
if (pProto->Class == ITEM_CLASS_RECIPE && pProto->Bonding == BIND_WHEN_PICKED_UP && pProto->Spells[1].SpellId != 0 && player->HasSpell(pProto->Spells[1].SpellId))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// check quest requirements
|
// check quest requirements
|
||||||
if (!pProto->HasFlagCu(ITEM_FLAGS_CU_IGNORE_QUEST_STATUS))
|
if (needs_quest && !pProto->HasFlagCu(ITEM_FLAGS_CU_IGNORE_QUEST_STATUS) && !player->HasQuestForItem(itemid))
|
||||||
{
|
return false;
|
||||||
// Don't drop quest items if the player is missing the relevant quest
|
|
||||||
if (needs_quest && !player->HasQuestForItem(itemid))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// for items that start quests
|
|
||||||
if (pProto->StartQuest)
|
|
||||||
{
|
|
||||||
// Don't drop the item if the player has already finished the quest OR player already has the item in their inventory, and that item is unique OR the player has not finished a prerequisite quest
|
|
||||||
uint32 prevQuestId = sObjectMgr->GetQuestTemplate(pProto->StartQuest) ? sObjectMgr->GetQuestTemplate(pProto->StartQuest)->GetPrevQuestId() : 0;
|
|
||||||
if (player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE || (player->HasItemCount(itemid, pProto->MaxCount) && pProto->MaxCount) || (prevQuestId && !player->GetQuestRewardStatus(prevQuestId)))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sScriptMgr->OnAllowedForPlayerLootCheck(player, source))
|
if (!sScriptMgr->OnAllowedForPlayerLootCheck(player, source))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -691,7 +642,7 @@ QuestItemList* Loot::FillQuestLoot(Player* player)
|
|||||||
|
|
||||||
QuestItemList* ql = new QuestItemList();
|
QuestItemList* ql = new QuestItemList();
|
||||||
|
|
||||||
Player* lootOwner = (roundRobinPlayer) ? ObjectAccessor::FindPlayer(roundRobinPlayer) : player;
|
bool isMasterLooter = player->GetGroup() && player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID();
|
||||||
|
|
||||||
for (uint8 i = 0; i < quest_items.size(); ++i)
|
for (uint8 i = 0; i < quest_items.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -699,32 +650,29 @@ QuestItemList* Loot::FillQuestLoot(Player* player)
|
|||||||
|
|
||||||
sScriptMgr->OnPlayerBeforeFillQuestLootItem(player, item);
|
sScriptMgr->OnPlayerBeforeFillQuestLootItem(player, item);
|
||||||
|
|
||||||
// Quest item is not free for all and is already assigned to another player
|
bool allowed = item.AllowedForPlayer(player, sourceWorldObjectGUID);
|
||||||
// or player doesn't need it
|
|
||||||
if (item.is_blocked || !item.AllowedForPlayer(player, sourceWorldObjectGUID))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Player is not the loot owner, and loot owner still needs this quest item
|
if (!allowed && !isMasterLooter)
|
||||||
if (!item.freeforall &&
|
|
||||||
lootOwner && lootOwner != player &&
|
|
||||||
item.AllowedForPlayer(lootOwner, sourceWorldObjectGUID))
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
ql->push_back(QuestItem(i));
|
ql->push_back(QuestItem(i));
|
||||||
++unlootedCount;
|
|
||||||
|
|
||||||
if (!item.freeforall)
|
// Only add "allowed looter" if you are actually allowed to loot.
|
||||||
|
if (allowed)
|
||||||
{
|
{
|
||||||
item.is_blocked = true;
|
item.AddAllowedLooter(player);
|
||||||
|
|
||||||
|
if (!item.is_counted)
|
||||||
|
{
|
||||||
|
++unlootedCount;
|
||||||
|
item.is_counted = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS)
|
if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ql->empty())
|
if (ql->empty())
|
||||||
{
|
{
|
||||||
delete ql;
|
delete ql;
|
||||||
|
|||||||
Reference in New Issue
Block a user