Tie SPB Attack and Encore together

- A method to access Encore in Time Attack
    - so we have SOME Encore singleplayer content on launch
- Also available for Versus mode (in Special Attack)
    - Finally, Encore rematches have a way to access them!
    - Obviously will not spawn a chasing SPB, it's just a signal for "hard mode"
- Relevant gametype + unlock checks have been abstracted into M_EncoreAttackTogglePermitted
This commit is contained in:
toaster 2024-02-17 23:11:58 +00:00
parent 3f78c9d2e6
commit b70e59755f
5 changed files with 37 additions and 14 deletions

View file

@ -428,7 +428,7 @@ void G_UpdateTimeStickerMedals(UINT16 map, boolean showownrecord)
}
case ET_MAP:
{
if (emblem->flags & ME_SPBATTACK && cv_dummyspbattack.value)
if (emblem->flags & (ME_SPBATTACK|ME_ENCORE) && cv_dummyspbattack.value)
break;
goto bademblem;
}
@ -436,7 +436,7 @@ void G_UpdateTimeStickerMedals(UINT16 map, boolean showownrecord)
goto bademblem;
}
if (cv_dummyspbattack.value && !(emblem->flags & ME_SPBATTACK))
if (cv_dummyspbattack.value && !(emblem->flags & (ME_SPBATTACK|ME_ENCORE)))
return;
if (!gamedata->collected[(emblem-emblemlocations)] && gonnadrawtime)
@ -537,7 +537,7 @@ void G_TickTimeStickerMedals(void)
void G_UpdateRecords(void)
{
UINT8 earnedEmblems;
recordtimes_t *record = (modeattacking & ATTACKING_SPB) ?
recordtimes_t *record = (encoremode == true) ?
&mapheaderinfo[gamemap-1]->records.spbattack :
&mapheaderinfo[gamemap-1]->records.timeattack;
@ -585,7 +585,7 @@ static void G_UpdateRecordReplays(void)
char lastdemo[256], bestdemo[256];
const char *modeprefix = "";
if (modeattacking & ATTACKING_SPB)
if (encoremode)
{
modeprefix = "spb-";
}

View file

@ -906,6 +906,7 @@ void M_ReplayTimeAttack(INT32 choice);
void M_HandleStaffReplay(INT32 choice);
void M_SetGuestReplay(INT32 choice);
void M_TimeAttackTick(void);
boolean M_EncoreAttackTogglePermitted(void);
boolean M_TimeAttackInputs (INT32 choice);
// MP selection

View file

@ -3530,19 +3530,20 @@ void M_DrawTimeAttack(void)
K_drawKartTimestamp(timerec, 162+t, timeheight+6, 0, 1);
// SPB Attack control hint + menu overlay
if (levellist.newgametype == GT_RACE && levellist.levelsearch.timeattack == true && M_SecretUnlocked(SECRET_SPBATTACK, true))
{
INT32 buttonx = 162 + t;
INT32 buttony = timeheight;
K_drawButtonAnim(buttonx + 35, buttony - 3, V_SNAPTOLEFT, kp_button_r, timeattackmenu.ticker);
if (M_EncoreAttackTogglePermitted())
{
K_drawButtonAnim(buttonx + 35, buttony - 3, V_SNAPTOLEFT, kp_button_r, timeattackmenu.ticker);
}
if ((timeattackmenu.spbflicker == 0 || timeattackmenu.ticker % 2) == (cv_dummyspbattack.value == 1))
{
V_DrawMappedPatch(buttonx + 7, buttony - 1, 0, W_CachePatchName("K_SPBATK", PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_RED, GTC_MENUCACHE));
}
}
}
else
opty = 80;

View file

@ -22,13 +22,21 @@ void M_TimeAttackTick(void)
}
}
boolean M_EncoreAttackTogglePermitted(void)
{
if ((gametypes[levellist.newgametype]->rules & GTR_ENCORE) == 0) //levellist.newgametype != GT_RACE
return false;
return M_SecretUnlocked(SECRET_SPBATTACK, true);
}
boolean M_TimeAttackInputs(INT32 ch)
{
const UINT8 pid = 0;
const boolean buttonR = M_MenuButtonPressed(pid, MBT_R);
(void) ch;
if (buttonR && levellist.newgametype == GT_RACE && M_SecretUnlocked(SECRET_SPBATTACK, true))
if (buttonR && M_EncoreAttackTogglePermitted())
{
CV_AddValue(&cv_dummyspbattack, 1);
timeattackmenu.spbflicker = TICRATE/6;
@ -348,7 +356,7 @@ void CV_SPBAttackChanged(void)
/*else if (PLAY_TimeAttackDef.lastOn == ta_ghosts)
PLAY_TimeAttackDef.lastOn = ta_start;*/
if ((active & 8) && levellist.newgametype == GT_RACE && M_SecretUnlocked(SECRET_SPBATTACK, true))
if ((active & 8) && M_EncoreAttackTogglePermitted())
{
PLAY_TAReplay[tareplay_header].status = IT_HEADER;
PLAY_TAReplay[tareplay_header].text = cv_dummyspbattack.value ? "SPB Attack..." : "Time Attack...";
@ -381,9 +389,19 @@ void M_PrepareTimeAttack(boolean menuupdate)
}
}
if (levellist.levelsearch.timeattack == false || levellist.newgametype != GT_RACE || !M_SecretUnlocked(SECRET_SPBATTACK, true))
if (cv_dummyspbattack.value
&& (levellist.levelsearch.timeattack == false || !M_EncoreAttackTogglePermitted()))
{
CV_StealthSetValue(&cv_dummyspbattack, 0);
if (!menuupdate)
{
timeattackmenu.spbflicker = TICRATE/6;
S_StartSound(NULL, sfx_s3k92);
S_StopSoundByID(NULL, sfx_s3k9f);
}
}
// Menu options / Time-sticker medals
CV_SPBAttackChanged();
}
@ -554,7 +572,10 @@ void M_StartTimeAttack(INT32 choice)
if (cv_dummyspbattack.value)
{
modeattacking |= ATTACKING_SPB;
if (levellist.newgametype == GT_RACE)
{
modeattacking |= ATTACKING_SPB;
}
modeprefix = "spb-";
}
@ -598,7 +619,7 @@ void M_StartTimeAttack(INT32 choice)
restoreMenu = &PLAY_TimeAttackDef;
M_ClearMenus(true);
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_dummygpencore.value == 1), 1, 1, false, false);
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_dummyspbattack.value == 1), 1, 1, false, false);
G_UpdateTimeStickerMedals(levellist.choosemap, true);
}

View file

@ -7791,7 +7791,7 @@ static void P_LoadRecordGhosts(void)
gpath = Z_StrDup(va("%s" PATHSEP "media" PATHSEP "replay" PATHSEP "%s" PATHSEP "%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)));
if (modeattacking & ATTACKING_SPB)
if (encoremode)
modeprefix = "spb-";
enum
@ -8294,7 +8294,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
wipegamestate = gamestate; // Don't fade if reloading the gamestate
// Encore mode fade to pink to white
// This is handled BEFORE sounds are stopped.
else if (encoremode && !prevencoremode && !demo.rewinding)
else if (encoremode && !prevencoremode && modeattacking == ATTACKING_NONE && !demo.rewinding)
{
if (rendermode != render_none)
{