X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fteamplay.qc;h=0d248ca1382290ab28885e07fa73a0c47ad3eaee;hp=ff9438e76d84b205679a05982d5b8bc1eb0b57f3;hb=360d5ed5afd2d5b52131b6633e9c38d2ee069b57;hpb=6c3f2ebbfc14b92d5e608e902d4e94e0867cb50b diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index ff9438e76d..0d248ca138 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -1,19 +1,19 @@ #include "teamplay.qh" -#include "client.qh" -#include "race.qh" -#include "scores.qh" -#include "scores_rules.qh" - -#include "bot/api.qh" - -#include "command/vote.qh" - -#include - -#include "../common/deathtypes/all.qh" +#include #include -#include "../common/teams.qh" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /// \brief Describes a state of team balance entity. enum @@ -28,8 +28,6 @@ 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,7 +35,7 @@ const int TEAM_NOT_ALLOWED = -1; .int m_num_players; ///< Number of players (both humans and bots) in a team. .int m_num_bots; ///< Number of bots in a team. .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. +.int m_num_owned_items; ///< Number of items owned by a team. string autocvar_g_forced_team_red; string autocvar_g_forced_team_blue; @@ -46,11 +44,13 @@ string autocvar_g_forced_team_pink; entity g_team_entities[NUM_TEAMS]; ///< Holds global team entities. -STATIC_INIT(g_team_entities) +void Team_InitTeams() { + if (g_team_entities[0]) + return; for (int i = 0; i < NUM_TEAMS; ++i) { - g_team_entities[i] = spawn(); + g_team_entities[i] = new_pure(team_entity); } } @@ -92,6 +92,21 @@ void Team_SetNumberOfAlivePlayers(entity team_ent, int number) team_ent.m_num_players_alive = number; } +int Team_GetWinnerAliveTeam() +{ + int winner = 0; + for (int i = 0; i < NUM_TEAMS; ++i) + { + if (g_team_entities[i].m_num_players_alive > 0) + { + if (winner) + return 0; + winner = Team_IndexToTeam(i + 1); + } + } + return (winner ? winner : -1); +} + int Team_GetNumberOfAliveTeams() { int result = 0; @@ -105,22 +120,37 @@ int Team_GetNumberOfAliveTeams() return result; } -int Team_GetNumberOfControlPoints(entity team_ent) +int Team_GetWinnerTeam_WithOwnedItems(int min_control_points) +{ + int winner = 0; + for (int i = 0; i < NUM_TEAMS; ++i) + { + if (g_team_entities[i].m_num_owned_items >= min_control_points) + { + if (winner) + return 0; + winner = Team_IndexToTeam(i + 1); + } + } + return (winner ? winner : -1); +} + +int Team_GetNumberOfOwnedItems(entity team_ent) { - return team_ent.m_num_control_points; + return team_ent.m_num_owned_items; } -void Team_SetNumberOfControlPoints(entity team_ent, int number) +void Team_SetNumberOfOwnedItems(entity team_ent, int number) { - team_ent.m_num_control_points = number; + team_ent.m_num_owned_items = number; } -int Team_GetNumberOfTeamsWithControlPoints() +int Team_GetNumberOfTeamsWithOwnedItems() { int result = 0; for (int i = 0; i < NUM_TEAMS; ++i) { - if (g_team_entities[i].m_num_control_points > 0) + if (g_team_entities[i].m_num_owned_items > 0) { ++result; } @@ -207,38 +237,38 @@ bool Player_SetTeamIndex(entity player, int index) bool SetPlayerTeam(entity player, int team_index, int type) { int old_team_index = Entity_GetTeamIndex(player); + if (!Player_SetTeamIndex(player, team_index)) - { return false; - } + LogTeamChange(player.playerid, player.team, type); + if (team_index != old_team_index) { - PlayerScore_Clear(player); - if (team_index != -1) - { - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM( - player.team, INFO_JOIN_PLAY_TEAM), player.netname); - } - else - { - if (!CS(player).just_joined) - { - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_SPECTATE, - player.netname); - } - } KillPlayerForTeamChange(player); + PlayerScore_Clear(player); // works only in game modes without teams + if (!IS_BOT_CLIENT(player)) - { TeamBalance_AutoBalanceBots(); - } + + if (team_index != -1) + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(player.team, INFO_JOIN_PLAY_TEAM), player.netname); } - else if (team_index == -1) + + if (team_index == -1) { - if (!CS(player).just_joined && player.frags != FRAGS_SPECTATOR) + if (autocvar_sv_maxidle_playertospectator > 0 && CS(player).idlekick_lasttimeleft) + { + // this done here so it happens even when manually speccing during the countdown + Kill_Notification(NOTIF_ONE_ONLY, player, MSG_CENTER, CPID_IDLING); + CS(player).idlekick_lasttimeleft = 0; + } + else if (!CS(player).just_joined && player.frags != FRAGS_SPECTATOR) + { Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_SPECTATE, player.netname); + } } + return true; } @@ -464,6 +494,7 @@ entity TeamBalance_CheckAllowedTeams(entity for_whom) team_ent.m_num_bots = 0; } setthink(balance, TeamBalance_Destroy); + balance.nextthink = time; int teams_mask = 0; string teament_name = string_null; @@ -496,8 +527,7 @@ entity TeamBalance_CheckAllowedTeams(entity for_whom) } // TODO: Balance quantity of bots across > 2 teams when bot_vs_human is set (and remove next line) - if (AvailableTeams() == 2) - if (autocvar_bot_vs_human && for_whom) + if (autocvar_bot_vs_human && AvailableTeams() == 2 && for_whom) { if (autocvar_bot_vs_human > 0) { @@ -683,7 +713,7 @@ void TeamBalance_GetTeamCounts(entity balance, entity ignore) } int team_num; // TODO: Reconsider when the player is truly on the team. - if (IS_CLIENT(it) || (it.caplayer)) + if (IS_CLIENT(it) || INGAME(it)) { team_num = it.team; } @@ -1123,18 +1153,13 @@ void SV_ChangeTeam(entity player, int new_color) { SetPlayerColors(player, new_color); } - // TODO: Should we really bother with this? if(!IS_CLIENT(player)) { - // since this is an engine function, and gamecode doesn't have any calls earlier than this, do the connecting message here - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_CONNECTING, - player.netname); return; } if (!teamplay) { return; } - Player_SetTeamIndexChecked(player, Team_TeamToIndex((new_color & 0x0F) + - 1)); + Player_SetTeamIndexChecked(player, Team_TeamToIndex((new_color & 0x0F) + 1)); }