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
+29 -3
View File
@@ -1139,22 +1139,48 @@ void Creature::SetLootRecipient(Unit* unit, bool withGroup)
m_lootRecipient.Clear();
m_lootRecipientGroup = 0;
RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE | UNIT_DYNFLAG_TAPPED);
ResetAllowedLooters();
return;
}
//if (unit->GetTypeId() != TYPEID_PLAYER && !unit->IsVehicle())
// return;
Player* player = unit->GetCharmerOrOwnerPlayerOrPlayerItself();
if (!player) // normal creature, no player involved
return;
m_lootRecipient = player->GetGUID();
Map* map = GetMap();
if (map && map->IsDungeon() && (isWorldBoss() || IsDungeonBoss()))
{
AddAllowedLooter(m_lootRecipient);
}
if (withGroup)
{
if (Group* group = player->GetGroup())
{
m_lootRecipientGroup = group->GetGUID().GetCounter();
if (map && map->IsDungeon() && (isWorldBoss() || IsDungeonBoss()))
{
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;
}
if (groupMember->GetGroup() == group)
{
AddAllowedLooter(groupMember->GetGUID());
}
}
}
}
}
}
else
m_lootRecipientGroup = 0;
+2 -1
View File
@@ -198,6 +198,7 @@ public:
Loot loot;
[[nodiscard]] ObjectGuid GetLootRecipientGUID() const { return m_lootRecipient; }
[[nodiscard]] Player* GetLootRecipient() const;
[[nodiscard]] ObjectGuid::LowType GetLootRecipientGroupGUID() const { return m_lootRecipientGroup; }
[[nodiscard]] Group* GetLootRecipientGroup() const;
[[nodiscard]] bool hasLootRecipient() const { return m_lootRecipient || m_lootRecipientGroup; }
bool isTappedBy(Player const* player) const; // return true if the creature is tapped by the player or a member of his party.
@@ -374,7 +375,7 @@ protected:
static float _GetHealthMod(int32 Rank);
ObjectGuid m_lootRecipient;
uint32 m_lootRecipientGroup;
ObjectGuid::LowType m_lootRecipientGroup;
/// Timers
time_t m_corpseRemoveTime; // (msecs)timer for death or corpse disappearance