diff --git a/src/g_game.c b/src/g_game.c index 2acafddb3..4463f55ce 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1672,7 +1672,7 @@ void G_DoLoadLevel(boolean resetplayer) CON_ClearHUD(); } -static INT32 pausedelay = 0; +INT32 pausedelay = 0; static INT32 camtoggledelay, camtoggledelay2 = 0; // @@ -1822,17 +1822,30 @@ boolean G_Responder(event_t *ev) if (ev->data1 == gamecontrol[gc_pause][0] || ev->data1 == gamecontrol[gc_pause][1]) { - if (!pausedelay) + if (modeattacking && !demoplayback && (gamestate == GS_LEVEL)) { - // don't let busy scripts prevent pausing - pausedelay = NEWTICRATE/7; + if (menuactive || pausedelay < 0 || leveltime < 2) + return true; - // command will handle all the checks for us - COM_ImmedExecute("pause"); - return true; + if (++pausedelay > (NEWTICRATE/3)) + { + pausedelay = INT32_MIN; + G_SetRetryFlag(); + return true; + } + pausedelay++; // counteract subsequent subtraction this frame } else - pausedelay = NEWTICRATE/7; + { + INT32 oldpausedelay = pausedelay; + pausedelay = (NEWTICRATE/7); + if (!oldpausedelay) + { + // command will handle all the checks for us + COM_ImmedExecute("pause"); + return true; + } + } } if (ev->data1 == gamecontrol[gc_camtoggle][0] || ev->data1 == gamecontrol[gc_camtoggle][1]) @@ -1892,11 +1905,16 @@ void G_Ticker(boolean run) { G_ClearRetryFlag(); - // Costs a life to retry ... unless the player in question is dead already. - if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != 0x7f) - players[consoleplayer].lives -= 1; + if (modeattacking) + M_ModeAttackRetry(0); + else + { + // Costs a life to retry ... unless the player in question is dead already. + if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != 0x7f) + players[consoleplayer].lives -= 1; - G_DoReborn(consoleplayer); + G_DoReborn(consoleplayer); + } } for (i = 0; i < MAXPLAYERS; i++) @@ -1994,8 +2012,13 @@ void G_Ticker(boolean run) if (run) { - if (pausedelay) - pausedelay--; + if (pausedelay && pausedelay != INT32_MIN) + { + if (pausedelay > 0) + pausedelay--; + else + pausedelay++; + } if (camtoggledelay) camtoggledelay--; @@ -2935,6 +2958,9 @@ static void G_DoCompleted(void) tokenlist = 0; // Reset the list + if (modeattacking && pausedelay) + pausedelay = 0; + gameaction = ga_nothing; if (metalplayback) diff --git a/src/g_game.h b/src/g_game.h index d6b41830e..3d04370aa 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -53,6 +53,7 @@ extern INT16 prevmap, nextmap; extern INT32 gameovertics; extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard display) extern INT16 rw_maximums[NUM_WEAPONS]; +extern INT32 pausedelay; // used in game menu extern consvar_t cv_crosshair, cv_crosshair2; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index bc57931f5..f4730005e 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1120,6 +1120,29 @@ void HU_Drawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text); } + + if (modeattacking && pausedelay > 1) + { + UINT8 strength = (pausedelay*10)/(NEWTICRATE/3); + INT32 y = hudinfo[HUD_LIVES].y - 13; + + if (strength > 9) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); + else if (strength) + V_DrawFadeScreen(0, strength); + + if (players[consoleplayer].powers[pw_carry] == CR_NIGHTSMODE) + y -= 16; + else + { + if (players[consoleplayer].pflags & PF_AUTOBRAKE) + y -= 8; + if (players[consoleplayer].pflags & PF_ANALOGMODE) + y -= 8; + } + + V_DrawThinString(hudinfo[HUD_LIVES].x-2, y, hudinfo[HUD_LIVES].f|((leveltime & 2) ? V_SKYMAP : V_BLUEMAP), "RETRYING..."); + } } //====================================================================== diff --git a/src/m_menu.c b/src/m_menu.c index a866dac1b..5258f4b44 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -282,7 +282,6 @@ static void M_Statistics(INT32 choice); static void M_ReplayTimeAttack(INT32 choice); static void M_ChooseTimeAttack(INT32 choice); static void M_ChooseNightsAttack(INT32 choice); -static void M_ModeAttackRetry(INT32 choice); static void M_ModeAttackEndGame(INT32 choice); static void M_SetGuestReplay(INT32 choice); static void M_HandleChoosePlayerMenu(INT32 choice); @@ -1083,7 +1082,7 @@ static menuitem_t OP_ChangeControlsMenu[] = {IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_CALL | IT_STRING2, NULL, "Game Status", M_ChangeControl, gc_scores }, - {IT_CALL | IT_STRING2, NULL, "Pause", M_ChangeControl, gc_pause }, + {IT_CALL | IT_STRING2, NULL, "Pause / Run Retry", M_ChangeControl, gc_pause }, {IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console }, {IT_HEADER, NULL, "Multiplayer", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding @@ -7841,9 +7840,10 @@ static void M_SetGuestReplay(INT32 choice) which(0); } -static void M_ModeAttackRetry(INT32 choice) +void M_ModeAttackRetry(INT32 choice) { (void)choice; + // todo -- maybe seperate this out and G_SetRetryFlag() here instead? is just calling this from the menu 100% safe? G_CheckDemoStatus(); // Cancel recording if (modeattacking == ATTACKING_RECORD) M_ChooseTimeAttack(0); diff --git a/src/m_menu.h b/src/m_menu.h index 9df56e897..c1e48912a 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -235,7 +235,7 @@ extern INT16 startmap; extern INT32 ultimate_selectable; extern INT16 char_on, startchar; -#define MAXSAVEGAMES 31 //note: last save game is "no save" +#define MAXSAVEGAMES 31 #define NOSAVESLOT 0 //slot where Play Without Saving appears #define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he @@ -244,6 +244,8 @@ void M_ForceSaveSlotSelected(INT32 sslot); void M_CheatActivationResponder(INT32 ch); +void M_ModeAttackRetry(INT32 choice); + // Level select updating void Nextmap_OnChange(void); diff --git a/src/p_setup.c b/src/p_setup.c index a5544c26b..11e6b4ef7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2728,7 +2728,9 @@ boolean P_SetupLevel(boolean skipprecip) // Special stage fade to white // This is handled BEFORE sounds are stopped. - if (rendermode != render_none && G_IsSpecialStage(gamemap)) + if (modeattacking && pausedelay == INT32_MIN) + ranspecialwipe = 2; + else if (rendermode != render_none && G_IsSpecialStage(gamemap)) { tic_t starttime = I_GetTime(); tic_t endtime = starttime + (3*TICRATE)/2; @@ -2778,6 +2780,12 @@ boolean P_SetupLevel(boolean skipprecip) F_RunWipe(wipedefs[wipe_level_toblack], false); } + if (ranspecialwipe == 2) + { + pausedelay = -NEWTICRATE; + S_StartSound(NULL, sfx_s3k73); + } + // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." if (!titlemapinaction && rendermode != render_none) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 2a7e0636a..698411533 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2367,11 +2367,13 @@ static void ST_overlayDrawer(void) { ST_drawFirstPersonHUD(); if (cv_powerupdisplay.value) - ST_drawPowerupHUD(); + ST_drawPowerupHUD(); // same as it ever was... } else if (cv_powerupdisplay.value == 2) - ST_drawPowerupHUD(); + ST_drawPowerupHUD(); // same as it ever was... } + else if (!(netgame || multiplayer) && cv_powerupdisplay.value == 2) + ST_drawPowerupHUD(); // same as it ever was... #ifdef HAVE_BLUA if (!(netgame || multiplayer) || !hu_showscores) @@ -2393,7 +2395,7 @@ static void ST_overlayDrawer(void) ) ST_drawTextHUD(); - if (modeattacking && !hu_showscores) + if (modeattacking && !(demoplayback && hu_showscores)) ST_drawInput(); ST_drawDebugInfo();