From: Samual Date: Tue, 27 Dec 2011 19:24:47 +0000 (-0500) Subject: Finish up work on timeout system, now has much cleaner functionality (though it still... X-Git-Tag: xonotic-v0.6.0~188^2~28^2~56 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=29b55dfa978a11a987d1f4ea1ec586272115ddab;p=xonotic%2Fxonotic-data.pk3dir.git Finish up work on timeout system, now has much cleaner functionality (though it still works on the same fundamental slowmo hack) and will be easier to maintain --- diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 9ddcaabac..92e2687cb 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -1528,7 +1528,7 @@ void ClientConnect (void) } self.jointime = time; - self.allowedTimeouts = autocvar_sv_timeout_number; + self.allowed_timeouts = autocvar_sv_timeout_number; if(clienttype(self) == CLIENTTYPE_REAL) { @@ -2603,7 +2603,7 @@ void PlayerPreThink (void) } //don't allow the player to turn around while game is paused! - if(timeoutStatus == 2) { + if(timeout_status == TIMEOUT_ACTIVE) { // FIXME turn this into CSQC stuff self.v_angle = self.lastV_angle; self.angles = self.lastV_angle; diff --git a/qcsrc/server/cl_impulse.qc b/qcsrc/server/cl_impulse.qc index 9e662bb84..524e796af 100644 --- a/qcsrc/server/cl_impulse.qc +++ b/qcsrc/server/cl_impulse.qc @@ -46,7 +46,7 @@ void ImpulseCommands (void) return; self.impulse = 0; - if (timeoutStatus == 2) //don't allow any impulses while the game is paused + if (timeout_status == TIMEOUT_ACTIVE) //don't allow any impulses while the game is paused return; if(CheatImpulse(imp)) diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index 5b369c27c..f67ac1be9 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -962,7 +962,7 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f flood = 1; } - if (timeoutStatus == 2) //when game is paused, no flood protection + if (timeout_status == TIMEOUT_ACTIVE) // when game is paused, no flood protection source.flood_field = flood = 0; } diff --git a/qcsrc/server/cl_weaponsystem.qc b/qcsrc/server/cl_weaponsystem.qc index 2062f446f..e049ef858 100644 --- a/qcsrc/server/cl_weaponsystem.qc +++ b/qcsrc/server/cl_weaponsystem.qc @@ -913,7 +913,7 @@ float weapon_prepareattack_check(float secondary, float attacktime) return FALSE; } - if (timeoutStatus == 2) //don't allow the player to shoot while game is paused + if (timeout_status == TIMEOUT_ACTIVE) //don't allow the player to shoot while game is paused return FALSE; // do not even think about shooting if switching diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc index f218a4e67..521db1a0a 100644 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@ -5,7 +5,7 @@ float SV_ParseClientCommand_floodcheck() { - if (timeoutStatus != 2) // if the game is not paused... but wait, doesn't that mean it could be dos'd by pausing it? eh? (old code) + if not(timeout_status) // not while paused { if(time <= (self.cmd_floodtime + autocvar_sv_clientcommand_antispam_time)) { @@ -192,7 +192,7 @@ void ClientCommand_ready(float request) // todo: anti-spam for toggling readynes } // cannot reset the game while a timeout is active! - if(!timeoutStatus) + if not(timeout_status) ReadyCount(); } else { sprint(self, "^1Game has already been restarted\n"); diff --git a/qcsrc/server/command/common.qc b/qcsrc/server/command/common.qc index 2e4034020..c333910ec 100644 --- a/qcsrc/server/command/common.qc +++ b/qcsrc/server/command/common.qc @@ -104,6 +104,99 @@ void print_to(entity to, string input) // Supporting functions for common commands // ========================================== +// used by CommonCommand_timeout() and CommonCommand_timein() to handle game pausing and messaging and such. +void timeout_handler_reset() +{ + entity tmp_player; + + timeout_caller = world; + timeout_time = 0; + timeout_leadtime = 0; + + FOR_EACH_REALPLAYER(tmp_player) + Send_CSQC_Centerprint_Generic_Expire(tmp_player, CPID_TIMEOUT_COUNTDOWN); + + remove(self); +} + +void timeout_handler_think() +{ + entity tmp_player; + + switch(timeout_status) + { + case TIMEOUT_ACTIVE: + { + if(timeout_time > 0) // countdown is still going + { + FOR_EACH_REALPLAYER(tmp_player) + Send_CSQC_Centerprint_Generic(tmp_player, CPID_TIMEOUT_COUNTDOWN, "Timeout ends in %d seconds!", 1, timeout_time); + + if(timeout_time == autocvar_sv_timeout_resumetime) // play a warning sound when only seconds are left + Announce("prepareforbattle"); + + self.nextthink = time + TIMEOUT_SLOWMO_VALUE; // think again in one second + timeout_time -= 1; // decrease the time counter + } + else // time to end the timeout + { + timeout_status = TIMEOUT_INACTIVE; + + // reset the slowmo value back to normal + cvar_set("slowmo", ftos(orig_slowmo)); + + // unlock the view for players so they can move around again + FOR_EACH_REALPLAYER(tmp_player) + tmp_player.fixangle = FALSE; + + timeout_handler_reset(); + } + + return; + } + + case TIMEOUT_LEADTIME: + { + if (timeout_leadtime > 0) // countdown is still going + { + // centerprint the information to every player + FOR_EACH_REALPLAYER(tmp_player) + Send_CSQC_Centerprint_Generic(tmp_player, CPID_TIMEOUT_COUNTDOWN, "Timeout begins in %d seconds!", 1, timeout_leadtime); + + self.nextthink = time + 1; // think again in one second + timeout_leadtime -= 1; // decrease the time counter + } + else // time to begin the timeout + { + timeout_status = TIMEOUT_ACTIVE; + + // set the slowmo value to the timeout default slowmo value + cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE)); + + // reset all the flood variables + FOR_EACH_CLIENT(tmp_player) + tmp_player.nickspamcount = tmp_player.nickspamtime = tmp_player.floodcontrol_chat = + tmp_player.floodcontrol_chatteam = tmp_player.floodcontrol_chattell = + tmp_player.floodcontrol_voice = tmp_player.floodcontrol_voiceteam = 0; + + // copy .v_angle to .lastV_angle for every player in order to fix their view during pause (see PlayerPreThink) + FOR_EACH_REALPLAYER(tmp_player) + tmp_player.lastV_angle = tmp_player.v_angle; + + self.nextthink = time; // think again next frame to handle it under TIMEOUT_ACTIVE code + } + } + + + case TIMEOUT_INACTIVE: + default: + { + timeout_handler_reset(); + return; + } + } +} + // =================================================== @@ -399,7 +492,7 @@ void CommonCommand_timein(float request, entity caller) case TIMEOUT_ACTIVE: { timeout_time = autocvar_sv_timeout_resumetime; - timeoutHandler.nextthink = time; // timeout_handler has to take care of it immediately + timeout_handler.nextthink = time; // timeout_handler has to take care of it immediately bprint(strcat("^1Attention: ^7", caller.netname, " resumed the game! Prepare for battle!\n")); return; } @@ -443,7 +536,7 @@ void CommonCommand_timeout(float request, entity caller) // DEAR GOD THIS COMMAN { if(caller) { caller.allowed_timeouts -= 1; } - bprint(GetCallerName(caller), " ^7called a timeout", (caller ? strcat(" (", ftos(caller.allowedTimeouts), " timeouts left)") : string_null), "!\n"); // write a bprint who started the timeout (and how many they have left) + bprint(GetCallerName(caller), " ^7called a timeout", (caller ? strcat(" (", ftos(caller.allowed_timeouts), " timeouts left)") : string_null), "!\n"); // write a bprint who started the timeout (and how many they have left) timeout_status = TIMEOUT_LEADTIME; timeout_caller = caller; diff --git a/qcsrc/server/command/vote.qc b/qcsrc/server/command/vote.qc index 1c7b17022..bf636a387 100644 --- a/qcsrc/server/command/vote.qc +++ b/qcsrc/server/command/vote.qc @@ -367,7 +367,7 @@ void ReadyRestart_force() } // after a restart every players number of allowed timeouts gets reset, too - if(autocvar_sv_timeout) { FOR_EACH_REALPLAYER(tmp_player) { tmp_player.allowedTimeouts = autocvar_sv_timeout_number; } } + if(autocvar_sv_timeout) { FOR_EACH_REALPLAYER(tmp_player) { tmp_player.allowed_timeouts = autocvar_sv_timeout_number; } } //reset map immediately if this cvar is not set if not(autocvar_sv_ready_restart_after_countdown) { reset_map(TRUE); } @@ -625,7 +625,7 @@ void VoteCommand_call(float request, entity caller, float argc, string vote_comm if not(autocvar_sv_vote_call || !caller) { print_to(caller, "^1Vote calling is not allowed."); } else if(vote_called) { print_to(caller, "^1There is already a vote called."); } else if(!spectators_allowed && (caller && (caller.classname != "player"))) { print_to(caller, "^1Only players can call a vote."); } - else if(timeoutStatus) { print_to(caller, "^1You can not call a vote while a timeout is active."); } + else if(timeout_status) { print_to(caller, "^1You can not call a vote while a timeout is active."); } else if(caller && (time < caller.vote_waittime)) { print_to(caller, strcat("^1You have to wait ^2", ftos(ceil(caller.vote_waittime - time)), "^1 seconds before you can again call a vote.")); } else if not(VoteCommand_checknasty(vote_command)) { print_to(caller, "^1Syntax error in command, see 'vhelp' for more info."); } else if not(VoteCommand_parse(caller, vote_command, autocvar_sv_vote_commands, 2, argc)) { print_to(caller, "^1This command is not acceptable, see 'vhelp' for more info."); } @@ -719,6 +719,7 @@ void VoteCommand_master(float request, entity caller, float argc, string vote_co { if not(autocvar_sv_vote_master_callable) { print_to(caller, "^1Vote to become vote master is not allowed."); } else if(vote_called) { print_to(caller, "^1There is already a vote called."); } + else if(timeout_status) { print_to(caller, "^1You can not call a vote while a timeout is active."); } else // everything went okay, continue with creating vote { diff --git a/qcsrc/server/g_hook.qc b/qcsrc/server/g_hook.qc index 84ea02101..370f2fb98 100644 --- a/qcsrc/server/g_hook.qc +++ b/qcsrc/server/g_hook.qc @@ -382,7 +382,7 @@ void FireGrapplingHook (void) void GrapplingHookFrame() { - if(g_grappling_hook && timeoutStatus != 2 && self.weapon != WEP_HOOK) + if(g_grappling_hook && timeout_status != TIMEOUT_ACTIVE && self.weapon != WEP_HOOK) { // offhand hook controls if(self.BUTTON_HOOK) diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 41288a808..80a34a0e6 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -95,83 +95,6 @@ void fteqcc_testbugs() world.cnt = 0; } -/** - * Takes care of pausing and unpausing the game. - * Centerprints the information about an upcoming or active timeout to all active - * players. Also plays reminder sounds. - */ -void timeoutHandler_Think() { - entity plr; - if (timeoutStatus == 1) { - if (remainingLeadTime > 0) { - //centerprint the information to every player - FOR_EACH_REALCLIENT(plr) { - if(plr.classname == "player") { - Send_CSQC_Centerprint_Generic(plr, CPID_TIMEOUT_COUNTDOWN, "Timeout begins in %d seconds!", 1, remainingLeadTime); - } - } - remainingLeadTime -= 1; - //think again in 1 second: - self.nextthink = time + 1; - } - else { - //now pause the game: - timeoutStatus = 2; - //reset all the flood variables - FOR_EACH_CLIENT(plr) { - plr.nickspamcount = plr.nickspamtime = plr.floodcontrol_chat = plr.floodcontrol_chatteam = plr.floodcontrol_chattell = plr.floodcontrol_voice = plr.floodcontrol_voiceteam = 0; - } - cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE)); - //copy .v_angle to .lastV_angle for every player in order to fix their view during pause (see PlayerPreThink) - FOR_EACH_REALPLAYER(plr) { - plr.lastV_angle = plr.v_angle; - } - self.nextthink = time; - } - } - else if (timeoutStatus == 2) { - if (remainingTimeoutTime > 0) { - FOR_EACH_REALCLIENT(plr) { - if(plr.classname == "player") { - Send_CSQC_Centerprint_Generic(plr, CPID_TIMEOUT_COUNTDOWN, "Timeout ends in %d seconds!", 1, remainingTimeoutTime); - } - } - if(remainingTimeoutTime == autocvar_sv_timeout_resumetime) { //play a warning sound when only seconds are left - Announce("prepareforbattle"); - } - remainingTimeoutTime -= 1; - self.nextthink = time + TIMEOUT_SLOWMO_VALUE; - } - else { - //unpause the game again - remainingTimeoutTime = timeoutStatus = 0; - cvar_set("slowmo", ftos(orig_slowmo)); - //and unlock the fixed view again once there is no timeout active anymore - FOR_EACH_REALPLAYER(plr) { - plr.fixangle = FALSE; - } - //get rid of the countdown message - FOR_EACH_REALCLIENT(plr) { - if(plr.classname == "player") { - Send_CSQC_Centerprint_Generic_Expire(plr, CPID_TIMEOUT_COUNTDOWN); - } - } - remove(self); - return; - } - - } - else if (timeoutStatus == 0) { //if a player called the resumegame command (which set timeoutStatus to 0 already) - FOR_EACH_REALCLIENT(plr) { - if(plr.classname == "player") { - Send_CSQC_Centerprint_Generic_Expire(plr, CPID_TIMEOUT_COUNTDOWN); - } - } - remove(self); - return; - } -} - void GotoFirstMap() { float n; diff --git a/qcsrc/server/sv_main.qc b/qcsrc/server/sv_main.qc index 7ec4b49d6..d9a0ad460 100644 --- a/qcsrc/server/sv_main.qc +++ b/qcsrc/server/sv_main.qc @@ -196,7 +196,7 @@ void StartFrame (void) if(sys_frametime <= 0) sys_frametime = 1.0 / 60.0; // somewhat safe fallback - if (timeoutStatus == 1) // just before the timeout (when timeoutStatus will be 2) + if (timeout_status == TIMEOUT_LEADTIME) // just before the timeout (when timeout_status will be TIMEOUT_ACTIVE) orig_slowmo = autocvar_slowmo; // slowmo will be restored after the timeout skill = autocvar_skill;