Merge branch 'menu-munchies' into 'master'

Postfreeze Menu Polish Act 1

See merge request KartKrew/Kart!1375
This commit is contained in:
Oni 2023-08-11 07:19:19 +00:00
commit c79812def4
15 changed files with 892 additions and 249 deletions

View file

@ -1041,10 +1041,10 @@ void readlevelheader(MYFILE *f, char * name)
continue;
}
if (fastcmp(word, "SUBTITLE"))
if (fastcmp(word, "MENUTITLE"))
{
deh_strlcpy(mapheaderinfo[num]->subttl, word2,
sizeof(mapheaderinfo[num]->subttl), va("Level header %d: subtitle", num));
deh_strlcpy(mapheaderinfo[num]->menuttl, word2,
sizeof(mapheaderinfo[num]->menuttl), va("Level header %d: menutitle", num));
continue;
}
@ -3496,6 +3496,11 @@ void readcupheader(MYFILE *f, cupheader_t *cup)
else
cup->monitor = (word2[0] - 'A') + 10;
}
else if (fastcmp(word, "REALNAME"))
{
deh_strlcpy(cup->realname, word2,
sizeof(cup->realname), va("%s Cup: realname", cup->name));
}
else if (fastcmp(word, "ICON"))
{
deh_strlcpy(cup->icon, word2,

View file

@ -495,6 +495,15 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
sizeof(cup->name), va("Cup header %s: name", word2));
cup->namehash = hash;
char *start = strchr(word2, '_');
if (start)
start++;
else
start = word2;
deh_strlcpy(cup->realname, start,
sizeof(cup->realname), va("%s Cup: realname (default)", cup->name));
// Check to see if we have any custom cup record data that we could substitute in.
unloaded_cupheader_t *unloadedcup, *unloadedprev = NULL;
for (unloadedcup = unloadedcupheaders; unloadedcup; unloadedprev = unloadedcup, unloadedcup = unloadedcup->next)

View file

@ -396,6 +396,8 @@ struct cupheader_t
char name[MAXCUPNAME]; ///< Cup title
UINT32 namehash; ///< Cup title hash
char realname[MAXCUPNAME]; ///< Cup nomme de gurre
char icon[9]; ///< Name of the icon patch
char *levellist[CUPCACHE_MAX]; ///< List of levels that belong to this cup
INT16 cachedlevels[CUPCACHE_MAX]; ///< IDs in levellist, bonusgame, and specialstage
@ -464,7 +466,7 @@ struct mapheader_t
// 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 menuttl[22]; ///< Menu title for level
char zonttl[22]; ///< "ZONE" replacement name
UINT8 actnum; ///< Act number or 0 for none.

View file

@ -4742,7 +4742,7 @@ void G_LoadGameSettings(void)
}
#define GD_VERSIONCHECK 0xBA5ED123 // Change every major version, as usual
#define GD_VERSIONMINOR 4 // Change every format update
#define GD_VERSIONMINOR 5 // Change every format update
typedef enum
{
@ -5024,8 +5024,6 @@ void G_LoadGameData(void)
dummyrecord.wins = READUINT32(save.p);
dummyrecord._saveid = i;
CONS_Printf(" (TEMPORARY DISPLAY) skinname is \"%s\", has %u wins\n", skinname, dummyrecord.wins);
tempskinreferences[i].id = MAXSKINS;
if (skin != -1)
@ -5129,7 +5127,19 @@ void G_LoadGameData(void)
cupwindata_t dummywindata[4];
// Find the relevant cup.
READSTRINGL(save.p, cupname, sizeof(cupname));
if (versionMinor < 5)
{
// Before this version cups were called things like RING.
// Now that example cup would be called RR_RING instead.
cupname[0] = cupname[1] = 'R';
cupname[2] = '_';
READSTRINGL(save.p, (cupname + 3), sizeof(cupname) - 3);
}
else
{
READSTRINGL(save.p, cupname, sizeof(cupname));
}
UINT32 hash = quickncasehash(cupname, MAXCUPNAME);
for (cup = kartcupheaders; cup; cup = cup->next)
{

View file

@ -162,7 +162,7 @@ static patch_t *kp_localtag[4][2];
static patch_t *kp_talk;
static patch_t *kp_typdot;
static patch_t *kp_eggnum[6];
patch_t *kp_eggnum[6];
static patch_t *kp_flameshieldmeter[FLAMESHIELD_MAX][2];
static patch_t *kp_flameshieldmeter_bg[FLAMESHIELD_MAX][2];
@ -1793,7 +1793,7 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U
}
if (mode && !drawtime)
V_DrawTimerString(TX, TY+3, splitflags, va("--'--\"--"));
V_DrawTimerString(TX, TY+3, splitflags, "--'--\"--");
else
{
// minutes time 00 __ __

View file

@ -75,6 +75,8 @@ extern patch_t *kp_button_down[2];
extern patch_t *kp_button_right[2];
extern patch_t *kp_button_left[2];
extern patch_t *kp_eggnum[6];
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -1259,10 +1259,23 @@ void M_DrawChallenges(void);
void M_ChallengesTick(void);
boolean M_ChallengesInputs(INT32 ch);
typedef enum
{
//statisticspage_overview = 0,
statisticspage_chars = 0,
statisticspage_gp,
statisticspage_maps,
statisticspage_max
} statisticspage_t;
extern struct statisticsmenu_s {
statisticspage_t page;
INT32 location;
INT32 nummaps;
INT32 gotmedals;
INT32 nummedals;
INT32 numextramedals;
UINT32 statgridplayed[9][9];
INT32 maxscroll;
UINT16 *maplist;
} statisticsmenu;
@ -1271,6 +1284,9 @@ void M_Statistics(INT32 choice);
void M_DrawStatistics(void);
boolean M_StatisticsInputs(INT32 ch);
void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT8 skin, UINT8 *colormap, boolean dot);
fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 difficulty, boolean flash, boolean statsmode);
#define MAXWRONGPLAYER MAXSPLITSCREENPLAYERS
#define WRONGPLAYEROFFSCREEN 48

View file

@ -162,7 +162,7 @@ static fixed_t bgImageScroll = 0;
static char bgImageName[9];
#define MENUBG_TEXTSCROLL 6
#define MENUBG_IMAGESCROLL 32
#define MENUBG_IMAGESCROLL 36
void M_UpdateMenuBGImage(boolean forceReset)
{
@ -181,7 +181,7 @@ void M_UpdateMenuBGImage(boolean forceReset)
if (forceReset == false && strcmp(bgImageName, oldName))
{
bgImageScroll = (BASEVIDWIDTH / 2)*FRACUNIT;
bgImageScroll = (3 * BASEVIDWIDTH) * (FRACUNIT / 4);
}
}
@ -205,15 +205,18 @@ void M_DrawMenuBackground(void)
V_DrawFixedPatch(8 * FRACUNIT, -bgText1Scroll + text1loop,
FRACUNIT, V_SUBTRACT, text1, NULL);
bgText1Scroll += (MENUBG_TEXTSCROLL*renderdeltatics);
while (bgText1Scroll > text1loop)
bgText1Scroll -= text1loop;
V_DrawFixedPatch(-bgText2Scroll, (BASEVIDHEIGHT-8) * FRACUNIT,
FRACUNIT, V_ADD, text2, NULL);
V_DrawFixedPatch(-bgText2Scroll + text2loop, (BASEVIDHEIGHT-8) * FRACUNIT,
FRACUNIT, V_ADD, text2, NULL);
if (renderdeltatics > 2*FRACUNIT)
return; // wipe hitch...
bgText1Scroll += (MENUBG_TEXTSCROLL*renderdeltatics);
while (bgText1Scroll > text1loop)
bgText1Scroll -= text1loop;
bgText2Scroll += (MENUBG_TEXTSCROLL*renderdeltatics);
while (bgText2Scroll > text2loop)
bgText2Scroll -= text2loop;
@ -2394,7 +2397,7 @@ static void M_DrawCupTitle(INT16 y, levelsearch_t *levelsearch)
boolean unlocked = (M_GetFirstLevelInList(&temp, levelsearch) != NEXTMAP_INVALID);
UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GREY, GTC_MENUCACHE);
patch_t *icon = W_CachePatchName(levelsearch->cup->icon, PU_CACHE);
const char *str = (unlocked ? va("%s Cup", levelsearch->cup->name) : "???");
const char *str = (unlocked ? va("%s Cup", levelsearch->cup->realname) : "???");
INT16 offset = V_LSTitleLowStringWidth(str, 0) / 2;
V_DrawLSTitleLowString(BASEVIDWIDTH/2 - offset, y+6, 0, str);
@ -2415,6 +2418,175 @@ static void M_DrawCupTitle(INT16 y, levelsearch_t *levelsearch)
}
}
fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 difficulty, boolean flash, boolean statsmode)
{
INT32 rankw = 14 + 1 + 12 + 1 + 12;
if (!cup)
return 0;
boolean noemerald = (!gamedata->everseenspecial || difficulty == KARTSPEED_EASY);
if (statsmode)
{
rankw += 10 + 1;
if (noemerald)
{
rankw -= (12 + 1);
rankx += 7; // vibes-based maths, as tyron puts it
}
}
rankx += 19 - (rankw / 2);
cupwindata_t *windata = &(cup->windata[difficulty]);
if (windata->best_placement == 0)
{
if (statsmode)
{
V_DrawCharacter((10-4)/2 + rankx, ranky, '.' | V_GRAYMAP, false);
rankx += 10 + 1;
V_DrawCharacter((14-4)/2 + rankx, ranky, '.' | V_GRAYMAP, false);
rankx += 14 + 1;
V_DrawCharacter((12-4)/2 + rankx, ranky, '.' | V_GRAYMAP, false);
if (!noemerald)
{
rankx += 12 + 1;
V_DrawCharacter((12-4)/2 + rankx, ranky, '.' | V_GRAYMAP, false);
}
}
return rankw;
}
UINT8 *colormap = NULL;
if (statsmode)
{
patch_t *monPat = W_CachePatchName(va("CUPMON%c%c", '0' + cup->monitor, 'C'), PU_CACHE);
UINT16 moncolor = SKINCOLOR_NONE;
switch (windata->best_placement)
{
case 1:
moncolor = SKINCOLOR_GOLD;
break;
case 2:
moncolor = SKINCOLOR_SILVER;
break;
case 3:
moncolor = SKINCOLOR_BRONZE;
break;
default:
moncolor = SKINCOLOR_BEIGE;
break;
}
if (moncolor != SKINCOLOR_NONE)
colormap = R_GetTranslationColormap(TC_RAINBOW, moncolor, GTC_MENUCACHE);
if (monPat)
V_DrawFixedPatch((rankx)*FRACUNIT, (ranky)*FRACUNIT, FRACUNIT, 0, monPat, colormap);
rankx += 10 + 1;
colormap = NULL;
}
const gp_rank_e grade = windata->best_grade; // (cupgrid.previewanim/TICRATE) % (GRADE_S + 1); -- testing
patch_t *gradePat = NULL;
UINT16 gradecolor = K_GetGradeColor(grade);
if (gradecolor != SKINCOLOR_NONE)
colormap = R_GetTranslationColormap(TC_DEFAULT, gradecolor, GTC_MENUCACHE);
switch (grade)
{
case GRADE_E:
gradePat = W_CachePatchName("R_CUPRNE", PU_CACHE);
break;
case GRADE_D:
gradePat = W_CachePatchName("R_CUPRND", PU_CACHE);
break;
case GRADE_C:
gradePat = W_CachePatchName("R_CUPRNC", PU_CACHE);
break;
case GRADE_B:
gradePat = W_CachePatchName("R_CUPRNB", PU_CACHE);
break;
case GRADE_A:
gradePat = W_CachePatchName("R_CUPRNA", PU_CACHE);
break;
case GRADE_S:
gradePat = W_CachePatchName("R_CUPRNS", PU_CACHE);
break;
default:
break;
}
if (gradePat)
V_DrawFixedPatch((rankx)*FRACUNIT, (ranky)*FRACUNIT, FRACUNIT, 0, gradePat, colormap);
rankx += 14 + 1;
patch_t *charPat = NULL;
if ((windata->best_skin.unloaded != NULL)
|| (windata->best_skin.id > numskins))
{
colormap = NULL;
charPat = W_CachePatchName("HUHMAP", PU_CACHE);
}
else
{
UINT8 skin = windata->best_skin.id;
colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE);
charPat = faceprefix[skin][FACE_MINIMAP];
}
if (charPat)
V_DrawFixedPatch((rankx)*FRACUNIT, (ranky)*FRACUNIT, FRACUNIT, 0, charPat, colormap);
rankx += 12 + 1;
if (noemerald)
;
else if (windata->got_emerald == true)
{
if (cup->emeraldnum == 0)
V_DrawCharacter(rankx+2, ranky+2, '+', false);
else
{
colormap = NULL;
if (!flash)
{
UINT16 col = SKINCOLOR_CHAOSEMERALD1 + (cup->emeraldnum-1) % 7;
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
}
const char *emname = va(
"%sMAP%c",
(cup->emeraldnum > 7) ? "SUP" : "EME",
colormap ? '\0' : 'B'
);
V_DrawFixedPatch((rankx)*FRACUNIT, (ranky)*FRACUNIT, FRACUNIT, 0, W_CachePatchName(emname, PU_CACHE), colormap);
}
}
else if (statsmode)
{
V_DrawCharacter((12-4)/2 + rankx, ranky, '.' | V_GRAYMAP, false);
}
return rankw;
}
void M_DrawCupSelect(void)
{
UINT8 i, j, temp = 0;
@ -2520,100 +2692,16 @@ void M_DrawCupSelect(void)
V_DrawScaledPatch(x + 32, y + 32, 0, W_CachePatchName("CUPBKUP1", PU_CACHE));
}
if (!windata)
;
else if (windata->best_placement != 0)
if (windata && windata->best_placement != 0)
{
const INT32 rankw = 14 + 12 + 12 + 2;
INT32 rankx = (x + 19) - (rankw / 2);
const INT32 ranky = 8 + (j*100) - (30*menutransition.tics);
patch_t *gradePat = NULL;
colormap = NULL;
const gp_rank_e grade = windata->best_grade; // (cupgrid.previewanim/TICRATE) % (GRADE_S + 1); -- testing
UINT16 gradecolor = K_GetGradeColor(grade);
if (gradecolor != SKINCOLOR_NONE)
colormap = R_GetTranslationColormap(TC_DEFAULT, gradecolor, GTC_MENUCACHE);
switch (grade)
{
case GRADE_E:
gradePat = W_CachePatchName("R_CUPRNE", PU_CACHE);
break;
case GRADE_D:
gradePat = W_CachePatchName("R_CUPRND", PU_CACHE);
break;
case GRADE_C:
gradePat = W_CachePatchName("R_CUPRNC", PU_CACHE);
break;
case GRADE_B:
gradePat = W_CachePatchName("R_CUPRNB", PU_CACHE);
break;
case GRADE_A:
gradePat = W_CachePatchName("R_CUPRNA", PU_CACHE);
break;
case GRADE_S:
gradePat = W_CachePatchName("R_CUPRNS", PU_CACHE);
break;
default:
break;
}
if (gradePat)
V_DrawFixedPatch((rankx)*FRACUNIT, (ranky)*FRACUNIT, FRACUNIT, 0, gradePat, colormap);
rankx += 14 + 1;
patch_t *charPat = NULL;
if ((windata->best_skin.unloaded != NULL)
|| (windata->best_skin.id > numskins))
{
colormap = NULL;
charPat = W_CachePatchName("HUHMAP", PU_CACHE);
}
else
{
UINT8 skin = windata->best_skin.id;
colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE);
charPat = faceprefix[skin][FACE_MINIMAP];
}
if (charPat)
V_DrawFixedPatch((rankx)*FRACUNIT, (ranky)*FRACUNIT, FRACUNIT, 0, charPat, colormap);
if (cv_dummygpdifficulty.value > 0
&& windata->got_emerald == true)
{
rankx += 12 + 1;
if (templevelsearch.cup->emeraldnum == 0)
V_DrawCharacter(rankx+2, ranky+2, '+', false);
else
{
colormap = NULL;
if (!(cupgrid.previewanim & 1))
{
UINT16 col = SKINCOLOR_CHAOSEMERALD1 + (templevelsearch.cup->emeraldnum-1) % 7;
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
}
const char *emname = va(
"%sMAP%c",
(templevelsearch.cup->emeraldnum > 7) ? "SUP" : "EME",
colormap ? '\0' : 'B'
);
V_DrawFixedPatch((rankx)*FRACUNIT, (ranky)*FRACUNIT, FRACUNIT, 0, W_CachePatchName(emname, PU_CACHE), colormap);
}
}
M_DrawCupWinData(
x,
8 + (j*100) - (30*menutransition.tics),
templevelsearch.cup,
cv_dummygpdifficulty.value,
(cupgrid.previewanim & 1),
false
);
}
}
}
@ -2656,16 +2744,22 @@ void M_DrawCupSelect(void)
static void M_DrawHighLowLevelTitle(INT16 x, INT16 y, INT16 map)
{
char word1[22];
char word2[22];
char word2[22 + 2]; // actnum
UINT8 word1len = 0;
UINT8 word2len = 0;
INT16 x2 = x;
UINT8 i;
if (!mapheaderinfo[map] || !mapheaderinfo[map]->lvlttl[0])
if (!mapheaderinfo[map]
|| (
!mapheaderinfo[map]->menuttl[0]
&& !mapheaderinfo[map]->lvlttl[0]
)
)
return;
if (mapheaderinfo[map]->zonttl[0])
if (!mapheaderinfo[map]->menuttl[0]
&& mapheaderinfo[map]->zonttl[0])
{
boolean one = true;
boolean two = true;
@ -2696,12 +2790,17 @@ static void M_DrawHighLowLevelTitle(INT16 x, INT16 y, INT16 map)
{
boolean donewithone = false;
char *ttlsource =
mapheaderinfo[map]->menuttl[0]
? mapheaderinfo[map]->menuttl
: mapheaderinfo[map]->lvlttl;
for (i = 0; i < 22; i++)
{
if (!mapheaderinfo[map]->lvlttl[i])
if (!ttlsource[i])
break;
if (mapheaderinfo[map]->lvlttl[i] == ' ')
if (ttlsource[i] == ' ')
{
if (!donewithone)
{
@ -2712,18 +2811,18 @@ static void M_DrawHighLowLevelTitle(INT16 x, INT16 y, INT16 map)
if (donewithone)
{
word2[word2len] = mapheaderinfo[map]->lvlttl[i];
word2[word2len] = ttlsource[i];
word2len++;
}
else
{
word1[word1len] = mapheaderinfo[map]->lvlttl[i];
word1[word1len] = ttlsource[i];
word1len++;
}
}
}
if (mapheaderinfo[map]->actnum)
if (!mapheaderinfo[map]->menuttl[0] && mapheaderinfo[map]->actnum)
{
word2[word2len] = ' ';
word2len++;
@ -5280,6 +5379,41 @@ drawborder:
#define challengetransparentstrength 8
void M_DrawCharacterIconAndEngine(INT32 x, INT32 y, UINT8 skin, UINT8 *colormap, boolean dot)
{
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT,
FRACUNIT,
0, faceprefix[skin][FACE_RANK],
colormap);
if (dot)
{
V_DrawScaledPatch(x, y + 11, 0, W_CachePatchName("ALTSDOT", PU_CACHE));
}
V_DrawFadeFill(x+16, y, 16, 16, 0, 31, challengetransparentstrength);
V_DrawFill(x+16+5, y+1, 1, 14, 0);
V_DrawFill(x+16+5+5, y+1, 1, 14, 0);
V_DrawFill(x+16+1, y+5, 14, 1, 0);
V_DrawFill(x+16+1, y+5+5, 14, 1, 0);
// The following is a partial duplication of R_GetEngineClass
{
INT32 s = (skins[skin].kartspeed - 1)/3;
INT32 w = (skins[skin].kartweight - 1)/3;
#define LOCKSTAT(stat) \
if (stat < 0) { stat = 0; } \
if (stat > 2) { stat = 2; }
LOCKSTAT(s);
LOCKSTAT(w);
#undef LOCKSTAT
V_DrawFill(x+16 + (s*5), y + (w*5), 6, 6, 0);
}
}
static void M_DrawChallengePreview(INT32 x, INT32 y)
{
unlockable_t *ref = NULL;
@ -5346,37 +5480,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
break;
}
V_DrawFixedPatch(4*FRACUNIT, (BASEVIDHEIGHT-(4+16))*FRACUNIT,
FRACUNIT,
0, faceprefix[i][FACE_RANK],
colormap);
if (i != skin)
{
V_DrawScaledPatch(4, (11 + BASEVIDHEIGHT-(4+16)), 0, W_CachePatchName("ALTSDOT", PU_CACHE));
}
V_DrawFadeFill(4+16, (BASEVIDHEIGHT-(4+16)), 16, 16, 0, 31, challengetransparentstrength);
V_DrawFill(4+16+5, (BASEVIDHEIGHT-(4+16))+1, 1, 14, 0);
V_DrawFill(4+16+5+5, (BASEVIDHEIGHT-(4+16))+1, 1, 14, 0);
V_DrawFill(4+16+1, (BASEVIDHEIGHT-(4+16))+5, 14, 1, 0);
V_DrawFill(4+16+1, (BASEVIDHEIGHT-(4+16))+5+5, 14, 1, 0);
// The following is a partial duplication of R_GetEngineClass
{
INT32 s = (skins[skin].kartspeed - 1)/3;
INT32 w = (skins[skin].kartweight - 1)/3;
#define LOCKSTAT(stat) \
if (stat < 0) { stat = 0; } \
if (stat > 2) { stat = 2; }
LOCKSTAT(s);
LOCKSTAT(w);
#undef LOCKSTAT
V_DrawFill(4+16 + (s*5), (BASEVIDHEIGHT-(4+16)) + (w*5), 6, 6, 0);
}
M_DrawCharacterIconAndEngine(4, BASEVIDHEIGHT-(4+16), i, colormap, (i == skin));
}
break;
}
@ -5884,6 +5988,10 @@ challengedesc:
keyholdrotation = 360 * ((challengesmenu.chaokeyhold - CHAOHOLD_BEGIN))
* (FRACUNIT/(CHAOHOLD_MAX - (CHAOHOLD_BEGIN + CHAOHOLD_END)));
INT32 time = 3 - (keyholdrotation - 1) / (90 * FRACUNIT);
if (time <= 5 && time >= 0)
V_DrawScaledPatch(selectx + 2, selecty - 2, 0, kp_eggnum[time]);
}
else
{
@ -5994,15 +6102,74 @@ static void M_DrawMapMedals(INT32 mapnum, INT32 x, INT32 y)
static void M_DrawStatsMaps(void)
{
INT32 y = 80, i = -1;
INT32 y = 70, i;
INT16 mnum;
boolean dotopname = true, dobottomarrow = (statisticsmenu.location < statisticsmenu.maxscroll);
INT32 location = statisticsmenu.location;
tic_t besttime = 0;
if (!statisticsmenu.maplist)
{
V_DrawCenteredThinString(BASEVIDWIDTH/2, 70, 0, "No maps!?");
return;
}
INT32 mapsunfinished = 0;
V_DrawThinString(30, 60, 0, va("x %d/%d", statisticsmenu.gotmedals, statisticsmenu.nummedals));
V_DrawSmallMappedPatch(20, 60, 0, W_CachePatchName("GOTITA", PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_GOLD, GTC_MENUCACHE));
INT32 medalspos = BASEVIDWIDTH - 20;
boolean timeattack[3];
timeattack[0] = M_SecretUnlocked(SECRET_TIMEATTACK, true);
timeattack[1] = M_SecretUnlocked(SECRET_PRISONBREAK, true);
timeattack[2] = M_SecretUnlocked(SECRET_SPECIALATTACK, true);
if (timeattack[0] || timeattack[1] || timeattack[2])
{
medalspos -= 64;
for (i = 0; i < nummapheaders; i++)
{
// Check for no visibility
if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & (LF2_NOTIMEATTACK|LF2_HIDEINSTATS|LF2_HIDEINMENU)))
continue;
// Has to be accessible via time attack
if (!(mapheaderinfo[i]->typeoflevel & (TOL_RACE|TOL_BATTLE|TOL_SPECIAL|TOL_VERSUS)))
continue;
if (mapheaderinfo[i]->records.time <= 0)
{
mapsunfinished++;
continue;
}
besttime += mapheaderinfo[i]->records.time;
}
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 60, 0,
va(
"Combined time: %c%i:%02i:%02i.%02i (%s)",
(mapsunfinished ? '\x85' : '\x80'),
G_TicsToHours(besttime),
G_TicsToMinutes(besttime, false),
G_TicsToSeconds(besttime),
G_TicsToCentiseconds(besttime),
(mapsunfinished ? "incomplete" : "complete")
)
);
}
if (location)
V_DrawCharacter(10, y-(skullAnimCounter/5),
V_DrawCharacter(10, 80-(skullAnimCounter/5),
'\x1A' | highlightflags, false); // up arrow
i = -1;
while ((mnum = statisticsmenu.maplist[++i]) != NEXTMAP_INVALID)
{
if (location)
@ -6024,8 +6191,10 @@ static void M_DrawStatsMaps(void)
{
const char *str;
if (mapheaderinfo[mnum]->cup)
str = va("%s CUP", mapheaderinfo[mnum]->cup->name);
if (mapheaderinfo[mnum]->typeoflevel & TOL_TUTORIAL)
str = "TUTORIAL MODE";
else if (mapheaderinfo[mnum]->cup)
str = va("%s CUP", mapheaderinfo[mnum]->cup->realname);
else
str = "LOST AND FOUND";
@ -6034,7 +6203,11 @@ static void M_DrawStatsMaps(void)
if (dotopname)
{
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, y, highlightflags, "MEDALS");
V_DrawRightAlignedThinString(medalspos, y, highlightflags, "MEDALS");
if (timeattack[0] || timeattack[1] || timeattack[2])
V_DrawRightAlignedThinString((BASEVIDWIDTH-20), y, highlightflags, "TIME");
dotopname = false;
}
@ -6045,8 +6218,41 @@ static void M_DrawStatsMaps(void)
continue;
}
M_DrawMapMedals(mnum+1, 291, y);
V_DrawFadeFill(24, y + 5, (BASEVIDWIDTH - 24) - 24, 3, 0, 31, 8 - (i & 1)*2);
if (!(mapheaderinfo[mnum]->menuflags & LF2_NOTIMEATTACK)
&& (
(timeattack[0] && (mapheaderinfo[mnum]->typeoflevel & TOL_RACE))
|| (timeattack[1] && (mapheaderinfo[mnum]->typeoflevel & TOL_BATTLE))
|| (timeattack[2] && (mapheaderinfo[mnum]->typeoflevel & (TOL_SPECIAL|TOL_VERSUS)))
)
)
{
besttime = mapheaderinfo[mnum]->records.time;
if (besttime)
{
V_DrawRightAlignedString((BASEVIDWIDTH-24), y+1, 0,
va("%02d'%02d\"%02d",
G_TicsToMinutes(besttime, true),
G_TicsToSeconds(besttime),
G_TicsToCentiseconds(besttime)
)
);
}
else
{
V_DrawRightAlignedString((BASEVIDWIDTH-24), y+1, V_GRAYMAP, "--'--\"--");
}
}
M_DrawMapMedals(mnum+1, medalspos - 8, y);
if (mapheaderinfo[mnum]->menuttl[0])
{
V_DrawThinString(24, y, V_FORCEUPPERCASE, mapheaderinfo[mnum]->menuttl);
}
else
{
char *title = G_BuildMapTitle(mnum+1);
V_DrawThinString(24, y, V_FORCEUPPERCASE, title);
@ -6126,26 +6332,258 @@ static void M_DrawStatsMaps(void)
}
bottomarrow:
if (dobottomarrow)
V_DrawCharacter(10, y-STATSSTEP + (skullAnimCounter/5),
V_DrawCharacter(10, BASEVIDHEIGHT-20 + (skullAnimCounter/5),
'\x1B' | highlightflags, false); // down arrow
}
#undef STATSSTEP
#define STATSSTEP 18
static void M_DrawStatsChars(void)
{
INT32 y = 80, i, j;
INT16 skin;
boolean dobottomarrow = (statisticsmenu.location < statisticsmenu.maxscroll);
INT32 location = statisticsmenu.location;
if (!statisticsmenu.maplist || !statisticsmenu.nummaps)
{
V_DrawCenteredThinString(BASEVIDWIDTH/2, 70, 0, "No chars!?");
return;
}
if (location)
V_DrawCharacter(10, y-(skullAnimCounter/5),
'\x1A' | highlightflags, false); // up arrow
i = -1;
V_DrawThinString(20, y - 10, highlightflags, "CHARACTER");
V_DrawRightAlignedThinString(BASEVIDWIDTH/2 + 34, y - 10, highlightflags, "WINS");
while ((skin = statisticsmenu.maplist[++i]) < numskins)
{
if (location)
{
--location;
continue;
}
{
UINT8 *colormap = R_GetTranslationColormap(skin, skins[skin].prefcolor, GTC_MENUCACHE);
M_DrawCharacterIconAndEngine(24, y, skin, colormap, false);
}
V_DrawThinString(24+32+2, y+3, 0, skins[skin].realname);
V_DrawRightAlignedThinString(BASEVIDWIDTH/2 + 30, y+3, 0, va("%d", skins[skin].records.wins));
y += STATSSTEP;
if (y >= BASEVIDHEIGHT-STATSSTEP)
goto bottomarrow;
}
bottomarrow:
if (dobottomarrow)
V_DrawCharacter(10, BASEVIDHEIGHT-20 + (skullAnimCounter/5),
'\x1B' | highlightflags, false); // down arrow
UINT32 x = BASEVIDWIDTH - 20 - 90;
y = 88;
V_DrawCenteredThinString(x + 45, y - 10, highlightflags, "HEATMAP");
V_DrawFadeFill(x, y, 91, 91, 0, 31, 8); // challengetransparentstrength
V_DrawFill(x+30, y+1, 1, 89, 0);
V_DrawFill(x+60, y+1, 1, 89, 0);
V_DrawFill(x+1, y+30, 89, 1, 0);
V_DrawFill(x+1, y+60, 89, 1, 0);
x++;
y++;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
if (statisticsmenu.statgridplayed[i][j] == 0)
continue;
V_DrawFill(
x + (i * 10),
y + (j * 10),
9,
9,
31 - ((statisticsmenu.statgridplayed[i][j] - 1) * 32) / FRACUNIT
);
}
}
}
#undef STATSSTEP
#define STATSSTEP 21
static void M_DrawStatsGP(void)
{
INT32 y = 80, i, x, j, endj;
INT16 id;
boolean dobottomarrow = (statisticsmenu.location < statisticsmenu.maxscroll);
INT32 location = statisticsmenu.location;
if (!statisticsmenu.maplist || !statisticsmenu.nummaps)
{
V_DrawCenteredThinString(BASEVIDWIDTH/2, 70, 0, "No cups!?");
return;
}
if (location)
V_DrawCharacter(10, y-(skullAnimCounter/5),
'\x1A' | highlightflags, false); // up arrow
const INT32 width = 53;
endj = KARTSPEED_NORMAL;
if (M_SecretUnlocked(SECRET_HARDSPEED, true))
{
endj = M_SecretUnlocked(SECRET_MASTERMODE, true)
? KARTGP_MASTER
: KARTSPEED_HARD;
}
const INT32 h = (21 * min(5, statisticsmenu.nummaps)) - 1;
x = 7 + BASEVIDWIDTH - 20 - width;
for (j = endj; j >= KARTSPEED_EASY; j--, x -= width)
{
if (j == KARTSPEED_EASY || !gamedata->everseenspecial)
{
V_DrawFadeFill(x + 6, y + 1, width - (12 + 1), h, 0, 31, 6 + (j & 1)*2);
V_DrawCenteredThinString(x + 19 + 7, y - 10, highlightflags|V_FORCEUPPERCASE, gpdifficulty_cons_t[j].strvalue);
x += (12 + 1);
}
else
{
V_DrawFadeFill(x - 7, y + 1, width, h, 0, 31, 6 + (j & 1)*2);
V_DrawCenteredThinString(x + 19, y - 10, highlightflags|V_FORCEUPPERCASE, gpdifficulty_cons_t[j].strvalue);
}
}
i = -1;
V_DrawThinString(20, y - 10, highlightflags, "CUP");
cupheader_t *cup = kartcupheaders;
while ((id = statisticsmenu.maplist[++i]) < numkartcupheaders)
{
if (location)
{
--location;
continue;
}
// If we have ANY sort of sorting other than instantiation, this won't work
while (cup && cup->id != id)
{
cup = cup->next;
}
if (!cup)
{
goto bottomarrow;
}
V_DrawFill(24, y+1, 21, 20, 31);
V_DrawScaledPatch(24-1, y, 0, W_CachePatchName(cup->icon, PU_CACHE));
V_DrawScaledPatch(24-1, y, 0, W_CachePatchName("CUPBOX", PU_CACHE));
V_DrawThinString(24+21+2, y + 7, 0, cup->realname);
x = 7 + BASEVIDWIDTH - 20 - width;
for (j = endj; j >= KARTSPEED_EASY; j--)
{
x -= (M_DrawCupWinData(x, y + 5, cup, j, false, true) + 2);
}
y += STATSSTEP;
if (y >= BASEVIDHEIGHT-STATSSTEP)
goto bottomarrow;
}
bottomarrow:
if (dobottomarrow)
V_DrawCharacter(10, BASEVIDHEIGHT-20 + (skullAnimCounter/5),
'\x1B' | highlightflags, false); // down arrow
}
#undef STATSSTEP
void M_DrawStatistics(void)
{
char beststr[256];
tic_t besttime = 0;
INT32 i;
INT32 mapsunfinished = 0;
{
patch_t *bg = W_CachePatchName("M_XTRABG", PU_CACHE);
V_DrawFixedPatch(0, 0, FRACUNIT, 0, bg, NULL);
}
{
const char *pagename = NULL;
INT32 pagenamewidth = 0;
V_DrawFixedPatch(0, 0, FRACUNIT, 0, W_CachePatchName("MENUHINT", PU_CACHE), NULL);
switch (statisticsmenu.page)
{
case statisticspage_gp:
{
pagename = gamedata->everseenspecial
? "GRAND PRIX & EMERALDS"
: "GRAND PRIX";
M_DrawStatsGP();
break;
}
case statisticspage_maps:
{
pagename = "LEVELS & MEDALS";
M_DrawStatsMaps();
break;
}
case statisticspage_chars:
{
pagename = "CHARACTERS & ENGINE CLASSES";
M_DrawStatsChars();
break;
}
default:
break;
}
if (pagename)
{
pagenamewidth = V_ThinStringWidth(pagename, 0);
V_DrawThinString((BASEVIDWIDTH - pagenamewidth)/2, 12, 0, pagename);
}
V_DrawCharacter((BASEVIDWIDTH - pagenamewidth)/2 - 10 - (skullAnimCounter/5), 12,
'\x1C', false); // left arrow
V_DrawCharacter((BASEVIDWIDTH + pagenamewidth)/2 + 2 + (skullAnimCounter/5), 12,
'\x1D', false); // right arrow
}
beststr[0] = 0;
V_DrawThinString(20, 22, highlightflags, "Total Play Time:");
V_DrawThinString(20, 30, highlightflags, "Total Play Time:");
besttime = G_TicsToHours(gamedata->totalplaytime);
if (besttime)
{
@ -6164,10 +6602,10 @@ void M_DrawStatistics(void)
}
besttime = G_TicsToSeconds(gamedata->totalplaytime);
strcat(beststr, va("%i second%s", besttime, (besttime == 1 ? "" : "s")));
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 22, 0, beststr);
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 30, 0, beststr);
beststr[0] = 0;
V_DrawThinString(20, 32, highlightflags, "Total Rings:");
V_DrawThinString(20, 40, highlightflags, "Total Rings:");
if (gamedata->totalrings > GDMAX_RINGS)
{
sprintf(beststr, "%c999,999,999+", '\x82');
@ -6184,10 +6622,10 @@ void M_DrawStatistics(void)
{
sprintf(beststr, "%u", gamedata->totalrings);
}
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 32, 0, va("%s collected", beststr));
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 40, 0, va("%s collected", beststr));
beststr[0] = 0;
V_DrawThinString(20, 42, highlightflags, "Total Rounds:");
V_DrawThinString(20, 50, highlightflags, "Total Rounds:");
strcat(beststr, va("%u Race", gamedata->roundsplayed[GDGT_RACE]));
@ -6208,49 +6646,9 @@ void M_DrawStatistics(void)
strcat(beststr, va(", %u Custom", gamedata->roundsplayed[GDGT_CUSTOM]));
}
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 42, 0, beststr);
if (!statisticsmenu.maplist)
{
V_DrawCenteredThinString(BASEVIDWIDTH/2, 62, 0, "No maps!?");
return;
}
besttime = 0;
for (i = 0; i < nummapheaders; i++)
{
if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & (LF2_NOTIMEATTACK|LF2_HIDEINSTATS|LF2_HIDEINMENU)))
continue;
if (mapheaderinfo[i]->records.time <= 0)
{
mapsunfinished++;
continue;
}
besttime += mapheaderinfo[i]->records.time;
}
V_DrawThinString(20, 60, 0, "Combined time records:");
sprintf(beststr, "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime));
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 60, (mapsunfinished ? V_REDMAP : 0), beststr);
if (mapsunfinished)
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 70, V_REDMAP, va("(%d unfinished)", mapsunfinished));
else
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 70, 0, "(complete)");
V_DrawThinString(32, 70, 0, va("x %d/%d", M_CountMedals(false, false), M_CountMedals(true, false)));
V_DrawSmallMappedPatch(20, 70, 0, W_CachePatchName("GOTITA", PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_GOLD, GTC_MENUCACHE));
M_DrawStatsMaps();
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 50, 0, beststr);
}
#undef STATSSTEP
static INT32 M_WrongWarpFallingHelper(INT32 y, INT32 falltime)
{
if (wrongwarp.ticker < falltime)

View file

@ -2487,8 +2487,8 @@ static int mapheaderinfo_get(lua_State *L)
const char *field = luaL_checkstring(L, 2);
if (fastcmp(field,"lvlttl"))
lua_pushstring(L, header->lvlttl);
else if (fastcmp(field,"subttl"))
lua_pushstring(L, header->subttl);
else if (fastcmp(field,"menuttl"))
lua_pushstring(L, header->menuttl);
else if (fastcmp(field,"zonttl"))
lua_pushstring(L, header->zonttl);
else if (fastcmp(field,"actnum"))

View file

@ -1432,7 +1432,7 @@ static const char *M_GetConditionString(condition_t *cn)
continue;
return va("%s%s %s CUP",
completetype, orbetter,
(M_CupLocked(cup) ? "???" : cup->name)
(M_CupLocked(cup) ? "???" : cup->realname)
);
}
return va("INVALID CUP CONDITION \"%d:%d\"", cn->type, cn->requirement);

View file

@ -5,10 +5,11 @@
#include "../z_zone.h"
#include "../m_cond.h" // Condition Sets
#include "../s_sound.h"
#include "../r_skins.h"
struct statisticsmenu_s statisticsmenu;
static boolean M_StatisticsAddMap(UINT16 map, cupheader_t *cup, boolean *headerexists)
static boolean M_StatisticsAddMap(UINT16 map, cupheader_t *cup, boolean *headerexists, boolean tutorial)
{
if (!mapheaderinfo[map])
return false;
@ -16,12 +17,11 @@ static boolean M_StatisticsAddMap(UINT16 map, cupheader_t *cup, boolean *headere
if (mapheaderinfo[map]->cup != cup)
return false;
// Check for no visibility
if (mapheaderinfo[map]->menuflags & (LF2_NOTIMEATTACK|LF2_HIDEINSTATS|LF2_HIDEINMENU))
if (((mapheaderinfo[map]->typeoflevel & TOL_TUTORIAL) == TOL_TUTORIAL) != tutorial)
return false;
// No TEST RUN, as that's another exception to Time Attack too
if (!mapheaderinfo[map]->typeoflevel)
// Check for no visibility
if (mapheaderinfo[map]->menuflags & (LF2_HIDEINSTATS|LF2_HIDEINMENU))
return false;
// Check for completion
@ -43,17 +43,16 @@ static boolean M_StatisticsAddMap(UINT16 map, cupheader_t *cup, boolean *headere
return true;
}
void M_Statistics(INT32 choice)
static void M_StatisticsMaps(void)
{
cupheader_t *cup;
UINT16 i;
boolean headerexists;
(void)choice;
statisticsmenu.maplist = Z_Malloc(sizeof(UINT16) * (nummapheaders+1 + numkartcupheaders), PU_STATIC, NULL);
statisticsmenu.nummaps = 0;
// Cups
for (cup = kartcupheaders; cup; cup = cup->next)
{
headerexists = false;
@ -66,28 +65,199 @@ void M_Statistics(INT32 choice)
if (cup->cachedlevels[i] >= nummapheaders)
continue;
M_StatisticsAddMap(cup->cachedlevels[i], cup, &headerexists);
M_StatisticsAddMap(cup->cachedlevels[i], cup, &headerexists, false);
}
}
// Lost and Found
headerexists = false;
for (i = 0; i < nummapheaders; i++)
{
M_StatisticsAddMap(i, NULL, &headerexists);
M_StatisticsAddMap(i, NULL, &headerexists, false);
}
if ((i = statisticsmenu.numextramedals = M_CountMedals(true, true)) != 0)
// Tutorial
headerexists = false;
for (i = 0; i < nummapheaders; i++)
{
M_StatisticsAddMap(i, NULL, &headerexists, true);
}
if ((i = statisticsmenu.numextramedals) != 0)
i += 2;
statisticsmenu.maplist[statisticsmenu.nummaps] = NEXTMAP_INVALID;
statisticsmenu.maxscroll = (statisticsmenu.nummaps + i) - 11;
statisticsmenu.maxscroll = (statisticsmenu.nummaps + i) - 12;
statisticsmenu.location = 0;
if (statisticsmenu.maxscroll < 0)
{
statisticsmenu.maxscroll = 0;
}
}
static void M_StatisticsChars(void)
{
UINT16 i;
statisticsmenu.maplist = Z_Malloc(sizeof(UINT16) * (1 + numskins), PU_STATIC, NULL);
statisticsmenu.nummaps = 0;
UINT32 beststat = 0;
for (i = 0; i < numskins; i++)
{
if (!R_SkinUsable(-1, i, false))
continue;
statisticsmenu.maplist[statisticsmenu.nummaps++] = i;
if (skins[i].records.wins == 0)
continue;
// The following is a partial duplication of R_GetEngineClass
{
if (skins[i].flags & SF_IRONMAN)
continue; // does not add to any engine class
INT32 s = (skins[i].kartspeed - 1);
INT32 w = (skins[i].kartweight - 1);
#define LOCKSTAT(stat) \
if (stat < 0) { continue; } \
if (stat > 8) { continue; }
LOCKSTAT(s);
LOCKSTAT(w);
#undef LOCKSTAT
if (
statisticsmenu.statgridplayed[s][w] > skins[i].records.wins
&& (UINT32_MAX - statisticsmenu.statgridplayed[s][w]) < skins[i].records.wins
)
continue; // overflow protection
statisticsmenu.statgridplayed[s][w] += skins[i].records.wins;
if (beststat >= statisticsmenu.statgridplayed[s][w])
continue;
beststat = statisticsmenu.statgridplayed[s][w];
}
}
statisticsmenu.maplist[statisticsmenu.nummaps] = MAXSKINS;
statisticsmenu.location = 0;
statisticsmenu.maxscroll = statisticsmenu.nummaps - 6;
if (statisticsmenu.maxscroll < 0)
{
statisticsmenu.maxscroll = 0;
}
if (beststat != 0)
{
UINT16 j;
UINT8 shif = 0;
// Done this way to ensure ample precision but also prevent overflow
while (beststat < FRACUNIT)
{
beststat <<= 1;
shif++;
}
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
if (statisticsmenu.statgridplayed[i][j] == 0)
continue;
statisticsmenu.statgridplayed[i][j] =
FixedDiv(
statisticsmenu.statgridplayed[i][j] << shif,
beststat
);
if (statisticsmenu.statgridplayed[i][j] == 0)
statisticsmenu.statgridplayed[i][j] = 1;
}
}
}
}
static void M_StatisticsGP(void)
{
statisticsmenu.maplist = Z_Malloc(sizeof(UINT16) * (1 + numkartcupheaders), PU_STATIC, NULL);
statisticsmenu.nummaps = 0;
cupheader_t *cup;
for (cup = kartcupheaders; cup; cup = cup->next)
{
if (M_CupLocked(cup))
continue;
statisticsmenu.maplist[statisticsmenu.nummaps++] = cup->id;
}
statisticsmenu.maplist[statisticsmenu.nummaps] = UINT16_MAX;
statisticsmenu.location = 0;
statisticsmenu.maxscroll = statisticsmenu.nummaps - 5;
if (statisticsmenu.maxscroll < 0)
{
statisticsmenu.maxscroll = 0;
}
}
static void M_StatisticsPageInit(void)
{
switch (statisticsmenu.page)
{
case statisticspage_maps:
{
M_StatisticsMaps();
break;
}
case statisticspage_chars:
{
M_StatisticsChars();
break;
}
case statisticspage_gp:
{
M_StatisticsGP();
break;
}
default:
break;
}
}
static void M_StatisticsPageClear(void)
{
if (statisticsmenu.maplist != NULL)
{
Z_Free(statisticsmenu.maplist);
statisticsmenu.maplist = NULL;
}
}
void M_Statistics(INT32 choice)
{
(void)choice;
statisticsmenu.gotmedals = M_CountMedals(false, false);
statisticsmenu.nummedals = M_CountMedals(true, false);
statisticsmenu.numextramedals = M_CountMedals(true, true);
M_StatisticsPageInit();
MISC_StatisticsDef.prevMenu = currentMenu;
M_SetupNextMenu(&MISC_StatisticsDef, false);
@ -104,12 +274,36 @@ boolean M_StatisticsInputs(INT32 ch)
M_GoBack(0);
M_SetMenuDelay(pid);
Z_Free(statisticsmenu.maplist);
statisticsmenu.maplist = NULL;
M_StatisticsPageClear();
return true;
}
if (menucmd[pid].dpad_lr != 0)
{
M_StatisticsPageClear();
statisticsmenu.page +=
statisticspage_max
+ (
(menucmd[pid].dpad_lr > 0)
? 1
: -1
);
statisticsmenu.page %= statisticspage_max;
M_StatisticsPageInit();
S_StartSound(NULL, sfx_s3k5b);
M_SetMenuDelay(pid);
return true;
}
if (statisticsmenu.maplist == NULL)
return true;
if (M_MenuExtraPressed(pid))
{
if (statisticsmenu.location > 0)

View file

@ -7,11 +7,11 @@
menuitem_t PLAY_RaceDifficulty[] =
{
// For GP
{IT_STRING | IT_CVAR, "Difficulty", "Select the game difficulty",
{IT_STRING | IT_CVAR, "Difficulty", "Select the game difficulty.",
"MENUI004", {.cvar = &cv_dummygpdifficulty}, 0, 0},
// Match Race
{IT_STRING | IT_CVAR, "Difficulty", "Select the game speed",
{IT_STRING | IT_CVAR, "Difficulty", "Select the game speed.",
"MENUI005", {.cvar = &cv_dummykartspeed}, 0, 0},
// DISABLE THAT OPTION OUTSIDE OF MATCH RACE

View file

@ -59,11 +59,11 @@ boolean M_TimeAttackInputs(INT32 ch)
// see ta_e
menuitem_t PLAY_TimeAttack[] =
{
{IT_STRING | IT_SUBMENU, "Replay...", NULL, NULL, {.submenu = &PLAY_TAReplayDef}, 0, 0},
{IT_STRING | IT_SUBMENU, "Guest...", NULL, NULL, {.submenu = &PLAY_TAReplayGuestDef}, 0, 0},
{IT_STRING | IT_SUBMENU, "Ghosts...", NULL, NULL, {.submenu = &PLAY_TAGhostsDef}, 0, 0},
{IT_STRING | IT_SUBMENU, "Replay...", NULL, "MENUI006", {.submenu = &PLAY_TAReplayDef}, 0, 0},
{IT_STRING | IT_SUBMENU, "Guest...", NULL, "MENUI006", {.submenu = &PLAY_TAReplayGuestDef}, 0, 0},
{IT_STRING | IT_SUBMENU, "Ghosts...", NULL, "MENUI006", {.submenu = &PLAY_TAGhostsDef}, 0, 0},
{IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0},
{IT_STRING | IT_CALL, "Start", NULL, NULL, {.routine = M_StartTimeAttack}, 0, 0},
{IT_STRING | IT_CALL, "Start", NULL, "MENUI006", {.routine = M_StartTimeAttack}, 0, 0},
};
menu_t PLAY_TimeAttackDef = {
@ -98,15 +98,15 @@ typedef enum
menuitem_t PLAY_TAReplay[] =
{
{IT_STRING | IT_CALL, "Replay Best Time", NULL, NULL, {.routine = M_ReplayTimeAttack}, 0, 0},
{IT_STRING | IT_CALL, "Replay Best Lap", NULL, NULL, {.routine = M_ReplayTimeAttack}, 0, 0},
{IT_STRING | IT_CALL, "Replay Best Time", NULL, "MENUI006", {.routine = M_ReplayTimeAttack}, 0, 0},
{IT_STRING | IT_CALL, "Replay Best Lap", NULL, "MENUI006", {.routine = M_ReplayTimeAttack}, 0, 0},
{IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0},
{IT_STRING | IT_CALL, "Replay Last", NULL, NULL, {.routine = M_ReplayTimeAttack}, 0, 0},
{IT_STRING | IT_CALL, "Replay Guest", NULL, NULL, {.routine = M_ReplayTimeAttack}, 0, 0},
{IT_STRING | IT_ARROWS, "Replay Staff", NULL, NULL, {.routine = M_HandleStaffReplay}, 0, 0},
{IT_STRING | IT_CALL, "Replay Last", NULL, "MENUI006", {.routine = M_ReplayTimeAttack}, 0, 0},
{IT_STRING | IT_CALL, "Replay Guest", NULL, "MENUI006", {.routine = M_ReplayTimeAttack}, 0, 0},
{IT_STRING | IT_ARROWS, "Replay Staff", NULL, "MENUI006", {.routine = M_HandleStaffReplay}, 0, 0},
{IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0},
{IT_STRING | IT_SUBMENU, "Back", NULL, NULL, {.submenu = &PLAY_TimeAttackDef}, 0, 0},
{IT_STRING | IT_SUBMENU, "Back", NULL, "MENUI006", {.submenu = &PLAY_TimeAttackDef}, 0, 0},
};
menu_t PLAY_TAReplayDef = {
@ -140,17 +140,17 @@ typedef enum
menuitem_t PLAY_TAReplayGuest[] =
{
{IT_HEADERTEXT|IT_HEADER, "Save as guest...", NULL, NULL, {NULL}, 0, 0},
{IT_HEADERTEXT|IT_HEADER, "Save as guest...", NULL, "MENUI006", {NULL}, 0, 0},
{IT_STRING | IT_CALL, "Best Time", NULL, NULL, {.routine = M_SetGuestReplay}, 0, 0},
{IT_STRING | IT_CALL, "Best Lap", NULL, NULL, {.routine = M_SetGuestReplay}, 0, 0},
{IT_STRING | IT_CALL, "Last Run", NULL, NULL, {.routine = M_SetGuestReplay}, 0, 0},
{IT_STRING | IT_CALL, "Best Time", NULL, "MENUI006", {.routine = M_SetGuestReplay}, 0, 0},
{IT_STRING | IT_CALL, "Best Lap", NULL, "MENUI006", {.routine = M_SetGuestReplay}, 0, 0},
{IT_STRING | IT_CALL, "Last Run", NULL, "MENUI006", {.routine = M_SetGuestReplay}, 0, 0},
{IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0},
{IT_STRING | IT_CALL, "Delete Guest", NULL, NULL, {.routine = M_SetGuestReplay}, 0, 0},
{IT_STRING | IT_CALL, "Delete Guest", NULL, "MENUI006", {.routine = M_SetGuestReplay}, 0, 0},
{IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0},
{IT_STRING | IT_SUBMENU, "Back", NULL, NULL, {.submenu = &PLAY_TimeAttackDef}, 0, 0},
{IT_STRING | IT_SUBMENU, "Back", NULL, "MENUI006", {.submenu = &PLAY_TimeAttackDef}, 0, 0},
};
@ -184,14 +184,14 @@ typedef enum
menuitem_t PLAY_TAGhosts[] =
{
{IT_STRING | IT_CVAR, "Best Time", NULL, NULL, {.cvar = &cv_ghost_besttime}, 0, 0},
{IT_STRING | IT_CVAR, "Best Lap", NULL, NULL, {.cvar = &cv_ghost_bestlap}, 0, 0},
{IT_STRING | IT_CVAR, "Last", NULL, NULL, {.cvar = &cv_ghost_last}, 0, 0},
{IT_DISABLED, "Guest", NULL, NULL, {.cvar = &cv_ghost_guest}, 0, 0},
{IT_DISABLED, "Staff", NULL, NULL, {.cvar = &cv_ghost_staff}, 0, 0},
{IT_STRING | IT_CVAR, "Best Time", NULL, "MENUI006", {.cvar = &cv_ghost_besttime}, 0, 0},
{IT_STRING | IT_CVAR, "Best Lap", NULL, "MENUI006", {.cvar = &cv_ghost_bestlap}, 0, 0},
{IT_STRING | IT_CVAR, "Last", NULL, "MENUI006", {.cvar = &cv_ghost_last}, 0, 0},
{IT_DISABLED, "Guest", NULL, "MENUI006", {.cvar = &cv_ghost_guest}, 0, 0},
{IT_DISABLED, "Staff", NULL, "MENUI006", {.cvar = &cv_ghost_staff}, 0, 0},
{IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0},
{IT_STRING | IT_SUBMENU, "Back", NULL, NULL, {.submenu = &PLAY_TimeAttackDef}, 0, 0},
{IT_STRING | IT_SUBMENU, "Back", NULL, "MENUI006", {.submenu = &PLAY_TimeAttackDef}, 0, 0},
};
menu_t PLAY_TAGhostsDef = {

View file

@ -252,6 +252,13 @@ boolean M_LevelListFromGametype(INT16 gt)
PLAY_LevelSelectDef.music = \
PLAY_TimeAttackDef.music = \
currentMenu->music;
if (gamestate == GS_MENU)
{
PLAY_CupSelectDef.menuitems[0].patch = \
PLAY_LevelSelectDef.menuitems[0].patch = \
currentMenu->menuitems[itemOn].patch;
}
}
// Obviously go to Cup Select in gametypes that have cups.

View file

@ -406,7 +406,7 @@ void P_DeleteHeaderFollowers(UINT16 i)
static void P_ClearSingleMapHeaderInfo(INT16 num)
{
mapheaderinfo[num]->lvlttl[0] = '\0';
mapheaderinfo[num]->subttl[0] = '\0';
mapheaderinfo[num]->menuttl[0] = '\0';
mapheaderinfo[num]->zonttl[0] = '\0';
mapheaderinfo[num]->actnum = 0;
mapheaderinfo[num]->typeoflevel = 0;