]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'z411/new_timer' into 'master'
authorterencehill <piuntn@gmail.com>
Sun, 6 Mar 2022 01:09:13 +0000 (01:09 +0000)
committerterencehill <piuntn@gmail.com>
Sun, 6 Mar 2022 01:09:13 +0000 (01:09 +0000)
New timer with secondary round timer and sub text indicating game phase

Closes #2636

See merge request xonotic/xonotic-data.pk3dir!978

20 files changed:
_hud_common.cfg
commands.cfg
hud_luma.cfg
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_minimal_xhair.cfg
hud_luminos_old.cfg
hud_nexuiz.cfg
qcsrc/client/hud/panel/timer.qc
qcsrc/client/hud/panel/timer.qh
qcsrc/client/view.qc
qcsrc/client/view.qh
qcsrc/common/stats.qh
qcsrc/menu/xonotic/dialog_hudpanel_timer.qc
qcsrc/server/command/common.qh
qcsrc/server/command/vote.qc
qcsrc/server/intermission.qc
qcsrc/server/round_handler.qc
qcsrc/server/world.qc
qcsrc/server/world.qh

index a97800ba15b33d8ed7c425f5ad60d30c83a0da4e..3aaa8ae6df5e74d0110106955cce979c0efb3d19 100644 (file)
@@ -93,6 +93,7 @@ seta hud_panel_healtharmor_progressbar_gfx_lowhealth 40 "health progressbar blin
 seta hud_panel_healtharmor_hide_ondeath 0 "hide this panel when dead"
 
 seta hud_panel_timer_increment "0" "show elapsed time instead of remaining time"
+seta hud_panel_timer_secondary "1" "secondary timer (0 = hide, 1 = show, 2 = show swapped)"
 seta hud_panel_timer_unbound "0" "show seconds leading up to the start of the match"
 
 seta hud_panel_engineinfo_framecounter_exponentialmovingaverage 1 "use an averaging method for calculating fps instead of counting frametime like engine does"
index a6162badf4037b12ecdc6a15bd90b55b8e3e44d2..e9dfc0e0232ff9b6a11ac3e36fe6fb81f324076d 100644 (file)
@@ -238,7 +238,8 @@ alias unlockteams          "qc_cmd_sv     unlockteams          ${* ?}" // Enable
 alias warp                 "qc_cmd_sv     warp                 ${* ?}" // Choose different level in campaign
 
 // other aliases for server commands
-alias endmatch "timelimit -1"
+set _endmatch 0 "if set to 1 ends the match immediately; use it instead of timelimit -1 (deprecated)"
+alias endmatch "_endmatch 1"
 alias bots "minplayers 4; minplayers_per_team 2"
 alias nobots "minplayers 0; minplayers_per_team 0"
 
index 7bcbef2b937fa8afb4af63737e06203c809eab90..a39ea003a8734a778efca27413ace686013431b2 100644 (file)
@@ -133,8 +133,8 @@ seta hud_panel_notify_time "10"
 seta hud_panel_notify_fadetime "3"
 seta hud_panel_notify_icon_aspect "1"
 
-seta hud_panel_timer_pos "0.456000 0"
-seta hud_panel_timer_size "0.088000 0.030000"
+seta hud_panel_timer_pos "0.455000 0"
+seta hud_panel_timer_size "0.090000 0.050000"
 seta hud_panel_timer_bg "border_plain_north"
 seta hud_panel_timer_bg_color ""
 seta hud_panel_timer_bg_color_team ""
index 715d57efdcff1b8da2a2a9acfb537277446b097c..7d3f119327a5da2632f2fd7a5fe08070ff0adda7 100644 (file)
@@ -133,8 +133,8 @@ seta hud_panel_notify_time "10"
 seta hud_panel_notify_fadetime "3"
 seta hud_panel_notify_icon_aspect "2"
 
-seta hud_panel_timer_pos "0.800000 0.040000"
-seta hud_panel_timer_size "0.070000 0.040000"
+seta hud_panel_timer_pos "0.790000 0.040000"
+seta hud_panel_timer_size "0.090000 0.050000"
 seta hud_panel_timer_bg "border_small_timer"
 seta hud_panel_timer_bg_color ""
 seta hud_panel_timer_bg_color_team ""
