/// \brief Indicates that the player is not allowed to join a team.
const int TEAM_NOT_ALLOWED = -1;
+.float team_forced; // can be a team number to force a team, or 0 for default action, or -1 for forced spectator
+
.int m_team_balance_state; ///< Holds the state of the team balance entity.
.entity m_team_balance_team[NUM_TEAMS]; ///< ???
.int m_num_players_alive; ///< Number of alive players in a team.
.int m_num_control_points; ///< Number of control points owned by a team.
+string autocvar_g_forced_team_red;
+string autocvar_g_forced_team_blue;
+string autocvar_g_forced_team_yellow;
+string autocvar_g_forced_team_pink;
+
entity g_team_entities[NUM_TEAMS]; ///< Holds global team entities.
STATIC_INIT(g_team_entities)
GameLogEcho(strcat(":team:", ftos(player_id), ":", ftos(team_number), ":", ftos(type)));
}
+bool Player_HasRealForcedTeam(entity player)
+{
+ return player.team_forced > TEAM_FORCE_DEFAULT;
+}
+
+int Player_GetForcedTeamIndex(entity player)
+{
+ return player.team_forced;
+}
+
+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("Player_SetForcedTeamIndex: 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;
+ }
+}
+
entity TeamBalance_CheckAllowedTeams(entity for_whom)
{
entity balance = spawn();
// if player has a forced team, ONLY allow that one
for (int i = 1; i <= NUM_TEAMS; ++i)
{
- if (for_whom.team_forced == Team_IndexToTeam(i) &&
+ if (for_whom.team_forced == i &&
TeamBalance_IsTeamAllowedInternal(balance, i))
{
TeamBalance_BanTeamsExcept(balance, i);
{
team_num = it.team;
}
- else if (it.team_forced > 0)
+ else if (Player_HasRealForcedTeam(it))
{
- team_num = it.team_forced; // reserve the spot
+ team_num = Team_IndexToTeam(it.team_forced); // reserve the spot
}
else
{
void TeamBalance_JoinBestTeam(entity this)
{
//PrintToChatAll(sprintf("JoinBestTeam: %s", this.netname));
- // don't join a team if we're not playing a team game
if (!teamplay)
{
return;
}
-
- // find out what teams are available
- entity balance = TeamBalance_CheckAllowedTeams(this);
-
if (this.bot_forced_team)
{
+ return;
+ }
+ int old_team_index = Team_TeamToIndex(this.team);
+ entity balance = TeamBalance_CheckAllowedTeams(this);
+ if (Player_HasRealForcedTeam(this))
+ {
+ int forced_team_index = this.team_forced;
+ bool is_team_allowed = TeamBalance_IsTeamAllowedInternal(balance,
+ forced_team_index);
TeamBalance_Destroy(balance);
+ if (!is_team_allowed)
+ {
+ return;
+ }
+ if (!SetPlayerTeam(this, forced_team_index, TEAM_CHANGE_AUTO))
+ {
+ return;
+ }
+ if ((old_team_index != -1) && !IS_BOT_CLIENT(this))
+ {
+ TeamBalance_AutoBalanceBots(forced_team_index, old_team_index);
+ }
return;
}
int best_team_index = TeamBalance_FindBestTeam(balance, this, true);
- int old_team_index = Team_TeamToIndex(this.team);
TeamBalance_Destroy(balance);
PlayerScore_Clear(this);
if (!SetPlayerTeam(this, best_team_index, TEAM_CHANGE_AUTO))
{
return;
}
+ if (source_team_index == -1)
+ {
+ return;
+ }
TeamBalance_AutoBalanceBots(destination_team_index, source_team_index);
}