From 685868edf50ff1ba3b2305d220d14984e2bb45e4 Mon Sep 17 00:00:00 2001 From: SinnamonLat Date: Fri, 19 Nov 2021 22:08:17 +0100 Subject: [PATCH] Pause: Player setup --- src/d_netcmd.c | 33 +++++++++++++++-- src/k_menudef.c | 2 +- src/k_menufunc.c | 93 ++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 118 insertions(+), 10 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 822435042..10e580d09 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5415,7 +5415,7 @@ static void Followercolor4_OnChange(void) } } -/** Sends a skin change for the console player, unless that player is moving. +/** Sends a skin change for the console player, unless that player is moving. Also forces them to spectate if the change is done during gameplay * \sa cv_skin, Skin2_OnChange, Color_OnChange * \author Graue */ @@ -5432,7 +5432,23 @@ static void Skin_OnChange(void) } if (CanChangeSkin(consoleplayer) && !P_PlayerMoving(consoleplayer)) + { + UINT8 i; + SendNameAndColor(0); + // check to see if there's anyone else at all + // even if we're playing splitscreen, if it ain't free play it spectates us if it can. + if (G_GametypeHasSpectators() && !players[consoleplayer].spectator) // Make sure we CAN spectate. + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (i == consoleplayer) + continue; + if (playeringame[i] && !players[i].spectator && gamestate == GS_LEVEL) + COM_ImmedExecute("changeteam spectator"); + } + } + } else { CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); @@ -5441,7 +5457,7 @@ static void Skin_OnChange(void) } /** Sends a skin change for the secondary splitscreen player, unless that - * player is moving. + * player is moving. Forces spectate the player if the change is done during gameplay. * \sa cv_skin2, Skin_OnChange, Color2_OnChange * \author Graue */ @@ -5451,7 +5467,12 @@ static void Skin2_OnChange(void) return; // do whatever you want if (CanChangeSkin(g_localplayers[1]) && !P_PlayerMoving(g_localplayers[1])) + { SendNameAndColor(1); + // With how we handle splitscreen, only check for gamestate here. + if (gamestate == GS_LEVEL && G_GametypeHasSpectators() && !players[g_localplayers[1]].spectator) + COM_ImmedExecute("changeteam2 spectator"); + } else { CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); @@ -5465,7 +5486,11 @@ static void Skin3_OnChange(void) return; // do whatever you want if (CanChangeSkin(g_localplayers[2]) && !P_PlayerMoving(g_localplayers[2])) + { SendNameAndColor(2); + if (gamestate == GS_LEVEL && G_GametypeHasSpectators() && !players[g_localplayers[2]].spectator) + COM_ImmedExecute("changeteam3 spectator"); + } else { CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); @@ -5479,7 +5504,11 @@ static void Skin4_OnChange(void) return; // do whatever you want if (CanChangeSkin(g_localplayers[3]) && !P_PlayerMoving(g_localplayers[3])) + { SendNameAndColor(3); + if (gamestate == GS_LEVEL && G_GametypeHasSpectators() && !players[g_localplayers[3]].spectator) + COM_ImmedExecute("changeteam4 spectator"); + } else { CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n")); diff --git a/src/k_menudef.c b/src/k_menudef.c index ee9213bb7..55beeac82 100644 --- a/src/k_menudef.c +++ b/src/k_menudef.c @@ -329,7 +329,7 @@ menuitem_t PAUSE_Main[] = NULL, NULL, 0, 0}, {IT_STRING | IT_CALL, "PLAYER SETUP", "M_ICOCHR", - NULL, NULL, 0, 0}, + NULL, M_CharacterSelectInit, 0, 0}, {IT_STRING | IT_CALL, "OPTIONS", "M_ICOOPT", NULL, NULL, 0, 0}, diff --git a/src/k_menufunc.c b/src/k_menufunc.c index 2f1943081..c9c085a32 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -1870,6 +1870,8 @@ void M_QuitSRB2(INT32 choice) // ========= // Character Select! +// @TODO: Splitscreen handling when profiles are added into the game. ...I probably won't be the one to handle this however. -Lat' + struct setup_chargrid_s setup_chargrid[9][9]; setup_player_t setup_player[MAXSPLITSCREENPLAYERS]; struct setup_explosions_s setup_explosions[48]; @@ -1921,6 +1923,7 @@ void M_CharacterSelectInit(INT32 choice) } } + PLAY_CharSelectDef.prevMenu = currentMenu; M_SetupNextMenu(&PLAY_CharSelectDef, false); } @@ -2172,6 +2175,48 @@ void M_CharacterSelectHandler(INT32 choice) } } +// Apply character skin and colour changes while ingame (we just call the skin / color commands.) +// ...Will this cause command buffer issues? -Lat' +static void M_MPConfirmCharacterSelection(void) +{ + UINT8 i; + INT16 col; + + char colstr[8]; + char commandnames[][2][MAXSTRINGLENGTH] = { {"skin ", "color "}, {"skin2 ", "color2 "}, {"skin3 ", "color3 "}, {"skin4 ", "color4 "}}; + // ^ laziness 100 (we append a space directly so that we don't have to do it later too!!!!) + + for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) + { + char cmd[MAXSTRINGLENGTH]; + + // skin + strcpy(cmd, commandnames[i][0]); + strcat(cmd, skins[setup_player[i].skin].name); + + COM_ImmedExecute(cmd); + + // colour + // (convert the number that's saved to a string we can use) + col = setup_player[i].color; + itoa(col, colstr, 10); + strcpy(cmd, commandnames[i][1]); + strcat(cmd, colstr); + + COM_ImmedExecute(cmd); + } + + M_ClearMenus(true); +} + +static void M_MPConfirmCharacterResponse(INT32 ch) +{ + if (ch == 'y' || ch == KEY_ENTER) + M_MPConfirmCharacterSelection(); + + M_ClearMenus(true); +} + void M_CharacterSelectTick(void) { UINT8 i; @@ -2207,14 +2252,48 @@ void M_CharacterSelectTick(void) if (setupnext) { - for (i = 0; i < setup_numplayers; i++) - { - CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin].name); - CV_StealthSetValue(&cv_playercolor[i], setup_player[i].color); - } - CV_StealthSetValue(&cv_splitplayers, setup_numplayers); - M_SetupNextMenu(&PLAY_MainDef, false); + // Selecting from the menu + if (gamestate == GS_MENU) + { + for (i = 0; i < setup_numplayers; i++) + { + CV_StealthSet(&cv_skin[i], skins[setup_player[i].skin].name); + CV_StealthSetValue(&cv_playercolor[i], setup_player[i].color); + } + + CV_StealthSetValue(&cv_splitplayers, setup_numplayers); + M_SetupNextMenu(&PLAY_MainDef, false); + } + else // In a game + { + // In the midst of a game, + // 1: warn players that confirming will force-spectate them until next round + // ^ This doesn't apply in FREEPLAY + + // 2: Call the "skin" and "color" commands for all local players. + // This command will force change team to spectate under the proper circumstances. (see d_clisrv.c) + UINT8 j; + + // check to see if there's anyone else at all + if (G_GametypeHasSpectators()) // Make sure we CAN spectate. + { + for (j = 0; j < MAXPLAYERS; j++) + { + if (j == displayplayers[0]) + continue; + if (playeringame[j] && !players[consoleplayer].spectator) + { + // Warn the player! + M_StartMessage(M_GetText("Any player who has changed skin will\nautomatically spectate. Proceed?\n(Press 'Y' to confirm)\n"), M_MPConfirmCharacterResponse, MM_YESNO); + return; + } + } + } + + // If we made it here then we're in freeplay or something and we can switch for free! + M_MPConfirmCharacterSelection(); + } } }