diff --git a/src/deh_soc.c b/src/deh_soc.c index 103579cb1..3e9855256 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -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); } diff --git a/src/doomstat.h b/src/doomstat.h index b47f9a4d2..a9d82419b 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -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 diff --git a/src/g_demo.c b/src/g_demo.c index 59b943d97..5313a1699 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -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; diff --git a/src/g_game.c b/src/g_game.c index 027a96011..7a3e90676 100644 --- a/src/g_game.c +++ b/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; diff --git a/src/g_game.h b/src/g_game.h index b0a0e7320..3cc0963cf 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -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]; diff --git a/src/k_battle.c b/src/k_battle.c index 14ecfabf5..e8afc580f 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -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) { diff --git a/src/k_menu.h b/src/k_menu.h index 415c54284..982d0bcf9 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -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; diff --git a/src/k_menudef.c b/src/k_menudef.c index d97083509..903366c73 100644 --- a/src/k_menudef.c +++ b/src/k_menudef.c @@ -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}, diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 8a1e368d3..598ad9b48 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -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; diff --git a/src/m_cond.c b/src/m_cond.c index cf2c41c3f..94169936c 100644 --- a/src/m_cond.c +++ b/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; diff --git a/src/p_setup.c b/src/p_setup.c index 3aefd4e1a..a74d9c137 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -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);