// --------------------------------------------------------------------------- // // // ROUTINE: TeamBalancer::PlaygroundSort // // PURPOSE: sort the players onto teams that are roughly equal given their scoring history // the first will go onto team 0, 2nd and 3rd to Team 1, 4th and 5th to Team 0, etc. // // --------------------------------------------------------------------------- // void TeamBalancer::PlaygroundSort() { uint32 nTeamSizes[2] = {0,0}; //sort the player score list from highest to lowest std::sort(m_vecPlayerScores.begin(),m_vecPlayerScores.end(),PlayerScoreHistoryCompare()); uint8 nTargetTeam = INVALID_TEAM; uint8 nOtherTeam = INVALID_TEAM; //step through the list of players, sorting them onto the teams PlayerScoreHistoryArray::iterator scoreIter = m_vecPlayerScores.begin(); while (scoreIter != m_vecPlayerScores.end()) { uint32 nID = scoreIter->first; GameClientData* pGameClientData = ServerConnectionMgr::Instance().GetGameClientDataByClientId(nID); if (pGameClientData) { //we want to leave the highest scoring player on his own team // so if we haven't set the target yet, set it to the team of the highest scoring player if (nTargetTeam == INVALID_TEAM) { nTargetTeam = pGameClientData->GetLastTeamId(); if (nTargetTeam == INVALID_TEAM) { nTargetTeam = 0; } nOtherTeam = (nTargetTeam + 1) % MAX_TEAMS; } //move the player to the current team pGameClientData->SetRequestedTeam(nTargetTeam); CPlayerObj* pPlayer = (CPlayerObj*)g_pLTServer->HandleToObject(pGameClientData->GetPlayer()); if (pPlayer) { pPlayer->HandleTeamSwitchRequest(); } //increment the team count nTeamSizes[nTargetTeam]++; //if the team we're adding to is larger, start adding to the other team if (nTeamSizes[nTargetTeam] > nTeamSizes[nOtherTeam]) { nTargetTeam = nOtherTeam; nOtherTeam = (nTargetTeam + 1) % MAX_TEAMS; } } scoreIter++; } }
// --------------------------------------------------------------------------- // // // ROUTINE: TeamBalancer::BalanceTeamSize // // PURPOSE: balance team sizes by moving the lowest score player(s) from the larger team // // --------------------------------------------------------------------------- // bool TeamBalancer::BalanceTeamSize() { bool bMovedPlayer = false; uint32 nTeamSizes[2] = {0,0}; for (uint8 nTeam = 0;nTeam < 2;++nTeam) { CTeam* pTeam = CTeamMgr::Instance( ).GetTeam(nTeam); if (pTeam) { nTeamSizes[nTeam] = pTeam->GetNumPlayers(); } } //check to see if one team is larger by at least 2 people if (LTDIFF(nTeamSizes[0],nTeamSizes[1]) > 1) { uint8 nLargerTeam = ((nTeamSizes[0] < nTeamSizes[1]) ? 1 : 0); uint8 nSmallerTeam = (nLargerTeam + 1) % MAX_TEAMS; //make a list of players on the team PlayerScoreHistoryArray vecScores; ServerConnectionMgr::GameClientDataList& gameClientDataList = ServerConnectionMgr::Instance( ).GetGameClientDataList( ); ServerConnectionMgr::GameClientDataList::iterator iter = gameClientDataList.begin( ); for( ; iter != gameClientDataList.end( ); iter++ ) { GameClientData* pGameClientData = *iter; if( !pGameClientData->GetClient( )) continue; //if player is on the larger team, add him to our list if (nLargerTeam == pGameClientData->GetLastTeamId()) { PlayerScoreHistory pairScore; pairScore.first = g_pLTServer->GetClientID(pGameClientData->GetClient( )); pairScore.second = 0; CPlayerScore* pScore = pGameClientData->GetPlayerScore(); if (pScore) { pairScore.second = pScore->GetScore(); } vecScores.push_back(pairScore); } } //sort the player list from highest to lowest std::sort(vecScores.begin(),vecScores.end(),PlayerScoreHistoryCompare()); //while the teams are still unbalanced move lowest scoring players from the larger team to the smaller PlayerScoreHistoryArray::reverse_iterator scoreIter = vecScores.rbegin(); while (LTDIFF(nTeamSizes[nLargerTeam],nTeamSizes[nSmallerTeam]) > 1 && scoreIter != vecScores.rend()) { uint32 nID = scoreIter->first; GameClientData* pGameClientData = ServerConnectionMgr::Instance().GetGameClientDataByClientId(nID); if (pGameClientData) { pGameClientData->SetRequestedTeam(nSmallerTeam); CPlayerObj* pPlayer = (CPlayerObj*)g_pLTServer->HandleToObject(pGameClientData->GetPlayer()); if (pPlayer) { pPlayer->HandleTeamSwitchRequest(); } //shrink the larger team and grow the smaller nTeamSizes[nLargerTeam]--; nTeamSizes[nSmallerTeam]++; bMovedPlayer = true; } scoreIter++; } } if (bMovedPlayer) { CAutoMessage cClientMsg; cClientMsg.Writeuint8(MID_PLAYER_EVENT); cClientMsg.Writeuint8(kPEAutobalance); cClientMsg.Writebool( false ); //didn't do score balancing g_pLTServer->SendToClient(cClientMsg.Read(), NULL, MESSAGE_GUARANTEED); } return bMovedPlayer; }