Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
sv_cmd.qh File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void balanceteams ()
void GameCommand_macro_write_aliases (float fh)
void race_deleteTime (string map, float pos)
void shuffleteams ()

Variables

bool balanceteams_on_reset_map
bool shuffleteams_on_reset_map

Function Documentation

◆ balanceteams()

void balanceteams ( )

Definition at line 386 of file sv_cmd.qc.

387{
388 if (!teamplay)
389 {
390 bprint("Can't balance teams when currently not playing a team game.\n");
391 return;
392 }
393 // We want all players in the game, even if they are dead and waiting to respawn (for example in clan arena), but not bots.
394 int active_player_count = 0;
395 FOREACH_CLIENT(!IS_BOT_CLIENT(it) && (IS_PLAYER(it) || INGAME(it)), {
396 ++active_player_count;
397 });
398 if (active_player_count <= 1)
399 {
400 bprint("You need more than 1 player to balance the teams.\n");
401 return;
402 }
403 if (active_player_count > 128)
404 {
405 bprint("Balancing is only supported for max 128 players, you currently have %d players.\n", active_player_count);
406 return;
407 }
408 if (AVAILABLE_TEAMS > 4)
409 {
410 bprint("XonStat does not support balancing with more than 4 teams.\n");
411 return;
412 }
413 // To justify calling the XonStat API, we need `AVAILABLE_TEAMS + 1` players
414 if (active_player_count <= AVAILABLE_TEAMS)
415 {
416 entity switch_players[NUM_TEAMS - 1];
417 bool team_not_empty[NUM_TEAMS];
418 for (int i = 0; i < AVAILABLE_TEAMS; ++i)
419 team_not_empty[i] = false;
420 int switch_count = 0;
421
422 // Find doubling-up players
423 FOREACH_CLIENT(!IS_BOT_CLIENT(it) && (IS_PLAYER(it) || INGAME(it)),
424 {
425 if (team_not_empty[Team_TeamToIndex(it.team) - 1])
426 switch_players[switch_count++] = it;
427 else
428 team_not_empty[Team_TeamToIndex(it.team) - 1] = true;
429 });
430
431 // Move doubling-up players
432 int team_i = 0;
433 for (int i = 0; i < switch_count; ++i)
434 {
435 while (team_not_empty[team_i]) // find an empty team
436 ++team_i;
437 MoveToTeam(switch_players[i], team_i + 1, 6);
438 }
439 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_TEAMS_BALANCED);
440 return;
441 }
442 bprint("Attempting to balance teams by skill...\n");
443 string balance_uri_with_query_params = sprintf("%s?scorefactor=%d&maxDifference=%d&stability=%d&sigmaRange=%.2f",
449 url_single_fopen(balance_uri_with_query_params, FILE_WRITE, balanceteams_handler, NULL);
450}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define IS_PLAYER(s)
Definition player.qh:242
const float FILE_WRITE
void bprint(string text,...)
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1500
int autocvar_g_playerstats_balance_stability
int autocvar_g_playerstats_balance_maxdifference
int autocvar_g_playerstats_balance_scorefactor
string autocvar_g_playerstats_balance_uri
float autocvar_g_playerstats_balance_sigmarange
#define NULL
Definition post.qh:14
#define AVAILABLE_TEAMS
Number of teams that exist currently.
void balanceteams_handler(entity fh, entity p, float status)
Definition sv_cmd.qc:275
#define INGAME(it)
Definition sv_rules.qh:24
bool MoveToTeam(entity client, int team_index, int type)
Moves player to the specified team.
Definition teamplay.qc:331
int Team_TeamToIndex(int team_num)
Converts team value into team index.
Definition teams.qh:184
const int NUM_TEAMS
Max number of teams that could exist, prefer AVAILABLE_TEAMS.
Definition teams.qh:3
bool teamplay
Definition teams.qh:59
ERASEABLE void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
Definition urllib.qc:90
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition utils.qh:15

References autocvar_g_playerstats_balance_maxdifference, autocvar_g_playerstats_balance_scorefactor, autocvar_g_playerstats_balance_sigmarange, autocvar_g_playerstats_balance_stability, autocvar_g_playerstats_balance_uri, AVAILABLE_TEAMS, balanceteams_handler(), bprint(), entity(), FILE_WRITE, FOREACH_CLIENT, INGAME, IS_BOT_CLIENT, IS_PLAYER, MoveToTeam(), NULL, NUM_TEAMS, Send_Notification(), Team_TeamToIndex(), teamplay, and url_single_fopen().

Referenced by GameCommand_balanceteams(), reset_map(), and SERVER_COMMAND().

◆ GameCommand_macro_write_aliases()

void GameCommand_macro_write_aliases ( float fh)

Definition at line 2032 of file sv_cmd.qc.

2033{
2034 FOREACH(SERVER_COMMANDS, true, { CMD_Write_Alias("qc_cmd_sv", it.m_name, it.m_description); });
2035}
#define CMD_Write_Alias(execute, command, description)
Definition generic.qh:34
#define FOREACH(list, cond, body)
Definition iter.qh:19

