]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Proper timeout and no rounds in warmup
authorz411 <z411@omaera.org>
Thu, 15 Oct 2020 23:58:22 +0000 (20:58 -0300)
committerz411 <z411@omaera.org>
Thu, 15 Oct 2020 23:58:22 +0000 (20:58 -0300)
18 files changed:
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/hud/panel/timer.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/mutators/mutator/bloodloss/bloodloss.qc
qcsrc/common/mutators/mutator/buffs/sv_buffs.qc
qcsrc/common/mutators/mutator/campcheck/sv_campcheck.qc
qcsrc/common/mutators/mutator/instagib/sv_instagib.qc
qcsrc/common/stats.qh
qcsrc/ecs/systems/sv_physics.qc
qcsrc/server/command/cmd.qc
qcsrc/server/command/common.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/items/items.qc
qcsrc/server/round_handler.qc
qcsrc/server/round_handler.qh
qcsrc/server/weapons/weaponsystem.qc
qcsrc/server/world.qc

index 579ff95584db8ff9d9209449b9c8267948442740..12eb71cd7eaa474175682a48f99594f68752528c 100644 (file)
@@ -1663,6 +1663,7 @@ vector MapStats_DrawKeyValue(vector pos, string key, string value) {
        return pos;
 }
 
+/*
 vector Scoreboard_MapStats_Draw(vector pos, vector rgb, vector bg_size) {
        float stat_secrets_found, stat_secrets_total;
        float stat_monsters_killed, stat_monsters_total;
@@ -1731,7 +1732,7 @@ vector Scoreboard_MapStats_Draw(vector pos, vector rgb, vector bg_size) {
        panel_size.x += panel_bg_padding * 2; // restore initial width
        return end_pos;
 }
-
+*/
 
 vector Scoreboard_Rankings_Draw(vector pos, string ranktitle, entity pl, vector rgb, vector bg_size)
 {
@@ -2223,7 +2224,7 @@ void Scoreboard_Draw()
                pos = Scoreboard_Rankings_Draw(pos, ranktitle, playerslots[player_localnum], panel_bg_color, bg_size);
        }
 
-       pos = Scoreboard_MapStats_Draw(pos, panel_bg_color, bg_size);
+       //pos = Scoreboard_MapStats_Draw(pos, panel_bg_color, bg_size);
 
        // List spectators
        for(pl = players.sort_next; pl; pl = pl.sort_next)
index 293247f951191325e9e63446c2904bce70aa942e..65abb0d272a06a1f49fa054787cba5ecf90777aa 100644 (file)
@@ -39,10 +39,13 @@ void HUD_Timer()
 
        string timer;
        string timer_sub = "";
-       float timelimit, timeleft, minutesLeft, overtimes;
+       bool game_timeout;
+       float timelimit, timeleft, minutesLeft, overtimes, timeout_last;
 
        timelimit = STAT(TIMELIMIT);
        overtimes = STAT(OVERTIMESADDED);
+       game_timeout = STAT(GAME_TIMEOUT);
+       timeout_last = STAT(TIMEOUT_LAST);
 
        timeleft = max(0, timelimit * 60 + STAT(GAMESTARTTIME) - time);
        timeleft = ceil(timeleft);
@@ -72,12 +75,20 @@ void HUD_Timer()
                timer = seconds_tostring(max(0, floor(intermission_time - STAT(GAMESTARTTIME))));
                timer_sub = "Intermission";
        //} else if (autocvar_hud_panel_timer_increment || (!warmup_stage && timelimit == 0) || (warmup_stage && warmup_timeleft <= 0)) {
