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;
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)
{
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)
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);
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));
} 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);
}
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)
{
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))
void buff_Respawn(entity this)
{
- if(game_stopped) return;
+ if(game_stopped || game_timeout) return;
vector oldbufforigin = this.origin;
this.velocity = '0 0 200';
void buff_Touch(entity this, entity toucher)
{
- if(game_stopped) return;
+ if(game_stopped || game_timeout) return;
if(ITEM_TOUCH_NEEDKILL())
{
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)
{
}
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);
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)
{
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)
{
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)
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);
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)
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)
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);
{
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);
{
case CMD_REQUEST_COMMAND:
{
- if (!intermission_running && IS_CLIENT(caller))
+ if (!intermission_running && IS_CLIENT(caller) && !game_timeout)
{
if(argv(1) != "")
{
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
{
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), {
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
}
}
+// 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)
// 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); }
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");
}
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)
{
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))
{
void round_handler_Think(entity this)
{
+ if (game_timeout) { this.nextthink = time + 1; return; }
+
if (intermission_running)
{
round_handler_Reset(0);
}
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)
#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
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)
{
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;
modname = strzone(modname);
WinningConditionHelper(this); // set worldstatus
-
+
world_initialized = 1;
__spawnfunc_spawn_all();
+
+ if(!warmup_stage)
+ round_handler_Activate(true);
}
spawnfunc(light)
// 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;