aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp7
-rw-r--r--src/server/game/Entities/Player/Player.h1
-rw-r--r--src/server/game/Groups/Group.cpp77
-rw-r--r--src/server/game/Groups/Group.h3
4 files changed, 67 insertions, 21 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 8c9f146cf63..0b2a18af684 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1869,7 +1869,6 @@ bool Player::TeleportToBGEntryPoint()
ScheduleDelayedOperation(DELAYED_BG_MOUNT_RESTORE);
ScheduleDelayedOperation(DELAYED_BG_TAXI_RESTORE);
- ScheduleDelayedOperation(DELAYED_BG_GROUP_RESTORE);
return TeleportTo(m_bgData.joinPos);
}
@@ -1908,12 +1907,6 @@ void Player::ProcessDelayedOperations()
}
}
- if (m_DelayedOperations & DELAYED_BG_GROUP_RESTORE)
- {
- if (Group* g = GetGroup())
- g->SendUpdateToPlayer(GetGUID());
- }
-
//we have executed ALL delayed ops, so clear the flag
m_DelayedOperations = 0;
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 45ec314f4da..9787e96573c 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -750,7 +750,6 @@ enum PlayerDelayedOperations
DELAYED_SPELL_CAST_DESERTER = 0x04,
DELAYED_BG_MOUNT_RESTORE = 0x08, ///< Flag to restore mount state after teleport from BG
DELAYED_BG_TAXI_RESTORE = 0x10, ///< Flag to restore taxi state after teleport from BG
- DELAYED_BG_GROUP_RESTORE = 0x20, ///< Flag to restore group state after teleport from BG
DELAYED_END
};
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 2913b415618..3a8ba730fa7 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -569,6 +569,8 @@ bool Group::RemoveMember(ObjectGuid guid, RemoveMethod const& method /*= GROUP_R
{
if (player)
{
+ bool isOriginalGroup = false;
+
// Battleground group handling
if (isBGGroup() || isBFGroup())
player->RemoveFromBattlegroundOrBattlefieldRaid();
@@ -576,7 +578,10 @@ bool Group::RemoveMember(ObjectGuid guid, RemoveMethod const& method /*= GROUP_R
// Regular group
{
if (player->GetOriginalGroup() == this)
+ {
player->SetOriginalGroup(nullptr);
+ isOriginalGroup = true;
+ }
else
player->SetGroup(nullptr);
@@ -592,11 +597,26 @@ bool Group::RemoveMember(ObjectGuid guid, RemoveMethod const& method /*= GROUP_R
player->SendDirectMessage(&data);
}
- // Do we really need to send this opcode?
- data.Initialize(SMSG_GROUP_LIST, 1+1+1+1+8+4+4+8);
- data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0);
- data << uint64(m_guid) << uint32(m_counter) << uint32(0) << uint64(0);
- player->SendDirectMessage(&data);
+ // if we had OriginalGroup (now in Group slot after removal) we need to notify the client to replace group data
+ if (Group* group = player->GetGroup())
+ group->SendUpdateToPlayer(player);
+ else
+ {
+ data.Initialize(SMSG_GROUP_LIST, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 8);
+ data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0);
+ data << uint64(m_guid) << uint32(m_counter) << uint32(0) << uint64(0);
+ player->SendDirectMessage(&data);
+ }
+
+ // if player left his original group but not bg/lfg group then we need to update values reported by Lua_GetReal** functions
+ if (isOriginalGroup)
+ {
+ data.Initialize(SMSG_REAL_GROUP_UPDATE, 1 + 4 + 8);
+ data << uint8(0x10);
+ data << uint32(0);
+ data << uint64(0);
+ player->SendDirectMessage(&data);
+ }
_homebindIfInstance(player);
}
@@ -800,6 +820,8 @@ void Group::Disband(bool hideDestroy /* = false */)
if (!player)
continue;
+ bool isOriginalGroup = false;
+
//we cannot call _removeMember because it would invalidate member iterator
//if we are removing player from battleground raid
if (isBGGroup() || isBFGroup())
@@ -808,7 +830,10 @@ void Group::Disband(bool hideDestroy /* = false */)
{
//we can remove player who is in battleground from his original group
if (player->GetOriginalGroup() == this)
+ {
player->SetOriginalGroup(nullptr);
+ isOriginalGroup = true;
+ }
else
player->SetGroup(nullptr);
}
@@ -840,6 +865,16 @@ void Group::Disband(bool hideDestroy /* = false */)
player->SendDirectMessage(&data);
}
+ // if player left his original group but not bg/lfg group then we need to update values reported by Lua_GetReal** functions
+ if (isOriginalGroup)
+ {
+ data.Initialize(SMSG_REAL_GROUP_UPDATE, 1 + 4 + 8);
+ data << uint8(0x10);
+ data << uint32(0);
+ data << uint64(0);
+ player->SendDirectMessage(&data);
+ }
+
_homebindIfInstance(player);
}
@@ -1669,25 +1704,34 @@ void Group::SendTargetIconList(WorldSession* session)
void Group::SendUpdate()
{
for (member_witerator witr = m_memberSlots.begin(); witr != m_memberSlots.end(); ++witr)
- SendUpdateToPlayer(witr->guid, &(*witr));
+ {
+ Player* player = ObjectAccessor::FindConnectedPlayer(witr->guid);
+ if (!player)
+ continue;
+
+ SendUpdateToPlayer(player, &(*witr));
+ }
}
-void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot)
+void Group::SendUpdateToPlayer(Player const* player, MemberSlot const* slot /*= nullptr*/)
{
- Player* player = ObjectAccessor::FindConnectedPlayer(playerGUID);
+ if (player->GetGroup() != this)
+ {
+ if (player->GetOriginalGroup() == this)
+ SendOriginalGroupUpdateToPlayer(player);
- if (!player || !player->GetSession() || player->GetGroup() != this)
return;
+ }
// if MemberSlot wasn't provided
if (!slot)
{
- member_witerator witr = _getMemberWSlot(playerGUID);
+ member_citerator citr = _getMemberCSlot(player->GetGUID());
- if (witr == m_memberSlots.end()) // if there is no MemberSlot for such a player
+ if (citr == m_memberSlots.end()) // if there is no MemberSlot for such a player
return;
- slot = &(*witr);
+ slot = &(*citr);
}
WorldPacket data(SMSG_GROUP_LIST, (1+1+1+1+1+4+8+4+4+(GetMembersCount()-1)*(13+8+1+1+1+1)+8+1+8+1+1+1+1));
@@ -1742,6 +1786,15 @@ void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot)
player->SendDirectMessage(&data);
}
+void Group::SendOriginalGroupUpdateToPlayer(Player const* player) const
+{
+ WorldPacket data(SMSG_REAL_GROUP_UPDATE, 1 + 4 + 8);
+ data << uint8(m_groupType);
+ data << uint32(GetMembersCount() - 1);
+ data << uint64(m_leaderGuid);
+ player->SendDirectMessage(&data);
+}
+
void Group::UpdatePlayerOutOfRange(Player* player)
{
if (!player || !player->IsInWorld())
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index 7793e092978..402264f19ef 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -276,7 +276,8 @@ class TC_GAME_API Group
//void SendInit(WorldSession* session);
void SendTargetIconList(WorldSession* session);
void SendUpdate();
- void SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot = nullptr);
+ void SendUpdateToPlayer(Player const* player, MemberSlot const* slot = nullptr);
+ void SendOriginalGroupUpdateToPlayer(Player const* player) const;
void UpdatePlayerOutOfRange(Player* player);
template<class Worker>