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

Go to the source code of this file.

Macros

#define spectators_allowed   (!autocvar_sv_vote_nospectators || (autocvar_sv_vote_nospectators == 1 && (warmup_stage || intermission_running)))
#define VOTE_COMMAND(name, function, description, assignment)
#define VOTE_COMMAND(name, function, description, assignment)
#define VOTE_COMMAND(name, function, description, assignment)
#define VOTE_COMMANDS(request, caller, arguments, command)

Functions

void Nagger_Init ()
void Nagger_ReadyCounted ()
bool Nagger_SendEntity (entity this, entity to, float sendflags)
void Nagger_VoteChanged ()
void Nagger_VoteCountChanged ()
string OriginalCallerName ()
void print_available_commands_to (entity caller)
void ReadyCount ()
void ReadyRestart (bool forceWarmupEnd)
void ReadyRestart_force (bool is_fake_round_start)
void ReadyRestart_think (entity this)
void reset_map (bool is_fake_round_start)
string ValidateMap (string validated_map, entity caller)
void VoteAccept ()
void VoteCommand (int request, entity caller, int argc, string vote_command)
void VoteCommand_abstain (int request, entity caller)
void VoteCommand_call (int request, entity caller, int argc, string vote_command)
bool Votecommand_check_assignment (entity caller, float assignment)
float VoteCommand_checkargs (float startpos, int argc)
bool VoteCommand_checkinlist (string vote_command, string list)
bool VoteCommand_checknasty (string vote_command)
string VoteCommand_checkreplacements (string input)
string VoteCommand_extractcommand (string input, float startpos, int argc)
float VoteCommand_macro_command (entity caller, int argc, string vote_command)
void VoteCommand_macro_help (entity caller, int argc)
void VoteCommand_master (int request, entity caller, int argc, string vote_command)
void VoteCommand_no (int request, entity caller)
int VoteCommand_parse (entity caller, string vote_command, string vote_list, float startpos, int argc)
void VoteCommand_status (int request, entity caller)
void VoteCommand_stop (int request, entity caller)
void VoteCommand_yes (int request, entity caller)
void VoteCount (float first_count)
void VoteReject ()
void VoteReset (bool verbose)
void VoteSpam (float notvoters, float mincount, string result)
void VoteStop (entity stopper, bool show_name)
void VoteThink ()
void VoteTimeout ()

Macro Definition Documentation

◆ spectators_allowed

Definition at line 218 of file vote.qc.

Referenced by VoteCommand_call(), VoteCommand_master(), and VoteCount().

◆ VOTE_COMMAND [1/3]

#define VOTE_COMMAND ( name,
function,
description,
assignment )
Value:
{ if (Votecommand_check_assignment(caller, assignment)) { print_to(caller, strcat(" ^2", name, "^7: ", description)); } }
string name
Definition menu.qh:30
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
void print_to(entity to, string input)
Definition common.qc:171
bool Votecommand_check_assignment(entity caller, float assignment)
Definition vote.qc:623

◆ VOTE_COMMAND [2/3]

#define VOTE_COMMAND ( name,
function,
description,
assignment )
Value:
{ if (Votecommand_check_assignment(caller, assignment)) { if (name == strtolower(argv(2))) { function; return; } } }
string strtolower(string s)
string argv(float n)

◆ VOTE_COMMAND [3/3]

#define VOTE_COMMAND ( name,
function,
description,
assignment )
Value:
{ if (Votecommand_check_assignment(caller, assignment)) { if (name == strtolower(argv(1))) { function; return true; } } }

◆ VOTE_COMMANDS

#define VOTE_COMMANDS ( request,
caller,
arguments,
command )
Value:
VOTE_COMMAND("abstain", VoteCommand_abstain(request, caller), "Abstain your vote in current vote", VC_ASGNMNT_CLIENTONLY) \
VOTE_COMMAND("call", VoteCommand_call(request, caller, arguments, command), "Create a new vote for players to decide on", VC_ASGNMNT_BOTH) \
VOTE_COMMAND("help", VoteCommand_macro_help(caller, arguments), "Shows this information", VC_ASGNMNT_BOTH) \
VOTE_COMMAND("master", VoteCommand_master(request, caller, arguments, command), "Full control over all voting and vote commands", VC_ASGNMNT_CLIENTONLY) \
VOTE_COMMAND("no", VoteCommand_no(request, caller), "Select no in current vote", VC_ASGNMNT_CLIENTONLY) \
VOTE_COMMAND("status", VoteCommand_status(request, caller), "Prints information about current vote", VC_ASGNMNT_BOTH) \
VOTE_COMMAND("stop", VoteCommand_stop(request, caller), "Immediately end a vote", VC_ASGNMNT_BOTH) \
VOTE_COMMAND("yes", VoteCommand_yes(request, caller), "Select yes in current vote", VC_ASGNMNT_CLIENTONLY) \
/* nothing */
void VoteCommand_call(int request, entity caller, int argc, string vote_command)
Definition vote.qc:986
void VoteCommand_yes(int request, entity caller)
Definition vote.qc:1302
void VoteCommand_no(int request, entity caller)
Definition vote.qc:1213
void VoteCommand_abstain(int request, entity caller)
Definition vote.qc:940
#define VOTE_COMMAND(name, function, description, assignment)
void VoteCommand_macro_help(entity caller, int argc)
Definition vote.qc:1382
void VoteCommand_master(int request, entity caller, int argc, string vote_command)
Definition vote.qc:1093
void VoteCommand_stop(int request, entity caller)
Definition vote.qc:1280
void VoteCommand_status(int request, entity caller)
Definition vote.qc:1258
const float VC_ASGNMNT_BOTH
Definition vote.qh:27
const float VC_ASGNMNT_CLIENTONLY
Definition vote.qh:28

Definition at line 1371 of file vote.qc.

1371#define VOTE_COMMANDS(request, caller, arguments, command) \
1372 VOTE_COMMAND("abstain", VoteCommand_abstain(request, caller), "Abstain your vote in current vote", VC_ASGNMNT_CLIENTONLY) \
1373 VOTE_COMMAND("call", VoteCommand_call(request, caller, arguments, command), "Create a new vote for players to decide on", VC_ASGNMNT_BOTH) \
1374 VOTE_COMMAND("help", VoteCommand_macro_help(caller, arguments), "Shows this information", VC_ASGNMNT_BOTH) \
1375 VOTE_COMMAND("master", VoteCommand_master(request, caller, arguments, command), "Full control over all voting and vote commands", VC_ASGNMNT_CLIENTONLY) \
1376 VOTE_COMMAND("no", VoteCommand_no(request, caller), "Select no in current vote", VC_ASGNMNT_CLIENTONLY) \
1377 VOTE_COMMAND("status", VoteCommand_status(request, caller), "Prints information about current vote", VC_ASGNMNT_BOTH) \
1378 VOTE_COMMAND("stop", VoteCommand_stop(request, caller), "Immediately end a vote", VC_ASGNMNT_BOTH) \
1379 VOTE_COMMAND("yes", VoteCommand_yes(request, caller), "Select yes in current vote", VC_ASGNMNT_CLIENTONLY) \
1380 /* nothing */

Referenced by VoteCommand_macro_command(), and VoteCommand_macro_help().

Function Documentation

◆ Nagger_Init()

void Nagger_Init ( )

Definition at line 97 of file vote.qc.

98{
100}
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
Definition net.qh:123
#define new_pure(class)
purely logical entities (not linked to the area grid)
Definition oo.qh:67
bool Nagger_SendEntity(entity this, entity to, float sendflags)
Definition vote.qc:37
entity nagger
Definition vote.qh:67

References nagger, Nagger_SendEntity(), Net_LinkEntity(), and new_pure.

Referenced by spawnfunc().

◆ Nagger_ReadyCounted()

void Nagger_ReadyCounted ( )

Definition at line 112 of file vote.qc.

113{
114 if (nagger) nagger.SendFlags |= BIT(0);
115}
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition bits.qh:8

References BIT, and nagger.

Referenced by ReadyCount(), and ReadyRestart_force().

◆ Nagger_SendEntity()

bool Nagger_SendEntity ( entity this,
entity to,
float sendflags )

Definition at line 37 of file vote.qc.

38{
39 int nags = 0;
40 WriteHeader(MSG_ENTITY, ENT_CLIENT_NAGGER);
41
42 // bits:
43 // 1 = ready
44 // 2 = player needs to ready up
45 // 4 = vote
46 // 8 = player needs to vote
47 // 16 = warmup
48 // sendflags:
49 // 64 = vote counts
50 // 128 = vote string
51
52 if (warmup_stage)
53 {
54 if (readycount)
55 {
56 nags |= BIT(0);
57 if (!to.ready) nags |= BIT(1);
58 }
59 nags |= BIT(4);
60 }
61
62 if (vote_called)
63 {
64 nags |= BIT(2);
65 if (to.vote_selection == 0) nags |= BIT(3);
66 nags |= sendflags & BIT(6);
67 nags |= sendflags & BIT(7);
68 }
69
70 WriteByte(MSG_ENTITY, nags);
71
72 if (nags & BIT(6))
73 {
77 WriteChar(MSG_ENTITY, to.vote_selection);
78 }
79
81
82 if (nags & BIT(0))
83 {
84 for (int i = 1; i <= maxclients;)
85 {
86 int f = 0;
87 for (int b = 0; b < 8 && i <= maxclients; ++b, ++i)
88 if (edict_num(i).ready)
89 f |= BIT(b);
91 }
92 }
93
94 return true;
95}
bool ready
Definition main.qh:88
bool warmup_stage
Definition main.qh:120
float maxclients
const int MSG_ENTITY
Definition net.qh:115
#define WriteHeader(to, id)
Definition net.qh:221
void WriteString(string data, float dest, float desto)
void WriteChar(float data, float dest, float desto)
void WriteByte(float data, float dest, float desto)
int vote_needed_overall
Definition vote.qh:50
int vote_accept_count
Definition vote.qh:47
int readycount
Definition vote.qh:68
string vote_called_display
Definition vote.qh:55
int vote_called
Definition vote.qh:45
int vote_reject_count
Definition vote.qh:48

