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
void SV_StartSinglePlayerServer(void)
void SV_StartSinglePlayerServer(INT32 dogametype, boolean donetgame)
{
INT32 lastgametype = gametype;
server = true;
netgame = false;
multiplayer = false;
multiplayer = (modeattacking == ATTACKING_NONE);
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))
{
G_SetGametype(GT_BATTLE);
}
else
{
G_SetGametype(GT_RACE);
}
netgame = false; // so setting timelimit works... (XD_NETVAR doesn't play nice with SV_StopServer)
G_SetGametype(dogametype);
if (gametype != lastgametype)
D_GameTypeChanged(lastgametype);
netgame = donetgame;
// no more tic the game with this settings!
SV_StopServer();
if (splitscreen)
multiplayer = true;
}
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 NetUpdate(void);
void SV_StartSinglePlayerServer(void);
void SV_StartSinglePlayerServer(INT32 dogametype, boolean donetgame);
boolean SV_SpawnServer(void);
void SV_StopServer(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);
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}};
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}};
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)
{
// Don't allow timelimit in Single Player/Co-Op/Race!
if (server && Playing() && cv_timelimit.value != 0 && (bossinfo.boss || !(gametyperules & GTR_TIMELIMIT)))
if (K_CanChangeRules() == false)
{
CV_SetValue(&cv_timelimit, 0);
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)
{
CONS_Printf(M_GetText("Time limit has been set to %d minute%s.\n"), cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s");
}
else
{
CONS_Printf(M_GetText("Time limit has been disabled.\n"));
}
timelimitintics = cv_timelimit.value * (60*TICRATE);
// 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.
}
#ifdef HAVE_DISCORDRPC
DRPC_UpdatePresence();
DRPC_UpdatePresence();
#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.
@ -5002,7 +5015,7 @@ void D_GameTypeChanged(INT32 lastgametype)
// 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.
if (server && (multiplayer || netgame))
if (server && multiplayer)
{
if (!cv_timelimit.changed) // user hasn't changed limits
{
@ -5013,27 +5026,6 @@ void D_GameTypeChanged(INT32 lastgametype)
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.
// also, stop any and all forms of team scrambling that might otherwise take place.
@ -6572,7 +6564,7 @@ static void NumLaps_OnChange(void)
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);
numlaps = (UINT8)cv_numlaps.value;
@ -6590,7 +6582,7 @@ static void KartFrantic_OnChange(void)
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"));
franticitems = (boolean)cv_kartfrantic.value;
@ -6608,7 +6600,7 @@ static void KartSpeed_OnChange(void)
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);
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)
{
UINT16 color = SKINCOLOR_NONE;
INT32 dogametype;
paused = false;
@ -4721,8 +4722,17 @@ void G_DeferedInitNew(boolean pencoremode, INT32 map, INT32 pickedchar, UINT8 ss
G_ResetRandMapBuffer();
if ((modeattacking == ATTACKING_CAPSULES) || (bossinfo.boss == true))
{
dogametype = GT_BATTLE;
}
else
{
dogametype = GT_RACE;
}
// this leave the actual game if needed
SV_StartSinglePlayerServer();
SV_StartSinglePlayerServer(dogametype, false);
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) && cv_timelimit.value && timelimitintics > 0)
if ((gametyperules & GTR_TIMELIMIT) && timelimitintics > 0)
{
UINT32 timeval = (timelimitintics + starttime + 1 - leveltime);
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
if (gamestate == GS_MENU)
{
SV_StartSinglePlayerServer();
multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this...
netgame = levellist.netgame; // ^ ditto.
SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
}
levelNum = grandprixinfo.cup->cachedlevels[0];
@ -3606,9 +3604,7 @@ void M_LevelSelectHandler(INT32 choice)
F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false);
SV_StartSinglePlayerServer();
multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this...
netgame = levellist.netgame; // ^ ditto.
SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string);
CV_StealthSet(&cv_kartencore, (cv_dummygpencore.value == 1) ? "On" : "Auto");
@ -3707,7 +3703,7 @@ void M_StartTimeAttack(INT32 choice)
F_WipeEndScreen();
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",
srb2home, timeattackfolder);

View file

@ -205,7 +205,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushinteger(L, redscore);
return 1;
} else if (fastcmp(word,"timelimit")) {
lua_pushinteger(L, cv_timelimit.value);
lua_pushinteger(L, timelimitintics);
return 1;
} else if (fastcmp(word,"pointlimit")) {
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,
* unless you are in overtime. In which case leveltime may stretch out beyond
* 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
*/
@ -605,11 +603,11 @@ void P_CheckTimeLimit(void)
{
INT32 i;
if (!cv_timelimit.value)
if (!timelimitintics)
return;
#ifndef TESTOVERTIMEINFREEPLAY
if (battlecapsules) // capsules override any time limit settings
if (battlecapsules && (grandprixinfo.gp == false))
return;
#endif
@ -625,7 +623,7 @@ void P_CheckTimeLimit(void)
if (gameaction == ga_completed)
return;
if ((cv_overtime.value) && (gametyperules & GTR_OVERTIME))
if ((grandprixinfo.gp == false) && (cv_overtime.value) && (gametyperules & GTR_OVERTIME))
{
#ifndef TESTOVERTIMEINFREEPLAY
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.
* Verify that the value of ::cv_pointlimit is greater than zero before
* calling this function.
*
* \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;
for (i = 0; i < NUMKARTITEMS-1; i++)