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

@@ -964,7 +964,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
Player* member = itr->GetSource();
if (!member)
continue;
if (member->IsAtGroupRewardDistance(pLootedObject))
if (member->IsAtLootRewardDistance(pLootedObject))
{
if (i->AllowedForPlayer(member))
{
@@ -1048,7 +1048,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
if (!member)
continue;
if (member->IsAtGroupRewardDistance(pLootedObject))
if (member->IsAtLootRewardDistance(pLootedObject))
{
if (i->AllowedForPlayer(member))
{
@@ -1108,7 +1108,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
if (!playerToRoll)
continue;
if (i->AllowedForPlayer(playerToRoll) && playerToRoll->IsAtGroupRewardDistance(lootedObject))
if (i->AllowedForPlayer(playerToRoll) && playerToRoll->IsAtLootRewardDistance(lootedObject))
{
r->totalPlayersRolling++;
if (playerToRoll->GetPassOnGroupLoot())
@@ -1182,7 +1182,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
if (!playerToRoll)
continue;
if (i->AllowedForPlayer(playerToRoll) && playerToRoll->IsAtGroupRewardDistance(lootedObject))
if (i->AllowedForPlayer(playerToRoll) && playerToRoll->IsAtLootRewardDistance(lootedObject))
{
r->totalPlayersRolling++;
r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
@@ -1247,31 +1247,32 @@ void Group::MasterLoot(Loot* loot, WorldObject* pLootedObject)
i->is_blocked = !i->is_underthreshold;
}
uint32 real_count = 0;
WorldPacket data(SMSG_LOOT_MASTER_LIST, 330);
data << (uint8)GetMembersCount();
std::vector<Player*> looters;
for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* looter = itr->GetSource();
if (!looter->IsInWorld())
continue;
if (looter->IsAtGroupRewardDistance(pLootedObject))
{
data << looter->GetGUID();
++real_count;
continue;
}
if (looter->IsAtLootRewardDistance(pLootedObject))
{
looters.push_back(looter);
}
}
data.put<uint8>(0, real_count);
WorldPacket data(SMSG_LOOT_MASTER_LIST, 1 + looters.size() * (1 + 8));
data << uint8(looters.size());
for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
for (Player* looter : looters)
{
Player* looter = itr->GetSource();
if (looter->IsAtGroupRewardDistance(pLootedObject))
looter->GetSession()->SendPacket(&data);
data << looter->GetGUID();
}
for (Player* looter : looters)
{
looter->GetSession()->SendPacket(&data);
}
}
@@ -1775,7 +1776,7 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
{
// not update if only update if need and ok
Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid);
if (looter && looter->IsAtGroupRewardDistance(pLootedObject))
if (looter && looter->IsAtLootRewardDistance(pLootedObject))
return;
}
++guid_itr;
@@ -1786,7 +1787,7 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
for (member_citerator itr = guid_itr; itr != m_memberSlots.end(); ++itr)
{
if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
if (player->IsAtGroupRewardDistance(pLootedObject))
if (player->IsAtLootRewardDistance(pLootedObject))
{
pNewLooter = player;
break;
@@ -1799,7 +1800,7 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
for (member_citerator itr = m_memberSlots.begin(); itr != guid_itr; ++itr)
{
if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
if (player->IsAtGroupRewardDistance(pLootedObject))
if (player->IsAtLootRewardDistance(pLootedObject))
{
pNewLooter = player;
break;