References BIT, entity(), maxclients, MSG_ENTITY, ready, readycount, vote_accept_count, vote_called, vote_called_display, vote_needed_overall, vote_reject_count, warmup_stage, WriteByte(), WriteChar(), WriteHeader, and WriteString().

Referenced by Nagger_Init().

◆ Nagger_VoteChanged()

void Nagger_VoteChanged ( )

Definition at line 102 of file vote.qc.

103{
104 if (nagger) nagger.SendFlags |= BIT(7);
105}

References BIT, and nagger.

Referenced by VoteCommand_call(), VoteCommand_master(), and VoteReset().

◆ Nagger_VoteCountChanged()

void Nagger_VoteCountChanged ( )

Definition at line 107 of file vote.qc.

108{
109 if (nagger) nagger.SendFlags |= BIT(6);
110}

References BIT, and nagger.

Referenced by VoteCount().

◆ OriginalCallerName()

string OriginalCallerName ( )

Definition at line 118 of file vote.qc.

119{
120 if (IS_REAL_CLIENT(vote_caller)) return playername(vote_caller.netname, vote_caller.team, false);
121 return vote_caller_name;
122}
string playername(string thename, int teamid, bool team_colorize)
Definition util.qc:2082
string vote_caller_name
Definition vote.qh:44
entity vote_caller
Definition vote.qh:43
#define IS_REAL_CLIENT(v)
Definition utils.qh:17

References IS_REAL_CLIENT, playername(), vote_caller, and vote_caller_name.

Referenced by VoteAccept(), VoteCommand_call(), VoteCommand_master(), VoteCommand_status(), VoteReject(), VoteStop(), and VoteTimeout().

◆ print_available_commands_to()

void print_available_commands_to ( entity caller)

Definition at line 981 of file vote.qc.

982{
983 print_to(caller, strcat("You can call a vote for or execute these commands: ^3", autocvar_sv_vote_commands, "^7 and maybe further ^3arguments^7"));
984}
string autocvar_sv_vote_commands
Definition vote.qh:5

References autocvar_sv_vote_commands, entity(), print_to(), and strcat().

Referenced by VoteCommand_call(), and VoteCommand_macro_help().

◆ ReadyCount()

void ReadyCount ( )

Definition at line 553 of file vote.qc.

554{
555 // cannot reset the game while a timeout is active or pending
556 if (timeout_status) return;
557
558 int total_players = 0, human_players = 0, humans_ready = 0;
559 readycount = 0;
560
563 if (it.ready) ++readycount;
564 if (IS_REAL_CLIENT(it))
565 {
566 ++human_players;
567 if (it.ready) ++humans_ready;
568 }
569 });
570
572
573 // can't read warmup_stage here as it could have been set to 0 by ReadyRestart()
574 // and we need to use this when checking if we should abort the countdown
575 // map_minplayers can only be > 0 if g_warmup was -1 at worldspawn
576 int minplayers = autocvar_g_warmup > 1 ? autocvar_g_warmup : map_minplayers;
577
578 // This allows warmup to end with zero players to prevent complaints
579 // of server never changing map with legacy config (sv_autopause 0).
580 bool badteams = (teamplay && total_players && autocvar_sv_teamnagger)
582 : false;
583
584 if (total_players < minplayers || badteams)
585 {
586 if (game_starttime > time) // someone bailed during countdown, back to warmup
587 {
588 warmup_stage = autocvar_g_warmup; // CAN change it AFTER calling Nagger_ReadyCounted() this frame
590 if (total_players < minplayers)
591 Send_Notification(NOTIF_ALL, NULL, MSG_MULTI, COUNTDOWN_STOP_MINPLAYERS, minplayers);
592 else
593 Send_Notification(NOTIF_ALL, NULL, MSG_MULTI, COUNTDOWN_STOP_BADTEAMS);
594 if (!sv_ready_restart_after_countdown) // if we ran reset_map() at start of countdown
596 }
597 warmup_limit = -1;
598 return; // don't ReadyRestart if players are ready but too few or teams are bad
599 }
600 else if (warmup_limit <= 0
601 && game_starttime <= time) // No countdown in progress, check prevents early countdown end if only player leaves
602 {
603 // there's enough players now and teams are ok
604 // but we're still in infinite warmup and may need to switch to timed warmup
605 warmup_limit = cvar("g_warmup_limit");
606 if (warmup_limit == 0)
608 if (warmup_limit > 0)
610 // implicit else: g_warmup -1 && g_warmup_limit -1 means
611 // warmup continues until enough players AND enough RUPs (no time limit)
612 }
613
614 if (humans_ready && humans_ready >= rint(human_players * bound(0.5, cvar("g_warmup_majority_factor"), 1)))
615 ReadyRestart(true);
616}
#define IS_PLAYER(s)
Definition player.qh:243
float warmup_limit
Definition stats.qh:375
int timeout_status
Definition stats.qh:87
#define autocvar_timelimit
Definition stats.qh:92
float game_starttime
Definition stats.qh:82
float time
int map_minplayers
Definition mapinfo.qh:190
float bound(float min, float value, float max)
float cvar(string name)
float rint(float f)
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1573
#define NULL
Definition post.qh:14
void GiveWarmupResources(entity this)
Definition client.qc:568
bool autocvar_sv_teamnagger
Definition client.qh:58
void ReadyRestart(bool forceWarmupEnd)
Definition vote.qc:526
void Nagger_ReadyCounted()
Definition vote.qc:112
#define INGAME_JOINED(it)
Definition sv_rules.qh:25
int total_players
Definition sv_rules.qh:12
int TeamBalance_SizeDifference(entity ignore)
Returns the size difference between the largest and smallest team (bots included).
Definition teamplay.qc:633
bool teamplay
Definition teams.qh:59
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:50
int autocvar_g_warmup
Definition world.qh:9
bool sv_ready_restart_after_countdown
Definition world.qh:116

References autocvar_g_warmup, autocvar_sv_teamnagger, autocvar_timelimit, bound(), cvar(), FOREACH_CLIENT, game_starttime, GiveWarmupResources(), INGAME_JOINED, IS_PLAYER, IS_REAL_CLIENT, map_minplayers, Nagger_ReadyCounted(), NULL, readycount, ReadyRestart(), rint(), Send_Notification(), sv_ready_restart_after_countdown, TeamBalance_SizeDifference(), teamplay, time, timeout_status, total_players, warmup_limit, and warmup_stage.

Referenced by bot_think(), ClientCommand_ready(), ClientDisconnect(), PutObserverInServer(), PutPlayerInServer(), SetPlayerTeam(), and timeout_handler_reset().

◆ ReadyRestart()

void ReadyRestart ( bool forceWarmupEnd)

Definition at line 526 of file vote.qc.

527{
528 if (MUTATOR_CALLHOOK(ReadyRestart_Deny))
529 {
530 // NOTE: ReadyRestart support is mandatory in campaign
532 error("ReadyRestart must be supported in campaign mode!");
533 localcmd("restart\n"); // if ReadyRestart is denied, restart the server
534 }
535 else if (intermission_running || race_completing) // game is over, ReadyRestart no longer available
536 localcmd("restart\n");
537 else
538 localcmd("\nsv_hook_readyrestart\n");
539
540 if(forceWarmupEnd || autocvar_g_campaign)
541 warmup_stage = 0; // forcefully end warmup and go to match stage
542 else
543 warmup_stage = autocvar_g_warmup; // go into warmup if it's enabled, otherwise restart into match stage
544
545 ReadyRestart_force(false);
546}
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
bool intermission_running
bool autocvar_g_campaign
Definition menu.qc:747
void localcmd(string command,...)
#define error
Definition pre.qh:6
void ReadyRestart_force(bool is_fake_round_start)
Definition vote.qc:441
float race_completing
Definition race.qh:28

References autocvar_g_campaign, autocvar_g_warmup, error, intermission_running, localcmd(), MUTATOR_CALLHOOK, race_completing, ReadyRestart_force(), and warmup_stage.

Referenced by CheckRules_World(), GameCommand_allready(), GameCommand_resetmatch(), Join(), ReadyCount(), and StartFrame().

◆ ReadyRestart_force()

void ReadyRestart_force ( bool is_fake_round_start)

Definition at line 441 of file vote.qc.

442{
444 return;
445 if (!is_fake_round_start && !autocvar_g_campaign)
446 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_COUNTDOWN_RESTART);
447
448 VoteReset(true);
449
450 // clear overtime, we have to decrease timelimit to its original value again.
454
455 if(warmup_stage)
456 game_starttime = time; // Warmup: No countdown in warmup
457 else if (autocvar_g_campaign)
458 game_starttime = time + 3;
459 else
460 game_starttime = time + RESTART_COUNTDOWN; // Go into match mode
461
462 // clear player attributes
464 it.alivetime_start = 0;
465 CS(it).killcount = 0;
466 });
467
468 // if we're ending the warmup stage call the corresponding hook
469 if(!is_fake_round_start && !warmup_stage)
470 localcmd("\nsv_hook_warmupend\n");
471
472 // reset the .ready status of all clients (including spectators and bots)
473 FOREACH_CLIENT(true, { it.ready = false; });
474 readycount = 0;
475 Nagger_ReadyCounted(); // NOTE: this causes a resend of that entity, and will also turn off warmup state on the client
476
477 // lock teams with lockonrestart
480
481 // initiate the restart-countdown-announcer entity
482 if (!is_fake_round_start && sv_ready_restart_after_countdown && !warmup_stage)
483 {
484 entity restart_timer = new_pure(restart_timer);
485 setthink(restart_timer, ReadyRestart_think);
486 restart_timer.nextthink = game_starttime;
487 }
488
489 // If we're returning to warmup join/switch all queued players for consistency:
490 // there's no queueing in warmup and imbalances are handled by sv_teamnagger blocking end of warmup.
491 if (warmup_stage)
492 {
493 // First pass: join player(s) queued for specific team(s)
494 FOREACH_CLIENT(it.wants_join > 0, Join(it, false));
495 // Second pass: join player(s) queued for team autoselection
496 FOREACH_CLIENT(it.wants_join < 0, Join(it, false));
497 }
498
499 // after a restart every players number of allowed timeouts gets reset, too
501 {
502 FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { CS(it).allowed_timeouts = autocvar_sv_timeout_number; });
503 }
504
506 {
508 {
509 if (it.vote_master)
510 ClientData_Touch(it.enemy, true);
511 else
512 {
513 Send_Notification(NOTIF_ONE_ONLY, it, MSG_MULTI, SPECTATE_SPEC_NOTALLOWED);
514 TRANSMUTE(Observer, it);
516 }
517 });
518 }
519
521 reset_map(is_fake_round_start);
522
523 if (autocvar_sv_eventlog) GameLogEcho(":restart");
524}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float game_stopped
Definition stats.qh:81
int overtimes
Definition stats.qh:86
void GameLogEcho(string s)
Definition gamelog.qc:15
bool autocvar_sv_eventlog
Definition gamelog.qh:3
#define PutClientInServer
Definition _all.inc:246
void cvar_set(string name, string value)
string ftos(float f)
#define TRANSMUTE(cname, this,...)
Definition oo.qh:136
#define setthink(e, f)
void Join(entity this, bool queued_join)
it's assumed this isn't called for bots (campaign_bots_may_start, centreprints)
Definition client.qc:2068
void ClientData_Touch(entity e, bool to_spectators_too)
Definition client.qc:185
bool autocvar_sv_spectate
Definition client.qh:57
bool autocvar_sv_timeout
Definition common.qh:5
int autocvar_sv_timeout_number
Definition common.qh:8
void reset_map(bool is_fake_round_start)
Definition vote.qc:351
void VoteReset(bool verbose)
Definition vote.qc:129
void ReadyRestart_think(entity this)
Definition vote.qc:433
const float RESTART_COUNTDOWN
Definition vote.qh:66
int g_race_qualifying
Definition race.qh:13
ClientState CS(Client this)
Definition state.qh:47
bool autocvar_teamplay_lockonrestart
Definition teamplay.qh:5
bool lockteams
Definition teamplay.qh:15
#define IS_SPEC(v)
Definition utils.qh:10
float checkrules_suddendeathwarning
Definition world.qh:36
int checkrules_overtimesadded
Definition world.qh:38
float checkrules_suddendeathend
Definition world.qh:37
float autocvar_timelimit_overtime
Definition world.qh:28

References autocvar_g_campaign, autocvar_sv_eventlog, autocvar_sv_spectate, autocvar_sv_timeout, autocvar_sv_timeout_number, autocvar_teamplay_lockonrestart, autocvar_timelimit, autocvar_timelimit_overtime, checkrules_overtimesadded, checkrules_suddendeathend, checkrules_suddendeathwarning, ClientData_Touch(), CS(), cvar_set(), entity(), FOREACH_CLIENT, ftos(), g_race_qualifying, game_starttime, game_stopped, GameLogEcho(), IS_PLAYER, IS_REAL_CLIENT, IS_SPEC, Join(), localcmd(), lockteams, Nagger_ReadyCounted(), new_pure, NULL, overtimes, PutClientInServer, readycount, ReadyRestart_think(), reset_map(), RESTART_COUNTDOWN, Send_Notification(), setthink, sv_ready_restart_after_countdown, teamplay, time, TRANSMUTE, VoteReset(), and warmup_stage.

Referenced by assault_new_round(), and ReadyRestart().

◆ ReadyRestart_think()

void ReadyRestart_think ( entity this)

Definition at line 433 of file vote.qc.

434{
435 if (!warmup_stage) // if the countdown was not aborted
436 reset_map(false);
437 delete(this);
438}

References entity(), reset_map(), and warmup_stage.

Referenced by ReadyRestart_force().

◆ reset_map()

void reset_map ( bool is_fake_round_start)

Definition at line 351 of file vote.qc.

352{
353 if (time <= game_starttime)
354 {
355 if (game_stopped)
356 return;
357
358 if (!is_fake_round_start)
359 {
362 }
363
366 }
367
369 {
370 shuffleteams();
372 }
373
374 FOREACH_CLIENT(true, {
375 if (time <= game_starttime)
376 accuracy_reset(it); // for spectators too because weapon accuracy is persistent
377 if (!IS_PLAYER(it))
378 continue;
380 entity store = PS(it);
381 if (store)
382 {
383 Inventory_clear(store.inventory);
384 Inventory_update(store);
385 }
386 });
387
388 MUTATOR_CALLHOOK(reset_map_global);
389
391 {
392 if(IS_CLIENT(it))
393 continue;
394 if (it.reset)
395 {
396 it.reset(it);
397 continue;
398 }
399 if (it.team_saved) it.team = it.team_saved;
400 if (it.flags & FL_PROJECTILE) delete(it); // remove any projectiles left
401 });
402
403 // Waypoints and assault start come LAST
405 if (it.reset2) it.reset2(it);
406 });
407
408 // Moving the player reset code here since the player-reset depends
409 // on spawnpoint entities which have to be reset first --blub
410 if (!MUTATOR_CALLHOOK(reset_map_players))
411 {
413 {
414 // PlayerScore_Clear(it);
415 CS(it).killcount = 0;
416 // stop the player from moving so that they stand still once they get respawned
417 it.velocity = '0 0 0';
418 it.avelocity = '0 0 0';
419 CS(it).movement = '0 0 0';
421
422 if(IS_BOT_CLIENT(it))
423 {
424 .entity weaponentity = weaponentities[0];
425 if(it.(weaponentity).m_weapon == WEP_Null)
426 W_NextWeapon(it, 0, weaponentity);
427 }
428 });
429 }
430}
void accuracy_reset(entity e)
Definition accuracy.qc:63
#define IS_NOT_A_CLIENT(s)
Definition player.qh:244
#define IS_CLIENT(s)
Definition player.qh:242
const int FL_PROJECTILE
Definition constants.qh:85
void Inventory_update(entity e)
Definition inventory.qh:159
void Inventory_clear(entity store)
Definition inventory.qh:169
#define FOREACH_ENTITY_ORDERED(cond, body)
Definition iter.qh:138
#define FOREACH_ENTITY_FLOAT_ORDERED(fld, match, body)
Definition iter.qh:175
bool pure_data
Definition oo.qh:9
void PlayerStats_GameReport_Reset_All()
void round_handler_Reset(float next_think)
#define round_handler_IsActive()
void Score_ClearAll()
Clear ALL scores (for ready-restart).
Definition scores.qc:306
void W_NextWeapon(entity this, int list,.entity weaponentity)
Definition selection.qc:322
void player_powerups_remove_all(entity this, bool allow_poweroff_sound)
Definition client.qc:1535
#define PS(this)
Definition state.qh:18
void shuffleteams()
Definition sv_cmd.qc:1339
bool shuffleteams_on_reset_map
Definition sv_cmd.qh:7
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition utils.qh:15
entity weaponentities[MAX_WEAPONSLOTS]
Definition weapon.qh:17

References accuracy_reset(), CS(), entity(), FL_PROJECTILE, FOREACH_CLIENT, FOREACH_ENTITY_FLOAT_ORDERED, FOREACH_ENTITY_ORDERED, game_starttime, game_stopped, Inventory_clear(), Inventory_update(), IS_BOT_CLIENT, IS_CLIENT, IS_NOT_A_CLIENT, IS_PLAYER, MUTATOR_CALLHOOK, player_powerups_remove_all(), PlayerStats_GameReport_Reset_All(), PS, pure_data, PutClientInServer, round_handler_IsActive, round_handler_Reset(), Score_ClearAll(), shuffleteams(), shuffleteams_on_reset_map, time, W_NextWeapon(), and weaponentities.

Referenced by ReadyRestart_force(), ReadyRestart_think(), and round_handler_Think().

◆ ValidateMap()

string ValidateMap ( string validated_map,
entity caller )

Definition at line 672 of file vote.qc.

673{
674 validated_map = MapInfo_FixName(validated_map);
675
676 if (!validated_map)
677 {
678 print_to(caller, "This map is not available on this server.");
679 return string_null;
680 }
681
683 {
684 if (Map_IsRecent(validated_map))
685 {
686 print_to(caller, "This server does not allow for recent maps to be played again. Please be patient for some rounds.");
687 return string_null;
688 }
689 }
690
691 if (!MapInfo_CheckMap(validated_map))
692 {
693 print_to(caller, strcat("^1Invalid mapname, \"^3", validated_map, "^1\" does not support the current gametype."));
694 return string_null;
695 }
696
697 return validated_map;
698}
bool Map_IsRecent(string m)
float MapInfo_CheckMap(string s)
Definition mapinfo.qc:1510
string MapInfo_FixName(string s)
Definition mapinfo.qc:1474
string string_null
Definition nil.qh:9
bool autocvar_sv_vote_override_mostrecent
Definition vote.qh:20