+       } else if (game_timeout) {
+               if(autocvar_hud_panel_timer_increment)
+                       timer = seconds_tostring(max(0, floor(timeout_last - STAT(GAMESTARTTIME))));
+               else
+                       timer = seconds_tostring(ceil(max(0, timelimit * 60 + STAT(GAMESTARTTIME) - timeout_last)));
+               timer_sub = "Timeout";
        } else if (autocvar_hud_panel_timer_increment || timelimit == 0) {
+               // Time elapsed timer
                if((warmup_stage && warmup_timeleft <= 0) || time < STAT(GAMESTARTTIME))
                        timer = seconds_tostring(0);
                else
                        timer = seconds_tostring(floor(time - STAT(GAMESTARTTIME)));
        } else {
+               // Time left timer
                if(warmup_stage) {
                        if(warmup_timeleft <= 0)
                                timer = seconds_tostring(floor(timelimit * 60));
@@ -86,8 +97,8 @@ void HUD_Timer()
                } else {
                        if (time < STAT(GAMESTARTTIME))
                                timer = seconds_tostring(floor(timelimit * 60));
-                       else if (overtimes > 0)
-                               timer = seconds_tostring(floor(time - STAT(OVERTIMESTARTTIME)));
+                       //else if (overtimes > 0)
+                       //      timer = seconds_tostring(floor(time - STAT(OVERTIMESTARTTIME)));
                        else
                                timer = seconds_tostring(timeleft);
                }
index d5bff8f0239f682727e8e09eac47c221329b3037..ba1d4941ff16ad22309b135bf5f8ec438731a079 100644 (file)
@@ -31,8 +31,8 @@
 
 void monsters_setstatus(entity this)
 {
-       STAT(MONSTERS_TOTAL, this) = monsters_total;
-       STAT(MONSTERS_KILLED, this) = monsters_killed;
+       //STAT(MONSTERS_TOTAL, this) = monsters_total;
+       //STAT(MONSTERS_KILLED, this) = monsters_killed;
 }
 
 void monster_dropitem(entity this, entity attacker)
index 41ceaa91fab751c6bfa7761d77f15cdc44ff9058..3992d985a3465e90072ff699218a6f94f3bdd569 100644 (file)
@@ -14,7 +14,7 @@ MUTATOR_HOOKFUNCTION(bloodloss, PlayerPreThink)
 {
        entity player = M_ARGV(0, entity);
 
-       if(game_stopped)
+       if(game_stopped || game_timeout)
                return; // during intermission, the player's health changes to strange values for the engine, let's not cause damage during this phase!
 
        if(IS_PLAYER(player))
index 30cef339a69a4249785e6f04344b451f5427691b..1c0327dcf1c466311a95f20c7755afd72cb9e8ae 100644 (file)
@@ -119,7 +119,7 @@ void buff_SetCooldown(entity this, float cd)
 
 void buff_Respawn(entity this)
 {
-       if(game_stopped) return;
+       if(game_stopped || game_timeout) return;
 
        vector oldbufforigin = this.origin;
        this.velocity = '0 0 200';
@@ -154,7 +154,7 @@ void buff_Respawn(entity this)
 
 void buff_Touch(entity this, entity toucher)
 {
-       if(game_stopped) return;
+       if(game_stopped || game_timeout) return;
 
        if(ITEM_TOUCH_NEEDKILL())
        {
@@ -269,7 +269,7 @@ void buff_Think(entity this)
                this.oldbuffs = STAT(BUFFS, this);
        }
 
-       if(!game_stopped)
+       if(!game_stopped && !game_timeout)
        if((round_handler_IsActive() && round_handler_IsRoundStarted()) || time >= game_starttime)
        if(!this.buff_activetime_updated)
        {
@@ -290,7 +290,7 @@ void buff_Think(entity this)
        }
 
        if(this.buff_activetime)
-       if(!game_stopped)
+       if(!game_stopped && !game_timeout)
        if((round_handler_IsActive() && round_handler_IsRoundStarted()) || time >= game_starttime)
        {
                this.buff_activetime = max(0, this.buff_activetime - frametime);
@@ -667,7 +667,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerUseKey, CBC_ORDER_FIRST)
 
 MUTATOR_HOOKFUNCTION(buffs, ForbidThrowCurrentWeapon)
 {
-       if(MUTATOR_RETURNVALUE || game_stopped) return;
+       if(MUTATOR_RETURNVALUE || game_stopped || game_timeout) return;
        entity player = M_ARGV(0, entity);
 
        if(STAT(BUFFS, player) & BUFF_SWAPPER.m_itemid)
@@ -827,7 +827,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
 {
        entity player = M_ARGV(0, entity);
 
-       if(game_stopped || IS_DEAD(player) || frametime || !IS_PLAYER(player)) return;
+       if(game_stopped || game_timeout || IS_DEAD(player) || frametime || !IS_PLAYER(player)) return;
 
        if(STAT(BUFFS, player) & BUFF_FLIGHT.m_itemid)
        {
index f53d8c356a5bac8c59f0f2e5682c65fb0d5b00cc..a2370a48c0f608178cad9dc2b6f690a5022dcb32 100644 (file)
@@ -38,7 +38,7 @@ MUTATOR_HOOKFUNCTION(campcheck, PlayerPreThink)
        bool checked = false;
 
        if(autocvar_g_campcheck_interval)
-       if(!game_stopped && !warmup_stage && time >= game_starttime)
+       if(!game_stopped && !game_timeout && !warmup_stage && time >= game_starttime)
        if(IS_PLAYER(player) && !IS_DEAD(player) && !STAT(FROZEN, player))
        if(autocvar_g_campcheck_typecheck || !PHYS_INPUT_BUTTON_CHAT(player))
        if(IS_REAL_CLIENT(player)) // only apply to real clients (bots may "camp" due to missing waypoints in the map, but that's no reason to constantly kill them, clones can't move)
index a23fc36970a6822f5ca48af79b29487c338a5df5..3e3f7ac84664ec812a56f441b6691403ff3fe109 100644 (file)
@@ -79,7 +79,7 @@ void instagib_ammocheck(entity this)
        if(!IS_PLAYER(this))
                return; // not a player
 
-       if(IS_DEAD(this) || game_stopped)
+       if(IS_DEAD(this) || game_stopped || game_timeout)
                instagib_stop_countdown(this);
        else if (GetResource(this, RES_CELLS) > 0 || (this.items & IT_UNLIMITED_AMMO) || (this.flags & FL_GODMODE))
                instagib_stop_countdown(this);
index 2a614e427dad700bd7035ec33ca6e9f478fb2d60..49be5178cebcdc859025f323258963fd538e4ce5 100644 (file)
@@ -67,12 +67,21 @@ 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
 float overtime_starttime; // z411 point in time where first overtime started
+
 float checkrules_overtimesadded; // z411 add
+float timeout_last;
+float timeout_total_time;
+bool game_timeout;
+
 bool autocvar_g_allow_oldvortexbeam;
 int autocvar_leadlimit;
 #endif
 REGISTER_STAT(WEAPONRATEFACTOR, float, W_WeaponRateFactor(this))
 REGISTER_STAT(GAME_STOPPED, int, game_stopped)
+
+REGISTER_STAT(GAME_TIMEOUT, bool, game_timeout)
+REGISTER_STAT(TIMEOUT_LAST, float, timeout_last)
+
 REGISTER_STAT(GAMESTARTTIME, float, game_starttime)
 REGISTER_STAT(STRENGTH_FINISHED, float)
 REGISTER_STAT(INVINCIBLE_FINISHED, float)
@@ -103,14 +112,14 @@ REGISTER_STAT(VEHICLESTAT_AMMO2, int)
 REGISTER_STAT(VEHICLESTAT_RELOAD2, int)
 REGISTER_STAT(VEHICLESTAT_W2MODE, int)
 REGISTER_STAT(NADE_TIMER, float)
-REGISTER_STAT(SECRETS_TOTAL, int, secrets_total)
-REGISTER_STAT(SECRETS_FOUND, int, secrets_found)
+//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(OVERTIMESTARTTIME, float, overtime_starttime)
 REGISTER_STAT(OVERTIMESADDED, float, checkrules_overtimesadded)
-REGISTER_STAT(MONSTERS_TOTAL, int)
-REGISTER_STAT(MONSTERS_KILLED, int)
+//REGISTER_STAT(MONSTERS_TOTAL, int)
+//REGISTER_STAT(MONSTERS_KILLED, int)
 REGISTER_STAT(BUFFS, int)
 REGISTER_STAT(NADE_BONUS, float)
 REGISTER_STAT(NADE_BONUS_TYPE, int)
index 1d5553d1d1084b50be15cec4287a17905ac6d28a..694359cbe1aca7d3a77e22ac1f1ad0f58298b64c 100644 (file)
@@ -42,7 +42,7 @@ void sys_phys_pregame_hold(entity this)
        if (!IS_PLAYER(this)) { return; }
        // z411
        //const bool allowed_to_move = (time >= game_starttime && !game_stopped);
-       const bool allowed_to_move = (!game_stopped);
+       const bool allowed_to_move = (!game_stopped && !game_timeout);
        if (!allowed_to_move) {
                this.velocity = '0 0 0';
                set_movetype(this, MOVETYPE_NONE);
index b1d568ba13aba6f1086158cd963de5f425685ab0..0ba8ed3006f643820086a89fbe36b55471c1af35 100644 (file)
@@ -285,7 +285,7 @@ void ClientCommand_join(entity caller, int request)
        {
                case CMD_REQUEST_COMMAND:
                {
-                       if (!game_stopped && IS_CLIENT(caller) && !IS_PLAYER(caller))
+                       if (!game_stopped && !game_timeout && IS_CLIENT(caller) && !IS_PLAYER(caller))
                        {
                                if (joinAllowed(caller))
                                        Join(caller);
@@ -636,7 +636,7 @@ void ClientCommand_spectate(entity caller, int request)
        {
                case CMD_REQUEST_COMMAND:
                {
-                       if (!intermission_running && IS_CLIENT(caller))
+                       if (!intermission_running && IS_CLIENT(caller) && !game_timeout)
                        {
                                if(argv(1) != "")
                                {
index c27c5ac337917a30585b77ebe72338abf8dd0b3a..94ea014e9f204ddbfcada905921a09371df93d2f 100644 (file)
@@ -212,7 +212,8 @@ void timeout_handler_think(entity this)
                                if (timeout_time == autocvar_sv_timeout_resumetime) // play a warning sound when only <sv_timeout_resumetime> seconds are left
                                        Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_PREPARE);
 
-                               this.nextthink = time + TIMEOUT_SLOWMO_VALUE;       // think again in one second
+                               //this.nextthink = time + TIMEOUT_SLOWMO_VALUE;       // think again in one second
+                               this.nextthink = time + 1;
                                timeout_time -= 1;                                  // decrease the time counter
                        }
                        else if (timeout_time == -1)  // infinite timer
@@ -224,9 +225,20 @@ void timeout_handler_think(entity this)
                        {
                                Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_TIMEIN);
                                timeout_status = TIMEOUT_INACTIVE;
+                               float total_time = time - timeout_last;
 
                                // reset the slowmo value back to normal
-                               cvar_set("slowmo", ftos(orig_slowmo));
+                               // z411 TODO
+                               //cvar_set("slowmo", ftos(orig_slowmo));
+                               
+                               // Disable timeout and fix times
+                               game_timeout = false;
+                               timeout_total_time += total_time;
+                               game_starttime += total_time;
+                               if(round_handler && round_handler_GetEndTime() > 0)
+                                       round_handler.round_endtime += total_time;
+                                       
+                               LOG_INFOF("timeout lasted %d secs", total_time);
 
                                // unlock the view for players so they can move around again
                                FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), {
@@ -253,7 +265,11 @@ void timeout_handler_think(entity this)
                                timeout_status = TIMEOUT_ACTIVE;
 
                                // set the slowmo value to the timeout default slowmo value
-                               cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE));
+                               //cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE));
+                               game_timeout = true;
+                               timeout_last = time;
+                               
+                               // play timeout sound
                                sound(NULL, CH_INFO, SND_TIMEOUT, VOL_BASE, ATTN_NONE);
 
                                // reset all the flood variables
index 526775c7c862112bab285153e62ebe5672ee55b9..4fe4c7c45b08b8eef0719b72d558faf83f1d7c65 100644 (file)
@@ -235,6 +235,30 @@ void GameCommand_allready(int request)
        }
 }
 
+// z411 TODO
+void GameCommand_stop(int request, int argc)
+{
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       if(argv(1) == "true")
+                               game_stopped = true;
+                       else
+                               game_stopped = false;
+                       return;
+               }
+
+               default:
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 sv_cmd stop");
+                       LOG_HELP("  No arguments required.");
+                       return;
+               }
+       }
+}
+
 void GameCommand_allspec(int request, int argc)
 {
        switch (request)
@@ -1712,6 +1736,7 @@ void GameCommand_(int request)
 // Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
 SERVER_COMMAND(setflag, "Set client flag") { GameCommand_setflag(request, arguments); }
 SERVER_COMMAND(teamname, "Set team name") { GameCommand_teamname(request, arguments); }
+SERVER_COMMAND(stop, "Stop") { GameCommand_stop(request, arguments); }
 
 SERVER_COMMAND(adminmsg, "Send an admin message to a client directly") { GameCommand_adminmsg(request, arguments); }
 SERVER_COMMAND(allready, "Restart the server and reset the players") { GameCommand_allready(request); }
index edd898546e539dc258e86e9964e703f15f51d987..8306349cf32a1462ab8dd56feeaf1ac4eb0b5063 100644 (file)
@@ -481,6 +481,7 @@ void ReadyRestart_force()
                FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { CS(it).allowed_timeouts = autocvar_sv_timeout_number; });
        }
 
+       round_handler_Activate(true);
        if (!sv_ready_restart_after_countdown) reset_map(true);
        if (autocvar_sv_eventlog) GameLogEcho(":restart");
 }
index 861b21eed2b566df931eef6a382f4b848139ec7c..906e89aeaf71d19f2036bfeec3528ba74caeb310 100644 (file)
@@ -280,12 +280,14 @@ void Item_RespawnCountdown(entity this)
 
 void Item_RespawnThink(entity this)
 {
-       this.nextthink = time;
+       this.nextthink = time + 1;
        if(this.origin != this.oldorigin)
                ItemUpdate(this);
-
-       if(time >= this.wait)
+       
+       if(!game_timeout && time - timeout_total_time >= this.wait)
                Item_Respawn(this);
+       
+       //LOG_INFOF("time until respawn %d", (this.wait) - (time - timeout_total_time));
 }
 
 void Item_ScheduleRespawnIn(entity e, float t)
@@ -308,8 +310,8 @@ void Item_ScheduleRespawnIn(entity e, float t)
        {
                setthink(e, Item_RespawnThink);
                e.nextthink = time;
-               e.scheduledrespawntime = time + t;
-               e.wait = time + t;
+               e.scheduledrespawntime = time - timeout_total_time + t;
+               e.wait = time - timeout_total_time + t;
 
                if(Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
                {
index 66da6c37c1fb154ec39cac5381e57be04e9978a3..9eb8963c8f1728f2733d11cc4841fde6f4dc832c 100644 (file)
@@ -9,6 +9,8 @@
 
 void round_handler_Think(entity this)
 {
+       if (game_timeout) { this.nextthink = time + 1; return; }
+       
        if (intermission_running)
        {
                round_handler_Reset(0);
@@ -96,13 +98,25 @@ void round_handler_Spawn(bool() canRoundStart_func, bool() canRoundEnd_func, voi
        }
        entity this = round_handler = new(round_handler);
 
-       setthink(this, round_handler_FirstThink);
+       
        this.canRoundStart = canRoundStart_func;
        this.canRoundEnd = canRoundEnd_func;
        this.roundStart = roundStart_func;
        this.wait = false;
        round_handler_Init(5, 5, 180);
-       this.nextthink = time;
+       
+}
+
+void round_handler_Activate(bool active) {
+       if (round_handler) {
+               entity this = round_handler;
+       
+               this.isactive = active;
+               if(active) {
+                       setthink(this, round_handler_FirstThink);
+                       this.nextthink = time;
+               }
+       }
 }
 
 void round_handler_Reset(float next_think)
index 5979eb5c33f810faeb55f2add99f7574533fc121..01288ab64620d1e089ee7a6c7595495a306b1f36 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 entity round_handler;
+.bool isactive;
 .float delay; // stores delay from round end to countdown start
 .float count; // stores initial number of the countdown
 .bool wait; // it's set to true when round ends, to false when countdown starts
@@ -15,9 +16,10 @@ entity round_handler;
 void round_handler_Init(float the_delay, float the_count, float the_round_timelimit);
 void round_handler_Spawn(bool() canRoundStart_func, bool() canRoundEnd_func, void() roundStart_func);
 void round_handler_Reset(float next_think);
+void round_handler_Activate(bool active);
 void round_handler_Remove();
 
-#define round_handler_IsActive() (round_handler != NULL)
+#define round_handler_IsActive() (round_handler != NULL && round_handler.isactive)
 #define round_handler_AwaitingNextRound() (round_handler.wait)
 #define round_handler_CountdownRunning() (!round_handler.wait && round_handler.cnt)
 #define round_handler_IsRoundStarted() (!round_handler.wait && !round_handler.cnt)
index 7638813882d306ca3e67544c10290ed80231d866..b3112fe3bf35bf3f72b13bd4018b19348388a139 100644 (file)
@@ -440,7 +440,7 @@ bool weaponLocked(entity player)
 {
        if (time < game_starttime && !sv_ready_restart_after_countdown) return true;
        if (player.player_blocked) return true;
-       if (game_stopped) return true;
+       if (game_stopped || game_timeout) return true;
        if (STAT(FROZEN, player)) return true;
        if (MUTATOR_CALLHOOK(LockWeapon, player)) return true;
        return false;
index 891131b38dce5db49590163ba22cba944f355013..309a42123ebe0a1ec5b60fd53042a4d20b86fa14 100644 (file)
@@ -1017,9 +1017,12 @@ spawnfunc(worldspawn)
        modname = strzone(modname);
 
        WinningConditionHelper(this); // set worldstatus
-
+       
        world_initialized = 1;
        __spawnfunc_spawn_all();
+       
+       if(!warmup_stage)
+               round_handler_Activate(true);
 }
 
 spawnfunc(light)
@@ -1955,6 +1958,9 @@ void CheckRules_World()
                        // again, but this shouldn't hurt
                return;
        }
+       
+       // z411 don't check rules if we're in a timeout
+       if (game_timeout) return;
 
        float timelimit = autocvar_timelimit * 60;
        float fraglimit = autocvar_fraglimit;