mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-03-08 04:06:25 +00:00
Icon selection + Extras menu access
* Icon selection
* You can use up, down, left, right, etc to select icons on the Challenges menu
* The text at the top changes based on the highlighted icon
* This text is now ??? if not yet unlocked
* Uses the border for character rank icons
* Challenges are now accessible on the Extras menu alongside Addons and Replay Hut.
* Previously there was a "Extras Checklist" dummy which did nothing when selected
* Now I won't have to clear my gamedata every time I want to check this menu!
* M_ChallengeGridExtraData's array is modified to now contain specific info on whether a given tile is connected to above or left (or both).
This commit is contained in:
parent
85160b1dc1
commit
ac15d4caa3
8 changed files with 311 additions and 50 deletions
|
|
@ -69,7 +69,7 @@ static patch_t *kp_racefinish[6];
|
|||
static patch_t *kp_positionnum[10][2][2]; // number, overlay or underlay, splitscreen
|
||||
|
||||
static patch_t *kp_facenum[MAXPLAYERS+1];
|
||||
static patch_t *kp_facehighlight[8];
|
||||
patch_t *kp_facehighlight[8];
|
||||
|
||||
static patch_t *kp_nocontestminimap;
|
||||
static patch_t *kp_spbminimap;
|
||||
|
|
|
|||
|
|
@ -39,4 +39,6 @@ void K_drawKartFreePlay(void);
|
|||
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode);
|
||||
void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol);
|
||||
|
||||
extern patch_t *kp_facehighlight[8];
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1091,11 +1091,15 @@ extern struct challengesmenu_s {
|
|||
UINT8 currentunlock;
|
||||
tic_t unlockanim;
|
||||
|
||||
UINT8 row, col, hilix, hiliy;
|
||||
|
||||
UINT8 *extradata;
|
||||
|
||||
boolean pending;
|
||||
} challengesmenu;
|
||||
|
||||
menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu);
|
||||
void M_Challenges(INT32 choice);
|
||||
void M_DrawChallenges(void);
|
||||
void M_ChallengesTick(void);
|
||||
boolean M_ChallengesInputs(INT32 ch);
|
||||
|
|
|
|||
|
|
@ -1496,14 +1496,14 @@ menuitem_t EXTRAS_Main[] =
|
|||
{IT_STRING | IT_CALL, "Addons", "Add files to customize your experience.",
|
||||
NULL, {.routine = M_Addons}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Challenges", "View the requirements for some of the secret content you can unlock!",
|
||||
NULL, {.routine = M_Challenges}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Replay Hut", "Play the replays you've saved throughout your many races & battles!",
|
||||
NULL, {.routine = M_ReplayHut}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Statistics", "Look back on some of your greatest achievements such as your playtime and wins!",
|
||||
NULL, {NULL}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_TRANSTEXT, "Extras Checklist", "View the requirement for some of the secret content you can unlock!",
|
||||
NULL, {NULL}, 0, 0},
|
||||
};
|
||||
|
||||
// the extras menu essentially reuses the options menu stuff
|
||||
|
|
|
|||
|
|
@ -600,10 +600,10 @@ static void M_DrawMenuTooltips(void)
|
|||
// Used for the secrets menu, to hide yet-to-be-unlocked stuff.
|
||||
static const char *M_CreateSecretMenuOption(const char *str)
|
||||
{
|
||||
static char qbuf[32];
|
||||
static char qbuf[64];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 31; ++i)
|
||||
for (i = 0; i < 63; ++i)
|
||||
{
|
||||
if (!str[i])
|
||||
{
|
||||
|
|
@ -616,7 +616,7 @@ static const char *M_CreateSecretMenuOption(const char *str)
|
|||
qbuf[i] = ' ';
|
||||
}
|
||||
|
||||
qbuf[31] = '\0';
|
||||
qbuf[63] = '\0';
|
||||
return qbuf;
|
||||
}
|
||||
|
||||
|
|
@ -4471,19 +4471,21 @@ void M_DrawChallenges(void)
|
|||
|
||||
if (challengesmenu.currentunlock < MAXUNLOCKABLES)
|
||||
{
|
||||
V_DrawThinString(x, y, V_ALLOWLOWERCASE, unlockables[challengesmenu.currentunlock].name);
|
||||
|
||||
if (challengesmenu.unlockanim >= UNLOCKTIME)
|
||||
V_DrawThinString(x, y + 10, V_ALLOWLOWERCASE, "Press (A)");
|
||||
const char *str = unlockables[challengesmenu.currentunlock].name;
|
||||
if (!gamedata->unlocked[challengesmenu.currentunlock])
|
||||
{
|
||||
str = "???"; //M_CreateSecretMenuOption(str);
|
||||
}
|
||||
V_DrawThinString(x, y, V_ALLOWLOWERCASE, str);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawThinString(x, y, V_ALLOWLOWERCASE, va("pending = %c", challengesmenu.pending ? 'T' : 'F'));
|
||||
|
||||
if (challengesmenu.unlockanim >= UNLOCKTIME)
|
||||
V_DrawThinString(x, y + 10, V_ALLOWLOWERCASE, "Press (B)");
|
||||
V_DrawThinString(x, y, V_ALLOWLOWERCASE, "---");
|
||||
}
|
||||
|
||||
if (challengesmenu.unlockanim >= UNLOCKTIME)
|
||||
V_DrawThinString(x, y + 10, V_ALLOWLOWERCASE, va("Press (%c)", challengesmenu.pending ? 'A' : 'B'));
|
||||
|
||||
x = currentMenu->x;
|
||||
y = currentMenu->y;
|
||||
|
||||
|
|
@ -4501,7 +4503,7 @@ void M_DrawChallenges(void)
|
|||
y += 16;
|
||||
id = (i * CHALLENGEGRIDHEIGHT) + j;
|
||||
|
||||
if (challengesmenu.extradata[id] == CHE_DONTDRAW)
|
||||
if (challengesmenu.extradata[id] & CHE_DONTDRAW)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -4512,7 +4514,8 @@ void M_DrawChallenges(void)
|
|||
if (num >= MAXUNLOCKABLES)
|
||||
{
|
||||
V_DrawFill(x, y, 16, 16, 27);
|
||||
continue;
|
||||
ref = NULL;
|
||||
goto drawborder;
|
||||
}
|
||||
|
||||
// Okay, this is what we want to draw.
|
||||
|
|
@ -4526,7 +4529,7 @@ void M_DrawChallenges(void)
|
|||
V_DrawFill(x, y, 16*work, 16*work,
|
||||
((challengesmenu.extradata[id] == CHE_HINT) ? 130 : 12)
|
||||
+ ((i & work) != (j & work) ? 0 : 2) + (work-1)); // funny checkerboard pattern
|
||||
continue;
|
||||
goto drawborder;
|
||||
}
|
||||
|
||||
switch (ref->type)
|
||||
|
|
@ -4551,6 +4554,19 @@ void M_DrawChallenges(void)
|
|||
V_DrawString(x, y, V_ALLOWLOWERCASE, va("%c", ref->name[0]));
|
||||
break;
|
||||
}
|
||||
|
||||
drawborder:
|
||||
if (i != challengesmenu.hilix)
|
||||
continue;
|
||||
if (j != challengesmenu.hiliy)
|
||||
continue;
|
||||
|
||||
V_DrawFixedPatch(
|
||||
x*FRACUNIT, y*FRACUNIT,
|
||||
((ref != NULL && ref->majorunlock) ? FRACUNIT*2 : FRACUNIT),
|
||||
0, kp_facehighlight[(challengesmenu.ticker / 4) % 8],
|
||||
NULL
|
||||
);
|
||||
}
|
||||
x += 16;
|
||||
}
|
||||
|
|
|
|||
288
src/k_menufunc.c
288
src/k_menufunc.c
|
|
@ -775,22 +775,6 @@ static boolean M_PrevOpt(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
static menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
|
||||
{
|
||||
M_UpdateUnlockablesAndExtraEmblems(false);
|
||||
|
||||
if (M_GetNextAchievedUnlock(false) < MAXUNLOCKABLES)
|
||||
{
|
||||
MISC_ChallengesDef.prevMenu = desiredmenu;
|
||||
challengesmenu.pending = true;
|
||||
challengesmenu.currentunlock = MAXUNLOCKABLES;
|
||||
M_PopulateChallengeGrid();
|
||||
return &MISC_ChallengesDef;
|
||||
}
|
||||
|
||||
return desiredmenu;
|
||||
}
|
||||
|
||||
//
|
||||
// M_Responder
|
||||
//
|
||||
|
|
@ -6826,19 +6810,122 @@ void M_Manual(INT32 choice)
|
|||
|
||||
struct challengesmenu_s challengesmenu;
|
||||
|
||||
menu_t *M_InterruptMenuWithChallenges(menu_t *desiredmenu)
|
||||
{
|
||||
M_UpdateUnlockablesAndExtraEmblems(false);
|
||||
|
||||
if (M_GetNextAchievedUnlock(false) < MAXUNLOCKABLES)
|
||||
{
|
||||
challengesmenu.pending = true;
|
||||
MISC_ChallengesDef.prevMenu = desiredmenu;
|
||||
}
|
||||
|
||||
if (challengesmenu.pending || desiredmenu == NULL)
|
||||
{
|
||||
challengesmenu.currentunlock = MAXUNLOCKABLES;
|
||||
M_PopulateChallengeGrid();
|
||||
return &MISC_ChallengesDef;
|
||||
}
|
||||
|
||||
return desiredmenu;
|
||||
}
|
||||
|
||||
void M_Challenges(INT32 choice)
|
||||
{
|
||||
UINT8 i;
|
||||
(void)choice;
|
||||
|
||||
M_InterruptMenuWithChallenges(NULL);
|
||||
MISC_ChallengesDef.prevMenu = currentMenu;
|
||||
|
||||
if (gamedata->challengegrid)
|
||||
{
|
||||
UINT8 selection[MAXUNLOCKABLES];
|
||||
UINT8 numunlocks = 0;
|
||||
|
||||
// Get a random available unlockable.
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
{
|
||||
if (!unlockables[i].conditionset)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!gamedata->unlocked[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
selection[numunlocks++] = i;
|
||||
}
|
||||
|
||||
if (!numunlocks)
|
||||
{
|
||||
// ...OK, get a random unlockable.
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
{
|
||||
if (!unlockables[i].conditionset)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
selection[numunlocks++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
challengesmenu.currentunlock = selection[M_RandomKey(numunlocks)];
|
||||
|
||||
for (i = 0; i < (CHALLENGEGRIDHEIGHT * gamedata->challengegridwidth); i++)
|
||||
{
|
||||
if (gamedata->challengegrid[i] != challengesmenu.currentunlock)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
challengesmenu.col = challengesmenu.hilix = i/CHALLENGEGRIDHEIGHT;
|
||||
challengesmenu.row = challengesmenu.hiliy = i%CHALLENGEGRIDHEIGHT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
M_SetupNextMenu(&MISC_ChallengesDef, false);
|
||||
}
|
||||
|
||||
void M_ChallengesTick(void)
|
||||
{
|
||||
UINT8 i, newunlock = MAXUNLOCKABLES;
|
||||
|
||||
challengesmenu.ticker++;
|
||||
|
||||
if (challengesmenu.pending && challengesmenu.currentunlock >= MAXUNLOCKABLES)
|
||||
{
|
||||
if ((challengesmenu.currentunlock = M_GetNextAchievedUnlock(true)) >= MAXUNLOCKABLES)
|
||||
if ((newunlock = M_GetNextAchievedUnlock(true)) < MAXUNLOCKABLES)
|
||||
{
|
||||
challengesmenu.currentunlock = newunlock;
|
||||
challengesmenu.unlockanim = 0;
|
||||
|
||||
if (gamedata->challengegrid)
|
||||
{
|
||||
for (i = 0; i < (CHALLENGEGRIDHEIGHT * gamedata->challengegridwidth); i++)
|
||||
{
|
||||
if (gamedata->challengegrid[i] != challengesmenu.currentunlock)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
challengesmenu.col = challengesmenu.hilix = i/CHALLENGEGRIDHEIGHT;
|
||||
challengesmenu.row = challengesmenu.hiliy = i%CHALLENGEGRIDHEIGHT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
challengesmenu.pending = false;
|
||||
G_SaveGameData();
|
||||
}
|
||||
Z_Free(challengesmenu.extradata);
|
||||
challengesmenu.extradata = M_ChallengeGridExtraData();
|
||||
challengesmenu.extradata = NULL;
|
||||
}
|
||||
else if (challengesmenu.unlockanim >= UNLOCKTIME)
|
||||
{
|
||||
|
|
@ -6848,14 +6935,25 @@ void M_ChallengesTick(void)
|
|||
{
|
||||
challengesmenu.unlockanim++;
|
||||
}
|
||||
|
||||
if (challengesmenu.extradata == NULL)
|
||||
{
|
||||
challengesmenu.extradata = M_ChallengeGridExtraData();
|
||||
}
|
||||
}
|
||||
|
||||
boolean M_ChallengesInputs(INT32 ch)
|
||||
{
|
||||
const UINT8 pid = 0;
|
||||
boolean start = M_MenuButtonPressed(pid, MBT_START);
|
||||
UINT8 i;
|
||||
const boolean start = M_MenuButtonPressed(pid, MBT_START);
|
||||
const boolean move = (menucmd[pid].dpad_ud || menucmd[pid].dpad_lr);
|
||||
(void) ch;
|
||||
|
||||
if (!challengesmenu.extradata)
|
||||
{
|
||||
;
|
||||
}
|
||||
if (challengesmenu.unlockanim < UNLOCKTIME)
|
||||
{
|
||||
;
|
||||
|
|
@ -6870,6 +6968,21 @@ boolean M_ChallengesInputs(INT32 ch)
|
|||
Z_Free(challengesmenu.extradata);
|
||||
challengesmenu.extradata = M_ChallengeGridExtraData();
|
||||
challengesmenu.unlockanim = 0;
|
||||
|
||||
if (challengesmenu.currentunlock != MAXUNLOCKABLES)
|
||||
{
|
||||
for (i = 0; i < (CHALLENGEGRIDHEIGHT * gamedata->challengegridwidth); i++)
|
||||
{
|
||||
if (gamedata->challengegrid[i] != challengesmenu.currentunlock)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
challengesmenu.col = challengesmenu.hilix = i/CHALLENGEGRIDHEIGHT;
|
||||
challengesmenu.row = challengesmenu.hiliy = i%CHALLENGEGRIDHEIGHT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -6878,19 +6991,142 @@ boolean M_ChallengesInputs(INT32 ch)
|
|||
if ((M_MenuConfirmPressed(pid) || start))
|
||||
{
|
||||
challengesmenu.currentunlock = MAXUNLOCKABLES;
|
||||
challengesmenu.unlockanim = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (M_MenuBackPressed(pid) || start)
|
||||
else
|
||||
{
|
||||
M_GoBack(0);
|
||||
M_SetMenuDelay(pid);
|
||||
if (M_MenuBackPressed(pid) || start)
|
||||
{
|
||||
M_GoBack(0);
|
||||
M_SetMenuDelay(pid);
|
||||
|
||||
Z_Free(challengesmenu.extradata);
|
||||
challengesmenu.extradata = NULL;
|
||||
Z_Free(challengesmenu.extradata);
|
||||
challengesmenu.extradata = NULL;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Determine movement around the grid
|
||||
if (move)
|
||||
{
|
||||
if (menucmd[pid].dpad_ud > 0)
|
||||
{
|
||||
i = 2;
|
||||
while (i > 0)
|
||||
{
|
||||
if (challengesmenu.row < CHALLENGEGRIDHEIGHT-1)
|
||||
{
|
||||
challengesmenu.row++;
|
||||
}
|
||||
else
|
||||
{
|
||||
challengesmenu.row = 0;
|
||||
}
|
||||
if (!(challengesmenu.extradata[
|
||||
(challengesmenu.col * CHALLENGEGRIDHEIGHT)
|
||||
+ challengesmenu.row]
|
||||
& CHE_CONNECTEDUP))
|
||||
{
|
||||
break;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(pid);
|
||||
}
|
||||
else if (menucmd[pid].dpad_ud < 0)
|
||||
{
|
||||
i = (challengesmenu.extradata[
|
||||
(challengesmenu.col * CHALLENGEGRIDHEIGHT)
|
||||
+ challengesmenu.row]
|
||||
& CHE_CONNECTEDUP) ? 2 : 1;
|
||||
while (i > 0)
|
||||
{
|
||||
if (challengesmenu.row > 0)
|
||||
{
|
||||
challengesmenu.row--;
|
||||
}
|
||||
else
|
||||
{
|
||||
challengesmenu.row = CHALLENGEGRIDHEIGHT-1;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(pid);
|
||||
}
|
||||
|
||||
if (menucmd[pid].dpad_lr > 0)
|
||||
{
|
||||
i = 2;
|
||||
while (i > 0)
|
||||
{
|
||||
if (challengesmenu.col < gamedata->challengegridwidth-1)
|
||||
{
|
||||
challengesmenu.col++;
|
||||
}
|
||||
else
|
||||
{
|
||||
challengesmenu.col = 0;
|
||||
}
|
||||
if (!(challengesmenu.extradata[
|
||||
(challengesmenu.col * CHALLENGEGRIDHEIGHT)
|
||||
+ challengesmenu.row]
|
||||
& CHE_CONNECTEDLEFT))
|
||||
{
|
||||
break;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(pid);
|
||||
}
|
||||
else if (menucmd[pid].dpad_lr < 0)
|
||||
{
|
||||
i = (challengesmenu.extradata[
|
||||
(challengesmenu.col * CHALLENGEGRIDHEIGHT)
|
||||
+ challengesmenu.row]
|
||||
& CHE_CONNECTEDLEFT) ? 2 : 1;
|
||||
while (i > 0)
|
||||
{
|
||||
if (challengesmenu.col > 0)
|
||||
{
|
||||
challengesmenu.col--;
|
||||
}
|
||||
else
|
||||
{
|
||||
challengesmenu.col = gamedata->challengegridwidth-1;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(pid);
|
||||
}
|
||||
|
||||
// After movement has been determined, figure out the current selection.
|
||||
i = (challengesmenu.col * CHALLENGEGRIDHEIGHT) + challengesmenu.row;
|
||||
challengesmenu.currentunlock = (gamedata->challengegrid[i]);
|
||||
|
||||
challengesmenu.hilix = challengesmenu.col;
|
||||
challengesmenu.hiliy = challengesmenu.row;
|
||||
if (challengesmenu.hiliy > 0 && (challengesmenu.extradata[i] & CHE_CONNECTEDUP))
|
||||
{
|
||||
challengesmenu.hiliy--;
|
||||
}
|
||||
|
||||
if ((challengesmenu.extradata[i] & CHE_CONNECTEDLEFT))
|
||||
{
|
||||
if (challengesmenu.hilix > 0)
|
||||
{
|
||||
challengesmenu.hilix--;
|
||||
}
|
||||
else
|
||||
{
|
||||
challengesmenu.hilix = gamedata->challengegridwidth-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -278,12 +278,13 @@ UINT8 *M_ChallengeGridExtraData(void)
|
|||
work = gamedata->challengegrid[tempid];
|
||||
if (work == num)
|
||||
{
|
||||
extradata[id] = CHE_DONTDRAW;
|
||||
extradata[id] = CHE_CONNECTEDUP;
|
||||
|
||||
// Get the id to write extra hint data to.
|
||||
// This check is safe because extradata's order of population
|
||||
if (extradata[tempid] == CHE_DONTDRAW)
|
||||
if (extradata[tempid] & CHE_CONNECTEDLEFT)
|
||||
{
|
||||
extradata[id] |= CHE_CONNECTEDLEFT;
|
||||
//CONS_Printf(" %d - %d above %d is invalid, check to left\n", num, tempid, id);
|
||||
if (i > 0)
|
||||
{
|
||||
|
|
@ -333,7 +334,7 @@ UINT8 *M_ChallengeGridExtraData(void)
|
|||
{
|
||||
extradata[tempid] = CHE_HINT;
|
||||
}
|
||||
extradata[id] = CHE_DONTDRAW;
|
||||
extradata[id] = CHE_CONNECTEDLEFT;
|
||||
id = tempid;
|
||||
}
|
||||
/*else
|
||||
|
|
|
|||
|
|
@ -176,9 +176,11 @@ extern UINT32 unlocktriggers;
|
|||
void M_NewGameDataStruct(void);
|
||||
void M_PopulateChallengeGrid(void);
|
||||
UINT8 *M_ChallengeGridExtraData(void);
|
||||
#define CHE_NONE 0
|
||||
#define CHE_HINT 1
|
||||
#define CHE_DONTDRAW 2
|
||||
#define CHE_NONE 0
|
||||
#define CHE_HINT 1
|
||||
#define CHE_CONNECTEDLEFT 2
|
||||
#define CHE_CONNECTEDUP 4
|
||||
#define CHE_DONTDRAW (CHE_CONNECTEDLEFT|CHE_CONNECTEDUP)
|
||||
|
||||
// Condition set setup
|
||||
void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue