Xonotic
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)   { if (Votecommand_check_assignment(caller, assignment)) { print_to(caller, strcat(" ^2", name, "^7: ", description)); } }
 
#define VOTE_COMMAND(name, function, description, assignment)   { if (Votecommand_check_assignment(caller, assignment)) { if (name == strtolower(argv(2))) { function; return; } } }
 
#define VOTE_COMMAND(name, function, description, assignment)   { if (Votecommand_check_assignment(caller, assignment)) { if (name == strtolower(argv(1))) { function; return true; } } }
 
#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 dorespawn, 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)
 
float Votecommand_check_assignment (entity caller, float assignment)
 
float VoteCommand_checkargs (float startpos, int argc)
 
float VoteCommand_checkinlist (string vote_command, string list)
 
float 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 ()
 
void VoteSpam (float notvoters, float mincount, string result)
 
void VoteStop (entity stopper)
 
void VoteThink ()
 
void VoteTimeout ()
 

Macro Definition Documentation

◆ spectators_allowed

Definition at line 205 of file vote.qc.

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

◆ VOTE_COMMAND [1/3]

#define VOTE_COMMAND (   name,
  function,
  description,
  assignment 
)    { if (Votecommand_check_assignment(caller, assignment)) { print_to(caller, strcat(" ^2", name, "^7: ", description)); } }

◆ VOTE_COMMAND [2/3]

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

◆ VOTE_COMMAND [3/3]

#define VOTE_COMMAND (   name,
  function,
  description,
  assignment 
)    { 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_yes(int request, entity caller)
Definition: vote.qc:1142
const float VC_ASGNMNT_CLIENTONLY
Definition: vote.qh:26
void VoteCommand_call(int request, entity caller, int argc, string vote_command)
Definition: vote.qc:842
void VoteCommand_stop(int request, entity caller)
Definition: vote.qc:1120
void VoteCommand_master(int request, entity caller, int argc, string vote_command)
Definition: vote.qc:940
void VoteCommand_abstain(int request, entity caller)
Definition: vote.qc:803
void VoteCommand_status(int request, entity caller)
Definition: vote.qc:1098
void VoteCommand_no(int request, entity caller)
Definition: vote.qc:1060
#define VOTE_COMMAND(name, function, description, assignment)
void VoteCommand_macro_help(entity caller, int argc)
Definition: vote.qc:1215
const float VC_ASGNMNT_BOTH
Definition: vote.qh:25

Definition at line 1204 of file vote.qc.

Referenced by VoteCommand_macro_command(), and VoteCommand_macro_help().

Function Documentation

◆ Nagger_Init()

void Nagger_Init ( )

Definition at line 97 of file vote.qc.

References nagger, Nagger_SendEntity(), and new_pure.

Referenced by spawnfunc().

98 {
99  Net_LinkEntity(nagger = new_pure(nagger), false, 0, Nagger_SendEntity);
100 }
bool Nagger_SendEntity(entity this, entity to, float sendflags)
Definition: vote.qc:35
entity nagger
Definition: vote.qh:64
#define new_pure(class)
purely logical entities (.origin doesn't work)
Definition: oo.qh:62
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Nagger_ReadyCounted()

void Nagger_ReadyCounted ( )

Definition at line 112 of file vote.qc.

References BIT, and nagger.

Referenced by ReadyCount(), and ReadyRestart_force().

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
entity nagger
Definition: vote.qh:64
+ Here is the caller graph for this function:

◆ Nagger_SendEntity()

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

Definition at line 35 of file vote.qc.

References BIT, entity(), IS_REAL_CLIENT, maxclients, nextent(), readycount, vote_accept_count, vote_called, vote_called_display, vote_needed_overall, vote_reject_count, warmup_stage, WriteByte(), WriteChar(), and WriteString().

Referenced by Nagger_Init().

36 {
37  int nags, i, f, b;
38  entity e;
39  WriteHeader(MSG_ENTITY, ENT_CLIENT_NAGGER);
40 
41  // bits:
42  // 1 = ready
43  // 2 = player needs to ready up
44  // 4 = vote
45  // 8 = player needs to vote
46  // 16 = warmup
47  // sendflags:
48  // 64 = vote counts
49  // 128 = vote string
50 
51  nags = 0;
52  if (readycount)
53  {
54  nags |= BIT(0);
55  if (to.ready == 0) nags |= BIT(1);
56  }
57  if (vote_called)
58  {
59  nags |= BIT(2);
60  if (to.vote_selection == 0) nags |= BIT(3);
61  }
62  if (warmup_stage) nags |= BIT(4);
63 
64  if (sendflags & BIT(6)) nags |= BIT(6);
65 
66  if (sendflags & BIT(7)) nags |= BIT(7);
67 
68  if (!(nags & 4)) // no vote called? send no string
69  nags &= ~(BIT(6) | BIT(7));
70 
71  WriteByte(MSG_ENTITY, nags);
72 
73  if (nags & BIT(6))
74  {
75  WriteByte(MSG_ENTITY, vote_accept_count);
76  WriteByte(MSG_ENTITY, vote_reject_count);
77  WriteByte(MSG_ENTITY, vote_needed_overall);
78  WriteChar(MSG_ENTITY, to.vote_selection);
79  }
80 
81  if (nags & BIT(7)) WriteString(MSG_ENTITY, vote_called_display);
82 
83  if (nags & 1)
84  {
85  for (i = 1; i <= maxclients; i += 8)
86  {
87  for (f = 0, e = edict_num(i), b = BIT(0); b < BIT(8); b <<= 1, e = nextent(e))
88  if (!IS_REAL_CLIENT(e) || e.ready)
89  f |= b;
90  WriteByte(MSG_ENTITY, f);
91  }
92  }
93 
94  return true;
95 }
entity() spawn
float readycount
Definition: vote.qh:65
bool warmup_stage
Definition: main.qh:103
float maxclients
Definition: csprogsdefs.qc:21
entity to
Definition: self.qh:96
float vote_called
Definition: vote.qh:43
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition: bits.qh:8
float vote_accept_count
Definition: vote.qh:45
float vote_needed_overall
Definition: vote.qh:48
string vote_called_display
Definition: vote.qh:53
float vote_reject_count
Definition: vote.qh:46
entity int sendflags
Definition: self.qh:96
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Nagger_VoteChanged()

void Nagger_VoteChanged ( )

Definition at line 102 of file vote.qc.

References BIT, and nagger.

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

103 {
104  if (nagger) nagger.SendFlags |= BIT(7);
105 }
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition: bits.qh:8
entity nagger
Definition: vote.qh:64
+ Here is the caller graph for this function:

◆ Nagger_VoteCountChanged()

void Nagger_VoteCountChanged ( )

Definition at line 107 of file vote.qc.

References BIT, and nagger.

Referenced by VoteCount().

108 {
109  if (nagger) nagger.SendFlags |= BIT(6);
110 }
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition: bits.qh:8
entity nagger
Definition: vote.qh:64
+ Here is the caller graph for this function:

◆ OriginalCallerName()

string OriginalCallerName ( )

Definition at line 118 of file vote.qc.

References IS_REAL_CLIENT, vote_caller, and vote_caller_name.

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

119 {
120  if (IS_REAL_CLIENT(vote_caller)) return playername(vote_caller.netname, vote_caller.team, false);
121  return vote_caller_name;
122 }
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
string vote_caller_name
Definition: vote.qh:42
entity vote_caller
Definition: vote.qh:41
+ Here is the caller graph for this function:

◆ print_available_commands_to()

void print_available_commands_to ( entity  caller)

Definition at line 837 of file vote.qc.

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

Referenced by VoteCommand_call(), and VoteCommand_macro_help().

838 {
839  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"));
840 }
void print_to(entity to, string input)
Definition: common.qc:172
string autocvar_sv_vote_commands
Definition: vote.qh:5
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ReadyCount()

void ReadyCount ( )

Definition at line 498 of file vote.qc.

References bound(), cvar(), floor(), FOREACH_CLIENT, INGAME_JOINED, IS_PLAYER, IS_REAL_CLIENT, Nagger_ReadyCounted(), readycount, and ReadyRestart().

Referenced by ClientCommand_ready(), ClientDisconnect(), and PutObserverInServer().

499 {
500  float ready_needed_factor, ready_needed_count;
501  float t_ready = 0, t_players = 0;
502 
504  ++t_players;
505  if (it.ready) ++t_ready;
506  });
507 
508  readycount = t_ready;
509 
511 
512  ready_needed_factor = bound(0.5, cvar("g_warmup_majority_factor"), 0.999);
513  ready_needed_count = floor(t_players * ready_needed_factor) + 1;
514 
515  if (readycount >= ready_needed_count) ReadyRestart(true);
516 }
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
float readycount
Definition: vote.qh:65
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
void Nagger_ReadyCounted()
Definition: vote.qc:112
void ReadyRestart(bool forceWarmupEnd)
Definition: vote.qc:484
#define INGAME_JOINED(it)
Definition: sv_rules.qh:21
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ReadyRestart()

