Prevent adding more than 5 people into RAID subgroup.

Optimized free subgroup in raid finding.
Optimized method calls, now using const uint64& instead of value passing.
Signed-off-by: ApoC <apoc@nymfe.net>
This commit is contained in:
ApoC 2008-10-25 20:51:40 +02:00
parent 454ff6e667
commit 61b2b3d234
3 changed files with 109 additions and 33 deletions

View file

@ -42,6 +42,7 @@ Group::Group()
m_lootMethod = (LootMethod)0; m_lootMethod = (LootMethod)0;
m_looterGuid = 0; m_looterGuid = 0;
m_lootThreshold = ITEM_QUALITY_UNCOMMON; m_lootThreshold = ITEM_QUALITY_UNCOMMON;
m_subGroupsCounts = NULL;
for(int i=0; i<TARGETICONCOUNT; i++) for(int i=0; i<TARGETICONCOUNT; i++)
m_targetIcons[i] = 0; m_targetIcons[i] = 0;
@ -71,6 +72,10 @@ Group::~Group()
for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++) for(uint8 i = 0; i < TOTAL_DIFFICULTIES; i++)
for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
itr->second.save->RemoveGroup(this); itr->second.save->RemoveGroup(this);
// Sub group counters clean up
if (m_subGroupsCounts)
delete[] m_subGroupsCounts;
} }
bool Group::Create(const uint64 &guid, const char * name) bool Group::Create(const uint64 &guid, const char * name)
@ -79,6 +84,10 @@ bool Group::Create(const uint64 &guid, const char * name)
m_leaderName = name; m_leaderName = name;
m_groupType = isBGGroup() ? GROUPTYPE_RAID : GROUPTYPE_NORMAL; m_groupType = isBGGroup() ? GROUPTYPE_RAID : GROUPTYPE_NORMAL;
if (m_groupType == GROUPTYPE_RAID)
_initRaidSubGroupsCounter();
m_lootMethod = GROUP_LOOT; m_lootMethod = GROUP_LOOT;
m_lootThreshold = ITEM_QUALITY_UNCOMMON; m_lootThreshold = ITEM_QUALITY_UNCOMMON;
m_looterGuid = guid; m_looterGuid = guid;
@ -134,6 +143,10 @@ bool Group::LoadGroupFromDB(const uint64 &leaderGuid, QueryResult *result, bool
} }
m_groupType = (*result)[13].GetBool() ? GROUPTYPE_RAID : GROUPTYPE_NORMAL; m_groupType = (*result)[13].GetBool() ? GROUPTYPE_RAID : GROUPTYPE_NORMAL;
if (m_groupType == GROUPTYPE_RAID)
_initRaidSubGroupsCounter();
m_difficulty = (*result)[14].GetUInt8(); m_difficulty = (*result)[14].GetUInt8();
m_mainTank = (*result)[0].GetUInt64(); m_mainTank = (*result)[0].GetUInt64();
m_mainAssistant = (*result)[1].GetUInt64(); m_mainAssistant = (*result)[1].GetUInt64();
@ -176,6 +189,9 @@ bool Group::LoadMemberFromDB(uint32 guidLow, uint8 subgroup, bool assistant)
member.group = subgroup; member.group = subgroup;
member.assistant = assistant; member.assistant = assistant;
m_memberSlots.push_back(member); m_memberSlots.push_back(member);
SubGroupCounterIncrease(subgroup);
return true; return true;
} }
@ -384,7 +400,7 @@ void Group::SendLootStartRoll(uint32 CountDown, const Roll &r)
} }
} }
void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r) void Group::SendLootRoll(const uint64& SourceGuid, const uint64& TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r)
{ {
WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1)); WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1));
data << uint64(SourceGuid); // guid of the item rolled data << uint64(SourceGuid); // guid of the item rolled
@ -408,7 +424,7 @@ void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber,
} }
} }
void Group::SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r) void Group::SendLootRollWon(const uint64& SourceGuid, const uint64& TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r)
{ {
WorldPacket data(SMSG_LOOT_ROLL_WON, (8+4+4+4+4+8+1+1)); WorldPacket data(SMSG_LOOT_ROLL_WON, (8+4+4+4+4+8+1+1));
data << uint64(SourceGuid); // guid of the item rolled data << uint64(SourceGuid); // guid of the item rolled
@ -451,7 +467,7 @@ void Group::SendLootAllPassed(uint32 NumberOfPlayers, const Roll &r)
} }
} }
void Group::GroupLoot(uint64 playerGUID, Loot *loot, Creature *creature) void Group::GroupLoot(const uint64& playerGUID, Loot *loot, Creature *creature)
{ {
std::vector<LootItem>::iterator i; std::vector<LootItem>::iterator i;
ItemPrototype const *item; ItemPrototype const *item;
@ -507,7 +523,7 @@ void Group::GroupLoot(uint64 playerGUID, Loot *loot, Creature *creature)
} }
} }
void Group::NeedBeforeGreed(uint64 playerGUID, Loot *loot, Creature *creature) void Group::NeedBeforeGreed(const uint64& playerGUID, Loot *loot, Creature *creature)
{ {
ItemPrototype const *item; ItemPrototype const *item;
Player *player = objmgr.GetPlayer(playerGUID); Player *player = objmgr.GetPlayer(playerGUID);
@ -561,7 +577,7 @@ void Group::NeedBeforeGreed(uint64 playerGUID, Loot *loot, Creature *creature)
} }
} }
void Group::MasterLoot(uint64 playerGUID, Loot* /*loot*/, Creature *creature) void Group::MasterLoot(const uint64& playerGUID, Loot* /*loot*/, Creature *creature)
{ {
Player *player = objmgr.GetPlayer(playerGUID); Player *player = objmgr.GetPlayer(playerGUID);
if(!player) if(!player)
@ -597,7 +613,7 @@ void Group::MasterLoot(uint64 playerGUID, Loot* /*loot*/, Creature *creature)
} }
} }
void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choise) void Group::CountRollVote(const uint64& playerGUID, const uint64& Guid, uint32 NumberOfPlayers, uint8 Choise)
{ {
Rolls::iterator rollI = GetRoll(Guid); Rolls::iterator rollI = GetRoll(Guid);
if (rollI == RollId.end()) if (rollI == RollId.end())
@ -929,13 +945,20 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant)
{ {
// get first not-full group // get first not-full group
uint8 groupid = 0; uint8 groupid = 0;
std::vector<uint8> temp(MAXRAIDSIZE/MAXGROUPSIZE); if (m_subGroupsCounts)
for(member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
{ {
if (itr->group >= temp.size()) continue; bool groupFound = false;
++temp[itr->group]; for (; groupid < MAXRAIDSIZE/MAXGROUPSIZE; ++groupid)
if(temp[groupid] >= MAXGROUPSIZE) {
++groupid; if (m_subGroupsCounts[groupid] < MAXGROUPSIZE)
{
groupFound = true;
break;
}
}
// We are raid group and no one slot is free
if (!groupFound)
return false;
} }
return _addMember(guid, name, isAssistant, groupid); return _addMember(guid, name, isAssistant, groupid);
@ -958,6 +981,8 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant, u
member.assistant = isAssistant; member.assistant = isAssistant;
m_memberSlots.push_back(member); m_memberSlots.push_back(member);
SubGroupCounterIncrease(group);
if(player) if(player)
{ {
player->SetGroupInvite(NULL); player->SetGroupInvite(NULL);
@ -995,7 +1020,11 @@ bool Group::_removeMember(const uint64 &guid)
member_witerator slot = _getMemberWSlot(guid); member_witerator slot = _getMemberWSlot(guid);
if (slot != m_memberSlots.end()) if (slot != m_memberSlots.end())
{
SubGroupCounterDecrease(slot->group);
m_memberSlots.erase(slot); m_memberSlots.erase(slot);
}
if(!isBGGroup()) if(!isBGGroup())
CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid='%u'", GUID_LOPART(guid)); CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid='%u'", GUID_LOPART(guid));
@ -1088,13 +1117,6 @@ void Group::_removeRolls(const uint64 &guid)
} }
} }
void Group::_convertToRaid()
{
m_groupType = GROUPTYPE_RAID;
if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET isRaid = 1 WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid));
}
bool Group::_setMembersGroup(const uint64 &guid, const uint8 &group) bool Group::_setMembersGroup(const uint64 &guid, const uint8 &group)
{ {
member_witerator slot = _getMemberWSlot(guid); member_witerator slot = _getMemberWSlot(guid);
@ -1102,7 +1124,11 @@ bool Group::_setMembersGroup(const uint64 &guid, const uint8 &group)
return false; return false;
slot->group = group; slot->group = group;
SubGroupCounterIncrease(group);
if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE group_member SET subgroup='%u' WHERE memberGuid='%u'", group, GUID_LOPART(guid)); if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE group_member SET subgroup='%u' WHERE memberGuid='%u'", group, GUID_LOPART(guid));
return true; return true;
} }
@ -1156,12 +1182,20 @@ void Group::ChangeMembersGroup(const uint64 &guid, const uint8 &group)
if(!isRaidGroup()) if(!isRaidGroup())
return; return;
Player *player = objmgr.GetPlayer(guid); Player *player = objmgr.GetPlayer(guid);
if (!player) if (!player)
{ {
uint8 prevSubGroup;
prevSubGroup = GetMemberGroup(guid);
SubGroupCounterDecrease(prevSubGroup);
if(_setMembersGroup(guid, group)) if(_setMembersGroup(guid, group))
SendUpdate(); SendUpdate();
} }
else ChangeMembersGroup(player, group); else
// This methods handles itself groupcounter decrease
ChangeMembersGroup(player, group);
} }
// only for online members // only for online members
@ -1171,6 +1205,11 @@ void Group::ChangeMembersGroup(Player *player, const uint8 &group)
return; return;
if(_setMembersGroup(player->GetGUID(), group)) if(_setMembersGroup(player->GetGUID(), group))
{ {
uint8 prevSubGroup;
prevSubGroup = player->GetSubGroup();
SubGroupCounterDecrease(prevSubGroup);
player->GetGroupRef().setSubGroup(group); player->GetGroupRef().setSubGroup(group);
SendUpdate(); SendUpdate();
} }

