/// <summary> /// Update the Role check info with the player selected role. /// </summary> /// <param name="grp">Group</param> /// <param name="plr">Player</param> void LFGMgr::UpdateRoleCheck(Group *grp, Player *plr /* = NULL*/) { assert(grp); uint32 rolecheckId = GUID_LOPART(grp->GetGUID()); LfgRoleCheck *pRoleCheck = NULL; LfgRolesMap check_roles; LfgRoleCheckMap::iterator itRoleCheck = m_RoleChecks.find(rolecheckId); bool newRoleCheck = itRoleCheck == m_RoleChecks.end(); if (newRoleCheck) { if (!grp->IsLeader(plr->GetGUID())) return; pRoleCheck = new LfgRoleCheck(); pRoleCheck->cancelTime = time_t(time(NULL)) + LFG_TIME_ROLECHECK; pRoleCheck->result = LFG_ROLECHECK_INITIALITING; pRoleCheck->leader = plr->GetGUID(); for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) if (Player *plrg = itr->getSource()) pRoleCheck->roles[plrg->GetGUID()] = 0; pRoleCheck->dungeons = plr->m_lookingForGroup.applyDungeons; } else pRoleCheck = itRoleCheck->second; LfgLockStatusMap *playersLockMap = NULL; if (plr) { // Player selected no role. if (plr->m_lookingForGroup.roles < ROLE_TANK) pRoleCheck->result = LFG_ROLECHECK_NO_ROLE; else { // Check if all players have selected a role pRoleCheck->roles[plr->GetGUID()] = plr->m_lookingForGroup.roles; uint8 size = 0; for (LfgRolesMap::const_iterator itRoles = pRoleCheck->roles.begin(); itRoles != pRoleCheck->roles.end() && itRoles->second != ROLE_NONE; ++itRoles) ++size; if (pRoleCheck->roles.size() == size) { // use temporal var to check roles, CheckGroupRoles modifies the roles for (LfgRolesMap::const_iterator itRoles = pRoleCheck->roles.begin(); itRoles != pRoleCheck->roles.end(); ++itRoles) check_roles[itRoles->first] = itRoles->second; if (!CheckGroupRoles(check_roles)) // Group is not posible pRoleCheck->result = LFG_ROLECHECK_WRONG_ROLES; else { // Check if we can find a dungeon for that group pRoleCheck->result = LFG_ROLECHECK_FINISHED; if (pRoleCheck->dungeons.size() > 1) playersLockMap = GetPartyLockStatusDungeons(plr, &pRoleCheck->dungeons); else { LfgDungeonSet::const_iterator it = pRoleCheck->dungeons.begin(); LFGDungeonEntry const *dungeon = sLFGDungeonStore.LookupEntry(*it); if (dungeon && dungeon->type == LFG_TYPE_RANDOM) playersLockMap = GetPartyLockStatusDungeons(plr, m_DungeonsMap[*it]); else playersLockMap = GetPartyLockStatusDungeons(plr, &pRoleCheck->dungeons); } } } } } else pRoleCheck->result = LFG_ROLECHECK_ABORTED; WorldSession *session; WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + pRoleCheck->dungeons.size() * 4 + 1 + pRoleCheck->roles.size() * (8 + 1 + 4 + 1)); DEBUG_LOG("SMSG_LFG_ROLE_CHECK_UPDATE"); BuildLfgRoleCheck(data, pRoleCheck); Player *plrg = NULL; for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { plrg = itr->getSource(); if (!plrg) continue; session = plrg->GetSession(); if (!newRoleCheck && plr) session->SendLfgRoleChosen(plr->GetGUID(), plr->m_lookingForGroup.roles); session->SendPacket(&data); switch (pRoleCheck->result) { case LFG_ROLECHECK_INITIALITING: continue; case LFG_ROLECHECK_FINISHED: if (!playersLockMap) { session->SendLfgUpdateParty(LFG_UPDATETYPE_ADDED_TO_QUEUE); } else { if (grp->IsLeader(plrg->GetGUID())) { uint32 size = 0; for (LfgLockStatusMap::const_iterator it = playersLockMap->begin(); it != playersLockMap->end(); ++it) size += 8 + 4 + it->second->size() * (4 + 4); WorldPacket data(SMSG_LFG_JOIN_RESULT, 4 + 4 + size); DEBUG_LOG("SMSG_LFG_JOIN_RESULT"); data << uint32(LFG_JOIN_PARTY_NOT_MEET_REQS); // Check Result data << uint32(0); // Check Value (always 0 when PartyNotMeetReqs BuildPartyLockDungeonBlock(data, playersLockMap); session->SendPacket(&data); } session->SendLfgUpdateParty(LFG_UPDATETYPE_ROLECHECK_FAILED); plrg->m_lookingForGroup.applyDungeons.clear(); plrg->m_lookingForGroup.roles = 0; } break; default: if (grp->IsLeader(plrg->GetGUID())) session->SendLfgJoinResult(LFG_JOIN_FAILED, pRoleCheck->result); session->SendLfgUpdateParty(LFG_UPDATETYPE_ROLECHECK_FAILED); plrg->m_lookingForGroup.applyDungeons.clear(); plrg->m_lookingForGroup.roles = 0; break; } } if (pRoleCheck->result == LFG_ROLECHECK_FINISHED) { // Add qroup to queue LfgQueueInfo *pqInfo; uint8 groupType = 0; uint8 tanks = LFG_TANKS_NEEDED; uint8 healers = LFG_HEALERS_NEEDED; uint8 dps = LFG_DPS_NEEDED; for (LfgRolesMap::const_iterator it = check_roles.begin(); it != check_roles.end(); ++it) { if (it->second & ROLE_TANK) --tanks; else if (it->second & ROLE_HEALER) --healers; else --dps; } uint64 guid = grp->GetGUID(); m_update = false; for (LfgDungeonSet::const_iterator it = pRoleCheck->dungeons.begin(); it != pRoleCheck->dungeons.end(); ++it) { groupType = GetDungeonGroupType(*it); pqInfo = m_Queues[groupType] ? m_Queues[groupType]->GetQueueInfo(guid) : NULL; // if exist we have already added the player with another dungeon sharing same GroupType if (pqInfo) continue; pqInfo = new LfgQueueInfo(); pqInfo->dungeonId = *it; pqInfo->joinTime = time_t(time(NULL)); pqInfo->tanks = tanks; pqInfo->healers = healers; pqInfo->dps = dps; for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { if (Player *plrg = itr->getSource()) pqInfo->roles[plrg->GetGUID()] = plrg->m_lookingForGroup.roles; } if (!m_Queues[groupType]) m_Queues[groupType] = new LFGQueue(); m_Queues[groupType]->AddToQueue(guid, pqInfo); } m_update = true; } if (pRoleCheck->result != LFG_ROLECHECK_INITIALITING) { delete pRoleCheck; if (!newRoleCheck) m_RoleChecks.erase(itRoleCheck); } else if (newRoleCheck) m_RoleChecks[rolecheckId] = pRoleCheck; }