aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Groups/Group.cpp
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/Groups/Group.cpp
parent9700b2a78680452d80025121a031da340af51348 (diff)
Core/Loot: Move loot rolls from Group to Loot
* Partial port of cmangos/mangos-wotlk@ffdf9a05d67a04c3c0304e9b021807fa5b867583
Diffstat (limited to 'src/server/game/Groups/Group.cpp')
-rw-r--r--src/server/game/Groups/Group.cpp694
1 files changed, 2 insertions, 692 deletions
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 69c62de6370..127b0dab275 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -28,8 +28,7 @@
#include "Item.h"
#include "LFGMgr.h"
#include "Log.h"
-#include "LootMgr.h"
-#include "LootPackets.h"
+#include "Loot.h"
#include "MapManager.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
@@ -37,34 +36,15 @@
#include "Pet.h"
#include "PhasingHandler.h"
#include "Player.h"
-#include "Random.h"
#include "TerrainMgr.h"
#include "UpdateData.h"
-#include "Util.h"
#include "World.h"
#include "WorldSession.h"
-Roll::Roll(LootItem const& li) : itemid(li.itemid),
-itemRandomBonusListId(li.randomBonusListId), itemCount(li.count),
-totalPlayersRolling(0), totalNeed(0), totalGreed(0), totalPass(0), itemSlot(0),
-rollVoteMask(ROLL_ALL_TYPE_NO_DISENCHANT) { }
-
-Roll::~Roll() { }
-
-void Roll::setLoot(Loot* pLoot)
-{
- link(pLoot, this);
-}
-
-Loot* Roll::getLoot()
-{
- return getTarget();
-}
-
Group::Group() : m_leaderGuid(), m_leaderFactionGroup(0), m_leaderName(""), m_groupFlags(GROUP_FLAG_NONE), m_groupCategory(GROUP_CATEGORY_HOME),
m_dungeonDifficulty(DIFFICULTY_NORMAL), m_raidDifficulty(DIFFICULTY_NORMAL_RAID), m_legacyRaidDifficulty(DIFFICULTY_10_N),
m_bgGroup(nullptr), m_bfGroup(nullptr), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(),
-m_masterLooterGuid(), m_subGroupsCounts(nullptr), m_guid(), m_maxEnchantingLevel(0), m_dbStoreId(0), m_isLeaderOffline(false),
+m_masterLooterGuid(), m_subGroupsCounts(nullptr), m_guid(), m_dbStoreId(0), m_isLeaderOffline(false),
m_readyCheckStarted(false), m_readyCheckTimer(Milliseconds::zero()), m_activeMarkers(0)
{
for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i)
@@ -86,14 +66,6 @@ Group::~Group()
else
TC_LOG_ERROR("misc", "Group::~Group: battleground group is not linked to the correct battleground.");
}
- Rolls::iterator itr;
- while (!RollId.empty())
- {
- itr = RollId.begin();
- Roll *r = *itr;
- RollId.erase(itr);
- delete(r);
- }
// this may unload some instance saves
for (auto difficultyItr = m_boundInstances.begin(); difficultyItr != m_boundInstances.end(); ++difficultyItr)
@@ -584,9 +556,6 @@ bool Group::AddMember(Player* player)
}
}
- if (m_maxEnchantingLevel < player->GetSkillValue(SKILL_ENCHANTING))
- m_maxEnchantingLevel = player->GetSkillValue(SKILL_ENCHANTING);
-
return true;
}
@@ -653,37 +622,6 @@ bool Group::RemoveMember(ObjectGuid guid, RemoveMethod method /*= GROUP_REMOVEME
DelinkMember(guid);
}
- // Reevaluate group enchanter if the leaving player had enchanting skill or the player is offline
- if (!player || player->GetSkillValue(SKILL_ENCHANTING))
- ResetMaxEnchantingLevel();
-
- // Remove player from loot rolls
- for (Rolls::iterator it = RollId.begin(); it != RollId.end(); ++it)
- {
- Roll* roll = *it;
- Roll::PlayerVote::iterator itr2 = roll->playerVote.find(guid);
- if (itr2 == roll->playerVote.end())
- continue;
-
- if (itr2->second == GREED || itr2->second == DISENCHANT)
- --roll->totalGreed;
- else if (itr2->second == NEED)
- --roll->totalNeed;
- else if (itr2->second == PASS)
- --roll->totalPass;
-
- if (itr2->second != NOT_VALID)
- --roll->totalPlayersRolling;
-
- roll->playerVote.erase(itr2);
-
- if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling)
- {
- CountTheRoll(it, nullptr);
- it = RollId.begin();
- }
- }
-
// Update subgroups
member_witerator slot = _getMemberWSlot(guid);
if (slot != m_memberSlots.end())
@@ -914,571 +852,6 @@ void Group::Disband(bool hideDestroy /* = false */)
delete this;
}
-/*********************************************************/
-/*** LOOT SYSTEM ***/
-/*********************************************************/
-void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r) const
-{
- WorldPackets::Loot::StartLootRoll startLootRoll;
- startLootRoll.LootObj = r->GetGUID();
- startLootRoll.MapID = mapId;
- startLootRoll.RollTime = countDown;
- startLootRoll.ValidRolls = r.rollVoteMask;
- if (!canNeed)
- startLootRoll.ValidRolls &= ~ROLL_FLAG_TYPE_NEED;
- startLootRoll.Method = GetLootMethod();
- r.FillPacket(startLootRoll.Item);
-
- if (ItemDisenchantLootEntry const* disenchant = r.GetItemDisenchantLoot(p))
- if (m_maxEnchantingLevel >= disenchant->SkillRequired)
- startLootRoll.ValidRolls |= ROLL_FLAG_TYPE_DISENCHANT;
-
- p->SendDirectMessage(startLootRoll.Write());
-}
-
-void Group::SendLootRoll(ObjectGuid playerGuid, int32 rollNumber, uint8 rollType, Roll const& roll, bool autoPass) const
-{
- WorldPackets::Loot::LootRollBroadcast lootRoll;
- lootRoll.LootObj = roll->GetGUID();
- lootRoll.Player = playerGuid;
- lootRoll.Roll = rollNumber;
- lootRoll.RollType = rollType;
- lootRoll.Autopassed = autoPass;
- roll.FillPacket(lootRoll.Item);
- lootRoll.Write();
-
- for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
- {
- Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
- if (!p || !p->GetSession())
- continue;
-
- if (itr->second != NOT_VALID)
- p->SendDirectMessage(lootRoll.GetRawPacket());
- }
-}
-
-void Group::SendLootRollWon(ObjectGuid winnerGuid, int32 rollNumber, uint8 rollType, Roll const& roll) const
-{
- WorldPackets::Loot::LootRollWon lootRollWon;
- lootRollWon.LootObj = roll->GetGUID();
- lootRollWon.Winner = winnerGuid;
- lootRollWon.Roll = rollNumber;
- lootRollWon.RollType = rollType;
- roll.FillPacket(lootRollWon.Item);
- lootRollWon.MainSpec = true; // offspec rolls not implemented
- lootRollWon.Write();
-
- for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
- {
- Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
- if (!p || !p->GetSession())
- continue;
-
- if (itr->second != NOT_VALID)
- p->SendDirectMessage(lootRollWon.GetRawPacket());
- }
-}
-
-void Group::SendLootAllPassed(Roll const& roll) const
-{
- WorldPackets::Loot::LootAllPassed lootAllPassed;
- lootAllPassed.LootObj = roll->GetGUID();
- roll.FillPacket(lootAllPassed.Item);
- lootAllPassed.Write();
-
- for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
- {
- Player* player = ObjectAccessor::FindConnectedPlayer(itr->first);
- if (!player || !player->GetSession())
- continue;
-
- if (itr->second != NOT_VALID)
- player->SendDirectMessage(lootAllPassed.GetRawPacket());
- }
-}
-
-void Group::SendLootRollsComplete(Roll const& roll) const
-{
- WorldPackets::Loot::LootRollsComplete lootRollsComplete;
- lootRollsComplete.LootObj = roll->GetGUID();
- lootRollsComplete.LootListID = roll.itemSlot + 1;
- lootRollsComplete.Write();
-
- for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
- {
- Player* player = ObjectAccessor::FindConnectedPlayer(itr->first);
- if (!player || !player->GetSession())
- continue;
-
- if (itr->second != NOT_VALID)
- player->SendDirectMessage(lootRollsComplete.GetRawPacket());
- }
-}
-
-// notify group members which player is the allowed looter for the given creature
-void Group::SendLooter(Creature* creature, Player* groupLooter)
-{
- ASSERT(creature);
-
- WorldPackets::Loot::LootList lootList;
-
- lootList.Owner = creature->GetGUID();
- lootList.LootObj = creature->m_loot->GetGUID();
-
- if (creature->m_loot->GetLootMethod() == MASTER_LOOT && creature->m_loot->hasOverThresholdItem())
- lootList.Master = GetMasterLooterGuid();
-
- if (groupLooter)
- lootList.RoundRobinWinner = groupLooter->GetGUID();
-
- BroadcastPacket(lootList.Write(), false);
-}
-
-bool CanRollOnItem(const LootItem& item, Player const* player)
-{
- // Players can't roll on unique items if they already reached the maximum quantity of that item
- ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid);
- if (!proto)
- return false;
-
- uint32 itemCount = player->GetItemCount(item.itemid);
- if (proto->GetMaxCount() > 0 && itemCount >= proto->GetMaxCount())
- return false;
-
- if (!item.AllowedForPlayer(player))
- return false;
-
- return true;
-}
-
-void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
-{
- ItemTemplate const* item;
- uint8 itemSlot = 0;
- for (std::vector<LootItem>::iterator i = loot->items.begin(); i != loot->items.end(); ++i, ++itemSlot)
- {
- if (i->freeforall)
- continue;
-
- item = ASSERT_NOTNULL(sObjectMgr->GetItemTemplate(i->itemid));
- ASSERT(item);
-
- //roll for over-threshold item if it's one-player loot
- if (item->GetQuality() >= uint32(m_lootThreshold))
- {
- Roll* r = new Roll(*i);
-
- for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
- {
- Player* playerToRoll = itr->GetSource();
- if (!playerToRoll || !playerToRoll->GetSession())
- continue;
-
- if (playerToRoll->IsAtGroupRewardDistance(lootedObject))
- {
- r->totalPlayersRolling++;
- RollVote vote = playerToRoll->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET;
- if (!CanRollOnItem(*i, playerToRoll))
- {
- vote = PASS;
- r->totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known
- }
- r->playerVote[playerToRoll->GetGUID()] = vote;
- }
- }
-
- if (r->totalPlayersRolling > 0)
- {
- r->setLoot(loot);
- r->itemSlot = itemSlot;
- if (item->HasFlag(ITEM_FLAG2_CAN_ONLY_ROLL_GREED))
- r->rollVoteMask &= ~ROLL_FLAG_TYPE_NEED;
-
- loot->items[itemSlot].is_blocked = true;
-
- //Broadcast Pass and Send Rollstart
- for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
- {
- Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
- if (!p || !p->GetSession())
- continue;
-
- if (itr->second == PASS)
- SendLootRoll(p->GetGUID(), -1, ROLL_PASS, *r, true);
- else
- SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
- }
-
- RollId.push_back(r);
-
- if (Creature* creature = lootedObject->ToCreature())
- {
- creature->m_groupLootTimer = 60000;
- creature->lootingGroupLowGUID = GetGUID();
- }
- else if (GameObject* go = lootedObject->ToGameObject())
- {
- go->m_groupLootTimer = 60000;
- go->lootingGroupLowGUID = GetGUID();
- }
- }
- else
- delete r;
- }
- else
- i->is_underthreshold = true;
- }
-
- for (std::vector<LootItem>::iterator i = loot->quest_items.begin(); i != loot->quest_items.end(); ++i, ++itemSlot)
- {
- if (!i->follow_loot_rules)
- continue;
-
- item = sObjectMgr->GetItemTemplate(i->itemid);
- Roll* r = new Roll(*i);
-
- for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
- {
- Player* playerToRoll = itr->GetSource();
- if (!playerToRoll || !playerToRoll->GetSession())
- continue;
-
- if (playerToRoll->IsAtGroupRewardDistance(lootedObject))
- {
- r->totalPlayersRolling++;
- RollVote vote = NOT_EMITED_YET;
- if (!CanRollOnItem(*i, playerToRoll))
- {
- vote = PASS;
- ++r->totalPass;
- }
- r->playerVote[playerToRoll->GetGUID()] = vote;
- }
- }
-
- if (r->totalPlayersRolling > 0)
- {
- r->setLoot(loot);
- r->itemSlot = itemSlot;
-
- loot->quest_items[itemSlot - loot->items.size()].is_blocked = true;
-
- //Broadcast Pass and Send Rollstart
- for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
- {
- Player* p = ObjectAccessor::FindConnectedPlayer(itr->first);
- if (!p || !p->GetSession())
- continue;
-
- if (itr->second == PASS)
- SendLootRoll(p->GetGUID(), -1, ROLL_PASS, *r, true);
- else
- SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
- }
-
- RollId.push_back(r);
-
- if (Creature* creature = lootedObject->ToCreature())
- {
- creature->m_groupLootTimer = 60000;
- creature->lootingGroupLowGUID = GetGUID();
- }
- else if (GameObject* go = lootedObject->ToGameObject())
- {
- go->m_groupLootTimer = 60000;
- go->lootingGroupLowGUID = GetGUID();
- }
- }
- else
- delete r;
- }
-}
-
-void Group::MasterLoot(Loot* loot, WorldObject* pLootedObject)
-{
- TC_LOG_DEBUG("network", "Group::MasterLoot (SMSG_MASTER_LOOT_CANDIDATE_LIST)");
-
- for (std::vector<LootItem>::iterator i = loot->items.begin(); i != loot->items.end(); ++i)
- {
- if (i->freeforall)
- continue;
-
- i->is_blocked = !i->is_underthreshold;
- }
-
- for (std::vector<LootItem>::iterator i = loot->quest_items.begin(); i != loot->quest_items.end(); ++i)
- {
- if (!i->follow_loot_rules)
- continue;
-
- i->is_blocked = !i->is_underthreshold;
- }
-
- WorldPackets::Loot::MasterLootCandidateList masterLootCandidateList;
- masterLootCandidateList.LootObj = loot->GetGUID();
-
- for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
- {
- Player* looter = itr->GetSource();
- if (!looter->IsInWorld())
- continue;
-
- if (looter->IsAtGroupRewardDistance(pLootedObject))
- masterLootCandidateList.Players.push_back(looter->GetGUID());
- }
-
- masterLootCandidateList.Write();
-
- for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
- {
- Player* looter = itr->GetSource();
- if (looter->IsAtGroupRewardDistance(pLootedObject))
- looter->SendDirectMessage(masterLootCandidateList.GetRawPacket());
- }
-}
-
-void Group::CountRollVote(ObjectGuid playerGuid, ObjectGuid lootObjectGuid, uint8 lootListId, uint8 choice)
-{
- Rolls::iterator rollI = GetRoll(lootObjectGuid, lootListId);
- if (rollI == RollId.end())
- return;
- Roll* roll = *rollI;
-
- Roll::PlayerVote::iterator itr = roll->playerVote.find(playerGuid);
- // this condition means that player joins to the party after roll begins
- if (itr == roll->playerVote.end())
- return;
-
- if (roll->getLoot())
- if (roll->getLoot()->items.empty())
- return;
-
- switch (choice)
- {
- case ROLL_PASS: // Player choose pass
- SendLootRoll(playerGuid, -1, ROLL_PASS, *roll);
- ++roll->totalPass;
- itr->second = PASS;
- break;
- case ROLL_NEED: // player choose Need
- SendLootRoll(playerGuid, 0, ROLL_NEED, *roll);
- ++roll->totalNeed;
- itr->second = NEED;
- break;
- case ROLL_GREED: // player choose Greed
- SendLootRoll(playerGuid, -7, ROLL_GREED, *roll);
- ++roll->totalGreed;
- itr->second = GREED;
- break;
- case ROLL_DISENCHANT: // player choose Disenchant
- SendLootRoll(playerGuid, -8, ROLL_DISENCHANT, *roll);
- ++roll->totalGreed;
- itr->second = DISENCHANT;
- break;
- }
-
- if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling)
- CountTheRoll(rollI, nullptr);
-}
-
-//called when roll timer expires
-void Group::EndRoll(Loot* pLoot, Map* allowedMap)
-{
- for (Rolls::iterator itr = RollId.begin(); itr != RollId.end();)
- {
- if ((*itr)->getLoot() == pLoot)
- {
- CountTheRoll(itr, allowedMap); //i don't have to edit player votes, who didn't vote ... he will pass
- itr = RollId.begin();
- }
- else
- ++itr;
- }
-}
-
-void Group::CountTheRoll(Rolls::iterator rollI, Map* allowedMap)
-{
- Roll* roll = *rollI;
- if (!roll->isValid()) // is loot already deleted ?
- {
- RollId.erase(rollI);
- delete roll;
- return;
- }
-
- //end of the roll
- if (roll->totalNeed > 0)
- {
- if (!roll->playerVote.empty())
- {
- uint8 maxresul = 0;
- ObjectGuid maxguid = ObjectGuid::Empty;
- Player* player = nullptr;
-
- for (Roll::PlayerVote::const_iterator itr = roll->playerVote.begin(); itr != roll->playerVote.end(); ++itr)
- {
- if (itr->second != NEED)
- continue;
-
- player = ObjectAccessor::FindPlayer(itr->first);
- if (!player || (allowedMap != nullptr && player->FindMap() != allowedMap))
- {
- --roll->totalNeed;
- continue;
- }
-
- uint8 randomN = urand(1, 100);
- SendLootRoll(itr->first, randomN, ROLL_NEED, *roll);
- if (maxresul < randomN)
- {
- maxguid = itr->first;
- maxresul = randomN;
- }
- }
-
- if (!maxguid.IsEmpty())
- {
- SendLootRollWon(maxguid, maxresul, ROLL_NEED, *roll);
- player = ObjectAccessor::FindConnectedPlayer(maxguid);
-
- if (player && player->GetSession())
- {
- player->UpdateCriteria(CriteriaType::RollNeed, roll->itemid, maxresul);
-
- ItemPosCountVec dest;
- LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
- InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
- if (msg == EQUIP_ERR_OK)
- {
- item->is_looted = true;
- roll->getLoot()->NotifyItemRemoved(roll->itemSlot, allowedMap);
- roll->getLoot()->unlootedCount--;
- player->StoreNewItem(dest, roll->itemid, true, item->randomBonusListId, item->GetAllowedLooters(), item->context, item->BonusListIDs);
- }
- else
- {
- item->is_blocked = false;
- item->rollWinnerGUID = player->GetGUID();
- player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
- }
- }
- }
- else
- roll->totalNeed = 0;
- }
- }
-
- if (roll->totalNeed == 0 && roll->totalGreed > 0) // if (roll->totalNeed == 0 && ...), not else if, because numbers can be modified above if player is on a different map
- {
- if (!roll->playerVote.empty())
- {
- uint8 maxresul = 0;
- ObjectGuid maxguid = ObjectGuid::Empty;
- Player* player = nullptr;
- RollVote rollvote = NOT_VALID;
-
- Roll::PlayerVote::iterator itr;
- for (itr = roll->playerVote.begin(); itr != roll->playerVote.end(); ++itr)
- {
- if (itr->second != GREED && itr->second != DISENCHANT)
- continue;
-
- player = ObjectAccessor::FindPlayer(itr->first);
- if (!player || (allowedMap != nullptr && player->FindMap() != allowedMap))
- {
- --roll->totalGreed;
- continue;
- }
-
- uint8 randomN = urand(1, 100);
- SendLootRoll(itr->first, randomN, itr->second, *roll);
- if (maxresul < randomN)
- {
- maxguid = itr->first;
- maxresul = randomN;
- rollvote = itr->second;
- }
- }
-
- if (!maxguid.IsEmpty())
- {
- SendLootRollWon(maxguid, maxresul, rollvote, *roll);
- player = ObjectAccessor::FindConnectedPlayer(maxguid);
-
- if (player && player->GetSession())
- {
- player->UpdateCriteria(CriteriaType::RollGreed, roll->itemid, maxresul);
-
- LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
-
- if (rollvote == GREED)
- {
- ItemPosCountVec dest;
- InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
- if (msg == EQUIP_ERR_OK)
- {
- item->is_looted = true;
- roll->getLoot()->NotifyItemRemoved(roll->itemSlot, allowedMap);
- roll->getLoot()->unlootedCount--;
- player->StoreNewItem(dest, roll->itemid, true, item->randomBonusListId, item->GetAllowedLooters(), item->context, item->BonusListIDs);
- }
- else
- {
- item->is_blocked = false;
- item->rollWinnerGUID = player->GetGUID();
- player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
- }
- }
- else if (rollvote == DISENCHANT)
- {
- item->is_looted = true;
- roll->getLoot()->NotifyItemRemoved(roll->itemSlot, allowedMap);
- roll->getLoot()->unlootedCount--;
- player->UpdateCriteria(CriteriaType::CastSpell, 13262); // Disenchant
-
- ItemDisenchantLootEntry const* disenchant = ASSERT_NOTNULL(roll->GetItemDisenchantLoot(player));
-
- ItemPosCountVec dest;
- InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
- if (msg == EQUIP_ERR_OK)
- player->AutoStoreLoot(disenchant->ID, LootTemplates_Disenchant, ItemContext::NONE, true);
- else // If the player's inventory is full, send the disenchant result in a mail.
- {
- Loot loot(allowedMap, roll->getLoot()->GetOwnerGUID(), LOOT_DISENCHANTING, roll->getLoot()->GetLootMethod());
- loot.FillLoot(disenchant->ID, LootTemplates_Disenchant, player, true);
-
- uint32 max_slot = loot.GetMaxSlotInLootFor(player);
- for (uint32 i = 0; i < max_slot; ++i)
- {
- LootItem* lootItem = loot.LootItemInSlot(i, player);
- player->SendEquipError(msg, nullptr, nullptr, lootItem->itemid);
- player->SendItemRetrievalMail(lootItem->itemid, lootItem->count, lootItem->context);
- }
- }
- }
- }
- }
- else
- roll->totalGreed = 0;
- }
- }
-
- if (roll->totalNeed == 0 && roll->totalGreed == 0) // if, not else, because numbers can be modified above if player is on a different map
- {
- SendLootAllPassed(*roll);
-
- // remove is_blocked so that the item is lootable by all players
- LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
- item->is_blocked = false;
- }
-
- SendLootRollsComplete(*roll);
-
- RollId.erase(rollI);
- delete roll;
-}
-
void Group::SetTargetIcon(uint8 symbol, ObjectGuid target, ObjectGuid changedBy, uint8 partyIndex)
{
if (symbol >= TARGET_ICONS_COUNT)
@@ -1965,48 +1338,6 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
return ERR_BATTLEGROUND_NONE;
}
-//===================================================
-//============== Roll ===============================
-//===================================================
-
-void Roll::targetObjectBuildLink()
-{
- // called from link()
- getTarget()->addLootValidatorRef(this);
-}
-
-void Roll::FillPacket(WorldPackets::Loot::LootItemData& lootItem) const
-{
- lootItem.UIType = (totalPlayersRolling > totalNeed + totalGreed + totalPass) ? LOOT_SLOT_TYPE_ROLL_ONGOING : LOOT_SLOT_TYPE_ALLOW_LOOT;
- lootItem.Quantity = itemCount;
- lootItem.LootListID = itemSlot + 1;
- if (LootItem const* lootItemInSlot = (*this)->GetItemInSlot(itemSlot))
- {
- lootItem.CanTradeToTapList = lootItemInSlot->allowedGUIDs.size() > 1;
- lootItem.Loot.Initialize(*lootItemInSlot);
- }
-}
-
-ItemDisenchantLootEntry const* Roll::GetItemDisenchantLoot(Player const* player) const
-{
- if (LootItem const* lootItemInSlot = (*this)->GetItemInSlot(itemSlot))
- {
- WorldPackets::Item::ItemInstance itemInstance;
- itemInstance.Initialize(*lootItemInSlot);
-
- BonusData bonusData;
- bonusData.Initialize(itemInstance);
- if (!bonusData.CanDisenchant)
- return nullptr;
-
- ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemid);
- uint32 itemLevel = Item::GetItemLevel(itemTemplate, bonusData, player->GetLevel(), 0, 0, 0, 0, false, 0);
- return Item::GetDisenchantLoot(itemTemplate, bonusData.Quality, itemLevel);
- }
-
- return nullptr;
-}
-
void Group::SetDungeonDifficultyID(Difficulty difficulty)
{
m_dungeonDifficulty = difficulty;
@@ -2343,18 +1674,6 @@ void Group::BroadcastGroupUpdate(void)
}
}
-void Group::ResetMaxEnchantingLevel()
-{
- m_maxEnchantingLevel = 0;
- Player* member = nullptr;
- for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
- {
- member = ObjectAccessor::FindPlayer(citr->guid);
- if (member && m_maxEnchantingLevel < member->GetSkillValue(SKILL_ENCHANTING))
- m_maxEnchantingLevel = member->GetSkillValue(SKILL_ENCHANTING);
- }
-}
-
void Group::SetLootMethod(LootMethod method)
{
m_lootMethod = method;
@@ -2711,15 +2030,6 @@ void Group::SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags fla
SendUpdate();
}
-Group::Rolls::iterator Group::GetRoll(ObjectGuid lootObjectGuid, uint8 lootListId)
-{
- for (Rolls::iterator iter = RollId.begin(); iter != RollId.end(); ++iter)
- if ((*iter)->isValid() && (**iter)->GetGUID() == lootObjectGuid && (*iter)->itemSlot == lootListId)
- return iter;
-
- return RollId.end();
-}
-
void Group::LinkMember(GroupReference* pRef)
{
m_memberMgr.insertFirst(pRef);