References autocvar_sv_vote_override_mostrecent, entity(), Map_IsRecent(), MapInfo_CheckMap(), MapInfo_FixName(), print_to(), strcat(), and string_null.

Referenced by GameCommand_nextmap(), and VoteCommand_parse().

◆ VoteAccept()

void VoteAccept ( )

Definition at line 171 of file vote.qc.

172{
173 bprint("\{1}^2* ^3", OriginalCallerName(), "^2's vote for ^1", vote_called_display, "^2 was accepted\n");
174
175 if ((vote_called == VOTE_MASTER) && vote_caller) vote_caller.vote_master = true;
177
178 if (vote_caller) vote_caller.vote_waittime = 0; // people like your votes, you don't need to wait to vote again
179
180 VoteReset(false);
181 Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_VOTE_ACCEPT);
182}
void bprint(string text,...)
string OriginalCallerName()
Definition vote.qc:118
string vote_called_command
Definition vote.qh:54
const float VOTE_MASTER
Definition vote.qh:40

References bprint(), localcmd(), NULL, OriginalCallerName(), Send_Notification(), strcat(), vote_called, vote_called_command, vote_called_display, vote_caller, VOTE_MASTER, and VoteReset().

Referenced by VoteCount().

◆ VoteCommand()

void VoteCommand ( int request,
entity caller,
int argc,
string vote_command )

Definition at line 1431 of file vote.qc.

1432{
1433 // Guide for working with argc arguments by example:
1434 // argc: 1 - 2 - 3 - 4
1435 // argv: 0 - 1 - 2 - 3
1436 // cmd vote - master - login - password
1437
1438 switch (request)
1439 {
1441 {
1442 if (VoteCommand_macro_command(caller, argc, vote_command)) return;
1443 }
1444
1445 default:
1446 print_to(caller, strcat(((argv(1) != "") ? strcat("Unknown vote command \"", argv(1), "\"") : "No command provided"), ". For a list of supported commands, try ", GetCommandPrefix(caller), " vote help.\n"));
1447 case CMD_REQUEST_USAGE:
1448 {
1449 VoteCommand_macro_help(caller, argc);
1450 return;
1451 }
1452 }
1453}
const int CMD_REQUEST_COMMAND
Definition command.qh:3
const int CMD_REQUEST_USAGE
Definition command.qh:4
string GetCommandPrefix(entity caller)
Definition common.qc:26
float VoteCommand_macro_command(entity caller, int argc, string vote_command)
Definition vote.qc:1415

References argv(), CMD_REQUEST_COMMAND, CMD_REQUEST_USAGE, entity(), GetCommandPrefix(), print_to(), strcat(), VoteCommand_macro_command(), and VoteCommand_macro_help().

Referenced by COMMON_COMMAND().

◆ VoteCommand_abstain()

void VoteCommand_abstain ( int request,
entity caller )

Definition at line 940 of file vote.qc.

941{
942 switch (request)
943 {
945 {
946 if (PlayerInList(caller, autocvar_g_voteban_list)) // voteban
947 {
948 print_to(caller, "^1You are banned from voting.");
949 Send_Notification(NOTIF_ONE, caller, MSG_CENTER, CENTER_VOTEBANYN);
950 return;
951 }
952
953 if (!vote_called) { print_to(caller, "^1No vote called."); }
954 else if (caller.vote_selection != VOTE_SELECT_NULL && !autocvar_sv_vote_change)
955 {
956 print_to(caller, "^1You have already voted.");
957 }
958
959 else // everything went okay, continue changing vote
960 {
961 print_to(caller, "^1You abstained from your vote.");
962 caller.vote_selection = VOTE_SELECT_ABSTAIN;
963 msg_entity = caller;
965 VoteCount(false);
966 }
967
968 return;
969 }
970
971 default:
973 {
974 print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote abstain"));
975 print_to(caller, " No arguments required.");
976 return;
977 }
978 }
979}
string autocvar_g_voteban_list
Definition banning.qh:16
entity msg_entity
Definition progsdefs.qc:63
bool PlayerInList(entity player, string list)
Definition client.qc:1045
void VoteCount(float first_count)
Definition vote.qc:220
bool autocvar_sv_vote_change
Definition vote.qh:4
const float VOTE_SELECT_NULL
Definition vote.qh:34
const float VOTE_SELECT_ABSTAIN
Definition vote.qh:32
bool autocvar_sv_vote_singlecount
Definition vote.qh:21

References autocvar_g_voteban_list, autocvar_sv_vote_change, autocvar_sv_vote_singlecount, CMD_REQUEST_COMMAND, CMD_REQUEST_USAGE, entity(), GetCommandPrefix(), msg_entity, PlayerInList(), print_to(), Send_Notification(), strcat(), vote_called, VOTE_SELECT_ABSTAIN, VOTE_SELECT_NULL, and VoteCount().

◆ VoteCommand_call()

void VoteCommand_call ( int request,
entity caller,
int argc,
string vote_command )

Definition at line 986 of file vote.qc.

987{
988 switch (request)
989 {
991 {
992 float tmp_playercount = 0;
993 int parse_error;
994
995 if (PlayerInList(caller, autocvar_g_voteban_list)) // voteban
996 {
997 print_to(caller, "^1You are banned from calling a vote.");
998 Send_Notification(NOTIF_ONE, caller, MSG_CENTER, CENTER_VOTEBAN);
999 return;
1000 }
1001
1002 vote_command = VoteCommand_extractcommand(vote_command, 2, argc);
1003
1004 if (!autocvar_sv_vote_call && caller)
1005 {
1006 print_to(caller, "^1Vote calling is not allowed.");
1007 }
1009 {
1010 print_to(caller, "^1Vote calling is not allowed before the match has started.");
1011 }
1012 else if (vote_called)
1013 {
1014 print_to(caller, "^1There is already a vote called.");
1015 }
1016 else if (!spectators_allowed && (caller && !IS_PLAYER(caller)))
1017 {
1018 print_to(caller, "^1Only players can call a vote.");
1019 }
1020 else if (caller && !IS_CLIENT(caller))
1021 {
1022 print_to(caller, "^1Only connected clients can vote.");
1023 }
1024 else if (timeout_status && vote_command != "timein")
1025 {
1026 print_to(caller, "^1You can not call a vote while a timeout is active.");
1027 }
1028 else if (caller && (time < caller.vote_waittime))
1029 {
1030 print_to(caller, strcat("^1You have to wait ^2", ftos(ceil(caller.vote_waittime - time)), "^1 seconds before you can again call a vote."));
1031 }
1032 else if (!VoteCommand_checknasty(vote_command))
1033 {
1034 print_to(caller, "^1Syntax error in command.");
1035 }
1036 else if ((parse_error = VoteCommand_parse(caller, vote_command, autocvar_sv_vote_commands, 2, argc)) <= 0)
1037 {
1038 if(parse_error == 0)
1039 {
1040 if (vote_called_command == "")
1041 VoteCommand_call(CMD_REQUEST_USAGE, caller, argc, vote_command);
1042 else
1043 print_to(caller, "^1This command is not acceptable or not available.");
1044 }
1045 }
1046 else // everything went okay, continue with calling the vote
1047 {
1048 vote_caller = caller; // remember who called the vote
1054
1055 if (caller)
1056 {
1057 caller.vote_selection = VOTE_SELECT_ACCEPT;
1058 caller.vote_waittime = time + autocvar_sv_vote_wait;
1059 msg_entity = caller;
1060 }
1061
1062 FOREACH_CLIENT(IS_REAL_CLIENT(it), { ++tmp_playercount; });
1063
1064 bprint("\{1}^2* ^3", OriginalCallerName(), "^2 calls a vote for ", vote_called_display, "\n");
1066 bprint("\{1}^2* ^3", "^6DEBUG MODE ACTIVE: bots can vote too\n"); // so servers don't forget it on
1068 GameLogEcho(strcat(":vote:vcall:", ftos(vote_caller.playerid), ":", vote_called_display));
1070 VoteCount(true); // needed if you are the only one
1071
1072 if (tmp_playercount > 1 && vote_called != VOTE_NULL)
1073 Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_VOTE_CALL);
1074 }
1075
1076 return;
1077 }
1078
1079 default:
1080 case CMD_REQUEST_USAGE:
1081 {
1082 print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote call <command>"));
1083 print_to(caller, " Where <command> is the command to request a vote upon.");
1084 print_to(caller, strcat("Examples: ", GetCommandPrefix(caller), " vote call gotomap dance"));
1085 print_to(caller, strcat(" ", GetCommandPrefix(caller), " vote call endmatch"));
1087 print_to(caller, "Shortcuts: ^2vcall <command>, vend, vmap, vkick, ...");
1088 return;
1089 }
1090 }
1091}
float ceil(float f)
string strzone(string s)
string GetCallerName(entity caller)
Definition common.qc:33
#define spectators_allowed
Definition vote.qc:218
void print_available_commands_to(entity caller)
Definition vote.qc:981
void Nagger_VoteChanged()
Definition vote.qc:102
string VoteCommand_extractcommand(string input, float startpos, int argc)
Definition vote.qc:634
int VoteCommand_parse(entity caller, string vote_command, string vote_list, float startpos, int argc)
Definition vote.qc:774
bool VoteCommand_checknasty(string vote_command)
Definition vote.qc:644
const float VOTE_NORMAL
Definition vote.qh:39
string vote_parsed_display
Definition vote.qh:57
float vote_endtime
Definition vote.qh:46
bool autocvar_sv_vote_call
Definition vote.qh:3
const float VOTE_NULL
Definition vote.qh:38
string vote_parsed_command
Definition vote.qh:56
bool autocvar_sv_vote_debug
Definition vote.qh:6
const float VOTE_SELECT_ACCEPT
Definition vote.qh:35
float autocvar_sv_vote_timeout
Definition vote.qh:23
float autocvar_sv_vote_wait
Definition vote.qh:24
bool autocvar_sv_vote_gamestart
Definition vote.qh:7

