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

View file

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

View file

@ -3530,19 +3530,20 @@ void M_DrawTimeAttack(void)
K_drawKartTimestamp(timerec, 162+t, timeheight+6, 0, 1); K_drawKartTimestamp(timerec, 162+t, timeheight+6, 0, 1);
// SPB Attack control hint + menu overlay // 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 buttonx = 162 + t;
INT32 buttony = timeheight; 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)) 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)); V_DrawMappedPatch(buttonx + 7, buttony - 1, 0, W_CachePatchName("K_SPBATK", PU_CACHE), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_RED, GTC_MENUCACHE));
} }
} }
} }
else else
opty = 80; 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) boolean M_TimeAttackInputs(INT32 ch)
{ {
const UINT8 pid = 0; const UINT8 pid = 0;
const boolean buttonR = M_MenuButtonPressed(pid, MBT_R); const boolean buttonR = M_MenuButtonPressed(pid, MBT_R);
(void) ch; (void) ch;
if (buttonR && levellist.newgametype == GT_RACE && M_SecretUnlocked(SECRET_SPBATTACK, true)) if (buttonR && M_EncoreAttackTogglePermitted())
{ {
CV_AddValue(&cv_dummyspbattack, 1); CV_AddValue(&cv_dummyspbattack, 1);
timeattackmenu.spbflicker = TICRATE/6; timeattackmenu.spbflicker = TICRATE/6;
@ -348,7 +356,7 @@ void CV_SPBAttackChanged(void)
/*else if (PLAY_TimeAttackDef.lastOn == ta_ghosts) /*else if (PLAY_TimeAttackDef.lastOn == ta_ghosts)
PLAY_TimeAttackDef.lastOn = ta_start;*/ 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].status = IT_HEADER;
PLAY_TAReplay[tareplay_header].text = cv_dummyspbattack.value ? "SPB Attack..." : "Time Attack..."; 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); 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 // Menu options / Time-sticker medals
CV_SPBAttackChanged(); CV_SPBAttackChanged();
} }
@ -554,7 +572,10 @@ void M_StartTimeAttack(INT32 choice)
if (cv_dummyspbattack.value) if (cv_dummyspbattack.value)
{ {
modeattacking |= ATTACKING_SPB; if (levellist.newgametype == GT_RACE)
{
modeattacking |= ATTACKING_SPB;
}
modeprefix = "spb-"; modeprefix = "spb-";
} }
@ -598,7 +619,7 @@ void M_StartTimeAttack(INT32 choice)
restoreMenu = &PLAY_TimeAttackDef; restoreMenu = &PLAY_TimeAttackDef;
M_ClearMenus(true); 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); 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))); 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-"; modeprefix = "spb-";
enum enum
@ -8294,7 +8294,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
wipegamestate = gamestate; // Don't fade if reloading the gamestate wipegamestate = gamestate; // Don't fade if reloading the gamestate
// Encore mode fade to pink to white // Encore mode fade to pink to white
// This is handled BEFORE sounds are stopped. // 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) if (rendermode != render_none)
{ {