stickermedalinfo, UpdateTimeStickerMedals: A centralised struct for Medal info attached to the time sticker.

- K_drawKartTimestamp: Significantly less messy, no longer dependent on static variables, and no longer iterates over M_GetLevelEmblems every rendered frame(!!)
    - TODO: Still handles playing sound in the drawer
- K_PrepareTimeAttack: Initial generation of a struct of emblems/text is handled on the menu
- G_UpdateRecords: Updated in-game if you unlock the next medal there
This commit was amended to centralise the new material in g_game.c and reduce the number of header additions required.
This commit is contained in:
toaster 2023-02-05 16:13:16 +00:00
parent 63fbdcfbc0
commit 4522ba3b4d
6 changed files with 144 additions and 102 deletions

View file

@ -465,11 +465,6 @@ void G_ClearRecords(void)
Z_Free(mapheaderinfo[i]->mainrecord);
mapheaderinfo[i]->mainrecord = NULL;
}
/*if (nightsrecords[i])
{
Z_Free(nightsrecords[i]);
nightsrecords[i] = NULL;
}*/
}
}
@ -495,6 +490,84 @@ tic_t G_GetBestLap(INT16 map)
}
*/
struct stickermedalinfo stickermedalinfo;
void G_UpdateTimeStickerMedals(UINT16 map)
{
emblem_t *emblem = M_GetLevelEmblems(map+1);
boolean gonnadrawtime = false;
stickermedalinfo.visiblecount = 0;
stickermedalinfo.targettext[0] = '\0';
stickermedalinfo.emblems[0] = stickermedalinfo.regenemblem = NULL;
stickermedalinfo.timetoreach = UINT32_MAX;
stickermedalinfo.canplaysound = true;
while (emblem != NULL)
{
UINT8 i = 0;
switch (emblem->type)
{
case ET_TIME:
{
break;
}
default:
goto bademblem;
}
if (!gamedata->collected[(emblem-emblemlocations)] && gonnadrawtime)
break;
// Simpler than having two checks
if (stickermedalinfo.visiblecount == MAXMEDALVISIBLECOUNT)
stickermedalinfo.visiblecount--;
// Shuffle along, so [0] is the "main focus"
for (i = stickermedalinfo.visiblecount; i > 0; i--)
{
stickermedalinfo.emblems[i] = stickermedalinfo.emblems[i-1];
}
stickermedalinfo.emblems[0] = emblem;
stickermedalinfo.visiblecount++;
if (!gamedata->collected[(emblem-emblemlocations)] || Playing())
gonnadrawtime = true;
bademblem:
emblem = M_GetLevelEmblems(-1);
}
if (stickermedalinfo.visiblecount > 0)
{
if (emblem != NULL && emblem != stickermedalinfo.emblems[0])
{
// Regenerate the entire array if this is unlocked
stickermedalinfo.regenemblem = emblem;
}
emblem = stickermedalinfo.emblems[0];
if (gonnadrawtime)
{
stickermedalinfo.timetoreach = emblem->var;
if (emblem->tag > 0)
{
if (emblem->tag > mapheaderinfo[map]->ghostCount
|| mapheaderinfo[map]->ghostBrief[emblem->tag-1] == NULL)
goto bademblem;
stickermedalinfo.timetoreach = mapheaderinfo[map]->ghostBrief[emblem->tag-1]->time;
}
snprintf(stickermedalinfo.targettext, 9, "%i'%02i\"%02i",
G_TicsToMinutes(stickermedalinfo.timetoreach, false),
G_TicsToSeconds(stickermedalinfo.timetoreach),
G_TicsToCentiseconds(stickermedalinfo.timetoreach));
}
}
}
//
// G_UpdateRecords
//
@ -534,7 +607,14 @@ void G_UpdateRecords(void)
// Check emblems when level data is updated
if ((earnedEmblems = M_CheckLevelEmblems()))
{
CONS_Printf(M_GetText("\x82" "Earned %hu medal%s for Record Attack records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
if (stickermedalinfo.regenemblem != NULL
&& gamedata->collected[(stickermedalinfo.regenemblem-emblemlocations)])
{
G_UpdateTimeStickerMedals(gamemap-1);
}
}
M_UpdateUnlockablesAndExtraEmblems(true);
G_SaveGameData();

View file

@ -201,6 +201,18 @@ void G_UseContinue(void);
void G_AfterIntermission(void);
void G_EndGame(void); // moved from y_inter.c/h and renamed
#define MAXMEDALVISIBLECOUNT 3
extern struct stickermedalinfo
{
UINT8 visiblecount;
boolean canplaysound;
tic_t timetoreach;
emblem_t *emblems[MAXMEDALVISIBLECOUNT];
emblem_t *regenemblem;
char targettext[9];
} stickermedalinfo;
void G_UpdateTimeStickerMedals(UINT16 map);
void G_UpdateRecords(void);
void G_Ticker(boolean run);

View file

@ -1466,14 +1466,11 @@ static void K_drawKartItem(void)
}
}
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode)
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, UINT8 mode)
{
// TIME_X = BASEVIDWIDTH-124; // 196
// TIME_Y = 6; // 6
static UINT8 prevmode = UINT8_MAX;
static emblem_t *maxemblem = NULL;
tic_t worktime;
INT32 jitter = 0;
@ -1513,10 +1510,6 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
}
}
if (mode != prevmode)
maxemblem = NULL;
prevmode = mode;
V_DrawScaledPatch(TX, TY, splitflags, ((mode == 2) ? kp_lapstickerwide : kp_timestickerwide));
TX += 33;
@ -1557,105 +1550,57 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
V_DrawKartString(TX+84, TY+3-jitter, splitflags, va("%d", worktime%10));
}
if (emblemmap && (modeattacking || (mode == 1)) && !demo.playback) // emblem time!
// Medal data!
if ((modeattacking || (mode == 1))
&& !demo.playback
&& stickermedalinfo.visiblecount > 0)
{
INT32 workx = TX + 96, worky = TY+18;
SINT8 curemb = 0;
patch_t *emblempic[3] = {NULL, NULL, NULL};
UINT8 *emblemcol[3] = {NULL, NULL, NULL};
UINT8 i = stickermedalinfo.visiblecount;
emblem_t *emblem = M_GetLevelEmblems(emblemmap);
while (emblem)
if (stickermedalinfo.targettext[0] != '\0')
{
char targettext[9];
emblem_t *nextemblem = M_GetLevelEmblems(-1);
switch (emblem->type)
if (!mode)
{
case ET_TIME:
if (stplyr->realtime > stickermedalinfo.timetoreach)
{
splitflags = (splitflags &~ V_HUDTRANS)|V_HUDTRANSHALF;
if (stickermedalinfo.canplaysound)
{
static boolean canplaysound = true;
tic_t timetoreach = emblem->var;
if (gamedata->collected[(emblem-emblemlocations)])
{
emblempic[curemb] = W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE);
emblemcol[curemb] = R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE);
curemb++;
if (emblem == maxemblem
&& nextemblem != NULL
&& nextemblem->type == emblem->type
&& gamedata->collected[(nextemblem-emblemlocations)])
maxemblem = NULL;
if (emblem != maxemblem)
goto bademblem;
}
maxemblem = emblem;
if (emblem->tag > 0)
{
if (emblem->tag > mapheaderinfo[emblemmap-1]->ghostCount
|| mapheaderinfo[emblemmap-1]->ghostBrief[emblem->tag-1] == NULL)
goto bademblem;
timetoreach = mapheaderinfo[emblemmap-1]->ghostBrief[emblem->tag-1]->time;
}
snprintf(targettext, 9, "%i'%02i\"%02i",
G_TicsToMinutes(timetoreach, false),
G_TicsToSeconds(timetoreach),
G_TicsToCentiseconds(timetoreach));
if (!mode)
{
if (stplyr->realtime > timetoreach)
{
splitflags = (splitflags &~ V_HUDTRANS)|V_HUDTRANSHALF;
if (canplaysound)
{
S_StartSound(NULL, sfx_s3k72); //sfx_s26d); -- you STOLE fizzy lifting drinks
canplaysound = false;
}
}
else if (!canplaysound)
canplaysound = true;
}
targettext[8] = 0;
S_StartSound(NULL, sfx_s3k72); //sfx_s26d); -- you STOLE fizzy lifting drinks
stickermedalinfo.canplaysound = false;
}
break;
default:
goto bademblem;
}
}
workx -= V_ThinStringWidth(targettext, splitflags|V_6WIDTHSPACE);
V_DrawThinString(workx, worky, splitflags|V_6WIDTHSPACE, targettext);
if (emblem != maxemblem || !gamedata->collected[(emblem-emblemlocations)])
{
emblempic[curemb] = W_CachePatchName("NEEDIT", PU_CACHE);
curemb++;
}
break;
bademblem:
if (emblem == maxemblem || curemb == 3)
break;
emblem = nextemblem;
workx -= V_ThinStringWidth(stickermedalinfo.targettext, splitflags|V_6WIDTHSPACE);
V_DrawThinString(workx, worky, splitflags|V_6WIDTHSPACE, stickermedalinfo.targettext);
}
workx -= (6 + (i*5));
if (!mode)
splitflags = (splitflags &~ V_HUDTRANSHALF)|V_HUDTRANS;
while (curemb--)
while (i > 0)
{
workx -= 11;
V_DrawSmallMappedPatch(workx, worky, splitflags, emblempic[curemb], emblemcol[curemb]);
i--;
if (gamedata->collected[(stickermedalinfo.emblems[i]-emblemlocations)])
{
V_DrawSmallMappedPatch(workx, worky, splitflags,
W_CachePatchName(M_GetEmblemPatch(stickermedalinfo.emblems[i], false), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(stickermedalinfo.emblems[i]), GTC_CACHE)
);
}
else
{
V_DrawSmallMappedPatch(workx, worky, splitflags,
W_CachePatchName("NEEDIT", PU_CACHE),
NULL
);
}
workx += 6;
}
}
}
@ -5089,7 +5034,7 @@ void K_drawKartHUD(void)
{
// Draw the timestamp
if (LUA_HudEnabled(hud_time))
K_drawKartTimestamp(stplyr->realtime, TIME_X, TIME_Y, gamemap, 0);
K_drawKartTimestamp(stplyr->realtime, TIME_X, TIME_Y, 0);
islonesome = K_drawKartPositionFaces();
}

View file

@ -40,7 +40,7 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny);
void K_LoadKartHUDGraphics(void);
void K_drawKartHUD(void);
void K_drawKartFreePlay(void);
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode);
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, UINT8 mode);
void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol);
void K_DrawMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, UINT16 map, UINT8 *colormap);
void K_DrawLikeMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, patch_t *patch, UINT8 *colormap);

View file

@ -2266,7 +2266,7 @@ void M_DrawTimeAttack(void)
&& (mapheaderinfo[map]->numlaps != 1))
{
V_DrawRightAlignedString(rightedge-12, timeheight, highlightflags, "BEST LAP:");
K_drawKartTimestamp(laprec, 162+t, timeheight+6, 0, 2);
K_drawKartTimestamp(laprec, 162+t, timeheight+6, 2);
timeheight += 30;
}
else
@ -2275,7 +2275,7 @@ void M_DrawTimeAttack(void)
}
V_DrawRightAlignedString(rightedge-12, timeheight, highlightflags, "BEST TIME:");
K_drawKartTimestamp(timerec, 162+t, timeheight+6, map+1, 1);
K_drawKartTimestamp(timerec, 162+t, timeheight+6, 1);
}
else
opty = 80;

View file

@ -178,6 +178,7 @@ void M_PrepareTimeAttack(INT32 choice)
{
(void) choice;
// Gametype guess
if (levellist.guessgt != MAXGAMETYPES)
{
levellist.newgametype = levellist.guessgt;
@ -189,6 +190,10 @@ void M_PrepareTimeAttack(INT32 choice)
}
}
// Time-sticker Medals
G_UpdateTimeStickerMedals(levellist.choosemap);
// Menu options
{
// see also p_setup.c's P_LoadRecordGhosts
char *gpath = Z_StrDup(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(levellist.choosemap+1)));