Move two of the three remaining NUMMAPS arrays part of the mapheader_t struct
- mapvisited and recorddata_t (previously mainrecords) - Changed how gamedata is saved and loaded - Change the versioncheck (funny hex provided by chengi) AND call it `developringdata.dat` in develop builds - Fix a bunch of off-by-ones in condition and emblem data ALSO, for Time Attack: - Fix menu not showing off your times - Now save times even when gamedata modified, since the menu didn't care (come back to it?) - Don't save times or do intermission screen if the Capsule Attack ended because you lost all your bumpers - Fix a crash adding ghosts in Capsule Attack
This commit is contained in:
parent
03d847d416
commit
07c1fbf426
10 changed files with 148 additions and 108 deletions
|
|
@ -2551,7 +2551,7 @@ void reademblemdata(MYFILE *f, INT32 num)
|
|||
}
|
||||
else if (fastcmp(word, "TAG"))
|
||||
emblemlocations[num-1].tag = (INT16)value;
|
||||
else if (fastcmp(word, "MAPNUM"))
|
||||
else if (fastcmp(word, "MAPNAME"))
|
||||
{
|
||||
emblemlocations[num-1].level = Z_StrDup(word2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,6 +107,23 @@ extern preciptype_t precip_freeslot;
|
|||
extern preciptype_t globalweather;
|
||||
extern preciptype_t curWeather;
|
||||
|
||||
/** Time attack information, currently a very small structure.
|
||||
*/
|
||||
struct recorddata_t
|
||||
{
|
||||
tic_t time; ///< Time in which the level was finished.
|
||||
tic_t lap; ///< Best lap time for this level.
|
||||
//UINT32 score; ///< Score when the level was finished.
|
||||
//UINT16 rings; ///< Rings when the level was finished.
|
||||
};
|
||||
|
||||
// mapvisited is now a set of flags that says what we've done in the map.
|
||||
#define MV_VISITED (1)
|
||||
#define MV_BEATEN (1<<1)
|
||||
#define MV_ENCORE (1<<2)
|
||||
#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE)
|
||||
#define MV_MP ((MV_MAX+1)<<1)
|
||||
|
||||
// Set if homebrew PWAD stuff has been added.
|
||||
extern boolean modifiedgame;
|
||||
extern boolean majormods;
|
||||
|
|
@ -410,6 +427,10 @@ struct mapheader_t
|
|||
fixed_t mobj_scale; ///< Replacement for TOL_ERZ3
|
||||
fixed_t default_waypoint_radius; ///< 0 is a special value for DEFAULT_WAYPOINT_RADIUS, but scaled with mobjscale
|
||||
|
||||
// Record data (modified liberally, saved to gamedata)
|
||||
UINT8 mapvisited; ///< A set of flags that says what we've done in the map.
|
||||
recorddata_t *mainrecord; ///< Stores best time attack data
|
||||
|
||||
// Lua stuff.
|
||||
// (This is not ifdeffed so the map header structure can stay identical, just in case.)
|
||||
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
|
||||
|
|
@ -564,27 +585,6 @@ extern INT32 luabanks[NUM_LUABANKS];
|
|||
|
||||
extern INT32 nummaprings; //keep track of spawned rings/coins
|
||||
|
||||
/** Time attack information, currently a very small structure.
|
||||
*/
|
||||
struct recorddata_t
|
||||
{
|
||||
tic_t time; ///< Time in which the level was finished.
|
||||
tic_t lap; ///< Best lap time for this level.
|
||||
//UINT32 score; ///< Score when the level was finished.
|
||||
//UINT16 rings; ///< Rings when the level was finished.
|
||||
};
|
||||
|
||||
//extern nightsdata_t *nightsrecords[NUMMAPS];
|
||||
extern recorddata_t *mainrecords[NUMMAPS];
|
||||
|
||||
// mapvisited is now a set of flags that says what we've done in the map.
|
||||
#define MV_VISITED (1)
|
||||
#define MV_BEATEN (1<<1)
|
||||
#define MV_ENCORE (1<<2)
|
||||
#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE)
|
||||
#define MV_MP ((MV_MAX+1)<<1)
|
||||
extern UINT8 mapvisited[NUMMAPS];
|
||||
|
||||
extern UINT32 token; ///< Number of tokens collected in a level
|
||||
extern UINT32 tokenlist; ///< List of tokens collected
|
||||
extern boolean gottoken; ///< Did you get a token? Used for end of act
|
||||
|
|
|
|||
|
|
@ -3510,7 +3510,7 @@ void G_AddGhost(char *defdemoname)
|
|||
ghosts = gh;
|
||||
|
||||
gh->version = ghostversion;
|
||||
mthing = playerstarts[0];
|
||||
mthing = playerstarts[0] ? playerstarts[0] : deathmatchstarts[0]; // todo not correct but out of scope
|
||||
I_Assert(mthing);
|
||||
{ // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling.
|
||||
fixed_t z,f,c;
|
||||
|
|
|
|||
153
src/g_game.c
153
src/g_game.c
|
|
@ -210,12 +210,6 @@ tic_t totalplaytime;
|
|||
UINT32 matchesplayed; // SRB2Kart
|
||||
boolean gamedataloaded = false;
|
||||
|
||||
// Time attack data for levels
|
||||
// These are dynamically allocated for space reasons now
|
||||
recorddata_t *mainrecords[NUMMAPS] = {NULL};
|
||||
//nightsdata_t *nightsrecords[NUMMAPS] = {NULL};
|
||||
UINT8 mapvisited[NUMMAPS];
|
||||
|
||||
// Temporary holding place for nights data for the current map
|
||||
//nightsdata_t ntemprecords;
|
||||
|
||||
|
|
@ -539,21 +533,23 @@ INT32 player_name_changes[MAXPLAYERS];
|
|||
// Allocation for time and nights data
|
||||
void G_AllocMainRecordData(INT16 i)
|
||||
{
|
||||
if (!mainrecords[i])
|
||||
mainrecords[i] = Z_Malloc(sizeof(recorddata_t), PU_STATIC, NULL);
|
||||
memset(mainrecords[i], 0, sizeof(recorddata_t));
|
||||
if (i > nummapheaders || !mapheaderinfo[i])
|
||||
I_Error("G_AllocMainRecordData: Internal map ID %d not found (nummapheaders = %d)\n", i, nummapheaders);
|
||||
if (!mapheaderinfo[i]->mainrecord)
|
||||
mapheaderinfo[i]->mainrecord = Z_Malloc(sizeof(recorddata_t), PU_STATIC, NULL);
|
||||
memset(mapheaderinfo[i]->mainrecord, 0, sizeof(recorddata_t));
|
||||
}
|
||||
|
||||
// MAKE SURE YOU SAVE DATA BEFORE CALLING THIS
|
||||
void G_ClearRecords(void)
|
||||
{
|
||||
INT16 i;
|
||||
for (i = 0; i < NUMMAPS; ++i)
|
||||
for (i = 0; i < nummapheaders; ++i)
|
||||
{
|
||||
if (mainrecords[i])
|
||||
if (mapheaderinfo[i]->mainrecord)
|
||||
{
|
||||
Z_Free(mainrecords[i]);
|
||||
mainrecords[i] = NULL;
|
||||
Z_Free(mapheaderinfo[i]->mainrecord);
|
||||
mapheaderinfo[i]->mainrecord = NULL;
|
||||
}
|
||||
/*if (nightsrecords[i])
|
||||
{
|
||||
|
|
@ -566,20 +562,22 @@ void G_ClearRecords(void)
|
|||
// For easy retrieval of records
|
||||
tic_t G_GetBestTime(INT16 map)
|
||||
{
|
||||
if (!mainrecords[map-1] || mainrecords[map-1]->time <= 0)
|
||||
if (!mapheaderinfo[map] || !mapheaderinfo[map]->mainrecord || mapheaderinfo[map]->mainrecord->time <= 0)
|
||||
return (tic_t)UINT32_MAX;
|
||||
|
||||
return mainrecords[map-1]->time;
|
||||
return mapheaderinfo[map]->mainrecord->time;
|
||||
}
|
||||
|
||||
// BE RIGHT BACK
|
||||
|
||||
// Not needed
|
||||
/*
|
||||
tic_t G_GetBestLap(INT16 map)
|
||||
{
|
||||
if (!mainrecords[map-1] || mainrecords[map-1]->lap <= 0)
|
||||
if (!mapheaderinfo[map] || !mapheaderinfo[map]->mainrecord || mapheaderinfo[map]->mainrecord->lap <= 0)
|
||||
return (tic_t)UINT32_MAX;
|
||||
|
||||
return mainrecords[map-1]->lap;
|
||||
return mapheaderinfo[map]->mainrecord->lap;
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
@ -595,7 +593,7 @@ static void G_UpdateRecordReplays(void)
|
|||
UINT8 earnedEmblems;
|
||||
|
||||
// Record new best time
|
||||
if (!mainrecords[gamemap-1])
|
||||
if (!mapheaderinfo[gamemap-1]->mainrecord)
|
||||
G_AllocMainRecordData(gamemap-1);
|
||||
|
||||
if (players[consoleplayer].pflags & PF_NOCONTEST)
|
||||
|
|
@ -603,20 +601,20 @@ static void G_UpdateRecordReplays(void)
|
|||
players[consoleplayer].realtime = UINT32_MAX;
|
||||
}
|
||||
|
||||
if (((mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < mainrecords[gamemap-1]->time))
|
||||
if (((mapheaderinfo[gamemap-1]->mainrecord->time == 0) || (players[consoleplayer].realtime < mapheaderinfo[gamemap-1]->mainrecord->time))
|
||||
&& (players[consoleplayer].realtime < UINT32_MAX)) // DNF
|
||||
{
|
||||
mainrecords[gamemap-1]->time = players[consoleplayer].realtime;
|
||||
mapheaderinfo[gamemap-1]->mainrecord->time = players[consoleplayer].realtime;
|
||||
}
|
||||
|
||||
if (modeattacking == ATTACKING_TIME)
|
||||
{
|
||||
if ((mainrecords[gamemap-1]->lap == 0) || (bestlap < mainrecords[gamemap-1]->lap))
|
||||
mainrecords[gamemap-1]->lap = bestlap;
|
||||
if ((mapheaderinfo[gamemap-1]->mainrecord->lap == 0) || (bestlap < mapheaderinfo[gamemap-1]->mainrecord->lap))
|
||||
mapheaderinfo[gamemap-1]->mainrecord->lap = bestlap;
|
||||
}
|
||||
else
|
||||
{
|
||||
mainrecords[gamemap-1]->lap = 0;
|
||||
mapheaderinfo[gamemap-1]->mainrecord->lap = 0;
|
||||
}
|
||||
|
||||
// Save demo!
|
||||
|
|
@ -3759,20 +3757,19 @@ void G_AddMapToBuffer(INT16 map)
|
|||
//
|
||||
static void G_UpdateVisited(void)
|
||||
{
|
||||
boolean spec = G_IsSpecialStage(gamemap);
|
||||
// Update visitation flags?
|
||||
if ((!modifiedgame || savemoddata) // Not modified
|
||||
&& !multiplayer && !demo.playback // SP/RA/NiGHTS mode
|
||||
&& !(spec && stagefailed)) // Not failed the special stage
|
||||
if (/*(!majormods || savemoddata) // Not modified
|
||||
&&*/ !multiplayer && !demo.playback // SP/RA/NiGHTS mode
|
||||
&& !(modeattacking && (players[consoleplayer].pflags & PF_NOCONTEST))) // Not failed
|
||||
{
|
||||
UINT8 earnedEmblems;
|
||||
|
||||
// Update visitation flags
|
||||
mapvisited[gamemap-1] |= MV_BEATEN;
|
||||
mapheaderinfo[gamemap-1]->mapvisited |= MV_BEATEN;
|
||||
|
||||
if (encoremode == true)
|
||||
{
|
||||
mapvisited[gamemap-1] |= MV_ENCORE;
|
||||
mapheaderinfo[gamemap-1]->mapvisited |= MV_ENCORE;
|
||||
}
|
||||
|
||||
if (modeattacking)
|
||||
|
|
@ -4053,7 +4050,9 @@ static void G_DoCompleted(void)
|
|||
// If the current gametype has no intermission screen set, then don't start it.
|
||||
Y_DetermineIntermissionType();
|
||||
|
||||
if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed) || (intertype == int_none))
|
||||
if ((skipstats && !modeattacking)
|
||||
|| (modeattacking && (players[consoleplayer].pflags & PF_NOCONTEST))
|
||||
|| (intertype == int_none))
|
||||
{
|
||||
G_UpdateVisited();
|
||||
G_HandleSaveLevel();
|
||||
|
|
@ -4285,18 +4284,19 @@ void G_LoadGameSettings(void)
|
|||
S_InitRuntimeSounds();
|
||||
}
|
||||
|
||||
#define GD_VERSIONCHECK 0xBA5ED444
|
||||
|
||||
// G_LoadGameData
|
||||
// Loads the main data file, which stores information such as emblems found, etc.
|
||||
void G_LoadGameData(void)
|
||||
{
|
||||
INT32 i, j;
|
||||
UINT32 i, j;
|
||||
UINT8 modded = false;
|
||||
UINT8 rtemp;
|
||||
savebuffer_t save = {0};
|
||||
|
||||
//For records
|
||||
tic_t rectime;
|
||||
tic_t reclap;
|
||||
UINT32 numgamedatamapheaders;
|
||||
|
||||
// Clear things so previously read gamedata doesn't transfer
|
||||
// to new gamedata
|
||||
|
|
@ -4327,7 +4327,7 @@ void G_LoadGameData(void)
|
|||
return;
|
||||
|
||||
// Version check
|
||||
if (READUINT32(save.p) != 0xFCAFE211)
|
||||
if (READUINT32(save.p) != GD_VERSIONCHECK)
|
||||
{
|
||||
const char *gdfolder = "the SRB2Kart folder";
|
||||
if (strcmp(srb2home,"."))
|
||||
|
|
@ -4355,11 +4355,6 @@ void G_LoadGameData(void)
|
|||
else if (modded != true && modded != false)
|
||||
goto datacorrupt;
|
||||
|
||||
// TODO put another cipher on these things? meh, I don't care...
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
if ((mapvisited[i] = READUINT8(save.p)) > MV_MAX)
|
||||
goto datacorrupt;
|
||||
|
||||
// To save space, use one bit per collected/achieved/unlocked flag
|
||||
for (i = 0; i < MAXEMBLEMS;)
|
||||
{
|
||||
|
|
@ -4393,16 +4388,44 @@ void G_LoadGameData(void)
|
|||
timesBeaten = READUINT32(save.p);
|
||||
|
||||
// Main records
|
||||
for (i = 0; i < NUMMAPS; ++i)
|
||||
numgamedatamapheaders = READUINT32(save.p);
|
||||
if (numgamedatamapheaders >= NEXTMAP_SPECIAL)
|
||||
goto datacorrupt;
|
||||
|
||||
for (i = 0; i < numgamedatamapheaders; i++)
|
||||
{
|
||||
char mapname[MAXMAPLUMPNAME];
|
||||
INT16 mapnum;
|
||||
tic_t rectime;
|
||||
tic_t reclap;
|
||||
|
||||
READSTRINGN(save.p, mapname, sizeof(mapname));
|
||||
mapnum = G_MapNumber(mapname);
|
||||
|
||||
rtemp = READUINT8(save.p);
|
||||
rectime = (tic_t)READUINT32(save.p);
|
||||
reclap = (tic_t)READUINT32(save.p);
|
||||
|
||||
if (rectime || reclap)
|
||||
if (mapnum < nummapheaders && mapheaderinfo[mapnum])
|
||||
{
|
||||
G_AllocMainRecordData((INT16)i);
|
||||
mainrecords[i]->time = rectime;
|
||||
mainrecords[i]->lap = reclap;
|
||||
// Valid mapheader, time to populate with record data.
|
||||
|
||||
if ((mapheaderinfo[mapnum]->mapvisited = rtemp) & ~MV_MAX)
|
||||
goto datacorrupt;
|
||||
|
||||
if (rectime || reclap)
|
||||
{
|
||||
G_AllocMainRecordData((INT16)i);
|
||||
mapheaderinfo[i]->mainrecord->time = rectime;
|
||||
mapheaderinfo[i]->mainrecord->lap = reclap;
|
||||
CONS_Printf("ID %d, Time = %d, Lap = %d\n", i, rectime/35, reclap/35);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Since it's not worth declaring the entire gamedata
|
||||
// corrupt over extra maps, we report and move on.
|
||||
CONS_Alert(CONS_WARNING, "Map with lumpname %s does not exist, time record data will be discarded", mapname);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4439,12 +4462,12 @@ void G_SaveGameData(void)
|
|||
if (!gamedataloaded)
|
||||
return; // If never loaded (-nodata), don't save
|
||||
|
||||
length = 4+4+4+(PWRLV_NUMTYPES*2)+1+(NUMMAPS)
|
||||
length = 4+4+4+(PWRLV_NUMTYPES*2)+1
|
||||
+ BIT_ARRAY_SIZE(MAXEMBLEMS)
|
||||
+ BIT_ARRAY_SIZE(MAXEXTRAEMBLEMS)
|
||||
+ BIT_ARRAY_SIZE(MAXUNLOCKABLES)
|
||||
+ BIT_ARRAY_SIZE(MAXCONDITIONSETS)
|
||||
+ 4+(NUMMAPS*9);
|
||||
+ 4+4+(nummapheaders*(MAXMAPLUMPNAME+1+4+4));
|
||||
|
||||
if (P_SaveBufferAlloc(&save, length) == false)
|
||||
{
|
||||
|
|
@ -4463,22 +4486,18 @@ void G_SaveGameData(void)
|
|||
#endif
|
||||
|
||||
// Version test
|
||||
WRITEUINT32(save.p, 0xFCAFE211);
|
||||
WRITEUINT32(save.p, GD_VERSIONCHECK); // 4
|
||||
|
||||
WRITEUINT32(save.p, totalplaytime);
|
||||
WRITEUINT32(save.p, matchesplayed);
|
||||
WRITEUINT32(save.p, totalplaytime); // 4
|
||||
WRITEUINT32(save.p, matchesplayed); // 4
|
||||
|
||||
for (i = 0; i < PWRLV_NUMTYPES; i++)
|
||||
WRITEUINT16(save.p, vspowerlevel[i]);
|
||||
|
||||
WRITEUINT8(save.p, (UINT8)savemoddata);
|
||||
|
||||
// TODO put another cipher on these things? meh, I don't care...
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
WRITEUINT8(save.p, (mapvisited[i] & MV_MAX));
|
||||
WRITEUINT8(save.p, (UINT8)savemoddata); // 1
|
||||
|
||||
// To save space, use one bit per collected/achieved/unlocked flag
|
||||
for (i = 0; i < MAXEMBLEMS;)
|
||||
for (i = 0; i < MAXEMBLEMS;) // BIT_ARRAY_SIZE(MAXEMBLEMS)
|
||||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j)
|
||||
|
|
@ -4486,7 +4505,7 @@ void G_SaveGameData(void)
|
|||
WRITEUINT8(save.p, btemp);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXEXTRAEMBLEMS;)
|
||||
for (i = 0; i < MAXEXTRAEMBLEMS;) // BIT_ARRAY_SIZE(MAXEXTRAEMBLEMS)
|
||||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j)
|
||||
|
|
@ -4494,7 +4513,7 @@ void G_SaveGameData(void)
|
|||
WRITEUINT8(save.p, btemp);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXUNLOCKABLES;)
|
||||
for (i = 0; i < MAXUNLOCKABLES;) // BIT_ARRAY_SIZE(MAXUNLOCKABLES)
|
||||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
|
||||
|
|
@ -4502,7 +4521,7 @@ void G_SaveGameData(void)
|
|||
WRITEUINT8(save.p, btemp);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXCONDITIONSETS;)
|
||||
for (i = 0; i < MAXCONDITIONSETS;) // BIT_ARRAY_SIZE(MAXCONDITIONSETS)
|
||||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j)
|
||||
|
|
@ -4511,22 +4530,28 @@ void G_SaveGameData(void)
|
|||
i += j;
|
||||
}
|
||||
|
||||
WRITEUINT32(save.p, timesBeaten);
|
||||
WRITEUINT32(save.p, timesBeaten); // 4
|
||||
|
||||
// Main records
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
WRITEUINT32(save.p, nummapheaders); // 4
|
||||
|
||||
for (i = 0; i < nummapheaders; i++) // nummapheaders * (MAXMAPLUMPNAME+1+4+4)
|
||||
{
|
||||
if (mainrecords[i])
|
||||
// For figuring out which header to assing it to on load
|
||||
WRITESTRING(save.p, mapheaderinfo[i]->lumpname);
|
||||
|
||||
WRITEUINT8(save.p, (mapheaderinfo[i]->mapvisited & MV_MAX));
|
||||
|
||||
if (mapheaderinfo[i]->mainrecord)
|
||||
{
|
||||
WRITEUINT32(save.p, mainrecords[i]->time);
|
||||
WRITEUINT32(save.p, mainrecords[i]->lap);
|
||||
WRITEUINT32(save.p, mapheaderinfo[i]->mainrecord->time);
|
||||
WRITEUINT32(save.p, mapheaderinfo[i]->mainrecord->lap);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITEUINT32(save.p, 0);
|
||||
WRITEUINT32(save.p, 0);
|
||||
}
|
||||
WRITEUINT8(save.p, 0); // compat
|
||||
}
|
||||
|
||||
length = save.p - save.buffer;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ extern "C" {
|
|||
extern char gamedatafilename[64];
|
||||
extern char timeattackfolder[64];
|
||||
extern char customversionstring[32];
|
||||
#define GAMEDATASIZE (4*8192)
|
||||
|
||||
extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
|
||||
extern INT32 player_name_changes[MAXPLAYERS];
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ void K_CheckBumpers(void)
|
|||
winnerscoreadd -= players[i].roundscore;
|
||||
}
|
||||
|
||||
if (bossinfo.boss)
|
||||
if (K_CanChangeRules() == false)
|
||||
{
|
||||
if (nobumpers)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1454,7 +1454,7 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
|
|||
else if ((drawtime/TICRATE) & 1)
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("99'59\"99"));
|
||||
|
||||
if (emblemmap && (modeattacking || (mode == 1)) && !demo.playback) // emblem time!
|
||||
if ((modeattacking || (mode == 1)) && !demo.playback) // emblem time!
|
||||
{
|
||||
INT32 workx = TX + 96, worky = TY+18;
|
||||
SINT8 curemb = 0;
|
||||
|
|
|
|||
27
src/m_cond.c
27
src/m_cond.c
|
|
@ -146,7 +146,10 @@ void M_ClearSecrets(void)
|
|||
{
|
||||
INT32 i;
|
||||
|
||||
memset(mapvisited, 0, sizeof(mapvisited));
|
||||
for (i = 0; i < nummapheaders; ++i)
|
||||
{
|
||||
mapheaderinfo[i]->mapvisited = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXEMBLEMS; ++i)
|
||||
emblemlocations[i].collected = false;
|
||||
|
|
@ -181,11 +184,19 @@ UINT8 M_CheckCondition(condition_t *cn)
|
|||
case UC_OVERALLTIME: // Requires overall time <= x
|
||||
return (M_GotLowEnoughTime(cn->requirement));
|
||||
case UC_MAPVISITED: // Requires map x to be visited
|
||||
return ((mapvisited[cn->requirement - 1] & MV_VISITED) == MV_VISITED);
|
||||
case UC_MAPBEATEN: // Requires map x to be beaten
|
||||
return ((mapvisited[cn->requirement - 1] & MV_BEATEN) == MV_BEATEN);
|
||||
case UC_MAPENCORE: // Requires map x to be beaten in encore
|
||||
return ((mapvisited[cn->requirement - 1] & MV_ENCORE) == MV_ENCORE);
|
||||
{
|
||||
UINT8 mvtype = MV_VISITED;
|
||||
if (cn->type == UC_MAPBEATEN)
|
||||
mvtype = MV_BEATEN;
|
||||
else if (cn->type == UC_MAPENCORE)
|
||||
mvtype = MV_ENCORE;
|
||||
|
||||
return ((cn->requirement < nummapheaders)
|
||||
&& (mapheaderinfo[cn->requirement])
|
||||
&& ((mapheaderinfo[cn->requirement]->mapvisited & mvtype) == mvtype));
|
||||
}
|
||||
case UC_MAPTIME: // Requires time on map <= x
|
||||
return (G_GetBestTime(cn->extrainfo1) <= (unsigned)cn->requirement);
|
||||
case UC_TRIGGER: // requires map trigger set
|
||||
|
|
@ -407,7 +418,7 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa
|
|||
if (embtype & ME_ENCORE)
|
||||
flags |= MV_ENCORE;
|
||||
|
||||
res = ((mapvisited[levelnum - 1] & flags) == flags);
|
||||
res = ((mapheaderinfo[levelnum]->mapvisited & flags) == flags);
|
||||
|
||||
emblemlocations[i].collected = res;
|
||||
if (res)
|
||||
|
|
@ -524,9 +535,9 @@ UINT8 M_GotLowEnoughTime(INT32 tictime)
|
|||
if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & LF2_NOTIMEATTACK))
|
||||
continue;
|
||||
|
||||
if (!mainrecords[i] || !mainrecords[i]->time)
|
||||
if (!mapheaderinfo[i]->mainrecord || !mapheaderinfo[i]->mainrecord->time)
|
||||
return false;
|
||||
else if ((curtics += mainrecords[i]->time) > tictime)
|
||||
else if ((curtics += mapheaderinfo[i]->mainrecord->time) > tictime)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -545,7 +556,7 @@ emblem_t *M_GetLevelEmblems(INT32 mapnum)
|
|||
static INT32 map = -1;
|
||||
static INT32 i = -1;
|
||||
|
||||
if (mapnum > 0)
|
||||
if (mapnum >= 0)
|
||||
{
|
||||
map = mapnum;
|
||||
i = numemblems;
|
||||
|
|
|
|||
16
src/m_menu.c
16
src/m_menu.c
|
|
@ -4519,7 +4519,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
|
|||
if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU)
|
||||
return false; // map hell
|
||||
|
||||
if ((mapheaderinfo[mapnum]->menuflags & LF2_VISITNEEDED) && !mapvisited[mapnum])
|
||||
if ((mapheaderinfo[mapnum]->menuflags & LF2_VISITNEEDED) && !mapheaderinfo[mapnum]->mapvisited)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
@ -7712,13 +7712,13 @@ static void M_DrawLevelStats(void)
|
|||
if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & LF2_NOTIMEATTACK))
|
||||
continue;
|
||||
|
||||
if (!mainrecords[i] || mainrecords[i]->time <= 0)
|
||||
if (!mapheaderinfo[i]->mainrecord || mapheaderinfo[i]->mainrecord->time <= 0)
|
||||
{
|
||||
mapsunfinished++;
|
||||
continue;
|
||||
}
|
||||
|
||||
besttime += mainrecords[i]->time;
|
||||
besttime += mapheaderinfo[i]->mainrecord->time;
|
||||
}
|
||||
|
||||
V_DrawString(20, 70, highlightflags, "Combined time records:");
|
||||
|
|
@ -7957,10 +7957,10 @@ void M_DrawTimeAttackMenu(void)
|
|||
{
|
||||
INT32 dupadjust = (vid.width/vid.dupx);
|
||||
tic_t lap = 0, time = 0;
|
||||
if (mainrecords[cv_nextmap.value-1])
|
||||
if (mapheaderinfo[cv_nextmap.value-1]->mainrecord)
|
||||
{
|
||||
lap = mainrecords[cv_nextmap.value-1]->lap;
|
||||
time = mainrecords[cv_nextmap.value-1]->time;
|
||||
lap = mapheaderinfo[cv_nextmap.value-1]->mainrecord->lap;
|
||||
time = mapheaderinfo[cv_nextmap.value-1]->mainrecord->time;
|
||||
}
|
||||
|
||||
V_DrawFill((BASEVIDWIDTH - dupadjust)>>1, 78, dupadjust, 36, 159);
|
||||
|
|
@ -7968,11 +7968,11 @@ void M_DrawTimeAttackMenu(void)
|
|||
if (levellistmode != LLM_ITEMBREAKER)
|
||||
{
|
||||
V_DrawRightAlignedString(149, 80, highlightflags, "BEST LAP:");
|
||||
K_drawKartTimestamp(lap, 19, 86, 0, 2);
|
||||
K_drawKartTimestamp(lap, 19, 86, -1, 2);
|
||||
}
|
||||
|
||||
V_DrawRightAlignedString(292, 80, highlightflags, "BEST TIME:");
|
||||
K_drawKartTimestamp(time, 162, 86, cv_nextmap.value, 1);
|
||||
K_drawKartTimestamp(time, 162, 86, cv_nextmap.value-1, 1);
|
||||
}
|
||||
/*{
|
||||
char beststr[40];
|
||||
|
|
|
|||
|
|
@ -448,6 +448,10 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
// see p_setup.c - prevents replacing maps in addons with different versions
|
||||
mapheaderinfo[num]->alreadyExists = exists;
|
||||
|
||||
mapheaderinfo[num]->mapvisited = 0;
|
||||
Z_Free(mapheaderinfo[num]->mainrecord);
|
||||
mapheaderinfo[num]->mainrecord = NULL;
|
||||
|
||||
mapheaderinfo[num]->customopts = NULL;
|
||||
mapheaderinfo[num]->numCustomOptions = 0;
|
||||
}
|
||||
|
|
@ -466,6 +470,7 @@ void P_AllocMapHeader(INT16 i)
|
|||
mapheaderinfo[i]->thumbnailPic = NULL;
|
||||
mapheaderinfo[i]->minimapPic = NULL;
|
||||
mapheaderinfo[i]->flickies = NULL;
|
||||
mapheaderinfo[i]->mainrecord = NULL;
|
||||
nummapheaders++;
|
||||
}
|
||||
P_ClearSingleMapHeaderInfo(i + 1);
|
||||
|
|
@ -8398,9 +8403,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
R_PrecacheLevel();
|
||||
|
||||
if (!(netgame || multiplayer || demo.playback) && !majormods)
|
||||
mapvisited[gamemap-1] |= MV_VISITED;
|
||||
mapheaderinfo[gamemap-1]->mapvisited |= MV_VISITED;
|
||||
else if (!demo.playback)
|
||||
mapvisited[gamemap-1] |= MV_MP; // you want to record that you've been there this session, but not permanently
|
||||
mapheaderinfo[gamemap-1]->mapvisited |= MV_MP; // you want to record that you've been there this session, but not permanently
|
||||
|
||||
G_AddMapToBuffer(gamemap-1);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue