61 LOG_FATALF(
"Team_GetTeamFromIndex: Index is invalid: %f", index);
70 LOG_FATALF(
"Team_GetTeam: Value is invalid: %f", team_num);
77 return team_ent.m_team_score;
82 team_ent.m_team_score = score;
87 return team_ent.m_num_players_alive;
92 team_ent.m_num_players_alive =
number;
107 return (winner ? winner : -1);
135 return (winner ? winner : -1);
140 return team_ent.m_num_owned_items;
145 team_ent.m_num_owned_items =
number;
165 this.
team = (clr & 15) + 1;
167 builtin_setcolor(
this, clr);
193 float pants = _color & 0x0F;
194 float shirt = _color & 0xF0;
197 setcolor(player, 16 * pants + pants);
208 if (player.team == new_team)
246 if (team_index != old_team_index)
250 CS(player).parm_idlesince =
time;
255 if (team_index != -1)
256 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_TEAM_NUM(player.team, INFO_JOIN_PLAY_TEAM), player.netname);
259 if (team_index == -1)
264 Kill_Notification(NOTIF_ONE_ONLY, player, MSG_CENTER,
CPID_IDLING);
265 CS(player).idlekick_lasttimeleft = 0;
269 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_QUIT_SPECTATE, player.netname);
289 Send_Notification(NOTIF_ONE, player, MSG_INFO,
290 INFO_TEAMCHANGE_NOTALLOWED);
315 player,
false)) == 0)
317 Send_Notification(NOTIF_ONE, player, MSG_INFO,
318 INFO_TEAMCHANGE_LARGERTEAM);
348 return player.team_forced;
358 player.team_forced = team_index;
365 LOG_FATAL(
"Player_SetForcedTeamIndex: Invalid team index.");
369 player.team_forced = team_index;
394 player.team_forced = 1;
398 player.team_forced = 2;
402 player.team_forced = 3;
406 player.team_forced = 4;
414 player.team_forced = 1;
419 player.team_forced = 2;
424 player.team_forced = 3;
429 player.team_forced = 4;
458 if (player.bot_forced_team)
465 int forced_team_index = player.team_forced;
469 if (!is_team_allowed)
492 entity team_ent = balance.m_team_balance_team[i] =
spawn();
495 team_ent.m_num_bots = 0;
498 balance.nextthink =
time;
503 teams_mask, teament_name, for_whom);
504 teams_mask =
M_ARGV(0,
float);
505 teament_name =
M_ARGV(1,
string);
506 if (mutator_returnvalue)
510 if (teams_mask &
BIT(i))
512 balance.m_team_balance_team[i].m_num_players = 0;
616 if (for_whom.team_forced == i &&
635 delete(balance.(m_team_balance_team[i]));
644 LOG_FATAL(
"TeamBalance_GetAllowedTeams: Team balance entity is NULL.");
648 LOG_FATAL(
"TeamBalance_GetAllowedTeams: " 649 "Team balance entity is not initialized.");
666 LOG_FATAL(
"TeamBalance_IsTeamAllowed: Team balance entity is NULL.");
671 "Team balance entity is not initialized.");
675 LOG_FATALF(
"TeamBalance_IsTeamAllowed: Team index is invalid: %f",
685 LOG_FATAL(
"TeamBalance_GetTeamCounts: Team balance entity is NULL.");
690 "Team balance entity is not initialized.");
701 team_ent.m_num_players =
M_ARGV(2,
float);
702 team_ent.m_num_bots =
M_ARGV(3,
float);
739 ++team_ent.m_num_players;
742 ++team_ent.m_num_bots;
754 if (team_ent.m_num_players == team_ent.m_num_bots)
756 ++team_ent.m_num_players;
767 LOG_FATAL(
"TeamBalance_GetNumberOfPlayers: " 768 "Team balance entity is NULL.");
772 LOG_FATAL(
"TeamBalance_GetNumberOfPlayers: " 773 "TeamBalance_GetTeamCounts has not been called.");
777 LOG_FATALF(
"TeamBalance_GetNumberOfPlayers: Team index is invalid: %f",
780 return balance.m_team_balance_team[index - 1].m_num_players;
787 LOG_FATAL(
"TeamBalance_FindBestTeam: Team balance entity is NULL.");
792 "Team balance entity is not initialized.");
806 LOG_FATALF(
"TeamBalance_FindBestTeam: No teams available for %s\n",
824 LOG_FATAL(
"TeamBalance_FindBestTeams: Team balance entity is NULL.");
829 "TeamBalance_GetTeamCounts has not been called.");
836 int previous_team = 0;
843 if (previous_team == 0)
867 entity player,
bool use_score)
871 LOG_FATAL(
"TeamBalance_CompareTeams: Team balance entity is NULL.");
876 "TeamBalance_GetTeamCounts has not been called.");
880 LOG_FATALF(
"TeamBalance_CompareTeams: team_index_a is invalid: %f",
885 LOG_FATALF(
"TeamBalance_CompareTeams: team_index_b is invalid: %f",
888 if (team_index_a == team_index_b)
905 int smallest_team_index = 0;
906 int smallest_team_player_count = 0;
915 if (smallest_team_index == 0)
917 smallest_team_index = i;
918 smallest_team_player_count = playercount;
920 else if (playercount < smallest_team_player_count)
922 smallest_team_index = i;
923 smallest_team_player_count = playercount;
934 if (smallest_team_index == largest_team_index)
943 if (largest_team_player_count - smallest_team_player_count < 2)
951 smallest_team_index,
true);
952 if (switchable_bot !=
NULL)
959 if (switchable_bot ==
NULL)
969 int largest_team_index = 0;
970 int largest_team_player_count = 0;
983 if (largest_team_index == 0)
985 largest_team_index = i;
986 largest_team_player_count = playercount;
988 else if (playercount > largest_team_player_count)
990 largest_team_index = i;
991 largest_team_player_count = playercount;
994 return largest_team_index;
998 int destination_team_index,
bool is_bot)
1001 destination_team_index, is_bot))
1014 if (temp_score >= lowest_score)
1025 lowest_score = temp_score;
1033 return lowest_player;
1046 GameLogEcho(sprintf(
":team:%d:%d:%d", player_id, team_number, type));
1059 Damage(player, player, player, 100000, DEATH_TEAMCHANGE.m_id,
DMG_NOWEP,
1060 player.origin,
'0 0 0');
1065 return balance.m_team_balance_team[index - 1].m_num_players !=
1084 LOG_FATALF(
"TeamBalance_GetTeamFromIndex: Index is invalid: %f", index);
1086 return balance.m_team_balance_team[index - 1];
1101 return team_ent.m_num_players;
1106 return team_ent.m_num_bots;
1110 entity player,
bool use_score)
1112 if (team_a == team_b)
1121 int num_players_team_a = team_a.m_num_players;
1122 int num_players_team_b = team_b.m_num_players;
1125 num_players_team_a -= team_a.m_num_bots;
1126 num_players_team_b -= team_b.m_num_bots;
1128 if (num_players_team_a < num_players_team_b)
1132 if (num_players_team_a > num_players_team_b)
1140 if (team_a.m_team_score < team_b.m_team_score)
1144 if (team_a.m_team_score > team_b.m_team_score)
const int NUM_TEAMS
Number of teams in the game.
int Team_IndexToBit(int index)
Converts team index into bit value that is used in team bitmasks.
int Team_GetWinnerTeam_WithOwnedItems(int min_control_points)
Returns the winner team.
string MapInfo_Type_ToString(Gametype t)
int Team_GetNumberOfTeamsWithOwnedItems()
Returns the number of teams that own items.
#define APP_TEAM_NUM(num, prefix)
One or both teams are invalid.
void TeamBalance_AutoBalanceBots()
Switches a bot from one team to another if teams are not balanced.
bool MoveToTeam(entity client, int team_index, int type)
Moves player to the specified team.
int TeamBalance_CompareTeamsInternal(entity team_a, entity team_b, entity player, bool use_score)
Compares two teams for the purposes of game balance.
bool SetPlayerTeam(entity player, int team_index, int type)
Sets the team of the player.
entity g_team_entities[NUM_TEAMS]
Holds global team entities.
string autocvar_g_forced_team_otherwise
#define PlayerScore_Get(player, scorefield)
Returns the player's score.
int TeamBalance_CompareTeams(entity balance, int team_index_a, int team_index_b, entity player, bool use_score)
Compares two teams for the purposes of game balance.
void Team_SetTeamScore(entity team_ent, float score)
Sets the score of the team.
ERASEABLE void RandomSelection_Init()
int TeamBalance_FindBestTeams(entity balance, entity player, bool use_score)
Returns the bitmask of the teams that will make the game most balanced if the player joins any of the...
void SetPlayerColors(entity player, float _color)
void TeamBalance_Destroy(entity balance)
Destroy the team balance entity.
TeamBalance_CheckAllowedTeams has been called.
int Team_GetNumberOfAlivePlayers(entity team_ent)
Returns the number of alive players in a team.
ClientState CS(Client this)
#define FOREACH_CLIENT(cond, body)
bool Team_IsValidIndex(int index)
Returns whether the team index is valid.
The team was selected by autobalance.
void TeamBalance_JoinBestTeam(entity player)
Assigns the given player to a team that will make the game most balanced.
float RandomSelection_chosen_float
bool autocvar_g_changeteam_banned
entity m_team_balance_team[NUM_TEAMS]
???
int autocvar_bot_vs_human
int Entity_GetTeamIndex(entity this)
Returns the team index of the given entity.
string autocvar_g_forced_team_red
Player has manually selected their team.
bool TeamBalanceTeam_IsAllowed(entity team_ent)
Returns whether the team is allowed.
int Team_GetNumberOfOwnedItems(entity team_ent)
Returns the number of items owned by a team.
entity Entity_GetTeam(entity this)
Returns the team entity of the given entity.
void Player_SetTeamIndexChecked(entity player, int team_index)
Sets the team of the player with all sanity checks.
void Team_SetNumberOfOwnedItems(entity team_ent, int number)
Sets the number of items owned by a team.
#define IS_REAL_CLIENT(v)
int m_num_players
Number of players (both humans and bots) in a team.
void setcolor(entity this, int clr)
bool Entity_HasValidTeam(entity this)
Returns whether the given entity belongs to a valid team.
float autocvar_g_campaign_forceteam
string autocvar_g_forced_team_blue
Force the player to spectator team.
int TeamBalance_GetLargestTeamIndex(entity balance, int teams)
Returns the index of the team with most players that is contained in the given bitmask of teams...
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
void KillPlayerForTeamChange(entity player)
Kills player as a result of team change.
entity Team_GetTeam(int team_num)
Returns the global team entity that corresponds to the given TEAM_NUM value.
bool autocvar_g_balance_teams_prevent_imbalance
Gametype MapInfo_CurrentGametype()
int TeamBalance_GetAllowedTeams(entity balance)
Returns the bitmask of allowed teams.
void SV_ChangeTeam(entity player, int new_color)
Called when the player changes color with the "color" command.
int Player_GetForcedTeamIndex(entity player)
Returns the index of the forced team of the given player.
entity TeamBalance_GetTeam(entity balance, int team_num)
Returns the team entity of the team balance entity that corresponds to the given TEAM_NUM value...
entity TeamBalance_GetTeamFromIndex(entity balance, int index)
Returns the team entity of the team balance entity at the given index.
void TeamBalance_GetTeamCounts(entity balance, entity ignore)
Counts the number of players and various other information about each team.
const int TEAM_NOT_ALLOWED
Indicates that the player is not allowed to join a team.
float autocvar_sv_maxidle_playertospectator
void Player_SetForcedTeamIndex(entity player, int team_index)
Sets the index of the forced team of the given player.
int TeamBalance_FindBestTeam(entity balance, entity player, bool ignore_player)
Finds the team that will make the game most balanced if the player joins it.
bool TeamBalance_IsTeamAllowedInternal(entity balance, int index)
Returns whether the team change to the specified team is allowed.
void Team_SetNumberOfAlivePlayers(entity team_ent, int number)
Sets the number of alive players in a team.
void TeamBalance_BanTeamsExcept(entity balance, int index)
Bans team change to all teams except the given one.
float PlayerScore_Clear(entity player)
Initialize the score of this player if needed.
void GameLogEcho(string s)
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
int Team_GetNumberOfAliveTeams()
Returns the number of alive teams.
entity Team_GetTeamFromIndex(int index)
Returns the global team entity at the given index.
string autocvar_g_forced_team_pink
string autocvar_g_forced_team_yellow
int Team_TeamToIndex(int team_num)
Converts team value into team index.
First team is less than the second one.
int TeamBalanceTeam_GetNumberOfBots(entity team_ent)
Returns the number of bots in a team.
bool Player_SetTeamIndex(entity player, int index)
Sets the team of the player using its index.
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 CPID_IDLING
#define RandomSelection_AddFloat(f, weight, priority)
bool TeamBalance_IsTeamAllowed(entity balance, int index)
Returns whether the team change to the specified team is allowed.
Don't force any team.
The team balance has not been initialized.
const int FRAGS_SPECTATOR
#define MUTATOR_CALLHOOK(id,...)
int TeamBalanceTeam_GetNumberOfPlayers(entity team_ent)
Returns the number of players (both humans and bots) in a team.
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
float m_team_score
The score of the team.
#define new_pure(class)
purely logical entities (.origin doesn't work)
bool Player_HasRealForcedTeam(entity player)
Returns whether player has real forced team.
bool autocvar_g_balance_teams
void Player_DetermineForcedTeam(entity player)
Determines the forced team of the player using current global config.
int TeamBalance_GetNumberOfPlayers(entity balance, int index)
Returns the number of players (both humans and bots) in a team.
int Team_GetWinnerAliveTeam()
Returns the winner team.
int Team_IndexToTeam(int index)
Converts team index into team value.
entity TeamBalance_CheckAllowedTeams(entity for_whom)
Checks whether the player can join teams according to global configuration and mutator settings...
bool autocvar_sv_eventlog
bool PlayerInList(entity player, string list)
int m_team_balance_state
Holds the state of the team balance entity.
void LogTeamChange(float player_id, float team_number, int type)
int m_num_owned_items
Number of items owned by a team.
float Team_GetTeamScore(entity team_ent)
Returns the score of the team.
TeamBalance_GetTeamCounts has been called.
bool Team_IsValidTeam(int team_num)
Returns whether team value is valid.
entity TeamBalance_GetPlayerForTeamSwitch(int source_team_index, int destination_team_index, bool is_bot)
Returns the player who is the most suitable for switching between the given teams.
int m_num_bots
Number of bots in a team.
int m_num_players_alive
Number of alive players in a team.
First team the greater than the second one.