References autocvar_g_voteban_list, autocvar_sv_eventlog, autocvar_sv_vote_call, autocvar_sv_vote_commands, autocvar_sv_vote_debug, autocvar_sv_vote_gamestart, autocvar_sv_vote_timeout, autocvar_sv_vote_wait, bprint(), ceil(), CMD_REQUEST_COMMAND, CMD_REQUEST_USAGE, entity(), FOREACH_CLIENT, ftos(), game_starttime, GameLogEcho(), GetCallerName(), GetCommandPrefix(), IS_CLIENT, IS_PLAYER, IS_REAL_CLIENT, msg_entity, Nagger_VoteChanged(), NULL, OriginalCallerName(), PlayerInList(), print_available_commands_to(), print_to(), Send_Notification(), spectators_allowed, strcat(), strzone(), time, timeout_status, vote_called, vote_called_command, vote_called_display, vote_caller, vote_caller_name, vote_endtime, VOTE_NORMAL, VOTE_NULL, vote_parsed_command, vote_parsed_display, VOTE_SELECT_ACCEPT, VoteCommand_call(), VoteCommand_checknasty(), VoteCommand_extractcommand(), VoteCommand_parse(), and VoteCount().

Referenced by VoteCommand_call().

◆ Votecommand_check_assignment()

bool Votecommand_check_assignment ( entity caller,
float assignment )

Definition at line 623 of file vote.qc.

624{
625 bool from_server = (!caller);
626
627 if ((assignment == VC_ASGNMNT_BOTH)
628 || ((!from_server && assignment == VC_ASGNMNT_CLIENTONLY)
629 || (from_server && assignment == VC_ASGNMNT_SERVERONLY))) return true;
630
631 return false;
632}
const float VC_ASGNMNT_SERVERONLY
Definition vote.qh:29

References entity(), VC_ASGNMNT_BOTH, VC_ASGNMNT_CLIENTONLY, and VC_ASGNMNT_SERVERONLY.

◆ VoteCommand_checkargs()

float VoteCommand_checkargs ( float startpos,
int argc )

Definition at line 700 of file vote.qc.

701{
702 float p, q, check, minargs;
703 string cvarname = strcat("sv_vote_command_restriction_", argv(startpos));
704 string cmdrestriction = ""; // No we don't.
705 string charlist, arg;
706 float checkmate;
707
708 if(cvar_type(cvarname) & CVAR_TYPEFLAG_EXISTS)
709 cmdrestriction = cvar_string(cvarname);
710 else
711 LOG_INFO("NOTE: ", cvarname, " does not exist, no restrictions will be applied.");
712
713 if (cmdrestriction == "") return true;
714
715 ++startpos; // skip command name
716
717 // check minimum arg count
718
719 // 0 args: argc == startpos
720 // 1 args: argc == startpos + 1
721 // ...
722
723 minargs = stof(cmdrestriction);
724 if (argc - startpos < minargs) return false;
725
726 p = strstrofs(cmdrestriction, ";", 0); // find first semicolon
727
728 for ( ; ; )
729 {
730 // we know that at any time, startpos <= argc - minargs
731 // so this means: argc-minargs >= startpos >= argc, thus
732 // argc-minargs >= argc, thus minargs <= 0, thus all minargs
733 // have been seen already
734
735 if (startpos >= argc) // all args checked? GOOD
736 break;
737
738 if (p < 0) // no more args? FAIL
739 {
740 // exception: exactly minargs left, this one included
741 if (argc - startpos == minargs) break;
742
743 // otherwise fail
744 return false;
745 }
746
747 // cut to next semicolon
748 q = strstrofs(cmdrestriction, ";", p + 1); // find next semicolon
749 if (q < 0) charlist = substring(cmdrestriction, p + 1, -1);
750 else charlist = substring(cmdrestriction, p + 1, q - (p + 1));
751
752 // in case we ever want to allow semicolons in VoteCommand_checknasty
753 // charlist = strreplace("^^", ";", charlist);
754
755 if (charlist != "")
756 {
757 // verify the arg only contains allowed chars
758 arg = argv(startpos);
759 checkmate = strlen(arg);
760 for (check = 0; check < checkmate; ++check)
761 if (strstrofs(charlist, substring(arg, check, 1), 0) < 0) return false;
762 // not allowed character
763 // all characters are allowed. FINE.
764 }
765
766 ++startpos;
767 --minargs;
768 p = q;
769 }
770
771 return true;
772}
float CVAR_TYPEFLAG_EXISTS
#define strstrofs
#define strlen
#define LOG_INFO(...)
Definition log.qh:65
float stof(string val,...)
string substring(string s, float start, float length)
const string cvar_string(string name)

References argv(), cvar_string(), CVAR_TYPEFLAG_EXISTS, LOG_INFO, stof(), strcat(), strlen, strstrofs, and substring().

Referenced by VoteCommand_parse().

◆ VoteCommand_checkinlist()

bool VoteCommand_checkinlist ( string vote_command,
string list )

Definition at line 663 of file vote.qc.

664{
665 if (vote_command == "" || list == "")
666 return false;
667
668 string l = VoteCommand_checkreplacements(list);
669 return (strstrofs(l, VoteCommand_checkreplacements(vote_command), 0) >= 0);
670}
string VoteCommand_checkreplacements(string input)
Definition vote.qc:653

References strstrofs, and VoteCommand_checkreplacements().

Referenced by VoteCommand_parse().

◆ VoteCommand_checknasty()

bool VoteCommand_checknasty ( string vote_command)

Definition at line 644 of file vote.qc.

645{
646 return !((strstrofs(vote_command, ";", 0) >= 0)
647 || (strstrofs(vote_command, "\n", 0) >= 0)
648 || (strstrofs(vote_command, "\r", 0) >= 0)
649 || (strstrofs(vote_command, "$", 0) >= 0));
650}

References strstrofs.

Referenced by VoteCommand_call(), and VoteCommand_master().

◆ VoteCommand_checkreplacements()

string VoteCommand_checkreplacements ( string input)

Definition at line 653 of file vote.qc.

654{
655 // add a space around the input so the start and end of the list is captured
656 string output = strcat(" ", input, " ");
657 // allow gotomap replacements
658 output = strreplace(" map ", " gotomap ", output);
659 output = strreplace(" chmap ", " gotomap ", output);
660 return output;
661}

References strcat().

Referenced by VoteCommand_checkinlist().

◆ VoteCommand_extractcommand()

string VoteCommand_extractcommand ( string input,
float startpos,
int argc )

Definition at line 634 of file vote.qc.

635{
636 string output;
637
638 if ((argc - 1) < startpos) output = "";
639 else output = substring(input, argv_start_index(startpos), argv_end_index(-1) - argv_start_index(startpos));
640
641 return output;
642}
#define argv_end_index
#define argv_start_index

References argv_end_index, argv_start_index, and substring().

Referenced by VoteCommand_call(), and VoteCommand_master().

◆ VoteCommand_macro_command()

float VoteCommand_macro_command ( entity caller,
int argc,
string vote_command )

Definition at line 1415 of file vote.qc.

1416{
1417 #define VOTE_COMMAND(name, function, description, assignment) \
1418 { if (Votecommand_check_assignment(caller, assignment)) { if (name == strtolower(argv(1))) { function; return true; } } }
1419
1420 VOTE_COMMANDS(CMD_REQUEST_COMMAND, caller, argc, vote_command);
1421 #undef VOTE_COMMAND
1422
1423 return false;
1424}
#define VOTE_COMMANDS(request, caller, arguments, command)
Definition vote.qc:1371

References CMD_REQUEST_COMMAND, entity(), and VOTE_COMMANDS.

Referenced by VoteCommand().

◆ VoteCommand_macro_help()

void VoteCommand_macro_help ( entity caller,
int argc )

Definition at line 1382 of file vote.qc.

1383{
1384 string command_origin = GetCommandPrefix(caller);
1385
1386 if (argc == 2 || argv(2) == "help") // help display listing all commands
1387 {
1388 print_to(caller, "\nVoting commands:\n");
1389 #define VOTE_COMMAND(name, function, description, assignment) \
1390 { if (Votecommand_check_assignment(caller, assignment)) { print_to(caller, strcat(" ^2", name, "^7: ", description)); } }
1391
1392 VOTE_COMMANDS(0, caller, 0, "");
1393 #undef VOTE_COMMAND
1394
1395 print_to(caller, strcat("\nUsage:^3 ", command_origin, " vote <command>^7, where possible commands are listed above.\n"));
1396 print_to(caller, strcat("For help about a specific command, type ", command_origin, " vote help <command>"));
1398 }
1399 else // usage for individual command
1400 {
1401 #define VOTE_COMMAND(name, function, description, assignment) \
1402 { if (Votecommand_check_assignment(caller, assignment)) { if (name == strtolower(argv(2))) { function; return; } } }
1403
1404 VOTE_COMMANDS(CMD_REQUEST_USAGE, caller, argc, "");
1405 #undef VOTE_COMMAND
1406
1407 string cvarname = strcat("sv_vote_command_help_", argv(2));
1408 if(cvar_type(cvarname) & CVAR_TYPEFLAG_EXISTS)
1409 wordwrap_sprint(caller, cvar_string(cvarname), 1000);
1410 else if (argv(2) != "")
1411 print_to(caller, "No documentation exists for this vote");
1412 }
1413}
void wordwrap_sprint(entity to, string s, float l)
Definition util.qc:192

References argv(), CMD_REQUEST_USAGE, cvar_string(), CVAR_TYPEFLAG_EXISTS, entity(), GetCommandPrefix(), print_available_commands_to(), print_to(), strcat(), VOTE_COMMANDS, and wordwrap_sprint().

Referenced by VoteCommand().

◆ VoteCommand_master()

void VoteCommand_master ( int request,
entity caller,
int argc,
string vote_command )

Definition at line 1093 of file vote.qc.

1094{
1095 switch (request)
1096 {
1098 {
1100 {
1101 switch (strtolower(argv(2)))
1102 {
1103 case "do":
1104 {
1105 int parse_error;
1106 vote_command = VoteCommand_extractcommand(vote_command, 3, argc);
1107
1108 if (!caller.vote_master)
1109 print_to(caller, "^1You do not have vote master privileges.");
1110 else if (!VoteCommand_checknasty(vote_command))
1111 {
1112 print_to(caller, "^1Syntax error in command.");
1113 }
1114 else if ((parse_error = VoteCommand_parse(caller, vote_command, strcat(autocvar_sv_vote_commands, " ", autocvar_sv_vote_master_commands), 3, argc)) <= 0)
1115 {
1116 if(parse_error == 0)
1117 {
1118 if (vote_called_command == "")
1119 VoteCommand_master(CMD_REQUEST_USAGE, caller, argc, vote_command);
1120 else
1121 print_to(caller, "^1This command is not acceptable or not available.");
1122 }
1123 }
1124 else // everything went okay, proceed with command
1125 {
1127 print_to(caller, strcat("Executing command '", vote_parsed_display, "' on server."));
1128 bprint("\{1}^2* ^3", GetCallerName(caller), "^2 used their ^3master^2 status to do \"^2", vote_parsed_display, "^2\".\n");
1130 GameLogEcho(strcat(":vote:vdo:", ftos(caller.playerid), ":", vote_parsed_display));
1131 }
1132
1133 return;
1134 }
1135
1136 case "login":
1137 {
1138 if (autocvar_sv_vote_master_password == "") { print_to(caller, "^1Login to vote master is not allowed."); }
1139 else if (caller.vote_master)
1140 {
1141 print_to(caller, "^1You are already logged in as vote master.");
1142 }
1144 {
1145 print_to(caller, strcat("Rejected vote master login from ", GetCallerName(caller)));
1146 }
1147 else // everything went okay, proceed with giving this player master privilages
1148 {
1149 caller.vote_master = true;
1150 print_to(caller, strcat("Accepted vote master login from ", GetCallerName(caller)));
1151 bprint("\{1}^2* ^3", GetCallerName(caller), "^2 logged in as ^3master^2\n");
1153 GameLogEcho(strcat(":vote:vlogin:", ftos(caller.playerid)));
1154 }
1155
1156 return;
1157 }
1158
1159 default: // calling a vote for master
1160 {
1161 if (!autocvar_sv_vote_master_callable) { print_to(caller, "^1Vote to become vote master is not allowed."); }
1162 else if (vote_called)
1163 {
1164 print_to(caller, "^1There is already a vote called.");
1165 }
1166 else if (!spectators_allowed && (caller && !IS_PLAYER(caller)))
1167 {
1168 print_to(caller, "^1Only players can call a vote.");
1169 }
1170 else if (timeout_status)
1171 {
1172 print_to(caller, "^1You can not call a vote while a timeout is active.");
1173 }
1174 else // everything went okay, continue with creating vote
1175 {
1176 vote_caller = caller;
1180 vote_called_display = strzone("^3master");
1182
1183 caller.vote_selection = VOTE_SELECT_ACCEPT;
1184 caller.vote_waittime = time + autocvar_sv_vote_wait;
1185
1186 bprint("\{1}^2* ^3", OriginalCallerName(), "^2 calls a vote to become ^3master^2.\n");
1188 GameLogEcho(strcat(":vote:vcall:", ftos(vote_caller.playerid), ":", vote_called_display));
1190 VoteCount(true); // needed if you are the only one
1191 }
1192
1193 return;
1194 }
1195 }
1196 }
1197 else { print_to(caller, "^1Master control of voting is not allowed."); }
1198
1199 return;
1200 }
1201
1202 default:
1203 case CMD_REQUEST_USAGE:
1204 {
1205 print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote master [<action> [<command> | <password>]]"));
1206 print_to(caller, " If <action> is left blank, it calls a vote for you to become master.");
1207 print_to(caller, " Otherwise it can be either 'do' (to run <command>) or 'login' as master.");
1208 return;
1209 }
1210 }
1211}
bool autocvar_sv_vote_master_callable
Definition vote.qh:12
bool autocvar_sv_vote_master
Definition vote.qh:11
string autocvar_sv_vote_master_commands
Definition vote.qh:13
string autocvar_sv_vote_master_password
Definition vote.qh:15

References argv(), autocvar_sv_eventlog, autocvar_sv_vote_commands, autocvar_sv_vote_master, autocvar_sv_vote_master_callable, autocvar_sv_vote_master_commands, autocvar_sv_vote_master_password, autocvar_sv_vote_timeout, autocvar_sv_vote_wait, bprint(), CMD_REQUEST_COMMAND, CMD_REQUEST_USAGE, entity(), ftos(), GameLogEcho(), GetCallerName(), GetCommandPrefix(), IS_PLAYER, localcmd(), Nagger_VoteChanged(), OriginalCallerName(), print_to(), spectators_allowed, strcat(), strtolower(), strzone(), time, timeout_status, vote_called, vote_called_command, vote_called_display, vote_caller, vote_caller_name, vote_endtime, VOTE_MASTER, vote_parsed_command, vote_parsed_display, VOTE_SELECT_ACCEPT, VoteCommand_checknasty(), VoteCommand_extractcommand(), VoteCommand_master(), VoteCommand_parse(), and VoteCount().

Referenced by VoteCommand_master().

◆ VoteCommand_no()

void VoteCommand_no ( int request,
entity caller )

Definition at line 1213 of file vote.qc.

1214{
1215 switch (request)
1216 {
1218 {
1219 if (PlayerInList(caller, autocvar_g_voteban_list)) // voteban
1220 {
1221 print_to(caller, "^1You are banned from voting.");
1222 Send_Notification(NOTIF_ONE, caller, MSG_CENTER, CENTER_VOTEBANYN);
1223 return;
1224 }
1225
1226 if (!vote_called) { print_to(caller, "^1No vote called."); }
1227 else if (caller.vote_selection != VOTE_SELECT_NULL && !autocvar_sv_vote_change)
1228 {
1229 print_to(caller, "^1You have already voted.");
1230 }
1231 else if (caller == vote_caller && autocvar_sv_vote_no_stops_vote)
1232 {
1233 VoteStop(caller, false);
1234 }
1235
1236 else // everything went okay, continue changing vote
1237 {
1238 print_to(caller, "^1You rejected the vote.");
1239 caller.vote_selection = VOTE_SELECT_REJECT;
1240 msg_entity = caller;
1242 VoteCount(false);
1243 }
1244
1245 return;
1246 }
1247
1248 default:
1249 case CMD_REQUEST_USAGE:
1250 {
1251 print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote no"));
1252 print_to(caller, " No arguments required.");
1253 return;
1254 }
1255 }
1256}
void VoteStop(entity stopper, bool show_name)
Definition vote.qc:156
bool autocvar_sv_vote_no_stops_vote
Definition vote.qh:17
const float VOTE_SELECT_REJECT
Definition vote.qh:33

References autocvar_g_voteban_list, autocvar_sv_vote_change, autocvar_sv_vote_no_stops_vote, autocvar_sv_vote_singlecount, CMD_REQUEST_COMMAND, CMD_REQUEST_USAGE, entity(), GetCommandPrefix(), msg_entity, PlayerInList(), print_to(), Send_Notification(), strcat(), vote_called, vote_caller, VOTE_SELECT_NULL, VOTE_SELECT_REJECT, VoteCount(), and VoteStop().

◆ VoteCommand_parse()

int VoteCommand_parse ( entity caller,
string vote_command,
string vote_list,
float startpos,
int argc )

Definition at line 774 of file vote.qc.