void ReadyRestart ( bool  forceWarmupEnd)

Definition at line 484 of file vote.qc.

References cvar(), intermission_running, localcmd, MUTATOR_CALLHOOK, race_completing, ReadyRestart_force(), and warmup_stage.

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

485 {
486  if (MUTATOR_CALLHOOK(ReadyRestart_Deny) || intermission_running || race_completing) localcmd("restart\n");
487  else localcmd("\nsv_hook_readyrestart\n");
488 
489  if(forceWarmupEnd)
490  warmup_stage = 0; // forcefully end warmup and go to match stage
491  else
492  warmup_stage = cvar("g_warmup"); // go into warmup if it's enabled, otherwise restart into match stage
493 
494  ReadyRestart_force(false);
495 }
void ReadyRestart_force(bool is_fake_round_start)
Definition: vote.qc:426
bool warmup_stage
Definition: main.qh:103
float race_completing
Definition: race.qh:27
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
bool intermission_running
Definition: intermission.qh:9
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ReadyRestart_force()

void ReadyRestart_force ( bool  is_fake_round_start)

Definition at line 426 of file vote.qc.

References autocvar_sv_eventlog, autocvar_sv_timeout, autocvar_sv_timeout_number, autocvar_teamplay_lockonrestart, autocvar_timelimit_overtime, bprint(), checkrules_overtimesadded, checkrules_suddendeathend, checkrules_suddendeathwarning, CS(), cvar_set(), entity(), FOREACH_CLIENT, ftos(), g_race_qualifying, GameLogEcho(), IS_PLAYER, IS_REAL_CLIENT, localcmd, lockteams, Nagger_ReadyCounted(), new_pure, readycount, ReadyRestart_think(), reset_map(), RESTART_COUNTDOWN, setthink, sv_ready_restart_after_countdown, teamplay, time, VoteReset(), and warmup_stage.

Referenced by assault_new_round(), and ReadyRestart().

427 {
428  if (time <= game_starttime && game_stopped)
429  return;
430  if (!is_fake_round_start)
431  bprint("^1Match is restarting...\n");
432 
433  VoteReset();
434 
435  // clear overtime, we have to decrease timelimit to its original value again.
437  cvar_set("timelimit", ftos(autocvar_timelimit - (checkrules_overtimesadded * autocvar_timelimit_overtime)));
439 
440  if(warmup_stage)
441  game_starttime = time; // Warmup: No countdown in warmup
442  else
443  game_starttime = time + RESTART_COUNTDOWN; // Go into match mode
444 
445  // clear player attributes
447  it.alivetime = 0;
448  CS(it).killcount = 0;
449  });
450 
451  // if we're ending the warmup stage call the corresponding hook
452  if(!is_fake_round_start && !warmup_stage)
453  localcmd("\nsv_hook_warmupend\n");
454 
455  // reset the .ready status of all players (also spectators)
456  FOREACH_CLIENT(IS_REAL_CLIENT(it), { it.ready = false; });
457  readycount = 0;
458  Nagger_ReadyCounted(); // NOTE: this causes a resend of that entity, and will also turn off warmup state on the client
459 
460  // lock teams with lockonrestart
463 
464  // initiate the restart-countdown-announcer entity
465  if (!is_fake_round_start && sv_ready_restart_after_countdown && !warmup_stage)
466  {
467  entity restart_timer = new_pure(restart_timer);
468  setthink(restart_timer, ReadyRestart_think);
469  restart_timer.nextthink = game_starttime;
470  }
471 
472  // after a restart every players number of allowed timeouts gets reset, too
474  {
475  FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { CS(it).allowed_timeouts = autocvar_sv_timeout_number; });
476  }
477 
479  reset_map(true, is_fake_round_start);
480 
481  if (autocvar_sv_eventlog) GameLogEcho(":restart");
482 }
bool autocvar_sv_timeout
Definition: common.qh:5
float checkrules_suddendeathend
Definition: world.qh:33
float autocvar_timelimit_overtime
Definition: world.qh:27
entity() spawn
ClientState CS(Client this)
Definition: state.qh:47
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
float readycount
Definition: vote.qh:65
int checkrules_overtimesadded
Definition: world.qh:34
void reset_map(bool dorespawn, bool is_fake_round_start)
Definition: vote.qc:339
float checkrules_suddendeathwarning
Definition: world.qh:32
bool warmup_stage
Definition: main.qh:103
bool g_race_qualifying
Definition: race.qh:12
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
bool autocvar_teamplay_lockonrestart
Definition: teamplay.qh:6
int autocvar_sv_timeout_number
Definition: common.qh:8
void GameLogEcho(string s)
Definition: gamelog.qc:12
float teamplay
Definition: progsdefs.qc:31
void Nagger_ReadyCounted()
Definition: vote.qc:112
bool lockteams
Definition: teamplay.qh:13
bool sv_ready_restart_after_countdown
Definition: world.qh:119
#define new_pure(class)
purely logical entities (.origin doesn&#39;t work)
Definition: oo.qh:62
#define setthink(e, f)
void VoteReset()
Definition: vote.qc:128
bool autocvar_sv_eventlog
Definition: gamelog.qh:3
float time
Definition: csprogsdefs.qc:16
const float RESTART_COUNTDOWN
Definition: vote.qh:63
void ReadyRestart_think(entity this)
Definition: vote.qc:419
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ReadyRestart_think()

void ReadyRestart_think ( entity  this)

Definition at line 419 of file vote.qc.

References reset_map().

Referenced by ReadyRestart_force().

420 {
421  reset_map(true, false);
422  delete(this);
423 }
void reset_map(bool dorespawn, bool is_fake_round_start)
Definition: vote.qc:339
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reset_map()

void reset_map ( bool  dorespawn,
bool  is_fake_round_start 
)

Definition at line 339 of file vote.qc.

References accuracy_reset(), CS(), entity(), FOREACH_CLIENT, FOREACH_ENTITY_FLOAT_ORDERED, FOREACH_ENTITY_ORDERED, if(), Inventory_clear(), IS_CLIENT, IS_NOT_A_CLIENT, IS_PLAYER, MUTATOR_CALLHOOK, player_powerups_remove_all(), PS, pure_data, PutClientInServer(), round_handler_IsActive, round_handler_Reset(), Score_ClearAll(), shuffleteams(), shuffleteams_on_reset_map, time, and Unfreeze().

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

340 {
341  if (time <= game_starttime)
342  {
343  if (game_stopped)
344  return;
345 
346  if (!is_fake_round_start)
347  {
348  Score_ClearAll();
349  PlayerStats_GameReport_Reset_All();
350  }
351 
353  round_handler_Reset(game_starttime);
354  }
355 
357  {
358  shuffleteams();
360  }
361 
362  FOREACH_CLIENT(true, {
363  if (time <= game_starttime)
364  accuracy_reset(it); // for spectators too because weapon accuracy is persistent
365  if (!IS_PLAYER(it))
366  continue;
367  if (STAT(FROZEN, it))
368  Unfreeze(it, false);
370  entity store = PS(it);
371  if (store)
372  {
373  Inventory_clear(store.inventory);
374  Inventory_update(store);
375  }
376  });
377 
378  MUTATOR_CALLHOOK(reset_map_global);
379 
381  {
382  if(IS_CLIENT(it))
383  continue;
384  if (it.reset)
385  {
386  it.reset(it);
387  continue;
388  }
389  if (it.team_saved) it.team = it.team_saved;
390  if (it.flags & FL_PROJECTILE) delete(it); // remove any projectiles left
391  });
392 
393  // Waypoints and assault start come LAST
395  if (it.reset2) it.reset2(it);
396  });
397 
398  // Moving the player reset code here since the player-reset depends
399  // on spawnpoint entities which have to be reset first --blub
400  if (dorespawn)
401  {
402  if (!MUTATOR_CALLHOOK(reset_map_players))
403  {
405  {
406  // PlayerScore_Clear(it);
407  CS(it).killcount = 0;
408  // stop the player from moving so that he stands still once he gets respawned
409  it.velocity = '0 0 0';
410  it.avelocity = '0 0 0';
411  CS(it).movement = '0 0 0';
412  PutClientInServer(it);
413  });
414  }
415  }
416 }
#define round_handler_IsActive()
#define IS_CLIENT(v)
Definition: utils.qh:13
entity() spawn
ClientState CS(Client this)
Definition: state.qh:47
void Score_ClearAll()
Clear ALL scores (for ready-restart).
Definition: scores.qc:288
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
#define PS(this)
Definition: state.qh:18
void shuffleteams()
Definition: sv_cmd.qc:1245
#define FOREACH_ENTITY_ORDERED(cond, body)
Definition: iter.qh:138
void Unfreeze(entity targ, bool reset_health)
Definition: damage.qc:546
void accuracy_reset(entity e)
Definition: accuracy.qc:58
bool pure_data
Definition: oo.qh:9
void round_handler_Reset(float next_think)
#define IS_NOT_A_CLIENT(v)
was: (clienttype(v) == CLIENTTYPE_NOTACLIENT)
Definition: utils.qh:19
bool shuffleteams_on_reset_map
Definition: sv_cmd.qh:7
void Inventory_clear(PlayerState this)
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
#define FOREACH_ENTITY_FLOAT_ORDERED(fld, match, body)
Definition: iter.qh:175
PutClientInServer(this)
if(IS_DEAD(this))
Definition: impulse.qc:92
float time
Definition: csprogsdefs.qc:16
#define IS_PLAYER(v)
Definition: utils.qh:9
void player_powerups_remove_all(entity this)
Definition: client.qc:1457
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ValidateMap()

