mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Lost and Found
- When selecting levels:
- If the gametype uses cups
- and a map has no cup
- and you're not in Grand Prix mode
- show those maps in a quasi-cup called "Lost and Found".
- Implementation details:
- a few == checks for the pointer to `cupheader_t dummy_lostandfound`
- Otherwise most of the apparatus was built as part of prior art!
This commit is contained in:
parent
1d3b5adfdf
commit
1701662b6b
3 changed files with 87 additions and 32 deletions
|
|
@ -743,6 +743,8 @@ extern struct levellist_s {
|
||||||
boolean netgame; // Start the game in an actual server
|
boolean netgame; // Start the game in an actual server
|
||||||
} levellist;
|
} levellist;
|
||||||
|
|
||||||
|
extern cupheader_t dummy_lostandfound;
|
||||||
|
|
||||||
boolean M_CanShowLevelInList(INT16 mapnum, levelsearch_t *levelsearch);
|
boolean M_CanShowLevelInList(INT16 mapnum, levelsearch_t *levelsearch);
|
||||||
UINT16 M_CountLevelsToShowInList(levelsearch_t *levelsearch);
|
UINT16 M_CountLevelsToShowInList(levelsearch_t *levelsearch);
|
||||||
UINT16 M_GetFirstLevelInList(UINT8 *i, levelsearch_t *levelsearch);
|
UINT16 M_GetFirstLevelInList(UINT8 *i, levelsearch_t *levelsearch);
|
||||||
|
|
|
||||||
|
|
@ -2092,7 +2092,11 @@ static void M_DrawCupTitle(INT16 y, levelsearch_t *levelsearch)
|
||||||
|
|
||||||
V_DrawScaledPatch(0, y, 0, W_CachePatchName("MENUHINT", PU_CACHE));
|
V_DrawScaledPatch(0, y, 0, W_CachePatchName("MENUHINT", PU_CACHE));
|
||||||
|
|
||||||
if (levelsearch->cup)
|
if (levelsearch->cup == &dummy_lostandfound)
|
||||||
|
{
|
||||||
|
V_DrawCenteredLSTitleLowString(BASEVIDWIDTH/2, y+6, 0, "Lost and Found");
|
||||||
|
}
|
||||||
|
else if (levelsearch->cup)
|
||||||
{
|
{
|
||||||
boolean unlocked = (M_GetFirstLevelInList(&temp, levelsearch) != NEXTMAP_INVALID);
|
boolean unlocked = (M_GetFirstLevelInList(&temp, levelsearch) != NEXTMAP_INVALID);
|
||||||
UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GREY, GTC_MENUCACHE);
|
UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GREY, GTC_MENUCACHE);
|
||||||
|
|
@ -2176,6 +2180,12 @@ void M_DrawCupSelect(void)
|
||||||
colormap = NULL;
|
colormap = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (templevelsearch.cup == &dummy_lostandfound)
|
||||||
|
{
|
||||||
|
// No cup? Lost and found!
|
||||||
|
monitor = '0';
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (templevelsearch.cup->monitor < 10)
|
if (templevelsearch.cup->monitor < 10)
|
||||||
{
|
{
|
||||||
|
|
@ -2200,7 +2210,9 @@ void M_DrawCupSelect(void)
|
||||||
|
|
||||||
V_DrawFixedPatch((x)*FRACUNIT, (y)<<FRACBITS, FRACUNIT, 0, patch, colormap);
|
V_DrawFixedPatch((x)*FRACUNIT, (y)<<FRACBITS, FRACUNIT, 0, patch, colormap);
|
||||||
|
|
||||||
if (M_GetFirstLevelInList(&temp, &templevelsearch) == NEXTMAP_INVALID)
|
if (templevelsearch.cup == &dummy_lostandfound)
|
||||||
|
; // Only ever placed on the list if valid
|
||||||
|
else if (M_GetFirstLevelInList(&temp, &templevelsearch) == NEXTMAP_INVALID)
|
||||||
{
|
{
|
||||||
patch_t *st = W_CachePatchName(va("ICONST0%d", (cupgrid.previewanim % 4) + 1), PU_CACHE);
|
patch_t *st = W_CachePatchName(va("ICONST0%d", (cupgrid.previewanim % 4) + 1), PU_CACHE);
|
||||||
V_DrawScaledPatch(x + 8, y + icony, 0, st);
|
V_DrawScaledPatch(x + 8, y + icony, 0, st);
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
#include "../../f_finale.h" // F_WipeStartScreen
|
#include "../../f_finale.h" // F_WipeStartScreen
|
||||||
#include "../../v_video.h"
|
#include "../../v_video.h"
|
||||||
|
|
||||||
|
cupheader_t dummy_lostandfound;
|
||||||
|
|
||||||
menuitem_t PLAY_LevelSelect[] =
|
menuitem_t PLAY_LevelSelect[] =
|
||||||
{
|
{
|
||||||
{IT_NOTHING | IT_KEYHANDLER, NULL, NULL, NULL, {.routine = M_LevelSelectHandler}, 0, 0},
|
{IT_NOTHING | IT_KEYHANDLER, NULL, NULL, NULL, {.routine = M_LevelSelectHandler}, 0, 0},
|
||||||
|
|
@ -71,10 +73,14 @@ boolean M_CanShowLevelInList(INT16 mapnum, levelsearch_t *levelsearch)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Don't permit cup when no cup requested (also no dupes in time attack)
|
// Don't permit cup when no cup requested (also no dupes in time attack)
|
||||||
if (levelsearch->cupmode
|
if (levelsearch->cupmode)
|
||||||
&& (levelsearch->timeattack || !levelsearch->cup)
|
{
|
||||||
&& mapheaderinfo[mapnum]->cup != levelsearch->cup)
|
cupheader_t *cup = (levelsearch->cup == &dummy_lostandfound) ? NULL : levelsearch->cup;
|
||||||
return false;
|
|
||||||
|
if ((!cup || levelsearch->timeattack)
|
||||||
|
&& mapheaderinfo[mapnum]->cup != cup)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Finally, the most complex check: does the map have lock conditions?
|
// Finally, the most complex check: does the map have lock conditions?
|
||||||
if (levelsearch->checklocked)
|
if (levelsearch->checklocked)
|
||||||
|
|
@ -100,7 +106,7 @@ UINT16 M_CountLevelsToShowInList(levelsearch_t *levelsearch)
|
||||||
if (!levelsearch)
|
if (!levelsearch)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (levelsearch->cup)
|
if (levelsearch->cup && levelsearch->cup != &dummy_lostandfound)
|
||||||
{
|
{
|
||||||
if (levelsearch->checklocked && M_CupLocked(levelsearch->cup))
|
if (levelsearch->checklocked && M_CupLocked(levelsearch->cup))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -129,7 +135,7 @@ UINT16 M_GetFirstLevelInList(UINT8 *i, levelsearch_t *levelsearch)
|
||||||
if (!levelsearch)
|
if (!levelsearch)
|
||||||
return NEXTMAP_INVALID;
|
return NEXTMAP_INVALID;
|
||||||
|
|
||||||
if (levelsearch->cup)
|
if (levelsearch->cup && levelsearch->cup != &dummy_lostandfound)
|
||||||
{
|
{
|
||||||
if (levelsearch->checklocked && M_CupLocked(levelsearch->cup))
|
if (levelsearch->checklocked && M_CupLocked(levelsearch->cup))
|
||||||
{
|
{
|
||||||
|
|
@ -165,7 +171,7 @@ UINT16 M_GetNextLevelInList(UINT16 mapnum, UINT8 *i, levelsearch_t *levelsearch)
|
||||||
if (!levelsearch)
|
if (!levelsearch)
|
||||||
return NEXTMAP_INVALID;
|
return NEXTMAP_INVALID;
|
||||||
|
|
||||||
if (levelsearch->cup)
|
if (levelsearch->cup && levelsearch->cup != &dummy_lostandfound)
|
||||||
{
|
{
|
||||||
mapnum = NEXTMAP_INVALID;
|
mapnum = NEXTMAP_INVALID;
|
||||||
(*i)++;
|
(*i)++;
|
||||||
|
|
@ -213,6 +219,9 @@ boolean M_LevelListFromGametype(INT16 gt)
|
||||||
{
|
{
|
||||||
cupgrid.cappages = 0;
|
cupgrid.cappages = 0;
|
||||||
cupgrid.builtgrid = NULL;
|
cupgrid.builtgrid = NULL;
|
||||||
|
dummy_lostandfound.cachedlevels[0] = NEXTMAP_INVALID;
|
||||||
|
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
levellist.newgametype = gt;
|
levellist.newgametype = gt;
|
||||||
|
|
@ -232,8 +241,6 @@ boolean M_LevelListFromGametype(INT16 gt)
|
||||||
levellist.levelsearch.cupmode = (!(gametypes[gt]->rules & GTR_NOCUPSELECT));
|
levellist.levelsearch.cupmode = (!(gametypes[gt]->rules & GTR_NOCUPSELECT));
|
||||||
|
|
||||||
CV_SetValue(&cv_dummyspbattack, 0);
|
CV_SetValue(&cv_dummyspbattack, 0);
|
||||||
|
|
||||||
first = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obviously go to Cup Select in gametypes that have cups.
|
// Obviously go to Cup Select in gametypes that have cups.
|
||||||
|
|
@ -269,6 +276,31 @@ boolean M_LevelListFromGametype(INT16 gt)
|
||||||
}
|
}
|
||||||
memset(cupgrid.builtgrid, 0, cupgrid.cappages * pagelen);
|
memset(cupgrid.builtgrid, 0, cupgrid.cappages * pagelen);
|
||||||
|
|
||||||
|
// The following doubles the size of the buffer if necessary.
|
||||||
|
#define GRID_INSERTCUP \
|
||||||
|
if ((currentid * sizeof(cupheader_t*)) >= cupgrid.cappages * pagelen) \
|
||||||
|
{ \
|
||||||
|
const size_t firstlen = cupgrid.cappages * pagelen; \
|
||||||
|
cupgrid.builtgrid = Z_Realloc(cupgrid.builtgrid, \
|
||||||
|
firstlen * 2, \
|
||||||
|
PU_STATIC, NULL); \
|
||||||
|
\
|
||||||
|
if (!cupgrid.builtgrid) \
|
||||||
|
{ \
|
||||||
|
I_Error("M_LevelListFromGametype: Not enough memory to reallocate builtgrid"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
cupgrid.cappages *= 2; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
cupgrid.builtgrid[currentid] = templevelsearch.cup;
|
||||||
|
|
||||||
|
#define GRID_FOCUSCUP \
|
||||||
|
cupgrid.x = currentid % CUPMENU_COLUMNS; \
|
||||||
|
cupgrid.y = (currentid / CUPMENU_COLUMNS) % CUPMENU_ROWS; \
|
||||||
|
cupgrid.pageno = currentid / (CUPMENU_COLUMNS * CUPMENU_ROWS); \
|
||||||
|
currentvalid = true;
|
||||||
|
|
||||||
while (templevelsearch.cup)
|
while (templevelsearch.cup)
|
||||||
{
|
{
|
||||||
templevelsearch.checklocked = false;
|
templevelsearch.checklocked = false;
|
||||||
|
|
@ -281,23 +313,7 @@ boolean M_LevelListFromGametype(INT16 gt)
|
||||||
|
|
||||||
foundany = true;
|
foundany = true;
|
||||||
|
|
||||||
if ((currentid * sizeof(cupheader_t*)) >= cupgrid.cappages * pagelen)
|
GRID_INSERTCUP;
|
||||||
{
|
|
||||||
// Double the size of the buffer, and clear the other stuff.
|
|
||||||
const size_t firstlen = cupgrid.cappages * pagelen;
|
|
||||||
cupgrid.builtgrid = Z_Realloc(cupgrid.builtgrid,
|
|
||||||
firstlen * 2,
|
|
||||||
PU_STATIC, NULL);
|
|
||||||
|
|
||||||
if (!cupgrid.builtgrid)
|
|
||||||
{
|
|
||||||
I_Error("M_LevelListFromGametype: Not enough memory to reallocate builtgrid");
|
|
||||||
}
|
|
||||||
|
|
||||||
cupgrid.cappages *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
cupgrid.builtgrid[currentid] = templevelsearch.cup;
|
|
||||||
|
|
||||||
templevelsearch.checklocked = true;
|
templevelsearch.checklocked = true;
|
||||||
if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID)
|
if (M_GetFirstLevelInList(&temp, &templevelsearch) != NEXTMAP_INVALID)
|
||||||
|
|
@ -308,10 +324,7 @@ boolean M_LevelListFromGametype(INT16 gt)
|
||||||
? (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == templevelsearch.cup)
|
? (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == templevelsearch.cup)
|
||||||
: (gt == -1 && levellist.levelsearch.cup == templevelsearch.cup))
|
: (gt == -1 && levellist.levelsearch.cup == templevelsearch.cup))
|
||||||
{
|
{
|
||||||
cupgrid.x = currentid % CUPMENU_COLUMNS;
|
GRID_FOCUSCUP;
|
||||||
cupgrid.y = (currentid / CUPMENU_COLUMNS) % CUPMENU_ROWS;
|
|
||||||
cupgrid.pageno = currentid / (CUPMENU_COLUMNS * CUPMENU_ROWS);
|
|
||||||
currentvalid = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -319,6 +332,34 @@ boolean M_LevelListFromGametype(INT16 gt)
|
||||||
templevelsearch.cup = templevelsearch.cup->next;
|
templevelsearch.cup = templevelsearch.cup->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lost and found, a simplified version of the above loop.
|
||||||
|
if (cupgrid.grandprix == false)
|
||||||
|
{
|
||||||
|
templevelsearch.cup = &dummy_lostandfound;
|
||||||
|
templevelsearch.checklocked = true;
|
||||||
|
|
||||||
|
if (M_GetFirstLevelInList(&temp, &levellist.levelsearch) != NEXTMAP_INVALID)
|
||||||
|
{
|
||||||
|
foundany = true;
|
||||||
|
GRID_INSERTCUP;
|
||||||
|
highestunlockedid = currentid;
|
||||||
|
|
||||||
|
if (Playing()
|
||||||
|
? (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == NULL)
|
||||||
|
: (gt == -1 && levellist.levelsearch.cup == templevelsearch.cup))
|
||||||
|
{
|
||||||
|
GRID_FOCUSCUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
templevelsearch.cup = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef GRID_INSERTCUP
|
||||||
|
#undef GRID_FOCUSCUP
|
||||||
|
|
||||||
if (foundany == false)
|
if (foundany == false)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue