fix(Core/Loot): (#7452)

- Players that did not participate in killing dungeon boss are not eligible to get loot.
- Players that are too far away from the looted object are not eligible to get loot.
- Players that released spirit and were outside the dungeon when the loot has been released are eligible to get loot.
- Players that have pending bind are not eligible to get loot.
- Properly get loot recipient for some chests in dungeons.
- All above fixes should work in any loot mode (group loot, master loot, etc.)
- Closes #2104.
This commit is contained in:
UltraNix
2021-08-24 23:48:22 +02:00
committed by GitHub
parent a594bf5b29
commit 1b7d3708a6
19 changed files with 197 additions and 97 deletions

View File

@@ -2305,29 +2305,60 @@ Group* GameObject::GetLootRecipientGroup() const
return sGroupMgr->GetGroupByGUID(m_lootRecipientGroup);
}
void GameObject::SetLootRecipient(Unit* unit)
void GameObject::SetLootRecipient(Creature* creature)
{
// set the player whose group should receive the right
// to loot the creature after it dies
// should be set to nullptr after the loot disappears
if (!unit)
if (!creature)
{
m_lootRecipient.Clear();
m_lootRecipientGroup = 0;
ResetAllowedLooters();
return;
}
if (unit->GetTypeId() != TYPEID_PLAYER && !unit->IsVehicle())
return;
m_lootRecipient = creature->GetLootRecipientGUID();
m_lootRecipientGroup = creature->GetLootRecipientGroupGUID();
SetAllowedLooters(creature->GetAllowedLooters());
}
Player* player = unit->GetCharmerOrOwnerPlayerOrPlayerItself();
if (!player) // normal creature, no player involved
return;
void GameObject::SetLootRecipient(Map* map)
{
Group* group = nullptr;
Map::PlayerList const& PlayerList = map->GetPlayers();
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
if (Player* groupMember = i->GetSource())
{
if (groupMember->IsGameMaster() || groupMember->IsSpectator())
{
continue;
}
m_lootRecipient = player->GetGUID();
if (Group* group = player->GetGroup())
m_lootRecipientGroup = group->GetGUID().GetCounter();
if (!m_lootRecipient)
{
m_lootRecipient = groupMember->GetGUID();
}
Group* memberGroup = groupMember->GetGroup();
if (memberGroup && !group)
{
group = memberGroup;
m_lootRecipientGroup = group->GetGUID().GetCounter();
}
if (memberGroup == group)
{
AddAllowedLooter(groupMember->GetGUID());
}
}
}
if (!group)
{
AddAllowedLooter(m_lootRecipient);
}
}
bool GameObject::IsLootAllowedFor(Player const* player) const