39 WriteHeader(MSG_ENTITY, ENT_CLIENT_NAGGER);
55 if (to.ready == 0) nags |=
BIT(1);
60 if (to.vote_selection == 0) nags |=
BIT(3);
64 if (sendflags &
BIT(6)) nags |=
BIT(6);
66 if (sendflags &
BIT(7)) nags |=
BIT(7);
69 nags &= ~(
BIT(6) |
BIT(7));
87 for (f = 0, e = edict_num(i), b =
BIT(0); b <
BIT(8); b <<= 1, e =
nextent(e))
168 Send_Notification(NOTIF_ALL,
NULL, MSG_ANNCE, ANNCE_VOTE_ACCEPT);
175 Send_Notification(NOTIF_ALL,
NULL, MSG_ANNCE, ANNCE_VOTE_FAIL);
182 Send_Notification(NOTIF_ALL,
NULL, MSG_ANNCE, ANNCE_VOTE_FAIL);
190 ((mincount >= 0) ?
strcat(
"^2 (^1",
ftos(mincount),
"^2 needed)") :
"^2"),
192 strcat(
", ^1",
ftos(notvoters),
strcat(
"^2 didn't ", ((mincount >= 0) ?
"" :
"have to "),
"vote\n"))));
205 #define spectators_allowed (!autocvar_sv_vote_nospectators || (autocvar_sv_vote_nospectators == 1 && (warmup_stage || intermission_running))) 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;
223 if (
IS_PLAYER(it)) ++vote_real_player_count;
224 switch (it.vote_selection)
226 case VOTE_SELECT_REJECT:
227 { ++vote_reject_count;
228 { if (IS_PLAYER(it)) ++vote_real_reject_count; } break;
231 { ++vote_accept_count;
232 { if (IS_PLAYER(it)) ++vote_real_accept_count; }
break;
236 {
if (
IS_PLAYER(it)) ++vote_real_abstain_count; }
break;
246 print_to(
vote_caller,
"^1There are not enough players on this server to allow you to become vote master.");
257 vote_player_count = vote_real_player_count;
272 if (vote_player_count == 0 && first_count)
319 VoteSpam(notvoters, final_needed_votes,
"timeout");
339 void reset_map(
bool dorespawn,
bool is_fake_round_start)
341 if (
time <= game_starttime)
346 if (!is_fake_round_start)
349 PlayerStats_GameReport_Reset_All();
363 if (
time <= game_starttime)
367 if (STAT(FROZEN, it))
374 Inventory_update(store);
389 if (it.team_saved) it.team = it.team_saved;
390 if (it.flags & FL_PROJECTILE)
delete(it);
395 if (it.reset2) it.reset2(it);
407 CS(it).killcount = 0;
409 it.velocity =
'0 0 0';
410 it.avelocity =
'0 0 0';
411 CS(it).movement =
'0 0 0';
428 if (
time <= game_starttime && game_stopped)
430 if (!is_fake_round_start)
431 bprint(
"^1Match is restarting...\n");
441 game_starttime =
time;
448 CS(it).killcount = 0;
469 restart_timer.nextthink = game_starttime;
487 else localcmd(
"\nsv_hook_readyrestart\n");
500 float ready_needed_factor, ready_needed_count;
501 float t_ready = 0, t_players = 0;
505 if (it.ready) ++t_ready;
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;
515 if (readycount >= ready_needed_count)
ReadyRestart(
true);
525 float from_server = (!caller);
538 if ((argc - 1) < startpos) output =
"";
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;
557 string output = input;
559 output = strreplace(
" map ",
" gotomap ", output);
560 output = strreplace(
" chmap ",
" gotomap ", output);
579 print_to(caller,
"This map is not available on this server.");
587 print_to(caller,
"This server does not allow for recent maps to be played again. Please be patient for some rounds.");
594 print_to(caller,
strcat(
"^1Invalid mapname, \"^3", validated_map,
"^1\" does not support the current game mode."));
598 return validated_map;
603 float p, q, check, minargs;
604 string cvarname =
strcat(
"sv_vote_command_restriction_",
argv(startpos));
605 string cmdrestriction =
"";
606 string charlist, arg;
612 LOG_INFO(
"NOTE: ", cvarname,
" does not exist, no restrictions will be applied.");
614 if (cmdrestriction ==
"")
return true;
624 minargs =
stof(cmdrestriction);
625 if (argc - startpos < minargs)
return false;
636 if (startpos >= argc)
642 if (argc - startpos == minargs)
break;
649 q =
strstrofs(cmdrestriction,
";", p + 1);
650 if (q < 0) charlist =
substring(cmdrestriction, p + 1, -1);
651 else charlist =
substring(cmdrestriction, p + 1, q - (p + 1));
659 arg =
argv(startpos);
661 for (check = 0; check < checkmate; ++check)
677 string first_command =
argv(startpos);
687 switch (
MUTATOR_CALLHOOK(VoteCommand_Parse, caller, first_command, vote_command, startpos, argc))
695 switch (first_command)
705 string reason =
"No reason provided";
709 string command_arguments = reason;
710 if (first_command ==
"kickban")
730 if (!vote_command)
return -1;
742 if (!vote_command)
return -1;
751 float timelimit_vote =
stof(
argv(startpos + 1));
765 vote_command =
"resetmatch";
777 print_to(caller,
"Game already started. Use the resetmatch command to restart the match.");
812 print_to(caller,
"^1You have already voted.");
817 print_to(caller,
"^1You abstained from your vote.");
831 print_to(caller,
" No arguments required.");
848 float tmp_playercount = 0;
855 print_to(caller,
"^1Vote calling is not allowed.");
859 print_to(caller,
"^1Vote calling is not allowed before the match has started.");
863 print_to(caller,
"^1There is already a vote called.");
867 print_to(caller,
"^1Only players can call a vote.");
871 print_to(caller,
"^1Only connected clients can vote.");
873 else if (timeout_status && vote_command !=
"timein")
875 print_to(caller,
"^1You can not call a vote while a timeout is active.");
877 else if (caller && (
time < caller.vote_waittime))
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."));
883 print_to(caller,
"^1Syntax error in command.");
892 print_to(caller,
"^1This command is not acceptable or not available.");
920 Send_Notification(NOTIF_ALL,
NULL, MSG_ANNCE, ANNCE_VOTE_CALL);
930 print_to(caller,
" Where <command> is the command to request a vote upon.");
934 print_to(caller,
"Shortcuts: ^2vcall <command>, vend, vmap, vkick, ...");
948 switch (strtolower(
argv(2)))
955 if (!caller.vote_master)
956 print_to(caller,
"^1You do not have vote master privileges.");
959 print_to(caller,
"^1Syntax error in command.");
968 print_to(caller,
"^1This command is not acceptable or not available.");
986 else if (caller.vote_master)
988 print_to(caller,
"^1You are already logged in as vote master.");
996 caller.vote_master =
true;
1011 print_to(caller,
"^1There is already a vote called.");
1015 print_to(caller,
"^1Only players can call a vote.");
1017 else if (timeout_status)
1019 print_to(caller,
"^1You can not call a vote while a timeout is active.");
1044 else {
print_to(caller,
"^1Master control of voting is not allowed."); }
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.");
1069 print_to(caller,
"^1You have already voted.");
1078 print_to(caller,
"^1You rejected the vote.");
1092 print_to(caller,
" No arguments required.");
1105 else print_to(caller,
"^1No vote called.");
1114 print_to(caller,
" No arguments required.");
1128 else print_to(caller,
"^1You are not allowed to stop that vote.");
1136 print_to(caller,
" No arguments required.");
1151 print_to(caller,
"^1You have already voted.");
1155 print_to(caller,
"^1You accepted the vote.");
1169 print_to(caller,
" No arguments required.");
1204 #define VOTE_COMMANDS(request, caller, arguments, command) \ 1205 VOTE_COMMAND("abstain", VoteCommand_abstain(request, caller), "Abstain your vote in current vote", VC_ASGNMNT_CLIENTONLY) \ 1206 VOTE_COMMAND("call", VoteCommand_call(request, caller, arguments, command), "Create a new vote for players to decide on", VC_ASGNMNT_BOTH) \ 1207 VOTE_COMMAND("help", VoteCommand_macro_help(caller, arguments), "Shows this information", VC_ASGNMNT_BOTH) \ 1208 VOTE_COMMAND("master", VoteCommand_master(request, caller, arguments, command), "Full control over all voting and vote commands", VC_ASGNMNT_CLIENTONLY) \ 1209 VOTE_COMMAND("no", VoteCommand_no(request, caller), "Select no in current vote", VC_ASGNMNT_CLIENTONLY) \ 1210 VOTE_COMMAND("status", VoteCommand_status(request, caller), "Prints information about current vote", VC_ASGNMNT_BOTH) \ 1211 VOTE_COMMAND("stop", VoteCommand_stop(request, caller), "Immediately end a vote", VC_ASGNMNT_BOTH) \ 1212 VOTE_COMMAND("yes", VoteCommand_yes(request, caller), "Select yes in current vote", VC_ASGNMNT_CLIENTONLY) \ 1219 if (argc == 2 ||
argv(2) ==
"help")
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)); } } 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>"));
1234 #define VOTE_COMMAND(name, function, description, assignment) \ 1235 { if (Votecommand_check_assignment(caller, assignment)) { if (name == strtolower(argv(2))) { function; return; } } } 1240 string cvarname =
strcat(
"sv_vote_command_help_",
argv(2));
1242 wordwrap_sprint(caller,
cvar_string(cvarname), 1000);
1243 else if (
argv(2) !=
"")
1244 print_to(caller,
"No documentation exists for this vote");
1250 #define VOTE_COMMAND(name, function, description, assignment) \ 1251 { if (Votecommand_check_assignment(caller, assignment)) { if (name == strtolower(argv(1))) { function; return true; } } } void print_available_commands_to(entity caller)
float autocvar_sv_vote_majority_factor_of_voted
#define round_handler_IsActive()
float checkrules_suddendeathend
float autocvar_timelimit_overtime
string OriginalCallerName()
bool autocvar_sv_vote_no_stops_vote
entity GetIndexedEntity(int argc, float start_index)
void VoteCommand_yes(int request, entity caller)
const float VC_ASGNMNT_CLIENTONLY
void ReadyRestart_force(bool is_fake_round_start)
bool autocvar_sv_vote_change
string GetCommandPrefix(entity caller)
int autocvar_sv_vote_limit
void Nagger_VoteChanged()
float autocvar_g_ban_default_bantime
const int CMD_REQUEST_USAGE
int autocvar_sv_vote_master_playerlimit
float autocvar_sv_vote_majority_factor
bool autocvar_sv_vote_master_callable
float autocvar_sv_vote_stop
float CVAR_TYPEFLAG_EXISTS
float VoteCommand_checkinlist(string vote_command, string list)
ClientState CS(Client this)
void VoteCommand_call(int request, entity caller, int argc, string vote_command)
void Score_ClearAll()
Clear ALL scores (for ready-restart).
#define FOREACH_CLIENT(cond, body)
void Nagger_VoteCountChanged()
int checkrules_overtimesadded
void reset_map(bool dorespawn, bool is_fake_round_start)
bool autocvar_sv_vote_call
float checkrules_suddendeathwarning
float VerifyClientEntity(entity client, float must_be_real, float must_be_bots)
float VoteCommand_macro_command(entity caller, int argc, string vote_command)
void print_to(entity to, string input)
void VoteCommand_stop(int request, entity caller)
const float VOTE_SELECT_NULL
string autocvar_sv_vote_commands
bool autocvar_sv_vote_master
bool autocvar_sv_vote_singlecount
void VoteCommand_master(int request, entity caller, int argc, string vote_command)
#define FOREACH_ENTITY_ORDERED(cond, body)
float autocvar_timelimit_max
#define IS_REAL_CLIENT(v)
int VoteCommand_parse(entity caller, string vote_command, string vote_list, float startpos, int argc)
void Unfreeze(entity targ, bool reset_health)
string autocvar_sv_vote_master_commands
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
string VoteCommand_extractcommand(string input, float startpos, int argc)
bool Nagger_SendEntity(entity this, entity to, float sendflags)
bool autocvar_teamplay_lockonrestart
string vote_parsed_display
const float VOTE_SELECT_REJECT
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 accuracy_reset(entity e)
int autocvar_sv_timeout_number
float autocvar_g_ban_default_masksize
float vote_needed_overall
void VoteStop(entity stopper)
string autocvar_sv_vote_master_password
const int CMD_REQUEST_COMMAND
string vote_parsed_command
void round_handler_Reset(float next_think)
void GameLogEcho(string s)
#define IS_NOT_A_CLIENT(v)
was: (clienttype(v) == CLIENTTYPE_NOTACLIENT)
string GetCallerName(entity caller)
float VoteCommand_checknasty(string vote_command)
float MapInfo_CheckMap(string s)
bool Map_IsRecent(string m)
string vote_called_display
bool autocvar_sv_vote_gamestart
void Nagger_ReadyCounted()
#define GetClientErrorString(clienterror, original_input)
#define VOTE_COMMANDS(request, caller, arguments, command)
void ReadyRestart(bool forceWarmupEnd)
bool autocvar_sv_vote_override_mostrecent
bool shuffleteams_on_reset_map
void Inventory_clear(PlayerState this)
float Votecommand_check_assignment(entity caller, float assignment)
const float VOTE_SELECT_ACCEPT
bool sv_ready_restart_after_countdown
void VoteCommand_abstain(int request, entity caller)
#define INGAME_JOINED(it)
string ValidateMap(string validated_map, entity caller)
#define MUTATOR_CALLHOOK(id,...)
void VoteCommand_status(int request, entity caller)
void VoteCommand_no(int request, entity caller)
#define new_pure(class)
purely logical entities (.origin doesn't work)
string MapInfo_FixName(string s)
#define FOREACH_ENTITY_FLOAT_ORDERED(fld, match, body)
const float VOTE_SELECT_ABSTAIN
void VoteCommand(int request, entity caller, int argc, string vote_command)
bool intermission_running
float autocvar_sv_vote_wait
void VoteCount(float first_count)
bool autocvar_sv_eventlog
string vote_called_command
string VoteCommand_checkreplacements(string input)
const float RESTART_COUNTDOWN
void VoteCommand_macro_help(entity caller, int argc)
const float VC_ASGNMNT_SERVERONLY
float VoteCommand_checkargs(float startpos, int argc)
#define spectators_allowed
const float VC_ASGNMNT_BOTH
void ReadyRestart_think(entity this)
void VoteSpam(float notvoters, float mincount, string result)
float autocvar_timelimit_min
void player_powerups_remove_all(entity this)
float autocvar_sv_vote_timeout