From 39028544b65bf299435dbcb566b4cddf5bbdf13a Mon Sep 17 00:00:00 2001 From: Lyberta Date: Thu, 26 Jul 2018 01:18:57 +0300 Subject: [PATCH] Teamplay: Abstracted forced teams. --- qcsrc/common/minigames/sv_minigames.qc | 4 +- qcsrc/server/autocvars.qh | 6 +- qcsrc/server/client.qc | 39 +--------- qcsrc/server/command/cmd.qc | 4 +- qcsrc/server/command/sv_cmd.qc | 10 +-- qcsrc/server/defs.qh | 2 - qcsrc/server/teamplay.qc | 103 ++++++++++++++++++++++++- qcsrc/server/teamplay.qh | 14 ++++ 8 files changed, 128 insertions(+), 54 deletions(-) diff --git a/qcsrc/common/minigames/sv_minigames.qc b/qcsrc/common/minigames/sv_minigames.qc index 5c6af26615..af74e6a5a6 100644 --- a/qcsrc/common/minigames/sv_minigames.qc +++ b/qcsrc/common/minigames/sv_minigames.qc @@ -9,7 +9,7 @@ void player_clear_minigame(entity player) set_movetype(player, MOVETYPE_WALK); else set_movetype(player, MOVETYPE_FLY_WORLDONLY); - player.team_forced = 0; + Player_SetForcedTeamIndex(player, TEAM_FORCE_DEFAULT); } void minigame_rmplayer(entity minigame_session, entity player) @@ -150,7 +150,7 @@ int minigame_addplayer(entity minigame_session, entity player) PutObserverInServer(player); } if ( autocvar_sv_minigames_observer == 2 ) - player.team_forced = -1; + Player_SetForcedTeamIndex(player, TEAM_FORCE_SPECTATOR); minigame_resend(minigame_session); } diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index 7d73a73a8b..5f5731e2df 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -124,11 +124,7 @@ int autocvar_g_chat_nospectators; bool autocvar_g_chat_teamcolors; bool autocvar_g_chat_tellprivacy; bool autocvar_g_forced_respawn; -string autocvar_g_forced_team_blue; -string autocvar_g_forced_team_otherwise; -string autocvar_g_forced_team_pink; -string autocvar_g_forced_team_red; -string autocvar_g_forced_team_yellow; +string autocvar_g_forced_team_otherwise; // TODO: Move to teamplay.qc #define autocvar_g_friendlyfire cvar("g_friendlyfire") #define autocvar_g_friendlyfire_virtual cvar("g_friendlyfire_virtual") #define autocvar_g_friendlyfire_virtual_force cvar("g_friendlyfire_virtual_force") diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index c356c359fc..5251ee55f9 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -1263,38 +1263,7 @@ void ClientConnect(entity this) TRANSMUTE(Client, this); CS(this).version_nagtime = time + 10 + random() * 10; - // identify the right forced team - if (autocvar_g_campaign) - { - if (IS_REAL_CLIENT(this)) // only players, not bots - { - switch (autocvar_g_campaign_forceteam) - { - case 1: this.team_forced = NUM_TEAM_1; break; - case 2: this.team_forced = NUM_TEAM_2; break; - case 3: this.team_forced = NUM_TEAM_3; break; - case 4: this.team_forced = NUM_TEAM_4; break; - default: this.team_forced = 0; - } - } - } - else if (PlayerInList(this, autocvar_g_forced_team_red)) this.team_forced = NUM_TEAM_1; - else if (PlayerInList(this, autocvar_g_forced_team_blue)) this.team_forced = NUM_TEAM_2; - else if (PlayerInList(this, autocvar_g_forced_team_yellow)) this.team_forced = NUM_TEAM_3; - else if (PlayerInList(this, autocvar_g_forced_team_pink)) this.team_forced = NUM_TEAM_4; - else switch (autocvar_g_forced_team_otherwise) - { - default: this.team_forced = 0; break; - case "red": this.team_forced = NUM_TEAM_1; break; - case "blue": this.team_forced = NUM_TEAM_2; break; - case "yellow": this.team_forced = NUM_TEAM_3; break; - case "pink": this.team_forced = NUM_TEAM_4; break; - case "spectate": - case "spectator": - this.team_forced = -1; - break; - } - if (!teamplay && this.team_forced > 0) this.team_forced = 0; + Player_DetermineForcedTeam(this); int playerid_save = this.playerid; this.playerid = 0; // silent @@ -2107,7 +2076,7 @@ void ShowRespawnCountdown(entity this) .bool team_selected; bool ShowTeamSelection(entity this) { - if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || this.team_selected || (CS(this).wasplayer && autocvar_g_changeteam_banned) || this.team_forced > 0) + if (!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || this.team_selected || (CS(this).wasplayer && autocvar_g_changeteam_banned) || Player_HasRealForcedTeam(this)) return false; stuffcmd(this, "menu_showteamselect\n"); return true; @@ -2155,7 +2124,7 @@ int nJoinAllowed(entity this, entity ignore) return 0; } - if(this && this.team_forced < 0) + if(this && (Player_GetForcedTeamIndex(this) == TEAM_FORCE_SPECTATOR)) return 0; // forced spectators can never join // TODO simplify this @@ -2707,7 +2676,7 @@ void PlayerPreThink (entity this) // don't do this in ClientConnect // many things can go wrong if a client is spawned as player on connection if (MUTATOR_CALLHOOK(AutoJoinOnConnection, this) - || (!(autocvar_sv_spectate || autocvar_g_campaign || this.team_forced < 0) + || (!(autocvar_sv_spectate || autocvar_g_campaign || (Player_GetForcedTeamIndex(this) == TEAM_FORCE_SPECTATOR)) && (!teamplay || autocvar_g_balance_teams))) { campaign_bots_may_start = true; diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc index 0e6781e374..30abb68487 100644 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@ -118,7 +118,7 @@ void ClientCommand_clientversion(entity caller, float request, float argc) // i { // JoinBestTeam(caller, false, true); } - else if (teamplay && !autocvar_sv_spectate && !(caller.team_forced > 0)) + else if (teamplay && !autocvar_sv_spectate && !(Player_GetForcedTeamIndex(caller) > 0)) { TRANSMUTE(Observer, caller); // really? stuffcmd(caller, "menu_showteamselect\n"); @@ -338,7 +338,7 @@ void ClientCommand_selectteam(entity caller, float request, float argc) sprint(caller, "^7selectteam can only be used in teamgames\n"); return; } - if (caller.team_forced > 0) + if (Player_GetForcedTeamIndex(caller) > 0) { sprint(caller, "^7selectteam can not be used as your team is forced\n"); return; diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc index 9ba78c32a0..8b8c345d80 100644 --- a/qcsrc/server/command/sv_cmd.qc +++ b/qcsrc/server/command/sv_cmd.qc @@ -1052,8 +1052,8 @@ void GameCommand_moveplayer(float request, float argc) { // set up float team_id; - float save = client.team_forced; - client.team_forced = 0; + int save = Player_GetForcedTeamIndex(client); + Player_SetForcedTeamIndex(client, TEAM_FORCE_DEFAULT); // find the team to move the player to team_id = Team_ColorToTeam(destination); @@ -1073,7 +1073,7 @@ void GameCommand_moveplayer(float request, float argc) { balance = TeamBalance_CheckAllowedTeams(client); } - client.team_forced = save; + Player_SetForcedTeamIndex(client, save); // Check to see if the destination team is even available switch (team_id) @@ -1130,7 +1130,7 @@ void GameCommand_moveplayer(float request, float argc) } // If so, lets continue and finally move the player - client.team_forced = 0; + Player_SetForcedTeamIndex(client, TEAM_FORCE_DEFAULT); if (MoveToTeam(client, Team_TeamToIndex(team_id), 6)) { successful = strcat(successful, (successful ? ", " : ""), playername(client, false)); @@ -1312,7 +1312,7 @@ void GameCommand_shuffleteams(float request) } FOREACH_CLIENT(IS_PLAYER(it) || it.caplayer, { - if (it.team_forced) { + if (Player_HasRealForcedTeam(it)) { // we could theoretically assign forced players to their teams // and shuffle the rest to fill the empty spots but in practise // either all players or none are gonna have forced teams diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index d2a695aeb9..908d994448 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -354,8 +354,6 @@ const float ACTIVE_TOGGLE = 3; //float serverflags; -.float team_forced; // can be a team number to force a team, or 0 for default action, or -1 for forced spectator - .float player_blocked; .float revival_time; // time at which player was last revived diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index 400943a636..6b2778b091 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -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) @@ -254,6 +261,96 @@ 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) +{ + player.team_forced = team_index; +} + +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(); @@ -383,7 +480,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); @@ -487,9 +584,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 { diff --git a/qcsrc/server/teamplay.qh b/qcsrc/server/teamplay.qh index 776a80d329..5e8b9fea71 100644 --- a/qcsrc/server/teamplay.qh +++ b/qcsrc/server/teamplay.qh @@ -110,6 +110,20 @@ enum void LogTeamchange(float player_id, float team_number, int type); +enum +{ + TEAM_FORCE_SPECTATOR = -1, + TEAM_FORCE_DEFAULT = 0 +}; + +bool Player_HasRealForcedTeam(entity player); + +int Player_GetForcedTeamIndex(entity player); + +void Player_SetForcedTeamIndex(entity player, int team_index); + +void Player_DetermineForcedTeam(entity player); + // ========================= Team balance API ================================= /// \brief Checks whether the player can join teams according to global -- 2.39.2