string ValidateMap ( string  validated_map,
entity  caller 
)

Definition at line 573 of file vote.qc.

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

Referenced by VoteCommand_parse().

574 {
575  validated_map = MapInfo_FixName(validated_map);
576 
577  if (!validated_map)
578  {
579  print_to(caller, "This map is not available on this server.");
580  return string_null;
581  }
582 
584  {
585  if (Map_IsRecent(validated_map))
586  {
587  print_to(caller, "This server does not allow for recent maps to be played again. Please be patient for some rounds.");
588  return string_null;
589  }
590  }
591 
592  if (!MapInfo_CheckMap(validated_map))
593  {
594  print_to(caller, strcat("^1Invalid mapname, \"^3", validated_map, "^1\" does not support the current game mode."));
595  return string_null;
596  }
597 
598  return validated_map;
599 }
string string_null
Definition: nil.qh:9
void print_to(entity to, string input)
Definition: common.qc:172
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
float MapInfo_CheckMap(string s)
Definition: mapinfo.qc:1170
bool Map_IsRecent(string m)
bool autocvar_sv_vote_override_mostrecent
Definition: vote.qh:17
string MapInfo_FixName(string s)
Definition: mapinfo.qc:1134
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteAccept()

void VoteAccept ( )

Definition at line 158 of file vote.qc.

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

Referenced by VoteCount().

159 {
160  bprint("\{1}^2* ^3", OriginalCallerName(), "^2's vote for ^1", vote_called_display, "^2 was accepted\n");
161 
162  if ((vote_called == VOTE_MASTER) && vote_caller) vote_caller.vote_master = 1;
163  else localcmd(strcat(vote_called_command, "\n"));
164 
165  if (vote_caller) vote_caller.vote_waittime = 0; // people like your votes, you don't need to wait to vote again
166 
167  VoteReset();
168  Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_VOTE_ACCEPT);
169 }
string OriginalCallerName()
Definition: vote.qc:118
const float VOTE_MASTER
Definition: vote.qh:38
float vote_called
Definition: vote.qh:43
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
#define NULL
Definition: post.qh:17
string vote_called_display
Definition: vote.qh:53
entity vote_caller
Definition: vote.qh:41
void VoteReset()
Definition: vote.qc:128
string vote_called_command
Definition: vote.qh:52
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteCommand()

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

Definition at line 1264 of file vote.qc.

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

Referenced by COMMON_COMMAND().

1265 {
1266  // Guide for working with argc arguments by example:
1267  // argc: 1 - 2 - 3 - 4
1268  // argv: 0 - 1 - 2 - 3
1269  // cmd vote - master - login - password
1270 
1271  switch (request)
1272  {
1273  case CMD_REQUEST_COMMAND:
1274  {
1275  if (VoteCommand_macro_command(caller, argc, vote_command)) return;
1276  }
1277 
1278  default:
1279  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"));
1280  case CMD_REQUEST_USAGE:
1281  {
1282  VoteCommand_macro_help(caller, argc);
1283  return;
1284  }
1285  }
1286 }
string GetCommandPrefix(entity caller)
Definition: common.qc:26
const int CMD_REQUEST_USAGE
Definition: command.qh:4
float VoteCommand_macro_command(entity caller, int argc, string vote_command)
Definition: vote.qc:1248
void print_to(entity to, string input)
Definition: common.qc:172
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
const int CMD_REQUEST_COMMAND
Definition: command.qh:3
void VoteCommand_macro_help(entity caller, int argc)
Definition: vote.qc:1215
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteCommand_abstain()

void VoteCommand_abstain ( int  request,
entity  caller 
)

Definition at line 803 of file vote.qc.

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

804 {
805  switch (request)
806  {
807  case CMD_REQUEST_COMMAND:
808  {
809  if (!vote_called) { print_to(caller, "^1No vote called."); }
810  else if (caller.vote_selection != VOTE_SELECT_NULL && !autocvar_sv_vote_change)
811  {
812  print_to(caller, "^1You have already voted.");
813  }
814 
815  else // everything went okay, continue changing vote
816  {
817  print_to(caller, "^1You abstained from your vote.");
818  caller.vote_selection = VOTE_SELECT_ABSTAIN;
819  msg_entity = caller;
821  VoteCount(false);
822  }
823 
824  return;
825  }
826 
827  default:
828  case CMD_REQUEST_USAGE:
829  {
830  print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote abstain"));
831  print_to(caller, " No arguments required.");
832  return;
833  }
834  }
835 }
bool autocvar_sv_vote_change
Definition: vote.qh:4
string GetCommandPrefix(entity caller)
Definition: common.qc:26
const int CMD_REQUEST_USAGE
Definition: command.qh:4
void print_to(entity to, string input)
Definition: common.qc:172
float vote_called
Definition: vote.qh:43
const float VOTE_SELECT_NULL
Definition: vote.qh:32
bool autocvar_sv_vote_singlecount
Definition: vote.qh:18
entity msg_entity
Definition: progsdefs.qc:63
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
const int CMD_REQUEST_COMMAND
Definition: command.qh:3
const float VOTE_SELECT_ABSTAIN
Definition: vote.qh:30
void VoteCount(float first_count)
Definition: vote.qc:207
+ Here is the call graph for this function:

◆ VoteCommand_call()

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

Definition at line 842 of file vote.qc.

References autocvar_sv_eventlog, autocvar_sv_vote_call, autocvar_sv_vote_commands, autocvar_sv_vote_gamestart, autocvar_sv_vote_timeout, autocvar_sv_vote_wait, bprint(), ceil(), CMD_REQUEST_COMMAND, CMD_REQUEST_USAGE, FOREACH_CLIENT, ftos(), GameLogEcho(), GetCallerName(), GetCommandPrefix(), IS_CLIENT, IS_PLAYER, IS_REAL_CLIENT, msg_entity, Nagger_VoteChanged(), NULL, OriginalCallerName(), print_available_commands_to(), print_to(), spectators_allowed, strcat(), strzone(), time, 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_checknasty(), VoteCommand_extractcommand(), VoteCommand_parse(), and VoteCount().

