mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
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
b8f3e64ca1
commit
60355d9efd
11 changed files with 179 additions and 106 deletions
|
|
@ -2334,7 +2334,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,23 @@ extern preciptype_t precip_freeslot;
|
|||
extern preciptype_t globalweather;
|
||||
extern preciptype_t curWeather;
|
||||
|
||||
/** Time attack information, currently a very small structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
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.
|
||||
} recorddata_t;
|
||||
|
||||
// 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;
|
||||
|
|
@ -402,6 +419,10 @@ typedef struct
|
|||
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.
|
||||
|
|
@ -563,27 +584,6 @@ extern INT32 luabanks[NUM_LUABANKS];
|
|||
|
||||
extern INT32 nummaprings; //keep track of spawned rings/coins
|
||||
|
||||
/** Time attack information, currently a very small structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
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.
|
||||
} recorddata_t;
|
||||
|
||||
//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
|
||||
|
|
|
|||
|
|
@ -3358,7 +3358,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;
|
||||
|
|
|
|||
160
src/g_game.c
160
src/g_game.c
|
|
@ -75,7 +75,11 @@ JoyType_t Joystick[MAXSPLITSCREENPLAYERS];
|
|||
#define SAVEGAMESIZE (1024)
|
||||
|
||||
// SRB2kart
|
||||
char gamedatafilename[64] = "ringdata.dat";
|
||||
char gamedatafilename[64] =
|
||||
#ifdef DEVELOP
|
||||
"develop"
|
||||
#endif
|
||||
"ringdata.dat";
|
||||
char timeattackfolder[64] = "ringracers";
|
||||
char customversionstring[32] = "\0";
|
||||
|
||||
|
|
@ -215,12 +219,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;
|
||||
|
||||
|
|
@ -473,21 +471,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])
|
||||
{
|
||||
|
|
@ -500,20 +500,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;
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
@ -530,7 +532,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)
|
||||
|
|
@ -538,20 +540,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!
|
||||
|
|
@ -3616,20 +3618,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)
|
||||
|
|
@ -3910,7 +3911,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();
|
||||
|
|
@ -4142,18 +4145,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)
|
||||
{
|
||||
size_t length;
|
||||
INT32 i, j;
|
||||
UINT32 i, j;
|
||||
UINT8 modded = false;
|
||||
UINT8 rtemp;
|
||||
|
||||
//For records
|
||||
tic_t rectime;
|
||||
tic_t reclap;
|
||||
UINT32 numgamedatamapheaders;
|
||||
|
||||
// Clear things so previously read gamedata doesn't transfer
|
||||
// to new gamedata
|
||||
|
|
@ -4184,7 +4188,7 @@ void G_LoadGameData(void)
|
|||
save_p = savebuffer;
|
||||
|
||||
// Version check
|
||||
if (READUINT32(save_p) != 0xFCAFE211)
|
||||
if (READUINT32(save_p) != GD_VERSIONCHECK)
|
||||
{
|
||||
const char *gdfolder = "the Ring Racers folder";
|
||||
if (strcmp(srb2home,"."))
|
||||
|
|
@ -4206,11 +4210,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;)
|
||||
{
|
||||
|
|
@ -4244,16 +4243,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[255];
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4291,7 +4318,10 @@ void G_SaveGameData(void)
|
|||
if (!gamedataloaded)
|
||||
return; // If never loaded (-nodata), don't save
|
||||
|
||||
save_p = savebuffer = (UINT8 *)malloc(GAMEDATASIZE);
|
||||
length = (4+4+4+1+(MAXEMBLEMS)+MAXEXTRAEMBLEMS+MAXUNLOCKABLES+MAXCONDITIONSETS+4+4);
|
||||
length += nummapheaders * (255+1+4+4);
|
||||
|
||||
save_p = savebuffer = (UINT8 *)malloc(length);
|
||||
if (!save_p)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n"));
|
||||
|
|
@ -4309,19 +4339,15 @@ 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
|
||||
|
||||
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;) // MAXEMBLEMS * 1;
|
||||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j)
|
||||
|
|
@ -4329,7 +4355,7 @@ void G_SaveGameData(void)
|
|||
WRITEUINT8(save_p, btemp);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXEXTRAEMBLEMS;)
|
||||
for (i = 0; i < MAXEXTRAEMBLEMS;) // MAXEXTRAEMBLEMS * 1;
|
||||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j)
|
||||
|
|
@ -4337,7 +4363,7 @@ void G_SaveGameData(void)
|
|||
WRITEUINT8(save_p, btemp);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXUNLOCKABLES;)
|
||||
for (i = 0; i < MAXUNLOCKABLES;) // MAXUNLOCKABLES * 1;
|
||||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
|
||||
|
|
@ -4345,7 +4371,7 @@ void G_SaveGameData(void)
|
|||
WRITEUINT8(save_p, btemp);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXCONDITIONSETS;)
|
||||
for (i = 0; i < MAXCONDITIONSETS;) // MAXCONDITIONSETS * 1;
|
||||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j)
|
||||
|
|
@ -4354,22 +4380,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 * (255+1+4+4)
|
||||
{
|
||||
if (mainrecords[i])
|
||||
// For figuring out which header to assing it to on load
|
||||
WRITESTRINGN(save_p, mapheaderinfo[i]->lumpname, 255);
|
||||
|
||||
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 - savebuffer;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
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];
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "s_sound.h"
|
||||
#include "m_random.h"
|
||||
#include "r_sky.h" // skyflatnum
|
||||
#include "k_grandprix.h" // K_CanChangeRules
|
||||
|
||||
// Battle overtime info
|
||||
struct battleovertime battleovertime;
|
||||
|
|
@ -126,7 +127,7 @@ void K_CheckBumpers(void)
|
|||
winnerscoreadd -= players[i].roundscore;
|
||||
}
|
||||
|
||||
if (bossinfo.boss)
|
||||
if (K_CanChangeRules() == false)
|
||||
{
|
||||
if (nobumpers)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -218,6 +218,15 @@ extern menu_t PLAY_LevelSelectDef;
|
|||
extern menuitem_t PLAY_TimeAttack[];
|
||||
extern menu_t PLAY_TimeAttackDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ta_replay = 0,
|
||||
ta_guest,
|
||||
ta_ghosts,
|
||||
ta_spacer,
|
||||
ta_start,
|
||||
} ta_e;
|
||||
|
||||
extern menuitem_t PLAY_TAReplay[];
|
||||
extern menu_t PLAY_TAReplayDef;
|
||||
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ menu_t PLAY_LevelSelectDef = {
|
|||
NULL
|
||||
};
|
||||
|
||||
// see ta_e
|
||||
menuitem_t PLAY_TimeAttack[] =
|
||||
{
|
||||
{IT_STRING | IT_SUBMENU, "Replay...", NULL, NULL, {.submenu = &PLAY_TAReplayDef}, 0, 0},
|
||||
|
|
|
|||
|
|
@ -2159,19 +2159,34 @@ void M_DrawTimeAttack(void)
|
|||
|
||||
V_DrawScaledPatch(149+t, 70, 0, W_CachePatchName("BESTTIME", PU_CACHE));
|
||||
|
||||
if (currentMenu == &PLAY_TimeAttackDef)
|
||||
if (currentMenu == &PLAY_TimeAttackDef && mapheaderinfo[map])
|
||||
{
|
||||
if (mapheaderinfo[map])
|
||||
tic_t timerec = 0;
|
||||
tic_t laprec = 0;
|
||||
UINT32 timeheight = 82;
|
||||
|
||||
if ((minimap = mapheaderinfo[map]->minimapPic))
|
||||
V_DrawScaledPatch(24-t, 82, 0, minimap);
|
||||
|
||||
if (mapheaderinfo[map]->mainrecord)
|
||||
{
|
||||
if ((minimap = mapheaderinfo[map]->minimapPic))
|
||||
V_DrawScaledPatch(24-t, 82, 0, minimap);
|
||||
timerec = mapheaderinfo[map]->mainrecord->time;
|
||||
laprec = mapheaderinfo[map]->mainrecord->lap;
|
||||
}
|
||||
|
||||
V_DrawRightAlignedString(rightedge-12, 82, highlightflags, "BEST LAP:");
|
||||
K_drawKartTimestamp(0, 162+t, 88, 0, 2);
|
||||
if (levellist.newgametype != GT_BATTLE)
|
||||
{
|
||||
V_DrawRightAlignedString(rightedge-12, timeheight, highlightflags, "BEST LAP:");
|
||||
K_drawKartTimestamp(laprec, 162+t, timeheight+6, 0, 2);
|
||||
timeheight += 30;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeheight += 15;
|
||||
}
|
||||
|
||||
V_DrawRightAlignedString(rightedge-12, 112, highlightflags, "BEST TIME:");
|
||||
K_drawKartTimestamp(0, 162+t, 118, map, 1);
|
||||
V_DrawRightAlignedString(rightedge-12, timeheight, highlightflags, "BEST TIME:");
|
||||
K_drawKartTimestamp(timerec, 162+t, timeheight+6, map, 1);
|
||||
}
|
||||
else
|
||||
opty = 80;
|
||||
|
|
|
|||
25
src/m_cond.c
25
src/m_cond.c
|
|
@ -81,7 +81,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;
|
||||
|
|
@ -129,11 +132,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
|
||||
|
|
@ -355,7 +366,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)
|
||||
|
|
@ -477,9 +488,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;
|
||||
|
|
|
|||
|
|
@ -408,6 +408,10 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
P_DeleteFlickies(num);
|
||||
#endif
|
||||
|
||||
mapheaderinfo[num]->mapvisited = 0;
|
||||
Z_Free(mapheaderinfo[num]->mainrecord);
|
||||
mapheaderinfo[num]->mainrecord = NULL;
|
||||
|
||||
mapheaderinfo[num]->customopts = NULL;
|
||||
mapheaderinfo[num]->numCustomOptions = 0;
|
||||
}
|
||||
|
|
@ -426,6 +430,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);
|
||||
|
|
@ -4265,9 +4270,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
skipstats = 0;
|
||||
|
||||
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…
Add table
Reference in a new issue