mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-27 12:31:54 +00:00
Merge branch 'map-access-flingerdinger' into 'master'
Stronger Course progression restriction Closes #832, #859, and #839 See merge request KartKrew/Kart!1795
This commit is contained in:
commit
df5c866573
13 changed files with 257 additions and 119 deletions
|
|
@ -1372,13 +1372,6 @@ void readlevelheader(MYFILE *f, char * name)
|
||||||
else
|
else
|
||||||
mapheaderinfo[num]->menuflags &= ~LF2_HIDEINMENU;
|
mapheaderinfo[num]->menuflags &= ~LF2_HIDEINMENU;
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "HIDEINSTATS"))
|
|
||||||
{
|
|
||||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
|
||||||
mapheaderinfo[num]->menuflags |= LF2_HIDEINSTATS;
|
|
||||||
else
|
|
||||||
mapheaderinfo[num]->menuflags &= ~LF2_HIDEINSTATS;
|
|
||||||
}
|
|
||||||
else if (fastcmp(word, "NOTIMEATTACK") || fastcmp(word, "NORECORDATTACK"))
|
else if (fastcmp(word, "NOTIMEATTACK") || fastcmp(word, "NORECORDATTACK"))
|
||||||
{ // RECORDATTACK is an accepted alias
|
{ // RECORDATTACK is an accepted alias
|
||||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||||
|
|
@ -1393,6 +1386,13 @@ void readlevelheader(MYFILE *f, char * name)
|
||||||
else
|
else
|
||||||
mapheaderinfo[num]->menuflags &= ~LF2_FINISHNEEDED;
|
mapheaderinfo[num]->menuflags &= ~LF2_FINISHNEEDED;
|
||||||
}
|
}
|
||||||
|
else if (fastcmp(word, "NOVISITNEEDED"))
|
||||||
|
{
|
||||||
|
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||||
|
mapheaderinfo[num]->menuflags |= LF2_NOVISITNEEDED;
|
||||||
|
else
|
||||||
|
mapheaderinfo[num]->menuflags &= ~LF2_NOVISITNEEDED;
|
||||||
|
}
|
||||||
else if (fastcmp(word, "GRAVITY"))
|
else if (fastcmp(word, "GRAVITY"))
|
||||||
mapheaderinfo[num]->gravity = FLOAT_TO_FIXED(atof(word2));
|
mapheaderinfo[num]->gravity = FLOAT_TO_FIXED(atof(word2));
|
||||||
else if (fastcmp(word, "DESTROYOBJECTSFORCHALLENGES"))
|
else if (fastcmp(word, "DESTROYOBJECTSFORCHALLENGES"))
|
||||||
|
|
|
||||||
|
|
@ -6890,8 +6890,8 @@ struct int_const_s const INT_CONST[] = {
|
||||||
{"LF_SUBTRACTNUM",LF_SUBTRACTNUM},
|
{"LF_SUBTRACTNUM",LF_SUBTRACTNUM},
|
||||||
// And map flags
|
// And map flags
|
||||||
{"LF2_HIDEINMENU",LF2_HIDEINMENU},
|
{"LF2_HIDEINMENU",LF2_HIDEINMENU},
|
||||||
{"LF2_HIDEINSTATS",LF2_HIDEINSTATS},
|
|
||||||
{"LF2_NOTIMEATTACK",LF2_NOTIMEATTACK},
|
{"LF2_NOTIMEATTACK",LF2_NOTIMEATTACK},
|
||||||
|
{"LF2_NOVISITNEEDED",LF2_NOVISITNEEDED},
|
||||||
{"LF2_FINISHNEEDED",LF2_FINISHNEEDED},
|
{"LF2_FINISHNEEDED",LF2_FINISHNEEDED},
|
||||||
|
|
||||||
// Emeralds
|
// Emeralds
|
||||||
|
|
|
||||||
|
|
@ -151,8 +151,6 @@ struct skinreference_t
|
||||||
#define MV_SPBATTACK (1<<3)
|
#define MV_SPBATTACK (1<<3)
|
||||||
#define MV_MYSTICMELODY (1<<4)
|
#define MV_MYSTICMELODY (1<<4)
|
||||||
#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE|MV_SPBATTACK|MV_MYSTICMELODY)
|
#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE|MV_SPBATTACK|MV_MYSTICMELODY)
|
||||||
#define MV_FINISHNEEDED (1<<7)
|
|
||||||
#define MV_PERSISTUNLOADED (MV_SPBATTACK|MV_FINISHNEEDED)
|
|
||||||
|
|
||||||
struct recorddata_t
|
struct recorddata_t
|
||||||
{
|
{
|
||||||
|
|
@ -573,8 +571,8 @@ struct mapheader_t
|
||||||
#define LF_SUBTRACTNUM (1<<3) ///< Use subtractive position number (for bright levels)
|
#define LF_SUBTRACTNUM (1<<3) ///< Use subtractive position number (for bright levels)
|
||||||
|
|
||||||
#define LF2_HIDEINMENU (1<<0) ///< Hide in the multiplayer menu
|
#define LF2_HIDEINMENU (1<<0) ///< Hide in the multiplayer menu
|
||||||
#define LF2_HIDEINSTATS (1<<1) ///< Hide in the statistics screen
|
#define LF2_NOTIMEATTACK (1<<1) ///< Hide this map in Time Attack modes
|
||||||
#define LF2_NOTIMEATTACK (1<<2) ///< Hide this map in Time Attack modes
|
#define LF2_NOVISITNEEDED (1<<2) ///< Map does not require visitation to be selectable
|
||||||
#define LF2_FINISHNEEDED (1<<3) ///< Not available in Time Attack modes until you beat the level
|
#define LF2_FINISHNEEDED (1<<3) ///< Not available in Time Attack modes until you beat the level
|
||||||
|
|
||||||
extern mapheader_t** mapheaderinfo;
|
extern mapheader_t** mapheaderinfo;
|
||||||
|
|
|
||||||
163
src/g_game.c
163
src/g_game.c
|
|
@ -3451,10 +3451,32 @@ static INT32 TOLMaps(UINT8 pgametype)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (M_MapLocked(i + 1))
|
// Only care about restrictions if the host is a listen server.
|
||||||
|
if (!dedicated)
|
||||||
{
|
{
|
||||||
// Don't include locked
|
if (!(mapheaderinfo[i]->menuflags & LF2_NOVISITNEEDED)
|
||||||
continue;
|
&& !(mapheaderinfo[i]->records.mapvisited & MV_VISITED)
|
||||||
|
&& !(
|
||||||
|
mapheaderinfo[i]->cup
|
||||||
|
&& mapheaderinfo[i]->cup->cachedlevels[0] == i
|
||||||
|
))
|
||||||
|
{
|
||||||
|
// Not visited OR head of cup
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mapheaderinfo[i]->menuflags & LF2_FINISHNEEDED)
|
||||||
|
&& !(mapheaderinfo[i]->records.mapvisited & MV_BEATEN))
|
||||||
|
{
|
||||||
|
// Not completed
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (M_MapLocked(i + 1) == true)
|
||||||
|
{
|
||||||
|
// We haven't earned this one.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
num++;
|
num++;
|
||||||
|
|
@ -3536,10 +3558,32 @@ tryAgain:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (M_MapLocked(i + 1) == true)
|
// Only care about restrictions if the host is a listen server.
|
||||||
|
if (!dedicated)
|
||||||
{
|
{
|
||||||
// We haven't earned this one.
|
if (!(mapheaderinfo[i]->menuflags & LF2_NOVISITNEEDED)
|
||||||
continue;
|
&& !(mapheaderinfo[i]->records.mapvisited & MV_VISITED)
|
||||||
|
&& !(
|
||||||
|
mapheaderinfo[i]->cup
|
||||||
|
&& mapheaderinfo[i]->cup->cachedlevels[0] == i
|
||||||
|
))
|
||||||
|
{
|
||||||
|
// Not visited OR head of cup
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mapheaderinfo[i]->menuflags & LF2_FINISHNEEDED)
|
||||||
|
&& !(mapheaderinfo[i]->records.mapvisited & MV_BEATEN))
|
||||||
|
{
|
||||||
|
// Not completed
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (M_MapLocked(i + 1) == true)
|
||||||
|
{
|
||||||
|
// We haven't earned this one.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ignoreBuffers == false)
|
if (ignoreBuffers == false)
|
||||||
|
|
@ -3974,7 +4018,7 @@ void G_GetNextMap(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < cup->numlevels; i++)
|
for (i = 0; i < CUPCACHE_PODIUM; i++)
|
||||||
{
|
{
|
||||||
cm = cup->cachedlevels[i];
|
cm = cup->cachedlevels[i];
|
||||||
|
|
||||||
|
|
@ -3982,9 +4026,35 @@ void G_GetNextMap(void)
|
||||||
if (cm >= nummapheaders
|
if (cm >= nummapheaders
|
||||||
|| !mapheaderinfo[cm]
|
|| !mapheaderinfo[cm]
|
||||||
|| mapheaderinfo[cm]->lumpnum == LUMPERROR
|
|| mapheaderinfo[cm]->lumpnum == LUMPERROR
|
||||||
|| !(mapheaderinfo[cm]->typeoflevel & tolflag)
|
|| !(mapheaderinfo[cm]->typeoflevel & tolflag))
|
||||||
|| (!marathonmode && M_MapLocked(cm+1)))
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only care about restrictions if the host is a listen server.
|
||||||
|
if (!dedicated && !marathonmode)
|
||||||
|
{
|
||||||
|
if (!(mapheaderinfo[cm]->menuflags & LF2_NOVISITNEEDED)
|
||||||
|
&& !(mapheaderinfo[cm]->records.mapvisited & MV_VISITED)
|
||||||
|
&& i != 0)
|
||||||
|
{
|
||||||
|
// Not visited OR head of cup
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mapheaderinfo[cm]->menuflags & LF2_FINISHNEEDED)
|
||||||
|
&& !(mapheaderinfo[cm]->records.mapvisited & MV_BEATEN))
|
||||||
|
{
|
||||||
|
// Not completed
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (M_MapLocked(cm + 1) == true)
|
||||||
|
{
|
||||||
|
// We haven't earned this one.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the map is in multiple cups, only consider the first one valid.
|
// If the map is in multiple cups, only consider the first one valid.
|
||||||
if (mapheaderinfo[cm]->cup != cup)
|
if (mapheaderinfo[cm]->cup != cup)
|
||||||
|
|
@ -4029,24 +4099,50 @@ void G_GetNextMap(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cm = prevmap;
|
cm = prevmap;
|
||||||
if (++cm >= nummapheaders)
|
|
||||||
cm = 0;
|
|
||||||
|
|
||||||
while (cm != prevmap)
|
do
|
||||||
{
|
{
|
||||||
|
if (++cm >= nummapheaders)
|
||||||
|
cm = 0;
|
||||||
|
|
||||||
if (!mapheaderinfo[cm]
|
if (!mapheaderinfo[cm]
|
||||||
|| mapheaderinfo[cm]->lumpnum == LUMPERROR
|
|| mapheaderinfo[cm]->lumpnum == LUMPERROR
|
||||||
|| !(mapheaderinfo[cm]->typeoflevel & tolflag)
|
|| !(mapheaderinfo[cm]->typeoflevel & tolflag)
|
||||||
|| (mapheaderinfo[cm]->menuflags & LF2_HIDEINMENU)
|
|| (mapheaderinfo[cm]->menuflags & LF2_HIDEINMENU))
|
||||||
|| M_MapLocked(cm+1))
|
|
||||||
{
|
{
|
||||||
if (++cm >= nummapheaders)
|
|
||||||
cm = 0;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only care about restrictions if the host is a listen server.
|
||||||
|
if (!dedicated && !marathonmode)
|
||||||
|
{
|
||||||
|
if (!(mapheaderinfo[cm]->menuflags & LF2_NOVISITNEEDED)
|
||||||
|
&& !(mapheaderinfo[cm]->records.mapvisited & MV_VISITED)
|
||||||
|
&& !(
|
||||||
|
mapheaderinfo[cm]->cup
|
||||||
|
&& mapheaderinfo[cm]->cup->cachedlevels[0] == cm
|
||||||
|
))
|
||||||
|
{
|
||||||
|
// Not visited OR head of cup
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mapheaderinfo[cm]->menuflags & LF2_FINISHNEEDED)
|
||||||
|
&& !(mapheaderinfo[cm]->records.mapvisited & MV_BEATEN))
|
||||||
|
{
|
||||||
|
// Not completed
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (M_MapLocked(cm + 1) == true)
|
||||||
|
{
|
||||||
|
// We haven't earned this one.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
} while (cm != prevmap);
|
||||||
|
|
||||||
nextmap = cm;
|
nextmap = cm;
|
||||||
}
|
}
|
||||||
|
|
@ -4295,26 +4391,27 @@ static void G_DoCompleted(void)
|
||||||
// If the current gametype has no intermission screen set, then don't start it.
|
// If the current gametype has no intermission screen set, then don't start it.
|
||||||
Y_DetermineIntermissionType();
|
Y_DetermineIntermissionType();
|
||||||
|
|
||||||
if (intertype == int_none)
|
if (intertype != int_none)
|
||||||
{
|
{
|
||||||
G_UpdateVisited();
|
|
||||||
if (grandprixinfo.gp == true)
|
|
||||||
{
|
|
||||||
K_UpdateGPRank(&grandprixinfo.rank);
|
|
||||||
}
|
|
||||||
G_AfterIntermission();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
G_SetGamestate(GS_INTERMISSION);
|
|
||||||
Y_StartIntermission();
|
Y_StartIntermission();
|
||||||
G_UpdateVisited();
|
|
||||||
}
|
}
|
||||||
|
else if (grandprixinfo.gp == true)
|
||||||
|
{
|
||||||
|
K_UpdateGPRank(&grandprixinfo.rank);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_UpdateVisited();
|
||||||
|
|
||||||
// This isn't in the above blocks because many
|
// This isn't in the above blocks because many
|
||||||
// mechanisms can queue up a gamedata save.
|
// mechanisms can queue up a gamedata save.
|
||||||
if (gamedata->deferredsave)
|
if (gamedata->deferredsave)
|
||||||
G_SaveGameData();
|
G_SaveGameData();
|
||||||
|
|
||||||
|
// Seperate from the above, as Y_StartIntermission can no-sell.
|
||||||
|
if (intertype == int_none)
|
||||||
|
{
|
||||||
|
G_AfterIntermission();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// See also F_EndCutscene, the only other place which handles intra-map/ending transitions
|
// See also F_EndCutscene, the only other place which handles intra-map/ending transitions
|
||||||
|
|
@ -4972,8 +5069,7 @@ void G_LoadGameData(void)
|
||||||
M_Memcpy(&mapheaderinfo[mapnum]->records, &dummyrecord, sizeof(recorddata_t));
|
M_Memcpy(&mapheaderinfo[mapnum]->records, &dummyrecord, sizeof(recorddata_t));
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
((dummyrecord.mapvisited & MV_PERSISTUNLOADED) != 0
|
(dummyrecord.mapvisited & MV_BEATEN)
|
||||||
&& (dummyrecord.mapvisited & MV_BEATEN) != 0)
|
|
||||||
|| dummyrecord.time != 0
|
|| dummyrecord.time != 0
|
||||||
|| dummyrecord.lap != 0
|
|| dummyrecord.lap != 0
|
||||||
)
|
)
|
||||||
|
|
@ -5575,11 +5671,6 @@ void G_SaveGameData(void)
|
||||||
|
|
||||||
UINT8 mapvisitedtemp = (mapheaderinfo[i]->records.mapvisited & MV_MAX);
|
UINT8 mapvisitedtemp = (mapheaderinfo[i]->records.mapvisited & MV_MAX);
|
||||||
|
|
||||||
if ((mapheaderinfo[i]->menuflags & (LF2_FINISHNEEDED|LF2_HIDEINMENU)))
|
|
||||||
{
|
|
||||||
mapvisitedtemp |= MV_FINISHNEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
WRITEUINT8(save.p, mapvisitedtemp);
|
WRITEUINT8(save.p, mapvisitedtemp);
|
||||||
|
|
||||||
WRITEUINT32(save.p, mapheaderinfo[i]->records.time);
|
WRITEUINT32(save.p, mapheaderinfo[i]->records.time);
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ static char hu_tick;
|
||||||
|
|
||||||
patch_t *missingpat;
|
patch_t *missingpat;
|
||||||
patch_t *blanklvl, *nolvl;
|
patch_t *blanklvl, *nolvl;
|
||||||
|
patch_t *unvisitedlvl[4];
|
||||||
|
|
||||||
// song credits
|
// song credits
|
||||||
static patch_t *songcreditbg;
|
static patch_t *songcreditbg;
|
||||||
|
|
@ -196,6 +197,11 @@ void HU_LoadGraphics(void)
|
||||||
HU_UpdatePatch(&blanklvl, "BLANKLVL");
|
HU_UpdatePatch(&blanklvl, "BLANKLVL");
|
||||||
HU_UpdatePatch(&nolvl, "M_NOLVL");
|
HU_UpdatePatch(&nolvl, "M_NOLVL");
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
HU_UpdatePatch(&unvisitedlvl[i], "PREVST0%d", i+1);
|
||||||
|
}
|
||||||
|
|
||||||
HU_UpdatePatch(&songcreditbg, "K_SONGCR");
|
HU_UpdatePatch(&songcreditbg, "K_SONGCR");
|
||||||
|
|
||||||
// cache ping gfx:
|
// cache ping gfx:
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,17 @@ void M_PickMenuBGMap(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(mapheaderinfo[i]->menuflags & LF2_NOVISITNEEDED)
|
||||||
|
&& !(mapheaderinfo[i]->records.mapvisited & MV_VISITED)
|
||||||
|
&& !(
|
||||||
|
mapheaderinfo[i]->cup
|
||||||
|
&& mapheaderinfo[i]->cup->cachedlevels[0] == i
|
||||||
|
))
|
||||||
|
{
|
||||||
|
// Not visited OR head of cup
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (M_MapLocked(i + 1) == true)
|
if (M_MapLocked(i + 1) == true)
|
||||||
{
|
{
|
||||||
// We haven't earned this one.
|
// We haven't earned this one.
|
||||||
|
|
@ -2676,24 +2687,28 @@ void M_DrawRaceDifficulty(void)
|
||||||
|
|
||||||
// LEVEL SELECT
|
// LEVEL SELECT
|
||||||
|
|
||||||
static void M_DrawCupPreview(INT16 y, levelsearch_t *levelsearch)
|
static void M_DrawCupPreview(INT16 y, levelsearch_t *baselevelsearch)
|
||||||
{
|
{
|
||||||
|
levelsearch_t locklesslevelsearch = *baselevelsearch; // full copy
|
||||||
|
locklesslevelsearch.checklocked = false;
|
||||||
|
|
||||||
UINT8 i = 0;
|
UINT8 i = 0;
|
||||||
INT16 maxlevels = M_CountLevelsToShowInList(levelsearch);
|
INT16 maxlevels = M_CountLevelsToShowInList(&locklesslevelsearch);
|
||||||
const fixed_t step = (82 * FRACUNIT);
|
const fixed_t step = (82 * FRACUNIT);
|
||||||
fixed_t previewanimwork = (cupgrid.previewanim * FRACUNIT) + rendertimefrac_unpaused;
|
fixed_t previewanimwork = (cupgrid.previewanim * FRACUNIT) + rendertimefrac_unpaused;
|
||||||
fixed_t x = -(previewanimwork % step);
|
fixed_t x = -(previewanimwork % step);
|
||||||
INT16 add;
|
INT16 map, start = M_GetFirstLevelInList(&i, &locklesslevelsearch);
|
||||||
INT16 map, start = M_GetFirstLevelInList(&i, levelsearch);
|
|
||||||
UINT8 starti = i;
|
UINT8 starti = i;
|
||||||
|
|
||||||
if (levelsearch->cup && maxlevels > 0)
|
patch_t *staticpat = unvisitedlvl[cupgrid.previewanim % 4];
|
||||||
|
|
||||||
|
if (baselevelsearch->cup && maxlevels > 0)
|
||||||
{
|
{
|
||||||
add = (previewanimwork / step) % maxlevels;
|
INT16 add = (previewanimwork / step) % maxlevels;
|
||||||
map = start;
|
map = start;
|
||||||
while (add > 0)
|
while (add > 0)
|
||||||
{
|
{
|
||||||
map = M_GetNextLevelInList(map, &i, levelsearch);
|
map = M_GetNextLevelInList(map, &i, &locklesslevelsearch);
|
||||||
|
|
||||||
if (map >= nummapheaders)
|
if (map >= nummapheaders)
|
||||||
{
|
{
|
||||||
|
|
@ -2710,24 +2725,35 @@ static void M_DrawCupPreview(INT16 y, levelsearch_t *levelsearch)
|
||||||
i = starti;
|
i = starti;
|
||||||
}
|
}
|
||||||
|
|
||||||
K_DrawMapThumbnail(
|
if (M_CanShowLevelInList(map, baselevelsearch))
|
||||||
x + FRACUNIT, (y+2)<<FRACBITS,
|
{
|
||||||
80<<FRACBITS,
|
K_DrawMapThumbnail(
|
||||||
0,
|
x + FRACUNIT, (y+2)<<FRACBITS,
|
||||||
map,
|
80<<FRACBITS,
|
||||||
NULL);
|
0,
|
||||||
|
map,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
V_DrawFixedPatch(
|
||||||
|
x + FRACUNIT, (y+2) * FRACUNIT,
|
||||||
|
FRACUNIT,
|
||||||
|
0,
|
||||||
|
staticpat,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
x += step;
|
x += step;
|
||||||
|
|
||||||
map = M_GetNextLevelInList(map, &i, levelsearch);
|
map = M_GetNextLevelInList(map, &i, &locklesslevelsearch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
patch_t *st = W_CachePatchName(va("PREVST0%d", (cupgrid.previewanim % 4) + 1), PU_CACHE);
|
|
||||||
while (x < BASEVIDWIDTH * FRACUNIT)
|
while (x < BASEVIDWIDTH * FRACUNIT)
|
||||||
{
|
{
|
||||||
V_DrawFixedPatch(x + FRACUNIT, (y+2) * FRACUNIT, FRACUNIT, 0, st, NULL);
|
V_DrawFixedPatch(x + FRACUNIT, (y+2) * FRACUNIT, FRACUNIT, 0, staticpat, NULL);
|
||||||
x += step;
|
x += step;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3118,7 +3144,13 @@ void M_DrawCupSelect(void)
|
||||||
&& templevelsearch.cup != NULL
|
&& templevelsearch.cup != NULL
|
||||||
&& templevelsearch.cup == cupsavedata.cup)
|
&& templevelsearch.cup == cupsavedata.cup)
|
||||||
{
|
{
|
||||||
V_DrawScaledPatch(x + 32, y + 32, 0, W_CachePatchName("CUPBKUP2", PU_CACHE));
|
V_DrawScaledPatch(
|
||||||
|
14 + (cupgrid.x*42) + 32,
|
||||||
|
20 + (cupgrid.y*44) + 32
|
||||||
|
+ ((cupgrid.cache_secondrowlocked == true) ? 28 : 0),
|
||||||
|
0,
|
||||||
|
W_CachePatchName("CUPBKUP2", PU_CACHE)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
INT16 ty = M_EaseWithTransition(Easing_Linear, 5 * 24);
|
INT16 ty = M_EaseWithTransition(Easing_Linear, 5 * 24);
|
||||||
|
|
@ -6374,7 +6406,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
||||||
templevelsearch.cupmode = true;
|
templevelsearch.cupmode = true;
|
||||||
templevelsearch.timeattack = false;
|
templevelsearch.timeattack = false;
|
||||||
templevelsearch.tutorial = false;
|
templevelsearch.tutorial = false;
|
||||||
templevelsearch.checklocked = false;
|
templevelsearch.checklocked = true;
|
||||||
|
|
||||||
M_DrawCupPreview(146, &templevelsearch);
|
M_DrawCupPreview(146, &templevelsearch);
|
||||||
|
|
||||||
|
|
@ -7177,7 +7209,7 @@ static void M_DrawStatsMaps(void)
|
||||||
for (i = 0; i < nummapheaders; i++)
|
for (i = 0; i < nummapheaders; i++)
|
||||||
{
|
{
|
||||||
// Check for no visibility
|
// Check for no visibility
|
||||||
if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & (LF2_NOTIMEATTACK|LF2_HIDEINSTATS|LF2_HIDEINMENU)))
|
if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & (LF2_NOTIMEATTACK|LF2_HIDEINMENU)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Has to be accessible via time attack
|
// Has to be accessible via time attack
|
||||||
|
|
|
||||||
11
src/m_cond.c
11
src/m_cond.c
|
|
@ -1094,7 +1094,7 @@ static void M_PrecacheLevelLocks(void)
|
||||||
{
|
{
|
||||||
if (!mapheaderinfo[mapcheck] || mapheaderinfo[mapcheck]->cup != NULL)
|
if (!mapheaderinfo[mapcheck] || mapheaderinfo[mapcheck]->cup != NULL)
|
||||||
continue;
|
continue;
|
||||||
if (mapheaderinfo[mapcheck]->menuflags & (LF2_HIDEINSTATS|LF2_HIDEINMENU))
|
if (mapheaderinfo[mapcheck]->menuflags & LF2_HIDEINMENU)
|
||||||
continue;
|
continue;
|
||||||
if (((mapheaderinfo[mapcheck]->typeoflevel & TOL_TUTORIAL) == TOL_TUTORIAL)
|
if (((mapheaderinfo[mapcheck]->typeoflevel & TOL_TUTORIAL) == TOL_TUTORIAL)
|
||||||
!= ((mapheaderinfo[map]->typeoflevel & TOL_TUTORIAL) == TOL_TUTORIAL))
|
!= ((mapheaderinfo[map]->typeoflevel & TOL_TUTORIAL) == TOL_TUTORIAL))
|
||||||
|
|
@ -1468,6 +1468,11 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
||||||
|
|
||||||
case UC_UNLOCKPERCENT:
|
case UC_UNLOCKPERCENT:
|
||||||
{
|
{
|
||||||
|
// Don't let netgame sessions intefere
|
||||||
|
// (or have this give a performance hit)
|
||||||
|
if (Playing())
|
||||||
|
return false;
|
||||||
|
|
||||||
UINT16 i, unlocked = cn->extrainfo2, total = 0;
|
UINT16 i, unlocked = cn->extrainfo2, total = 0;
|
||||||
|
|
||||||
// Special case for maps
|
// Special case for maps
|
||||||
|
|
@ -1475,7 +1480,7 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
||||||
{
|
{
|
||||||
for (i = 0; i < basenummapheaders; i++)
|
for (i = 0; i < basenummapheaders; i++)
|
||||||
{
|
{
|
||||||
if (!mapheaderinfo[i] || mapheaderinfo[i]->menuflags & (LF2_HIDEINSTATS|LF2_HIDEINMENU))
|
if (!mapheaderinfo[i] || mapheaderinfo[i]->menuflags & (LF2_HIDEINMENU))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
total++;
|
total++;
|
||||||
|
|
@ -1957,7 +1962,7 @@ static char *M_BuildConditionTitle(UINT16 map)
|
||||||
{
|
{
|
||||||
char *title, *ref;
|
char *title, *ref;
|
||||||
|
|
||||||
if (((mapheaderinfo[map]->menuflags & LF2_FINISHNEEDED)
|
if ((!(mapheaderinfo[map]->menuflags & LF2_NOVISITNEEDED)
|
||||||
// the following is intentionally not MV_BEATEN, just in case the title is for "Finish a round on X"
|
// the following is intentionally not MV_BEATEN, just in case the title is for "Finish a round on X"
|
||||||
&& !(mapheaderinfo[map]->records.mapvisited & MV_VISITED))
|
&& !(mapheaderinfo[map]->records.mapvisited & MV_VISITED))
|
||||||
|| M_MapLocked(map+1))
|
|| M_MapLocked(map+1))
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,22 @@ static boolean M_StatisticsAddMap(UINT16 map, cupheader_t *cup, boolean *headere
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check for no visibility
|
// Check for no visibility
|
||||||
if (mapheaderinfo[map]->menuflags & (LF2_HIDEINSTATS|LF2_HIDEINMENU))
|
if (mapheaderinfo[map]->menuflags & LF2_HIDEINMENU)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Check for visitation
|
||||||
|
// (M_CanShowLevelInList also checks being the first map in a cup,
|
||||||
|
// but we don't need to do this here because it'd just muddy stats!)
|
||||||
|
if (!(mapheaderinfo[map]->menuflags & LF2_NOVISITNEEDED)
|
||||||
|
&& !(mapheaderinfo[map]->records.mapvisited & MV_VISITED))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#if 0
|
||||||
// Check for completion
|
// Check for completion
|
||||||
if ((mapheaderinfo[map]->menuflags & LF2_FINISHNEEDED)
|
if ((mapheaderinfo[map]->menuflags & LF2_FINISHNEEDED)
|
||||||
&& !(mapheaderinfo[map]->records.mapvisited & MV_BEATEN))
|
&& !(mapheaderinfo[map]->records.mapvisited & MV_BEATEN))
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check for unlock
|
// Check for unlock
|
||||||
if (M_MapLocked(map+1))
|
if (M_MapLocked(map+1))
|
||||||
|
|
@ -80,11 +89,7 @@ static void M_StatisticsMaps(void)
|
||||||
headerexists = false;
|
headerexists = false;
|
||||||
for (i = 0; i < nummapheaders; i++)
|
for (i = 0; i < nummapheaders; i++)
|
||||||
{
|
{
|
||||||
if (M_StatisticsAddMap(i, NULL, &headerexists, true))
|
M_StatisticsAddMap(i, NULL, &headerexists, true);
|
||||||
{
|
|
||||||
if (!(mapheaderinfo[i]->records.mapvisited & MV_BEATEN))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((i = statisticsmenu.numextramedals) != 0)
|
if ((i = statisticsmenu.numextramedals) != 0)
|
||||||
|
|
|
||||||
|
|
@ -77,11 +77,11 @@ boolean M_CanShowLevelInList(INT16 mapnum, levelsearch_t *levelsearch)
|
||||||
if (levelsearch->timeattack && (mapheaderinfo[mapnum]->menuflags & LF2_NOTIMEATTACK))
|
if (levelsearch->timeattack && (mapheaderinfo[mapnum]->menuflags & LF2_NOTIMEATTACK))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
cupheader_t *cup = (levelsearch->cup == &dummy_lostandfound) ? NULL : levelsearch->cup;
|
||||||
|
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
cupheader_t *cup = (levelsearch->cup == &dummy_lostandfound) ? NULL : levelsearch->cup;
|
|
||||||
|
|
||||||
if ((!cup || levelsearch->timeattack)
|
if ((!cup || levelsearch->timeattack)
|
||||||
&& mapheaderinfo[mapnum]->cup != cup)
|
&& mapheaderinfo[mapnum]->cup != cup)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -90,6 +90,12 @@ boolean M_CanShowLevelInList(INT16 mapnum, levelsearch_t *levelsearch)
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
|
// Check for visitation
|
||||||
|
if (!(mapheaderinfo[mapnum]->menuflags & LF2_NOVISITNEEDED)
|
||||||
|
&& !(mapheaderinfo[mapnum]->records.mapvisited & MV_VISITED)
|
||||||
|
&& !(cup && cup->cachedlevels[0] == mapnum))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Check for completion
|
// Check for completion
|
||||||
if ((mapheaderinfo[mapnum]->menuflags & LF2_FINISHNEEDED)
|
if ((mapheaderinfo[mapnum]->menuflags & LF2_FINISHNEEDED)
|
||||||
&& !(mapheaderinfo[mapnum]->records.mapvisited & MV_BEATEN))
|
&& !(mapheaderinfo[mapnum]->records.mapvisited & MV_BEATEN))
|
||||||
|
|
@ -128,22 +134,9 @@ UINT16 M_CountLevelsToShowInList(levelsearch_t *levelsearch)
|
||||||
|
|
||||||
for (i = 0; i < nummapheaders; i++)
|
for (i = 0; i < nummapheaders; i++)
|
||||||
{
|
{
|
||||||
if (M_CanShowLevelInList(i, levelsearch))
|
if (!M_CanShowLevelInList(i, levelsearch))
|
||||||
{
|
continue;
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
// Tutorial will only show what you've made your way to
|
|
||||||
if (!levelsearch->checklocked)
|
|
||||||
continue;
|
|
||||||
if (!levelsearch->tutorial)
|
|
||||||
continue;
|
|
||||||
if (i >= basenummapheaders)
|
|
||||||
continue;
|
|
||||||
if (mapheaderinfo[i]->records.mapvisited & MV_BEATEN)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
@ -206,13 +199,6 @@ UINT16 M_GetNextLevelInList(UINT16 mapnum, UINT8 *i, levelsearch_t *levelsearch)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Tutorial will only show what you've made your way to
|
|
||||||
if (levelsearch->checklocked
|
|
||||||
&& levelsearch->tutorial
|
|
||||||
&& mapnum < basenummapheaders
|
|
||||||
&& !(mapheaderinfo[mapnum]->records.mapvisited & MV_BEATEN))
|
|
||||||
return NEXTMAP_INVALID;
|
|
||||||
|
|
||||||
mapnum++;
|
mapnum++;
|
||||||
while (!M_CanShowLevelInList(mapnum, levelsearch) && mapnum < nummapheaders)
|
while (!M_CanShowLevelInList(mapnum, levelsearch) && mapnum < nummapheaders)
|
||||||
mapnum++;
|
mapnum++;
|
||||||
|
|
|
||||||
|
|
@ -336,7 +336,14 @@ void M_HandlePauseMenuGametype(INT32 choice)
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
if (server || IsPlayerAdmin(consoleplayer))
|
if (server || IsPlayerAdmin(consoleplayer))
|
||||||
{
|
{
|
||||||
D_SetupVote(menugametype);
|
if (cv_advancemap.value == 3) // Voting screen.
|
||||||
|
{
|
||||||
|
D_SetupVote(menugametype);
|
||||||
|
}
|
||||||
|
else // ideally for "random" only, but no sane fallback for "same" and "next"
|
||||||
|
{
|
||||||
|
COM_ImmedExecute(va("randommap -gt %s", gametypes[menugametype]->name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -900,6 +900,7 @@ struct patch_t
|
||||||
|
|
||||||
extern patch_t *missingpat;
|
extern patch_t *missingpat;
|
||||||
extern patch_t *blanklvl, *nolvl;
|
extern patch_t *blanklvl, *nolvl;
|
||||||
|
extern patch_t *unvisitedlvl[4];
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
|
||||||
|
|
@ -1393,11 +1393,13 @@ static boolean S_SoundTestDefLocked(musicdef_t *def)
|
||||||
|
|
||||||
mapheader_t *header = mapheaderinfo[def->sequence.map];
|
mapheader_t *header = mapheaderinfo[def->sequence.map];
|
||||||
|
|
||||||
// Is the level tied to SP progression?
|
// Visitation required?
|
||||||
if ((
|
if (!(header->menuflags & LF2_NOVISITNEEDED)
|
||||||
(header->menuflags & (LF2_FINISHNEEDED|LF2_HIDEINMENU))
|
&& !(header->records.mapvisited & MV_VISITED))
|
||||||
|| (def->sequence.altref == ALTREF_REQUIRESBEATEN) // Associated music only when completed
|
return true;
|
||||||
)
|
|
||||||
|
// Associated music only when completed
|
||||||
|
if ((def->sequence.altref == ALTREF_REQUIRESBEATEN)
|
||||||
&& !(header->records.mapvisited & MV_BEATEN))
|
&& !(header->records.mapvisited & MV_BEATEN))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1982,10 +1982,7 @@ void Y_StartIntermission(void)
|
||||||
// determine the tic everybody's scores/PWR starts getting sorted
|
// determine the tic everybody's scores/PWR starts getting sorted
|
||||||
sorttic = -1;
|
sorttic = -1;
|
||||||
if (!timer)
|
if (!timer)
|
||||||
{
|
;
|
||||||
// Prevent a weird bug
|
|
||||||
timer = 1;
|
|
||||||
}
|
|
||||||
else if (
|
else if (
|
||||||
( // Match Race or Time Attack
|
( // Match Race or Time Attack
|
||||||
netgame == false
|
netgame == false
|
||||||
|
|
@ -2033,11 +2030,6 @@ void Y_StartIntermission(void)
|
||||||
if (prevmap >= nummapheaders || !mapheaderinfo[prevmap])
|
if (prevmap >= nummapheaders || !mapheaderinfo[prevmap])
|
||||||
I_Error("Y_StartIntermission: Internal map ID %d not found (nummapheaders = %d)", prevmap, nummapheaders);
|
I_Error("Y_StartIntermission: Internal map ID %d not found (nummapheaders = %d)", prevmap, nummapheaders);
|
||||||
|
|
||||||
if (timer > 1 && musiccountdown == 0)
|
|
||||||
Music_Play("intermission");
|
|
||||||
|
|
||||||
S_ShowMusicCredit(); // Always call
|
|
||||||
|
|
||||||
switch (intertype)
|
switch (intertype)
|
||||||
{
|
{
|
||||||
case int_score:
|
case int_score:
|
||||||
|
|
@ -2058,9 +2050,6 @@ void Y_StartIntermission(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LUA_HUD_DestroyDrawList(luahuddrawlist_intermission);
|
|
||||||
luahuddrawlist_intermission = LUA_HUD_CreateDrawList();
|
|
||||||
|
|
||||||
if (powertype != PWRLV_DISABLED)
|
if (powertype != PWRLV_DISABLED)
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
|
@ -2078,6 +2067,22 @@ void Y_StartIntermission(void)
|
||||||
SV_BumpMatchStats();
|
SV_BumpMatchStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!timer)
|
||||||
|
{
|
||||||
|
Y_EndIntermission();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_SetGamestate(GS_INTERMISSION);
|
||||||
|
|
||||||
|
if (musiccountdown == 0)
|
||||||
|
Music_Play("intermission");
|
||||||
|
|
||||||
|
S_ShowMusicCredit(); // Always call
|
||||||
|
|
||||||
|
LUA_HUD_DestroyDrawList(luahuddrawlist_intermission);
|
||||||
|
luahuddrawlist_intermission = LUA_HUD_CreateDrawList();
|
||||||
|
|
||||||
if (roundqueue.size > 0 && roundqueue.position == roundqueue.size)
|
if (roundqueue.size > 0 && roundqueue.position == roundqueue.size)
|
||||||
{
|
{
|
||||||
Automate_Run(AEV_QUEUEEND);
|
Automate_Run(AEV_QUEUEEND);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue