Port SRB2Kart join on intermission fix

All gamestates besides GS_LEVEL are unsupported by the save game functions. This commit forces players joining during these gamestates into GS_WAITINGPLAYERS, which is a basic gamestate that just maintains the connection until we can enter the start of a new one. Also provides an extremely simple drawer for GS_WAITINGPLAYERS so the joining player knows what's going on.
This commit is contained in:
Sally Coolatta 2023-06-12 22:34:42 -04:00
parent 9a31064c4a
commit 80bf4d6c2d
8 changed files with 59 additions and 6 deletions

View file

@ -1889,7 +1889,7 @@ void CON_Drawer(void)
CON_DrawConsole(); CON_DrawConsole();
else if (gamestate == GS_LEVEL else if (gamestate == GS_LEVEL
|| gamestate == GS_INTERMISSION || gamestate == GS_ENDING || gamestate == GS_CUTSCENE || gamestate == GS_INTERMISSION || gamestate == GS_ENDING || gamestate == GS_CUTSCENE
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION) || gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_WAITINGPLAYERS)
CON_DrawHudlines(); CON_DrawHudlines();
Unlock_state(); Unlock_state();

View file

@ -2600,6 +2600,8 @@ static void CL_ConnectToServer(void)
} }
while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes)))); while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes))));
if (netgame)
F_StartWaitingPlayers();
DEBFILE(va("Synchronisation Finished\n")); DEBFILE(va("Synchronisation Finished\n"));
displayplayer = consoleplayer; displayplayer = consoleplayer;

View file

@ -458,6 +458,13 @@ static void D_Display(void)
case GS_WAITINGPLAYERS: case GS_WAITINGPLAYERS:
// The clientconnect drawer is independent... // The clientconnect drawer is independent...
if (netgame)
{
// I don't think HOM from nothing drawing is independent...
F_WaitingPlayersDrawer();
HU_Erase();
HU_Drawer();
}
case GS_DEDICATEDSERVER: case GS_DEDICATEDSERVER:
case GS_NULL: case GS_NULL:
break; break;

View file

@ -2174,7 +2174,7 @@ static void Command_Pause(void)
if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer))) if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer)))
{ {
if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) || (marathonmode && gamestate == GS_INTERMISSION)) if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_WAITINGPLAYERS) || (marathonmode && gamestate == GS_INTERMISSION))
{ {
CONS_Printf(M_GetText("You can't pause here.\n")); CONS_Printf(M_GetText("You can't pause here.\n"));
return; return;

View file

@ -4660,3 +4660,36 @@ void F_TextPromptTicker(void)
animtimer--; animtimer--;
} }
} }
// ================
// WAITINGPLAYERS
// ================
void F_StartWaitingPlayers(void)
{
wipegamestate = GS_TITLESCREEN; // technically wiping from title screen
finalecount = 0;
}
void F_WaitingPlayersTicker(void)
{
if (paused)
return;
finalecount++;
// dumb hack, only start the music on the 1st tick so if you instantly go into the map you aren't hearing a tic of music
if (finalecount == 2)
S_ChangeMusicInternal("_CHSEL", true);
}
void F_WaitingPlayersDrawer(void)
{
const char *waittext1 = "You will join";
const char *waittext2 = "next level...";
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
V_DrawCreditString((160 - (V_CreditStringWidth(waittext1)>>1))<<FRACBITS, 48<<FRACBITS, 0, waittext1);
V_DrawCreditString((160 - (V_CreditStringWidth(waittext2)>>1))<<FRACBITS, 64<<FRACBITS, 0, waittext2);
}

View file

@ -74,6 +74,10 @@ void F_StartContinue(void);
void F_ContinueTicker(void); void F_ContinueTicker(void);
void F_ContinueDrawer(void); void F_ContinueDrawer(void);
void F_StartWaitingPlayers(void);
void F_WaitingPlayersTicker(void);
void F_WaitingPlayersDrawer(void);
extern INT32 finalecount; extern INT32 finalecount;
extern INT32 titlescrollxspeed; extern INT32 titlescrollxspeed;
extern INT32 titlescrollyspeed; extern INT32 titlescrollyspeed;

View file

@ -2437,14 +2437,17 @@ void G_Ticker(boolean run)
case GS_TITLESCREEN: case GS_TITLESCREEN:
if (titlemapinaction) if (titlemapinaction)
P_Ticker(run); P_Ticker(run);
// then intentionally fall through
/* FALLTHRU */
case GS_WAITINGPLAYERS:
if (run) if (run)
F_MenuPresTicker(); F_MenuPresTicker();
F_TitleScreenTicker(run); F_TitleScreenTicker(run);
break; break;
case GS_WAITINGPLAYERS:
if (netgame)
F_WaitingPlayersTicker();
HU_Ticker();
break;
case GS_DEDICATEDSERVER: case GS_DEDICATEDSERVER:
case GS_NULL: case GS_NULL:
break; // do nothing break; // do nothing

View file

@ -4279,7 +4279,11 @@ static void P_NetArchiveMisc(boolean resending)
if (resending) if (resending)
WRITEUINT32(save_p, gametic); WRITEUINT32(save_p, gametic);
WRITEINT16(save_p, gamemap); WRITEINT16(save_p, gamemap);
WRITEINT16(save_p, gamestate);
if (gamestate != GS_LEVEL)
WRITEINT16(save_p, GS_WAITINGPLAYERS); // nice hack to put people back into waitingplayers
else
WRITEINT16(save_p, gamestate);
WRITEINT16(save_p, gametype); WRITEINT16(save_p, gametype);
{ {