aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Groups/Group.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Groups/Group.cpp')
-rw-r--r--src/server/game/Groups/Group.cpp205
1 files changed, 100 insertions, 105 deletions
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index d855776fa3a..947c54357c8 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -38,7 +38,7 @@
#include "PartyPackets.h"
#include "LootPackets.h"
-Roll::Roll(ObjectGuid _guid, LootItem const& li) : itemGUID(_guid), itemid(li.itemid),
+Roll::Roll(LootItem const& li) : itemid(li.itemid),
itemRandomPropId(li.randomPropertyId), itemRandomSuffix(li.randomSuffix), itemCount(li.count),
totalPlayersRolling(0), totalNeed(0), totalGreed(0), totalPass(0), itemSlot(0),
rollVoteMask(ROLL_ALL_TYPE_NO_DISENCHANT) { }
@@ -598,7 +598,11 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R
roll->playerVote.erase(itr2);
- CountRollVote(guid, roll->itemGUID, MAX_ROLL_TYPE);
+ if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling)
+ {
+ CountTheRoll(it);
+ it = RollId.begin();
+ }
}
// Update subgroups
@@ -785,12 +789,8 @@ void Group::Disband(bool hideDestroy /* = false */)
if (!player->GetSession())
continue;
- WorldPacket data;
if (!hideDestroy)
- {
- data.Initialize(SMSG_GROUP_DESTROYED, 0);
- player->GetSession()->SendPacket(&data);
- }
+ player->SendDirectMessage(WorldPackets::Party::GroupDestroyed().Write());
//we already removed player from group and in player->GetGroup() is his original group, send update
if (Group* group = player->GetGroup())
@@ -799,10 +799,14 @@ void Group::Disband(bool hideDestroy /* = false */)
}
else
{
- data.Initialize(SMSG_PARTY_UPDATE, 1+1+1+1+8+4+4+8);
- data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0);
- data << m_guid << uint32(m_counter) << uint32(0) << uint64(0);
- player->GetSession()->SendPacket(&data);
+ WorldPackets::Party::PartyUpdate partyUpdate;
+ partyUpdate.PartyFlags = GROUP_FLAG_DESTROYED;
+ partyUpdate.PartyIndex = 1; // 0 = original group, 1 = instance/bg group
+ partyUpdate.PartyType = GROUP_TYPE_NONE;
+ partyUpdate.PartyGUID = m_guid;
+ partyUpdate.MyIndex = -1;
+ partyUpdate.SequenceNum = m_counter;
+ player->GetSession()->SendPacket(partyUpdate.Write());
}
_homebindIfInstance(player);
@@ -844,67 +848,52 @@ void Group::Disband(bool hideDestroy /* = false */)
/*********************************************************/
/*** 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);
+
+ p->GetSession()->SendPacket(startLootRoll.Write());
+}
-void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r)
+void Group::SendLootRoll(ObjectGuid playerGuid, int32 rollNumber, uint8 rollType, Roll const& roll) const
{
- WorldPacket data(SMSG_START_LOOT_ROLL, (8+4+4+4+4+4+4+1));
- data << r.itemGUID; // guid of rolled item
- data << uint32(mapid); // 3.3.3 mapid
- data << uint32(r.itemSlot); // itemslot
- data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
- data << uint32(r.itemRandomSuffix); // randomSuffix
- data << uint32(r.itemRandomPropId.Id); // item random property ID
- data << uint32(r.itemCount); // items in stack
- data << uint32(countDown); // the countdown time to choose "need" or "greed"
- data << uint8(r.rollVoteMask); // roll type mask
- data << uint8(r.totalPlayersRolling); // maybe the number of players rolling for it???
+ WorldPackets::Loot::LootRollBroadcast lootRoll;
+ lootRoll.LootObj = roll->GetGUID();
+ lootRoll.Player = playerGuid;
+ lootRoll.Roll = rollNumber;
+ lootRoll.RollType = rollType;
+ roll.FillPacket(lootRoll.Item);
+ lootRoll.Write();
- for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
+ 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_EMITED_YET)
- p->GetSession()->SendPacket(&data);
+ if (itr->second != NOT_VALID)
+ p->GetSession()->SendPacket(lootRoll.GetRawPacket());
}
}
-void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r)
+void Group::SendLootRollWon(ObjectGuid winnerGuid, int32 rollNumber, uint8 rollType, Roll const& roll) const
{
- if (!p || !p->GetSession())
- return;
-
- WorldPacket data(SMSG_START_LOOT_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1));
- data << r.itemGUID; // guid of rolled item
- data << uint32(mapId); // 3.3.3 mapid
- data << uint32(r.itemSlot); // itemslot
- data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
- data << uint32(r.itemRandomSuffix); // randomSuffix
- data << uint32(r.itemRandomPropId.Id); // item random property ID
- data << uint32(r.itemCount); // items in stack
- data << uint32(countDown); // the countdown time to choose "need" or "greed"
- uint8 voteMask = r.rollVoteMask;
- if (!canNeed)
- voteMask &= ~ROLL_FLAG_TYPE_NEED;
- data << uint8(voteMask); // roll type mask
- data << uint8(r.totalPlayersRolling); // maybe the number of players rolling for it???
-
- p->GetSession()->SendPacket(&data);
-}
-
-void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll)
-{
- WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1+1));
- data << sourceGuid; // guid of the item rolled
- data << uint32(roll.itemSlot); // slot
- data << targetGuid;
- data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
- data << uint32(roll.itemRandomSuffix); // randomSuffix
- data << uint32(roll.itemRandomPropId.Id); // Item random property ID
- data << uint32(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number
- data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll
- data << uint8(0); // 1: "You automatically passed on: %s because you cannot loot that item." - Possibly used in need befor greed
+ 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)
{
@@ -913,41 +902,34 @@ void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rol
continue;
if (itr->second != NOT_VALID)
- p->GetSession()->SendPacket(&data);
+ p->GetSession()->SendPacket(lootRollWon.GetRawPacket());
}
}
-void Group::SendLootRollWon(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll)
+void Group::SendLootAllPassed(Roll const& roll) const
{
- WorldPacket data(SMSG_LOOT_ROLL_WON, (8+4+4+4+4+8+1+1));
- data << sourceGuid; // guid of the item rolled
- data << uint32(roll.itemSlot); // slot
- data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
- data << uint32(roll.itemRandomSuffix); // randomSuffix
- data << uint32(roll.itemRandomPropId.Id); // Item random property
- data << targetGuid; // guid of the player who won.
- data << uint32(rollNumber); // rollnumber realted to SMSG_LOOT_ROLL
- data << uint8(rollType); // rollType related to SMSG_LOOT_ROLL
+ 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* p = ObjectAccessor::FindConnectedPlayer(itr->first);
- if (!p || !p->GetSession())
+ Player* player = ObjectAccessor::FindConnectedPlayer(itr->first);
+ if (!player || !player->GetSession())
continue;
if (itr->second != NOT_VALID)
- p->GetSession()->SendPacket(&data);
+ player->GetSession()->SendPacket(lootAllPassed.GetRawPacket());
}
}
-void Group::SendLootAllPassed(Roll const& roll)
+void Group::SendLootRollsComplete(Roll const& roll) const
{
- WorldPacket data(SMSG_LOOT_ALL_PASSED, (8+4+4+4+4));
- data << roll.itemGUID; // Guid of the item rolled
- data << uint32(roll.itemSlot); // Item loot slot
- data << uint32(roll.itemid); // The itemEntryId for the item that shall be rolled for
- data << uint32(roll.itemRandomPropId.Id); // Item random property ID
- data << uint32(roll.itemRandomSuffix); // Item random suffix ID
+ 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)
{
@@ -956,7 +938,7 @@ void Group::SendLootAllPassed(Roll const& roll)
continue;
if (itr->second != NOT_VALID)
- player->GetSession()->SendPacket(&data);
+ player->GetSession()->SendPacket(lootRollsComplete.GetRawPacket());
}
}
@@ -992,8 +974,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
//roll for over-threshold item if it's one-player loot
if (item->GetQuality() >= uint32(m_lootThreshold))
{
- ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate());
- Roll* r = new Roll(newitemGUID, *i);
+ Roll* r = new Roll(*i);
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
@@ -1036,7 +1017,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
continue;
if (itr->second == PASS)
- SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r);
+ SendLootRoll(p->GetGUID(), -1, ROLL_PASS, *r);
else
SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
}
@@ -1067,8 +1048,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
continue;
item = sObjectMgr->GetItemTemplate(i->itemid);
- ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate());
- Roll* r = new Roll(newitemGUID, *i);
+ Roll* r = new Roll(*i);
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
@@ -1099,7 +1079,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
continue;
if (itr->second == PASS)
- SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r);
+ SendLootRoll(p->GetGUID(), -1, ROLL_PASS, *r);
else
SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
}
@@ -1170,14 +1150,14 @@ void Group::MasterLoot(Loot* loot, WorldObject* pLootedObject)
}
}
-void Group::CountRollVote(ObjectGuid playerGUID, ObjectGuid Guid, uint8 Choice)
+void Group::CountRollVote(ObjectGuid playerGuid, ObjectGuid lootObjectGuid, uint8 lootListId, uint8 choice)
{
- Rolls::iterator rollI = GetRoll(Guid);
+ Rolls::iterator rollI = GetRoll(lootObjectGuid, lootListId);
if (rollI == RollId.end())
return;
Roll* roll = *rollI;
- Roll::PlayerVote::iterator itr = roll->playerVote.find(playerGUID);
+ 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;
@@ -1186,25 +1166,25 @@ void Group::CountRollVote(ObjectGuid playerGUID, ObjectGuid Guid, uint8 Choice)
if (roll->getLoot()->items.empty())
return;
- switch (Choice)
+ switch (choice)
{
case ROLL_PASS: // Player choose pass
- SendLootRoll(ObjectGuid::Empty, playerGUID, 128, ROLL_PASS, *roll);
+ SendLootRoll(playerGuid, -1, ROLL_PASS, *roll);
++roll->totalPass;
itr->second = PASS;
break;
case ROLL_NEED: // player choose Need
- SendLootRoll(ObjectGuid::Empty, playerGUID, 0, 0, *roll);
+ SendLootRoll(playerGuid, 0, ROLL_NEED, *roll);
++roll->totalNeed;
itr->second = NEED;
break;
case ROLL_GREED: // player choose Greed
- SendLootRoll(ObjectGuid::Empty, playerGUID, 128, ROLL_GREED, *roll);
+ SendLootRoll(playerGuid, -7, ROLL_GREED, *roll);
++roll->totalGreed;
itr->second = GREED;
break;
case ROLL_DISENCHANT: // player choose Disenchant
- SendLootRoll(ObjectGuid::Empty, playerGUID, 128, ROLL_DISENCHANT, *roll);
+ SendLootRoll(playerGuid, -8, ROLL_DISENCHANT, *roll);
++roll->totalGreed;
itr->second = DISENCHANT;
break;
@@ -1219,7 +1199,8 @@ void Group::EndRoll(Loot* pLoot)
{
for (Rolls::iterator itr = RollId.begin(); itr != RollId.end();)
{
- if ((*itr)->getLoot() == pLoot) {
+ if ((*itr)->getLoot() == pLoot)
+ {
CountTheRoll(itr); //i don't have to edit player votes, who didn't vote ... he will pass
itr = RollId.begin();
}
@@ -1253,14 +1234,14 @@ void Group::CountTheRoll(Rolls::iterator rollI)
continue;
uint8 randomN = urand(1, 100);
- SendLootRoll(ObjectGuid::Empty, itr->first, randomN, ROLL_NEED, *roll);
+ SendLootRoll(itr->first, randomN, ROLL_NEED, *roll);
if (maxresul < randomN)
{
maxguid = itr->first;
maxresul = randomN;
}
}
- SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, ROLL_NEED, *roll);
+ SendLootRollWon(maxguid, maxresul, ROLL_NEED, *roll);
player = ObjectAccessor::FindConnectedPlayer(maxguid);
if (player && player->GetSession())
@@ -1301,7 +1282,7 @@ void Group::CountTheRoll(Rolls::iterator rollI)
continue;
uint8 randomN = urand(1, 100);
- SendLootRoll(ObjectGuid::Empty, itr->first, randomN, itr->second, *roll);
+ SendLootRoll(itr->first, randomN, itr->second, *roll);
if (maxresul < randomN)
{
maxguid = itr->first;
@@ -1309,7 +1290,7 @@ void Group::CountTheRoll(Rolls::iterator rollI)
rollvote = itr->second;
}
}
- SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, rollvote, *roll);
+ SendLootRollWon(maxguid, maxresul, rollvote, *roll);
player = ObjectAccessor::FindConnectedPlayer(maxguid);
if (player && player->GetSession())
@@ -1374,6 +1355,8 @@ void Group::CountTheRoll(Rolls::iterator rollI)
item->is_blocked = false;
}
+ SendLootRollsComplete(*roll);
+
RollId.erase(rollI);
delete roll;
}
@@ -1862,6 +1845,18 @@ void Roll::targetObjectBuildLink()
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);
+ }
+}
+
void Group::SetDungeonDifficultyID(Difficulty difficulty)
{
m_dungeonDifficulty = difficulty;
@@ -2525,12 +2520,12 @@ void Group::SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags fla
SendUpdate();
}
-Group::Rolls::iterator Group::GetRoll(ObjectGuid Guid)
+Group::Rolls::iterator Group::GetRoll(ObjectGuid lootObjectGuid, uint8 lootListId)
{
- Rolls::iterator iter;
- for (iter=RollId.begin(); iter != RollId.end(); ++iter)
- if ((*iter)->itemGUID == Guid && (*iter)->isValid())
+ for (Rolls::iterator iter = RollId.begin(); iter != RollId.end(); ++iter)
+ if ((**iter)->GetGUID() == lootObjectGuid && (*iter)->itemSlot == lootListId && (*iter)->isValid())
return iter;
+
return RollId.end();
}