Rework time limit a bit

- Make timelimitintics handled a bit more like gamespeed, encore, frantic, etc - update on mapload/starttime, not during gameplay
    - Use default setting if can't change rules - this is a surprise tool that will help us later
- Have it properly update when adjusting gametype from the menu
    - Cleaned up SV_StartSinglePlayerServer to do this
- Remove CV_SAVE to prevent time limit bruh moments
This commit is contained in:
toaster 2022-10-11 23:00:44 +01:00
parent 13c8d45764
commit 243f38227c
9 changed files with 72 additions and 70 deletions

View file

@ -3877,31 +3877,23 @@ void SV_StopServer(void)
} }
// called at singleplayer start and stopdemo // called at singleplayer start and stopdemo
void SV_StartSinglePlayerServer(void) void SV_StartSinglePlayerServer(INT32 dogametype, boolean donetgame)
{ {
INT32 lastgametype = gametype; INT32 lastgametype = gametype;
server = true; server = true;
netgame = false; multiplayer = (modeattacking == ATTACKING_NONE);
multiplayer = false;
joinedIP[0] = '\0'; // Make sure to empty this so that we don't save garbage when we start our own game. (because yes we use this for netgames too....) joinedIP[0] = '\0'; // Make sure to empty this so that we don't save garbage when we start our own game. (because yes we use this for netgames too....)
if ((modeattacking == ATTACKING_CAPSULES) || (bossinfo.boss == true)) netgame = false; // so setting timelimit works... (XD_NETVAR doesn't play nice with SV_StopServer)
{
G_SetGametype(GT_BATTLE);
}
else
{
G_SetGametype(GT_RACE);
}
G_SetGametype(dogametype);
if (gametype != lastgametype) if (gametype != lastgametype)
D_GameTypeChanged(lastgametype); D_GameTypeChanged(lastgametype);
netgame = donetgame;
// no more tic the game with this settings! // no more tic the game with this settings!
SV_StopServer(); SV_StopServer();
if (splitscreen)
multiplayer = true;
} }
static void SV_SendRefuse(INT32 node, const char *reason) static void SV_SendRefuse(INT32 node, const char *reason)

View file

@ -473,7 +473,7 @@ void SendKick(UINT8 playernum, UINT8 msg);
void NetKeepAlive(void); void NetKeepAlive(void);
void NetUpdate(void); void NetUpdate(void);
void SV_StartSinglePlayerServer(void); void SV_StartSinglePlayerServer(INT32 dogametype, boolean donetgame);
boolean SV_SpawnServer(void); boolean SV_SpawnServer(void);
void SV_StopServer(void); void SV_StopServer(void);
void SV_ResetServer(void); void SV_ResetServer(void);

View file

