pause menu: spectate + exit game

This commit is contained in:
SinnamonLat 2021-11-18 20:47:52 +01:00
parent e560bffcf7
commit 55b9489af0
4 changed files with 154 additions and 55 deletions

View file

@ -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;

View file

@ -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,

View file

@ -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!

View file

@ -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)