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
@@ -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
@@ -863,7 +863,8 @@ public:
[[nodiscard]] Player* GetLootRecipient() const;
[[nodiscard]] Group* GetLootRecipientGroup() const;
void SetLootRecipient(Unit* unit);
void SetLootRecipient(Creature* creature);
void SetLootRecipient(Map* map);
bool IsLootAllowedFor(Player const* player) const;
[[nodiscard]] bool HasLootRecipient() const { return m_lootRecipient || m_lootRecipientGroup; }
uint32 m_groupLootTimer; // (msecs)timer used for group loot
@@ -982,7 +983,7 @@ protected:
Position m_stationaryPosition;
ObjectGuid m_lootRecipient;
uint32 m_lootRecipientGroup;
ObjectGuid::LowType m_lootRecipientGroup;
uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable
uint32 m_lootGenerationTime;
private:
@@ -3036,3 +3036,33 @@ float WorldObject::GetFloorZ() const
return std::max<float>(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhaseMask(), GetPositionX(), GetPositionY(), GetPositionZ() + std::max(GetCollisionHeight(), Z_OFFSET_FIND_HEIGHT)));
}
void WorldObject::AddAllowedLooter(ObjectGuid guid)
{
_allowedLooters.insert(guid);
}
void WorldObject::SetAllowedLooters(GuidUnorderedSet const looters)
{
_allowedLooters = looters;
}
void WorldObject::ResetAllowedLooters()
{
_allowedLooters.clear();
}
bool WorldObject::HasAllowedLooter(ObjectGuid guid) const
{
if (_allowedLooters.empty())
{
return true;
}
return _allowedLooters.find(guid) != _allowedLooters.end();
}
GuidUnorderedSet const& WorldObject::GetAllowedLooters() const
{
return _allowedLooters;
}
+8
View File
@@ -1047,6 +1047,12 @@ public:
[[nodiscard]] virtual float GetCollisionWidth() const { return GetObjectSize(); }
[[nodiscard]] virtual float GetCollisionRadius() const { return GetObjectSize() / 2; }
void AddAllowedLooter(ObjectGuid guid);
void ResetAllowedLooters();
void SetAllowedLooters(GuidUnorderedSet const looters);
[[nodiscard]] bool HasAllowedLooter(ObjectGuid guid) const;
[[nodiscard]] GuidUnorderedSet const& GetAllowedLooters() const;
protected:
std::string m_name;
bool m_isActive;
@@ -1091,6 +1097,8 @@ private:
bool CanDetectInvisibilityOf(WorldObject const* obj) const;
//bool CanDetectStealthOf(WorldObject const* obj) const;
bool CanDetectStealthOf(WorldObject const* obj, bool checkAlert = false) const;
GuidUnorderedSet _allowedLooters;
};
namespace Acore
+26 -4
View File
@@ -7560,7 +7560,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
if (groupRules)
group->UpdateLooterGuid(go, true);
loot->FillLoot(lootid, LootTemplates_Gameobject, this, !groupRules, false, go->GetLootMode());
loot->FillLoot(lootid, LootTemplates_Gameobject, this, !groupRules, false, go->GetLootMode(), go);
go->SetLootGenerationTime();
// get next RR player (for next loot)
@@ -11846,18 +11846,40 @@ void Player::RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject* pRewar
bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const
{
if (!pRewardSource || !IsInMap(pRewardSource))
return false;
const WorldObject* player = GetCorpse();
WorldObject const* player = GetCorpse();
if (!player || IsAlive())
{
player = this;
}
if (!pRewardSource || !player->IsInMap(pRewardSource))
{
return false;
}
if (pRewardSource->GetMap()->IsDungeon())
{
return true;
}
return pRewardSource->GetDistance(player) <= sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE);
}
bool Player::IsAtLootRewardDistance(WorldObject const* pRewardSource) const
{
if (!IsAtGroupRewardDistance(pRewardSource))
{
return false;
}
if (HasPendingBind())
{
return false;
}
return pRewardSource->HasAllowedLooter(GetGUID());
}
bool Player::IsAtRecruitAFriendDistance(WorldObject const* pOther) const
{
if (!pOther)
+1
View File
@@ -1996,6 +1996,7 @@ public:
void InitDisplayIds();
bool IsAtGroupRewardDistance(WorldObject const* pRewardSource) const;
bool IsAtLootRewardDistance(WorldObject const* pRewardSource) const;
bool IsAtRecruitAFriendDistance(WorldObject const* pOther) const;
void RewardPlayerAndGroupAtKill(Unit* victim, bool isBattleGround);
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject* pRewardSource);
+2 -2
View File
@@ -16935,7 +16935,7 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp
else if (Group* lrg = creature->GetLootRecipientGroup())
for (GroupReference* itr = lrg->GetFirstMember(); itr != nullptr; itr = itr->next())
if (Player* member = itr->GetSource())
if (member->IsAtGroupRewardDistance(creature))
if (member->IsAtLootRewardDistance(creature))
{
player = member;
break;
@@ -16997,7 +16997,7 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp
loot->clear();
if (uint32 lootid = creature->GetCreatureTemplate()->lootid)
loot->FillLoot(lootid, LootTemplates_Creature, looter, false, false, creature->GetLootMode());
loot->FillLoot(lootid, LootTemplates_Creature, looter, false, false, creature->GetLootMode(), creature);
if (creature->GetLootMode())
loot->generateMoneyLoot(creature->GetCreatureTemplate()->mingold, creature->GetCreatureTemplate()->maxgold);
+23 -22
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;
+1 -1
View File
@@ -170,7 +170,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/)
if (!member)
continue;
if (player->IsAtGroupRewardDistance(member))
if (player->IsAtLootRewardDistance(member))
playersNear.push_back(member);
}
+1 -1
View File
@@ -209,7 +209,7 @@ bool LootItemStorage::LoadStoredLoot(Item* item, Player* player)
if (loot->unlootedCount)
{
loot->FillNotNormalLootFor(player, true);
loot->FillNotNormalLootFor(player);
}
// Mark the item if it has loot so it won't be generated again on open
+16 -14
View File
@@ -510,7 +510,7 @@ void Loot::AddItem(LootStoreItem const& item)
}
// Calls processor of corresponding LootTemplate (which handles everything including references)
bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bool personal, bool noEmptyError, uint16 lootMode /*= LOOT_MODE_DEFAULT*/)
bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bool personal, bool noEmptyError, uint16 lootMode /*= LOOT_MODE_DEFAULT*/, WorldObject* lootSource /*= nullptr*/)
{
// Must be provided
if (!lootOwner)
@@ -541,9 +541,15 @@ bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bo
roundRobinPlayer = lootOwner->GetGUID();
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
if (player->IsInMap(lootOwner)) // pussywizard: multithreading crashfix
FillNotNormalLootFor(player, player->IsAtGroupRewardDistance(lootOwner));
{
if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
{
if (player->IsAtLootRewardDistance(lootSource ? lootSource : lootOwner))
{
FillNotNormalLootFor(player);
}
}
}
for (uint8 i = 0; i < items.size(); ++i)
{
@@ -554,12 +560,12 @@ bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bo
}
// ... for personal loot
else
FillNotNormalLootFor(lootOwner, true);
FillNotNormalLootFor(lootOwner);
return true;
}
void Loot::FillNotNormalLootFor(Player* player, bool presentAtLooting)
void Loot::FillNotNormalLootFor(Player* player)
{
ObjectGuid playerGuid = player->GetGUID();
@@ -573,11 +579,7 @@ void Loot::FillNotNormalLootFor(Player* player, bool presentAtLooting)
qmapitr = PlayerNonQuestNonFFAConditionalItems.find(playerGuid);
if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end())
FillNonQuestNonFFAConditionalLoot(player, presentAtLooting);
// if not auto-processed player will have to come and pick it up manually
if (!presentAtLooting)
return;
FillNonQuestNonFFAConditionalLoot(player);
// Process currency items
uint32 max_slot = GetMaxSlotInLootFor(player);
@@ -658,7 +660,7 @@ QuestItemList* Loot::FillQuestLoot(Player* player)
return ql;
}
QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player, bool presentAtLooting)
QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player)
{
QuestItemList* ql = new QuestItemList();
@@ -667,8 +669,8 @@ QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player, bool pres
LootItem& item = items[i];
if (!item.is_looted && !item.freeforall && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT ))))
{
if (presentAtLooting)
item.AddAllowedLooter(player);
item.AddAllowedLooter(player);
if (!item.conditions.empty())
{
ql->push_back(QuestItem(i));
+3 -3
View File
@@ -362,7 +362,7 @@ struct Loot
void RemoveLooter(ObjectGuid GUID) { PlayersLooting.erase(GUID); }
void generateMoneyLoot(uint32 minAmount, uint32 maxAmount);
bool FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bool personal, bool noEmptyError = false, uint16 lootMode = LOOT_MODE_DEFAULT);
bool FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bool personal, bool noEmptyError = false, uint16 lootMode = LOOT_MODE_DEFAULT, WorldObject* lootSource = nullptr);
// Inserts the item into the loot (called by LootTemplate processors)
void AddItem(LootStoreItem const& item);
@@ -372,12 +372,12 @@ struct Loot
bool hasItemForAll() const;
bool hasItemFor(Player* player) const;
[[nodiscard]] bool hasOverThresholdItem() const;
void FillNotNormalLootFor(Player* player, bool presentAtLooting);
void FillNotNormalLootFor(Player* player);
private:
QuestItemList* FillFFALoot(Player* player);
QuestItemList* FillQuestLoot(Player* player);
QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player, bool presentAtLooting);
QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player);
typedef GuidSet PlayersLootingSet;
PlayersLootingSet PlayersLooting;
@@ -127,7 +127,7 @@ public:
else if (HelpersKilled == MAX_ACTIVE_HELPERS)
{
me->loot.clear();
me->loot.FillLoot(me->GetCreatureTemplate()->lootid, LootTemplates_Creature, me->GetLootRecipient(), false, false, 1);
me->loot.FillLoot(me->GetCreatureTemplate()->lootid, LootTemplates_Creature, me->GetLootRecipient(), false, false, 1, me);
instance->SetData(DATA_DELRISSA_EVENT, DONE);
me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
}
@@ -425,17 +425,10 @@ public:
cacheEntry = GO_CRUSADERS_CACHE_25_H;
break;
}
if (GameObject* go = c->SummonGameObject(cacheEntry, Locs[LOC_CENTER].GetPositionX(), Locs[LOC_CENTER].GetPositionY(), Locs[LOC_CENTER].GetPositionZ(), Locs[LOC_CENTER].GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 630000000))
{
Map::PlayerList const& pl = instance->GetPlayers();
for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
if (Player* plr = itr->GetSource())
if (Group* g = plr->GetGroup())
if (!plr->IsGameMaster() && g->GetLeaderGUID() == plr->GetGUID())
{
go->SetLootRecipient(plr);
break;
}
go->SetLootRecipient(instance);
}
}
@@ -1375,16 +1368,7 @@ public:
if (GameObject* chest = c->SummonGameObject(tributeChest, 665.12f, 143.78f, 142.12f, 0.0f, 0, 0, 0, 0, 90000000))
{
chest->SetRespawnTime(chest->GetRespawnDelay());
Map::PlayerList const& pl = instance->GetPlayers();
for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
if (Player* plr = itr->GetSource())
if (Group* g = plr->GetGroup())
if (!plr->IsGameMaster() && g->GetLeaderGUID() == plr->GetGUID())
{
chest->SetLootRecipient(plr);
break;
}
chest->SetLootRecipient(instance);
}
}
}
@@ -760,7 +760,7 @@ public:
case GO_CACHE_OF_THE_DREAMWALKER_10H:
case GO_CACHE_OF_THE_DREAMWALKER_25H:
if (Creature* valithria = instance->GetCreature(ValithriaDreamwalkerGUID))
go->SetLootRecipient(valithria->GetLootRecipient());
go->SetLootRecipient(valithria);
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN);
break;
case GO_SCOURGE_TRANSPORTER_LK:
@@ -1029,14 +1029,7 @@ public:
{
if (GameObject* loot = instance->GetGameObject(GunshipArmoryGUID))
{
Map::PlayerList const& pl = instance->GetPlayers();
for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
if (Player* p = itr->GetSource())
if (!p->IsGameMaster() && p->GetGroup() && p->GetGroup()->isRaidGroup())
{
loot->SetLootRecipient(p);
break;
}
loot->SetLootRecipient(instance);
loot->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN);
}
}
@@ -1050,7 +1043,7 @@ public:
if (GameObject* loot = instance->GetGameObject(DeathbringersCacheGUID))
{
if (Creature* deathbringer = instance->GetCreature(DeathbringerSaurfangGUID))
loot->SetLootRecipient(deathbringer->GetLootRecipient());
loot->SetLootRecipient(deathbringer);
loot->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN);
}
[[fallthrough]];
@@ -211,7 +211,7 @@ public:
c->SetLootMode(1);
c->loot.clear();
if (uint32 lootid = c->GetCreatureTemplate()->lootid)
c->loot.FillLoot(lootid, LootTemplates_Creature, c->GetLootRecipient(), false, false, c->GetLootMode());
c->loot.FillLoot(lootid, LootTemplates_Creature, c->GetLootRecipient(), false, false, c->GetLootMode(), c);
if (c->GetLootMode())
c->loot.generateMoneyLoot(c->GetCreatureTemplate()->mingold, c->GetCreatureTemplate()->maxgold);
c->DestroyForNearbyPlayers();
@@ -226,7 +226,7 @@ public:
c->SetLootMode(1);
c->loot.clear();
if (uint32 lootid = c->GetCreatureTemplate()->lootid)
c->loot.FillLoot(lootid, LootTemplates_Creature, c->GetLootRecipient(), false, false, c->GetLootMode());
c->loot.FillLoot(lootid, LootTemplates_Creature, c->GetLootRecipient(), false, false, c->GetLootMode(), c);
if (c->GetLootMode())
c->loot.generateMoneyLoot(c->GetCreatureTemplate()->mingold, c->GetCreatureTemplate()->maxgold);
c->DestroyForNearbyPlayers();
@@ -104,7 +104,7 @@ public:
else if (actionId == MAX_ADD_NUMBER)
{
me->loot.clear();
me->loot.FillLoot(me->GetCreatureTemplate()->lootid, LootTemplates_Creature, me->GetLootRecipient(), false, false, 1);
me->loot.FillLoot(me->GetCreatureTemplate()->lootid, LootTemplates_Creature, me->GetLootRecipient(), false, false, 1, me);
me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
_JustDied();
}