References CMD_Write_Alias, and FOREACH.

Referenced by GENERIC_COMMAND().

◆ race_deleteTime()

void race_deleteTime ( string map,
float pos )

Definition at line 461 of file race.qc.

462{
463 for(int i = pos; i <= RANKINGS_CNT; ++i)
464 {
465 string therank = ftos(i);
466 if (i == RANKINGS_CNT)
467 {
468 db_remove(ServerProgsDB, strcat(map, record_type, "time", therank));
469 db_remove(ServerProgsDB, strcat(map, record_type, "crypto_idfp", therank));
470 }
471 else
472 {
473 db_put(ServerProgsDB, strcat(map, record_type, "time", therank), ftos(race_readTime(GetMapname(), i+1)));
474 db_put(ServerProgsDB, strcat(map, record_type, "crypto_idfp", therank), race_readUID(GetMapname(), i+1));
475 }
476 }
477
478 race_SendRanking(pos, 0, 1, MSG_ALL);
479 if(pos == 1)
481
483}
string rankings_reply
Definition util.qh:168
const int RANKINGS_CNT
Definition constants.qh:32
string getrankings()
Definition getreplies.qc:46
string GetMapname()
#define db_remove(db, key)
Definition map.qh:100
ERASEABLE void db_put(int db, string key, string value)
Definition map.qh:103
string ftos(float f)
float MSG_ALL
Definition menudefs.qc:57
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
void race_SendRanking(float pos, float prevpos, float del, float msg)
Definition race.qc:293
float race_readTime(string map, float pos)
Definition race.qc:69
void race_send_recordtime(float msg)
Definition race.qc:259
string race_readUID(string map, float pos)
Definition race.qc:74
#define strcpy(this, s)
Definition string.qh:51
string record_type
Definition world.qh:55
float ServerProgsDB
Definition world.qh:127

References db_put(), db_remove, ftos(), GetMapname(), getrankings(), MSG_ALL, race_readTime(), race_readUID(), race_send_recordtime(), race_SendRanking(), RANKINGS_CNT, rankings_reply, record_type, ServerProgsDB, strcat(), and strcpy.

Referenced by GameCommand_delrec().

◆ shuffleteams()

void shuffleteams ( )

Definition at line 1535 of file sv_cmd.qc.

1536{
1537 if (!teamplay)
1538 {
1539 LOG_INFO("Can't shuffle teams when currently not playing a team game.");
1540 return;
1541 }
1542
1543 FOREACH_CLIENT(IS_PLAYER(it) || INGAME(it), {
1544 if (Player_HasRealForcedTeam(it)) {
1545 // we could theoretically assign forced players to their teams
1546 // and shuffle the rest to fill the empty spots but in practise
1547 // either all players or none are gonna have forced teams
1548 LOG_INFO("Can't shuffle teams because at least one player has a forced team.");
1549 return;
1550 }
1551 });
1552
1553 int number_of_teams = 0;
1555 for (int i = 1; i <= AVAILABLE_TEAMS; ++i)
1556 if (TeamBalance_IsTeamAllowed(balance, i))
1557 number_of_teams = max(i, number_of_teams);
1558 TeamBalance_Destroy(balance);
1559
1560 int team_index = 0;
1562 int target_team_index = team_index + 1;
1563 if (Entity_GetTeamIndex(it) != target_team_index)
1564 MoveToTeam(it, target_team_index, 6);
1565 team_index = (team_index + 1) % number_of_teams;
1566 });
1567
1568 bprint("Successfully shuffled the players around randomly.\n");
1569}
#define LOG_INFO(...)
Definition log.qh:62
float max(float f,...)
int Entity_GetTeamIndex(entity this)
Returns the team index of the given entity.
Definition teamplay.qc:210
void TeamBalance_Destroy(entity balance)
Destroy the team balance entity.
Definition teamplay.qc:528
bool Player_HasRealForcedTeam(entity player)
Returns whether player has real forced team.
Definition teamplay.qc:340
entity TeamBalance_CheckAllowedTeams(entity for_whom)
Checks whether the player can join teams according to global configuration and mutator settings.
Definition teamplay.qc:424
bool TeamBalance_IsTeamAllowed(entity balance, int index)
Returns whether the team change to the specified team is allowed.
Definition teamplay.qc:738
#define FOREACH_CLIENT_RANDOM(cond, body)
Definition utils.qh:58

References AVAILABLE_TEAMS, bprint(), entity(), Entity_GetTeamIndex(), FOREACH_CLIENT, FOREACH_CLIENT_RANDOM, INGAME, IS_PLAYER, LOG_INFO, max(), MoveToTeam(), NULL, Player_HasRealForcedTeam(), TeamBalance_CheckAllowedTeams(), TeamBalance_Destroy(), TeamBalance_IsTeamAllowed(), and teamplay.

Referenced by GameCommand_shuffleteams(), reset_map(), and SERVER_COMMAND().

Variable Documentation

◆ balanceteams_on_reset_map

bool balanceteams_on_reset_map

◆ shuffleteams_on_reset_map

bool shuffleteams_on_reset_map