mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-07 07:22:54 +00:00
Merge branch 'splitscreen-spectate-switch' into 'master'
Splitscreen Spectate Switch (resolves #981) Closes #981 See merge request KartKrew/Kart!1964
This commit is contained in:
commit
762a029dd9
5 changed files with 222 additions and 67 deletions
|
|
@ -3708,11 +3708,15 @@ static void Got_Teamchange(const UINT8 **cp, INT32 playernum)
|
|||
//Now that we've done our error checking and killed the player
|
||||
//if necessary, put the player on the correct team/status.
|
||||
|
||||
// This serves us in both teamchange contexts.
|
||||
if (NetPacket.packet.newteam != 0)
|
||||
{
|
||||
// This serves us in both teamchange contexts.
|
||||
players[playernum].pflags |= PF_WANTSTOJOIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
players[playernum].pflags &= ~PF_WANTSTOJOIN;
|
||||
}
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
|
|
|
|||
11
src/k_menu.h
11
src/k_menu.h
|
|
@ -497,10 +497,7 @@ typedef enum
|
|||
mpause_tryagain,
|
||||
|
||||
mpause_continue,
|
||||
mpause_spectate,
|
||||
mpause_entergame,
|
||||
mpause_canceljoin,
|
||||
mpause_spectatemenu,
|
||||
mpause_spectatetoggle,
|
||||
mpause_psetup,
|
||||
mpause_cheats,
|
||||
mpause_options,
|
||||
|
|
@ -1151,6 +1148,8 @@ extern struct pausemenu_s {
|
|||
|
||||
menu_anim_t openoffset; // Used when you open / close the menu to slide everything in.
|
||||
boolean closing; // When this is set, the open offset goes backwards to close the menu smoothly.
|
||||
|
||||
UINT8 splitscreenfocusid; // This is not exclusively visual, but thog dont care. For selecting splitscreen players to individually change their spectator state.
|
||||
} pausemenu;
|
||||
|
||||
void M_OpenPauseMenu(void);
|
||||
|
|
@ -1174,9 +1173,7 @@ extern consvar_t cv_dummyspectator;
|
|||
void M_RestartMap(INT32 choice); // Restart level (MP)
|
||||
void M_TryAgain(INT32 choice); // Try again (SP)
|
||||
void M_GiveUp(INT32 choice); // Give up (SP)
|
||||
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_HandleSpectateToggle(INT32 choice); // Spectate confirm
|
||||
void M_EndGame(INT32 choice); // Quitting to title
|
||||
|
||||
// Replay Playback
|
||||
|
|
|
|||
|
|
@ -5528,6 +5528,24 @@ void M_DrawPause(void)
|
|||
|
||||
fixed_t t = M_DueFrac(pausemenu.offset.start, 3);
|
||||
|
||||
UINT8 splitspectatestate = 0;
|
||||
if (G_GametypeHasSpectators() && pausemenu.splitscreenfocusid <= splitscreen)
|
||||
{
|
||||
// Identify relevant spectator state of pausemenu.splitscreenfocusid.
|
||||
// See also M_HandleSpectatorToggle.
|
||||
|
||||
const UINT8 splitspecid =
|
||||
g_localplayers[pausemenu.splitscreenfocusid];
|
||||
|
||||
if (players[splitspecid].spectator)
|
||||
{
|
||||
splitspectatestate =
|
||||
(players[splitspecid].pflags & PF_WANTSTOJOIN)
|
||||
? UINT8_MAX
|
||||
: 1;
|
||||
}
|
||||
}
|
||||
|
||||
//V_DrawFadeScreen(0xFF00, 16);
|
||||
|
||||
{
|
||||
|
|
@ -5630,7 +5648,6 @@ void M_DrawPause(void)
|
|||
|
||||
while (itemsdrawn < 7)
|
||||
{
|
||||
|
||||
switch (currentMenu->menuitems[i].status & IT_DISPLAY)
|
||||
{
|
||||
case IT_STRING:
|
||||
|
|
@ -5644,6 +5661,17 @@ void M_DrawPause(void)
|
|||
va("M_ICOR2%c", ('A'+(pausemenu.ticker & 1))),
|
||||
PU_CACHE);
|
||||
}
|
||||
else if (i == mpause_spectatetoggle)
|
||||
{
|
||||
pp = W_CachePatchName(
|
||||
((splitspectatestate == 1)
|
||||
? "M_ICOENT"
|
||||
: "M_ICOSPC"
|
||||
), PU_CACHE
|
||||
);
|
||||
if (i == itemOn)
|
||||
colormap = yellowmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
pp = W_CachePatchName(currentMenu->menuitems[i].tooltip, PU_CACHE);
|
||||
|
|
@ -5668,29 +5696,30 @@ 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!
|
||||
|
||||
const char *maintext = NULL;
|
||||
const char *selectableheadertext = NULL;
|
||||
const char *selectabletext = NULL;
|
||||
INT32 mainflags = V_YELLOWMAP, selectableflags = 0;
|
||||
INT32 mainflags = 0, selectableflags = 0;
|
||||
|
||||
if (itemOn == mpause_changegametype)
|
||||
{
|
||||
selectableheadertext = currentMenu->menuitems[itemOn].text;
|
||||
selectabletext = gametypes[menugametype]->name;
|
||||
}
|
||||
else if (itemOn == mpause_callvote)
|
||||
{
|
||||
selectableheadertext = currentMenu->menuitems[itemOn].text;
|
||||
selectabletext = K_GetMidVoteLabel(menucallvote);
|
||||
|
||||
if (K_MinimalCheckNewMidVote(menucallvote) == false)
|
||||
|
|
@ -5714,22 +5743,57 @@ void M_DrawPause(void)
|
|||
}
|
||||
|
||||
if (maintext != NULL)
|
||||
{
|
||||
mainflags |= V_YELLOWMAP;
|
||||
selectableflags |= V_MODULATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (itemOn == mpause_spectatetoggle)
|
||||
{
|
||||
const char *spectatetext = NULL;
|
||||
INT32 spectateflags = 0;
|
||||
|
||||
if (splitspectatestate == 0)
|
||||
spectatetext = "SPECTATE";
|
||||
else if (splitspectatestate == 1)
|
||||
{
|
||||
spectatetext = "ENTER GAME";
|
||||
|
||||
if (!cv_allowteamchange.value)
|
||||
{
|
||||
spectateflags |= V_MODULATE;
|
||||
}
|
||||
}
|
||||
else
|
||||
spectatetext = "CANCEL JOIN";
|
||||
|
||||
if (splitscreen)
|
||||
{
|
||||
selectableheadertext = spectatetext;
|
||||
selectabletext = va("PLAYER %c", 'A' + pausemenu.splitscreenfocusid);
|
||||
selectableflags |= spectateflags;
|
||||
}
|
||||
else
|
||||
{
|
||||
maintext = spectatetext;
|
||||
mainflags |= spectateflags;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
maintext = currentMenu->menuitems[itemOn].text;
|
||||
mainflags = 0;
|
||||
}
|
||||
|
||||
if (selectableheadertext != NULL)
|
||||
{
|
||||
// For selections, show the full menu text on top.
|
||||
V_DrawCenteredLSTitleHighString(220 + offset*2, 75, selectableflags, selectableheadertext);
|
||||
}
|
||||
|
||||
if (selectabletext != NULL)
|
||||
{
|
||||
// We have a selection. Let's show the full menu text on top, and the choice below.
|
||||
|
||||
if (currentMenu->menuitems[itemOn].text)
|
||||
V_DrawCenteredLSTitleHighString(220 + offset*2, 75, selectableflags, currentMenu->menuitems[itemOn].text);
|
||||
|
||||
// The selectable text is shown below.
|
||||
selectableflags |= V_YELLOWMAP;
|
||||
|
||||
INT32 w = V_LSTitleLowStringWidth(selectabletext, selectableflags)/2;
|
||||
|
|
|
|||
|
|
@ -385,19 +385,63 @@ boolean M_Responder(event_t *ev)
|
|||
}
|
||||
#endif
|
||||
|
||||
// Attack modes quick-restart
|
||||
if (CON_Ready() == false && modeattacking && G_PlayerInputDown(0, gc_y, splitscreen + 1) == true)
|
||||
if (CON_Ready() == false)
|
||||
{
|
||||
M_TryAgain(0);
|
||||
return true;
|
||||
}
|
||||
boolean allowmpause = true;
|
||||
|
||||
if (CON_Ready() == false && G_PlayerInputDown(0, gc_start, splitscreen + 1) == true)
|
||||
{
|
||||
if (!chat_on)
|
||||
// Special mid-game input behaviours
|
||||
if (Playing() && !demo.playback)
|
||||
{
|
||||
M_StartControlPanel();
|
||||
return true;
|
||||
// Quick Retry (Y in modeattacking)
|
||||
if (modeattacking && G_PlayerInputDown(0, gc_y, splitscreen + 1) == true)
|
||||
{
|
||||
M_TryAgain(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Quick Spectate (L+R+A+Start online)
|
||||
if (G_GametypeHasSpectators())
|
||||
{
|
||||
UINT8 workingpid = 0;
|
||||
for (workingpid = 0; workingpid <= splitscreen; workingpid++)
|
||||
{
|
||||
if (players[g_localplayers[workingpid]].spectator == true)
|
||||
continue;
|
||||
|
||||
if (G_PlayerInputDown(workingpid, gc_l, 0) == false)
|
||||
continue;
|
||||
if (G_PlayerInputDown(workingpid, gc_r, 0) == false)
|
||||
continue;
|
||||
if (G_PlayerInputDown(workingpid, gc_a, 0) == false)
|
||||
continue;
|
||||
if (G_PlayerInputDown(workingpid, gc_start, 0) == false)
|
||||
continue;
|
||||
|
||||
if (workingpid == 0)
|
||||
{
|
||||
allowmpause = false;
|
||||
COM_ImmedExecute("changeteam spectator");
|
||||
continue;
|
||||
}
|
||||
|
||||
COM_ImmedExecute(
|
||||
va(
|
||||
"changeteam%u spectator",
|
||||
workingpid + 1
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bog-standard Pause
|
||||
if (allowmpause && G_PlayerInputDown(0, gc_start, splitscreen + 1) == true)
|
||||
{
|
||||
if (!chat_on)
|
||||
{
|
||||
M_StartControlPanel();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,17 +54,8 @@ menuitem_t PAUSE_Main[] =
|
|||
{IT_STRING | IT_CALL, "RESUME GAME", "M_ICOUNP",
|
||||
NULL, {.routine = M_QuitPauseMenu}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "SPECTATE", "M_ICOSPC",
|
||||
NULL, {.routine = M_ConfirmSpectate}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "ENTER GAME", "M_ICOENT",
|
||||
NULL, {.routine = M_ConfirmEnterGame}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "CANCEL JOIN", "M_ICOSPC",
|
||||
NULL, {.routine = M_ConfirmSpectate}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_SUBMENU, "JOIN OR SPECTATE", "M_ICOENT",
|
||||
NULL, {NULL}, 0, 0},
|
||||
{IT_STRING | IT_ARROWS, "SPECTATE", "M_ICOSPC",
|
||||
NULL, {.routine = M_HandleSpectateToggle}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "PLAYER SETUP", "M_ICOCHR",
|
||||
NULL, {.routine = M_CharacterSelect}, 0, 0},
|
||||
|
|
@ -142,10 +133,7 @@ void M_OpenPauseMenu(void)
|
|||
PAUSE_Main[mpause_restartmap].status = IT_DISABLED;
|
||||
PAUSE_Main[mpause_tryagain].status = IT_DISABLED;
|
||||
|
||||
PAUSE_Main[mpause_spectate].status = IT_DISABLED;
|
||||
PAUSE_Main[mpause_entergame].status = IT_DISABLED;
|
||||
PAUSE_Main[mpause_canceljoin].status = IT_DISABLED;
|
||||
PAUSE_Main[mpause_spectatemenu].status = IT_DISABLED;
|
||||
PAUSE_Main[mpause_spectatetoggle].status = IT_DISABLED;
|
||||
PAUSE_Main[mpause_psetup].status = IT_DISABLED;
|
||||
PAUSE_Main[mpause_cheats].status = IT_DISABLED;
|
||||
|
||||
|
|
@ -236,17 +224,13 @@ void M_OpenPauseMenu(void)
|
|||
|
||||
if (G_GametypeHasSpectators())
|
||||
{
|
||||
if (splitscreen)
|
||||
PAUSE_Main[mpause_spectatemenu].status = IT_STRING|IT_SUBMENU;
|
||||
else
|
||||
if (pausemenu.splitscreenfocusid > splitscreen)
|
||||
{
|
||||
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;
|
||||
// Only futz if necessary.
|
||||
pausemenu.splitscreenfocusid = 0;
|
||||
}
|
||||
|
||||
PAUSE_Main[mpause_spectatetoggle].status = IT_STRING | IT_ARROWS;
|
||||
}
|
||||
|
||||
if (CV_CheatsEnabled())
|
||||
|
|
@ -462,24 +446,86 @@ void M_GiveUp(INT32 choice)
|
|||
}
|
||||
|
||||
// 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(-1);
|
||||
COM_ImmedExecute("changeteam spectator");
|
||||
}
|
||||
|
||||
void M_ConfirmEnterGame(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
if (!cv_allowteamchange.value)
|
||||
void M_HandleSpectateToggle(INT32 choice)
|
||||
{
|
||||
if (choice == 2)
|
||||
{
|
||||
M_StartMessage("Team Change", M_GetText("The server is not allowing\nteam changes at this time.\n"), NULL, MM_NOTHING, NULL, NULL);
|
||||
if (!(G_GametypeHasSpectators() && pausemenu.splitscreenfocusid <= splitscreen))
|
||||
{
|
||||
M_StartMessage("Team Change", va("You can't change spectator status right now. (Player %c)", ('A' + pausemenu.splitscreenfocusid)), NULL, MM_NOTHING, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean tospectator = false;
|
||||
{
|
||||
// Identify relevant spectator state of pausemenu.splitscreenfocusid.
|
||||
// See also M_DrawPause.
|
||||
|
||||
const UINT8 splitspecid =
|
||||
g_localplayers[pausemenu.splitscreenfocusid];
|
||||
|
||||
tospectator = (
|
||||
players[splitspecid].spectator == false
|
||||
|| (players[splitspecid].pflags & PF_WANTSTOJOIN)
|
||||
);
|
||||
}
|
||||
|
||||
if (!tospectator && !cv_allowteamchange.value)
|
||||
{
|
||||
M_StartMessage("Team Change", M_GetText("The server is not allowing\nteam changes at this time.\n"), NULL, MM_NOTHING, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
M_QuitPauseMenu(-1);
|
||||
|
||||
const char *destinationstate = tospectator ? "spectator" : "playing";
|
||||
|
||||
// These console command names...
|
||||
if (pausemenu.splitscreenfocusid == 0)
|
||||
{
|
||||
COM_ImmedExecute(
|
||||
va(
|
||||
"changeteam %s",
|
||||
destinationstate
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
COM_ImmedExecute(
|
||||
va(
|
||||
"changeteam%u %s",
|
||||
pausemenu.splitscreenfocusid + 1,
|
||||
destinationstate
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
M_QuitPauseMenu(-1);
|
||||
COM_ImmedExecute("changeteam playing");
|
||||
|
||||
if (splitscreen == 0)
|
||||
return;
|
||||
|
||||
if (choice == 0) // left
|
||||
{
|
||||
if (pausemenu.splitscreenfocusid)
|
||||
pausemenu.splitscreenfocusid--;
|
||||
else
|
||||
pausemenu.splitscreenfocusid = splitscreen;
|
||||
}
|
||||
else if (choice == 1) // right
|
||||
{
|
||||
if (pausemenu.splitscreenfocusid < splitscreen)
|
||||
pausemenu.splitscreenfocusid++;
|
||||
else
|
||||
pausemenu.splitscreenfocusid = 0;
|
||||
}
|
||||
else // reset
|
||||
{
|
||||
pausemenu.splitscreenfocusid = 0;
|
||||
}
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
}
|
||||
|
||||
static void M_ExitGameResponse(INT32 ch)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue