X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fteamplay.qc;h=1959fe369791811fd19385308acb52e3795df9be;hb=8f4e38f34794f44d2ea707ca4b836d88b0a39c3d;hp=3faa2d8a83cb24f00ce0472359ee7e5859224e62;hpb=5896259929573bd6f2bef7053022409eedfeb494;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index 3faa2d8a8..1959fe369 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -9,10 +9,10 @@ #include "command/vote.qh" -#include "mutators/_mod.qh" +#include #include "../common/deathtypes/all.qh" -#include "../common/gamemodes/_mod.qh" +#include #include "../common/teams.qh" /// \brief Describes a state of team balance entity. @@ -28,6 +28,8 @@ enum /// \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]; ///< ??? @@ -37,6 +39,11 @@ const int TEAM_NOT_ALLOWED = -1; .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) @@ -185,7 +192,11 @@ bool Player_SetTeamIndex(entity player, int index) // Mutator has blocked team change. return false; } - if (new_team != -1) + if (new_team == -1) + { + player.team = -1; + } + else { SetPlayerColors(player, new_team - 1); } @@ -250,6 +261,116 @@ void LogTeamchange(float player_id, float team_number, int type) 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(); @@ -260,6 +381,7 @@ entity TeamBalance_CheckAllowedTeams(entity for_whom) team_ent.m_num_players = TEAM_NOT_ALLOWED; team_ent.m_num_bots = 0; } + setthink(balance, TeamBalance_Destroy); int teams_mask = 0; string teament_name = string_null; @@ -378,7 +500,7 @@ entity TeamBalance_CheckAllowedTeams(entity for_whom) // 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); @@ -482,9 +604,9 @@ void TeamBalance_GetTeamCounts(entity balance, entity ignore) { 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 { @@ -626,48 +748,40 @@ int TeamBalance_FindBestTeams(entity balance, entity player, bool use_score) return team_bits; } -void TeamBalance_JoinBestTeam(entity this, bool force_best_team) +void TeamBalance_JoinBestTeam(entity this) { - //PrintToChatAll(sprintf("JoinBestTeam: %s, %f", this.netname, force_best_team)); - // don't join a team if we're not playing a team game + //PrintToChatAll(sprintf("JoinBestTeam: %s", this.netname)); if (!teamplay) { return; } - - // find out what teams are available + if (this.bot_forced_team) + { + return; + } + int old_team_index = Team_TeamToIndex(this.team); entity balance = TeamBalance_CheckAllowedTeams(this); - - // if we don't care what team they end up on, put them on whatever team they entered as. - // if they're not on a valid team, then let other code put them on the smallest team - if (!force_best_team) + if (Player_HasRealForcedTeam(this)) { - int selected_team_index = -1; - for (int i = 1; i <= NUM_TEAMS; ++i) + int forced_team_index = this.team_forced; + bool is_team_allowed = TeamBalance_IsTeamAllowedInternal(balance, + forced_team_index); + TeamBalance_Destroy(balance); + if (!is_team_allowed) { - if (TeamBalance_IsTeamAllowedInternal(balance, i) && - (Team_TeamToIndex(this.team) == i)) - { - selected_team_index = i; - break; - } + return; } - - if (Team_IsValidIndex(selected_team_index)) + if (!SetPlayerTeam(this, forced_team_index, TEAM_CHANGE_AUTO)) { - SetPlayerTeam(this, selected_team_index, TEAM_CHANGE_AUTO_RELAXED); - TeamBalance_Destroy(balance); return; } - } - // otherwise end up on the smallest team (handled below) - if (this.bot_forced_team) - { - TeamBalance_Destroy(balance); + 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)) @@ -961,5 +1075,9 @@ void SV_ChangeTeam(entity this, float _color) { return; } + if (source_team_index == -1) + { + return; + } TeamBalance_AutoBalanceBots(destination_team_index, source_team_index); }