843 {
844  switch (request)
845  {
846  case CMD_REQUEST_COMMAND:
847  {
848  float tmp_playercount = 0;
849  int parse_error;
850 
851  vote_command = VoteCommand_extractcommand(vote_command, 2, argc);
852 
853  if (!autocvar_sv_vote_call && caller)
854  {
855  print_to(caller, "^1Vote calling is not allowed.");
856  }
857  else if (!autocvar_sv_vote_gamestart && time < game_starttime)
858  {
859  print_to(caller, "^1Vote calling is not allowed before the match has started.");
860  }
861  else if (vote_called)
862  {
863  print_to(caller, "^1There is already a vote called.");
864  }
865  else if (!spectators_allowed && (caller && !IS_PLAYER(caller)))
866  {
867  print_to(caller, "^1Only players can call a vote.");
868  }
869  else if (caller && !IS_CLIENT(caller))
870  {
871  print_to(caller, "^1Only connected clients can vote.");
872  }
873  else if (timeout_status && vote_command != "timein")
874  {
875  print_to(caller, "^1You can not call a vote while a timeout is active.");
876  }
877  else if (caller && (time < caller.vote_waittime))
878  {
879  print_to(caller, strcat("^1You have to wait ^2", ftos(ceil(caller.vote_waittime - time)), "^1 seconds before you can again call a vote."));
880  }
881  else if (!VoteCommand_checknasty(vote_command))
882  {
883  print_to(caller, "^1Syntax error in command.");
884  }
885  else if ((parse_error = VoteCommand_parse(caller, vote_command, autocvar_sv_vote_commands, 2, argc)) <= 0)
886  {
887  if(parse_error == 0)
888  {
889  if (vote_called_command == "")
890  VoteCommand_call(CMD_REQUEST_USAGE, caller, argc, vote_command);
891  else
892  print_to(caller, "^1This command is not acceptable or not available.");
893  }
894  }
895  else // everything went okay, continue with calling the vote
896  {
897  vote_caller = caller; // remember who called the vote
903 
904  if (caller)
905  {
906  caller.vote_selection = VOTE_SELECT_ACCEPT;
907  caller.vote_waittime = time + autocvar_sv_vote_wait;
908  msg_entity = caller;
909  }
910 
911  FOREACH_CLIENT(IS_REAL_CLIENT(it), { ++tmp_playercount; });
912 
913  bprint("\{1}^2* ^3", OriginalCallerName(), "^2 calls a vote for ", vote_called_display, "\n");
915  GameLogEcho(strcat(":vote:vcall:", ftos(vote_caller.playerid), ":", vote_called_display));
917  VoteCount(true); // needed if you are the only one
918 
919  if (tmp_playercount > 1 && vote_called != VOTE_NULL)
920  Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_VOTE_CALL);
921  }
922 
923  return;
924  }
925 
926  default:
927  case CMD_REQUEST_USAGE:
928  {
929  print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote call <command>"));
930  print_to(caller, " Where <command> is the command to request a vote upon.");
931  print_to(caller, strcat("Examples: ", GetCommandPrefix(caller), " vote call gotomap dance"));
932  print_to(caller, strcat(" ", GetCommandPrefix(caller), " vote call endmatch"));
934  print_to(caller, "Shortcuts: ^2vcall <command>, vend, vmap, vkick, ...");
935  return;
936  }
937  }
938 }
void print_available_commands_to(entity caller)
Definition: vote.qc:837
string OriginalCallerName()
Definition: vote.qc:118
string GetCommandPrefix(entity caller)
Definition: common.qc:26
#define IS_CLIENT(v)
Definition: utils.qh:13
void Nagger_VoteChanged()
Definition: vote.qc:102
const int CMD_REQUEST_USAGE
Definition: command.qh:4
void VoteCommand_call(int request, entity caller, int argc, string vote_command)
Definition: vote.qc:842
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
bool autocvar_sv_vote_call
Definition: vote.qh:3
void print_to(entity to, string input)
Definition: common.qc:172
float vote_called
Definition: vote.qh:43
string autocvar_sv_vote_commands
Definition: vote.qh:5
const float VOTE_NULL
Definition: vote.qh:36
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
int VoteCommand_parse(entity caller, string vote_command, string vote_list, float startpos, int argc)
Definition: vote.qc:675
float vote_endtime
Definition: vote.qh:44
string VoteCommand_extractcommand(string input, float startpos, int argc)
Definition: vote.qc:534
entity msg_entity
Definition: progsdefs.qc:63
string vote_parsed_display
Definition: vote.qh:55
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
const float VOTE_NORMAL
Definition: vote.qh:37
#define NULL
Definition: post.qh:17
const int CMD_REQUEST_COMMAND
Definition: command.qh:3
string vote_parsed_command
Definition: vote.qh:54
void GameLogEcho(string s)
Definition: gamelog.qc:12
string GetCallerName(entity caller)
Definition: common.qc:33
float VoteCommand_checknasty(string vote_command)
Definition: vote.qc:544
string vote_called_display
Definition: vote.qh:53
bool autocvar_sv_vote_gamestart
Definition: vote.qh:22
string vote_caller_name
Definition: vote.qh:42
entity vote_caller
Definition: vote.qh:41
const float VOTE_SELECT_ACCEPT
Definition: vote.qh:33
float autocvar_sv_vote_wait
Definition: vote.qh:21
void VoteCount(float first_count)
Definition: vote.qc:207
bool autocvar_sv_eventlog
Definition: gamelog.qh:3
string vote_called_command
Definition: vote.qh:52
float time
Definition: csprogsdefs.qc:16
#define spectators_allowed
Definition: vote.qc:205
#define IS_PLAYER(v)
Definition: utils.qh:9
float autocvar_sv_vote_timeout
Definition: vote.qh:20
+ Here is the call graph for this function:

◆ Votecommand_check_assignment()

float Votecommand_check_assignment ( entity  caller,
float  assignment 
)

Definition at line 523 of file vote.qc.

References VC_ASGNMNT_BOTH, VC_ASGNMNT_CLIENTONLY, and VC_ASGNMNT_SERVERONLY.

524 {
525  float from_server = (!caller);
526 
527  if ((assignment == VC_ASGNMNT_BOTH)
528  || ((!from_server && assignment == VC_ASGNMNT_CLIENTONLY)
529  || (from_server && assignment == VC_ASGNMNT_SERVERONLY))) return true;
530 
531  return false;
532 }
const float VC_ASGNMNT_CLIENTONLY
Definition: vote.qh:26
const float VC_ASGNMNT_SERVERONLY
Definition: vote.qh:27
const float VC_ASGNMNT_BOTH
Definition: vote.qh:25

◆ VoteCommand_checkargs()

float VoteCommand_checkargs ( float  startpos,
int  argc 
)

Definition at line 601 of file vote.qc.

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

Referenced by VoteCommand_parse().

602 {
603  float p, q, check, minargs;
604  string cvarname = strcat("sv_vote_command_restriction_", argv(startpos));
605  string cmdrestriction = ""; // No we don't.
606  string charlist, arg;
607  float checkmate;
608 
609  if(cvar_type(cvarname) & CVAR_TYPEFLAG_EXISTS)
610  cmdrestriction = cvar_string(cvarname);
611  else
612  LOG_INFO("NOTE: ", cvarname, " does not exist, no restrictions will be applied.");
613 
614  if (cmdrestriction == "") return true;
615 
616  ++startpos; // skip command name
617 
618  // check minimum arg count
619 
620  // 0 args: argc == startpos
621  // 1 args: argc == startpos + 1
622  // ...
623 
624  minargs = stof(cmdrestriction);
625  if (argc - startpos < minargs) return false;
626 
627  p = strstrofs(cmdrestriction, ";", 0); // find first semicolon
628 
629  for ( ; ; )
630  {
631  // we know that at any time, startpos <= argc - minargs
632  // so this means: argc-minargs >= startpos >= argc, thus
633  // argc-minargs >= argc, thus minargs <= 0, thus all minargs
634  // have been seen already
635 
636  if (startpos >= argc) // all args checked? GOOD
637  break;
638 
639  if (p < 0) // no more args? FAIL
640  {
641  // exception: exactly minargs left, this one included
642  if (argc - startpos == minargs) break;
643 
644  // otherwise fail
645  return false;
646  }
647 
648  // cut to next semicolon
649  q = strstrofs(cmdrestriction, ";", p + 1); // find next semicolon
650  if (q < 0) charlist = substring(cmdrestriction, p + 1, -1);
651  else charlist = substring(cmdrestriction, p + 1, q - (p + 1));
652 
653  // in case we ever want to allow semicolons in VoteCommand_checknasty
654  // charlist = strreplace("^^", ";", charlist);
655 
656  if (charlist != "")
657  {
658  // verify the arg only contains allowed chars
659  arg = argv(startpos);
660  checkmate = strlen(arg);
661  for (check = 0; check < checkmate; ++check)
662  if (strstrofs(charlist, substring(arg, check, 1), 0) < 0) return false;
663  // not allowed character
664  // all characters are allowed. FINE.
665  }
666 
667  ++startpos;
668  --minargs;
669  p = q;
670  }
671 
672  return true;
673 }
float CVAR_TYPEFLAG_EXISTS
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
#define LOG_INFO(...)
Definition: log.qh:70
#define strstrofs
Definition: dpextensions.qh:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteCommand_checkinlist()

float VoteCommand_checkinlist ( string  vote_command,
string  list 
)

Definition at line 564 of file vote.qc.

References strcat(), strstrofs, and VoteCommand_checkreplacements().

Referenced by VoteCommand_parse().

565 {
566  string l = VoteCommand_checkreplacements(strcat(" ", list, " "));
567 
568  if (strstrofs(l, VoteCommand_checkreplacements(strcat(" ", vote_command, " ")), 0) >= 0) return true;
569 
570  return false;
571 }
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
#define strstrofs
Definition: dpextensions.qh:42
string VoteCommand_checkreplacements(string input)
Definition: vote.qc:555
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteCommand_checknasty()

