-// set c1...c4 to show what teams are allowed
-void CheckAllowedTeams(entity for_whom)
-{
- int teams_mask = 0;
-
- c1 = c2 = c3 = c4 = -1;
- num_bots_team1 = num_bots_team2 = num_bots_team3 = num_bots_team4 = 0;
-
- string teament_name = string_null;
-
- bool mutator_returnvalue = MUTATOR_CALLHOOK(CheckAllowedTeams, teams_mask, teament_name, for_whom);
- teams_mask = M_ARGV(0, float);
- teament_name = M_ARGV(1, string);
-
- if(!mutator_returnvalue)
- {
- if(teams_mask & BIT(0)) c1 = 0;
- if(teams_mask & BIT(1)) c2 = 0;
- if(teams_mask & BIT(2)) c3 = 0;
- if(teams_mask & BIT(3)) c4 = 0;
- }
-
- // find out what teams are allowed if necessary
- if(teament_name)
- {
- entity head = find(NULL, classname, teament_name);
- while(head)
- {
- switch(head.team)
- {
- case NUM_TEAM_1: c1 = 0; break;
- case NUM_TEAM_2: c2 = 0; break;
- case NUM_TEAM_3: c3 = 0; break;
- case NUM_TEAM_4: c4 = 0; break;
- }
-
- head = find(head, classname, teament_name);
- }
- }
-
- // 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 > 0)
- {
- // find last team available
-
- if(IS_BOT_CLIENT(for_whom))
- {
- if(c4 >= 0) { c3 = c2 = c1 = -1; }
- else if(c3 >= 0) { c4 = c2 = c1 = -1; }
- else { c4 = c3 = c1 = -1; }
- // no further cases, we know at least 2 teams exist
- }
- else
- {
- if(c1 >= 0) { c2 = c3 = c4 = -1; }
- else if(c2 >= 0) { c1 = c3 = c4 = -1; }
- else { c1 = c2 = c4 = -1; }
- // no further cases, bots have one of the teams
- }
- }
- else
- {
- // find first team available
-
- if(IS_BOT_CLIENT(for_whom))
- {
- if(c1 >= 0) { c2 = c3 = c4 = -1; }
- else if(c2 >= 0) { c1 = c3 = c4 = -1; }
- else { c1 = c2 = c4 = -1; }
- // no further cases, we know at least 2 teams exist
- }
- else
- {
- if(c4 >= 0) { c3 = c2 = c1 = -1; }
- else if(c3 >= 0) { c4 = c2 = c1 = -1; }
- else { c4 = c3 = c1 = -1; }
- // no further cases, bots have one of the teams
- }
- }
- }
-
- if(!for_whom)
- return;
-
- // if player has a forced team, ONLY allow that one
- if(for_whom.team_forced == NUM_TEAM_1 && c1 >= 0)
- c2 = c3 = c4 = -1;
- else if(for_whom.team_forced == NUM_TEAM_2 && c2 >= 0)
- c1 = c3 = c4 = -1;
- else if(for_whom.team_forced == NUM_TEAM_3 && c3 >= 0)
- c1 = c2 = c4 = -1;
- else if(for_whom.team_forced == NUM_TEAM_4 && c4 >= 0)
- c1 = c2 = c3 = -1;
-}
-
-float PlayerValue(entity p)
-{
- return 1;
- // FIXME: it always returns 1...
-}
-
-// c1...c4 should be set to -1 (not allowed) or 0 (allowed).
-// teams that are allowed will now have their player counts stored in c1...c4
-void GetTeamCounts(entity ignore)
-{
- if (MUTATOR_CALLHOOK(GetTeamCounts) == true)
- {
- if (c1 >= 0)
- {
- MUTATOR_CALLHOOK(GetTeamCount, NUM_TEAM_1, ignore, c1,
- num_bots_team1, lowest_human_team1, lowest_bot_team1);
- c1 = M_ARGV(2, float);
- num_bots_team1 = M_ARGV(3, float);
- lowest_human_team1 = M_ARGV(4, entity);
- lowest_bot_team1 = M_ARGV(5, entity);
- }
- if (c2 >= 0)
- {
- MUTATOR_CALLHOOK(GetTeamCount, NUM_TEAM_2, ignore, c2,
- num_bots_team2, lowest_human_team2, lowest_bot_team2);
- c2 = M_ARGV(2, float);
- num_bots_team2 = M_ARGV(3, float);
- lowest_human_team2 = M_ARGV(4, entity);
- lowest_bot_team2 = M_ARGV(5, entity);
- }
- if (c3 >= 0)
- {
- MUTATOR_CALLHOOK(GetTeamCount, NUM_TEAM_3, ignore, c3,
- num_bots_team3, lowest_human_team3, lowest_bot_team3);
- c3 = M_ARGV(2, float);
- num_bots_team3 = M_ARGV(3, float);
- lowest_human_team3 = M_ARGV(4, entity);
- lowest_bot_team3 = M_ARGV(5, entity);
- }
- if (c4 >= 0)
- {
- MUTATOR_CALLHOOK(GetTeamCount, NUM_TEAM_4, ignore,
- c4, num_bots_team4, lowest_human_team4, lowest_bot_team4);
- c4 = M_ARGV(2, float);
- num_bots_team4 = M_ARGV(3, float);
- lowest_human_team4 = M_ARGV(4, entity);
- lowest_bot_team4 = M_ARGV(5, entity);
- }
- }
- else
- {
- float value, bvalue;
- // now count how many players are on each team already
- float lowest_human_score1 = FLOAT_MAX;
- float lowest_bot_score1 = FLOAT_MAX;
- float lowest_human_score2 = FLOAT_MAX;
- float lowest_bot_score2 = FLOAT_MAX;
- float lowest_human_score3 = FLOAT_MAX;
- float lowest_bot_score3 = FLOAT_MAX;
- float lowest_human_score4 = FLOAT_MAX;
- float lowest_bot_score4 = FLOAT_MAX;
- FOREACH_CLIENT(true,
- {
- float t;
- if (IS_PLAYER(it) || it.caplayer)
- {
- t = it.team;
- }
- else if (it.team_forced > 0)
- {
- t = it.team_forced; // reserve the spot
- }
- else
- {
- continue;
- }
- if (it == ignore)
- {
- continue;
- }
- value = PlayerValue(it);
- if (IS_BOT_CLIENT(it))
- {
- bvalue = value;
- }
- else
- {
- bvalue = 0;
- }
- if (value == 0)
- {
- continue;
- }
- switch (t)
- {
- case NUM_TEAM_1:
- {
- if (c1 < 0)
- {
- break;
- }
- c1 += value;
- num_bots_team1 += bvalue;
- float temp_score = PlayerScore_Get(it, SP_SCORE);
- if (!bvalue)
- {
- if (temp_score < lowest_human_score1)
- {
- lowest_human_team1 = it;
- lowest_human_score1 = temp_score;
- }
- break;
- }
- if (temp_score < lowest_bot_score1)
- {
- lowest_bot_team1 = it;
- lowest_bot_score1 = temp_score;
- }
- break;
- }
- case NUM_TEAM_2:
- {
- if (c2 < 0)
- {
- break;
- }
- c2 += value;
- num_bots_team2 += bvalue;
- float temp_score = PlayerScore_Get(it, SP_SCORE);
- if (!bvalue)
- {
- if (temp_score < lowest_human_score2)
- {
- lowest_human_team2 = it;
- lowest_human_score2 = temp_score;
- }
- break;
- }
- if (temp_score < lowest_bot_score2)
- {
- lowest_bot_team2 = it;
- lowest_bot_score2 = temp_score;
- }
- break;
- }
- case NUM_TEAM_3:
- {
- if (c3 < 0)
- {
- break;
- }
- c3 += value;
- num_bots_team3 += bvalue;
- float temp_score = PlayerScore_Get(it, SP_SCORE);
- if (!bvalue)
- {
- if (temp_score < lowest_human_score3)
- {
- lowest_human_team3 = it;
- lowest_human_score3 = temp_score;
- }
- break;
- }
- if (temp_score < lowest_bot_score3)
- {
- lowest_bot_team3 = it;
- lowest_bot_score3 = temp_score;
- }
- break;
- }
- case NUM_TEAM_4:
- {
- if (c4 < 0)
- {
- break;
- }
- c4 += value;
- num_bots_team4 += bvalue;
- float temp_score = PlayerScore_Get(it, SP_SCORE);
- if (!bvalue)
- {
- if (temp_score < lowest_human_score4)
- {
- lowest_human_team4 = it;
- lowest_human_score4 = temp_score;
- }
- break;
- }
- if (temp_score < lowest_bot_score4)
- {
- lowest_bot_team4 = it;
- lowest_bot_score4 = temp_score;
- }
- break;
- }
- }
- });
- }
-
- // if the player who has a forced team has not joined yet, reserve the spot
- if(autocvar_g_campaign)
- {
- switch(autocvar_g_campaign_forceteam)
- {
- case 1: if(c1 == num_bots_team1) ++c1; break;
- case 2: if(c2 == num_bots_team2) ++c2; break;
- case 3: if(c3 == num_bots_team3) ++c3; break;
- case 4: if(c4 == num_bots_team4) ++c4; break;
- }
- }
-}
-
-bool IsTeamSmallerThanTeam(int team_a, int team_b, entity player,
- bool use_score)
-{
- if (team_a == team_b)
- {
- return false;
- }
- // we assume that CheckAllowedTeams and GetTeamCounts have already been called
- int num_players_team_a = -1, num_players_team_b = -1;
- int num_bots_team_a = 0, num_bots_team_b = 0;
- float score_team_a = 0, score_team_b = 0;
- switch (team_a)
- {
- case 1:
- {
- num_players_team_a = c1;
- num_bots_team_a = num_bots_team1;
- score_team_a = team1_score;
- break;
- }
- case 2:
- {
- num_players_team_a = c2;
- num_bots_team_a = num_bots_team2;
- score_team_a = team2_score;
- break;
- }
- case 3:
- {
- num_players_team_a = c3;
- num_bots_team_a = num_bots_team3;
- score_team_a = team3_score;
- break;
- }
- case 4:
- {
- num_players_team_a = c4;
- num_bots_team_a = num_bots_team4;
- score_team_a = team4_score;
- break;
- }
- }
- switch (team_b)
- {
- case 1:
- {
- num_players_team_b = c1;
- num_bots_team_b = num_bots_team1;
- score_team_b = team1_score;
- break;
- }
- case 2:
- {
- num_players_team_b = c2;
- num_bots_team_b = num_bots_team2;
- score_team_b = team2_score;
- break;
- }
- case 3:
- {
- num_players_team_b = c3;
- num_bots_team_b = num_bots_team3;
- score_team_b = team3_score;
- break;
- }
- case 4:
- {
- num_players_team_b = c4;
- num_bots_team_b = num_bots_team4;
- score_team_b = team4_score;
- break;
- }
- }
- // invalid
- if (num_players_team_a < 0 || num_players_team_b < 0)
- {
- return false;
- }
- if (IS_REAL_CLIENT(player) && bots_would_leave)
- {
- num_players_team_a -= num_bots_team_a;
- num_players_team_b -= num_bots_team_b;
- }
- if (!use_score)
- {
- return num_players_team_a < num_players_team_b;
- }
- if (num_players_team_a < num_players_team_b)
- {
- return true;
- }
- if (num_players_team_a > num_players_team_b)
- {
- return false;
- }
- return score_team_a < score_team_b;
-}
-
-bool IsTeamEqualToTeam(int team_a, int team_b, entity player, bool use_score)
-{
- if (team_a == team_b)
- {
- return true;
- }
- // we assume that CheckAllowedTeams and GetTeamCounts have already been called
- int num_players_team_a = -1, num_players_team_b = -1;
- int num_bots_team_a = 0, num_bots_team_b = 0;
- float score_team_a = 0, score_team_b = 0;
- switch (team_a)
- {
- case 1:
- {
- num_players_team_a = c1;
- num_bots_team_a = num_bots_team1;
- score_team_a = team1_score;
- break;
- }
- case 2:
- {
- num_players_team_a = c2;
- num_bots_team_a = num_bots_team2;
- score_team_a = team2_score;
- break;
- }
- case 3:
- {
- num_players_team_a = c3;
- num_bots_team_a = num_bots_team3;
- score_team_a = team3_score;
- break;
- }
- case 4:
- {
- num_players_team_a = c4;
- num_bots_team_a = num_bots_team4;
- score_team_a = team4_score;
- break;
- }
- }
- switch (team_b)
- {
- case 1:
- {
- num_players_team_b = c1;
- num_bots_team_b = num_bots_team1;
- score_team_b = team1_score;
- break;
- }
- case 2:
- {
- num_players_team_b = c2;
- num_bots_team_b = num_bots_team2;
- score_team_b = team2_score;
- break;
- }
- case 3:
- {
- num_players_team_b = c3;
- num_bots_team_b = num_bots_team3;
- score_team_b = team3_score;
- break;
- }
- case 4:
- {
- num_players_team_b = c4;
- num_bots_team_b = num_bots_team4;
- score_team_b = team4_score;
- break;
- }
- }
- // invalid
- if (num_players_team_a < 0 || num_players_team_b < 0)
- return false;
-
- if (IS_REAL_CLIENT(player) && bots_would_leave)
- {
- num_players_team_a -= num_bots_team_a;
- num_players_team_b -= num_bots_team_b;
- }
- if (!use_score)
- {
- return num_players_team_a == num_players_team_b;
- }
- if (num_players_team_a != num_players_team_b)
- {
- return false;
- }
- return score_team_a == score_team_b;
-}
-
-int FindBestTeams(entity player, bool use_score)