diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Group.cpp | 85 | ||||
-rw-r--r-- | src/game/Group.h | 50 | ||||
-rw-r--r-- | src/game/GroupHandler.cpp | 17 |
3 files changed, 92 insertions, 60 deletions
diff --git a/src/game/Group.cpp b/src/game/Group.cpp index ea561df6df9..0ffd3242549 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -203,7 +203,13 @@ bool Group::LoadMemberFromDB(uint32 guidLow, uint8 subgroup, bool assistant) return false; member.group = subgroup; - member.assistant = assistant; + if (assistant) + member.flags |= MEMBER_FLAG_ASSISTANT; + if (member.guid == m_mainTank) + member.flags |= MEMBER_FLAG_MAINTANK; + if (member.guid == m_mainAssistant) + member.flags |= MEMBER_FLAG_MAINASSIST; + m_memberSlots.push_back(member); SubGroupCounterIncrease(subgroup); @@ -956,10 +962,10 @@ void Group::SendUpdate() continue; // guess size WorldPacket data(SMSG_GROUP_LIST, (1+1+1+1+8+4+GetMembersCount()*20)); - data << (uint8)m_groupType; // group type - data << (uint8)(isBGGroup() ? 1 : 0); // 2.0.x, isBattleGroundGroup? - data << (uint8)(citr->group); // groupid - data << (uint8)(citr->assistant?0x01:0); // 0x2 main assist, 0x4 main tank + data << uint8(m_groupType); // group type + data << uint8(isBGGroup() ? 1 : 0); // 2.0.x, isBattleGroundGroup? + data << uint8(citr->group); // groupid + data << uint8(0); // unk data << uint64(0x50000000FFFFFFFELL); // related to voice chat? data << uint32(GetMembersCount()-1); for (member_citerator citr2 = m_memberSlots.begin(); citr2 != m_memberSlots.end(); ++citr2) @@ -967,25 +973,26 @@ void Group::SendUpdate() if(citr->guid == citr2->guid) continue; Player* member = objmgr.GetPlayer(citr2->guid); + + // Sometimes objmgr can't find player when he is teleporting between maps, causing him to show up as offline uint8 onlineState = (member) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; onlineState = onlineState | ((isBGGroup()) ? MEMBER_STATUS_PVP : 0); data << citr2->name; - data << (uint64)citr2->guid; - // online-state - data << (uint8)(onlineState); - data << (uint8)(citr2->group); // groupid - data << (uint8)(citr2->assistant?0x01:0); // 0x2 main assist, 0x4 main tank + data << uint64(citr2->guid); // guid + data << uint8(onlineState); // online-state + data << uint8(citr2->group); // groupid + data << uint8(citr2->flags); // See enum GroupMemberFlags } data << uint64(m_leaderGuid); // leader guid if(GetMembersCount()-1) { - data << (uint8)m_lootMethod; // loot method - data << (uint64)m_looterGuid; // looter guid - data << (uint8)m_lootThreshold; // loot threshold - data << (uint8)m_dungeonDifficulty; // Dungeon Difficulty - data << (uint8)m_raidDifficulty; // Raid Difficulty + data << uint8(m_lootMethod); // loot method + data << uint64(m_looterGuid); // looter guid + data << uint8(m_lootThreshold); // loot threshold + data << uint8(m_dungeonDifficulty); // Dungeon Difficulty + data << uint8(m_raidDifficulty); // Raid Difficulty } player->GetSession()->SendPacket( &data ); } @@ -1047,7 +1054,7 @@ void Group::OfflineReadyCheck() } } -bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant) +bool Group::_addMember(const uint64 &guid, const char* name) { // get first not-full group uint8 groupid = 0; @@ -1067,10 +1074,10 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant) return false; } - return _addMember(guid, name, isAssistant, groupid); + return _addMember(guid, name, groupid); } -bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant, uint8 group) +bool Group::_addMember(const uint64 &guid, const char* name, uint8 group) { if(IsFull()) return false; @@ -1084,7 +1091,7 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant, u member.guid = guid; member.name = name; member.group = group; - member.assistant = isAssistant; + member.flags = 0; m_memberSlots.push_back(member); SubGroupCounterIncrease(group); @@ -1116,7 +1123,7 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant, u if(!isBGGroup()) { // insert into group table - CharacterDatabase.PExecute("INSERT INTO group_member(leaderGuid,memberGuid,assistant,subgroup) VALUES('%u','%u','%u','%u')", GUID_LOPART(m_leaderGuid), GUID_LOPART(member.guid), ((member.assistant==1)?1:0), member.group); + CharacterDatabase.PExecute("INSERT INTO group_member(leaderGuid,memberGuid,assistant,subgroup) VALUES('%u','%u','%u','%u')", GUID_LOPART(m_leaderGuid), GUID_LOPART(member.guid), ((member.flags & MEMBER_FLAG_ASSISTANT)?1:0), member.group); } return true; @@ -1256,40 +1263,44 @@ bool Group::_setMembersGroup(const uint64 &guid, const uint8 &group) return true; } -bool Group::_setAssistantFlag(const uint64 &guid, const bool &state) +bool Group::_setAssistantFlag(const uint64 &guid, const bool &apply) { member_witerator slot = _getMemberWSlot(guid); - if(slot==m_memberSlots.end()) + if (slot == m_memberSlots.end()) return false; - slot->assistant = state; - if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE group_member SET assistant='%u' WHERE memberGuid='%u'", (state==true)?1:0, GUID_LOPART(guid)); + ToggleGroupMemberFlag(slot, MEMBER_FLAG_ASSISTANT, apply); + + if(!isBGGroup()) + CharacterDatabase.PExecute("UPDATE group_member SET assistant='%u' WHERE memberGuid='%u'", (apply)?1:0, GUID_LOPART(guid)); return true; } -bool Group::_setMainTank(const uint64 &guid) +bool Group::_setMainTank(const uint64 &guid, const bool &apply) { - member_citerator slot = _getMemberCSlot(guid); - if(slot==m_memberSlots.end()) + member_witerator slot = _getMemberWSlot(guid); // First check member slots to see if the target exists + if (slot == m_memberSlots.end()) return false; - if(m_mainAssistant == guid) - _setMainAssistant(0); - m_mainTank = guid; - if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET mainTank='%u' WHERE leaderGuid='%u'", GUID_LOPART(m_mainTank), GUID_LOPART(m_leaderGuid)); + RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main tank flag from current if any. + ToggleGroupMemberFlag(slot, MEMBER_FLAG_MAINTANK, apply); // And apply main tank flag on new main tank. + + if (!isBGGroup()) + CharacterDatabase.PExecute("UPDATE groups SET mainTank='%u' WHERE leaderGuid='%u'", GUID_LOPART(m_mainTank), GUID_LOPART(m_leaderGuid)); return true; } -bool Group::_setMainAssistant(const uint64 &guid) +bool Group::_setMainAssistant(const uint64 &guid, const bool &apply) { member_witerator slot = _getMemberWSlot(guid); - if(slot==m_memberSlots.end()) + if (slot == m_memberSlots.end()) return false; - if(m_mainTank == guid) - _setMainTank(0); - m_mainAssistant = guid; - if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET mainAssistant='%u' WHERE leaderGuid='%u'", GUID_LOPART(m_mainAssistant), GUID_LOPART(m_leaderGuid)); + RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINASSIST); // Remove main assist flag from current if any. + ToggleGroupMemberFlag(slot, MEMBER_FLAG_MAINASSIST, apply); // Apply main assist flag on new main assist. + + if (!isBGGroup()) + CharacterDatabase.PExecute("UPDATE groups SET mainAssistant='%u' WHERE leaderGuid='%u'", GUID_LOPART(m_mainAssistant), GUID_LOPART(m_leaderGuid)); return true; } diff --git a/src/game/Group.h b/src/game/Group.h index 26c2ea878e6..0e7bb81a3ae 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -56,6 +56,13 @@ enum GroupMemberOnlineStatus MEMBER_STATUS_UNK5 = 0x0080, // never seen }; +enum GroupMemberFlags +{ + MEMBER_FLAG_ASSISTANT = 1, + MEMBER_FLAG_MAINTANK = 2, + MEMBER_FLAG_MAINASSIST = 4, +}; + enum GroupType { GROUPTYPE_NORMAL = 0, @@ -141,7 +148,7 @@ class TRINITY_DLL_SPEC Group uint64 guid; std::string name; uint8 group; - bool assistant; + uint8 flags; }; typedef std::list<MemberSlot> MemberSlotList; typedef MemberSlotList::const_iterator member_citerator; @@ -206,7 +213,7 @@ class TRINITY_DLL_SPEC Group if(mslot==m_memberSlots.end()) return false; - return mslot->assistant; + return mslot->flags & MEMBER_FLAG_ASSISTANT; } Player* GetInvited(const uint64& guid) const; Player* GetInvited(const std::string& name) const; @@ -258,27 +265,27 @@ class TRINITY_DLL_SPEC Group void ChangeMembersGroup(const uint64 &guid, const uint8 &group); void ChangeMembersGroup(Player *player, const uint8 &group); - void SetAssistant(uint64 guid, const bool &state) + void SetAssistant(uint64 guid, const bool &apply) { if(!isRaidGroup()) return; - if(_setAssistantFlag(guid, state)) + if(_setAssistantFlag(guid, apply)) SendUpdate(); } - void SetMainTank(uint64 guid) + void SetMainTank(uint64 guid, const bool &apply) { if(!isRaidGroup()) return; - if(_setMainTank(guid)) + if(_setMainTank(guid, apply)) SendUpdate(); } - void SetMainAssistant(uint64 guid) + void SetMainAssistant(uint64 guid, const bool &apply) { if(!isRaidGroup()) return; - if(_setMainAssistant(guid)) + if(_setMainAssistant(guid, apply)) SendUpdate(); } @@ -343,17 +350,17 @@ class TRINITY_DLL_SPEC Group void BroadcastGroupUpdate(void); protected: - bool _addMember(const uint64 &guid, const char* name, bool isAssistant=false); - bool _addMember(const uint64 &guid, const char* name, bool isAssistant, uint8 group); + bool _addMember(const uint64 &guid, const char* name); + bool _addMember(const uint64 &guid, const char* name, uint8 group); bool _removeMember(const uint64 &guid); // returns true if leader has changed void _setLeader(const uint64 &guid); void _removeRolls(const uint64 &guid); bool _setMembersGroup(const uint64 &guid, const uint8 &group); - bool _setAssistantFlag(const uint64 &guid, const bool &state); - bool _setMainTank(const uint64 &guid); - bool _setMainAssistant(const uint64 &guid); + bool _setAssistantFlag(const uint64 &guid, const bool &apply); + bool _setMainTank(const uint64 &guid, const bool &apply); + bool _setMainAssistant(const uint64 &guid, const bool &apply); void _homebindIfInstance(Player *player); @@ -400,6 +407,23 @@ class TRINITY_DLL_SPEC Group if (m_subGroupsCounts) --m_subGroupsCounts[subgroup]; } + + void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag) + { + for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) + { + if (itr->flags & flag) + itr->flags = GroupMemberFlags(itr->flags & ~flag); + } + } + + void ToggleGroupMemberFlag(member_witerator slot, uint8 flag, bool apply) + { + if (apply) + slot->flags |= flag; + else + slot->flags &= ~flag; + } MemberSlotList m_memberSlots; GroupRefManager m_memberMgr; diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index f8bdc008e51..ef7cee5cfa4 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -572,14 +572,10 @@ void WorldSession::HandlePartyAssignmentOpcode( WorldPacket & recv_data ) if(!group) return; - uint8 flag1, flag2; + uint8 flag, apply; uint64 guid; - recv_data >> flag1 >> flag2; + recv_data >> flag >> apply; recv_data >> guid; - // if(flag1) Main Assist - // 0x4 - // if(flag2) Main Tank - // 0x2 /** error handling **/ if(!group->IsLeader(GetPlayer()->GetGUID())) @@ -587,10 +583,11 @@ void WorldSession::HandlePartyAssignmentOpcode( WorldPacket & recv_data ) /********************/ // everything's fine, do it - if(flag1 == 1) - group->SetMainAssistant(guid); - if(flag2 == 1) - group->SetMainTank(guid); + if (flag == MEMBER_FLAG_MAINTANK) + group->SetMainTank(guid, apply); + + else if (flag == MEMBER_FLAG_MAINASSIST) + group->SetMainAssistant(guid, apply); } void WorldSession::HandleRaidReadyCheckOpcode( WorldPacket & recv_data ) |