diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 5cad5e080..417fbade4 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -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) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 354e62486..eb11ca04a 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -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); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ed1bea371..344c6380b 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -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; diff --git a/src/g_game.c b/src/g_game.c index 50834509b..a1f76a2ea 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -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) { diff --git a/src/hu_stuff.c b/src/hu_stuff.c index e02e3ed67..63d093ae1 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -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) diff --git a/src/k_menufunc.c b/src/k_menufunc.c index 1f015a907..25e61c5e3 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -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); diff --git a/src/lua_script.c b/src/lua_script.c index eaacbf145..4fcd7dd00 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -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); diff --git a/src/p_inter.c b/src/p_inter.c index b7e26d63a..fd13e38f7 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -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 */ diff --git a/src/p_setup.c b/src/p_setup.c index cc4f06ece..49deb7cf4 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -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++)