diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
-rw-r--r-- | src/server/game/Groups/Group.cpp | 77 | ||||
-rw-r--r-- | src/server/game/Groups/Group.h | 3 |
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> |