index 25f871bf12b7165008527e3d25b4d25300a9a238..66fdc01cb2c8fcd4c684fa2d818343d4a81a9700 100644 (file)
@@ -133,8 +133,8 @@ seta hud_panel_notify_time "10"
 seta hud_panel_notify_fadetime "3"
 seta hud_panel_notify_icon_aspect "2"
 
-seta hud_panel_timer_pos "0.435000 0"
-seta hud_panel_timer_size "0.135000 0.060000"
+seta hud_panel_timer_pos "0.430000 0"
+seta hud_panel_timer_size "0.140000 0.060000"
 seta hud_panel_timer_bg "0"
 seta hud_panel_timer_bg_color ""
 seta hud_panel_timer_bg_color_team ""
@@ -159,7 +159,7 @@ seta hud_panel_radar_maximized_size "0.5 0.5"
 seta hud_panel_radar_maximized_rotation "1"
 seta hud_panel_radar_maximized_zoommode "3"
 
-seta hud_panel_score_pos "0.465000 0.045000"
+seta hud_panel_score_pos "0.465000 0.060000"
 seta hud_panel_score_size "0.090000 0.060000"
 seta hud_panel_score_bg ""
 seta hud_panel_score_bg_color ""
@@ -169,7 +169,7 @@ seta hud_panel_score_bg_border ""
 seta hud_panel_score_bg_padding ""
 seta hud_panel_score_rankings "1"
 
-seta hud_panel_racetimer_pos "0.360000 0.090000"
+seta hud_panel_racetimer_pos "0.360000 0.130000"
 seta hud_panel_racetimer_size "0.280000 0.090000"
 seta hud_panel_racetimer_bg "0"
 seta hud_panel_racetimer_bg_color ""
@@ -188,7 +188,7 @@ seta hud_panel_vote_bg_border ""
 seta hud_panel_vote_bg_padding ""
 seta hud_panel_vote_alreadyvoted_alpha "0.8"
 
-seta hud_panel_modicons_pos "0.560000 0"
+seta hud_panel_modicons_pos "0.580000 0"
 seta hud_panel_modicons_size "0.050000 0.100000"
 seta hud_panel_modicons_bg ""
 seta hud_panel_modicons_bg_color ""
index e3e857b0a0f5a9fdf7a9f7ee47e9440709793071..147d9f9e5d7cbc7f171ad52edef9da0c5ee4f7ba 100644 (file)
@@ -133,8 +133,8 @@ seta hud_panel_notify_time "10"
 seta hud_panel_notify_fadetime "3"
 seta hud_panel_notify_icon_aspect "2"
 
-seta hud_panel_timer_pos "0.435000 0"
-seta hud_panel_timer_size "0.135000 0.060000"
+seta hud_panel_timer_pos "0.430000 0"
+seta hud_panel_timer_size "0.140000 0.060000"
 seta hud_panel_timer_bg "0"
 seta hud_panel_timer_bg_color ""
 seta hud_panel_timer_bg_color_team ""
@@ -159,7 +159,7 @@ seta hud_panel_radar_maximized_size "0.5 0.5"
 seta hud_panel_radar_maximized_rotation "1"
 seta hud_panel_radar_maximized_zoommode "3"
 
-seta hud_panel_score_pos "0.465000 0.045000"
+seta hud_panel_score_pos "0.465000 0.060000"
 seta hud_panel_score_size "0.090000 0.060000"
 seta hud_panel_score_bg ""
 seta hud_panel_score_bg_color ""
@@ -169,7 +169,7 @@ seta hud_panel_score_bg_border ""
 seta hud_panel_score_bg_padding ""
 seta hud_panel_score_rankings "1"
 
-seta hud_panel_racetimer_pos "0.360000 0.090000"
+seta hud_panel_racetimer_pos "0.360000 0.130000"
 seta hud_panel_racetimer_size "0.280000 0.090000"
 seta hud_panel_racetimer_bg "0"
 seta hud_panel_racetimer_bg_color ""
@@ -188,7 +188,7 @@ seta hud_panel_vote_bg_border ""
 seta hud_panel_vote_bg_padding ""
 seta hud_panel_vote_alreadyvoted_alpha "0.8"
 
