mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-26 12:01:47 +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
|
||||
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"))
|
||||
{ // RECORDATTACK is an accepted alias
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
|
|
@ -1393,6 +1386,13 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
else
|
||||
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"))
|
||||
mapheaderinfo[num]->gravity = FLOAT_TO_FIXED(atof(word2));
|
||||
else if (fastcmp(word, "DESTROYOBJECTSFORCHALLENGES"))
|
||||
|
|
|
|||
|
|
@ -6890,8 +6890,8 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"LF_SUBTRACTNUM",LF_SUBTRACTNUM},
|
||||
// And map flags
|
||||
{"LF2_HIDEINMENU",LF2_HIDEINMENU},
|
||||
{"LF2_HIDEINSTATS",LF2_HIDEINSTATS},
|
||||
{"LF2_NOTIMEATTACK",LF2_NOTIMEATTACK},
|
||||
{"LF2_NOVISITNEEDED",LF2_NOVISITNEEDED},
|
||||
{"LF2_FINISHNEEDED",LF2_FINISHNEEDED},
|
||||
|
||||
// Emeralds
|
||||
|
|
|
|||
|
|
@ -151,8 +151,6 @@ struct skinreference_t
|
|||
#define MV_SPBATTACK (1<<3)
|
||||
#define MV_MYSTICMELODY (1<<4)
|
||||
#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
|
||||
{
|
||||
|
|
@ -573,8 +571,8 @@ struct mapheader_t
|
|||
#define LF_SUBTRACTNUM (1<<3) ///< Use subtractive position number (for bright levels)
|
||||
|
||||
#define LF2_HIDEINMENU (1<<0) ///< Hide in the multiplayer menu
|
||||
#define LF2_HIDEINSTATS (1<<1) ///< Hide in the statistics screen
|
||||
#define LF2_NOTIMEATTACK (1<<2) ///< Hide this map in Time Attack modes
|
||||
#define LF2_NOTIMEATTACK (1<<1) ///< 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
|
||||
|
||||
extern mapheader_t** mapheaderinfo;
|
||||
|
|
|
|||
163
src/g_game.c
163
src/g_game.c
|
|
@ -3451,10 +3451,32 @@ static INT32 TOLMaps(UINT8 pgametype)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (M_MapLocked(i + 1))
|
||||
// Only care about restrictions if the host is a listen server.
|
||||
if (!dedicated)
|
||||
{
|
||||
// Don't include locked
|
||||
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 ((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++;
|
||||
|
|
@ -3536,10 +3558,32 @@ tryAgain:
|
|||
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.
|
||||
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 ((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)
|
||||
|
|
@ -3974,7 +4018,7 @@ void G_GetNextMap(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < cup->numlevels; i++)
|
||||
for (i = 0; i < CUPCACHE_PODIUM; i++)
|
||||
{
|
||||
cm = cup->cachedlevels[i];
|
||||
|
||||
|
|
@ -3982,9 +4026,35 @@ void G_GetNextMap(void)
|
|||
if (cm >= nummapheaders
|
||||
|| !mapheaderinfo[cm]
|
||||
|| mapheaderinfo[cm]->lumpnum == LUMPERROR
|
||||
|| !(mapheaderinfo[cm]->typeoflevel & tolflag)
|
||||
|| (!marathonmode && M_MapLocked(cm+1)))
|
||||
|| !(mapheaderinfo[cm]->typeoflevel & tolflag))
|
||||
{
|
||||
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 (mapheaderinfo[cm]->cup != cup)
|
||||
|
|
@ -4029,24 +4099,50 @@ void G_GetNextMap(void)
|
|||
else
|
||||
{
|
||||
cm = prevmap;
|
||||
if (++cm >= nummapheaders)
|
||||
cm = 0;
|
||||
|
||||
while (cm != prevmap)
|
||||
do
|
||||
{
|
||||
if (++cm >= nummapheaders)
|
||||
cm = 0;
|
||||
|
||||
if (!mapheaderinfo[cm]
|
||||
|| mapheaderinfo[cm]->lumpnum == LUMPERROR
|
||||
|| !(mapheaderinfo[cm]->typeoflevel & tolflag)
|
||||
|| (mapheaderinfo[cm]->menuflags & LF2_HIDEINMENU)
|
||||
|| M_MapLocked(cm+1))
|
||||
|| (mapheaderinfo[cm]->menuflags & LF2_HIDEINMENU))
|
||||
{
|
||||
if (++cm >= nummapheaders)
|
||||
cm = 0;
|
||||
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;
|
||||
}
|
||||
} while (cm != prevmap);
|
||||
|
||||
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.
|
||||
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();
|
||||
G_UpdateVisited();
|
||||
}
|
||||
else if (grandprixinfo.gp == true)
|
||||
{
|
||||
K_UpdateGPRank(&grandprixinfo.rank);
|
||||
}
|
||||
|
||||
G_UpdateVisited();
|
||||
|
||||
// This isn't in the above blocks because many
|
||||
// mechanisms can queue up a gamedata save.
|
||||
if (gamedata->deferredsave)
|
||||
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
|
||||
|
|
@ -4972,8 +5069,7 @@ void G_LoadGameData(void)
|
|||
M_Memcpy(&mapheaderinfo[mapnum]->records, &dummyrecord, sizeof(recorddata_t));
|
||||
}
|
||||
else if (
|
||||
((dummyrecord.mapvisited & MV_PERSISTUNLOADED) != 0
|
||||
&& (dummyrecord.mapvisited & MV_BEATEN) != 0)
|
||||
(dummyrecord.mapvisited & MV_BEATEN)
|
||||
|| dummyrecord.time != 0
|
||||
|| dummyrecord.lap != 0
|
||||
)
|
||||
|
|
@ -5575,11 +5671,6 @@ void G_SaveGameData(void)
|
|||
|
||||
UINT8 mapvisitedtemp = (mapheaderinfo[i]->records.mapvisited & MV_MAX);
|
||||
|
||||
if ((mapheaderinfo[i]->menuflags & (LF2_FINISHNEEDED|LF2_HIDEINMENU)))
|
||||
{
|
||||
mapvisitedtemp |= MV_FINISHNEEDED;
|
||||
}
|
||||
|
||||
WRITEUINT8(save.p, mapvisitedtemp);
|
||||
|
||||
WRITEUINT32(save.p, mapheaderinfo[i]->records.time);
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ static char hu_tick;
|
|||
|
||||
patch_t *missingpat;
|
||||
patch_t *blanklvl, *nolvl;
|
||||
patch_t *unvisitedlvl[4];
|
||||
|
||||
// song credits
|
||||
static patch_t *songcreditbg;
|
||||
|
|
@ -196,6 +197,11 @@ void HU_LoadGraphics(void)
|
|||
HU_UpdatePatch(&blanklvl, "BLANKLVL");
|
||||
HU_UpdatePatch(&nolvl, "M_NOLVL");
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
HU_UpdatePatch(&unvisitedlvl[i], "PREVST0%d", i+1);
|
||||
}
|
||||
|
||||
HU_UpdatePatch(&songcreditbg, "K_SONGCR");
|
||||
|
||||
// cache ping gfx:
|
||||
|
|
|
|||
|
|
@ -205,6 +205,17 @@ void M_PickMenuBGMap(void)
|
|||
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)
|
||||
{
|
||||
// We haven't earned this one.
|
||||
|
|
@ -2676,24 +2687,28 @@ void M_DrawRaceDifficulty(void)
|
|||
|
||||
// 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;
|
||||
INT16 maxlevels = M_CountLevelsToShowInList(levelsearch);
|
||||
INT16 maxlevels = M_CountLevelsToShowInList(&locklesslevelsearch);
|
||||
const fixed_t step = (82 * FRACUNIT);
|
||||
fixed_t previewanimwork = (cupgrid.previewanim * FRACUNIT) + rendertimefrac_unpaused;
|
||||
fixed_t x = -(previewanimwork % step);
|
||||
INT16 add;
|
||||
INT16 map, start = M_GetFirstLevelInList(&i, levelsearch);
|
||||
INT16 map, start = M_GetFirstLevelInList(&i, &locklesslevelsearch);
|
||||
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;
|
||||
while (add > 0)
|
||||
{
|
||||
map = M_GetNextLevelInList(map, &i, levelsearch);
|
||||
map = M_GetNextLevelInList(map, &i, &locklesslevelsearch);
|
||||
|
||||
if (map >= nummapheaders)
|
||||
{
|
||||
|
|
@ -2710,24 +2725,35 @@ static void M_DrawCupPreview(INT16 y, levelsearch_t *levelsearch)
|
|||
i = starti;
|
||||
}
|
||||
|
||||
K_DrawMapThumbnail(
|
||||
x + FRACUNIT, (y+2)<<FRACBITS,
|
||||
80<<FRACBITS,
|
||||
0,
|
||||
map,
|
||||
NULL);
|
||||
if (M_CanShowLevelInList(map, baselevelsearch))
|
||||
{
|
||||
K_DrawMapThumbnail(
|
||||
x + FRACUNIT, (y+2)<<FRACBITS,
|
||||
80<<FRACBITS,
|
||||
0,
|
||||
map,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch(
|
||||
x + FRACUNIT, (y+2) * FRACUNIT,
|
||||
FRACUNIT,
|
||||
0,
|
||||
staticpat,
|
||||
NULL);
|
||||
}
|
||||
|
||||
x += step;
|
||||
|
||||
map = M_GetNextLevelInList(map, &i, levelsearch);
|
||||
map = M_GetNextLevelInList(map, &i, &locklesslevelsearch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
patch_t *st = W_CachePatchName(va("PREVST0%d", (cupgrid.previewanim % 4) + 1), PU_CACHE);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -3118,7 +3144,13 @@ void M_DrawCupSelect(void)
|
|||
&& templevelsearch.cup != NULL
|
||||
&& 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);
|
||||
|
|
@ -6374,7 +6406,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
|||
templevelsearch.cupmode = true;
|
||||
templevelsearch.timeattack = false;
|
||||
templevelsearch.tutorial = false;
|
||||
templevelsearch.checklocked = false;
|
||||
templevelsearch.checklocked = true;
|
||||
|
||||
M_DrawCupPreview(146, &templevelsearch);
|
||||
|
||||
|
|
@ -7177,7 +7209,7 @@ static void M_DrawStatsMaps(void)
|
|||
for (i = 0; i < nummapheaders; i++)
|
||||
{
|
||||
// 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;
|
||||
|
||||
// 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)
|
||||
continue;
|
||||
if (mapheaderinfo[mapcheck]->menuflags & (LF2_HIDEINSTATS|LF2_HIDEINMENU))
|
||||
if (mapheaderinfo[mapcheck]->menuflags & LF2_HIDEINMENU)
|
||||
continue;
|
||||
if (((mapheaderinfo[mapcheck]->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:
|
||||
{
|
||||
// Don't let netgame sessions intefere
|
||||
// (or have this give a performance hit)
|
||||
if (Playing())
|
||||
return false;
|
||||
|
||||
UINT16 i, unlocked = cn->extrainfo2, total = 0;
|
||||
|
||||
// Special case for maps
|
||||
|
|
@ -1475,7 +1480,7 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
{
|
||||
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;
|
||||
|
||||
total++;
|
||||
|
|
@ -1957,7 +1962,7 @@ static char *M_BuildConditionTitle(UINT16 map)
|
|||
{
|
||||
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"
|
||||
&& !(mapheaderinfo[map]->records.mapvisited & MV_VISITED))
|
||||
|| M_MapLocked(map+1))
|
||||
|
|
|
|||
|
|
@ -21,13 +21,22 @@ static boolean M_StatisticsAddMap(UINT16 map, cupheader_t *cup, boolean *headere
|
|||
return false;
|
||||
|
||||
// Check for no visibility
|
||||
if (mapheaderinfo[map]->menuflags & (LF2_HIDEINSTATS|LF2_HIDEINMENU))
|
||||
if (mapheaderinfo[map]->menuflags & LF2_HIDEINMENU)
|
||||
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
|
||||
if ((mapheaderinfo[map]->menuflags & LF2_FINISHNEEDED)
|
||||
&& !(mapheaderinfo[map]->records.mapvisited & MV_BEATEN))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// Check for unlock
|
||||
if (M_MapLocked(map+1))
|
||||
|
|
@ -80,11 +89,7 @@ static void M_StatisticsMaps(void)
|
|||
headerexists = false;
|
||||
for (i = 0; i < nummapheaders; i++)
|
||||
{
|
||||
if (M_StatisticsAddMap(i, NULL, &headerexists, true))
|
||||
{
|
||||
if (!(mapheaderinfo[i]->records.mapvisited & MV_BEATEN))
|
||||
break;
|
||||
}
|
||||
M_StatisticsAddMap(i, NULL, &headerexists, true);
|
||||
}
|
||||
|
||||
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))
|
||||
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)
|
||||
if (levelsearch->cupmode)
|
||||
{
|
||||
cupheader_t *cup = (levelsearch->cup == &dummy_lostandfound) ? NULL : levelsearch->cup;
|
||||
|
||||
if ((!cup || levelsearch->timeattack)
|
||||
&& mapheaderinfo[mapnum]->cup != cup)
|
||||
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?
|
||||
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
|
||||
if ((mapheaderinfo[mapnum]->menuflags & LF2_FINISHNEEDED)
|
||||
&& !(mapheaderinfo[mapnum]->records.mapvisited & MV_BEATEN))
|
||||
|
|
@ -128,22 +134,9 @@ UINT16 M_CountLevelsToShowInList(levelsearch_t *levelsearch)
|
|||
|
||||
for (i = 0; i < nummapheaders; i++)
|
||||
{
|
||||
if (M_CanShowLevelInList(i, levelsearch))
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (!M_CanShowLevelInList(i, levelsearch))
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
|
|
@ -206,13 +199,6 @@ UINT16 M_GetNextLevelInList(UINT16 mapnum, UINT8 *i, levelsearch_t *levelsearch)
|
|||
}
|
||||
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++;
|
||||
while (!M_CanShowLevelInList(mapnum, levelsearch) && mapnum < nummapheaders)
|
||||
mapnum++;
|
||||
|
|
|
|||
|
|
@ -336,7 +336,14 @@ void M_HandlePauseMenuGametype(INT32 choice)
|
|||
M_ClearMenus(true);
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -900,6 +900,7 @@ struct patch_t
|
|||
|
||||
extern patch_t *missingpat;
|
||||
extern patch_t *blanklvl, *nolvl;
|
||||
extern patch_t *unvisitedlvl[4];
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(1)
|
||||
|
|
|
|||
|
|
@ -1393,11 +1393,13 @@ static boolean S_SoundTestDefLocked(musicdef_t *def)
|
|||
|
||||
mapheader_t *header = mapheaderinfo[def->sequence.map];
|
||||
|
||||
// Is the level tied to SP progression?
|
||||
if ((
|
||||
(header->menuflags & (LF2_FINISHNEEDED|LF2_HIDEINMENU))
|
||||
|| (def->sequence.altref == ALTREF_REQUIRESBEATEN) // Associated music only when completed
|
||||
)
|
||||
// Visitation required?
|
||||
if (!(header->menuflags & LF2_NOVISITNEEDED)
|
||||
&& !(header->records.mapvisited & MV_VISITED))
|
||||
return true;
|
||||
|
||||
// Associated music only when completed
|
||||
if ((def->sequence.altref == ALTREF_REQUIRESBEATEN)
|
||||
&& !(header->records.mapvisited & MV_BEATEN))
|
||||
return true;
|
||||
|
||||
|
|
|
|||
|
|
@ -1982,10 +1982,7 @@ void Y_StartIntermission(void)
|
|||
// determine the tic everybody's scores/PWR starts getting sorted
|
||||
sorttic = -1;
|
||||
if (!timer)
|
||||
{
|
||||
// Prevent a weird bug
|
||||
timer = 1;
|
||||
}
|
||||
;
|
||||
else if (
|
||||
( // Match Race or Time Attack
|
||||
netgame == false
|
||||
|
|
@ -2033,11 +2030,6 @@ void Y_StartIntermission(void)
|
|||
if (prevmap >= nummapheaders || !mapheaderinfo[prevmap])
|
||||
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)
|
||||
{
|
||||
case int_score:
|
||||
|
|
@ -2058,9 +2050,6 @@ void Y_StartIntermission(void)
|
|||
break;
|
||||
}
|
||||
|
||||
LUA_HUD_DestroyDrawList(luahuddrawlist_intermission);
|
||||
luahuddrawlist_intermission = LUA_HUD_CreateDrawList();
|
||||
|
||||
if (powertype != PWRLV_DISABLED)
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
@ -2078,6 +2067,22 @@ void Y_StartIntermission(void)
|
|||
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)
|
||||
{
|
||||
Automate_Run(AEV_QUEUEEND);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue