Tri map records pt.3: Finalize changes

This commit is contained in:
NepDisk 2025-04-12 10:45:33 -04:00
parent 807e95a011
commit 28a493dbc3
8 changed files with 133 additions and 75 deletions

View file

@ -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 },

View file

@ -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[3]; ///< 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
};

View file

@ -471,16 +471,14 @@ SINT8 G_RecordPresetIndex(void)
if (rings && stacking && chaining && slipdash && purpledrift)
return 2;
return -1;
return 3;
}
// Allocation for time and nights data
void G_AllocMainRecordData(INT16 i)
void G_AllocMainRecordData(INT16 i, SINT8 preset)
{
SINT8 preset = G_RecordPresetIndex();
if (preset == -1)
return;
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);
@ -493,17 +491,17 @@ void G_AllocMainRecordData(INT16 i)
void G_ClearRecords(void)
{
INT16 i;
SINT8 preset = G_RecordPresetIndex();
if (preset == -1)
return;
SINT8 k;
for (i = 0; i < nummapheaders; ++i)
{
if (mapheaderinfo[i]->mainrecord[preset])
for (k = 0; k < MAXMAPRECORDS; k++)
{
Z_Free(mapheaderinfo[i]->mainrecord[preset]);
mapheaderinfo[i]->mainrecord[preset] = NULL;
if (mapheaderinfo[i]->mainrecord[k])
{
Z_Free(mapheaderinfo[i]->mainrecord[k]);
mapheaderinfo[i]->mainrecord[k] = NULL;
}
}
}
}
@ -513,7 +511,7 @@ tic_t G_GetBestTime(INT16 map)
{
SINT8 preset = G_RecordPresetIndex();
if (!mapheaderinfo[map] || preset == -1 || !mapheaderinfo[map]->mainrecord[preset] || mapheaderinfo[map]->mainrecord[preset]->time <= 0)
if (!mapheaderinfo[map] || !mapheaderinfo[map]->mainrecord[preset] || mapheaderinfo[map]->mainrecord[preset]->time <= 0)
return (tic_t)UINT32_MAX;
return mapheaderinfo[map]->mainrecord[preset]->time;
@ -547,17 +545,15 @@ 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();
if (preset == -1)
return;
// Record new best time
if (!mapheaderinfo[gamemap-1]->mainrecord[preset])
G_AllocMainRecordData(gamemap-1);
G_AllocMainRecordData(gamemap-1, preset);
if (players[consoleplayer].pflags & PF_NOCONTEST)
{
@ -591,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))
@ -609,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))
@ -625,6 +621,7 @@ static void G_UpdateRecordReplays(void)
}
free(gpath);
free(gamemode);
// Check emblems when level data is updated
if ((earnedEmblems = M_CheckLevelEmblems()))
@ -3884,7 +3881,7 @@ void G_AddMapToBuffer(INT16 map)
static void G_UpdateVisited(void)
{
UINT8 i;
UINT8 earnedEmblems;
//UINT8 earnedEmblems;
// No demos.
if (demo.playback)
@ -4564,7 +4561,7 @@ void G_LoadGameData(void)
if (rectime || reclap)
{
G_AllocMainRecordData((INT16)i);
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);

View file

@ -249,9 +249,8 @@ void G_SetGamestate(gamestate_t newstate);
boolean G_GamestateUsesLevel(void);
// Gamedata record shit
#define MAXMAPRECORDS 3
SINT8 G_RecordPresetIndex(void);
void G_AllocMainRecordData(INT16 i);
void G_AllocMainRecordData(INT16 i, SINT8 preset);
void G_ClearRecords(void);
boolean K_EmblemsEnabled(void);

View file

@ -7,6 +7,7 @@ _(PLAYBACK)
_(SP_MAIN)
_(SP_GRANDPRIX)
_(SP_TIMEATTACK)
_(SP_PRES)
_(SP_MODS)
_(SP_GUESTREPLAY)
_(SP_REPLAY)

View file

@ -542,8 +542,6 @@ UINT8 M_GotLowEnoughTime(INT32 tictime)
if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & LF2_NOTIMEATTACK))
continue;
if (preset == -1)
return false;
if (!mapheaderinfo[i]->mainrecord[preset] || !mapheaderinfo[i]->mainrecord[preset]->time)
return false;
else if ((curtics += mapheaderinfo[i]->mainrecord[preset]->time) > tictime)

View file

@ -5218,7 +5218,7 @@ static void M_DrawStatsMaps(void)
if (!mapheaderinfo[j] || (mapheaderinfo[j]->menuflags & LF2_NOTIMEATTACK))
continue;
if (preset == -1 || !mapheaderinfo[j]->mainrecord[preset] || mapheaderinfo[j]->mainrecord[preset]->time <= 0)
if (!mapheaderinfo[j]->mainrecord[preset] || mapheaderinfo[j]->mainrecord[preset]->time <= 0)
{
mapsunfinished++;
continue;
@ -5665,7 +5665,7 @@ void M_DrawTimeAttackMenu(void)
{
INT32 dupadjust = (vid.width/vid.dupx);
tic_t lap = 0, time = 0;
if (preset != -1 && mapheaderinfo[cv_nextmap.value-1]->mainrecord[preset])
if (mapheaderinfo[cv_nextmap.value-1]->mainrecord[preset])
{
lap = mapheaderinfo[cv_nextmap.value-1]->mainrecord[preset]->lap;
time = mapheaderinfo[cv_nextmap.value-1]->mainrecord[preset]->time;
@ -5683,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)
{
@ -5840,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)
{

View file

@ -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);