View file

@ -181,8 +181,8 @@ class MANGOS_DLL_SPEC Group
ItemQualities GetLootThreshold() const { return m_lootThreshold; } ItemQualities GetLootThreshold() const { return m_lootThreshold; }
// member manipulation methods // member manipulation methods
bool IsMember(uint64 guid) const { return _getMemberCSlot(guid) != m_memberSlots.end(); } bool IsMember(const uint64& guid) const { return _getMemberCSlot(guid) != m_memberSlots.end(); }
bool IsLeader(uint64 guid) const { return (GetLeaderGUID() == guid); } bool IsLeader(const uint64& guid) const { return (GetLeaderGUID() == guid); }
bool IsAssistant(uint64 guid) const bool IsAssistant(uint64 guid) const
{ {
member_citerator mslot = _getMemberCSlot(guid); member_citerator mslot = _getMemberCSlot(guid);
@ -192,7 +192,7 @@ class MANGOS_DLL_SPEC Group
return mslot->assistant; return mslot->assistant;
} }
bool SameSubGroup(uint64 guid1, uint64 guid2) const bool SameSubGroup(uint64 guid1,const uint64& guid2) const
{ {
member_citerator mslot2 = _getMemberCSlot(guid2); member_citerator mslot2 = _getMemberCSlot(guid2);
if(mslot2==m_memberSlots.end()) if(mslot2==m_memberSlots.end())
@ -210,6 +210,11 @@ class MANGOS_DLL_SPEC Group
return (mslot1->group==slot2->group); return (mslot1->group==slot2->group);
} }
bool HasFreeSlotSubGroup(uint8 subgroup) const
{
return (m_subGroupsCounts && m_subGroupsCounts[subgroup] < MAXGROUPSIZE);
}
bool SameSubGroup(Player const* member1, Player const* member2) const; bool SameSubGroup(Player const* member1, Player const* member2) const;
MemberSlotList const& GetMemberSlots() const { return m_memberSlots; } MemberSlotList const& GetMemberSlots() const { return m_memberSlots; }
@ -228,7 +233,11 @@ class MANGOS_DLL_SPEC Group
// some additional raid methods // some additional raid methods
void ConvertToRaid() void ConvertToRaid()
{ {
_convertToRaid(); m_groupType = GROUPTYPE_RAID;
_initRaidSubGroupsCounter();
if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET isRaid = 1 WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid));
SendUpdate(); SendUpdate();
} }
void SetBattlegroundGroup(BattleGround *bg) { m_bgGroup = bg; } void SetBattlegroundGroup(BattleGround *bg) { m_bgGroup = bg; }
@ -236,14 +245,14 @@ class MANGOS_DLL_SPEC Group
void ChangeMembersGroup(const uint64 &guid, const uint8 &group); void ChangeMembersGroup(const uint64 &guid, const uint8 &group);
void ChangeMembersGroup(Player *player, const uint8 &group); void ChangeMembersGroup(Player *player, const uint8 &group);
void SetAssistant(const uint64 &guid, const bool &state) void SetAssistant(uint64 guid, const bool &state)
{ {
if(!isRaidGroup()) if(!isRaidGroup())
return; return;
if(_setAssistantFlag(guid, state)) if(_setAssistantFlag(guid, state))
SendUpdate(); SendUpdate();
} }
void SetMainTank(const uint64 &guid) void SetMainTank(uint64 guid)
{ {
if(!isRaidGroup()) if(!isRaidGroup())
return; return;
@ -251,7 +260,7 @@ class MANGOS_DLL_SPEC Group
if(_setMainTank(guid)) if(_setMainTank(guid))
SendUpdate(); SendUpdate();
} }
void SetMainAssistant(const uint64 &guid) void SetMainAssistant(uint64 guid)
{ {
if(!isRaidGroup()) if(!isRaidGroup())
return; return;
@ -282,12 +291,12 @@ class MANGOS_DLL_SPEC Group
/*********************************************************/ /*********************************************************/
void SendLootStartRoll(uint32 CountDown, const Roll &r); void SendLootStartRoll(uint32 CountDown, const Roll &r);
void SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r); void SendLootRoll(const uint64& SourceGuid, const uint64& TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r);
void SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r); void SendLootRollWon(const uint64& SourceGuid, const uint64& TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r);
void SendLootAllPassed(uint32 NumberOfPlayers, const Roll &r); void SendLootAllPassed(uint32 NumberOfPlayers, const Roll &r);
void GroupLoot(uint64 playerGUID, Loot *loot, Creature *creature); void GroupLoot(const uint64& playerGUID, Loot *loot, Creature *creature);
void NeedBeforeGreed(uint64 playerGUID, Loot *loot, Creature *creature); void NeedBeforeGreed(const uint64& playerGUID, Loot *loot, Creature *creature);
void MasterLoot(uint64 playerGUID, Loot *loot, Creature *creature); void MasterLoot(const uint64& playerGUID, Loot *loot, Creature *creature);
Rolls::iterator GetRoll(uint64 Guid) Rolls::iterator GetRoll(uint64 Guid)
{ {
Rolls::iterator iter; Rolls::iterator iter;
@ -301,7 +310,7 @@ class MANGOS_DLL_SPEC Group
return RollId.end(); return RollId.end();
} }
void CountTheRoll(Rolls::iterator roll, uint32 NumberOfPlayers); void CountTheRoll(Rolls::iterator roll, uint32 NumberOfPlayers);
void CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choise); void CountRollVote(const uint64& playerGUID, const uint64& Guid, uint32 NumberOfPlayers, uint8 Choise);
void EndRoll(); void EndRoll();
void LinkMember(GroupReference *pRef) { m_memberMgr.insertFirst(pRef); } void LinkMember(GroupReference *pRef) { m_memberMgr.insertFirst(pRef); }
@ -328,6 +337,18 @@ class MANGOS_DLL_SPEC Group
void _homebindIfInstance(Player *player); void _homebindIfInstance(Player *player);
void _initRaidSubGroupsCounter()
{
// Sub group counters initialization
if (!m_subGroupsCounts)
m_subGroupsCounts = new uint8[MAXRAIDSIZE / MAXGROUPSIZE];
memset((void*)m_subGroupsCounts, 0, (MAXRAIDSIZE / MAXGROUPSIZE)*sizeof(uint8));
for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
++m_subGroupsCounts[itr->group];
}
member_citerator _getMemberCSlot(uint64 Guid) const member_citerator _getMemberCSlot(uint64 Guid) const
{ {
for(member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) for(member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
@ -348,6 +369,18 @@ class MANGOS_DLL_SPEC Group
return m_memberSlots.end(); return m_memberSlots.end();
} }
void SubGroupCounterIncrease(uint8 subgroup)
{
if (m_subGroupsCounts)
++m_subGroupsCounts[subgroup];
}
void SubGroupCounterDecrease(uint8 subgroup)
{
if (m_subGroupsCounts)
--m_subGroupsCounts[subgroup];
}
MemberSlotList m_memberSlots; MemberSlotList m_memberSlots;
GroupRefManager m_memberMgr; GroupRefManager m_memberMgr;
InvitesList m_invitees; InvitesList m_invitees;
@ -364,5 +397,6 @@ class MANGOS_DLL_SPEC Group
uint64 m_looterGuid; uint64 m_looterGuid;
Rolls RollId; Rolls RollId;
BoundInstancesMap m_boundInstances[TOTAL_DIFFICULTIES]; BoundInstancesMap m_boundInstances[TOTAL_DIFFICULTIES];
uint8* m_subGroupsCounts;
}; };
#endif #endif

View file

@ -543,6 +543,9 @@ void WorldSession::HandleGroupChangeSubGroupOpcode( WorldPacket & recv_data )
/** error handling **/ /** error handling **/
if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
return; return;
if (!group->HasFreeSlotSubGroup(groupNr))
return;
/********************/ /********************/
// everything's fine, do it // everything's fine, do it