float VoteCommand_checknasty ( string  vote_command)

Definition at line 544 of file vote.qc.

References strstrofs.

Referenced by VoteCommand_call(), and VoteCommand_master().

545 {
546  if ((strstrofs(vote_command, ";", 0) >= 0)
547  || (strstrofs(vote_command, "\n", 0) >= 0)
548  || (strstrofs(vote_command, "\r", 0) >= 0)
549  || (strstrofs(vote_command, "$", 0) >= 0)) return false;
550 
551  return true;
552 }
#define strstrofs
Definition: dpextensions.qh:42
+ Here is the caller graph for this function:

◆ VoteCommand_checkreplacements()

string VoteCommand_checkreplacements ( string  input)

Definition at line 555 of file vote.qc.

Referenced by VoteCommand_checkinlist().

556 {
557  string output = input;
558  // allow gotomap replacements
559  output = strreplace(" map ", " gotomap ", output);
560  output = strreplace(" chmap ", " gotomap ", output);
561  return output;
562 }
+ Here is the caller graph for this function:

◆ VoteCommand_extractcommand()

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

Definition at line 534 of file vote.qc.

References argv_end_index, argv_start_index, and substring().

Referenced by VoteCommand_call(), and VoteCommand_master().

535 {
536  string output;
537 
538  if ((argc - 1) < startpos) output = "";
539  else output = substring(input, argv_start_index(startpos), argv_end_index(-1) - argv_start_index(startpos));
540 
541  return output;
542 }
#define argv_end_index
Definition: dpextensions.qh:30
#define argv_start_index
Definition: dpextensions.qh:27
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteCommand_macro_command()

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

Definition at line 1248 of file vote.qc.

References CMD_REQUEST_COMMAND, and VOTE_COMMANDS.

Referenced by VoteCommand().

1249 {
1250  #define VOTE_COMMAND(name, function, description, assignment) \
1251  { if (Votecommand_check_assignment(caller, assignment)) { if (name == strtolower(argv(1))) { function; return true; } } }
1252 
1253  VOTE_COMMANDS(CMD_REQUEST_COMMAND, caller, argc, vote_command);
1254  #undef VOTE_COMMAND
1255 
1256  return false;
1257 }
const int CMD_REQUEST_COMMAND
Definition: command.qh:3
#define VOTE_COMMANDS(request, caller, arguments, command)
Definition: vote.qc:1204
+ Here is the caller graph for this function:

◆ VoteCommand_macro_help()

void VoteCommand_macro_help ( entity  caller,
int  argc 
)

Definition at line 1215 of file vote.qc.

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

Referenced by VoteCommand().

1216 {
1217  string command_origin = GetCommandPrefix(caller);
1218 
1219  if (argc == 2 || argv(2) == "help") // help display listing all commands
1220  {
1221  print_to(caller, "\nVoting commands:\n");
1222  #define VOTE_COMMAND(name, function, description, assignment) \
1223  { if (Votecommand_check_assignment(caller, assignment)) { print_to(caller, strcat(" ^2", name, "^7: ", description)); } }
1224 
1225  VOTE_COMMANDS(0, caller, 0, "");
1226  #undef VOTE_COMMAND
1227 
1228  print_to(caller, strcat("\nUsage:^3 ", command_origin, " vote <command>^7, where possible commands are listed above.\n"));
1229  print_to(caller, strcat("For help about a specific command, type ", command_origin, " vote help <command>"));
1231  }
1232  else // usage for individual command
1233  {
1234  #define VOTE_COMMAND(name, function, description, assignment) \
1235  { if (Votecommand_check_assignment(caller, assignment)) { if (name == strtolower(argv(2))) { function; return; } } }
1236 
1237  VOTE_COMMANDS(CMD_REQUEST_USAGE, caller, argc, "");
1238  #undef VOTE_COMMAND
1239 
1240  string cvarname = strcat("sv_vote_command_help_", argv(2));
1241  if(cvar_type(cvarname) & CVAR_TYPEFLAG_EXISTS)
1242  wordwrap_sprint(caller, cvar_string(cvarname), 1000);
1243  else if (argv(2) != "")
1244  print_to(caller, "No documentation exists for this vote");
1245  }
1246 }
void print_available_commands_to(entity caller)
Definition: vote.qc:837
string GetCommandPrefix(entity caller)
Definition: common.qc:26
const int CMD_REQUEST_USAGE
Definition: command.qh:4
float CVAR_TYPEFLAG_EXISTS
void print_to(entity to, string input)
Definition: common.qc:172
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
#define VOTE_COMMANDS(request, caller, arguments, command)
Definition: vote.qc:1204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteCommand_master()

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

Definition at line 940 of file vote.qc.

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, ftos(), GameLogEcho(), GetCallerName(), GetCommandPrefix(), IS_PLAYER, localcmd, Nagger_VoteChanged(), OriginalCallerName(), print_to(), spectators_allowed, strcat(), strzone(), time, 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_parse(), and VoteCount().

941 {
942  switch (request)
943  {
944  case CMD_REQUEST_COMMAND:
945  {
947  {
948  switch (strtolower(argv(2)))
949  {
950  case "do":
951  {
952  int parse_error;
953  vote_command = VoteCommand_extractcommand(vote_command, 3, argc);
954 
955  if (!caller.vote_master)
956  print_to(caller, "^1You do not have vote master privileges.");
957  else if (!VoteCommand_checknasty(vote_command))
958  {
959  print_to(caller, "^1Syntax error in command.");
960  }
961  else if ((parse_error = VoteCommand_parse(caller, vote_command, strcat(autocvar_sv_vote_commands, " ", autocvar_sv_vote_master_commands), 3, argc)) <= 0)
962  {
963  if(parse_error == 0)
964  {
965  if (vote_called_command == "")
966  VoteCommand_master(CMD_REQUEST_USAGE, caller, argc, vote_command);
967  else
968  print_to(caller, "^1This command is not acceptable or not available.");
969  }
970  }
971  else // everything went okay, proceed with command
972  {
974  print_to(caller, strcat("Executing command '", vote_parsed_display, "' on server."));
975  bprint("\{1}^2* ^3", GetCallerName(caller), "^2 used their ^3master^2 status to do \"^2", vote_parsed_display, "^2\".\n");
977  GameLogEcho(strcat(":vote:vdo:", ftos(caller.playerid), ":", vote_parsed_display));
978  }
979 
980  return;
981  }
982 
983  case "login":
984  {
985  if (autocvar_sv_vote_master_password == "") { print_to(caller, "^1Login to vote master is not allowed."); }
986  else if (caller.vote_master)
987  {
988  print_to(caller, "^1You are already logged in as vote master.");
989  }
990  else if (autocvar_sv_vote_master_password != argv(3))
991  {
992  print_to(caller, strcat("Rejected vote master login from ", GetCallerName(caller)));
993  }
994  else // everything went okay, proceed with giving this player master privilages
995  {
996  caller.vote_master = true;
997  print_to(caller, strcat("Accepted vote master login from ", GetCallerName(caller)));
998  bprint("\{1}^2* ^3", GetCallerName(caller), "^2 logged in as ^3master^2\n");
1000  GameLogEcho(strcat(":vote:vlogin:", ftos(caller.playerid)));
1001  }
1002 
1003  return;
1004  }
1005 
1006  default: // calling a vote for master
1007  {
1008  if (!autocvar_sv_vote_master_callable) { print_to(caller, "^1Vote to become vote master is not allowed."); }
1009  else if (vote_called)
1010  {
1011  print_to(caller, "^1There is already a vote called.");
1012  }
1013  else if (!spectators_allowed && (caller && !IS_PLAYER(caller)))
1014  {
1015  print_to(caller, "^1Only players can call a vote.");
1016  }
1017  else if (timeout_status)
1018  {
1019  print_to(caller, "^1You can not call a vote while a timeout is active.");
1020  }
1021  else // everything went okay, continue with creating vote
1022  {
1023  vote_caller = caller;
1026  vote_called_command = strzone("XXX");
1027  vote_called_display = strzone("^3master");
1029 
1030  caller.vote_selection = VOTE_SELECT_ACCEPT;
1031  caller.vote_waittime = time + autocvar_sv_vote_wait;
1032 
1033  bprint("\{1}^2* ^3", OriginalCallerName(), "^2 calls a vote to become ^3master^2.\n");
1035  GameLogEcho(strcat(":vote:vcall:", ftos(vote_caller.playerid), ":", vote_called_display));
1037  VoteCount(true); // needed if you are the only one
1038  }
1039 
1040  return;
1041  }
1042  }
1043  }
1044  else { print_to(caller, "^1Master control of voting is not allowed."); }
1045 
1046  return;
1047  }
1048 
1049  default:
1050  case CMD_REQUEST_USAGE:
1051  {
1052  print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote master [<action> [<command> | <password>]]"));
1053  print_to(caller, " If <action> is left blank, it calls a vote for you to become master.");
1054  print_to(caller, " Otherwise it can be either 'do' (to run <command>) or 'login' as master.");
1055  return;
1056  }
1057  }
1058 }
string OriginalCallerName()
Definition: vote.qc:118
string GetCommandPrefix(entity caller)
Definition: common.qc:26
void Nagger_VoteChanged()
Definition: vote.qc:102
const int CMD_REQUEST_USAGE
Definition: command.qh:4
bool autocvar_sv_vote_master_callable
Definition: vote.qh:10
const float VOTE_MASTER
Definition: vote.qh:38
void print_to(entity to, string input)
Definition: common.qc:172
float vote_called
Definition: vote.qh:43
string autocvar_sv_vote_commands
Definition: vote.qh:5
bool autocvar_sv_vote_master
Definition: vote.qh:9
void VoteCommand_master(int request, entity caller, int argc, string vote_command)
Definition: vote.qc:940
int VoteCommand_parse(entity caller, string vote_command, string vote_list, float startpos, int argc)
Definition: vote.qc:675
float vote_endtime
Definition: vote.qh:44
string autocvar_sv_vote_master_commands
Definition: vote.qh:11
string VoteCommand_extractcommand(string input, float startpos, int argc)
Definition: vote.qc:534
string vote_parsed_display
Definition: vote.qh:55
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
string autocvar_sv_vote_master_password
Definition: vote.qh:12
const int CMD_REQUEST_COMMAND
Definition: command.qh:3
string vote_parsed_command
Definition: vote.qh:54
void GameLogEcho(string s)
Definition: gamelog.qc:12
string GetCallerName(entity caller)
Definition: common.qc:33
float VoteCommand_checknasty(string vote_command)
Definition: vote.qc:544
string vote_called_display
Definition: vote.qh:53
string vote_caller_name
Definition: vote.qh:42
entity vote_caller
Definition: vote.qh:41
const float VOTE_SELECT_ACCEPT
Definition: vote.qh:33
float autocvar_sv_vote_wait
Definition: vote.qh:21
void VoteCount(float first_count)
Definition: vote.qc:207
bool autocvar_sv_eventlog
Definition: gamelog.qh:3
string vote_called_command
Definition: vote.qh:52
float time
Definition: csprogsdefs.qc:16
#define spectators_allowed
Definition: vote.qc:205
#define IS_PLAYER(v)
Definition: utils.qh:9
float autocvar_sv_vote_timeout
Definition: vote.qh:20
+ Here is the call graph for this function:

