+void Player_SetForcedTeamIndex(entity player, int team_index)
+{
+ switch (team_index)
+ {
+ case TEAM_FORCE_SPECTATOR:
+ case TEAM_FORCE_DEFAULT:
+ {
+ player.team_forced = team_index;
+ break;
+ }
+ default:
+ {
+ if (!Team_IsValidIndex(team_index))
+ {
+ LOG_FATAL("Invalid team index.");
+ }
+ else
+ {
+ player.team_forced = team_index;
+ break;
+ }
+ }
+ }
+}
+
+void Player_DetermineForcedTeam(entity player)
+{
+ if (autocvar_g_campaign)
+ {
+ if (IS_REAL_CLIENT(player)) // only players, not bots
+ {
+ if (Team_IsValidIndex(autocvar_g_campaign_forceteam))
+ {
+ player.team_forced = autocvar_g_campaign_forceteam;
+ }
+ else
+ {
+ player.team_forced = TEAM_FORCE_DEFAULT;
+ }
+ }
+ }
+ else if (PlayerInList(player, autocvar_g_forced_team_red))
+ {
+ player.team_forced = 1;
+ }
+ else if (PlayerInList(player, autocvar_g_forced_team_blue))
+ {
+ player.team_forced = 2;
+ }
+ else if (PlayerInList(player, autocvar_g_forced_team_yellow))
+ {
+ player.team_forced = 3;
+ }
+ else if (PlayerInList(player, autocvar_g_forced_team_pink))
+ {
+ player.team_forced = 4;
+ }
+ else
+ {
+ switch (autocvar_g_forced_team_otherwise)
+ {
+ case "red":
+ {
+ player.team_forced = 1;
+ break;
+ }
+ case "blue":
+ {
+ player.team_forced = 2;
+ break;
+ }
+ case "yellow":
+ {
+ player.team_forced = 3;
+ break;
+ }
+ case "pink":
+ {
+ player.team_forced = 4;
+ break;
+ }
+ case "spectate":
+ case "spectator":
+ {
+ player.team_forced = TEAM_FORCE_SPECTATOR;
+ break;
+ }
+ default:
+ {
+ player.team_forced = TEAM_FORCE_DEFAULT;
+ break;
+ }
+ }
+ }
+ if (!teamplay && Player_HasRealForcedTeam(player))
+ {
+ player.team_forced = TEAM_FORCE_DEFAULT;
+ }
+}
+
+void TeamBalance_JoinBestTeam(entity player)
+{
+ //PrintToChatAll(sprintf("TeamBalance_JoinBestTeam: %s", player.netname));
+ if (!teamplay)
+ {
+ return;
+ }
+ if (player.bot_forced_team)
+ {
+ return;
+ }
+ entity balance = TeamBalance_CheckAllowedTeams(player);
+ if (Player_HasRealForcedTeam(player))
+ {
+ int forced_team_index = player.team_forced;
+ bool is_team_allowed = TeamBalance_IsTeamAllowedInternal(balance,
+ forced_team_index);
+ TeamBalance_Destroy(balance);
+ if (!is_team_allowed)
+ {
+ return;
+ }
+ if (!SetPlayerTeam(player, forced_team_index, TEAM_CHANGE_AUTO))
+ {
+ return;
+ }
+ return;
+ }
+ int best_team_index = TeamBalance_FindBestTeam(balance, player, true);
+ TeamBalance_Destroy(balance);
+ if (!SetPlayerTeam(player, best_team_index, TEAM_CHANGE_AUTO))
+ {
+ return;
+ }
+}
+
+entity TeamBalance_CheckAllowedTeams(entity for_whom)
+{
+ entity balance = spawn();
+ for (int i = 0; i < NUM_TEAMS; ++i)
+ {
+ entity team_ent = balance.m_team_balance_team[i] = spawn();
+ team_ent.m_team_score = g_team_entities[i].m_team_score;
+ team_ent.m_num_players = TEAM_NOT_ALLOWED;
+ team_ent.m_num_bots = 0;
+ }
+ setthink(balance, TeamBalance_Destroy);
+ balance.nextthink = time;