]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/vote.qc
Merge branch 'master' into MaidenBeast/translation_updates
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / vote.qc
index e67b5378073820b7815b4c428d000aec986b0237..1690cf437b828c9f91538af05a4b982ab0827caf 100644 (file)
@@ -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);
-       WriteByte(MSG_ONE, selected);
-}
-
-void VoteDialog_Reset() {
-       WriteByte(MSG_ALL, SVC_TEMPENTITY);
-       WriteByte(MSG_ALL, TE_CSQC_VOTERESET);
-}
-
 float GameCommand_Vote(string s, entity e) {
+       local 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
@@ -161,8 +150,8 @@ float GameCommand_Vote(string s, entity e) {
                                        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);
+
+                                               local 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,17 +207,17 @@ 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.");
@@ -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 {
@@ -250,7 +243,7 @@ float GameCommand_Vote(string s, entity e) {
                        }
                } else if(argv(1) == "login") {
                        local string masterpwd;
-                       masterpwd = cvar_string("sv_vote_master_password");
+                       masterpwd = autocvar_sv_vote_master_password;
                        if(masterpwd != "") {
                                local float granted;
                                granted = (masterpwd == argv(2));
@@ -259,7 +252,7 @@ float GameCommand_Vote(string s, entity e) {
                                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,12 @@ 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 +283,12 @@ 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 +300,12 @@ 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 {
@@ -332,17 +322,17 @@ float GameCommand_Vote(string s, entity e) {
 
 void VoteHelp(entity e) {
        local string vmasterdis;
-       if(!cvar("sv_vote_master")) {
+       if(!autocvar_sv_vote_master) {
                vmasterdis = " ^1(disabled)";
        }
 
        local string vlogindis;
-       if("" == cvar_string("sv_vote_master_password")) {
+       if("" == autocvar_sv_vote_master_password) {
                vlogindis = " ^1(disabled)";
        }
 
        local string vcalldis;
-       if(!cvar("sv_vote_call")) {
+       if(!autocvar_sv_vote_call) {
                vcalldis = " ^1(disabled)";
        }
 
@@ -358,9 +348,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 +358,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 +374,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 +424,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;
        }
 
@@ -469,6 +459,8 @@ void VoteReset() {
        votecalled = FALSE;
        votecalledmaster = FALSE;
        votefinished = 0;
+       votecalledvote = string_null;
+       votecalledvote_display = string_null;
 }
 
 void VoteAccept() {
@@ -486,79 +478,70 @@ 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);
-       WriteByte(msg, vyes);
-       WriteByte(msg, vno);
-       WriteByte(msg, needed);
-}
-
 void VoteCount() {
        local float playercount;
        playercount = 0;
-       local float yescount;
-       yescount = 0;
-       local float nocount;
-       nocount = 0;
-       local float abstaincount;
-       abstaincount = 0;
+       vote_yescount = 0;
+       vote_nocount = 0;
+       vote_abstaincount = 0;
        local entity player;
        //same for real players
        local float realplayercount;
@@ -567,14 +550,16 @@ void VoteCount() {
        local 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 +576,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 +612,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 +643,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();
                }
        }
 }