aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2022-09-16 16:58:03 +0200
committerShauren <shauren.trinity@gmail.com>2022-09-16 16:58:03 +0200
commit3ef5079feeedfdafc9d3c1d9f865e96dbc77ecc8 (patch)
treec88a3e2c1a8ae8459eb43fa63c66081c37393170 /src/server/game/Entities
parent9700b2a78680452d80025121a031da340af51348 (diff)
Core/Loot: Move loot rolls from Group to Loot
* Partial port of cmangos/mangos-wotlk@ffdf9a05d67a04c3c0304e9b021807fa5b867583
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/Corpse/Corpse.cpp8
-rw-r--r--src/server/game/Entities/Corpse/Corpse.h2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp26
-rw-r--r--src/server/game/Entities/Creature/Creature.h3
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp17
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp110
-rw-r--r--src/server/game/Entities/Player/Player.h7
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp28
9 files changed, 74 insertions, 129 deletions
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index e5085e73849..37d36295a54 100644
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -93,6 +93,14 @@ bool Corpse::Create(ObjectGuid::LowType guidlow, Player* owner)
return true;
}
+void Corpse::Update(uint32 diff)
+{
+ WorldObject::Update(diff);
+
+ if (m_loot)
+ m_loot->Update();
+}
+
void Corpse::SaveToDB()
{
// prevent DB data inconsistence problems and duplicates
diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h
index b54742c3e9c..e34b8d73a50 100644
--- a/src/server/game/Entities/Corpse/Corpse.h
+++ b/src/server/game/Entities/Corpse/Corpse.h
@@ -81,6 +81,8 @@ class TC_GAME_API Corpse : public WorldObject, public GridObject<Corpse>
bool Create(ObjectGuid::LowType guidlow, Map* map);
bool Create(ObjectGuid::LowType guidlow, Player* owner);
+ void Update(uint32 diff) override;
+
void SaveToDB();
bool LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields);
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 940e20e95ae..34302dcbce9 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -19,7 +19,7 @@
#include "BattlegroundMgr.h"
#include "CellImpl.h"
#include "CombatPackets.h"
-#include "Common.h"
+#include "Containers.h"
#include "CreatureAI.h"
#include "CreatureAISelector.h"
#include "CreatureGroups.h"
@@ -31,8 +31,9 @@
#include "GridNotifiersImpl.h"
#include "Group.h"
#include "GroupMgr.h"
-#include "InstanceScript.h"
+#include "ItemTemplate.h"
#include "Log.h"
+#include "Loot.h"
#include "LootMgr.h"
#include "MapManager.h"
#include "MiscPackets.h"
@@ -44,14 +45,13 @@
#include "PoolMgr.h"
#include "QueryPackets.h"
#include "ScriptedGossip.h"
+#include "Spell.h"
#include "SpellAuraEffects.h"
#include "SpellMgr.h"
#include "TemporarySummon.h"
-#include "Transport.h"
-#include "Util.h"
#include "Vehicle.h"
#include "World.h"
-#include "WorldPacket.h"
+#include "ZoneScript.h"
#include <G3D/g3dmath.h>
#include <sstream>
@@ -775,20 +775,10 @@ void Creature::Update(uint32 diff)
if (IsEngaged())
Unit::AIUpdateTick(diff);
- if (m_loot && m_groupLootTimer && !lootingGroupLowGUID.IsEmpty())
- {
- if (m_groupLootTimer <= diff)
- {
- if (Group* group = sGroupMgr->GetGroupByGUID(lootingGroupLowGUID))
- group->EndRoll(m_loot.get(), GetMap());
+ if (m_loot)
+ m_loot->Update();
- m_groupLootTimer = 0;
- lootingGroupLowGUID.Clear();
- }
- else
- m_groupLootTimer -= diff;
- }
- else if (m_corpseRemoveTime <= GameTime::GetGameTime())
+ if (m_corpseRemoveTime <= GameTime::GetGameTime())
{
RemoveCorpse(false);
TC_LOG_DEBUG("entities.unit", "Removing corpse... %u ", GetEntry());
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index aadd60fde52..4b14899c0f7 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -292,9 +292,6 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
m_combatPulseTime = delay;
}
- uint32 m_groupLootTimer; // (msecs)timer used for group loot
- ObjectGuid lootingGroupLowGUID; // used to find group which is looting corpse
-
void SendZoneUnderAttackMessage(Player* attacker);
bool hasQuest(uint32 quest_id) const override;
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index c789fc6f64b..5e506dd8be0 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -37,6 +37,7 @@
#include "GroupMgr.h"
#include "Item.h"
#include "Log.h"
+#include "Loot.h"
#include "LootMgr.h"
#include "Map.h"
#include "MapManager.h"
@@ -520,7 +521,6 @@ GameObject::GameObject() : WorldObject(false), MapObject(),
m_spawnId = UI64LIT(0);
- m_groupLootTimer = 0;
m_lootGenerationTime = 0;
ResetLootMode(); // restore default loot mode
@@ -1173,19 +1173,8 @@ void GameObject::Update(uint32 diff)
}
break;
case GAMEOBJECT_TYPE_CHEST:
- if (m_loot && m_groupLootTimer)
- {
- if (m_groupLootTimer <= diff)
- {
- if (Group* group = sGroupMgr->GetGroupByGUID(lootingGroupLowGUID))
- group->EndRoll(m_loot.get(), GetMap());
-
- m_groupLootTimer = 0;
- lootingGroupLowGUID.Clear();
- }
- else
- m_groupLootTimer -= diff;
- }
+ if (m_loot)
+ m_loot->Update();
// Non-consumable chest was partially looted and restock time passed, restock all loot now
if (GetGOInfo()->chest.consumable == 0 && GameTime::GetGameTime() >= m_restockTime)
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 133c1c4e460..fba6febb163 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -287,8 +287,6 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
bool IsLootAllowedFor(Player const* player) const;
bool HasLootRecipient() const { return !m_lootRecipient.IsEmpty() || !m_lootRecipientGroup.IsEmpty(); }
Loot* GetLootForPlayer(Player const* /*player*/) const override { return m_loot.get(); }
- uint32 m_groupLootTimer; // (msecs)timer used for group loot
- ObjectGuid lootingGroupLowGUID; // used to find group which is looting
GameObject* GetLinkedTrap();
void SetLinkedTrap(GameObject* linkedTrap) { m_linkedTrap = linkedTrap->GetGUID(); }
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 143219d35c6..58bbc90a40c 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -75,6 +75,7 @@
#include "LanguageMgr.h"
#include "LFGMgr.h"
#include "Log.h"
+#include "Loot.h"
#include "LootItemStorage.h"
#include "LootMgr.h"
#include "LootPackets.h"
@@ -1634,6 +1635,7 @@ void Player::RemoveFromWorld()
UnsummonPetTemporaryIfAny();
ClearComboPoints();
m_session->DoLootReleaseAll();
+ m_lootRolls.clear();
sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
}
@@ -8713,6 +8715,20 @@ Loot* Player::GetLootByWorldObjectGUID(ObjectGuid const& lootWorldObjectGuid) co
return itr != m_AELootView.end() ? itr->second : nullptr;
}
+LootRoll* Player::GetLootRoll(ObjectGuid const& lootObjectGuid, uint8 lootListId)
+{
+ auto itr = std::find_if(m_lootRolls.begin(), m_lootRolls.end(), [&](LootRoll const* roll)
+ {
+ return roll->IsLootItem(lootObjectGuid, lootListId);
+ });
+ return itr != m_lootRolls.end() ? *itr : nullptr;
+}
+
+void Player::RemoveLootRoll(LootRoll* roll)
+{
+ m_lootRolls.erase(std::remove(m_lootRolls.begin(), m_lootRolls.end(), roll), m_lootRolls.end());
+}
+
/* If in a battleground a player dies, and an enemy removes the insignia, the player's bones is lootable
Called by remove insignia spell effect */
void Player::RemovedInsignia(Player* looterPlr)
@@ -8740,7 +8756,7 @@ void Player::RemovedInsignia(Player* looterPlr)
// Now we must make bones lootable, and send player loot
bones->SetCorpseDynamicFlag(CORPSE_DYNFLAG_LOOTABLE);
- bones->m_loot.reset(new Loot(GetMap(), bones->GetGUID(), LOOT_INSIGNIA, looterPlr->GetGroup() ? looterPlr->GetGroup()->GetLootMethod() : FREE_FOR_ALL));
+ bones->m_loot.reset(new Loot(GetMap(), bones->GetGUID(), LOOT_INSIGNIA, looterPlr->GetGroup()));
// For AV Achievement
if (Battleground* bg = GetBattleground())
@@ -8837,7 +8853,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting/* = fa
Group* group = GetGroup();
bool groupRules = (group && go->GetGOInfo()->type == GAMEOBJECT_TYPE_CHEST && go->GetGOInfo()->chest.usegrouplootrules);
- loot = new Loot(GetMap(), guid, loot_type, groupRules ? group->GetLootMethod() : FREE_FOR_ALL);
+ loot = new Loot(GetMap(), guid, loot_type, groupRules ? group : nullptr);
if (go->GetMap()->Is25ManRaid())
loot->maxDuplicates = 3;
@@ -8866,22 +8882,6 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting/* = fa
else if (loot_type == LOOT_FISHING_JUNK)
go->getFishLootJunk(loot, this);
- if (go->GetGOInfo()->type == GAMEOBJECT_TYPE_CHEST && go->GetGOInfo()->chest.usegrouplootrules)
- {
- switch (loot->GetLootMethod())
- {
- case GROUP_LOOT:
- // GroupLoot: rolls items over threshold. Items with quality < threshold, round robin
- group->GroupLoot(loot, go);
- break;
- case MASTER_LOOT:
- group->MasterLoot(loot, go);
- break;
- default:
- break;
- }
- }
-
go->SetLootState(GO_ACTIVATED, this);
}
@@ -8897,6 +8897,9 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting/* = fa
case FREE_FOR_ALL:
permission = ALL_PERMISSION;
break;
+ case ROUND_ROBIN:
+ permission = ROUND_ROBIN_PERMISSION;
+ break;
default:
permission = GROUP_PERMISSION;
break;
@@ -8925,7 +8928,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting/* = fa
if (!item->m_lootGenerated && !sLootItemStorage->LoadStoredLoot(item, this))
{
item->m_lootGenerated = true;
- loot = new Loot(GetMap(), guid, loot_type, FREE_FOR_ALL);
+ loot = new Loot(GetMap(), guid, loot_type, nullptr);
item->m_loot.reset(loot);
switch (loot_type)
@@ -8996,7 +8999,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting/* = fa
{
creature->StartPickPocketRefillTimer();
- loot = new Loot(GetMap(), creature->GetGUID(), LOOT_PICKPOCKETING, FREE_FOR_ALL);
+ loot = new Loot(GetMap(), creature->GetGUID(), LOOT_PICKPOCKETING, nullptr);
creature->m_loot.reset(loot);
if (uint32 lootid = creature->GetCreatureTemplate()->pickpocketLootId)
loot->FillLoot(lootid, LootTemplates_Pickpocketing, this, true);
@@ -9032,26 +9035,6 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting/* = fa
return;
}
- if (loot->loot_type == LOOT_NONE)
- {
- // for creature, loot is filled when creature is killed.
- if (Group* group = creature->GetLootRecipientGroup())
- {
- switch (loot->GetLootMethod())
- {
- case GROUP_LOOT:
- // GroupLoot: rolls items over threshold. Items with quality < threshold, round robin
- group->GroupLoot(loot, creature);
- break;
- case MASTER_LOOT:
- group->MasterLoot(loot, creature);
- break;
- default:
- break;
- }
- }
- }
-
// if loot is already skinning loot then don't do anything else
if (loot->loot_type == LOOT_SKINNING)
{
@@ -9083,6 +9066,9 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting/* = fa
case FREE_FOR_ALL:
permission = ALL_PERMISSION;
break;
+ case ROUND_ROBIN:
+ permission = ROUND_ROBIN_PERMISSION;
+ break;
default:
permission = GROUP_PERMISSION;
break;
@@ -9115,7 +9101,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type, bool aeLooting/* = fa
SendDirectMessage(packet.Write());
// add 'this' player as one of the players that are looting 'loot'
- loot->AddLooter(GetGUID());
+ loot->OnLootOpened(GetMap(), GetGUID());
m_AELootView[loot->GetGUID()] = loot;
if (loot_type == LOOT_CORPSE && !guid.IsItem())
@@ -11367,13 +11353,12 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto, bool skipRequiredL
return EQUIP_ERR_OK;
}
-InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObject const* lootedObject) const
+InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, Map const* map) const
{
if (!GetGroup() || !GetGroup()->isLFGGroup())
return EQUIP_ERR_OK; // not in LFG group
// check if looted object is inside the lfg dungeon
- Map const* map = lootedObject->GetMap();
if (!sLFGMgr->inLfgDungeonMap(GetGroup()->GetGUID(), map->GetId(), map->GetDifficultyID()))
return EQUIP_ERR_OK;
@@ -18197,7 +18182,15 @@ bool Player::isAllowedToLoot(const Creature* creature) const
case MASTER_LOOT:
case FREE_FOR_ALL:
return true;
+ case ROUND_ROBIN:
+ // may only loot if the player is the loot roundrobin player
+ // or if there are free/quest/conditional item for the player
+ if (loot->roundRobinPlayer.IsEmpty() || loot->roundRobinPlayer == GetGUID())
+ return true;
+
+ return loot->hasItemFor(this);
case GROUP_LOOT:
+ case NEED_BEFORE_GREED:
// may only loot if the player is the loot roundrobin player
// or item over threshold (so roll(s) can be launched)
// or if there are free/quest/conditional item for the player
@@ -25574,7 +25567,8 @@ PartyResult Player::CanUninviteFromGroup(ObjectGuid guidMember) const
if (state == lfg::LFG_STATE_FINISHED_DUNGEON)
return ERR_PARTY_LFG_BOOT_DUNGEON_COMPLETE;
- if (grp->isRollLootActive())
+ Player* player = ObjectAccessor::FindConnectedPlayer(guidMember);
+ if (!player->m_lootRolls.empty())
return ERR_PARTY_LFG_BOOT_LOOT_ROLLS;
/// @todo Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer.
@@ -26023,31 +26017,9 @@ void Player::InitRunes()
void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, ItemContext context, bool broadcast, bool createdByPlayer)
{
- Loot loot(nullptr, ObjectGuid::Empty, LOOT_NONE, FREE_FOR_ALL);
+ Loot loot(nullptr, ObjectGuid::Empty, LOOT_NONE, nullptr);
loot.FillLoot(loot_id, store, this, true, false, LOOT_MODE_DEFAULT, context);
-
- uint32 max_slot = loot.GetMaxSlotInLootFor(this);
- for (uint32 i = 0; i < max_slot; ++i)
- {
- LootItem* lootItem = loot.LootItemInSlot(i, this);
-
- ItemPosCountVec dest;
- InventoryResult msg = CanStoreNewItem(bag, slot, dest, lootItem->itemid, lootItem->count);
- if (msg != EQUIP_ERR_OK && slot != NULL_SLOT)
- msg = CanStoreNewItem(bag, NULL_SLOT, dest, lootItem->itemid, lootItem->count);
- if (msg != EQUIP_ERR_OK && bag != NULL_BAG)
- msg = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, lootItem->itemid, lootItem->count);
- if (msg != EQUIP_ERR_OK)
- {
- SendEquipError(msg, nullptr, nullptr, lootItem->itemid);
- continue;
- }
-
- Item* pItem = StoreNewItem(dest, lootItem->itemid, true, lootItem->randomBonusListId, GuidSet(), lootItem->context, lootItem->BonusListIDs);
- SendNewItem(pItem, lootItem->count, false, createdByPlayer, broadcast);
- ApplyItemLootedSpell(pItem, true);
- }
-
+ loot.AutoStore(this, bag, slot, broadcast, createdByPlayer);
Unit::ProcSkillsAndAuras(this, nullptr, PROC_FLAG_LOOTED, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
}
@@ -26141,7 +26113,7 @@ void Player::StoreLootItem(ObjectGuid lootWorldObjectGuid, uint8 lootSlot, Loot*
// LootItem is being removed (looted) from the container, delete it from the DB.
if (loot->loot_type == LOOT_ITEM)
- sLootItemStorage->RemoveStoredLootItemForContainer(lootWorldObjectGuid.GetCounter(), item->itemid, item->count, item->itemIndex);
+ sLootItemStorage->RemoveStoredLootItemForContainer(lootWorldObjectGuid.GetCounter(), item->itemid, item->count, item->LootListId);
ApplyItemLootedSpell(newitem, true);
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 9b52a94a6d0..ce1d2c586f5 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -76,6 +76,7 @@ class Garrison;
class Group;
class Guild;
class Item;
+class LootRoll;
class LootStore;
class OutdoorPvP;
class Pet;
@@ -1401,7 +1402,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
InventoryResult CanUseItem(Item* pItem, bool not_loading = true) const;
bool HasItemTotemCategory(uint32 TotemCategory) const;
InventoryResult CanUseItem(ItemTemplate const* pItem, bool skipRequiredLevelCheck = false) const;
- InventoryResult CanRollForItemInLFG(ItemTemplate const* item, WorldObject const* lootedObject) const;
+ InventoryResult CanRollForItemInLFG(ItemTemplate const* item, Map const* map) const;
Item* StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool update, ItemRandomBonusListId randomBonusListId = 0, GuidSet const& allowedLooters = GuidSet(), ItemContext context = ItemContext::NONE, std::vector<int32> const& bonusListIDs = std::vector<int32>(), bool addToCollection = true);
Item* StoreItem(ItemPosCountVec const& pos, Item* pItem, bool update);
Item* EquipNewItem(uint16 pos, uint32 item, ItemContext context, bool update);
@@ -2064,6 +2065,9 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void SetLootGUID(ObjectGuid const& guid) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::LootTargetGUID), guid); }
Loot* GetLootByWorldObjectGUID(ObjectGuid const& lootWorldObjectGuid) const;
std::unordered_map<ObjectGuid, Loot*> const& GetAELootView() const { return m_AELootView; }
+ LootRoll* GetLootRoll(ObjectGuid const& lootObjectGuid, uint8 lootListId);
+ void AddLootRoll(LootRoll* roll) { m_lootRolls.push_back(roll); }
+ void RemoveLootRoll(LootRoll* roll);
void RemovedInsignia(Player* looterPlr);
@@ -3177,6 +3181,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
SceneMgr m_sceneMgr;
std::unordered_map<ObjectGuid /*LootObject*/, Loot*> m_AELootView;
+ std::vector<LootRoll*> m_lootRolls; // loot rolls waiting for answer
void _InitHonorLevelOnLoadFromDB(uint32 honor, uint32 honorLevel);
std::unique_ptr<RestMgr> _restMgr;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 0faf4a9f7f0..a0d14ec192e 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -46,6 +46,7 @@
#include "InstanceScript.h"
#include "Item.h"
#include "Log.h"
+#include "Loot.h"
#include "LootMgr.h"
#include "LootPackets.h"
#include "MiscPackets.h"
@@ -10660,7 +10661,6 @@ void Unit::SetMeleeAnimKitId(uint16 animKitId)
Player* looter = player;
Group* group = player->GetGroup();
- bool hasLooterGuid = false;
if (group)
{
@@ -10673,10 +10673,7 @@ void Unit::SetMeleeAnimKitId(uint16 animKitId)
{
looter = ObjectAccessor::FindPlayer(group->GetLooterGuid());
if (looter)
- {
- hasLooterGuid = true;
creature->SetLootRecipient(looter); // update creature loot recipient to the allowed looter.
- }
}
}
}
@@ -10686,7 +10683,7 @@ void Unit::SetMeleeAnimKitId(uint16 animKitId)
// Generate loot before updating looter
if (creature)
{
- creature->m_loot.reset(new Loot(creature->GetMap(), creature->GetGUID(), LOOT_CORPSE, group ? group->GetLootMethod() : FREE_FOR_ALL));
+ creature->m_loot.reset(new Loot(creature->GetMap(), creature->GetGUID(), LOOT_CORPSE, group));
Loot* loot = creature->m_loot.get();
if (creature->GetMap()->Is25ManRaid())
loot->maxDuplicates = 3;
@@ -10697,24 +10694,11 @@ void Unit::SetMeleeAnimKitId(uint16 animKitId)
if (creature->GetLootMode() > 0)
loot->generateMoneyLoot(creature->GetCreatureTemplate()->mingold, creature->GetCreatureTemplate()->maxgold);
- if (group)
- {
- if (hasLooterGuid)
- group->SendLooter(creature, looter);
- else
- group->SendLooter(creature, nullptr);
+ loot->NotifyLootList(creature->GetMap());
- // Update round robin looter only if the creature had loot
- if (!loot->empty())
- group->UpdateLooterGuid(creature);
- }
- else
- {
- WorldPackets::Loot::LootList lootList;
- lootList.Owner = creature->GetGUID();
- lootList.LootObj = creature->m_loot->GetGUID();
- player->SendMessageToSet(lootList.Write(), true);
- }
+ // Update round robin looter only if the creature had loot
+ if (group && !loot->empty())
+ group->UpdateLooterGuid(creature);
}
player->RewardPlayerAndGroupAtKill(victim, false);