From: Lyberta Date: Mon, 9 Apr 2018 01:03:49 +0000 (+0300) Subject: Improved TeamBalance_AutoBalanceBots. X-Git-Tag: xonotic-v0.8.5~1953^2~18 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=56ce89ae8a7a6d75aa746e2844de468be99adb7b;p=xonotic%2Fxonotic-data.pk3dir.git Improved TeamBalance_AutoBalanceBots. --- diff --git a/qcsrc/server/mutators/events.qh b/qcsrc/server/mutators/events.qh index 7c2fa32dc..9b329e918 100644 --- a/qcsrc/server/mutators/events.qh +++ b/qcsrc/server/mutators/events.qh @@ -146,18 +146,12 @@ MUTATOR_HOOKABLE(TeamBalance_CheckAllowedTeams, /** return true to manually override team counts */ MUTATOR_HOOKABLE(TeamBalance_GetTeamCounts, EV_NO_ARGS); -/** allow overriding of team counts */ +/** allows overriding of team counts */ #define EV_TeamBalance_GetTeamCount(i, o) \ /** team index to count */ i(float, MUTATOR_ARGV_0_float) \ /** player to ignore */ i(entity, MUTATOR_ARGV_1_entity) \ - /** number of players in a team */ i(float, MUTATOR_ARGV_2_float) \ - /**/ o(float, MUTATOR_ARGV_2_float) \ - /** number of bots in a team */ i(float, MUTATOR_ARGV_3_float) \ - /**/ o(float, MUTATOR_ARGV_3_float) \ - /** lowest scoring human in a team */ i(entity, MUTATOR_ARGV_4_entity) \ - /**/ o(entity, MUTATOR_ARGV_4_entity) \ - /** lowest scoring bot in a team */ i(entity, MUTATOR_ARGV_5_entity) \ - /**/ o(entity, MUTATOR_ARGV_5_entity) \ + /** number of players in a team */ o(float, MUTATOR_ARGV_2_float) \ + /** number of bots in a team */ o(float, MUTATOR_ARGV_3_float) \ /**/ MUTATOR_HOOKABLE(TeamBalance_GetTeamCount, EV_TeamBalance_GetTeamCount); @@ -170,6 +164,17 @@ MUTATOR_HOOKABLE(TeamBalance_GetTeamCount, EV_TeamBalance_GetTeamCount); /**/ MUTATOR_HOOKABLE(TeamBalance_FindBestTeams, EV_TeamBalance_FindBestTeams); +/** Called during autobalance. Return true to override the player that will +switched. */ +#define EV_TeamBalance_GetPlayerForTeamSwitch(i, o) \ + /** source team index */ i(int, MUTATOR_ARGV_0_int) \ + /** destination team index */ i(int, MUTATOR_ARGV_1_int) \ + /** is looking for bot */ i(bool, MUTATOR_ARGV_2_bool) \ + /** player to switch */ o(entity, MUTATOR_ARGV_3_entity) \ + /**/ +MUTATOR_HOOKABLE(TeamBalance_GetPlayerForTeamSwitch, + EV_TeamBalance_GetPlayerForTeamSwitch); + /** copies variables for spectating "spectatee" to "this" */ #define EV_SpectateCopy(i, o) \ /** spectatee */ i(entity, MUTATOR_ARGV_0_entity) \ diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index 6a6a26341..1e91d72c3 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -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. @@ -256,8 +254,6 @@ entity TeamBalance_CheckAllowedTeams(entity for_whom) 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; - team_ent.m_lowest_human = NULL; - team_ent.m_lowest_bot = NULL; } int teams_mask = 0; @@ -461,13 +457,9 @@ void TeamBalance_GetTeamCounts(entity balance, entity ignore) entity team_ent = TeamBalance_GetTeamFromIndex(balance, i); if (TeamBalanceTeam_IsAllowed(team_ent)) { - MUTATOR_CALLHOOK(TeamBalance_GetTeamCount, i, ignore, - team_ent.m_num_players, team_ent.m_num_bots, - team_ent.m_lowest_human, team_ent.m_lowest_bot); + MUTATOR_CALLHOOK(TeamBalance_GetTeamCount, i, ignore); team_ent.m_num_players = M_ARGV(2, float); team_ent.m_num_bots = M_ARGV(3, float); - team_ent.m_lowest_human = M_ARGV(4, entity); - team_ent.m_lowest_bot = M_ARGV(5, entity); } } } @@ -507,30 +499,6 @@ void TeamBalance_GetTeamCounts(entity balance, entity ignore) { ++team_ent.m_num_bots; } - float temp_score = PlayerScore_Get(it, SP_SCORE); - if (!IS_BOT_CLIENT(it)) - { - if (team_ent.m_lowest_human == NULL) - { - team_ent.m_lowest_human = it; - continue; - } - if (temp_score < PlayerScore_Get(team_ent.m_lowest_human, - SP_SCORE)) - { - team_ent.m_lowest_human = it; - } - continue; - } - if (team_ent.m_lowest_bot == NULL) - { - team_ent.m_lowest_bot = it; - continue; - } - if (temp_score < PlayerScore_Get(team_ent.m_lowest_bot, SP_SCORE)) - { - team_ent.m_lowest_bot = it; - } }); } @@ -695,15 +663,15 @@ 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); + TeamBalance_Destroy(balance); PlayerScore_Clear(this); Player_SetTeamIndex(this, best_team_index); LogTeamchange(this.playerid, this.team, TEAM_CHANGE_AUTO); 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); + KillPlayerForTeamChange(this); } int TeamBalance_CompareTeams(entity balance, int team_index_a, int team_index_b, @@ -737,28 +705,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 || @@ -766,21 +725,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) @@ -829,16 +821,6 @@ int TeamBalanceTeam_GetNumberOfBots(entity team_ent) return team_ent.m_num_bots; } -entity TeamBalanceTeam_GetLowestHuman(entity team_ent) -{ - return team_ent.m_lowest_human; -} - -entity TeamBalanceTeam_GetLowestBot(entity team_ent) -{ - return team_ent.m_lowest_bot; -} - int TeamBalance_CompareTeamsInternal(entity team_a, entity team_b, entity player, bool use_score) { @@ -959,6 +941,7 @@ 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 @@ -967,16 +950,13 @@ void SV_ChangeTeam(entity this, float _color) if (!SetPlayerTeam(this, destination_team_index, source_team_index, !IS_CLIENT(this))) { - TeamBalance_Destroy(balance); + return; } - TeamBalance_AutoBalanceBots(balance, source_team_index, - destination_team_index); + TeamBalance_AutoBalanceBots(destination_team_index, source_team_index); if (!IS_PLAYER(this) || (source_team_index == destination_team_index)) { - TeamBalance_Destroy(balance); return; } KillPlayerForTeamChange(this); - TeamBalance_Destroy(balance); } diff --git a/qcsrc/server/teamplay.qh b/qcsrc/server/teamplay.qh index d40b98504..6a862abb8 100644 --- a/qcsrc/server/teamplay.qh +++ b/qcsrc/server/teamplay.qh @@ -199,13 +199,10 @@ enum int TeamBalance_CompareTeams(entity balance, int team_index_a, int team_index_b, entity player, bool use_score); -/// \brief Auto balances bots in teams after the player has changed team. -/// \param[in] balance Team balance entity. -/// \param[in] source_team_index Previous index of the team of the player. -/// \param[in] destination_team_index Current index of the team of the player. -/// \note You need to call CheckAllowedTeams and GetTeamCounts before calling -/// this function. -void TeamBalance_AutoBalanceBots(entity balance, int source_team_index, +/// \brief Switches a bot from one team to another if teams are not balanced. +/// \param[in] source_team_index Index of the team to switch from. +/// \param[in] destination_team_index Index of the team to switch to. +void TeamBalance_AutoBalanceBots(int source_team_index, int destination_team_index); // ============================ Internal API ================================== @@ -257,22 +254,6 @@ int TeamBalanceTeam_GetNumberOfPlayers(entity team_ent); /// function. int TeamBalanceTeam_GetNumberOfBots(entity team_ent); -/// \brief Returns the human with the lowest score in a team or NULL if there is -/// none. -/// \param[in] team_ent Team entity. -/// \return Human with the lowest score in a team or NULL if there is none. -/// \note You need to call TeamBalance_GetTeamCounts before calling this -/// function. -entity TeamBalanceTeam_GetLowestHuman(entity team_ent); - -/// \brief Returns the bot with the lowest score in a team or NULL if there is -/// none. -/// \param[in] team_ent Team entity. -/// \return Bot with the lowest score in a team or NULL if there is none. -/// \note You need to call TeamBalance_GetTeamCounts before calling this -/// function. -entity TeamBalanceTeam_GetLowestBot(entity team_ent); - /// \brief Compares two teams for the purposes of game balance. /// \param[in] team_a First team. /// \param[in] team_b Second team.