775{
776 string first_command = argv(startpos);
777 int missing_chars = argv_start_index(startpos);
778
779 if (autocvar_sv_vote_limit > 0 && strlen(vote_command) > autocvar_sv_vote_limit)
780 return 0;
781
782 if (caller && !VoteCommand_checkinlist(first_command, vote_list)) return 0;
783
784 if (!VoteCommand_checkargs(startpos, argc)) return 0;
785
786 switch (MUTATOR_CALLHOOK(VoteCommand_Parse, caller, first_command, vote_command, startpos, argc))
787 {
788 case MUT_VOTEPARSE_CONTINUE: { break; }
789 case MUT_VOTEPARSE_SUCCESS: { return 1; }
790 case MUT_VOTEPARSE_INVALID: { return -1; }
791 case MUT_VOTEPARSE_UNACCEPTABLE: { return 0; }
792 }
793
794 switch (first_command) // now go through and parse the proper commands to adjust as needed.
795 {
796 case "movetoauto":
797 case "movetored":
798 case "movetoblue":
799 case "movetoyellow":
800 case "movetopink":
801 case "movetospec":
802 {
803 entity victim = GetIndexedEntity(argc, (startpos + 1));
804 float accepted = VerifyClientEntity(victim, true, false);
805 if (accepted > 0)
806 {
807 vote_parsed_command = vote_command;
808 vote_parsed_display = sprintf("^1%s #%d ^7%s", first_command, etof(victim), victim.netname);
809 }
810 else
811 {
812 print_to(caller, strcat("vcall: ", GetClientErrorString(accepted, argv(startpos + 1)), ".\n"));
813 return 0;
814 }
815
816 break;
817 }
818
819 case "kick":
820 case "kickban": // catch all kick/kickban commands
821 {
822 entity victim = GetIndexedEntity(argc, (startpos + 1));
823 float accepted = VerifyClientEntity(victim, true, false);
824
825 if (accepted > 0)
826 {
827 string reason = "No reason provided";
828 if(argc > next_token)
829 reason = substring(vote_command, argv_start_index(next_token) - missing_chars, -1);
830
831 string command_arguments = reason;
832 if (first_command == "kickban")
834
835 vote_parsed_command = strcat(first_command, " # ", ftos(etof(victim)), " ", command_arguments);
836 vote_parsed_display = sprintf("^1%s #%d ^7%s^1 %s", first_command, etof(victim), victim.netname, reason);
837 }
838 else
839 {
840 print_to(caller, strcat("vcall: ", GetClientErrorString(accepted, argv(startpos + 1)), ".\n"));
841 return 0;
842 }
843
844 break;
845 }
846
847 case "map":
848 case "chmap":
849 case "gotomap": // re-direct all map selection commands to gotomap
850 {
851 vote_command = ValidateMap(argv(startpos + 1), caller);
852 if (!vote_command) return -1;
853 vote_parsed_command = strcat("gotomap ", vote_command);
855
856 break;
857 }
858
859 // TODO: replicate the old behaviour of being able to vote for maps from different modes on multimode servers (possibly support it in gotomap too)
860 // maybe fallback instead of aborting if map name is invalid?
861 case "nextmap":
862 {
863 vote_command = ValidateMap(argv(startpos + 1), caller);
864 if (!vote_command) return -1;
865 vote_parsed_command = strcat("nextmap ", vote_command);
867
868 break;
869 }
870
871 case "fraglimit": // include restrictions on the maximum votable frag limit
872 {
873 float fraglimit_vote = stof(argv(startpos + 1));
874 float fraglimit_min = 0;
875 float fraglimit_max = 999999;
876 if(fraglimit_vote > fraglimit_max || fraglimit_vote < fraglimit_min)
877 {
878 print_to(caller, strcat("Invalid fraglimit vote, accepted values are between ", ftos(fraglimit_min), " and ", ftos(fraglimit_max), "."));
879 return -1;
880 }
881 vote_parsed_command = strcat("fraglimit ", ftos(fraglimit_vote));
883
884 break;
885 }
886
887 case "timelimit": // include restrictions on the maximum votable time limit
888 {
889 float timelimit_vote = stof(argv(startpos + 1));
890 if(timelimit_vote > autocvar_timelimit_max || timelimit_vote < autocvar_timelimit_min)
891 {
892 print_to(caller, strcat("Invalid timelimit vote, accepted values are between ", ftos(autocvar_timelimit_min), " and ", ftos(autocvar_timelimit_max), "."));
893 return -1;
894 }
895 vote_parsed_command = strcat("timelimit ", ftos(timelimit_vote));
897
898 break;
899 }
900
901 case "restart":
902 {
903 // add a delay so that vote result can be seen and announcer can be heard
904 // if the vote is accepted
905 vote_parsed_command = strcat("defer 1 ", vote_command);
906 vote_parsed_display = strzone(strcat("^1", vote_command));
907
908 break;
909 }
910
911 case "allready":
912 {
913 if(!warmup_stage) {
914 print_to(caller, "Game already started. Use the resetmatch command to restart the match.");
915 return -1;
916 }
917
918 vote_parsed_command = vote_command;
919 vote_parsed_display = strzone(strcat("^1", vote_command));
920 break;
921 }
922
923 default:
924 {
925 vote_parsed_command = vote_command;
926 vote_parsed_display = strzone(strcat("^1", vote_command));
927
928 break;
929 }
930 }
931
932 return 1;
933}
float autocvar_g_ban_default_bantime
Definition banning.qh:3
float autocvar_g_ban_default_masksize
Definition banning.qh:4
#define etof(e)
Definition misc.qh:25
entity GetIndexedEntity(int argc, int start_index)
Definition common.qc:82
int VerifyClientEntity(entity client, bool must_be_real, bool must_be_bots)
Definition common.qc:47
#define GetClientErrorString(clienterror, original_input)
Definition common.qh:87
int next_token
Definition common.qh:71
float VoteCommand_checkargs(float startpos, int argc)
Definition vote.qc:700
string ValidateMap(string validated_map, entity caller)
Definition vote.qc:672
bool VoteCommand_checkinlist(string vote_command, string list)
Definition vote.qc:663
int autocvar_sv_vote_limit
Definition vote.qh:8
@ MUT_VOTEPARSE_CONTINUE
Definition events.qh:1248
@ MUT_VOTEPARSE_UNACCEPTABLE
Definition events.qh:1251
@ MUT_VOTEPARSE_INVALID
Definition events.qh:1250
@ MUT_VOTEPARSE_SUCCESS
Definition events.qh:1249
float autocvar_timelimit_max
Definition world.qh:27
float autocvar_timelimit_min
Definition world.qh:26

References argv(), argv_start_index, autocvar_g_ban_default_bantime, autocvar_g_ban_default_masksize, autocvar_sv_vote_limit, autocvar_timelimit_max, autocvar_timelimit_min, entity(), etof, ftos(), GetClientErrorString, GetIndexedEntity(), MUT_VOTEPARSE_CONTINUE, MUT_VOTEPARSE_INVALID, MUT_VOTEPARSE_SUCCESS, MUT_VOTEPARSE_UNACCEPTABLE, MUTATOR_CALLHOOK, next_token, print_to(), stof(), strcat(), strlen, strzone(), substring(), ValidateMap(), VerifyClientEntity(), vote_parsed_command, vote_parsed_display, VoteCommand_checkargs(), VoteCommand_checkinlist(), and warmup_stage.

Referenced by VoteCommand_call(), and VoteCommand_master().

◆ VoteCommand_status()

void VoteCommand_status ( int request,
entity caller )

Definition at line 1258 of file vote.qc.

1259{
1260 switch (request)
1261 {
1263 {
1264 if (vote_called) print_to(caller, strcat("^7Vote for ", vote_called_display, "^7 called by ^7", OriginalCallerName(), "^7."));
1265 else print_to(caller, "^1No vote called.");
1266
1267 return;
1268 }
1269
1270 default:
1271 case CMD_REQUEST_USAGE:
1272 {
1273 print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote status"));
1274 print_to(caller, " No arguments required.");
1275 return;
1276 }
1277 }
1278}

References CMD_REQUEST_COMMAND, CMD_REQUEST_USAGE, entity(), GetCommandPrefix(), OriginalCallerName(), print_to(), strcat(), vote_called, and vote_called_display.

◆ VoteCommand_stop()

void VoteCommand_stop ( int request,
entity caller )

Definition at line 1280 of file vote.qc.

1281{
1282 switch (request)
1283 {
1285 {
1286 if (!vote_called) print_to(caller, "^1No vote called.");
1287 else if ((caller == vote_caller) || !caller || caller.vote_master) VoteStop(caller, false);
1288 else print_to(caller, "^1You are not allowed to stop that vote.");
1289 return;
1290 }
1291
1292 default:
1293 case CMD_REQUEST_USAGE:
1294 {
1295 print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote stop"));
1296 print_to(caller, " No arguments required.");
1297 return;
1298 }
1299 }
1300}

References CMD_REQUEST_COMMAND, CMD_REQUEST_USAGE, entity(), GetCommandPrefix(), print_to(), strcat(), vote_called, vote_caller, and VoteStop().

◆ VoteCommand_yes()

void VoteCommand_yes ( int request,
entity caller )

Definition at line 1302 of file vote.qc.

1303{
1304 switch (request)
1305 {
1307 {
1308 if (PlayerInList(caller, autocvar_g_voteban_list)) // voteban
1309 {
1310 print_to(caller, "^1You are banned from voting.");
1311 Send_Notification(NOTIF_ONE, caller, MSG_CENTER, CENTER_VOTEBANYN);
1312 return;
1313 }
1314
1315 if (!vote_called) { print_to(caller, "^1No vote called."); }
1316 else if (caller.vote_selection != VOTE_SELECT_NULL && !autocvar_sv_vote_change)
1317 {
1318 print_to(caller, "^1You have already voted.");
1319 }
1320 else // everything went okay, continue changing vote
1321 {
1322 print_to(caller, "^1You accepted the vote.");
1323 caller.vote_selection = VOTE_SELECT_ACCEPT;
1324 msg_entity = caller;
1326 VoteCount(false);
1327 }
1328
1329 return;
1330 }
1331
1332 default:
1333 case CMD_REQUEST_USAGE:
1334 {
1335 print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote yes"));
1336 print_to(caller, " No arguments required.");
1337 return;
1338 }
1339 }
1340}

References autocvar_g_voteban_list, autocvar_sv_vote_change, autocvar_sv_vote_singlecount, CMD_REQUEST_COMMAND, CMD_REQUEST_USAGE, entity(), GetCommandPrefix(), msg_entity, PlayerInList(), print_to(), Send_Notification(), strcat(), vote_called, VOTE_SELECT_ACCEPT, VOTE_SELECT_NULL, and VoteCount().

