diff options
| author | Shauren <shauren.trinity@gmail.com> | 2017-02-05 01:57:15 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2017-02-05 01:57:15 +0100 |
| commit | e991a15dd7cbf5ba374f8942b7ea88f3a4d7b365 (patch) | |
| tree | f03739080e27b68dd31471790b63f97db56abffa /src | |
| parent | 331fa3e03c6e4f0f1994fe64472c3e90a47f0f1c (diff) | |
Core/Groups: Fixed UI bugs related to leaving and rejoining the same group
Closes #18789
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 27 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 12 | ||||
| -rw-r--r-- | src/server/game/Groups/Group.cpp | 46 | ||||
| -rw-r--r-- | src/server/game/Groups/Group.h | 13 |
4 files changed, 69 insertions, 29 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 3823f256870..12763bf5982 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -18920,6 +18920,8 @@ void Player::_LoadGroup(PreparedQueryResult result) uint8 subgroup = group->GetMemberGroup(GetGUID()); SetGroup(group, subgroup); + SetPartyType(group->GetGroupCategory(), GROUP_TYPE_NORMAL); + ResetGroupUpdateSequenceIfNeeded(group); if (getLevel() >= LEVELREQUIREMENT_HEROIC) { // the group leader may change the instance difficulty while the player is offline @@ -24760,6 +24762,31 @@ void Player::SetOriginalGroup(Group* group, int8 subgroup) } } +void Player::SetPartyType(GroupCategory category, uint8 type) +{ + ASSERT(category < MAX_GROUP_CATEGORY); + uint8 value = GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_PARTY_TYPE); + value &= ~uint8(uint8(0xFF) << (category * 4)); + value |= uint8(uint8(type) << (category * 4)); + SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_PARTY_TYPE, value); +} + +void Player::ResetGroupUpdateSequenceIfNeeded(Group const* group) +{ + GroupCategory category = group->GetGroupCategory(); + // Rejoining the last group should not reset the sequence + if (m_groupUpdateSequences[category].GroupGuid != group->GetGUID()) + { + m_groupUpdateSequences[category].GroupGuid = group->GetGUID(); + m_groupUpdateSequences[category].UpdateSequenceNumber = 1; + } +} + +int32 Player::NextGroupUpdateSequenceNumber(GroupCategory category) +{ + return m_groupUpdateSequences[category].UpdateSequenceNumber++; +} + void Player::UpdateUnderwaterState(Map* m, float x, float y, float z) { LiquidData liquid_status; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index cd7167b2d26..ffabf1aed11 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -55,6 +55,8 @@ class PlayerSocial; class SpellCastTargets; class PlayerAI; +enum GroupCategory : uint8; + typedef std::deque<Mail*> PlayerMails; #define PLAYER_MAX_SKILLS 128 @@ -1166,6 +1168,12 @@ struct ResurrectionData uint32 Aura; }; +struct GroupUpdateCounter +{ + ObjectGuid GroupGuid; + int32 UpdateSequenceNumber; +}; + enum TalentLearnResult { TALENT_LEARN_OK = 0, @@ -2402,6 +2410,9 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; } void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; } void RemoveGroupUpdateFlag(uint32 flag) { m_groupUpdateMask &= ~flag; } + void SetPartyType(GroupCategory category, uint8 type); + void ResetGroupUpdateSequenceIfNeeded(Group const* group); + int32 NextGroupUpdateSequenceNumber(GroupCategory category); Player* GetNextRandomRaidMember(float radius); PartyResult CanUninviteFromGroup(ObjectGuid guidMember = ObjectGuid::Empty) const; @@ -2744,6 +2755,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> Group* m_groupInvite; uint32 m_groupUpdateMask; bool m_bPassOnGroupLoot; + std::array<GroupUpdateCounter, 2> m_groupUpdateSequences; // last used pet number (for BG's) uint32 m_lastpetnumber; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 24b2111796d..b6a1903da95 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -55,7 +55,7 @@ Loot* Roll::getLoot() return getTarget(); } -Group::Group() : m_leaderGuid(), m_leaderName(""), m_groupFlags(GROUP_FLAG_NONE), +Group::Group() : m_leaderGuid(), 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), @@ -105,7 +105,10 @@ bool Group::Create(Player* leader) leader->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER); if (isBGGroup() || isBFGroup()) + { m_groupFlags = GROUP_MASK_BGRAID; + m_groupCategory = GROUP_CATEGORY_INSTANCE; + } if (m_groupFlags & GROUP_FLAG_RAID) _initRaidSubGroupsCounter(); @@ -227,6 +230,7 @@ void Group::LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uin void Group::ConvertToLFG() { m_groupFlags = GroupFlags(m_groupFlags | GROUP_FLAG_LFG | GROUP_FLAG_LFG_RESTRICTED); + m_groupCategory = GROUP_CATEGORY_INSTANCE; m_lootMethod = GROUP_LOOT; if (!isBGGroup() && !isBFGroup()) { @@ -392,7 +396,6 @@ bool Group::AddMember(Player* player) member.group = subGroup; member.flags = 0; member.roles = 0; - member.updateSequenceNumber = 1; member.readyChecked = false; m_memberSlots.push_back(member); @@ -409,6 +412,9 @@ bool Group::AddMember(Player* player) else //if player is not in group, then call set group player->SetGroup(this, subGroup); + player->SetPartyType(m_groupCategory, GROUP_TYPE_NORMAL); + player->ResetGroupUpdateSequenceIfNeeded(this); + // if the same group invites the player back, cancel the homebind timer player->m_InstanceValid = player->CheckInstanceValidity(false); @@ -538,7 +544,6 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R if (GetMembersCount() > ((isBGGroup() || isLFGGroup() || isBFGroup()) ? 1u : 2u)) { Player* player = ObjectAccessor::FindConnectedPlayer(guid); - uint8 partyIndex = 0; if (player) { // Battleground group handling @@ -550,15 +555,14 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R if (player->GetOriginalGroup() == this) player->SetOriginalGroup(NULL); else - { player->SetGroup(NULL); - partyIndex = 1; - } // quest related GO state dependent from raid membership player->UpdateForQuestWorldObjects(); } + player->SetPartyType(m_groupCategory, GROUP_TYPE_NONE); + WorldPacket data; if (method == GROUP_REMOVEMETHOD_KICK || method == GROUP_REMOVEMETHOD_KICK_LFG) @@ -611,11 +615,9 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R } // Update subgroups - int32 updateSequenceNumber = 1; member_witerator slot = _getMemberWSlot(guid); if (slot != m_memberSlots.end()) { - updateSequenceNumber = slot->updateSequenceNumber; SubGroupCounterDecrease(slot->group); m_memberSlots.erase(slot); } @@ -651,7 +653,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R else if (player) { // send update to removed player too so party frames are destroyed clientside - SendUpdateDestroyGroupToPlayer(player, partyIndex, updateSequenceNumber); + SendUpdateDestroyGroupToPlayer(player); } return true; @@ -794,26 +796,16 @@ void Group::Disband(bool hideDestroy /* = false */) player->SetGroup(NULL); } + player->SetPartyType(m_groupCategory, GROUP_TYPE_NONE); + // quest related GO state dependent from raid membership if (isRaidGroup()) player->UpdateForQuestWorldObjects(); - if (!player->GetSession()) - continue; - if (!hideDestroy) player->SendDirectMessage(WorldPackets::Party::GroupDestroyed().Write()); - uint8 disbandedPartyIndex = 0; - - //we already removed player from group and in player->GetGroup() is his original group, send update - if (Group* group = player->GetGroup()) - { - group->SendUpdate(); - disbandedPartyIndex = 1; - } - - SendUpdateDestroyGroupToPlayer(player, disbandedPartyIndex, citr->updateSequenceNumber); + SendUpdateDestroyGroupToPlayer(player); _homebindIfInstance(player); } @@ -1428,13 +1420,13 @@ void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot) WorldPackets::Party::PartyUpdate partyUpdate; partyUpdate.PartyFlags = m_groupFlags; - partyUpdate.PartyIndex = (player->GetOriginalGroup() && player->GetOriginalGroup() != this) ? 1 : 0; // 0 = original group, 1 = instance/bg group + partyUpdate.PartyIndex = m_groupCategory; partyUpdate.PartyType = IsCreated() ? GROUP_TYPE_NORMAL : GROUP_TYPE_NONE; partyUpdate.PartyGUID = m_guid; partyUpdate.LeaderGUID = m_leaderGuid; - partyUpdate.SequenceNum = slot->updateSequenceNumber++; // 3.3, value increases every time this packet gets sent + partyUpdate.SequenceNum = player->NextGroupUpdateSequenceNumber(m_groupCategory); partyUpdate.MyIndex = -1; uint8 index = 0; @@ -1509,15 +1501,15 @@ void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot) player->GetSession()->SendPacket(partyUpdate.Write()); } -void Group::SendUpdateDestroyGroupToPlayer(Player* player, uint8 partyIndex, int32 sequenceNum) const +void Group::SendUpdateDestroyGroupToPlayer(Player* player) const { WorldPackets::Party::PartyUpdate partyUpdate; partyUpdate.PartyFlags = GROUP_FLAG_DESTROYED; - partyUpdate.PartyIndex = partyIndex; + partyUpdate.PartyIndex = m_groupCategory; partyUpdate.PartyType = GROUP_TYPE_NONE; partyUpdate.PartyGUID = m_guid; partyUpdate.MyIndex = -1; - partyUpdate.SequenceNum = sequenceNum; + partyUpdate.SequenceNum = player->NextGroupUpdateSequenceNumber(m_groupCategory); player->GetSession()->SendPacket(partyUpdate.Write()); } diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 6f92ca17fe9..6fe7fda3c74 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -116,6 +116,14 @@ enum GroupFlags GROUP_MASK_BGRAID = GROUP_FLAG_FAKE_RAID | GROUP_FLAG_RAID, }; +enum GroupCategory : uint8 +{ + GROUP_CATEGORY_HOME = 0, + GROUP_CATEGORY_INSTANCE = 1, + + MAX_GROUP_CATEGORY +}; + enum GroupUpdateFlags { GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing @@ -218,7 +226,6 @@ class TC_GAME_API Group uint8 group; uint8 flags; uint8 roles; - int32 updateSequenceNumber; bool readyChecked; }; typedef std::list<MemberSlot> MemberSlotList; @@ -287,6 +294,7 @@ class TC_GAME_API Group bool isBGGroup() const; bool isBFGroup() const; bool IsCreated() const; + GroupCategory GetGroupCategory() const { return m_groupCategory; } ObjectGuid GetLeaderGUID() const; ObjectGuid GetGUID() const; const char * GetLeaderName() const; @@ -347,7 +355,7 @@ class TC_GAME_API Group void SendTargetIconList(WorldSession* session, int8 partyIndex = 0); void SendUpdate(); void SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot = NULL); - void SendUpdateDestroyGroupToPlayer(Player* player, uint8 partyIndex, int32 sequenceNum) const; + void SendUpdateDestroyGroupToPlayer(Player* player) const; void UpdatePlayerOutOfRange(Player* player); template<class Worker> @@ -419,6 +427,7 @@ class TC_GAME_API Group ObjectGuid m_leaderGuid; std::string m_leaderName; GroupFlags m_groupFlags; + GroupCategory m_groupCategory; Difficulty m_dungeonDifficulty; Difficulty m_raidDifficulty; Difficulty m_legacyRaidDifficulty; |