◆ VoteCommand_no()

void VoteCommand_no ( int  request,
entity  caller 
)

Definition at line 1060 of file vote.qc.

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

1061 {
1062  switch (request)
1063  {
1064  case CMD_REQUEST_COMMAND:
1065  {
1066  if (!vote_called) { print_to(caller, "^1No vote called."); }
1067  else if (caller.vote_selection != VOTE_SELECT_NULL && !autocvar_sv_vote_change)
1068  {
1069  print_to(caller, "^1You have already voted.");
1070  }
1071  else if (((caller == vote_caller) || caller.vote_master) && autocvar_sv_vote_no_stops_vote)
1072  {
1073  VoteStop(caller);
1074  }
1075 
1076  else // everything went okay, continue changing vote
1077  {
1078  print_to(caller, "^1You rejected the vote.");
1079  caller.vote_selection = VOTE_SELECT_REJECT;
1080  msg_entity = caller;
1082  VoteCount(false);
1083  }
1084 
1085  return;
1086  }
1087 
1088  default:
1089  case CMD_REQUEST_USAGE:
1090  {
1091  print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote no"));
1092  print_to(caller, " No arguments required.");
1093  return;
1094  }
1095  }
1096 }
bool autocvar_sv_vote_no_stops_vote
Definition: vote.qh:14
bool autocvar_sv_vote_change
Definition: vote.qh:4
string GetCommandPrefix(entity caller)
Definition: common.qc:26
const int CMD_REQUEST_USAGE
Definition: command.qh:4
void print_to(entity to, string input)
Definition: common.qc:172
float vote_called
Definition: vote.qh:43
const float VOTE_SELECT_NULL
Definition: vote.qh:32
bool autocvar_sv_vote_singlecount
Definition: vote.qh:18
entity msg_entity
Definition: progsdefs.qc:63
const float VOTE_SELECT_REJECT
Definition: vote.qh:31
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
void VoteStop(entity stopper)
Definition: vote.qc:149
const int CMD_REQUEST_COMMAND
Definition: command.qh:3
entity vote_caller
Definition: vote.qh:41
void VoteCount(float first_count)
Definition: vote.qc:207
+ Here is the call graph for this function:

◆ VoteCommand_parse()

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

Definition at line 675 of file vote.qc.

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

676 {
677  string first_command = argv(startpos);
678  int missing_chars = argv_start_index(startpos);
679 
680  if (autocvar_sv_vote_limit > 0 && strlen(vote_command) > autocvar_sv_vote_limit)
681  return 0;
682 
683  if (!VoteCommand_checkinlist(first_command, vote_list)) return 0;
684 
685  if (!VoteCommand_checkargs(startpos, argc)) return 0;
686 
687  switch (MUTATOR_CALLHOOK(VoteCommand_Parse, caller, first_command, vote_command, startpos, argc))
688  {
689  case MUT_VOTEPARSE_CONTINUE: { break; }
690  case MUT_VOTEPARSE_SUCCESS: { return 1; }
691  case MUT_VOTEPARSE_INVALID: { return -1; }
692  case MUT_VOTEPARSE_UNACCEPTABLE: { return 0; }
693  }
694 
695  switch (first_command) // now go through and parse the proper commands to adjust as needed.
696  {
697  case "kick":
698  case "kickban": // catch all kick/kickban commands
699  {
700  entity victim = GetIndexedEntity(argc, (startpos + 1));
701  float accepted = VerifyClientEntity(victim, true, false);
702 
703  if (accepted > 0)
704  {
705  string reason = "No reason provided";
706  if(argc > next_token)
707  reason = substring(vote_command, argv_start_index(next_token) - missing_chars, -1);
708 
709  string command_arguments = reason;
710  if (first_command == "kickban")
712 
713  vote_parsed_command = strcat(first_command, " # ", ftos(etof(victim)), " ", command_arguments);
714  vote_parsed_display = sprintf("^1%s #%d ^7%s^1 %s", first_command, etof(victim), victim.netname, reason);
715  }
716  else
717  {
718  print_to(caller, strcat("vcall: ", GetClientErrorString(accepted, argv(startpos + 1)), ".\n"));
719  return 0;
720  }
721 
722  break;
723  }
724 
725  case "map":
726  case "chmap":
727  case "gotomap": // re-direct all map selection commands to gotomap
728  {
729  vote_command = ValidateMap(argv(startpos + 1), caller);
730  if (!vote_command) return -1;
731  vote_parsed_command = strcat("gotomap ", vote_command);
733 
734  break;
735  }
736 
737  // TODO: replicate the old behaviour of being able to vote for maps from different modes on multimode servers (possibly support it in gotomap too)
738  // maybe fallback instead of aborting if map name is invalid?
739  case "nextmap":
740  {
741  vote_command = ValidateMap(argv(startpos + 1), caller);
742  if (!vote_command) return -1;
743  vote_parsed_command = strcat("nextmap ", vote_command);
745 
746  break;
747  }
748 
749  case "timelimit": // include restrictions on the maximum votable time limit
750  {
751  float timelimit_vote = stof(argv(startpos + 1));
752  if(timelimit_vote > autocvar_timelimit_max || timelimit_vote < autocvar_timelimit_min)
753  {
754  print_to(caller, strcat("Invalid timelimit vote, accepted values are between ", ftos(autocvar_timelimit_min), " and ", ftos(autocvar_timelimit_max), "."));
755  return -1;
756  }
757  timelimit_vote = bound(autocvar_timelimit_min, timelimit_vote, autocvar_timelimit_max);
758  vote_parsed_command = strcat("timelimit ", ftos(timelimit_vote));
760 
761  break;
762  }
763 
764  case "restart": // re-direct all match restarting to resetmatch
765  vote_command = "resetmatch"; // fall-through
766  case "resetmatch":
767  {
768  vote_parsed_command = vote_command;
769  vote_parsed_display = strzone(strcat("^1", vote_command));
770 
771  break;
772  }
773 
774  case "allready":
775  {
776  if(!warmup_stage) {
777  print_to(caller, "Game already started. Use the resetmatch command to restart the match.");
778  return -1;
779  }
780 
781  vote_parsed_command = vote_command;
782  vote_parsed_display = strzone(strcat("^1", vote_command));
783  break;
784  }
785 
786  default:
787  {
788  vote_parsed_command = vote_command;
789  vote_parsed_display = strzone(strcat("^1", vote_command));
790 
791  break;
792  }
793  }
794 
795  return 1;
796 }
entity GetIndexedEntity(int argc, float start_index)
Definition: common.qc:83
int autocvar_sv_vote_limit
Definition: vote.qh:6
float autocvar_g_ban_default_bantime
Definition: banning.qh:3
entity() spawn
float VoteCommand_checkinlist(string vote_command, string list)
Definition: vote.qc:564
float VerifyClientEntity(entity client, float must_be_real, float must_be_bots)
Definition: common.qc:47
bool warmup_stage
Definition: main.qh:103
void print_to(entity to, string input)
Definition: common.qc:172
float autocvar_timelimit_max
Definition: world.qh:26
float next_token
Definition: common.qh:71
string vote_parsed_display
Definition: vote.qh:55
#define argv_start_index
Definition: dpextensions.qh:27
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
float autocvar_g_ban_default_masksize
Definition: banning.qh:4
string vote_parsed_command
Definition: vote.qh:54
#define GetClientErrorString(clienterror, original_input)
Definition: common.qh:87
string ValidateMap(string validated_map, entity caller)
Definition: vote.qc:573
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
float VoteCommand_checkargs(float startpos, int argc)
Definition: vote.qc:601
float autocvar_timelimit_min
Definition: world.qh:25
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteCommand_status()