◆ VoteCount()

void VoteCount ( float first_count)

Definition at line 220 of file vote.qc.

221{
223
224 float vote_player_count = 0, notvoters = 0;
225 float vote_real_player_count = 0, vote_real_accept_count = 0;
226 float vote_real_reject_count = 0, vote_real_abstain_count = 0;
227 float vote_needed_of_voted, final_needed_votes;
228 float vote_factor_overall, vote_factor_of_voted;
229
231
232 // add up all the votes from each connected client
234 ++vote_player_count;
235 if (IS_PLAYER(it) || INGAME(it)) ++vote_real_player_count;
236 switch (it.vote_selection)
237 {
240 if (IS_PLAYER(it) || INGAME(it)) ++vote_real_reject_count;
241 break;
244 if (IS_PLAYER(it) || INGAME(it)) ++vote_real_accept_count;
245 break;
248 if (IS_PLAYER(it) || INGAME(it)) ++vote_real_abstain_count;
249 break;
250 default: break;
251 }
252 });
253
254 // Check to see if there are enough players on the server to allow master voting... otherwise, vote master could be used for evil.
255 if ((vote_called == VOTE_MASTER) && autocvar_sv_vote_master_playerlimit > vote_player_count)
256 {
257 if (vote_caller) vote_caller.vote_waittime = 0;
258 print_to(vote_caller, "^1There are not enough players on this server to allow you to become vote master.");
259 VoteReset(false);
260 return;
261 }
262
263 // if spectators aren't allowed to vote and there are players in a match, then only count the players in the vote and ignore spectators.
264 if (!spectators_allowed && (vote_real_player_count > 0))
265 {
266 vote_accept_count = vote_real_accept_count;
267 vote_reject_count = vote_real_reject_count;
268 vote_abstain_count = vote_real_abstain_count;
269 vote_player_count = vote_real_player_count;
270 }
271
272 // people who have no opinion in any way :D
273 notvoters = (vote_player_count - vote_accept_count - vote_reject_count - vote_abstain_count);
274
275 // determine the goal for the vote to be passed or rejected normally
276 vote_factor_overall = bound(0.5, autocvar_sv_vote_majority_factor, 0.999);
277 vote_needed_overall = floor((vote_player_count - vote_abstain_count) * vote_factor_overall) + 1;
278
279 // if the vote times out, determine the amount of votes needed of the people who actually already voted
280 vote_factor_of_voted = bound(0.5, autocvar_sv_vote_majority_factor_of_voted, 0.999);
281 vote_needed_of_voted = floor((vote_accept_count + vote_reject_count) * vote_factor_of_voted) + 1;
282
283 // are there any players at all on the server? it could be an admin vote
284 if (vote_player_count == 0 && first_count)
285 {
286 VoteSpam(0, -1, "yes"); // no players at all, just accept it
287 VoteAccept();
288 return;
289 }
290
291 // since there ARE players, finally calculate the result of the vote
293 {
294 VoteSpam(notvoters, -1, "yes"); // there is enough acceptions to pass the vote
295 VoteAccept();
296 return;
297 }
298
299 if (vote_reject_count > vote_player_count - vote_abstain_count - vote_needed_overall)
300 {
301 VoteSpam(notvoters, -1, "no"); // there is enough rejections to deny the vote
302 VoteReject();
303 return;
304 }
305
306 // there is not enough votes in either direction, now lets just calculate what the voters have said
307 if (time > vote_endtime)
308 {
309 final_needed_votes = vote_needed_overall;
310
312 {
313 if (vote_accept_count >= vote_needed_of_voted)
314 {
315 VoteSpam(notvoters, min(vote_needed_overall, vote_needed_of_voted), "yes");
316 VoteAccept();
317 return;
318 }
319
321 {
322 VoteSpam(notvoters, min(vote_needed_overall, vote_needed_of_voted), "no");
323 VoteReject();
324 return;
325 }
326
327 final_needed_votes = min(vote_needed_overall, vote_needed_of_voted);
328 }
329
330 // it didn't pass or fail, so not enough votes to even make a decision.
331 VoteSpam(notvoters, final_needed_votes, "timeout");
332 VoteTimeout();
333 }
334}
float min(float f,...)
float floor(float f)
void VoteReject()
Definition vote.qc:184
void Nagger_VoteCountChanged()
Definition vote.qc:107
void VoteTimeout()
Definition vote.qc:191
void VoteSpam(float notvoters, float mincount, string result)
Definition vote.qc:198
void VoteAccept()
Definition vote.qc:171
float autocvar_sv_vote_majority_factor_of_voted
Definition vote.qh:10
int autocvar_sv_vote_master_playerlimit
Definition vote.qh:16
int vote_abstain_count
Definition vote.qh:49
float autocvar_sv_vote_majority_factor
Definition vote.qh:9
#define INGAME(it)
Definition sv_rules.qh:24

References autocvar_sv_vote_debug, autocvar_sv_vote_majority_factor, autocvar_sv_vote_majority_factor_of_voted, autocvar_sv_vote_master_playerlimit, bound(), floor(), FOREACH_CLIENT, INGAME, IS_PLAYER, IS_REAL_CLIENT, min(), Nagger_VoteCountChanged(), print_to(), spectators_allowed, time, vote_abstain_count, vote_accept_count, vote_called, vote_caller, vote_endtime, VOTE_MASTER, vote_needed_overall, vote_reject_count, VOTE_SELECT_ABSTAIN, VOTE_SELECT_ACCEPT, VOTE_SELECT_REJECT, VoteAccept(), VoteReject(), VoteReset(), VoteSpam(), and VoteTimeout().

Referenced by ClientDisconnect(), PutObserverInServer(), VoteCommand_abstain(), VoteCommand_call(), VoteCommand_master(), VoteCommand_no(), VoteCommand_yes(), and VoteThink().

◆ VoteReject()

void VoteReject ( )

Definition at line 184 of file vote.qc.

185{
186 bprint("\{1}^2* ^3", OriginalCallerName(), "^2's vote for ", vote_called_display, "^2 was rejected\n");
187 VoteReset(false);
188 Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_VOTE_FAIL);
189}

References bprint(), NULL, OriginalCallerName(), Send_Notification(), vote_called_display, and VoteReset().

Referenced by VoteCount().

◆ VoteReset()

◆ VoteSpam()

void VoteSpam ( float notvoters,
float mincount,
string result )

Definition at line 198 of file vote.qc.

199{
201 strcat("\{1}^2* vote results: ^1", ftos(vote_accept_count)),
202 strcat("^2:^1", ftos(vote_reject_count)),
203 ((mincount >= 0) ? strcat("^2 (^1", ftos(mincount), "^2 needed)") : "^2"),
204 strcat(", ^1", ftos(vote_abstain_count), "^2 didn't care"),
205 strcat(", ^1", ftos(notvoters), strcat("^2 didn't ", ((mincount >= 0) ? "" : "have to "), "vote\n"))));
206
208 {
210 strcat(":vote:v", result, ":", ftos(vote_accept_count)),
213 strcat(":", ftos(notvoters)),
214 strcat(":", ftos(mincount))));
215 }
216}
entity result
Definition promise.qc:43

References autocvar_sv_eventlog, bprint(), ftos(), GameLogEcho(), result, strcat(), vote_abstain_count, vote_accept_count, and vote_reject_count.

Referenced by VoteCount().

◆ VoteStop()

void VoteStop ( entity stopper,
bool show_name )

Definition at line 156 of file vote.qc.

157{
158 if (canceled) // Code such as NextLevel() stopped it, not a direct action by a human.
159 bprint("\{1}^2* ^3", OriginalCallerName(), "^2's vote was canceled\n");
160 else if (stopper == vote_caller)
161 bprint("\{1}^2* ^3", OriginalCallerName(), "^2 stopped their vote\n");
162 else
163 bprint("\{1}^2* ^3", GetCallerName(stopper), "^2 stopped ^3", OriginalCallerName(), "^2's vote\n");
164
165 if (autocvar_sv_eventlog) GameLogEcho(strcat(":vote:vstop:", ftos(stopper.playerid)));
166 // Don't force them to wait for next vote, this way they can e.g. correct their vote.
167 if ((vote_caller) && (stopper == vote_caller)) vote_caller.vote_waittime = time + autocvar_sv_vote_stop;
168 VoteReset(false);
169}
float autocvar_sv_vote_stop
Definition vote.qh:22

References autocvar_sv_eventlog, autocvar_sv_vote_stop, bprint(), entity(), ftos(), GameLogEcho(), GetCallerName(), OriginalCallerName(), strcat(), time, vote_caller, and VoteReset().

Referenced by VoteCommand_no(), VoteCommand_stop(), and VoteReset().

◆ VoteThink()

void VoteThink ( )

Definition at line 336 of file vote.qc.

337{
338 if (vote_endtime > 0) // a vote was called
339 {
340 if (time > vote_endtime) // time is up
341 VoteCount(false);
342 }
343}

References time, vote_endtime, and VoteCount().

Referenced by CheckRules_World().

◆ VoteTimeout()

void VoteTimeout ( )

Definition at line 191 of file vote.qc.

192{
193 bprint("\{1}^2* ^3", OriginalCallerName(), "^2's vote for ", vote_called_display, "^2 timed out\n");
194 VoteReset(false);
195 Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_VOTE_FAIL);
196}

References bprint(), NULL, OriginalCallerName(), Send_Notification(), vote_called_display, and VoteReset().

Referenced by VoteCount().