diff options
| author | Shauren <shauren.trinity@gmail.com> | 2022-09-16 16:58:03 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2022-09-16 16:58:03 +0200 |
| commit | 3ef5079feeedfdafc9d3c1d9f865e96dbc77ecc8 (patch) | |
| tree | c88a3e2c1a8ae8459eb43fa63c66081c37393170 /src/server/game/Entities | |
| parent | 9700b2a78680452d80025121a031da340af51348 (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.cpp | 8 | ||||
| -rw-r--r-- | src/server/game/Entities/Corpse/Corpse.h | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 26 | ||||
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 3 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 17 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 110 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 7 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 28 |
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); |
