X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fteamplay.qc;h=25acdd3e01595b82a8f584c44bb8f8a72bf1e2d0;hp=51e360a1978d6d508985438cbd632a036b240c89;hb=54f5e3660e26a65316b8a3c803f68c71d1513836;hpb=77f1f3b0667dfde580e45fc96d4957eadc8b83bf diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index 51e360a19..25acdd3e0 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. @@ -36,8 +36,6 @@ const int TEAM_NOT_ALLOWED = -1; .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. -.entity m_lowest_human; ///< Human with the lowest score in a team. -.entity m_lowest_bot; ///< Bot with the lowest score in a team. entity g_team_entities[NUM_TEAMS]; ///< Holds global team entities. @@ -67,24 +65,24 @@ entity Team_GetTeam(int team_num) return g_team_entities[Team_TeamToIndex(team_num) - 1]; } -float Team_GetTeamScore(entity team_) +float Team_GetTeamScore(entity team_ent) { - return team_.m_team_score; + return team_ent.m_team_score; } -void Team_SetTeamScore(entity team_, float score) +void Team_SetTeamScore(entity team_ent, float score) { - team_.m_team_score = score; + team_ent.m_team_score = score; } -int Team_GetNumberOfAlivePlayers(entity team_) +int Team_GetNumberOfAlivePlayers(entity team_ent) { - return team_.m_num_players_alive; + return team_ent.m_num_players_alive; } -void Team_SetNumberOfAlivePlayers(entity team_, int number) +void Team_SetNumberOfAlivePlayers(entity team_ent, int number) { - team_.m_num_players_alive = number; + team_ent.m_num_players_alive = number; } int Team_GetNumberOfAliveTeams() @@ -100,14 +98,14 @@ int Team_GetNumberOfAliveTeams() return result; } -int Team_GetNumberOfControlPoints(entity team_) +int Team_GetNumberOfControlPoints(entity team_ent) { - return team_.m_num_control_points; + return team_ent.m_num_control_points; } -void Team_SetNumberOfControlPoints(entity team_, int number) +void Team_SetNumberOfControlPoints(entity team_ent, int number) { - team_.m_num_control_points = number; + team_ent.m_num_control_points = number; } int Team_GetNumberOfTeamsWithControlPoints() @@ -123,22 +121,6 @@ int Team_GetNumberOfTeamsWithControlPoints() return result; } -void TeamchangeFrags(entity e) -{ - PlayerScore_Clear(e); -} - -void LogTeamchange(float player_id, float team_number, float type) -{ - if(!autocvar_sv_eventlog) - return; - - if(player_id < 1) - return; - - GameLogEcho(strcat(":team:", ftos(player_id), ":", ftos(team_number), ":", ftos(type))); -} - void setcolor(entity this, int clr) { #if 0 @@ -188,9 +170,13 @@ bool Player_SetTeamIndex(entity player, int index) int new_team = Team_IndexToTeam(index); if (player.team == new_team) { - // This is important when players join the game and one of their color - // matches the team color while other doesn't. For example [BOT]Lion. - SetPlayerColors(player, new_team - 1); + if (new_team != -1) + { + // This is important when players join the game and one of their + // color matches the team color while other doesn't. For example + // [BOT]Lion. + SetPlayerColors(player, new_team - 1); + } return true; } int old_index = Team_TeamToIndex(player.team); @@ -199,42 +185,47 @@ bool Player_SetTeamIndex(entity player, int index) // Mutator has blocked team change. return false; } - SetPlayerColors(player, new_team - 1); + if (new_team == -1) + { + player.team = -1; + } + else + { + SetPlayerColors(player, new_team - 1); + } MUTATOR_CALLHOOK(Player_ChangedTeam, player, old_index, index); return true; } -bool SetPlayerTeam(entity player, int destination_team_index, - int source_team_index, bool no_print) +bool SetPlayerTeam(entity player, int team_index, int type) { - if (!Player_SetTeamIndex(player, destination_team_index)) + int old_team_index = Entity_GetTeamIndex(player); + if (!Player_SetTeamIndex(player, team_index)) { return false; } - LogTeamchange(player.playerid, player.team, 3); // log manual team join - if (no_print) + LogTeamchange(player.playerid, player.team, type); + if (team_index != old_team_index) { - return true; + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(player.team, + INFO_JOIN_PLAY_TEAM), player.netname); + KillPlayerForTeamChange(player); } - bprint(playername(player, false), "^7 has changed from ", - Team_IndexToColoredFullName(source_team_index), "^7 to ", - Team_IndexToColoredFullName(destination_team_index), "\n"); return true; } bool MoveToTeam(entity client, int team_index, int type) { + //PrintToChatAll(sprintf("MoveToTeam: %s, %f", client.netname, team_index)); int lockteams_backup = lockteams; // backup any team lock lockteams = 0; // disable locked teams - TeamchangeFrags(client); // move the players frags - if (!Player_SetTeamIndex(client, team_index)) + PlayerScore_Clear(client); + if (!SetPlayerTeam(client, team_index, type)) { lockteams = lockteams_backup; // restore the team lock return false; } - KillPlayerForTeamChange(client); lockteams = lockteams_backup; // restore the team lock - LogTeamchange(client.playerid, client.team, type); return true; } @@ -252,18 +243,28 @@ void KillPlayerForTeamChange(entity player) player.origin, '0 0 0'); } +void LogTeamchange(float player_id, float team_number, int type) +{ + if(!autocvar_sv_eventlog) + return; + + if(player_id < 1) + return; + + GameLogEcho(strcat(":team:", ftos(player_id), ":", ftos(team_number), ":", ftos(type))); +} + entity TeamBalance_CheckAllowedTeams(entity for_whom) { entity balance = spawn(); for (int i = 0; i < NUM_TEAMS; ++i) { - entity team_ = balance.m_team_balance_team[i] = spawn(); - team_.m_team_score = g_team_entities[i].m_team_score; - team_.m_num_players = TEAM_NOT_ALLOWED; - team_.m_num_bots = 0; - team_.m_lowest_human = NULL; - team_.m_lowest_bot = NULL; + entity team_ent = balance.m_team_balance_team[i] = spawn(); + team_ent.m_team_score = g_team_entities[i].m_team_score; + 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; @@ -401,9 +402,9 @@ void TeamBalance_Destroy(entity balance) } for (int i = 0; i < NUM_TEAMS; ++i) { - remove(balance.(m_team_balance_team[i])); + delete(balance.(m_team_balance_team[i])); } - remove(balance); + delete(balance); } int TeamBalance_GetAllowedTeams(entity balance) @@ -463,16 +464,12 @@ void TeamBalance_GetTeamCounts(entity balance, entity ignore) // Mutator has overriden the configuration. for (int i = 1; i <= NUM_TEAMS; ++i) { - entity team_ = TeamBalance_GetTeamFromIndex(balance, i); - if (TeamBalanceTeam_IsAllowed(team_)) + entity team_ent = TeamBalance_GetTeamFromIndex(balance, i); + if (TeamBalanceTeam_IsAllowed(team_ent)) { - MUTATOR_CALLHOOK(TeamBalance_GetTeamCount, i, ignore, - team_.m_num_players, team_.m_num_bots, team_.m_lowest_human, - team_.m_lowest_bot); - team_.m_num_players = M_ARGV(2, float); - team_.m_num_bots = M_ARGV(3, float); - team_.m_lowest_human = M_ARGV(4, entity); - team_.m_lowest_bot = M_ARGV(5, entity); + MUTATOR_CALLHOOK(TeamBalance_GetTeamCount, i, ignore); + team_ent.m_num_players = M_ARGV(2, float); + team_ent.m_num_bots = M_ARGV(3, float); } } } @@ -502,39 +499,15 @@ void TeamBalance_GetTeamCounts(entity balance, entity ignore) { continue; } - entity team_ = TeamBalance_GetTeam(balance, team_num); - if (!TeamBalanceTeam_IsAllowed(team_)) + entity team_ent = TeamBalance_GetTeam(balance, team_num); + if (!TeamBalanceTeam_IsAllowed(team_ent)) { continue; } - ++team_.m_num_players; + ++team_ent.m_num_players; if (IS_BOT_CLIENT(it)) { - ++team_.m_num_bots; - } - float temp_score = PlayerScore_Get(it, SP_SCORE); - if (!IS_BOT_CLIENT(it)) - { - if (team_.m_lowest_human == NULL) - { - team_.m_lowest_human = it; - continue; - } - if (temp_score < PlayerScore_Get(team_.m_lowest_human, - SP_SCORE)) - { - team_.m_lowest_human = it; - } - continue; - } - if (team_.m_lowest_bot == NULL) - { - team_.m_lowest_bot = it; - continue; - } - if (temp_score < PlayerScore_Get(team_.m_lowest_bot, SP_SCORE)) - { - team_.m_lowest_bot = it; + ++team_ent.m_num_bots; } }); } @@ -544,11 +517,11 @@ void TeamBalance_GetTeamCounts(entity balance, entity ignore) { if (Team_IsValidIndex(autocvar_g_campaign_forceteam)) { - entity team_ = TeamBalance_GetTeamFromIndex(balance, + entity team_ent = TeamBalance_GetTeamFromIndex(balance, autocvar_g_campaign_forceteam); - if (team_.m_num_players == team_.m_num_bots) + if (team_ent.m_num_players == team_ent.m_num_bots) { - ++team_.m_num_players; + ++team_ent.m_num_players; } } } @@ -660,6 +633,7 @@ int TeamBalance_FindBestTeams(entity balance, entity player, bool use_score) void TeamBalance_JoinBestTeam(entity this, bool force_best_team) { + //PrintToChatAll(sprintf("JoinBestTeam: %s, %f", this.netname, force_best_team)); // don't join a team if we're not playing a team game if (!teamplay) { @@ -686,8 +660,7 @@ void TeamBalance_JoinBestTeam(entity this, bool force_best_team) if (Team_IsValidIndex(selected_team_index)) { - Player_SetTeamIndex(this, selected_team_index); - LogTeamchange(this.playerid, this.team, 99); + SetPlayerTeam(this, selected_team_index, TEAM_CHANGE_AUTO_RELAXED); TeamBalance_Destroy(balance); return; } @@ -700,15 +673,16 @@ void TeamBalance_JoinBestTeam(entity this, bool force_best_team) } int best_team_index = TeamBalance_FindBestTeam(balance, this, true); int old_team_index = Team_TeamToIndex(this.team); - TeamchangeFrags(this); - Player_SetTeamIndex(this, best_team_index); - LogTeamchange(this.playerid, this.team, 2); // log auto join + TeamBalance_Destroy(balance); + PlayerScore_Clear(this); + if (!SetPlayerTeam(this, best_team_index, TEAM_CHANGE_AUTO)) + { + return; + } if ((old_team_index != -1) && !IS_BOT_CLIENT(this)) { - TeamBalance_AutoBalanceBots(balance, old_team_index, best_team_index); + TeamBalance_AutoBalanceBots(best_team_index, old_team_index); } - KillPlayerForTeamChange(this); - TeamBalance_Destroy(balance); } int TeamBalance_CompareTeams(entity balance, int team_index_a, int team_index_b, @@ -742,28 +716,19 @@ int TeamBalance_CompareTeams(entity balance, int team_index_a, int team_index_b, return TeamBalance_CompareTeamsInternal(team_a, team_b, player, use_score); } -void TeamBalance_AutoBalanceBots(entity balance, int source_team_index, +void TeamBalance_AutoBalanceBots(int source_team_index, int destination_team_index) { - if (balance == NULL) - { - LOG_FATAL("TeamBalance_AutoBalanceBots: Team balance entity is NULL."); - } - if (balance.m_team_balance_state != TEAM_BALANCE_TEAM_COUNTS_FILLED) - { - LOG_FATAL("TeamBalance_AutoBalanceBots: " - "TeamBalance_GetTeamCounts has not been called."); - } if (!Team_IsValidIndex(source_team_index)) { - LOG_WARNF("AutoBalanceBots: Source team index is invalid: %f", - source_team_index); + LOG_WARNF("TeamBalance_AutoBalanceBots: " + "Source team index is invalid: %f", source_team_index); return; } if (!Team_IsValidIndex(destination_team_index)) { - LOG_WARNF("AutoBalanceBots: Destination team index is invalid: %f", - destination_team_index); + LOG_WARNF("TeamBalance_AutoBalanceBots: " + "Destination team index is invalid: %f", destination_team_index); return; } if (!autocvar_g_balance_teams || @@ -771,21 +736,54 @@ void TeamBalance_AutoBalanceBots(entity balance, int source_team_index, { return; } + entity balance = TeamBalance_CheckAllowedTeams(NULL); + TeamBalance_GetTeamCounts(balance, NULL); entity source_team = TeamBalance_GetTeamFromIndex(balance, source_team_index); - if (!TeamBalanceTeam_IsAllowed(source_team)) + entity destination_team = TeamBalance_GetTeamFromIndex(balance, + destination_team_index); + if ((source_team.m_num_bots == 0) || (source_team.m_num_players <= + destination_team.m_num_players)) { + TeamBalance_Destroy(balance); return; } - entity destination_team = TeamBalance_GetTeamFromIndex(balance, - destination_team_index); - if ((destination_team.m_num_players <= source_team.m_num_players) || - (destination_team.m_lowest_bot == NULL)) + TeamBalance_Destroy(balance); + entity lowest_bot = NULL; + if (MUTATOR_CALLHOOK(TeamBalance_GetPlayerForTeamSwitch, source_team_index, + destination_team_index, true)) + { + lowest_bot = M_ARGV(3, entity); + } + else + { + float lowest_score = FLOAT_MAX; + FOREACH_CLIENT(IS_BOT_CLIENT(it) && (Entity_GetTeamIndex(it) == + source_team_index), + { + float temp_score = PlayerScore_Get(it, SP_SCORE); + if (temp_score >= lowest_score) + { + continue; + } + balance = TeamBalance_CheckAllowedTeams(it); + if (TeamBalance_IsTeamAllowed(balance, destination_team_index)) + { + lowest_bot = it; + lowest_score = temp_score; + } + TeamBalance_Destroy(balance); + }); + } + if (lowest_bot == NULL) { return; } - Player_SetTeamIndex(destination_team.m_lowest_bot, source_team_index); - KillPlayerForTeamChange(destination_team.m_lowest_bot); + if (!Player_SetTeamIndex(lowest_bot, destination_team_index)) + { + return; + } + KillPlayerForTeamChange(lowest_bot); } bool TeamBalance_IsTeamAllowedInternal(entity balance, int index) @@ -819,29 +817,19 @@ entity TeamBalance_GetTeam(entity balance, int team_num) return TeamBalance_GetTeamFromIndex(balance, Team_TeamToIndex(team_num)); } -bool TeamBalanceTeam_IsAllowed(entity team_) +bool TeamBalanceTeam_IsAllowed(entity team_ent) { - return team_.m_num_players != TEAM_NOT_ALLOWED; + return team_ent.m_num_players != TEAM_NOT_ALLOWED; } -int TeamBalanceTeam_GetNumberOfPlayers(entity team_) +int TeamBalanceTeam_GetNumberOfPlayers(entity team_ent) { - return team_.m_num_players; + return team_ent.m_num_players; } -int TeamBalanceTeam_GetNumberOfBots(entity team_) +int TeamBalanceTeam_GetNumberOfBots(entity team_ent) { - return team_.m_num_bots; -} - -entity TeamBalanceTeam_GetLowestHuman(entity team_) -{ - return team_.m_lowest_human; -} - -entity TeamBalanceTeam_GetLowestBot(entity team_) -{ - return team_.m_lowest_bot; + return team_ent.m_num_bots; } int TeamBalance_CompareTeamsInternal(entity team_a, entity team_b, @@ -886,10 +874,11 @@ int TeamBalance_CompareTeamsInternal(entity team_a, entity team_b, return TEAMS_COMPARE_EQUAL; } +// Called when the player connects or when they change their color with "color" +// command. void SV_ChangeTeam(entity this, float _color) { - int source_color, destination_color; - int source_team_index, destination_team_index; + //PrintToChatAll(sprintf("SV_ChangeTeam: %s, %f", this.netname, _color)); // in normal deathmatch we can just apply the color and we're done if(!teamplay) @@ -905,6 +894,9 @@ void SV_ChangeTeam(entity this, float _color) if(!teamplay) return; + int source_color, destination_color; + int source_team_index, destination_team_index; + source_color = this.clientcolors & 0x0F; destination_color = _color & 0x0F; @@ -942,7 +934,7 @@ void SV_ChangeTeam(entity this, float _color) // not changing teams if (source_color == destination_color) { - SetPlayerTeam(this, destination_team_index, source_team_index, true); + SetPlayerTeam(this, destination_team_index, TEAM_CHANGE_MANUAL); TeamBalance_Destroy(balance); return; } @@ -964,24 +956,15 @@ void SV_ChangeTeam(entity this, float _color) return; } } + TeamBalance_Destroy(balance); if (IS_PLAYER(this) && source_team_index != destination_team_index) { // reduce frags during a team change - TeamchangeFrags(this); - } - if (!SetPlayerTeam(this, destination_team_index, source_team_index, - !IS_CLIENT(this))) - { - TeamBalance_Destroy(balance); - return; + PlayerScore_Clear(this); } - TeamBalance_AutoBalanceBots(balance, source_team_index, - destination_team_index); - if (!IS_PLAYER(this) || (source_team_index == destination_team_index)) + if (!SetPlayerTeam(this, destination_team_index, TEAM_CHANGE_MANUAL)) { - TeamBalance_Destroy(balance); return; } - KillPlayerForTeamChange(this); - TeamBalance_Destroy(balance); + TeamBalance_AutoBalanceBots(destination_team_index, source_team_index); }