-seta hud_panel_modicons_pos "0.560000 0"
+seta hud_panel_modicons_pos "0.580000 0"
 seta hud_panel_modicons_size "0.050000 0.100000"
 seta hud_panel_modicons_bg ""
 seta hud_panel_modicons_bg_color ""
index fdf1efff39a046b5aea8571c6a01b8672736c1d1..d490f5fcedacd379eb2f72be88243d722c017e1a 100644 (file)
@@ -134,7 +134,7 @@ seta hud_panel_notify_fadetime "3"
 seta hud_panel_notify_icon_aspect "2"
 
 seta hud_panel_timer_pos "0.870000 0"
-seta hud_panel_timer_size "0.130000 0.060000"
+seta hud_panel_timer_size "0.130000 0.090000"
 seta hud_panel_timer_bg "0"
 seta hud_panel_timer_bg_color ""
 seta hud_panel_timer_bg_color_team ""
index 74132c08a90604924cc5d2546398467ab50f1197..7ae8ea586839256aa91f4bc1078732d2d5f07e17 100644 (file)
@@ -134,7 +134,7 @@ seta hud_panel_notify_fadetime "3"
 seta hud_panel_notify_icon_aspect "2"
 
 seta hud_panel_timer_pos "0.850000 0"
-seta hud_panel_timer_size "0.150000 0.060000"
+seta hud_panel_timer_size "0.150000 0.080000"
 seta hud_panel_timer_bg ""
 seta hud_panel_timer_bg_color "0 0.5 0.35"
 seta hud_panel_timer_bg_color_team ""
index f70e5a2805962a43cbebc48607f65b80d27cda8b..93da240eadcdbf68d8d5f210f2c3f3489b3edaa4 100644 (file)
@@ -10,6 +10,32 @@ void HUD_Timer_Export(int fh)
        // allow saving cvars that aesthetically change the panel into hud skin files
 }
 
