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)) { if (name == strtolower(argv(1))) { function; return true; } } }
string strtolower(string s)
string name
Definition menu.qh:30
string argv(float n)
bool Votecommand_check_assignment(entity caller, float assignment)
Definition vote.qc:629

◆ 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; } } }

◆ VOTE_COMMAND [3/3]

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

◆ 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:992
void VoteCommand_yes(int request, entity caller)
Definition vote.qc:1308
void VoteCommand_no(int request, entity caller)
Definition vote.qc:1219
void VoteCommand_abstain(int request, entity caller)
Definition vote.qc:946
#define VOTE_COMMAND(name, function, description, assignment)
void VoteCommand_macro_help(entity caller, int argc)
Definition vote.qc:1388
void VoteCommand_master(int request, entity caller, int argc, string vote_command)
Definition vote.qc:1099
void VoteCommand_stop(int request, entity caller)
Definition vote.qc:1286
void VoteCommand_status(int request, entity caller)
Definition vote.qc:1264
const float VC_ASGNMNT_BOTH
Definition vote.qh:27
const float VC_ASGNMNT_CLIENTONLY
Definition vote.qh:28

Definition at line 1377 of file vote.qc.

1377#define VOTE_COMMANDS(request, caller, arguments, command) \
1378 VOTE_COMMAND("abstain", VoteCommand_abstain(request, caller), "Abstain your vote in current vote", VC_ASGNMNT_CLIENTONLY) \
1379 VOTE_COMMAND("call", VoteCommand_call(request, caller, arguments, command), "Create a new vote for players to decide on", VC_ASGNMNT_BOTH) \
1380 VOTE_COMMAND("help", VoteCommand_macro_help(caller, arguments), "Shows this information", VC_ASGNMNT_BOTH) \
1381 VOTE_COMMAND("master", VoteCommand_master(request, caller, arguments, command), "Full control over all voting and vote commands", VC_ASGNMNT_CLIENTONLY) \
1382 VOTE_COMMAND("no", VoteCommand_no(request, caller), "Select no in current vote", VC_ASGNMNT_CLIENTONLY) \
1383 VOTE_COMMAND("status", VoteCommand_status(request, caller), "Prints information about current vote", VC_ASGNMNT_BOTH) \
1384 VOTE_COMMAND("stop", VoteCommand_stop(request, caller), "Immediately end a vote", VC_ASGNMNT_BOTH) \
1385 VOTE_COMMAND("yes", VoteCommand_yes(request, caller), "Select yes in current vote", VC_ASGNMNT_CLIENTONLY) \
1386 /* 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:167
#define new_pure(class)
purely logical entities (not linked to the area grid)
Definition oo.qh:66
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
WriteString(chan, ent.netname)
WriteByte(chan, ent.angles.y/DEC_FACTOR)
const int MSG_ENTITY
Definition net.qh:156
#define WriteHeader(to, id)
Definition net.qh:265
void WriteChar(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:2180
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 987 of file vote.qc.

988{
989 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"));
990}
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 559 of file vote.qc.

560{
561 // cannot reset the game while a timeout is active or pending
562 if (timeout_status) return;
563
564 int total_players = 0, human_players = 0, humans_ready = 0;
565 readycount = 0;
566
569 if (it.ready) ++readycount;
570 if (IS_REAL_CLIENT(it))
571 {
572 ++human_players;
573 if (it.ready) ++humans_ready;
574 }
575 });
576
578
579 // can't read warmup_stage here as it could have been set to 0 by ReadyRestart()
580 // and we need to use this when checking if we should abort the countdown
581 // map_minplayers can only be > 0 if g_warmup was -1 at worldspawn
582 int minplayers = autocvar_g_warmup > 1 ? autocvar_g_warmup : map_minplayers;
583
584 // This allows warmup to end with zero players to prevent complaints
585 // of server never changing map with legacy config (sv_autopause 0).
586 bool badteams = (teamplay && total_players && autocvar_sv_teamnagger)
588 : false;
589
590 if (total_players < minplayers || badteams)
591 {
592 if (game_starttime > time) // someone bailed during countdown, back to warmup
593 {
594 warmup_stage = autocvar_g_warmup; // CAN change it AFTER calling Nagger_ReadyCounted() this frame
596 if (total_players < minplayers)
597 Send_Notification(NOTIF_ALL, NULL, MSG_MULTI, COUNTDOWN_STOP_MINPLAYERS, minplayers);
598 else
599 Send_Notification(NOTIF_ALL, NULL, MSG_MULTI, COUNTDOWN_STOP_BADTEAMS);
600 if (!sv_ready_restart_after_countdown) // if we ran reset_map() at start of countdown
602 }
603 warmup_limit = -1;
604 return; // don't ReadyRestart if players are ready but too few or teams are bad
605 }
606 else if (warmup_limit <= 0
607 && game_starttime <= time) // No countdown in progress, check prevents early countdown end if only player leaves
608 {
609 // there's enough players now and teams are ok
610 // but we're still in infinite warmup and may need to switch to timed warmup
611 warmup_limit = cvar("g_warmup_limit");
612 if (warmup_limit == 0)
614 if (warmup_limit > 0)
616 // implicit else: g_warmup -1 && g_warmup_limit -1 means
617 // warmup continues until enough players AND enough RUPs (no time limit)
618 }
619
620 if (humans_ready && humans_ready >= rint(human_players * bound(0.5, cvar("g_warmup_majority_factor"), 1)))
621 ReadyRestart(true);
622}
#define IS_PLAYER(s)
Definition player.qh:242
float warmup_limit
Definition stats.qh:377
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:1500
#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:532
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:562
bool teamplay
Definition teams.qh:59
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52
int autocvar_g_warmup
Definition world.qh:9
bool sv_ready_restart_after_countdown
Definition world.qh:115

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 532 of file vote.qc.

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

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 447 of file vote.qc.

448{
450 return;
451 if (!is_fake_round_start && !autocvar_g_campaign)
452 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_COUNTDOWN_RESTART);
453
454 VoteReset(true);
455
456 // clear overtime, we have to decrease timelimit to its original value again.
460
461 if(warmup_stage)
462 game_starttime = time; // Warmup: No countdown in warmup
463 else if (autocvar_g_campaign)
464 game_starttime = time + 3;
465 else
466 game_starttime = time + RESTART_COUNTDOWN; // Go into match mode
467
468 // clear player attributes
470 it.alivetime_start = 0;
471 CS(it).killcount = 0;
472 });
473
474 // if we're ending the warmup stage call the corresponding hook
475 if(!is_fake_round_start && !warmup_stage)
476 localcmd("\nsv_hook_warmupend\n");
477
478 // reset the .ready status of all clients (including spectators and bots)
479 FOREACH_CLIENT(true, { it.ready = false; });
480 readycount = 0;
481 Nagger_ReadyCounted(); // NOTE: this causes a resend of that entity, and will also turn off warmup state on the client
482
483 // lock teams with lockonrestart
486
487 // initiate the restart-countdown-announcer entity
488 if (!is_fake_round_start && sv_ready_restart_after_countdown && !warmup_stage)
489 {
490 entity restart_timer = new_pure(restart_timer);
491 setthink(restart_timer, ReadyRestart_think);
492 restart_timer.nextthink = game_starttime;
493 }
494
495 // If we're returning to warmup join/switch all queued players for consistency:
496 // there's no queueing in warmup and imbalances are handled by sv_teamnagger blocking end of warmup.
497 if (warmup_stage)
498 {
499 // First pass: join player(s) queued for specific team(s)
500 FOREACH_CLIENT(it.wants_join > 0, Join(it, false));
501 // Second pass: join player(s) queued for team autoselection
502 FOREACH_CLIENT(it.wants_join < 0, Join(it, false));
503 }
504
505 // after a restart every players number of allowed timeouts gets reset, too
507 {
508 FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { CS(it).allowed_timeouts = autocvar_sv_timeout_number; });
509 }
510
512 {
514 {
515 if (it.vote_master)
516 ClientData_Touch(it.enemy, true);
517 else
518 {
519 Send_Notification(NOTIF_ONE_ONLY, it, MSG_MULTI, SPECTATE_SPEC_NOTALLOWED);
520 TRANSMUTE(Observer, it);
522 }
523 });
524 }
525
527 reset_map(is_fake_round_start);
528
529 if (autocvar_sv_eventlog) GameLogEcho(":restart");
530}
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:251
void cvar_set(string name, string value)
string ftos(float f)
#define TRANSMUTE(cname, this,...)
Definition oo.qh:139
#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:2073
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:439
const float RESTART_COUNTDOWN
Definition vote.qh:66
int g_race_qualifying
Definition race.qh:11
ClientState CS(Client this)
Definition state.qh:47
bool autocvar_teamplay_lockonrestart
Definition teamplay.qh:5
bool lockteams
Definition teamplay.qh:20
#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 439 of file vote.qc.

440{
441 if (!warmup_stage) // if the countdown was not aborted
442 reset_map(false);
443 delete(this);
444}

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 balanceteams();
372 }
373
375 {
376 shuffleteams();
378 }
379
380 FOREACH_CLIENT(true, {
381 if (time <= game_starttime)
382 accuracy_reset(it); // for spectators too because weapon accuracy is persistent
383 if (!IS_PLAYER(it))
384 continue;
386 entity store = PS(it);
387 if (store)
388 {
389 Inventory_clear(store.inventory);
390 Inventory_update(store);
391 }
392 });
393
394 MUTATOR_CALLHOOK(reset_map_global);
395
397 {
398 if(IS_CLIENT(it))
399 continue;
400 if (it.reset)
401 {
402 it.reset(it);
403 continue;
404 }
405 if (it.team_saved) it.team = it.team_saved;
406 if (it.flags & FL_PROJECTILE) delete(it); // remove any projectiles left
407 });
408
409 // Waypoints and assault start come LAST
411 if (it.reset2) it.reset2(it);
412 });
413
414 // Moving the player reset code here since the player-reset depends
415 // on spawnpoint entities which have to be reset first --blub
416 if (!MUTATOR_CALLHOOK(reset_map_players))
417 {
419 {
420 // PlayerScore_Clear(it);
421 CS(it).killcount = 0;
422 // stop the player from moving so that they stand still once they get respawned
423 it.velocity = '0 0 0';
424 it.avelocity = '0 0 0';
425 CS(it).movement = '0 0 0';
427
428 if(IS_BOT_CLIENT(it))
429 {
430 .entity weaponentity = weaponentities[0];
431 if(it.(weaponentity).m_weapon == WEP_Null)
432 W_NextWeapon(it, 0, weaponentity);
433 }
434 });
435 }
436}
void accuracy_reset(entity e)
Definition accuracy.qc:63
#define IS_NOT_A_CLIENT(s)
Definition player.qh:243
#define IS_CLIENT(s)
Definition player.qh:241
const int FL_PROJECTILE
Definition constants.qh:77
void Inventory_update(entity e)
Definition inventory.qh:159
void Inventory_clear(entity store)
Definition inventory.qh:170
#define FOREACH_ENTITY_ORDERED(cond, body)
Definition iter.qh:137
#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:303
void W_NextWeapon(entity this, int list,.entity weaponentity)
Goto next weapon.
Definition selection.qc:310
void player_powerups_remove_all(entity this, bool allow_poweroff_sound)
Definition client.qc:1540
#define PS(this)
Definition state.qh:18
void shuffleteams()
Definition sv_cmd.qc:1535
void balanceteams()
Definition sv_cmd.qc:386
bool shuffleteams_on_reset_map
Definition sv_cmd.qh:9
bool balanceteams_on_reset_map
Definition sv_cmd.qh:6
#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(), balanceteams(), balanceteams_on_reset_map, 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 678 of file vote.qc.

679{
680 validated_map = MapInfo_FixName(validated_map);
681
682 if (!validated_map)
683 {
684 print_to(caller, "This map is not available on this server.");
685 return string_null;
686 }
687
689 {
690 if (Map_IsRecent(validated_map))
691 {
692 print_to(caller, "This server does not allow for recent maps to be played again. Please be patient for some rounds.");
693 return string_null;
694 }
695 }
696
697 if (!MapInfo_CheckMap(validated_map))
698 {
699 print_to(caller, strcat("^1Invalid mapname, \"^3", validated_map, "^1\" does not support the current gametype."));
700 return string_null;
701 }
702
703 return validated_map;
704}
bool Map_IsRecent(string m)
float MapInfo_CheckMap(string s)
Definition mapinfo.qc:1507
string MapInfo_FixName(string s)
Definition mapinfo.qc:1471
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 1437 of file vote.qc.

1438{
1439 // Guide for working with argc arguments by example:
1440 // argc: 1 - 2 - 3 - 4
1441 // argv: 0 - 1 - 2 - 3
1442 // cmd vote - master - login - password
1443
1444 switch (request)
1445 {
1447 {
1448 if (VoteCommand_macro_command(caller, argc, vote_command)) return;
1449 }
1450
1451 default:
1452 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"));
1453 case CMD_REQUEST_USAGE:
1454 {
1455 VoteCommand_macro_help(caller, argc);
1456 return;
1457 }
1458 }
1459}
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:1421

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 946 of file vote.qc.

947{
948 switch (request)
949 {
951 {
952 if (PlayerInList(caller, autocvar_g_voteban_list)) // voteban
953 {
954 print_to(caller, "^1You are banned from voting.");
955 Send_Notification(NOTIF_ONE, caller, MSG_CENTER, CENTER_VOTEBANYN);
956 return;
957 }
958
959 if (!vote_called) { print_to(caller, "^1No vote called."); }
960 else if (caller.vote_selection != VOTE_SELECT_NULL && !autocvar_sv_vote_change)
961 {
962 print_to(caller, "^1You have already voted.");
963 }
964
965 else // everything went okay, continue changing vote
966 {
967 print_to(caller, "^1You abstained from your vote.");
968 caller.vote_selection = VOTE_SELECT_ABSTAIN;
969 msg_entity = caller;
971 VoteCount(false);
972 }
973
974 return;
975 }
976
977 default:
979 {
980 print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote abstain"));
981 print_to(caller, " No arguments required.");
982 return;
983 }
984 }
985}
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:1048
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 992 of file vote.qc.

993{
994 switch (request)
995 {
997 {
998 float tmp_playercount = 0;
999 int parse_error;
1000
1001 if (PlayerInList(caller, autocvar_g_voteban_list)) // voteban
1002 {
1003 print_to(caller, "^1You are banned from calling a vote.");
1004 Send_Notification(NOTIF_ONE, caller, MSG_CENTER, CENTER_VOTEBAN);
1005 return;
1006 }
1007
1008 vote_command = VoteCommand_extractcommand(vote_command, 2, argc);
1009
1010 if (!autocvar_sv_vote_call && caller)
1011 {
1012 print_to(caller, "^1Vote calling is not allowed.");
1013 }
1015 {
1016 print_to(caller, "^1Vote calling is not allowed before the match has started.");
1017 }
1018 else if (vote_called)
1019 {
1020 print_to(caller, "^1There is already a vote called.");
1021 }
1022 else if (!spectators_allowed && (caller && !IS_PLAYER(caller)))
1023 {
1024 print_to(caller, "^1Only players can call a vote.");
1025 }
1026 else if (caller && !IS_CLIENT(caller))
1027 {
1028 print_to(caller, "^1Only connected clients can vote.");
1029 }
1030 else if (timeout_status && vote_command != "timein")
1031 {
1032 print_to(caller, "^1You can not call a vote while a timeout is active.");
1033 }
1034 else if (caller && (time < caller.vote_waittime))
1035 {
1036 print_to(caller, strcat("^1You have to wait ^2", ftos(ceil(caller.vote_waittime - time)), "^1 seconds before you can again call a vote."));
1037 }
1038 else if (!VoteCommand_checknasty(vote_command))
1039 {
1040 print_to(caller, "^1Syntax error in command.");
1041 }
1042 else if ((parse_error = VoteCommand_parse(caller, vote_command, autocvar_sv_vote_commands, 2, argc)) <= 0)
1043 {
1044 if(parse_error == 0)
1045 {
1046 if (vote_called_command == "")
1047 VoteCommand_call(CMD_REQUEST_USAGE, caller, argc, vote_command);
1048 else
1049 print_to(caller, "^1This command is not acceptable or not available.");
1050 }
1051 }
1052 else // everything went okay, continue with calling the vote
1053 {
1054 vote_caller = caller; // remember who called the vote
1060
1061 if (caller)
1062 {
1063 caller.vote_selection = VOTE_SELECT_ACCEPT;
1064 caller.vote_waittime = time + autocvar_sv_vote_wait;
1065 msg_entity = caller;
1066 }
1067
1068 FOREACH_CLIENT(IS_REAL_CLIENT(it), { ++tmp_playercount; });
1069
1070 bprint("\{1}^2* ^3", OriginalCallerName(), "^2 calls a vote for ", vote_called_display, "\n");
1072 bprint("\{1}^2* ^3", "^6DEBUG MODE ACTIVE: bots can vote too\n"); // so servers don't forget it on
1074 GameLogEcho(strcat(":vote:vcall:", ftos(vote_caller.playerid), ":", vote_called_display));
1076 VoteCount(true); // needed if you are the only one
1077
1078 if (tmp_playercount > 1 && vote_called != VOTE_NULL)
1079 Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_VOTE_CALL);
1080 }
1081
1082 return;
1083 }
1084
1085 default:
1086 case CMD_REQUEST_USAGE:
1087 {
1088 print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote call <command>"));
1089 print_to(caller, " Where <command> is the command to request a vote upon.");
1090 print_to(caller, strcat("Examples: ", GetCommandPrefix(caller), " vote call gotomap dance"));
1091 print_to(caller, strcat(" ", GetCommandPrefix(caller), " vote call endmatch"));
1093 print_to(caller, "Shortcuts: ^2vcall <command>, vend, vmap, vkick, ...");
1094 return;
1095 }
1096 }
1097}
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:987
void Nagger_VoteChanged()
Definition vote.qc:102
string VoteCommand_extractcommand(string input, float startpos, int argc)
Definition vote.qc:640
int VoteCommand_parse(entity caller, string vote_command, string vote_list, float startpos, int argc)
Definition vote.qc:780
bool VoteCommand_checknasty(string vote_command)
Definition vote.qc:650
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 629 of file vote.qc.

630{
631 bool from_server = (!caller);
632
633 if ((assignment == VC_ASGNMNT_BOTH)
634 || ((!from_server && assignment == VC_ASGNMNT_CLIENTONLY)
635 || (from_server && assignment == VC_ASGNMNT_SERVERONLY))) return true;
636
637 return false;
638}
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 706 of file vote.qc.

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

670{
671 if (vote_command == "" || list == "")
672 return false;
673
674 string l = VoteCommand_checkreplacements(list);
675 return (strstrofs(l, VoteCommand_checkreplacements(vote_command), 0) >= 0);
676}
string VoteCommand_checkreplacements(string input)
Definition vote.qc:659

References strstrofs, and VoteCommand_checkreplacements().

Referenced by VoteCommand_parse().

◆ VoteCommand_checknasty()

bool VoteCommand_checknasty ( string vote_command)

Definition at line 650 of file vote.qc.

651{
652 return !((strstrofs(vote_command, ";", 0) >= 0)
653 || (strstrofs(vote_command, "\n", 0) >= 0)
654 || (strstrofs(vote_command, "\r", 0) >= 0)
655 || (strstrofs(vote_command, "$", 0) >= 0));
656}

References strstrofs.

Referenced by VoteCommand_call(), and VoteCommand_master().

◆ VoteCommand_checkreplacements()

string VoteCommand_checkreplacements ( string input)

Definition at line 659 of file vote.qc.

660{
661 // add a space around the input so the start and end of the list is captured
662 string output = strcat(" ", input, " ");
663 // allow gotomap replacements
664 output = strreplace(" map ", " gotomap ", output);
665 output = strreplace(" chmap ", " gotomap ", output);
666 return output;
667}

References strcat().

Referenced by VoteCommand_checkinlist().

◆ VoteCommand_extractcommand()

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

Definition at line 640 of file vote.qc.

641{
642 string output;
643
644 if ((argc - 1) < startpos) output = "";
645 else output = substring(input, argv_start_index(startpos), argv_end_index(-1) - argv_start_index(startpos));
646
647 return output;
648}
#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 1421 of file vote.qc.

1422{
1423 #define VOTE_COMMAND(name, function, description, assignment) \
1424 { if (Votecommand_check_assignment(caller, assignment)) { if (name == strtolower(argv(1))) { function; return true; } } }
1425
1426 VOTE_COMMANDS(CMD_REQUEST_COMMAND, caller, argc, vote_command);
1427 #undef VOTE_COMMAND
1428
1429 return false;
1430}
#define VOTE_COMMANDS(request, caller, arguments, command)
Definition vote.qc:1377

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 1388 of file vote.qc.

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

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 1099 of file vote.qc.

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

1220{
1221 switch (request)
1222 {
1224 {
1225 if (PlayerInList(caller, autocvar_g_voteban_list)) // voteban
1226 {
1227 print_to(caller, "^1You are banned from voting.");
1228 Send_Notification(NOTIF_ONE, caller, MSG_CENTER, CENTER_VOTEBANYN);
1229 return;
1230 }
1231
1232 if (!vote_called) { print_to(caller, "^1No vote called."); }
1233 else if (caller.vote_selection != VOTE_SELECT_NULL && !autocvar_sv_vote_change)
1234 {
1235 print_to(caller, "^1You have already voted.");
1236 }
1237 else if (caller == vote_caller && autocvar_sv_vote_no_stops_vote)
1238 {
1239 VoteStop(caller, false);
1240 }
1241
1242 else // everything went okay, continue changing vote
1243 {
1244 print_to(caller, "^1You rejected the vote.");
1245 caller.vote_selection = VOTE_SELECT_REJECT;
1246 msg_entity = caller;
1248 VoteCount(false);
1249 }
1250
1251 return;
1252 }
1253
1254 default:
1255 case CMD_REQUEST_USAGE:
1256 {
1257 print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote no"));
1258 print_to(caller, " No arguments required.");
1259 return;
1260 }
1261 }
1262}
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 780 of file vote.qc.

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

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

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 1286 of file vote.qc.

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

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 1308 of file vote.qc.

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

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:45

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().