Merge pull request 'Add Support for Multiple records per map.' (#44) from trimaprecords into blankart-dev
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/44
This commit is contained in:
commit
d8c7bbbc7e
11 changed files with 222 additions and 125 deletions
|
|
@ -158,7 +158,8 @@ void clear_levels(void)
|
|||
|
||||
P_DeleteFlickies(nummapheaders);
|
||||
|
||||
Z_Free(mapheaderinfo[nummapheaders]->mainrecord);
|
||||
for (SINT8 k = 0; k < MAXMAPRECORDS; k++)
|
||||
Z_Free(mapheaderinfo[nummapheaders]->mainrecord[k]);
|
||||
|
||||
Patch_Free(mapheaderinfo[nummapheaders]->thumbnailPic);
|
||||
Patch_Free(mapheaderinfo[nummapheaders]->minimapPic);
|
||||
|
|
|
|||
|
|
@ -632,6 +632,9 @@ struct menu_routine_s const MENU_ROUTINES[] = {
|
|||
{ "CHOOSETIMEATTACK", &M_ChooseTimeAttack },
|
||||
{ "SETGUESTREPLAY", &M_SetGuestReplay },
|
||||
{ "REPLAYTIMEATTACK", &M_ReplayTimeAttack },
|
||||
{ "SRB2KARTPRESET", &M_SRB2KartPreset },
|
||||
{ "TECHPRESET", &M_TechPreset },
|
||||
{ "BLANKARTPRESET", &M_BlanKartPreset },
|
||||
{ "HANDLESTAFFREPLAY", &M_HandleStaffReplay },
|
||||
{ "SETUPMULTIHANDLER", &M_SetupMultiHandler },
|
||||
{ "HANDLESETUPMULTIPLAYER", &M_HandleSetupMultiPlayer },
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#define NOMD5
|
||||
#define NOMD5
|
||||
|
||||
// Uncheck this to compile debugging code
|
||||
//#define RANGECHECK
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ struct recorddata_t
|
|||
//UINT32 score; ///< Score when the level was finished.
|
||||
//UINT16 rings; ///< Rings when the level was finished.
|
||||
};
|
||||
#define MAXMAPRECORDS 4
|
||||
|
||||
// mapvisited is now a set of flags that says what we've done in the map.
|
||||
#define MV_VISITED (1)
|
||||
|
|
@ -368,80 +369,80 @@ extern UINT16 numkartcupheaders;
|
|||
struct mapheader_t
|
||||
{
|
||||
// Core game information, not user-modifiable directly
|
||||
char *lumpname; ///< Lump name can be really long
|
||||
UINT32 lumpnamehash; ///< quickncasehash(->lumpname, MAXMAPLUMPNAME)
|
||||
lumpnum_t lumpnum; ///< Lump number for the map, used by vres_GetMap
|
||||
char *lumpname; ///< Lump name can be really long
|
||||
UINT32 lumpnamehash; ///< quickncasehash(->lumpname, MAXMAPLUMPNAME)
|
||||
lumpnum_t lumpnum; ///< Lump number for the map, used by vres_GetMap
|
||||
|
||||
void *thumbnailPic; ///< Lump data for the level select thumbnail.
|
||||
void *minimapPic; ///< Lump data for the minimap graphic.
|
||||
void *thumbnailPic; ///< Lump data for the level select thumbnail.
|
||||
void *minimapPic; ///< Lump data for the minimap graphic.
|
||||
|
||||
UINT8 mapvisited; ///< A set of flags that says what we've done in the map.
|
||||
recorddata_t *mainrecord; ///< Stores best time attack data
|
||||
UINT8 mapvisited; ///< A set of flags that says what we've done in the map.
|
||||
recorddata_t *mainrecord[MAXMAPRECORDS]; ///< Stores best time attack data
|
||||
|
||||
cupheader_t *cup; ///< Cached cup
|
||||
cupheader_t *cup; ///< Cached cup
|
||||
|
||||
// Titlecard information
|
||||
char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway)
|
||||
char subttl[33]; ///< Subtitle for level
|
||||
char zonttl[22]; ///< "ZONE" replacement name
|
||||
char actnum[3]; ///< SRB2Kart: Now a 2 character long string.
|
||||
char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway)
|
||||
char subttl[33]; ///< Subtitle for level
|
||||
char zonttl[22]; ///< "ZONE" replacement name
|
||||
char actnum[3]; ///< SRB2Kart: Now a 2 character long string.
|
||||
|
||||
// Selection metadata
|
||||
char keywords[33]; ///< Keywords separated by space to search for. 32 characters.
|
||||
char keywords[33]; ///< Keywords separated by space to search for. 32 characters.
|
||||
|
||||
SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no.
|
||||
UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in?
|
||||
UINT8 menuflags; ///< LF2_flags: options that affect record attack menus
|
||||
SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no.
|
||||
UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in?
|
||||
UINT8 menuflags; ///< LF2_flags: options that affect record attack menus
|
||||
|
||||
// Operational metadata
|
||||
UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below
|
||||
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
|
||||
UINT8 numlaps; ///< Number of laps in circuit mode, unless overridden.
|
||||
UINT8 lapspersection; ///< Number of laps per section in hybrid section-circuit maps.
|
||||
fixed_t gravity; ///< Map-wide gravity.
|
||||
UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below
|
||||
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
|
||||
UINT8 numlaps; ///< Number of laps in circuit mode, unless overridden.
|
||||
UINT8 lapspersection; ///< Number of laps per section in hybrid section-circuit maps.
|
||||
fixed_t gravity; ///< Map-wide gravity.
|
||||
|
||||
// Music information
|
||||
char musname[MAXMUSNAMES][7]; ///< Music tracks to play. First dimension is the track number, second is the music string. "" for no music.
|
||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||
UINT32 muspos; ///< Music position to jump to.
|
||||
UINT8 musname_size; ///< Number of music tracks defined
|
||||
char musname[MAXMUSNAMES][7]; ///< Music tracks to play. First dimension is the track number, second is the music string. "" for no music.
|
||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||
UINT32 muspos; ///< Music position to jump to.
|
||||
UINT8 musname_size; ///< Number of music tracks defined
|
||||
|
||||
// Sky information
|
||||
UINT8 weather; ///< See preciptype_t
|
||||
char skytexture[9]; ///< Sky texture to use.
|
||||
INT16 skybox_scalex; ///< Skybox X axis scale. (0 = no movement, 1 = 1:1 movement, 16 = 16:1 slow movement, -4 = 1:4 fast movement, etc.)
|
||||
INT16 skybox_scaley; ///< Skybox Y axis scale.
|
||||
INT16 skybox_scalez; ///< Skybox Z axis scale.
|
||||
UINT8 weather; ///< See preciptype_t
|
||||
char skytexture[9]; ///< Sky texture to use.
|
||||
INT16 skybox_scalex; ///< Skybox X axis scale. (0 = no movement, 1 = 1:1 movement, 16 = 16:1 slow movement, -4 = 1:4 fast movement, etc.)
|
||||
INT16 skybox_scaley; ///< Skybox Y axis scale.
|
||||
INT16 skybox_scalez; ///< Skybox Z axis scale.
|
||||
|
||||
// Distance information
|
||||
fixed_t mobj_scale; ///< Defines the size all object calculations are relative to
|
||||
fixed_t default_waypoint_radius; ///< 0 is a special value for DEFAULT_WAYPOINT_RADIUS, but scaled with mobjscale
|
||||
fixed_t mobj_scale; ///< Defines the size all object calculations are relative to
|
||||
fixed_t default_waypoint_radius; ///< 0 is a special value for DEFAULT_WAYPOINT_RADIUS, but scaled with mobjscale
|
||||
|
||||
// Visual information
|
||||
UINT16 palette; ///< PAL lump to use on this map
|
||||
UINT16 encorepal; ///< PAL for encore mode
|
||||
mapheader_lighting_t lighting; ///< Wall and sprite lighting
|
||||
mapheader_lighting_t lighting_encore; ///< Alternative lighting for Encore mode
|
||||
boolean use_encore_lighting; ///< Whether to use separate Encore lighting
|
||||
UINT16 palette; ///< PAL lump to use on this map
|
||||
UINT16 encorepal; ///< PAL for encore mode
|
||||
mapheader_lighting_t lighting; ///< Wall and sprite lighting
|
||||
mapheader_lighting_t lighting_encore; ///< Alternative lighting for Encore mode
|
||||
boolean use_encore_lighting; ///< Whether to use separate Encore lighting
|
||||
|
||||
// Freed animal information
|
||||
UINT8 numFlickies; ///< Internal. For freed flicky support.
|
||||
mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful.
|
||||
UINT8 numFlickies; ///< Internal. For freed flicky support.
|
||||
mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful.
|
||||
|
||||
// Script information
|
||||
char runsoc[33]; ///< SOC to execute at start of level (32 character limit instead of 63)
|
||||
char scriptname[33]; ///< Script to use when the map is switched to. (32 character limit instead of 191)
|
||||
char runsoc[33]; ///< SOC to execute at start of level (32 character limit instead of 63)
|
||||
char scriptname[33]; ///< Script to use when the map is switched to. (32 character limit instead of 191)
|
||||
|
||||
// Cutscene information
|
||||
UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts.
|
||||
UINT8 cutscenenum; ///< Cutscene number to use, 0 for none.
|
||||
UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts.
|
||||
UINT8 cutscenenum; ///< Cutscene number to use, 0 for none.
|
||||
|
||||
// Lua information
|
||||
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
|
||||
customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful.
|
||||
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
|
||||
customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful.
|
||||
|
||||
// BlanKart
|
||||
boolean use_walltransfer; ///< Whether to use DRRR style wall transfering or not
|
||||
boolean use_walltransfer; ///< Whether to use DRRR style wall transfering or not
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
153
src/g_game.c
153
src/g_game.c
|
|
@ -453,57 +453,70 @@ consvar_t cv_deadzone[MAXSPLITSCREENPLAYERS] = {
|
|||
char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
|
||||
INT32 player_name_changes[MAXPLAYERS];
|
||||
|
||||
// Allocation for time and nights data
|
||||
void G_AllocMainRecordData(INT16 i)
|
||||
// What record should preset should we use?
|
||||
SINT8 G_RecordPresetIndex(void)
|
||||
{
|
||||
boolean rings = cv_dummyattackingrings.value;
|
||||
boolean stacking = cv_dummyattackingstacking.value;
|
||||
boolean chaining = cv_dummyattackingchaining.value;
|
||||
boolean slipdash = cv_dummyattackingslipdash.value;
|
||||
boolean purpledrift = cv_dummyattackingpurpledrift.value;
|
||||
|
||||
if (!rings && !stacking && !chaining && !slipdash && !purpledrift)
|
||||
return 0;
|
||||
|
||||
if (stacking && chaining && !rings && !slipdash && !purpledrift)
|
||||
return 1;
|
||||
|
||||
if (rings && stacking && chaining && slipdash && purpledrift)
|
||||
return 2;
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Allocation for time and nights data
|
||||
void G_AllocMainRecordData(INT16 i, SINT8 preset)
|
||||
{
|
||||
if (preset < 0 || preset >= MAXMAPRECORDS)
|
||||
I_Error("G_AllocMainRecordData: Tried allocating invalid record index (%d)", preset);
|
||||
|
||||
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));
|
||||
if (!mapheaderinfo[i]->mainrecord[preset])
|
||||
mapheaderinfo[i]->mainrecord[preset] = Z_Malloc(sizeof(recorddata_t), PU_STATIC, NULL);
|
||||
memset(mapheaderinfo[i]->mainrecord[preset], 0, sizeof(recorddata_t));
|
||||
}
|
||||
|
||||
// MAKE SURE YOU SAVE DATA BEFORE CALLING THIS
|
||||
void G_ClearRecords(void)
|
||||
{
|
||||
INT16 i;
|
||||
SINT8 k;
|
||||
|
||||
for (i = 0; i < nummapheaders; ++i)
|
||||
{
|
||||
if (mapheaderinfo[i]->mainrecord)
|
||||
for (k = 0; k < MAXMAPRECORDS; k++)
|
||||
{
|
||||
Z_Free(mapheaderinfo[i]->mainrecord);
|
||||
mapheaderinfo[i]->mainrecord = NULL;
|
||||
if (mapheaderinfo[i]->mainrecord[k])
|
||||
{
|
||||
Z_Free(mapheaderinfo[i]->mainrecord[k]);
|
||||
mapheaderinfo[i]->mainrecord[k] = NULL;
|
||||
}
|
||||
}
|
||||
/*if (nightsrecords[i])
|
||||
{
|
||||
Z_Free(nightsrecords[i]);
|
||||
nightsrecords[i] = NULL;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
// For easy retrieval of records
|
||||
tic_t G_GetBestTime(INT16 map)
|
||||
{
|
||||
if (!mapheaderinfo[map] || !mapheaderinfo[map]->mainrecord || mapheaderinfo[map]->mainrecord->time <= 0)
|
||||
SINT8 preset = G_RecordPresetIndex();
|
||||
|
||||
if (!mapheaderinfo[map] || !mapheaderinfo[map]->mainrecord[preset] || mapheaderinfo[map]->mainrecord[preset]->time <= 0)
|
||||
return (tic_t)UINT32_MAX;
|
||||
|
||||
return mapheaderinfo[map]->mainrecord->time;
|
||||
return mapheaderinfo[map]->mainrecord[preset]->time;
|
||||
}
|
||||
|
||||
// BE RIGHT BACK
|
||||
|
||||
// Not needed
|
||||
/*
|
||||
tic_t G_GetBestLap(INT16 map)
|
||||
{
|
||||
if (!mapheaderinfo[map] || !mapheaderinfo[map]->mainrecord || mapheaderinfo[map]->mainrecord->lap <= 0)
|
||||
return (tic_t)UINT32_MAX;
|
||||
|
||||
return mapheaderinfo[map]->mainrecord->lap;
|
||||
}
|
||||
*/
|
||||
|
||||
boolean K_EmblemsEnabled(void)
|
||||
{
|
||||
if (cv_dummyattackingrings.value)
|
||||
|
|
@ -532,33 +545,35 @@ boolean K_EmblemsEnabled(void)
|
|||
static void G_UpdateRecordReplays(void)
|
||||
{
|
||||
char *gpath;
|
||||
char *gamemode = M_AppendGametypeAndModName();
|
||||
char lastdemo[256], bestdemo[256];
|
||||
UINT8 earnedEmblems;
|
||||
int parts;
|
||||
SINT8 preset = G_RecordPresetIndex();
|
||||
|
||||
// Record new best time
|
||||
if (!mapheaderinfo[gamemap-1]->mainrecord)
|
||||
G_AllocMainRecordData(gamemap-1);
|
||||
if (!mapheaderinfo[gamemap-1]->mainrecord[preset])
|
||||
G_AllocMainRecordData(gamemap-1, preset);
|
||||
|
||||
if (players[consoleplayer].pflags & PF_NOCONTEST)
|
||||
{
|
||||
players[consoleplayer].realtime = UINT32_MAX;
|
||||
}
|
||||
|
||||
if (((mapheaderinfo[gamemap-1]->mainrecord->time == 0) || (players[consoleplayer].realtime < mapheaderinfo[gamemap-1]->mainrecord->time))
|
||||
if (((mapheaderinfo[gamemap-1]->mainrecord[preset]->time == 0) || (players[consoleplayer].realtime < mapheaderinfo[gamemap-1]->mainrecord[preset]->time))
|
||||
&& (players[consoleplayer].realtime < UINT32_MAX)) // DNF
|
||||
{
|
||||
mapheaderinfo[gamemap-1]->mainrecord->time = players[consoleplayer].realtime;
|
||||
mapheaderinfo[gamemap-1]->mainrecord[preset]->time = players[consoleplayer].realtime;
|
||||
}
|
||||
|
||||
if (modeattacking == ATTACKING_TIME)
|
||||
{
|
||||
if ((mapheaderinfo[gamemap-1]->mainrecord->lap == 0) || (bestlap < mapheaderinfo[gamemap-1]->mainrecord->lap))
|
||||
mapheaderinfo[gamemap-1]->mainrecord->lap = bestlap;
|
||||
if ((mapheaderinfo[gamemap-1]->mainrecord[preset]->lap == 0) || (bestlap < mapheaderinfo[gamemap-1]->mainrecord[preset]->lap))
|
||||
mapheaderinfo[gamemap-1]->mainrecord[preset]->lap = bestlap;
|
||||
}
|
||||
else
|
||||
{
|
||||
mapheaderinfo[gamemap-1]->mainrecord->lap = 0;
|
||||
mapheaderinfo[gamemap-1]->mainrecord[preset]->lap = 0;
|
||||
}
|
||||
|
||||
// Save demo!
|
||||
|
|
@ -572,14 +587,14 @@ static void G_UpdateRecordReplays(void)
|
|||
parts = M_PathParts(gpath);
|
||||
M_MkdirEachUntil(gpath, parts - 4, parts - 1, 0755);
|
||||
|
||||
snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, cv_chooseskin.string);
|
||||
snprintf(lastdemo, 255, "%s-%s-%s-last.lmp", gpath, cv_chooseskin.string, gamemode);
|
||||
|
||||
if (FIL_FileExists(lastdemo))
|
||||
{
|
||||
UINT8 *buf;
|
||||
size_t len = FIL_ReadFile(lastdemo, &buf);
|
||||
|
||||
snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, cv_chooseskin.string);
|
||||
snprintf(bestdemo, 255, "%s-%s-%s-time-best.lmp", gpath, cv_chooseskin.string, gamemode);
|
||||
if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1)
|
||||
{ // Better time, save this demo.
|
||||
if (FIL_FileExists(bestdemo))
|
||||
|
|
@ -590,7 +605,7 @@ static void G_UpdateRecordReplays(void)
|
|||
|
||||
if (modeattacking == ATTACKING_TIME)
|
||||
{
|
||||
snprintf(bestdemo, 255, "%s-%s-lap-best.lmp", gpath, cv_chooseskin.string);
|
||||
snprintf(bestdemo, 255, "%s-%s-%s-lap-best.lmp", gpath, cv_chooseskin.string, gamemode);
|
||||
if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & (1<<1))
|
||||
{ // Better lap time, save this demo.
|
||||
if (FIL_FileExists(bestdemo))
|
||||
|
|
@ -606,6 +621,7 @@ static void G_UpdateRecordReplays(void)
|
|||
}
|
||||
|
||||
free(gpath);
|
||||
free(gamemode);
|
||||
|
||||
// Check emblems when level data is updated
|
||||
if ((earnedEmblems = M_CheckLevelEmblems()))
|
||||
|
|
@ -3865,7 +3881,7 @@ void G_AddMapToBuffer(INT16 map)
|
|||
static void G_UpdateVisited(void)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT8 earnedEmblems;
|
||||
//UINT8 earnedEmblems;
|
||||
|
||||
// No demos.
|
||||
if (demo.playback)
|
||||
|
|
@ -4530,29 +4546,33 @@ void G_LoadGameData(void)
|
|||
mapnum = G_MapNumber(mapname);
|
||||
|
||||
rtemp = READUINT8(save.p);
|
||||
rectime = (tic_t)READUINT32(save.p);
|
||||
reclap = (tic_t)READUINT32(save.p);
|
||||
|
||||
if (mapnum < nummapheaders && mapheaderinfo[mapnum])
|
||||
for (SINT8 k = 0; k < MAXMAPRECORDS; k++)
|
||||
{
|
||||
// Valid mapheader, time to populate with record data.
|
||||
rectime = (tic_t)READUINT32(save.p);
|
||||
reclap = (tic_t)READUINT32(save.p);
|
||||
|
||||
if ((mapheaderinfo[mapnum]->mapvisited = rtemp) & ~MV_MAX)
|
||||
goto datacorrupt;
|
||||
|
||||
if (rectime || reclap)
|
||||
if (mapnum < nummapheaders && mapheaderinfo[mapnum])
|
||||
{
|
||||
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);
|
||||
// Valid mapheader, time to populate with record data.
|
||||
|
||||
if ((mapheaderinfo[mapnum]->mapvisited = rtemp) & ~MV_MAX)
|
||||
goto datacorrupt;
|
||||
|
||||
if (rectime || reclap)
|
||||
{
|
||||
G_AllocMainRecordData((INT16)i, k);
|
||||
mapheaderinfo[i]->mainrecord[k]->time = rectime;
|
||||
mapheaderinfo[i]->mainrecord[k]->lap = reclap;
|
||||
CONS_Printf("Map Record %d, ID %d, Time = %d, Lap = %d\n", k, 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\n", mapname);
|
||||
}
|
||||
}
|
||||
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\n", mapname);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4658,15 +4678,18 @@ void G_SaveGameData(void)
|
|||
|
||||
WRITEUINT8(save.p, (mapheaderinfo[i]->mapvisited & MV_MAX));
|
||||
|
||||
if (mapheaderinfo[i]->mainrecord)
|
||||
for (SINT8 k = 0; k < MAXMAPRECORDS; k++)
|
||||
{
|
||||
WRITEUINT32(save.p, mapheaderinfo[i]->mainrecord->time);
|
||||
WRITEUINT32(save.p, mapheaderinfo[i]->mainrecord->lap);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITEUINT32(save.p, 0);
|
||||
WRITEUINT32(save.p, 0);
|
||||
if (mapheaderinfo[i]->mainrecord[k])
|
||||
{
|
||||
WRITEUINT32(save.p, mapheaderinfo[i]->mainrecord[k]->time);
|
||||
WRITEUINT32(save.p, mapheaderinfo[i]->mainrecord[k]->lap);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITEUINT32(save.p, 0);
|
||||
WRITEUINT32(save.p, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -249,8 +249,8 @@ void G_SetGamestate(gamestate_t newstate);
|
|||
boolean G_GamestateUsesLevel(void);
|
||||
|
||||
// Gamedata record shit
|
||||
#define MAXMAPRECORDS 25
|
||||
void G_AllocMainRecordData(INT16 i);
|
||||
SINT8 G_RecordPresetIndex(void);
|
||||
void G_AllocMainRecordData(INT16 i, SINT8 preset);
|
||||
void G_ClearRecords(void);
|
||||
|
||||
boolean K_EmblemsEnabled(void);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ _(PLAYBACK)
|
|||
_(SP_MAIN)
|
||||
_(SP_GRANDPRIX)
|
||||
_(SP_TIMEATTACK)
|
||||
_(SP_PRES)
|
||||
_(SP_MODS)
|
||||
_(SP_GUESTREPLAY)
|
||||
_(SP_REPLAY)
|
||||
|
|
|
|||
|
|
@ -538,12 +538,13 @@ UINT8 M_GotLowEnoughTime(INT32 tictime)
|
|||
|
||||
for (i = 0; i < nummapheaders; ++i)
|
||||
{
|
||||
SINT8 preset = G_RecordPresetIndex();
|
||||
if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & LF2_NOTIMEATTACK))
|
||||
continue;
|
||||
|
||||
if (!mapheaderinfo[i]->mainrecord || !mapheaderinfo[i]->mainrecord->time)
|
||||
if (!mapheaderinfo[i]->mainrecord[preset] || !mapheaderinfo[i]->mainrecord[preset]->time)
|
||||
return false;
|
||||
else if ((curtics += mapheaderinfo[i]->mainrecord->time) > tictime)
|
||||
else if ((curtics += mapheaderinfo[i]->mainrecord[preset]->time) > tictime)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
68
src/m_menu.c
68
src/m_menu.c
|
|
@ -5211,19 +5211,20 @@ static void M_DrawStatsMaps(void)
|
|||
INT16 mnum;
|
||||
extraemblem_t *exemblem;
|
||||
boolean dotopname = true, dobottomarrow = (location < statsMax);
|
||||
SINT8 preset = G_RecordPresetIndex();
|
||||
|
||||
for (j = 0; j < nummapheaders; j++)
|
||||
{
|
||||
if (!mapheaderinfo[j] || (mapheaderinfo[j]->menuflags & LF2_NOTIMEATTACK))
|
||||
continue;
|
||||
|
||||
if (!mapheaderinfo[j]->mainrecord || mapheaderinfo[j]->mainrecord->time <= 0)
|
||||
if (!mapheaderinfo[j]->mainrecord[preset] || mapheaderinfo[j]->mainrecord[preset]->time <= 0)
|
||||
{
|
||||
mapsunfinished++;
|
||||
continue;
|
||||
}
|
||||
|
||||
besttime += mapheaderinfo[j]->mainrecord->time;
|
||||
besttime += mapheaderinfo[j]->mainrecord[preset]->time;
|
||||
}
|
||||
|
||||
V_DrawString(20, 42, highlightflags, "Combined time records:");
|
||||
|
|
@ -5575,6 +5576,7 @@ void M_DrawTimeAttackMenu(void)
|
|||
{
|
||||
INT32 i, x, y, cursory = 0;
|
||||
UINT16 dispstatus;
|
||||
SINT8 preset = G_RecordPresetIndex();
|
||||
|
||||
//S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback
|
||||
|
||||
|
|
@ -5663,10 +5665,10 @@ void M_DrawTimeAttackMenu(void)
|
|||
{
|
||||
INT32 dupadjust = (vid.width/vid.dupx);
|
||||
tic_t lap = 0, time = 0;
|
||||
if (mapheaderinfo[cv_nextmap.value-1]->mainrecord)
|
||||
if (mapheaderinfo[cv_nextmap.value-1]->mainrecord[preset])
|
||||
{
|
||||
lap = mapheaderinfo[cv_nextmap.value-1]->mainrecord->lap;
|
||||
time = mapheaderinfo[cv_nextmap.value-1]->mainrecord->time;
|
||||
lap = mapheaderinfo[cv_nextmap.value-1]->mainrecord[preset]->lap;
|
||||
time = mapheaderinfo[cv_nextmap.value-1]->mainrecord[preset]->time;
|
||||
}
|
||||
|
||||
V_DrawFill((BASEVIDWIDTH - dupadjust)>>1, 78, dupadjust, 36, 159);
|
||||
|
|
@ -5681,6 +5683,29 @@ void M_DrawTimeAttackMenu(void)
|
|||
K_drawKartTimestamp(time, 162, 86, cv_nextmap.value-1, 1);
|
||||
}
|
||||
|
||||
// Draw current RA preset mode.
|
||||
{
|
||||
const char *mode = "Unkown mode";
|
||||
if (preset == 0)
|
||||
{
|
||||
mode = "SRB2Kart Mode";
|
||||
}
|
||||
else if (preset == 1)
|
||||
{
|
||||
mode = "Tech Mode";
|
||||
}
|
||||
else if (preset == 2)
|
||||
{
|
||||
mode = "BlanKart Mode";
|
||||
}
|
||||
else if (preset == 3)
|
||||
{
|
||||
mode = "Custom Mode";
|
||||
}
|
||||
|
||||
V_DrawString(50, 104, V_6WIDTHSPACE, mode);
|
||||
}
|
||||
|
||||
// ALWAYS DRAW player name, level name, skin and color even when not on this menu!
|
||||
if (menustack[0] != MN_SP_TIMEATTACK)
|
||||
{
|
||||
|
|
@ -5838,6 +5863,39 @@ void M_HandleStaffReplay(INT32 choice)
|
|||
M_ExitMenu();
|
||||
}
|
||||
|
||||
void M_SRB2KartPreset(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
CV_Set(&cv_dummyattackingrings, "Off");
|
||||
CV_Set(&cv_dummyattackingstacking, "Off");
|
||||
CV_Set(&cv_dummyattackingchaining, "Off");
|
||||
CV_Set(&cv_dummyattackingslipdash, "Off");
|
||||
CV_Set(&cv_dummyattackingpurpledrift, "Off");
|
||||
}
|
||||
|
||||
void M_TechPreset(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
CV_Set(&cv_dummyattackingrings, "Off");
|
||||
CV_Set(&cv_dummyattackingstacking, "On");
|
||||
CV_Set(&cv_dummyattackingchaining, "On");
|
||||
CV_Set(&cv_dummyattackingslipdash,"Off");
|
||||
CV_Set(&cv_dummyattackingpurpledrift, "Off");
|
||||
}
|
||||
|
||||
void M_BlanKartPreset(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
CV_Set(&cv_dummyattackingrings, "On");
|
||||
CV_Set(&cv_dummyattackingstacking, "On");
|
||||
CV_Set(&cv_dummyattackingchaining, "On");
|
||||
CV_Set(&cv_dummyattackingslipdash, "On");
|
||||
CV_Set(&cv_dummyattackingpurpledrift, "On");
|
||||
}
|
||||
|
||||
// Player has selected the "REPLAY" from the time attack screen
|
||||
void M_ReplayTimeAttack(INT32 choice)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -279,6 +279,9 @@ void M_StartGrandPrix(INT32 choice);
|
|||
void M_QuitTimeAttackMenu(INT32 choice);
|
||||
void M_ChooseTimeAttack(INT32 choice);
|
||||
void M_SetGuestReplay(INT32 choice);
|
||||
void M_SRB2KartPreset(INT32 choice);
|
||||
void M_TechPreset(INT32 choice);
|
||||
void M_BlanKartPreset(INT32 choice);
|
||||
void M_ReplayTimeAttack(INT32 choice);
|
||||
void M_HandleStaffReplay(INT32 choice);
|
||||
void M_SetupMultiHandler(INT32 choice);
|
||||
|
|
|
|||
|
|
@ -448,8 +448,11 @@ static void P_ClearSingleMapHeaderInfo(INT16 num)
|
|||
#endif
|
||||
|
||||
mapheaderinfo[num]->mapvisited = 0;
|
||||
Z_Free(mapheaderinfo[num]->mainrecord);
|
||||
mapheaderinfo[num]->mainrecord = NULL;
|
||||
for (int j = 0; j < MAXMAPRECORDS; j++)
|
||||
{
|
||||
Z_Free(mapheaderinfo[num]->mainrecord[j]);
|
||||
mapheaderinfo[num]->mainrecord[j] = NULL;
|
||||
}
|
||||
|
||||
mapheaderinfo[num]->customopts = NULL;
|
||||
mapheaderinfo[num]->numCustomOptions = 0;
|
||||
|
|
@ -503,7 +506,10 @@ void P_AllocMapHeader(INT16 i)
|
|||
mapheaderinfo[i]->thumbnailPic = NULL;
|
||||
mapheaderinfo[i]->minimapPic = NULL;
|
||||
mapheaderinfo[i]->cup = NULL;
|
||||
mapheaderinfo[i]->mainrecord = NULL;
|
||||
for (int j = 0; j < MAXMAPRECORDS; j++)
|
||||
{
|
||||
mapheaderinfo[i]->mainrecord[j] = NULL;
|
||||
}
|
||||
mapheaderinfo[i]->flickies = NULL;
|
||||
nummapheaders++;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue