コード例 #1
0
ファイル: TeamBalancer.cpp プロジェクト: Arc0re/lithtech
// --------------------------------------------------------------------------- //
//
//	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++;
	}

}
コード例 #2
0
ファイル: TeamBalancer.cpp プロジェクト: Arc0re/lithtech
// --------------------------------------------------------------------------- //
//
//	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;
}