+vector HUD_Timer_Color(float timeleft)
+{
+       if(timeleft >= 300)
+               return '1 1 1'; //white
+       else if(timeleft >= 60)
+               return '1 1 0'; //yellow
+       else
+               return '1 0 0'; //red
+}
+
+float HUD_Timer_TimeElapsed(float curtime, float starttime)
+{
+       float time_elapsed = curtime - starttime;
+       if (!autocvar_hud_panel_timer_unbound)
+               time_elapsed = max(0, time_elapsed);
+       return floor(time_elapsed);
+}
+
+float HUD_Timer_TimeLeft(float curtime, float starttime, float timelimit)
+{
+       float timeleft = timelimit + starttime - curtime;
+       if (!autocvar_hud_panel_timer_unbound)
+               timeleft = bound(0, timeleft, timelimit);
+       return ceil(timeleft);
+}
+
 void HUD_Timer()
 {
        if(!autocvar__hud_configure)
@@ -29,7 +55,6 @@ void HUD_Timer()
                HUD_Scale_Enable();
        else
                HUD_Scale_Disable();
-       HUD_Panel_DrawBg();
        if(panel_bg_padding)
        {
                pos += '1 1 0' * panel_bg_padding;
@@ -37,59 +62,100 @@ void HUD_Timer()
        }
 
        string timer;
-       float timelimit, timeleft, minutesLeft;
-
-       timelimit = STAT(TIMELIMIT);
-
-       if (autocvar_hud_panel_timer_unbound){
-               timeleft = max(0, timelimit * 60 + STAT(GAMESTARTTIME) - time);
-       } else {
-               timeleft = bound(0, timelimit * 60 + STAT(GAMESTARTTIME) - time, timelimit * 60);
-       }
-       timeleft = ceil(timeleft);
-
-       minutesLeft = floor(timeleft / 60);
-
-       float warmup_timeleft = 0;
+       string subtimer = string_null;
+       string subtext = string_null;
+       float curtime, timelimit, timeleft;
+       vector timer_size, subtext_size, subtimer_size;
+       vector timer_color = '1 1 1';
+       vector subtimer_color = '1 1 1';
+       bool swap = (autocvar_hud_panel_timer_secondary == 2 && STAT(ROUNDSTARTTIME));
+
+       // Use real or frozen time and get the time limit
+       curtime = (intermission_time ? intermission_time : time);
        if(warmup_stage)
        {
-               float warmup_timelimit = STAT(WARMUP_TIMELIMIT);
-               if(warmup_timelimit > 0)
-                       warmup_timeleft = max(0, warmup_timelimit - time + STAT(GAMESTARTTIME));
-               else if(warmup_timelimit == 0)
-                       warmup_timeleft = timeleft;
-               warmup_timeleft = ceil(warmup_timeleft);
+               timelimit = STAT(WARMUP_TIMELIMIT);
+               if(timelimit == 0)
+                       timelimit = STAT(TIMELIMIT) * 60;
+       }
+       else
+       {
+               timelimit = STAT(TIMELIMIT) * 60;
        }
 
-       vector timer_color;
-       if(intermission_time || minutesLeft >= 5 || warmup_stage || timelimit == 0)
-               timer_color = '1 1 1'; //white
-       else if(minutesLeft >= 1)
-               timer_color = '1 1 0'; //yellow
+       // Calculate time left
+       timeleft = HUD_Timer_TimeLeft(curtime, STAT(GAMESTARTTIME), timelimit);
+
+       // Timer color
+       if(!intermission_time && !warmup_stage && timelimit > 0)
+               timer_color = HUD_Timer_Color(timeleft);
+
+       // Timer text
+       if (autocvar_hud_panel_timer_increment || timelimit == 0)
+               timer = seconds_tostring(HUD_Timer_TimeElapsed(curtime, STAT(GAMESTARTTIME)));
        else
-               timer_color = '1 0 0'; //red
-
-       if (intermission_time) {
-               timer = seconds_tostring(max(0, floor(intermission_time - STAT(GAMESTARTTIME))));
-       } else if (warmup_stage && warmup_timeleft >= 60) {
-               timer = _("WARMUP");
-       } else if (autocvar_hud_panel_timer_increment || (!warmup_stage && timelimit == 0) || (warmup_stage && warmup_timeleft <= 0)) {
-               if (time < STAT(GAMESTARTTIME))
-                       if (autocvar_hud_panel_timer_unbound){
-                               timer = seconds_tostring(-(STAT(GAMESTARTTIME) - time));
-                       } else {
-                               timer = seconds_tostring(0); //while restart is still active, show 00:00
-                       }
-               else
-                       timer = seconds_tostring(floor(time - STAT(GAMESTARTTIME)));
-       } else {
-               if(warmup_stage)
-                       timer = seconds_tostring(warmup_timeleft);
-               else
-                       timer = seconds_tostring(timeleft);
+               timer = seconds_tostring(timeleft);
+       
+       // Secondary timer for round-based game modes
+       if(STAT(ROUNDSTARTTIME) && autocvar_hud_panel_timer_secondary)
+       {
+               if(STAT(ROUNDSTARTTIME) == -1) {
+                       // Round can't start
+                       subtimer = "--:--";
+                       subtimer_color = '1 0 0';
+               } else {
+                       float round_curtime, round_timelimit, round_timeleft;
+
+                       // Use real or frozen time and get the time limit
+                       round_curtime = (game_stopped_time ? game_stopped_time : time);
+                       round_timelimit = STAT(ROUND_TIMELIMIT);
+
+                       // Calculate time left
+                       round_timeleft = HUD_Timer_TimeLeft(round_curtime, STAT(ROUNDSTARTTIME), round_timelimit);
+
+                       // Subtimer color
+                       if(!intermission_time && round_timelimit > 0)
+                               subtimer_color = HUD_Timer_Color(round_timeleft);
+
+                       // Subtimer text
+                       if (autocvar_hud_panel_timer_increment || round_timelimit <= 0)
+                               subtimer = seconds_tostring(HUD_Timer_TimeElapsed(round_curtime, STAT(ROUNDSTARTTIME)));
+                       else
+                               subtimer = seconds_tostring(round_timeleft);
+               }
        }
 
-       drawstring_aspect(pos, timer, mySize, timer_color, panel_fg_alpha, DRAWFLAG_NORMAL);
+       // Subtext
+       int overtimes = STAT(OVERTIMES);
+
+       if(warmup_stage || autocvar__hud_configure)
+               subtext = _("Warmup");
+       else if(STAT(TIMEOUT_STATUS))
+               subtext = _("Timeout");
+       else if (overtimes == -1)
+               subtext = _("Sudden Death");
+       else if(overtimes == 1)
+               subtext = _("Overtime");
+       else if (overtimes >= 2)
+               subtext = sprintf(_("Overtime #%d"), overtimes);
+
+       subtext_size  = vec2(mySize.x, mySize.y / 3);
+       timer_size    = vec2(mySize.x, mySize.y - subtext_size.y);
+       subtimer_size = vec2(mySize.x / 3, mySize.y - subtext_size.y);
+       
+       panel_size.y -= subtext_size.y;
+       HUD_Panel_DrawBg();
+       
+       if(subtimer) {
+               float subtimer_padding = subtimer_size.y / 5;
+               timer_size.x -= subtimer_size.x;
+               drawstring_aspect(pos + eX * timer_size.x + eY * subtimer_padding, (swap ? timer : subtimer), subtimer_size - eY * subtimer_padding * 2, (swap ? timer_color : subtimer_color), panel_fg_alpha, DRAWFLAG_NORMAL);
+       }
+       
+       drawstring_aspect(pos, (swap ? subtimer : timer), timer_size, (swap ? subtimer_color : timer_color), panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       if(subtext)
+               drawstring_aspect(pos + eY * timer_size.y, subtext, subtext_size, '0 1 0', panel_fg_alpha, DRAWFLAG_NORMAL);
 
        draw_endBoldFont();
 }
index bbeeb727282064ec95637d2c6550c4e27a30036b..3790f477708accf11c062186355477a102761359 100644 (file)
@@ -4,4 +4,9 @@
 bool autocvar_hud_panel_timer;
 bool autocvar_hud_panel_timer_dynamichud        = true;
 bool autocvar_hud_panel_timer_increment;
+int autocvar_hud_panel_timer_secondary = 1;
 bool autocvar_hud_panel_timer_unbound;
+
+vector HUD_Timer_Color(float timeleft);
+float HUD_Timer_TimeElapsed(float curtime, float starttime);
+float HUD_Timer_TimeLeft(float curtime, float starttime, float timelimit);
index 0d2d6e1227aade3dddc156b94719f546f58f77b5..0399ef87b1d9d7cf9531168c4ac9bf632c5c061d 100644 (file)
@@ -1639,6 +1639,11 @@ void CSQC_UpdateView(entity this, float w, float h)
        if(intermission && !intermission_time)
                intermission_time = time;
 
+       if(STAT(GAME_STOPPED) && !game_stopped_time)
+               game_stopped_time = time;
+       else if(game_stopped_time && !STAT(GAME_STOPPED))
+               game_stopped_time = 0;
+
        if(intermission && !isdemo() && !(calledhooks & HOOK_END))
        {
                if(calledhooks & HOOK_START)
index 0abcb13fe8d0a7e78708fe478711ff46f662db23..45959383bdf38c893dc30abad243237c01629e79 100644 (file)
@@ -125,3 +125,4 @@ float blurtest_time0, blurtest_time1, blurtest_radius, blurtest_power;
 #endif
 
 float intermission_time;
+float game_stopped_time;
index 091f7e689dbb1960c7e71c1312d11da1646ef866..abadaa47deefb24f227e0f5350d1673dfa8ff02b 100644 (file)
@@ -79,6 +79,9 @@ float game_stopped;
 float game_starttime; //point in time when the countdown to game start is over
 float round_starttime; //point in time when the countdown to round start is over
 int autocvar_leadlimit;
+int overtimes; // overtimes added (-1 = sudden death)
+int timeout_status; // (values: 0, 1, 2) contains whether a timeout is not active (0), was called but still at leadtime (1) or is active (2)
+
 // TODO: world.qh can't be included here due to circular includes!
 #define autocvar_fraglimit cvar("fraglimit")
 #define autocvar_fraglimit_override cvar("fraglimit_override")
@@ -115,6 +118,8 @@ REGISTER_STAT(SECRETS_TOTAL, int, secrets_total)
 REGISTER_STAT(SECRETS_FOUND, int, secrets_found)
 REGISTER_STAT(RESPAWN_TIME, float)
 REGISTER_STAT(ROUNDSTARTTIME, float, round_starttime)
+REGISTER_STAT(OVERTIMES, int, overtimes)
+REGISTER_STAT(TIMEOUT_STATUS, int, timeout_status)
 REGISTER_STAT(MONSTERS_TOTAL, int)
 REGISTER_STAT(MONSTERS_KILLED, int)
 REGISTER_STAT(NADE_BONUS, float)
@@ -360,6 +365,7 @@ REGISTER_STAT(Q3COMPAT, int, q3compat)
 #ifdef SVQC
 #include "physics/movetypes/movetypes.qh"
 float warmup_limit;
+float round_limit;
 #endif
 
 #ifdef SVQC
@@ -399,6 +405,7 @@ REGISTER_STAT(MOVEVARS_AIRCONTROL, float)
 REGISTER_STAT(FRAGLIMIT, float, autocvar_fraglimit)
 REGISTER_STAT(TIMELIMIT, float, autocvar_timelimit)
 REGISTER_STAT(WARMUP_TIMELIMIT, float, warmup_limit)
+REGISTER_STAT(ROUND_TIMELIMIT, float, round_limit)
 #ifdef SVQC
 float autocvar_sv_wallfriction;
 #define autocvar_sv_gravity cvar("sv_gravity")
index 84c6d862dbebb8a4644e2546516a9d9b70a71de1..bea70827948dd77a830ced4b4965858780fa668d 100644 (file)
@@ -1,5 +1,6 @@
 #include "dialog_hudpanel_timer.qh"
 
+#include "textslider.qh"
 #include "checkbox.qh"
 #include "textlabel.qh"
 
@@ -17,4 +18,12 @@ void XonoticHUDTimerDialog_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_timer_increment", _("Show elapsed time")));
+       me.TR(me);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Secondary timer:")));
+        me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_panel_timer_secondary"));
+            e.addValue(e, _("Disable"), "0");
+            e.addValue(e, _("Enable"), "1");
+            e.addValue(e, _("Swapped"), "2");
+            e.configureXonoticTextSliderValues(e);
 }
index 5fd66bdbbac1f595e76e0bb06ca4024d0865ea46..5fbf0dc697d5a0ac5d046292d525f6a6c2def2a5 100644 (file)
@@ -58,7 +58,6 @@ float sys_frametime;     // gets initialised in worldspawn, saves the value from
 float orig_slowmo;       // contains the value of autocvar_slowmo so that, after timeout finished, it isn't set to slowmo 1 necessarily
 float timeout_time;      // contains the time in seconds that the active timeout has left
 float timeout_leadtime;  // contains the number of seconds left of the leadtime (before the timeout starts)
-float timeout_status;    // (values: 0, 1, 2) contains whether a timeout is not active (0), was called but still at leadtime (1) or is active (2)
 .float allowed_timeouts; // contains the number of allowed timeouts for each player
 .vector lastV_angle;     // used when pausing the game in order to force the player to keep his old view angle fixed
 
index 40b621aa9ba77e157f3d20f056e7f79e42290a86..7ff8d2a133e16abd24425031214f7f11201c35aa 100644 (file)
@@ -435,7 +435,7 @@ void ReadyRestart_force(bool is_fake_round_start)
        // clear overtime, we have to decrease timelimit to its original value again.
        if (checkrules_overtimesadded > 0 && g_race_qualifying != 2)
                cvar_set("timelimit", ftos(autocvar_timelimit - (checkrules_overtimesadded * autocvar_timelimit_overtime)));
-       checkrules_suddendeathend = checkrules_overtimesadded = checkrules_suddendeathwarning = 0;
+       checkrules_suddendeathend = checkrules_overtimesadded = checkrules_suddendeathwarning = overtimes = 0;
 
        if(warmup_stage)
                game_starttime = time; // Warmup: No countdown in warmup
index 81850d8df33ce041796423d6ed377c31e28241e8..98d2ef25b08febaa7805ba1f42e5f7327cb9c0af 100644 (file)
@@ -399,7 +399,7 @@ string GotoMap(string m)
        if(!MapInfo_CheckMap(m))
                return "The map you suggested does not support the current game mode.";
        cvar_set("nextmap", m);
-       cvar_set("timelimit", "-1");
+       cvar_set("_endmatch", "1");
        if(mapvote_initialized || alreadychangedlevel)
        {
                if(DoNextMapOverride(0))
index 5307eca782a827398f66eed801fdd73682d458b4..b63883dcc828e4b932a984d6bd8d959455610100 100644 (file)
@@ -50,6 +50,7 @@ void round_handler_Think(entity this)
                else
                {
                        round_handler_Reset(0);
+                       round_starttime = -1; // can't start
                }
                this.nextthink = time + 1;  // canRoundStart every second
        }
@@ -75,6 +76,7 @@ void round_handler_Init(float the_delay, float the_count, float the_round_timeli
        this.count = fabs(floor(the_count));
        this.cnt = this.count + 1;
        this.round_timelimit = (the_round_timelimit > 0) ? the_round_timelimit : 0;
+       round_limit = the_round_timelimit;
 }
 
 // NOTE: this is only needed because if round_handler spawns at time 1
@@ -111,7 +113,8 @@ void round_handler_Reset(float next_think)
        if (this.count)
                if (this.cnt < this.count + 1) this.cnt = this.count + 1;
        this.nextthink = next_think;
-       round_starttime = (next_think) ? (next_think + this.count) : -1;
+       if (next_think)
+               round_starttime = next_think + this.count;
 }
 
 void round_handler_Remove()
index 51093d51b512abb12fc687c7b391ee0fea9b28db..7fce21e6ee81f69fe4a35112daaec00739e22ccc 100644 (file)
@@ -1275,6 +1275,7 @@ only called if a time or frag limit has expired
 */
 void NextLevel()
 {
+       cvar_set("_endmatch", "0");
        game_stopped = true;
        intermission_running = true; // game over
 
@@ -1350,9 +1351,14 @@ float InitiateSuddenDeath()
                if(!checkrules_suddendeathend)
                {
                        if(autocvar_g_campaign)
+                       {
                                checkrules_suddendeathend = time; // no suddendeath in campaign
+                       }
                        else
+                       {
                                checkrules_suddendeathend = time + 60 * autocvar_timelimit_suddendeath;
+                               overtimes = -1;
+                       }
                        if(g_race && !g_race_qualifying)
                                race_StartCompleting();
                }
@@ -1363,6 +1369,7 @@ float InitiateSuddenDeath()
 void InitiateOvertime() // ONLY call this if InitiateSuddenDeath returned true
 {
        ++checkrules_overtimesadded;
+       overtimes = checkrules_overtimesadded;
        //add one more overtime by simply extending the timelimit
        cvar_set("timelimit", ftos(autocvar_timelimit + autocvar_timelimit_overtime));
        Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_OVERTIME_TIME, autocvar_timelimit_overtime * 60);
@@ -1613,17 +1620,16 @@ void CheckRules_World()
                leadlimit = 0; // no leadlimit for now
        }
 
-       if(timelimit > 0)
-       {
-               timelimit += game_starttime;
-       }
-       else if (timelimit < 0)
+       if (autocvar__endmatch || timelimit < 0)
        {
                // endmatch
                NextLevel();
                return;
        }
 
+       if(timelimit > 0)
+               timelimit += game_starttime;
+
        float wantovertime;
        wantovertime = 0;
 
index 299c88535446724e3819fc5f90c67ac07efe0693..242b3369470546ff8c0a1c4b0169e14605237044 100644 (file)
@@ -3,6 +3,7 @@
 #include <common/weapons/_all.qh>
 
 bool autocvar__sv_init;
+bool autocvar__endmatch;
 bool autocvar_g_use_ammunition;
 bool autocvar_g_jetpack;
 bool autocvar_g_warmup_allguns;
@@ -30,7 +31,7 @@ float autocvar_timelimit_suddendeath;
 float checkrules_equality;
 float checkrules_suddendeathwarning;
 float checkrules_suddendeathend;
-float checkrules_overtimesadded; //how many overtimes have been already added
+int checkrules_overtimesadded; //how many overtimes have been already added
 
 // flag set on worldspawn so that the code knows if it is dedicated or not
 bool server_is_dedicated;