diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 48539dd3f..e384c1ed5 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -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; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 2ef1c91d5..5bc4ad5c2 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -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 diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 2810c0da3..d777a2a81 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -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 diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index fe193eceb..05d0abf3e 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -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: diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index e46e7257c..87b0bb428 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -3036,3 +3036,33 @@ float WorldObject::GetFloorZ() const return std::max(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; +} diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 5e5f51adc..3b316eb96 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -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 diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c6eaff907..6d3dbca08 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -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) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index dfd8c076b..3b2b0dff5 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -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); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 22c426487..fd6c57a78 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -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); diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index b70ae1f78..54fd027af 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -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 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(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; diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index adad06644..5c5637791 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -170,7 +170,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) if (!member) continue; - if (player->IsAtGroupRewardDistance(member)) + if (player->IsAtLootRewardDistance(member)) playersNear.push_back(member); } diff --git a/src/server/game/Loot/LootItemStorage.cpp b/src/server/game/Loot/LootItemStorage.cpp index af1a8f4e0..dd0c5a6c9 100644 --- a/src/server/game/Loot/LootItemStorage.cpp +++ b/src/server/game/Loot/LootItemStorage.cpp @@ -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 diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 752cb35c5..0b2fe036c 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -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)); diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index b1d6a3f14..afafae172 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -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; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp index 160e06b3a..dc12bd671 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp @@ -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); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp index 791d5f2c3..f0e24667f 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp @@ -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); } } } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 32c2c66b5..993ace476 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -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]]; diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp index bbc79a579..ed9c14829 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp @@ -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(); diff --git a/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp b/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp index 8d1b668d3..dd385688e 100644 --- a/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp +++ b/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp @@ -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(); }