void VoteCommand_status ( int  request,
entity  caller 
)

Definition at line 1098 of file vote.qc.

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

1099 {
1100  switch (request)
1101  {
1102  case CMD_REQUEST_COMMAND:
1103  {
1104  if (vote_called) print_to(caller, strcat("^7Vote for ", vote_called_display, "^7 called by ^7", OriginalCallerName(), "^7."));
1105  else print_to(caller, "^1No vote called.");
1106 
1107  return;
1108  }
1109 
1110  default:
1111  case CMD_REQUEST_USAGE:
1112  {
1113  print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote status"));
1114  print_to(caller, " No arguments required.");
1115  return;
1116  }
1117  }
1118 }
string OriginalCallerName()
Definition: vote.qc:118
string GetCommandPrefix(entity caller)
Definition: common.qc:26
const int CMD_REQUEST_USAGE
Definition: command.qh:4
void print_to(entity to, string input)
Definition: common.qc:172
float vote_called
Definition: vote.qh:43
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
const int CMD_REQUEST_COMMAND
Definition: command.qh:3
string vote_called_display
Definition: vote.qh:53
+ Here is the call graph for this function:

◆ VoteCommand_stop()

void VoteCommand_stop ( int  request,
entity  caller 
)

Definition at line 1120 of file vote.qc.

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

1121 {
1122  switch (request)
1123  {
1124  case CMD_REQUEST_COMMAND:
1125  {
1126  if (!vote_called) print_to(caller, "^1No vote called.");
1127  else if ((caller == vote_caller) || !caller || caller.vote_master) VoteStop(caller);
1128  else print_to(caller, "^1You are not allowed to stop that vote.");
1129  return;
1130  }
1131 
1132  default:
1133  case CMD_REQUEST_USAGE:
1134  {
1135  print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote stop"));
1136  print_to(caller, " No arguments required.");
1137  return;
1138  }
1139  }
1140 }
string GetCommandPrefix(entity caller)
Definition: common.qc:26
const int CMD_REQUEST_USAGE
Definition: command.qh:4
void print_to(entity to, string input)
Definition: common.qc:172
float vote_called
Definition: vote.qh:43
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
void VoteStop(entity stopper)
Definition: vote.qc:149
const int CMD_REQUEST_COMMAND
Definition: command.qh:3
entity vote_caller
Definition: vote.qh:41
+ Here is the call graph for this function:

◆ VoteCommand_yes()

void VoteCommand_yes ( int  request,
entity  caller 
)

Definition at line 1142 of file vote.qc.

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

1143 {
1144  switch (request)
1145  {
1146  case CMD_REQUEST_COMMAND:
1147  {
1148  if (!vote_called) { print_to(caller, "^1No vote called."); }
1149  else if (caller.vote_selection != VOTE_SELECT_NULL && !autocvar_sv_vote_change)
1150  {
1151  print_to(caller, "^1You have already voted.");
1152  }
1153  else // everything went okay, continue changing vote
1154  {
1155  print_to(caller, "^1You accepted the vote.");
1156  caller.vote_selection = VOTE_SELECT_ACCEPT;
1157  msg_entity = caller;
1159  VoteCount(false);
1160  }
1161 
1162  return;
1163  }
1164 
1165  default:
1166  case CMD_REQUEST_USAGE:
1167  {
1168  print_to(caller, strcat("\nUsage:^3 ", GetCommandPrefix(caller), " vote yes"));
1169  print_to(caller, " No arguments required.");
1170  return;
1171  }
1172  }
1173 }
bool autocvar_sv_vote_change
Definition: vote.qh:4
string GetCommandPrefix(entity caller)
Definition: common.qc:26
const int CMD_REQUEST_USAGE
Definition: command.qh:4
void print_to(entity to, string input)
Definition: common.qc:172
float vote_called
Definition: vote.qh:43
const float VOTE_SELECT_NULL
Definition: vote.qh:32
bool autocvar_sv_vote_singlecount
Definition: vote.qh:18
entity msg_entity
Definition: progsdefs.qc:63
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
const int CMD_REQUEST_COMMAND
Definition: command.qh:3
const float VOTE_SELECT_ACCEPT
Definition: vote.qh:33
void VoteCount(float first_count)
Definition: vote.qc:207
+ Here is the call graph for this function:

◆ VoteCount()

void VoteCount ( float  first_count)

Definition at line 207 of file vote.qc.

References autocvar_sv_vote_majority_factor, autocvar_sv_vote_majority_factor_of_voted, autocvar_sv_vote_master_playerlimit, bound(), floor(), FOREACH_CLIENT, IS_CLIENT, 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, VoteAccept(), VoteReject(), VoteReset(), VoteSpam(), and VoteTimeout().

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