@ -472,9 +472,9 @@ consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_NETVAR, CV_YesNo, NULL)
consvar_t cv_rollingdemos = CVAR_INIT ("rollingdemos", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_rollingdemos = CVAR_INIT ("rollingdemos", "On", CV_SAVE, CV_OnOff, NULL);
static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, {0, "None"}, {0, NULL}}; static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, {0, "None"}, {0, NULL}};
consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange); consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange);
static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}}; static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}};
consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange); consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange);
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {MAX_LAPS, "MAX"}, {0, "Map default"}, {0, NULL}}; static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {MAX_LAPS, "MAX"}, {0, "Map default"}, {0, NULL}};
consvar_t cv_numlaps = CVAR_INIT ("numlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, numlaps_cons_t, NumLaps_OnChange); consvar_t cv_numlaps = CVAR_INIT ("numlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, numlaps_cons_t, NumLaps_OnChange);
@ -4956,26 +4956,39 @@ UINT32 timelimitintics = 0;
*/ */
static void TimeLimit_OnChange(void) static void TimeLimit_OnChange(void)
{ {
// Don't allow timelimit in Single Player/Co-Op/Race! if (K_CanChangeRules() == false)
if (server && Playing() && cv_timelimit.value != 0 && (bossinfo.boss || !(gametyperules & GTR_TIMELIMIT)))
{ {
CV_SetValue(&cv_timelimit, 0);
return; return;
} }
if (cv_timelimit.value != 0) if (gamestate == GS_LEVEL && leveltime < starttime)
{ {
CONS_Printf(M_GetText("Rounds will end after %d minute%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003 if (cv_timelimit.value)
timelimitintics = cv_timelimit.value * (60*TICRATE); {
CONS_Printf(M_GetText("Time limit has been set to %d minute%s.\n"), cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s");
// Note the deliberate absence of any code preventing
// pointlimit and timelimit from being set simultaneously.
// Some people might like to use them together. It works.
} }
else
{
CONS_Printf(M_GetText("Time limit has been disabled.\n"));
}
timelimitintics = cv_timelimit.value * (60*TICRATE);
#ifdef HAVE_DISCORDRPC #ifdef HAVE_DISCORDRPC
DRPC_UpdatePresence(); DRPC_UpdatePresence();
#endif #endif
}
else
{
if (cv_timelimit.value)
{
CONS_Printf(M_GetText("Time limit will be %d minute%s next round.\n"), cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s");
}
else
{
CONS_Printf(M_GetText("Time limit will be disabled next round.\n"));
}
}
} }
/** Adjusts certain settings to match a changed gametype. /** Adjusts certain settings to match a changed gametype.
@ -5002,7 +5015,7 @@ void D_GameTypeChanged(INT32 lastgametype)
// Only do the following as the server, not as remote admin. // Only do the following as the server, not as remote admin.
// There will always be a server, and this only needs to be done once. // There will always be a server, and this only needs to be done once.
if (server && (multiplayer || netgame)) if (server && multiplayer)
{ {
if (!cv_timelimit.changed) // user hasn't changed limits if (!cv_timelimit.changed) // user hasn't changed limits
{ {
@ -5013,27 +5026,6 @@ void D_GameTypeChanged(INT32 lastgametype)
CV_SetValue(&cv_pointlimit, pointlimits[gametype]); CV_SetValue(&cv_pointlimit, pointlimits[gametype]);
} }
} }
/* -- no longer useful
else if (!multiplayer && !netgame)
{
G_SetGametype(GT_RACE);
}
*/
// reset timelimit and pointlimit in race/coop, prevent stupid cheats
if (server)
{
if (!(gametyperules & GTR_TIMELIMIT))
{
if (cv_timelimit.value)
CV_SetValue(&cv_timelimit, 0);
}
if (!(gametyperules & GTR_POINTLIMIT))
{
if (cv_pointlimit.value)
CV_SetValue(&cv_pointlimit, 0);
}
}
// don't retain teams in other modes or between changes from ctf to team match. // don't retain teams in other modes or between changes from ctf to team match.
// also, stop any and all forms of team scrambling that might otherwise take place. // also, stop any and all forms of team scrambling that might otherwise take place.
@ -6572,7 +6564,7 @@ static void NumLaps_OnChange(void)
return; return;
} }
if (leveltime < starttime) if (gamestate == GS_LEVEL && leveltime < starttime)
{ {
CONS_Printf(M_GetText("Number of laps have been set to %d.\n"), cv_numlaps.value); CONS_Printf(M_GetText("Number of laps have been set to %d.\n"), cv_numlaps.value);
numlaps = (UINT8)cv_numlaps.value; numlaps = (UINT8)cv_numlaps.value;
@ -6590,7 +6582,7 @@ static void KartFrantic_OnChange(void)
return; return;
} }
if (leveltime < starttime) if (gamestate == GS_LEVEL && leveltime < starttime)
{ {
CONS_Printf(M_GetText("Frantic items has been set to %s.\n"), cv_kartfrantic.value ? M_GetText("on") : M_GetText("off")); CONS_Printf(M_GetText("Frantic items has been set to %s.\n"), cv_kartfrantic.value ? M_GetText("on") : M_GetText("off"));
franticitems = (boolean)cv_kartfrantic.value; franticitems = (boolean)cv_kartfrantic.value;
@ -6608,7 +6600,7 @@ static void KartSpeed_OnChange(void)
return; return;
} }
if (leveltime < starttime && cv_kartspeed.value != KARTSPEED_AUTO) if (gamestate == GS_LEVEL && leveltime < starttime && cv_kartspeed.value != KARTSPEED_AUTO)
{ {
CONS_Printf(M_GetText("Game speed has been changed to \"%s\".\n"), cv_kartspeed.string); CONS_Printf(M_GetText("Game speed has been changed to \"%s\".\n"), cv_kartspeed.string);
gamespeed = (UINT8)cv_kartspeed.value; gamespeed = (UINT8)cv_kartspeed.value;

View file

@ -4711,6 +4711,7 @@ cleanup:
void G_DeferedInitNew(boolean pencoremode, INT32 map, INT32 pickedchar, UINT8 ssplayers, boolean FLS) void G_DeferedInitNew(boolean pencoremode, INT32 map, INT32 pickedchar, UINT8 ssplayers, boolean FLS)
{ {
UINT16 color = SKINCOLOR_NONE; UINT16 color = SKINCOLOR_NONE;
INT32 dogametype;
paused = false; paused = false;
@ -4721,8 +4722,17 @@ void G_DeferedInitNew(boolean pencoremode, INT32 map, INT32 pickedchar, UINT8 ss
G_ResetRandMapBuffer(); G_ResetRandMapBuffer();
if ((modeattacking == ATTACKING_CAPSULES) || (bossinfo.boss == true))
{
dogametype = GT_BATTLE;
}
else
{
dogametype = GT_RACE;
}
// this leave the actual game if needed // this leave the actual game if needed
SV_StartSinglePlayerServer(); SV_StartSinglePlayerServer(dogametype, false);
if (splitscreen != ssplayers) if (splitscreen != ssplayers)
{ {

View file

@ -2416,7 +2416,7 @@ static void HU_DrawRankings(void)
if ((gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT)) && !bossinfo.boss) if ((gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT)) && !bossinfo.boss)
{ {
if ((gametyperules & GTR_TIMELIMIT) && cv_timelimit.value && timelimitintics > 0) if ((gametyperules & GTR_TIMELIMIT) && timelimitintics > 0)
{ {
UINT32 timeval = (timelimitintics + starttime + 1 - leveltime); UINT32 timeval = (timelimitintics + starttime + 1 - leveltime);
if (timeval > timelimitintics+1) if (timeval > timelimitintics+1)

View file

@ -3449,9 +3449,7 @@ void M_CupSelectHandler(INT32 choice)
// Don't restart the server if we're already in a game lol // Don't restart the server if we're already in a game lol
if (gamestate == GS_MENU) if (gamestate == GS_MENU)
{ {
SV_StartSinglePlayerServer(); SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this...
netgame = levellist.netgame; // ^ ditto.
} }
levelNum = grandprixinfo.cup->cachedlevels[0]; levelNum = grandprixinfo.cup->cachedlevels[0];
@ -3606,9 +3604,7 @@ void M_LevelSelectHandler(INT32 choice)
F_WipeEndScreen(); F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false); F_RunWipe(wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false);
SV_StartSinglePlayerServer(); SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this...
netgame = levellist.netgame; // ^ ditto.
CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string); CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string);
CV_StealthSet(&cv_kartencore, (cv_dummygpencore.value == 1) ? "On" : "Auto"); CV_StealthSet(&cv_kartencore, (cv_dummygpencore.value == 1) ? "On" : "Auto");
@ -3707,7 +3703,7 @@ void M_StartTimeAttack(INT32 choice)
F_WipeEndScreen(); F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false); F_RunWipe(wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false);
SV_StartSinglePlayerServer(); SV_StartSinglePlayerServer(levellist.newgametype, false);
gpath = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s", gpath = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s",
srb2home, timeattackfolder); srb2home, timeattackfolder);

View file

@ -205,7 +205,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushinteger(L, redscore); lua_pushinteger(L, redscore);
return 1; return 1;
} else if (fastcmp(word,"timelimit")) { } else if (fastcmp(word,"timelimit")) {
lua_pushinteger(L, cv_timelimit.value); lua_pushinteger(L, timelimitintics);
return 1; return 1;
} else if (fastcmp(word,"pointlimit")) { } else if (fastcmp(word,"pointlimit")) {
lua_pushinteger(L, cv_pointlimit.value); lua_pushinteger(L, cv_pointlimit.value);

View file

@ -596,8 +596,6 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost)
/** Checks if the level timer is over the timelimit and the round should end, /** Checks if the level timer is over the timelimit and the round should end,
* unless you are in overtime. In which case leveltime may stretch out beyond * unless you are in overtime. In which case leveltime may stretch out beyond
* timelimitintics and overtime's status will be checked here each tick. * timelimitintics and overtime's status will be checked here each tick.
* Verify that the value of ::cv_timelimit is greater than zero before
* calling this function.
* *
* \sa cv_timelimit, P_CheckPointLimit, P_UpdateSpecials * \sa cv_timelimit, P_CheckPointLimit, P_UpdateSpecials
*/ */
@ -605,11 +603,11 @@ void P_CheckTimeLimit(void)
{ {
INT32 i; INT32 i;
if (!cv_timelimit.value) if (!timelimitintics)
return; return;
#ifndef TESTOVERTIMEINFREEPLAY #ifndef TESTOVERTIMEINFREEPLAY
if (battlecapsules) // capsules override any time limit settings if (battlecapsules && (grandprixinfo.gp == false))
return; return;
#endif #endif
@ -625,7 +623,7 @@ void P_CheckTimeLimit(void)
if (gameaction == ga_completed) if (gameaction == ga_completed)
return; return;
if ((cv_overtime.value) && (gametyperules & GTR_OVERTIME)) if ((grandprixinfo.gp == false) && (cv_overtime.value) && (gametyperules & GTR_OVERTIME))
{ {
#ifndef TESTOVERTIMEINFREEPLAY #ifndef TESTOVERTIMEINFREEPLAY
boolean foundone = false; // Overtime is used for closing off down to a specific item. boolean foundone = false; // Overtime is used for closing off down to a specific item.
@ -700,8 +698,6 @@ void P_CheckTimeLimit(void)
} }
/** Checks if a player's score is over the pointlimit and the round should end. /** Checks if a player's score is over the pointlimit and the round should end.
* Verify that the value of ::cv_pointlimit is greater than zero before
* calling this function.
* *
* \sa cv_pointlimit, P_CheckTimeLimit, P_UpdateSpecials * \sa cv_pointlimit, P_CheckTimeLimit, P_UpdateSpecials
*/ */

View file

@ -3867,6 +3867,22 @@ static void P_InitGametype(void)
} }
} }
if ((gametyperules & GTR_TIMELIMIT) && !bossinfo.boss)
{
if (K_CanChangeRules() == false)
{
timelimitintics = timelimits[gametype] * (60*TICRATE);
}
else
{
timelimitintics = cv_timelimit.value * (60*TICRATE);
}
}
else
{
timelimitintics = 0;
}
wantedcalcdelay = wantedfrequency*2; wantedcalcdelay = wantedfrequency*2;
for (i = 0; i < NUMKARTITEMS-1; i++) for (i = 0; i < NUMKARTITEMS-1; i++)