diff --git a/src/k_menu.h b/src/k_menu.h index 33d63b52a..b16edd416 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -199,6 +199,25 @@ extern menu_t PLAY_BattleGamemodesDef; extern menuitem_t PAUSE_Main[]; extern menu_t PAUSE_MainDef; +// We'll need this since we're gonna have to dynamically enable and disable options depending on which state we're in. +typedef enum +{ + mpause_addons = 0, + mpause_switchmap, +#ifdef HAVE_DISCORDRPC + mpause_discordrequests, +#endif + + mpause_continue, + mpause_spectate, + mpause_entergame, + mpause_canceljoin, + mpause_psetup, + mpause_options, + + mpause_title, +} mpause_e; + extern menuitem_t PAUSE_GamemodesMenu[]; extern menu_t PAUSE_GamemodesDef; @@ -422,10 +441,15 @@ extern struct pausemenu_s { void M_OpenPauseMenu(void); void M_QuitPauseMenu(void); - boolean M_PauseInputs(INT32 ch); void M_PauseTick(void); +// Bunch of funny functions for the pause menu...~ +void M_ConfirmSpectate(INT32 choice); // Spectate confirm when you're alone +void M_ConfirmEnterGame(INT32 choice); // Enter game confirm when you're alone +void M_ConfirmSpectateChange(INT32 choice); // Splitscreen spectate/play menu func +void M_EndGame(INT32 choice); // Quitting to title + // Replay Playback extern tic_t playback_last_menu_interaction_leveltime; diff --git a/src/k_menudef.c b/src/k_menudef.c index f1ff28350..d80e74760 100644 --- a/src/k_menudef.c +++ b/src/k_menudef.c @@ -317,13 +317,13 @@ menuitem_t PAUSE_Main[] = NULL, M_QuitPauseMenu, 0, 0}, {IT_STRING | IT_CALL, "SPECTATE", "M_ICOSPC", - NULL, NULL, 0, 0}, + NULL, M_ConfirmSpectate, 0, 0}, {IT_STRING | IT_CALL, "ENTER GAME", "M_ICOENT", - NULL, NULL, 0, 0}, + NULL, M_ConfirmEnterGame, 0, 0}, {IT_STRING | IT_CALL, "CANCEL JOIN", "M_ICOSPC", - NULL, NULL, 0, 0}, + NULL, M_ConfirmSpectate, 0, 0}, {IT_STRING | IT_CALL, "PLAYER SETUP", "M_ICOCHR", NULL, NULL, 0, 0}, @@ -332,29 +332,9 @@ menuitem_t PAUSE_Main[] = NULL, NULL, 0, 0}, {IT_STRING | IT_CALL, "EXIT GAME", "M_ICOEXT", - NULL, NULL, 0, 0}, + NULL, M_EndGame, 0, 0}, }; -// We'll need this since we're gonna have to dynamically enable and disable options depending on which state we're in. -typedef enum -{ - mpause_addons = 0, - mpause_switchmap, -#ifdef HAVE_DISCORDRPC - mpause_discordrequests, -#endif - - mpause_continue, - mpause_spectate, - mpause_entergame, - mpause_canceljoin, - mpause_psetup, - mpause_options, - - mpause_title, -} mpause_e; - - menu_t PAUSE_MainDef = { sizeof (PAUSE_Main) / sizeof (menuitem_t), NULL, diff --git a/src/k_menudraw.c b/src/k_menudraw.c index fb0653459..c2de58df2 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -1632,10 +1632,17 @@ void M_DrawPause(void) // Which means... let's count down from itemOn for (i = itemOn; countdown < 3; countdown++) { - //CONS_Printf("pass %d: %d\n", countdown, i); i--; if (i < 0) i = currentMenu->numitems-1; + + while (currentMenu->menuitems[i].status == IT_DISABLED) + { + i--; + + if (i < 0) + i = currentMenu->numitems-1; + } } // Aaaaand now we can start drawing! @@ -1690,7 +1697,12 @@ void M_DrawPause(void) i++; // Regardless of whether we drew or not, go to the next item in the menu. if (i > currentMenu->numitems) + { i = 0; + while (!(currentMenu->menuitems[i].status & IT_DISPLAY)) + i++; + + } } // Draw the string! diff --git a/src/k_menufunc.c b/src/k_menufunc.c index 458bfd441..6a1788974 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -2577,39 +2577,39 @@ void M_LevelSelectHandler(INT32 choice) } else { - UINT8 ssplayers = cv_splitplayers.value-1; - - netgame = false; - multiplayer = true; - - strncpy(connectedservername, cv_servername.string, MAXSERVERNAME); - - // Still need to reset devmode - cv_debug = 0; - - if (demo.playback) - G_StopDemo(); - if (metalrecording) - G_StopMetalDemo(); - - /*if (levellist.choosemap == 0) - levellist.choosemap = G_RandMap(G_TOLFlag(levellist.newgametype), -1, false, 0, false, NULL);*/ - - if (cv_maxplayers.value < ssplayers+1) - CV_SetValue(&cv_maxplayers, ssplayers+1); - - if (splitscreen != ssplayers) + if (gamestate == GS_MENU) { - splitscreen = ssplayers; - SplitScreen_OnChange(); - } + UINT8 ssplayers = cv_splitplayers.value-1; - S_StartSound(NULL, sfx_s3k63); + netgame = false; + multiplayer = true; - paused = false; + strncpy(connectedservername, cv_servername.string, MAXSERVERNAME); + + // Still need to reset devmode + cv_debug = 0; + + if (demo.playback) + G_StopDemo(); + if (metalrecording) + G_StopMetalDemo(); + + /*if (levellist.choosemap == 0) + levellist.choosemap = G_RandMap(G_TOLFlag(levellist.newgametype), -1, false, 0, false, NULL);*/ + + if (cv_maxplayers.value < ssplayers+1) + CV_SetValue(&cv_maxplayers, ssplayers+1); + + if (splitscreen != ssplayers) + { + splitscreen = ssplayers; + SplitScreen_OnChange(); + } + + S_StartSound(NULL, sfx_s3k63); + + paused = false; - if (gamestate == GS_MENU) // Don't restart the server if we're already in a game lol. Don't fade out either. - { // Early fadeout to let the sound finish playing F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); @@ -2877,6 +2877,7 @@ struct pausemenu_s pausemenu; // Pause menu! void M_OpenPauseMenu(void) { + boolean singleplayermode = (modeattacking || grandprixinfo.gp); currentMenu = &PAUSE_MainDef; // Ready the variables @@ -2885,6 +2886,45 @@ void M_OpenPauseMenu(void) pausemenu.offset = 0; pausemenu.openoffset = 256; pausemenu.closing = false; + + itemOn = mpause_continue; // Make sure we select "RESUME GAME" by default + + + // Now the hilarious balancing act of deciding what options should be enabled and which ones shouldn't be! + // By default, disable anything sensitive: + + PAUSE_Main[mpause_addons].status = IT_DISABLED; + PAUSE_Main[mpause_switchmap].status = IT_DISABLED; +#ifdef HAVE_DISCORDRPC + PAUSE_Main[mpause_discordrequests].status = IT_DISABLED; +#endif + + PAUSE_Main[mpause_spectate].status = IT_DISABLED; + PAUSE_Main[mpause_entergame].status = IT_DISABLED; + PAUSE_Main[mpause_canceljoin].status = IT_DISABLED; + PAUSE_Main[mpause_psetup].status = IT_DISABLED; + + if (!singleplayermode && (server || IsPlayerAdmin(consoleplayer))) + { + PAUSE_Main[mpause_switchmap].status = IT_STRING | IT_SUBMENU; + PAUSE_Main[mpause_addons].status = IT_STRING | IT_CALL; + } + + if (!singleplayermode) + PAUSE_Main[mpause_psetup].status = IT_STRING | IT_CALL; + + if (G_GametypeHasSpectators()) + { + if (!players[consoleplayer].spectator) + PAUSE_Main[mpause_spectate].status = IT_STRING | IT_CALL; + else if (players[consoleplayer].pflags & PF_WANTSTOJOIN) + PAUSE_Main[mpause_canceljoin].status = IT_STRING | IT_CALL; + else + PAUSE_Main[mpause_entergame].status = IT_STRING | IT_CALL; + } + + + } void M_QuitPauseMenu(void) @@ -2943,6 +2983,49 @@ boolean M_PauseInputs(INT32 ch) return false; } +// Pause spectate / join functions +void M_ConfirmSpectate(INT32 choice) +{ + (void)choice; + // We allow switching to spectator even if team changing is not allowed + M_QuitPauseMenu(); + COM_ImmedExecute("changeteam spectator"); +} + +void M_ConfirmEnterGame(INT32 choice) +{ + (void)choice; + if (!cv_allowteamchange.value) + { + M_StartMessage(M_GetText("The server is not allowing\nteam changes at this time.\nPress a key.\n"), NULL, MM_NOTHING); + return; + } + M_QuitPauseMenu(); + COM_ImmedExecute("changeteam playing"); +} + +static void M_ExitGameResponse(INT32 ch) +{ + if (ch != 'y' && ch != KEY_ENTER) + return; + + //Command_ExitGame_f(); + G_SetExitGameFlag(); + M_ClearMenus(true); +} + +void M_EndGame(INT32 choice) +{ + (void)choice; + if (demo.playback) + return; + + if (!Playing()) + return; + + M_StartMessage(M_GetText("Are you sure you want to return\nto the title screen?\n(Press 'Y' to confirm)\n"), M_ExitGameResponse, MM_YESNO); +} + // Replay Playback Menu void M_SetPlaybackMenuPointer(void)