208 {
209  // declarations
211 
212  float vote_player_count = 0, notvoters = 0;
213  float vote_real_player_count = 0, vote_real_accept_count = 0;
214  float vote_real_reject_count = 0, vote_real_abstain_count = 0;
215  float vote_needed_of_voted, final_needed_votes;
216  float vote_factor_overall, vote_factor_of_voted;
217 
219 
220  // add up all the votes from each connected client
222  ++vote_player_count;
223  if (IS_PLAYER(it)) ++vote_real_player_count;
224  switch (it.vote_selection)
225  {
226  case VOTE_SELECT_REJECT:
227  { ++vote_reject_count;
228  { if (IS_PLAYER(it)) ++vote_real_reject_count; } break;
229  }
230  case VOTE_SELECT_ACCEPT:
231  { ++vote_accept_count;
232  { if (IS_PLAYER(it)) ++vote_real_accept_count; } break;
233  }
234  case VOTE_SELECT_ABSTAIN:
235  { ++vote_abstain_count;
236  { if (IS_PLAYER(it)) ++vote_real_abstain_count; } break;
237  }
238  default: break;
239  }
240  });
241 
242  // Check to see if there are enough players on the server to allow master voting... otherwise, vote master could be used for evil.
243  if ((vote_called == VOTE_MASTER) && autocvar_sv_vote_master_playerlimit > vote_player_count)
244  {
245  if (vote_caller) vote_caller.vote_waittime = 0;
246  print_to(vote_caller, "^1There are not enough players on this server to allow you to become vote master.");
247  VoteReset();
248  return;
249  }
250 
251  // 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.
252  if (!spectators_allowed && (vote_real_player_count > 0))
253  {
254  vote_accept_count = vote_real_accept_count;
255  vote_reject_count = vote_real_reject_count;
256  vote_abstain_count = vote_real_abstain_count;
257  vote_player_count = vote_real_player_count;
258  }
259 
260  // people who have no opinion in any way :D
261  notvoters = (vote_player_count - vote_accept_count - vote_reject_count - vote_abstain_count);
262 
263  // determine the goal for the vote to be passed or rejected normally
264  vote_factor_overall = bound(0.5, autocvar_sv_vote_majority_factor, 0.999);
265  vote_needed_overall = floor((vote_player_count - vote_abstain_count) * vote_factor_overall) + 1;
266 
267  // if the vote times out, determine the amount of votes needed of the people who actually already voted
268  vote_factor_of_voted = bound(0.5, autocvar_sv_vote_majority_factor_of_voted, 0.999);
269  vote_needed_of_voted = floor((vote_accept_count + vote_reject_count) * vote_factor_of_voted) + 1;
270 
271  // are there any players at all on the server? it could be an admin vote
272  if (vote_player_count == 0 && first_count)
273  {
274  VoteSpam(0, -1, "yes"); // no players at all, just accept it
275  VoteAccept();
276  return;
277  }
278 
279  // since there ARE players, finally calculate the result of the vote
281  {
282  VoteSpam(notvoters, -1, "yes"); // there is enough acceptions to pass the vote
283  VoteAccept();
284  return;
285  }
286 
287  if (vote_reject_count > vote_player_count - vote_abstain_count - vote_needed_overall)
288  {
289  VoteSpam(notvoters, -1, "no"); // there is enough rejections to deny the vote
290  VoteReject();
291  return;
292  }
293 
294  // there is not enough votes in either direction, now lets just calculate what the voters have said
295  if (time > vote_endtime)
296  {
297  final_needed_votes = vote_needed_overall;
298 
300  {
301  if (vote_accept_count >= vote_needed_of_voted)
302  {
303  VoteSpam(notvoters, min(vote_needed_overall, vote_needed_of_voted), "yes");
304  VoteAccept();
305  return;
306  }
307 
309  {
310  VoteSpam(notvoters, min(vote_needed_overall, vote_needed_of_voted), "no");
311  VoteReject();
312  return;
313  }
314 
315  final_needed_votes = min(vote_needed_overall, vote_needed_of_voted);
316  }
317 
318  // it didn't pass or fail, so not enough votes to even make a decision.
319  VoteSpam(notvoters, final_needed_votes, "timeout");
320  VoteTimeout();
321  }
322 }
float autocvar_sv_vote_majority_factor_of_voted
Definition: vote.qh:8
#define IS_CLIENT(v)
Definition: utils.qh:13
int autocvar_sv_vote_master_playerlimit
Definition: vote.qh:13
float autocvar_sv_vote_majority_factor
Definition: vote.qh:7
const float VOTE_MASTER
Definition: vote.qh:38
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
void Nagger_VoteCountChanged()
Definition: vote.qc:107
void print_to(entity to, string input)
Definition: common.qc:172
float vote_called
Definition: vote.qh:43
void VoteTimeout()
Definition: vote.qc:178
void VoteReject()
Definition: vote.qc:171
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
float vote_endtime
Definition: vote.qh:44
void VoteAccept()
Definition: vote.qc:158
float vote_accept_count
Definition: vote.qh:45
float vote_needed_overall
Definition: vote.qh:48
float vote_reject_count
Definition: vote.qh:46
entity vote_caller
Definition: vote.qh:41
const float VOTE_SELECT_ACCEPT
Definition: vote.qh:33
float vote_abstain_count
Definition: vote.qh:47
const float VOTE_SELECT_ABSTAIN
Definition: vote.qh:30
void VoteReset()
Definition: vote.qc:128
float time
Definition: csprogsdefs.qc:16
#define spectators_allowed
Definition: vote.qc:205
void VoteSpam(float notvoters, float mincount, string result)
Definition: vote.qc:185
#define IS_PLAYER(v)
Definition: utils.qh:9
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteReject()

void VoteReject ( )

Definition at line 171 of file vote.qc.

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

Referenced by VoteCount().

172 {
173  bprint("\{1}^2* ^3", OriginalCallerName(), "^2's vote for ", vote_called_display, "^2 was rejected\n");
174  VoteReset();
175  Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_VOTE_FAIL);
176 }
string OriginalCallerName()
Definition: vote.qc:118
#define NULL
Definition: post.qh:17
string vote_called_display
Definition: vote.qh:53
void VoteReset()
Definition: vote.qc:128
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteReset()

void VoteReset ( )

Definition at line 128 of file vote.qc.

References FOREACH_CLIENT, Nagger_VoteChanged(), NULL, strfree, string_null, vote_called, vote_called_command, vote_called_display, vote_caller, vote_caller_name, vote_endtime, VOTE_NULL, vote_parsed_command, and vote_parsed_display.

Referenced by InitGameplayMode(), NextLevel(), ReadyRestart_force(), VoteAccept(), VoteCount(), VoteReject(), VoteStop(), and VoteTimeout().

129 {
130  FOREACH_CLIENT(true, { it.vote_selection = 0; });
131 
132  if (vote_called)
133  {
137  }
138 
140  vote_caller = NULL;
141  vote_endtime = 0;
142 
145 
147 }
string string_null
Definition: nil.qh:9
void Nagger_VoteChanged()
Definition: vote.qc:102
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
float vote_called
Definition: vote.qh:43
const float VOTE_NULL
Definition: vote.qh:36
float vote_endtime
Definition: vote.qh:44
string vote_parsed_display
Definition: vote.qh:55
#define NULL
Definition: post.qh:17
string vote_parsed_command
Definition: vote.qh:54
string vote_called_display
Definition: vote.qh:53
string vote_caller_name
Definition: vote.qh:42
entity vote_caller
Definition: vote.qh:41
#define strfree(this)
Definition: string.qh:56
string vote_called_command
Definition: vote.qh:52
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteSpam()

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

Definition at line 185 of file vote.qc.

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

Referenced by VoteCount().

186 {
187  bprint(strcat(
188  strcat("\{1}^2* vote results: ^1", ftos(vote_accept_count)),
189  strcat("^2:^1", ftos(vote_reject_count)),
190  ((mincount >= 0) ? strcat("^2 (^1", ftos(mincount), "^2 needed)") : "^2"),
191  strcat(", ^1", ftos(vote_abstain_count), "^2 didn't care"),
192  strcat(", ^1", ftos(notvoters), strcat("^2 didn't ", ((mincount >= 0) ? "" : "have to "), "vote\n"))));
193 
195  {
197  strcat(":vote:v", result, ":", ftos(vote_accept_count)),
200  strcat(":", ftos(notvoters)),
201  strcat(":", ftos(mincount))));
202  }
203 }
entity result
Definition: promise.qc:43
float vote_accept_count
Definition: vote.qh:45
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
void GameLogEcho(string s)
Definition: gamelog.qc:12
float vote_reject_count
Definition: vote.qh:46
float vote_abstain_count
Definition: vote.qh:47
bool autocvar_sv_eventlog
Definition: gamelog.qh:3
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteStop()

void VoteStop ( entity  stopper)

Definition at line 149 of file vote.qc.

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

Referenced by VoteCommand_no(), and VoteCommand_stop().

150 {
151  bprint("\{1}^2* ^3", GetCallerName(stopper), "^2 stopped ^3", OriginalCallerName(), "^2's vote\n");
152  if (autocvar_sv_eventlog) GameLogEcho(strcat(":vote:vstop:", ftos(stopper.playerid)));
153  // Don't force them to wait for next vote, this way they can e.g. correct their vote.
154  if ((vote_caller) && (stopper == vote_caller)) vote_caller.vote_waittime = time + autocvar_sv_vote_stop;
155  VoteReset();
156 }
string OriginalCallerName()
Definition: vote.qc:118
float autocvar_sv_vote_stop
Definition: vote.qh:19
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
void GameLogEcho(string s)
Definition: gamelog.qc:12
string GetCallerName(entity caller)
Definition: common.qc:33
entity vote_caller
Definition: vote.qh:41
void VoteReset()
Definition: vote.qc:128
bool autocvar_sv_eventlog
Definition: gamelog.qh:3
float time
Definition: csprogsdefs.qc:16
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteThink()

void VoteThink ( )

Definition at line 324 of file vote.qc.

References time, vote_endtime, and VoteCount().

Referenced by CheckRules_World().

325 {
326  if (vote_endtime > 0) // a vote was called
327  {
328  if (time > vote_endtime) // time is up
329  VoteCount(false);
330  }
331 }
float vote_endtime
Definition: vote.qh:44
void VoteCount(float first_count)
Definition: vote.qc:207
float time
Definition: csprogsdefs.qc:16
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VoteTimeout()

void VoteTimeout ( )

Definition at line 178 of file vote.qc.

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

Referenced by VoteCount().

179 {
180  bprint("\{1}^2* ^3", OriginalCallerName(), "^2's vote for ", vote_called_display, "^2 timed out\n");
181  VoteReset();
182  Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_VOTE_FAIL);
183 }
string OriginalCallerName()
Definition: vote.qc:118
#define NULL
Definition: post.qh:17
string vote_called_display
Definition: vote.qh:53
void VoteReset()
Definition: vote.qc:128
+ Here is the call graph for this function:
+ Here is the caller graph for this function: