X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fvote.qc;h=3043ceaab510a3e4bb882c69e71984f245174f27;hb=84c0acb4b206a2b4892bd976b19c98d411953dc2;hp=338d98476b38b2a685cfd71ce2b396d827e204b5;hpb=4bef2cd934377b15182a705bfa3639967e331678;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/vote.qc b/qcsrc/server/vote.qc index 338d98476..3043ceaab 100644 --- a/qcsrc/server/vote.qc +++ b/qcsrc/server/vote.qc @@ -55,7 +55,7 @@ entity GetKickVoteVictim(string vote, string cmd, entity caller) GetKickVoteVictim_newcommand = strcat(argv(0), " # ", ftos(num_for_edict(e))); if(argv(0) == "kickban") { - GetKickVoteVictim_newcommand = strcat(GetKickVoteVictim_newcommand, " ", cvar_string("g_ban_default_bantime"), " ", cvar_string("g_ban_default_masksize"), " ", reason); + GetKickVoteVictim_newcommand = strcat(GetKickVoteVictim_newcommand, " ", ftos(autocvar_g_ban_default_bantime), " ", ftos(autocvar_g_ban_default_masksize), " ", reason); } else if(argv(0) == "kick") { @@ -116,19 +116,8 @@ float RemapVote(string vote, string cmd, entity e) return TRUE; } -void VoteDialog_UpdateHighlight(float selected) { - WriteByte(MSG_ONE, SVC_TEMPENTITY); - WriteByte(MSG_ONE, TE_CSQC_VOTE); - WriteByte(MSG_ONE, 1); - WriteShort(MSG_ONE, selected); -} - -void VoteDialog_Reset() { - WriteByte(MSG_ALL, SVC_TEMPENTITY); - WriteByte(MSG_ALL, TE_CSQC_VOTERESET); -} - float GameCommand_Vote(string s, entity e) { + float playercount; float argc; argc = tokenize_console(s); if(argv(0) == "help") { @@ -146,8 +135,8 @@ float GameCommand_Vote(string s, entity e) { print_to(e, "^1No vote called."); } } else if(argv(1) == "call") { - if(!e || cvar("sv_vote_call")) { - if(cvar("sv_vote_nospectators") && e && e.classname != "player") { + if(!e || autocvar_sv_vote_call) { + if(autocvar_sv_vote_nospectators && e && e.classname != "player") { print_to(e, "^1Error: Only players can call a vote."); // TODO invent a cvar name for allowing votes by spectators during warmup anyway } else if(timeoutStatus) { //don't allow a vote call during a timeout @@ -156,13 +145,13 @@ float GameCommand_Vote(string s, entity e) { else if(votecalled) { print_to(e, "^1There is already a vote called."); } else { - local string vote; + string vote; vote = VoteParse(s, argc); if(vote == "") { print_to(e, "^1Your vote is empty. See 'vhelp' for more info."); } else if(e - && time < e.vote_next) { - print_to(e, strcat("^1You have to wait ^2", ftos(ceil(e.vote_next - time)), "^1 seconds before you can again call a vote.")); + && time < e.vote_next) { + print_to(e, strcat("^1You have to wait ^2", ftos(ceil(e.vote_next - time)), "^1 seconds before you can again call a vote.")); } else if(VoteCheckNasty(vote)) { print_to(e, "Syntax error in command. See 'vhelp' for more info."); } else if(RemapVote(vote, "vcall", e)) { @@ -170,19 +159,26 @@ float GameCommand_Vote(string s, entity e) { votecalledvote_display = strzone(RemapVote_display); votecalled = TRUE; votecalledmaster = FALSE; - votefinished = time + cvar("sv_vote_timeout"); + votefinished = time + autocvar_sv_vote_timeout; votecaller = e; // remember who called the vote if(e) { e.vote_vote = 1; // of course you vote yes - e.vote_next = time + cvar("sv_vote_wait"); + e.vote_next = time + autocvar_sv_vote_wait; } bprint("\{1}^2* ^3", VoteNetname(votecaller), "^2 calls a vote for ", votecalledvote_display, "\n"); - if(cvar("sv_eventlog")) + if(autocvar_sv_eventlog) GameLogEcho(strcat(":vote:vcall:", ftos(votecaller.playerid), ":", votecalledvote_display)); - VoteCount(); // needed if you are the only one Nagger_VoteChanged(); + VoteCount(); // needed if you are the only one msg_entity = e; - VoteDialog_UpdateHighlight(1); + + entity player; + FOR_EACH_REALCLIENT(player) + { + ++playercount; + } + if(playercount > 1) // don't announce a "vote now" sound if player is alone + Announce("votecall"); } else { print_to(e, "^1This vote is not ok. See 'vhelp' for more info."); } @@ -194,19 +190,16 @@ float GameCommand_Vote(string s, entity e) { if(!votecalled) { print_to(e, "^1No vote called."); } else if(e == votecaller) { // the votecaller can stop a vote - VoteDialog_Reset(); VoteStop(e); } else if(!e) { // server admin / console can too - VoteDialog_Reset(); VoteStop(e); } else if(e.vote_master) { // masters can too - VoteDialog_Reset(); VoteStop(e); } else { print_to(e, "^1You are not allowed to stop that Vote."); } } else if(argv(1) == "master") { - if(cvar("sv_vote_master")) { + if(autocvar_sv_vote_master) { if(votecalled) { print_to(e, "^1There is already a vote called."); } else { @@ -214,24 +207,24 @@ float GameCommand_Vote(string s, entity e) { votecalledmaster = TRUE; votecalledvote = strzone("XXX"); votecalledvote_display = strzone("^3master"); - votefinished = time + cvar("sv_vote_timeout"); + votefinished = time + autocvar_sv_vote_timeout; votecaller = e; // remember who called the vote if(e) { e.vote_vote = 1; // of course you vote yes - e.vote_next = time + cvar("sv_vote_wait"); + e.vote_next = time + autocvar_sv_vote_wait; } bprint("\{1}^2* ^3", VoteNetname(votecaller), "^2 calls a vote to become ^3master^2.\n"); - if(cvar("sv_eventlog")) + if(autocvar_sv_eventlog) GameLogEcho(strcat(":vote:vcall:", ftos(votecaller.playerid), ":", votecalledvote_display)); - VoteCount(); // needed if you are the only one Nagger_VoteChanged(); + VoteCount(); // needed if you are the only one } } else { print_to(e, "^1Vote to become master is NOT allowed."); } } else if(argv(1) == "do") { if(!e || e.vote_master) { - local string dovote; + string dovote; dovote = VoteParse(s, argc); if(dovote == "") { print_to(e, "^1Your command was empty. See 'vhelp' for more info."); @@ -239,7 +232,7 @@ float GameCommand_Vote(string s, entity e) { print_to(e, "Syntax error in command. See 'vhelp' for more info."); } else if(RemapVote(dovote, "vdo", e)) { // strcat seems to be necessary bprint("\{1}^2* ^3", VoteNetname(e), "^2 used their ^3master^2 status to do \"^2", RemapVote_display, "^2\".\n"); - if(cvar("sv_eventlog")) + if(autocvar_sv_eventlog) GameLogEcho(strcat(":vote:vdo:", ftos(e.playerid), ":", RemapVote_display)); localcmd(strcat(RemapVote_vote, "\n")); } else { @@ -249,17 +242,17 @@ float GameCommand_Vote(string s, entity e) { print_to(e, "^1You are NOT a master. You might need to login or vote to become master first. See 'vhelp' for more info."); } } else if(argv(1) == "login") { - local string masterpwd; - masterpwd = cvar_string("sv_vote_master_password"); + string masterpwd; + masterpwd = autocvar_sv_vote_master_password; if(masterpwd != "") { - local float granted; + float granted; granted = (masterpwd == argv(2)); if (e) e.vote_master = granted; if(granted) { print("Accepted master login from ", VoteNetname(e), "\n"); bprint("\{1}^2* ^3", VoteNetname(e), "^2 logged in as ^3master^2\n"); - if(cvar("sv_eventlog")) + if(autocvar_sv_eventlog) GameLogEcho(strcat(":vote:vlogin:", ftos(e.playerid))); } else @@ -273,13 +266,11 @@ float GameCommand_Vote(string s, entity e) { } else if (!e) { print_to(e, "^1You can't vote from the server console."); } else if(e.vote_vote == 0 - || cvar("sv_vote_change")) { + || autocvar_sv_vote_change) { msg_entity = e; - VoteDialog_UpdateHighlight(1); print_to(e, "^1You accepted the vote."); e.vote_vote = 1; - centerprint_expire(e, CENTERPRIO_VOTE); - if(!cvar("sv_vote_singlecount")) { + if(!autocvar_sv_vote_singlecount) { VoteCount(); } } else { @@ -291,13 +282,11 @@ float GameCommand_Vote(string s, entity e) { } else if (!e) { print_to(e, "^1You can't vote from the server console."); } else if(e.vote_vote == 0 - || cvar("sv_vote_change")) { + || autocvar_sv_vote_change) { msg_entity = e; - VoteDialog_UpdateHighlight(2); print_to(e, "^1You rejected the vote."); e.vote_vote = -1; - centerprint_expire(e, CENTERPRIO_VOTE); - if(!cvar("sv_vote_singlecount")) { + if(!autocvar_sv_vote_singlecount) { VoteCount(); } } else { @@ -309,13 +298,11 @@ float GameCommand_Vote(string s, entity e) { } else if (!e) { print_to(e, "^1You can't vote from the server console."); } else if(e.vote_vote == 0 - || cvar("sv_vote_change")) { + || autocvar_sv_vote_change) { msg_entity = e; - VoteDialog_UpdateHighlight(3); print_to(e, "^1You abstained from your vote."); e.vote_vote = -2; - centerprint_expire(e, CENTERPRIO_VOTE); - if(!cvar("sv_vote_singlecount")) { + if(!autocvar_sv_vote_singlecount) { VoteCount(); } } else { @@ -331,18 +318,18 @@ float GameCommand_Vote(string s, entity e) { } void VoteHelp(entity e) { - local string vmasterdis; - if(!cvar("sv_vote_master")) { + string vmasterdis; + if(!autocvar_sv_vote_master) { vmasterdis = " ^1(disabled)"; } - local string vlogindis; - if("" == cvar_string("sv_vote_master_password")) { + string vlogindis; + if("" == autocvar_sv_vote_master_password) { vlogindis = " ^1(disabled)"; } - local string vcalldis; - if(!cvar("sv_vote_call")) { + string vcalldis; + if(!autocvar_sv_vote_call) { vcalldis = " ^1(disabled)"; } @@ -358,9 +345,9 @@ void VoteHelp(entity e) { print_to(e, "^7\"^2yes^7\", \"^2no^7\", \"^2abstain^7\" and \"^2dontcare^7\" to make your vote."); print_to(e, "^7If enough of the players vote yes the vote is accepted."); print_to(e, "^7If enough of the players vote no the vote is rejected."); - print_to(e, strcat("^7If neither the vote will timeout after ", cvar_string("sv_vote_timeout"), "^7 seconds.")); + print_to(e, strcat("^7If neither the vote will timeout after ", ftos(autocvar_sv_vote_timeout), "^7 seconds.")); print_to(e, "^7You can call a vote for or execute these commands:"); - print_to(e, strcat("^3", cvar_string("sv_vote_commands"), "^7 and maybe further ^3arguments^7")); + print_to(e, strcat("^3", autocvar_sv_vote_commands, "^7 and maybe further ^3arguments^7")); } string VoteNetname(entity e) @@ -368,10 +355,10 @@ string VoteNetname(entity e) if(e) { return e.netname; } else { - if(cvar_string("sv_adminnick") != "") { - return cvar_string("sv_adminnick"); + if(autocvar_sv_adminnick != "") { + return autocvar_sv_adminnick; } else { - return cvar_string("hostname"); + return autocvar_hostname; } } } @@ -384,7 +371,7 @@ string ValidateMap(string m, entity e) print_to(e, "This map is not available on this server."); return string_null; } - if(!cvar("sv_vote_override_mostrecent")) + if(!autocvar_sv_vote_override_mostrecent) if(Map_IsRecent(m)) { print_to(e, "This server does not allow for recent maps to be played again. Please be patient for some rounds."); @@ -434,17 +421,17 @@ float VoteCommandInList(string votecommand, string list) } float VoteAllowed(string votecommand, string cmd) { - if(VoteCommandInList(votecommand, cvar_string("sv_vote_commands"))) + if(VoteCommandInList(votecommand, autocvar_sv_vote_commands)) return TRUE; if(cmd == "vdo") { - if(VoteCommandInList(votecommand, cvar_string("sv_vote_master_commands"))) + if(VoteCommandInList(votecommand, autocvar_sv_vote_master_commands)) return TRUE; } else { - if(VoteCommandInList(votecommand, cvar_string("sv_vote_only_commands"))) + if(VoteCommandInList(votecommand, autocvar_sv_vote_only_commands)) return TRUE; } @@ -452,12 +439,11 @@ float VoteAllowed(string votecommand, string cmd) { } void VoteReset() { - local entity player; + entity player; FOR_EACH_CLIENT(player) { player.vote_vote = 0; - centerprint_expire(player, CENTERPRIO_VOTE); } if(votecalled) @@ -469,6 +455,10 @@ void VoteReset() { votecalled = FALSE; votecalledmaster = FALSE; votefinished = 0; + votecalledvote = string_null; + votecalledvote_display = string_null; + + Nagger_VoteChanged(); } void VoteAccept() { @@ -486,95 +476,88 @@ void VoteAccept() { // no wait for next vote } VoteReset(); + Announce("voteaccept"); } void VoteReject() { bprint("\{1}^2* ^3", VoteNetname(votecaller), "^2's vote for ", votecalledvote_display, "^2 was rejected\n"); VoteReset(); + Announce("votefail"); } void VoteTimeout() { bprint("\{1}^2* ^3", VoteNetname(votecaller), "^2's vote for ", votecalledvote_display, "^2 timed out\n"); VoteReset(); + Announce("votefail"); } void VoteStop(entity stopper) { bprint("\{1}^2* ^3", VoteNetname(stopper), "^2 stopped ^3", VoteNetname(votecaller), "^2's vote\n"); - if(cvar("sv_eventlog")) + if(autocvar_sv_eventlog) GameLogEcho(strcat(":vote:vstop:", ftos(stopper.playerid))); if(stopper == votecaller) { // no wait for next vote so you can correct your vote if(votecaller) { - votecaller.vote_next = time + cvar("sv_vote_stop"); + votecaller.vote_next = time + autocvar_sv_vote_stop; } } VoteReset(); } -void VoteSpam(float yescount, float nocount, float abstaincount, float notvoters, float mincount, string result) +void VoteSpam(float notvoters, float mincount, string result) { string s; if(mincount >= 0) { - s = strcat("\{1}^2* vote results: ^1", ftos(yescount), "^2:^1"); - s = strcat(s, ftos(nocount), "^2 (^1"); + s = strcat("\{1}^2* vote results: ^1", ftos(vote_yescount), "^2:^1"); + s = strcat(s, ftos(vote_nocount), "^2 (^1"); s = strcat(s, ftos(mincount), "^2 needed), ^1"); - s = strcat(s, ftos(abstaincount), "^2 didn't care, ^1"); + s = strcat(s, ftos(vote_abstaincount), "^2 didn't care, ^1"); s = strcat(s, ftos(notvoters), "^2 didn't vote\n"); } else { - s = strcat("\{1}^2* vote results: ^1", ftos(yescount), "^2:^1"); - s = strcat(s, ftos(nocount), "^2, ^1"); - s = strcat(s, ftos(abstaincount), "^2 didn't care, ^1"); + s = strcat("\{1}^2* vote results: ^1", ftos(vote_yescount), "^2:^1"); + s = strcat(s, ftos(vote_nocount), "^2, ^1"); + s = strcat(s, ftos(vote_abstaincount), "^2 didn't care, ^1"); s = strcat(s, ftos(notvoters), "^2 didn't have to vote\n"); } bprint(s); - if(cvar("sv_eventlog")) + if(autocvar_sv_eventlog) { - s = strcat(":vote:v", result, ":", ftos(yescount)); - s = strcat(s, ":", ftos(nocount)); - s = strcat(s, ":", ftos(abstaincount)); + s = strcat(":vote:v", result, ":", ftos(vote_yescount)); + s = strcat(s, ":", ftos(vote_nocount)); + s = strcat(s, ":", ftos(vote_abstaincount)); s = strcat(s, ":", ftos(notvoters)); s = strcat(s, ":", ftos(mincount)); GameLogEcho(s); } } -void VoteDialog_Update(float msg, float vyes, float vno, float needed) { - WriteByte(msg, SVC_TEMPENTITY); - WriteByte(msg, TE_CSQC_VOTE); - WriteByte(msg, 0); - WriteShort(msg, vyes); - WriteShort(msg, vno); - WriteShort(msg, needed); -} - void VoteCount() { - local float playercount; + float playercount; playercount = 0; - local float yescount; - yescount = 0; - local float nocount; - nocount = 0; - local float abstaincount; - abstaincount = 0; - local entity player; + vote_yescount = 0; + vote_nocount = 0; + vote_abstaincount = 0; + entity player; //same for real players - local float realplayercount; - local float realplayeryescount; - local float realplayernocount; - local float realplayerabstaincount; + float realplayercount; + float realplayeryescount; + float realplayernocount; + float realplayerabstaincount; realplayercount = realplayernocount = realplayerabstaincount = realplayeryescount = 0; + Nagger_VoteCountChanged(); + FOR_EACH_REALCLIENT(player) { if(player.vote_vote == -1) { - ++nocount; + ++vote_nocount; } else if(player.vote_vote == 1) { - ++yescount; + ++vote_yescount; } else if(player.vote_vote == -2) { - ++abstaincount; + ++vote_abstaincount; } ++playercount; //do the same for real players @@ -591,20 +574,27 @@ void VoteCount() { } //in tournament mode, if we have at least one player then don't make the vote dependent on spectators (so specs don't have to press F1) - if(cvar("sv_vote_nospectators")) + if(autocvar_sv_vote_nospectators) if(realplayercount > 0) { - yescount = realplayeryescount; - nocount = realplayernocount; - abstaincount = realplayerabstaincount; + vote_yescount = realplayeryescount; + vote_nocount = realplayernocount; + vote_abstaincount = realplayerabstaincount; playercount = realplayercount; } float votefactor, simplevotefactor; - votefactor = bound(0.5, cvar("sv_vote_majority_factor"), 0.999); - simplevotefactor = cvar("sv_vote_simple_majority_factor"); - float needed; - needed = floor((playercount - abstaincount) * max(votefactor, simplevotefactor)) + 1; - VoteDialog_Update(MSG_ALL, yescount, nocount, needed); + votefactor = bound(0.5, autocvar_sv_vote_majority_factor, 0.999); + simplevotefactor = autocvar_sv_vote_simple_majority_factor; + + // FIXME this number is a guess + vote_needed_absolute = floor((playercount - vote_abstaincount) * votefactor) + 1; + if(simplevotefactor) + { + simplevotefactor = bound(votefactor, simplevotefactor, 0.999); + vote_needed_simple = floor((vote_yescount + vote_nocount) * simplevotefactor) + 1; + } + else + vote_needed_simple = 0; if(votecalledmaster && playercount == 1) { @@ -620,31 +610,28 @@ void VoteCount() { } VoteReset(); } else { - if(yescount > (playercount - abstaincount) * votefactor) + if(vote_yescount >= vote_needed_absolute) { - VoteSpam(yescount, nocount, abstaincount, playercount - yescount - nocount - abstaincount, -1, "yes"); + VoteSpam(playercount - vote_yescount - vote_nocount - vote_abstaincount, -1, "yes"); VoteAccept(); - VoteDialog_Reset(); } - else if(nocount >= (playercount - abstaincount) * (1 - votefactor)) // that means, yescount cannot reach minyes any more + else if(vote_nocount > playercount - vote_abstaincount - vote_needed_absolute) // that means, vote_yescount cannot reach vote_needed_absolute any more { - VoteSpam(yescount, nocount, abstaincount, playercount - yescount - nocount - abstaincount, -1, "no"); + VoteSpam(playercount - vote_yescount - vote_nocount - vote_abstaincount, -1, "no"); VoteReject(); - VoteDialog_Reset(); } else if(time > votefinished) { if(simplevotefactor) { string result; - simplevotefactor = bound(votefactor, simplevotefactor, 0.999); - if(yescount > (yescount + nocount) * simplevotefactor) + if(vote_yescount >= vote_needed_simple) result = "yes"; - else if(yescount + nocount > 0) + else if(vote_yescount + vote_nocount > 0) result = "no"; else result = "timeout"; - VoteSpam(yescount, nocount, abstaincount, playercount - yescount - nocount - abstaincount, floor(min((playercount - abstaincount) * votefactor, (yescount + nocount) * simplevotefactor)) + 1, result); + VoteSpam(playercount - vote_yescount - vote_nocount - vote_abstaincount, min(vote_needed_absolute, vote_needed_simple), result); if(result == "yes") VoteAccept(); else if(result == "no") @@ -654,10 +641,9 @@ void VoteCount() { } else { - VoteSpam(yescount, nocount, abstaincount, playercount - yescount - nocount - abstaincount, floor((playercount - abstaincount) * votefactor) + 1, "timeout"); + VoteSpam(playercount - vote_yescount - vote_nocount - vote_abstaincount, vote_needed_absolute, "timeout"); VoteTimeout(); } - VoteDialog_Reset(); } } }