mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Conversion to using gamedata_t
A small piece of (STJr/SRB2!1756). Due to how RR currently handles time attack records and how it WILL handle unlocks, it's not currently feasible to split everything such that you can have two independent gamedata_t... but what's done so far is certainly more sane and less dependent on global variables Other minor refactors: - M_UpdateUnlockablesAndExtraEmblems and M_SilentUpdateUnlockablesAndEmblems are now one function with a boolean for loudness - Unlock prints are currently living in the console, since the cecho stuff was a little broken
This commit is contained in:
parent
6a2aa87e95
commit
845fe12b52
18 changed files with 174 additions and 186 deletions
|
|
@ -1377,6 +1377,8 @@ void D_SRB2Main(void)
|
|||
Z_Init();
|
||||
CON_SetLoadingProgress(LOADED_ZINIT);
|
||||
|
||||
M_NewGameDataStruct();
|
||||
|
||||
// Do this up here so that WADs loaded through the command line can use ExecCfg
|
||||
COM_Init();
|
||||
|
||||
|
|
|
|||
|
|
@ -186,8 +186,6 @@ extern INT32 postimgparam[MAXSPLITSCREENPLAYERS];
|
|||
extern INT32 viewwindowx, viewwindowy;
|
||||
extern INT32 viewwidth, scaledviewwidth;
|
||||
|
||||
extern boolean gamedataloaded;
|
||||
|
||||
// Player taking events, and displaying.
|
||||
extern INT32 consoleplayer;
|
||||
extern INT32 displayplayers[MAXSPLITSCREENPLAYERS];
|
||||
|
|
@ -538,9 +536,6 @@ typedef struct
|
|||
extern tolinfo_t TYPEOFLEVEL[NUMTOLNAMES];
|
||||
extern UINT32 lastcustomtol;
|
||||
|
||||
extern tic_t totalplaytime;
|
||||
extern UINT32 matchesplayed;
|
||||
|
||||
extern UINT8 stagefailed;
|
||||
|
||||
// Emeralds stored as bits to throw savegame hackers off.
|
||||
|
|
@ -682,8 +677,6 @@ extern INT16 votelevels[4][2];
|
|||
extern SINT8 votes[MAXPLAYERS];
|
||||
extern SINT8 pickedvote;
|
||||
|
||||
extern UINT32 timesBeaten; // # of times the game has been beaten.
|
||||
|
||||
// ===========================
|
||||
// Internal parameters, fixed.
|
||||
// ===========================
|
||||
|
|
|
|||
|
|
@ -866,7 +866,7 @@ boolean F_CreditResponder(event_t *event)
|
|||
return false;
|
||||
}
|
||||
|
||||
/*if (!(timesBeaten) && !(netgame || multiplayer) && !cht_debug)
|
||||
/*if (!(gamedata->timesBeaten) && !(netgame || multiplayer) && !cht_debug)
|
||||
return false;*/
|
||||
|
||||
if (key != KEY_ESCAPE && key != KEY_ENTER && key != KEY_BACKSPACE)
|
||||
|
|
@ -1024,31 +1024,6 @@ void F_GameEvaluationDrawer(void)
|
|||
|
||||
V_DrawCreditString((BASEVIDWIDTH - V_CreditStringWidth(endingtext))<<(FRACBITS-1), (BASEVIDHEIGHT-100)<<(FRACBITS-1), 0, endingtext);
|
||||
|
||||
#if 0 // the following looks like hot garbage the more unlockables we add, and we now have a lot of unlockables
|
||||
if (finalecount >= 5*TICRATE)
|
||||
{
|
||||
V_DrawString(8, 16, V_YELLOWMAP, "Unlocked:");
|
||||
|
||||
if (!usedCheats)
|
||||
{
|
||||
INT32 startcoord = 32;
|
||||
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
{
|
||||
if (unlockables[i].conditionset && unlockables[i].conditionset < MAXCONDITIONSETS
|
||||
&& unlockables[i].type && !unlockables[i].nocecho)
|
||||
{
|
||||
if (unlockables[i].unlocked)
|
||||
V_DrawString(8, startcoord, 0, unlockables[i].name);
|
||||
startcoord += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
V_DrawString(8, 96, V_YELLOWMAP, "Cheated games\ncan't unlock\nextras!");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (marathonmode)
|
||||
{
|
||||
const char *rtatext, *cuttext;
|
||||
|
|
@ -1101,9 +1076,9 @@ void F_GameEvaluationTicker(void)
|
|||
{
|
||||
if (!usedCheats)
|
||||
{
|
||||
++timesBeaten;
|
||||
++gamedata->timesBeaten;
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
|
||||
G_SaveGameData();
|
||||
|
|
@ -1611,7 +1586,7 @@ void F_EndingDrawer(void)
|
|||
//colset(linkmap, 164, 165, 169); -- the ideal purple colour to represent a clicked in-game link, but not worth it just for a soundtest-controlled secret
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 8, V_ALLOWLOWERCASE|(trans<<V_ALPHASHIFT), str);
|
||||
V_DrawCharacter(32, BASEVIDHEIGHT-16, '>'|(trans<<V_ALPHASHIFT), false);
|
||||
V_DrawString(40, ((finalecount == STOPPINGPOINT-(20+TICRATE)) ? 1 : 0)+BASEVIDHEIGHT-16, ((timesBeaten || finalecount >= STOPPINGPOINT-TICRATE) ? V_PURPLEMAP : V_BLUEMAP)|(trans<<V_ALPHASHIFT), " [S] ===>");
|
||||
V_DrawString(40, ((finalecount == STOPPINGPOINT-(20+TICRATE)) ? 1 : 0)+BASEVIDHEIGHT-16, ((gamedata->timesBeaten || finalecount >= STOPPINGPOINT-TICRATE) ? V_PURPLEMAP : V_BLUEMAP)|(trans<<V_ALPHASHIFT), " [S] ===>");
|
||||
}
|
||||
|
||||
if (finalecount > STOPPINGPOINT-(20+(2*TICRATE)))
|
||||
|
|
|
|||
66
src/g_game.c
66
src/g_game.c
|
|
@ -189,7 +189,8 @@ struct quake quake;
|
|||
|
||||
// Map Header Information
|
||||
mapheader_t** mapheaderinfo = {NULL};
|
||||
INT32 nummapheaders, mapallocsize = 0;
|
||||
INT32 nummapheaders = 0;
|
||||
INT32 mapallocsize = 0;
|
||||
|
||||
// Kart cup definitions
|
||||
cupheader_t *kartcupheaders = NULL;
|
||||
|
|
@ -208,10 +209,6 @@ UINT32 tokenlist; // List of tokens collected
|
|||
boolean gottoken; // Did you get a token? Used for end of act
|
||||
INT32 tokenbits; // Used for setting token bits
|
||||
|
||||
tic_t totalplaytime;
|
||||
UINT32 matchesplayed; // SRB2Kart
|
||||
boolean gamedataloaded = false;
|
||||
|
||||
// Temporary holding place for nights data for the current map
|
||||
//nightsdata_t ntemprecords;
|
||||
|
||||
|
|
@ -340,9 +337,6 @@ static void G_ResetRandMapBuffer(void)
|
|||
//intentionally not resetting randmaps.counttogametype here
|
||||
}
|
||||
|
||||
// Grading
|
||||
UINT32 timesBeaten;
|
||||
|
||||
typedef struct joystickvector2_s
|
||||
{
|
||||
INT32 xaxis;
|
||||
|
|
@ -600,7 +594,7 @@ static void G_UpdateRecordReplays(void)
|
|||
if ((earnedEmblems = M_CheckLevelEmblems()))
|
||||
CONS_Printf(M_GetText("\x82" "Earned %hu medal%s for Record Attack records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
S_StartSound(NULL, sfx_ncitem);
|
||||
|
||||
// SRB2Kart - save here so you NEVER lose your earned times/medals.
|
||||
|
|
@ -2194,8 +2188,8 @@ static inline void G_PlayerFinishLevel(INT32 player)
|
|||
{
|
||||
if (legitimateexit && !demo.playback && !mapreset) // (yes you're allowed to unlock stuff this way when the game is modified)
|
||||
{
|
||||
matchesplayed++;
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
gamedata->matchesplayed++;
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
S_StartSound(NULL, sfx_ncitem);
|
||||
G_SaveGameData();
|
||||
}
|
||||
|
|
@ -3691,7 +3685,7 @@ static void G_UpdateVisited(void)
|
|||
if ((earnedEmblems = M_CompletionEmblems()))
|
||||
CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : "");
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
S_StartSound(NULL, sfx_ncitem);
|
||||
G_SaveGameData();
|
||||
}
|
||||
|
|
@ -3876,7 +3870,7 @@ static void G_GetNextMap(void)
|
|||
while (cup)
|
||||
{
|
||||
// Not unlocked? Grab the next result afterwards
|
||||
if (!marathonmode && cup->unlockrequired != -1 && !unlockables[cup->unlockrequired].unlocked)
|
||||
if (!marathonmode && cup->unlockrequired != -1 && !gamedata->unlocked[cup->unlockrequired])
|
||||
{
|
||||
cup = cup->next;
|
||||
gettingresult = 1;
|
||||
|
|
@ -4326,15 +4320,15 @@ void G_LoadGameData(void)
|
|||
UINT32 numgamedatamapheaders;
|
||||
|
||||
// Stop saving, until we successfully load it again.
|
||||
gamedataloaded = false;
|
||||
gamedata->loaded = false;
|
||||
|
||||
// Clear things so previously read gamedata doesn't transfer
|
||||
// to new gamedata
|
||||
G_ClearRecords(); // main and nights records
|
||||
G_ClearRecords(); // records
|
||||
M_ClearSecrets(); // emblems, unlocks, maps visited, etc
|
||||
|
||||
totalplaytime = 0; // total play time (separate from all)
|
||||
matchesplayed = 0; // SRB2Kart: matches played & finished
|
||||
gamedata->totalplaytime = 0; // total play time (separate from all)
|
||||
gamedata->matchesplayed = 0; // SRB2Kart: matches played & finished
|
||||
|
||||
if (M_CheckParm("-nodata"))
|
||||
{
|
||||
|
|
@ -4345,7 +4339,7 @@ void G_LoadGameData(void)
|
|||
if (M_CheckParm("-resetdata"))
|
||||
{
|
||||
// Don't load, but do save. (essentially, reset)
|
||||
gamedataloaded = true;
|
||||
gamedata->loaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4353,7 +4347,7 @@ void G_LoadGameData(void)
|
|||
if (!length)
|
||||
{
|
||||
// No gamedata. We can save a new one.
|
||||
gamedataloaded = true;
|
||||
gamedata->loaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4372,8 +4366,8 @@ void G_LoadGameData(void)
|
|||
I_Error("Game data is not for Ring Racers v2.0.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
|
||||
}
|
||||
|
||||
totalplaytime = READUINT32(save_p);
|
||||
matchesplayed = READUINT32(save_p);
|
||||
gamedata->totalplaytime = READUINT32(save_p);
|
||||
gamedata->matchesplayed = READUINT32(save_p);
|
||||
|
||||
{
|
||||
// Quick & dirty hash for what mod this save file is for.
|
||||
|
|
@ -4392,32 +4386,32 @@ void G_LoadGameData(void)
|
|||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j)
|
||||
emblemlocations[j+i].collected = ((rtemp >> j) & 1);
|
||||
gamedata->collected[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXEXTRAEMBLEMS;)
|
||||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j)
|
||||
extraemblems[j+i].collected = ((rtemp >> j) & 1);
|
||||
gamedata->extraCollected[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXUNLOCKABLES;)
|
||||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
|
||||
unlockables[j+i].unlocked = ((rtemp >> j) & 1);
|
||||
gamedata->unlocked[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXCONDITIONSETS;)
|
||||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j)
|
||||
conditionSets[j+i].achieved = ((rtemp >> j) & 1);
|
||||
gamedata->achieved[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
|
||||
timesBeaten = READUINT32(save_p);
|
||||
gamedata->timesBeaten = READUINT32(save_p);
|
||||
|
||||
// Main records
|
||||
numgamedatamapheaders = READUINT32(save_p);
|
||||
|
|
@ -4469,10 +4463,10 @@ void G_LoadGameData(void)
|
|||
// It used to do this much earlier, but this would cause the gamedata to
|
||||
// save over itself when it I_Errors from the corruption landing point below,
|
||||
// which can accidentally delete players' legitimate data if the code ever has any tiny mistakes!
|
||||
gamedataloaded = true;
|
||||
gamedata->loaded = true;
|
||||
|
||||
// Silent update unlockables in case they're out of sync with conditions
|
||||
M_SilentUpdateUnlockablesAndEmblems();
|
||||
M_UpdateUnlockablesAndExtraEmblems(false);
|
||||
|
||||
return;
|
||||
|
||||
|
|
@ -4498,7 +4492,7 @@ void G_SaveGameData(void)
|
|||
INT32 i, j;
|
||||
UINT8 btemp;
|
||||
|
||||
if (!gamedataloaded)
|
||||
if (!gamedata->loaded)
|
||||
return; // If never loaded (-nodata), don't save
|
||||
|
||||
if (usedCheats)
|
||||
|
|
@ -4522,8 +4516,8 @@ void G_SaveGameData(void)
|
|||
// Version test
|
||||
|
||||
WRITEUINT32(save_p, GD_VERSIONCHECK); // 4
|
||||
WRITEUINT32(save_p, totalplaytime); // 4
|
||||
WRITEUINT32(save_p, matchesplayed); // 4
|
||||
WRITEUINT32(save_p, gamedata->totalplaytime); // 4
|
||||
WRITEUINT32(save_p, gamedata->matchesplayed); // 4
|
||||
WRITEUINT32(save_p, quickncasehash(timeattackfolder, 64));
|
||||
|
||||
// To save space, use one bit per collected/achieved/unlocked flag
|
||||
|
|
@ -4531,7 +4525,7 @@ void G_SaveGameData(void)
|
|||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j)
|
||||
btemp |= (emblemlocations[j+i].collected << j);
|
||||
btemp |= (gamedata->collected[j+i] << j);
|
||||
WRITEUINT8(save_p, btemp);
|
||||
i += j;
|
||||
}
|
||||
|
|
@ -4539,7 +4533,7 @@ void G_SaveGameData(void)
|
|||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j)
|
||||
btemp |= (extraemblems[j+i].collected << j);
|
||||
btemp |= (gamedata->extraCollected[j+i] << j);
|
||||
WRITEUINT8(save_p, btemp);
|
||||
i += j;
|
||||
}
|
||||
|
|
@ -4547,7 +4541,7 @@ void G_SaveGameData(void)
|
|||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
|
||||
btemp |= (unlockables[j+i].unlocked << j);
|
||||
btemp |= (gamedata->unlocked[j+i] << j);
|
||||
WRITEUINT8(save_p, btemp);
|
||||
i += j;
|
||||
}
|
||||
|
|
@ -4555,12 +4549,12 @@ void G_SaveGameData(void)
|
|||
{
|
||||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j)
|
||||
btemp |= (conditionSets[j+i].achieved << j);
|
||||
btemp |= (gamedata->achieved[j+i] << j);
|
||||
WRITEUINT8(save_p, btemp);
|
||||
i += j;
|
||||
}
|
||||
|
||||
WRITEUINT32(save_p, timesBeaten); // 4
|
||||
WRITEUINT32(save_p, gamedata->timesBeaten); // 4
|
||||
|
||||
// Main records
|
||||
WRITEUINT32(save_p, nummapheaders); // 4
|
||||
|
|
|
|||
|
|
@ -1494,7 +1494,7 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
|
|||
static boolean canplaysound = true;
|
||||
tic_t timetoreach = emblem->var;
|
||||
|
||||
if (emblem->collected)
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -1908,7 +1908,7 @@ static void M_DrawCupPreview(INT16 y, cupheader_t *cup)
|
|||
|
||||
V_DrawFill(0, y, BASEVIDWIDTH, 54, 31);
|
||||
|
||||
if (cup && (cup->unlockrequired == -1 || unlockables[cup->unlockrequired].unlocked))
|
||||
if (cup && (cup->unlockrequired == -1 || gamedata->unlocked[cup->unlockrequired]))
|
||||
{
|
||||
i = (cupgrid.previewanim / 82) % cup->numlevels;
|
||||
while (x < BASEVIDWIDTH + pad)
|
||||
|
|
@ -1946,7 +1946,7 @@ static void M_DrawCupTitle(INT16 y, cupheader_t *cup)
|
|||
|
||||
if (cup)
|
||||
{
|
||||
boolean unlocked = (cup->unlockrequired == -1 || unlockables[cup->unlockrequired].unlocked);
|
||||
boolean unlocked = (cup->unlockrequired == -1 || gamedata->unlocked[cup->unlockrequired]);
|
||||
UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GREY, GTC_MENUCACHE);
|
||||
patch_t *icon = W_CachePatchName(cup->icon, PU_CACHE);
|
||||
const char *str = (unlocked ? va("%s Cup", cup->name) : "???");
|
||||
|
|
@ -2014,7 +2014,7 @@ void M_DrawCupSelect(void)
|
|||
|
||||
V_DrawScaledPatch(x, y, 0, patch);
|
||||
|
||||
if (iconcup->unlockrequired != -1 && !unlockables[iconcup->unlockrequired].unlocked)
|
||||
if (iconcup->unlockrequired != -1 && !gamedata->unlocked[iconcup->unlockrequired])
|
||||
{
|
||||
patch_t *st = W_CachePatchName(va("ICONST0%d", (cupgrid.previewanim % 4) + 1), PU_CACHE);
|
||||
V_DrawScaledPatch(x + 8, y + icony, 0, st);
|
||||
|
|
|
|||
|
|
@ -343,8 +343,8 @@ static void M_EraseDataResponse(INT32 ch)
|
|||
if (optionsmenu.erasecontext == 2)
|
||||
{
|
||||
// SRB2Kart: This actually needs to be done FIRST, so that you don't immediately regain playtime/matches secrets
|
||||
totalplaytime = 0;
|
||||
matchesplayed = 0;
|
||||
gamedata->totalplaytime = 0;
|
||||
gamedata->matchesplayed = 0;
|
||||
}
|
||||
if (optionsmenu.erasecontext != 1)
|
||||
G_ClearRecords();
|
||||
|
|
@ -3441,7 +3441,7 @@ static void M_LevelListFromGametype(INT16 gt)
|
|||
|
||||
while (cup)
|
||||
{
|
||||
if (cup->unlockrequired == -1 || unlockables[cup->unlockrequired].unlocked)
|
||||
if (cup->unlockrequired == -1 || gamedata->unlocked[cup->unlockrequired])
|
||||
{
|
||||
highestid = cup->id;
|
||||
if (Playing() && mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == cup)
|
||||
|
|
@ -3575,7 +3575,7 @@ void M_CupSelectHandler(INT32 choice)
|
|||
M_SetMenuDelay(pid);
|
||||
|
||||
if ((!newcup)
|
||||
|| (newcup && newcup->unlockrequired != -1 && !unlockables[newcup->unlockrequired].unlocked)
|
||||
|| (newcup && newcup->unlockrequired != -1 && !gamedata->unlocked[newcup->unlockrequired])
|
||||
|| (newcup->cachedlevels[0] == NEXTMAP_INVALID))
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3kb2);
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ void K_CashInPowerLevels(void)
|
|||
{
|
||||
pr->powerlevels[powerType] = clientpowerlevels[i][powerType];
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
{
|
||||
S_StartSound(NULL, sfx_ncitem);
|
||||
}
|
||||
|
|
@ -642,7 +642,7 @@ void K_PlayerForfeit(UINT8 playerNum, boolean pointLoss)
|
|||
{
|
||||
pr->powerlevels[powerType] = yourPower + inc;
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
{
|
||||
S_StartSound(NULL, sfx_ncitem);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,16 +76,16 @@ static UINT8 cheatf_warp(void)
|
|||
{
|
||||
if (!unlockables[i].conditionset)
|
||||
continue;
|
||||
if (!unlockables[i].unlocked)
|
||||
if (!gamedata->unlocked[i])
|
||||
{
|
||||
unlockables[i].unlocked = true;
|
||||
gamedata->unlocked[i] = true;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
G_SaveGameData(); //G_SetUsedCheats();
|
||||
G_SetUsedCheats();
|
||||
S_StartSound(0, sfx_kc42);
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ static UINT8 cheatf_devmode(void)
|
|||
// Just unlock all the things and turn on -debug and console devmode.
|
||||
G_SetUsedCheats();
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
unlockables[i].unlocked = true;
|
||||
gamedata->unlocked[i] = true;
|
||||
devparm = true;
|
||||
cht_debug |= 0x8000;
|
||||
|
||||
|
|
|
|||
160
src/m_cond.c
160
src/m_cond.c
|
|
@ -24,6 +24,8 @@
|
|||
#include "k_pwrlv.h"
|
||||
#include "k_profiles.h"
|
||||
|
||||
gamedata_t *gamedata = NULL;
|
||||
|
||||
// Map triggers for linedef executors
|
||||
// 32 triggers, one bit each
|
||||
UINT32 unlocktriggers;
|
||||
|
|
@ -44,6 +46,14 @@ unlockable_t unlockables[MAXUNLOCKABLES];
|
|||
INT32 numemblems = 0;
|
||||
INT32 numextraemblems = 0;
|
||||
|
||||
// Create a new gamedata_t, for start-up
|
||||
void M_NewGameDataStruct(void)
|
||||
{
|
||||
gamedata = Z_Calloc(sizeof (gamedata_t), PU_STATIC, NULL);
|
||||
M_ClearSecrets();
|
||||
G_ClearRecords();
|
||||
}
|
||||
|
||||
void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2)
|
||||
{
|
||||
condition_t *cond;
|
||||
|
|
@ -73,7 +83,7 @@ void M_ClearConditionSet(UINT8 set)
|
|||
conditionSets[set - 1].condition = NULL;
|
||||
conditionSets[set - 1].numconditions = 0;
|
||||
}
|
||||
conditionSets[set - 1].achieved = false;
|
||||
gamedata->achieved[set - 1] = false;
|
||||
}
|
||||
|
||||
// Clear ALL secrets.
|
||||
|
|
@ -87,18 +97,18 @@ void M_ClearSecrets(void)
|
|||
}
|
||||
|
||||
for (i = 0; i < MAXEMBLEMS; ++i)
|
||||
emblemlocations[i].collected = false;
|
||||
gamedata->collected[i] = false;
|
||||
for (i = 0; i < MAXEXTRAEMBLEMS; ++i)
|
||||
extraemblems[i].collected = false;
|
||||
gamedata->extraCollected[i] = false;
|
||||
for (i = 0; i < MAXUNLOCKABLES; ++i)
|
||||
unlockables[i].unlocked = false;
|
||||
gamedata->unlocked[i] = false;
|
||||
for (i = 0; i < MAXCONDITIONSETS; ++i)
|
||||
conditionSets[i].achieved = false;
|
||||
gamedata->achieved[i] = false;
|
||||
|
||||
timesBeaten = 0;
|
||||
gamedata->timesBeaten = 0;
|
||||
|
||||
// Re-unlock any always unlocked things
|
||||
M_SilentUpdateUnlockablesAndEmblems();
|
||||
M_UpdateUnlockablesAndExtraEmblems(false);
|
||||
}
|
||||
|
||||
// ----------------------
|
||||
|
|
@ -109,9 +119,9 @@ UINT8 M_CheckCondition(condition_t *cn)
|
|||
switch (cn->type)
|
||||
{
|
||||
case UC_PLAYTIME: // Requires total playing time >= x
|
||||
return (totalplaytime >= (unsigned)cn->requirement);
|
||||
return (gamedata->totalplaytime >= (unsigned)cn->requirement);
|
||||
case UC_MATCHESPLAYED: // Requires any level completed >= x times
|
||||
return (matchesplayed >= (unsigned)cn->requirement);
|
||||
return (gamedata->matchesplayed >= (unsigned)cn->requirement);
|
||||
case UC_POWERLEVEL: // Requires power level >= x on a certain gametype
|
||||
{
|
||||
UINT8 i;
|
||||
|
|
@ -128,7 +138,7 @@ UINT8 M_CheckCondition(condition_t *cn)
|
|||
return false;
|
||||
}
|
||||
case UC_GAMECLEAR: // Requires game beaten >= x times
|
||||
return (timesBeaten >= (unsigned)cn->requirement);
|
||||
return (gamedata->timesBeaten >= (unsigned)cn->requirement);
|
||||
case UC_OVERALLTIME: // Requires overall time <= x
|
||||
return (M_GotLowEnoughTime(cn->requirement));
|
||||
case UC_MAPVISITED: // Requires map x to be visited
|
||||
|
|
@ -152,9 +162,9 @@ UINT8 M_CheckCondition(condition_t *cn)
|
|||
case UC_TOTALEMBLEMS: // Requires number of emblems >= x
|
||||
return (M_GotEnoughEmblems(cn->requirement));
|
||||
case UC_EMBLEM: // Requires emblem x to be obtained
|
||||
return emblemlocations[cn->requirement-1].collected;
|
||||
return gamedata->collected[cn->requirement-1];
|
||||
case UC_EXTRAEMBLEM: // Requires extra emblem x to be obtained
|
||||
return extraemblems[cn->requirement-1].collected;
|
||||
return gamedata->extraCollected[cn->requirement-1];
|
||||
case UC_CONDITIONSET: // requires condition set x to already be achieved
|
||||
return M_Achieved(cn->requirement-1);
|
||||
}
|
||||
|
|
@ -196,14 +206,14 @@ void M_CheckUnlockConditions(void)
|
|||
for (i = 0; i < MAXCONDITIONSETS; ++i)
|
||||
{
|
||||
c = &conditionSets[i];
|
||||
if (!c->numconditions || c->achieved)
|
||||
if (!c->numconditions || gamedata->achieved[i])
|
||||
continue;
|
||||
|
||||
c->achieved = (M_CheckConditionSet(c));
|
||||
gamedata->achieved[i] = (M_CheckConditionSet(c));
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 M_UpdateUnlockablesAndExtraEmblems(void)
|
||||
boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud)
|
||||
{
|
||||
INT32 i;
|
||||
char cechoText[992] = "";
|
||||
|
|
@ -211,16 +221,31 @@ UINT8 M_UpdateUnlockablesAndExtraEmblems(void)
|
|||
|
||||
M_CheckUnlockConditions();
|
||||
|
||||
if (!loud)
|
||||
{
|
||||
// Just in case they aren't to sync
|
||||
M_CheckLevelEmblems();
|
||||
M_CompletionEmblems();
|
||||
}
|
||||
|
||||
// Go through extra emblems
|
||||
for (i = 0; i < numextraemblems; ++i)
|
||||
{
|
||||
if (extraemblems[i].collected || !extraemblems[i].conditionset)
|
||||
continue;
|
||||
if ((extraemblems[i].collected = M_Achieved(extraemblems[i].conditionset - 1)) != false)
|
||||
if (gamedata->extraCollected[i] || !extraemblems[i].conditionset)
|
||||
{
|
||||
strcat(cechoText, va(M_GetText("Got \"%s\" medal!\\"), extraemblems[i].name));
|
||||
++cechoLines;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((gamedata->extraCollected[i] = M_Achieved(extraemblems[i].conditionset - 1)) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (loud)
|
||||
{
|
||||
strcat(cechoText, va("Got \"%s\" medal!\n", extraemblems[i].name));
|
||||
}
|
||||
++cechoLines;
|
||||
}
|
||||
|
||||
// Fun part: if any of those unlocked we need to go through the
|
||||
|
|
@ -231,67 +256,40 @@ UINT8 M_UpdateUnlockablesAndExtraEmblems(void)
|
|||
// Go through unlockables
|
||||
for (i = 0; i < MAXUNLOCKABLES; ++i)
|
||||
{
|
||||
if (unlockables[i].unlocked || !unlockables[i].conditionset)
|
||||
continue;
|
||||
if ((unlockables[i].unlocked = M_Achieved(unlockables[i].conditionset - 1)) != false)
|
||||
if (gamedata->unlocked[i] || !unlockables[i].conditionset)
|
||||
{
|
||||
if (unlockables[i].nocecho)
|
||||
continue;
|
||||
strcat(cechoText, va(M_GetText("\"%s\" unlocked!\\"), unlockables[i].name));
|
||||
++cechoLines;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((gamedata->unlocked[i] = M_Achieved(unlockables[i].conditionset - 1)) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (unlockables[i].nocecho)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (loud)
|
||||
{
|
||||
strcat(cechoText, va("\"%s\" unlocked!\n", unlockables[i].name));
|
||||
}
|
||||
++cechoLines;
|
||||
}
|
||||
|
||||
// Announce
|
||||
if (cechoLines)
|
||||
if (cechoLines && loud)
|
||||
{
|
||||
char slashed[1024] = "";
|
||||
for (i = 0; (i < 19) && (i < 24 - cechoLines); ++i)
|
||||
slashed[i] = '\\';
|
||||
slashed[i] = 0;
|
||||
|
||||
strcat(slashed, cechoText);
|
||||
|
||||
HU_SetCEchoFlags(V_YELLOWMAP);
|
||||
HU_SetCEchoDuration(6);
|
||||
HU_DoCEcho(slashed);
|
||||
#ifdef DEVELOP
|
||||
// todo make debugmode
|
||||
CONS_Printf("%s\n", cechoText);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Used when loading gamedata to make sure all unlocks are synched with conditions
|
||||
void M_SilentUpdateUnlockablesAndEmblems(void)
|
||||
{
|
||||
INT32 i;
|
||||
boolean checkAgain = false;
|
||||
|
||||
// Just in case they aren't to sync
|
||||
M_CheckUnlockConditions();
|
||||
M_CheckLevelEmblems();
|
||||
|
||||
// Go through extra emblems
|
||||
for (i = 0; i < numextraemblems; ++i)
|
||||
{
|
||||
if (extraemblems[i].collected || !extraemblems[i].conditionset)
|
||||
continue;
|
||||
if ((extraemblems[i].collected = M_Achieved(extraemblems[i].conditionset - 1)) != false)
|
||||
checkAgain = true;
|
||||
}
|
||||
|
||||
// check again if extra emblems unlocked, blah blah, etc
|
||||
if (checkAgain)
|
||||
M_CheckUnlockConditions();
|
||||
|
||||
// Go through unlockables
|
||||
for (i = 0; i < MAXUNLOCKABLES; ++i)
|
||||
{
|
||||
if (unlockables[i].unlocked || !unlockables[i].conditionset)
|
||||
continue;
|
||||
unlockables[i].unlocked = M_Achieved(unlockables[i].conditionset - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Emblem unlocking shit
|
||||
UINT8 M_CheckLevelEmblems(void)
|
||||
{
|
||||
|
|
@ -306,7 +304,7 @@ UINT8 M_CheckLevelEmblems(void)
|
|||
{
|
||||
INT32 checkLevel;
|
||||
|
||||
if (emblemlocations[i].type < ET_TIME || emblemlocations[i].collected)
|
||||
if (emblemlocations[i].type < ET_TIME || gamedata->collected[i])
|
||||
continue;
|
||||
|
||||
checkLevel = G_MapNumber(emblemlocations[i].level);
|
||||
|
|
@ -326,7 +324,7 @@ UINT8 M_CheckLevelEmblems(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
emblemlocations[i].collected = res;
|
||||
gamedata->collected[i] = res;
|
||||
if (res)
|
||||
++somethingUnlocked;
|
||||
}
|
||||
|
|
@ -346,7 +344,7 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa
|
|||
{
|
||||
INT32 checkLevel;
|
||||
|
||||
if (emblemlocations[i].type < ET_TIME || emblemlocations[i].collected)
|
||||
if (emblemlocations[i].type < ET_TIME || gamedata->collected[i])
|
||||
continue;
|
||||
|
||||
checkLevel = G_MapNumber(emblemlocations[i].level);
|
||||
|
|
@ -363,7 +361,7 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa
|
|||
|
||||
res = ((mapheaderinfo[levelnum]->mapvisited & flags) == flags);
|
||||
|
||||
emblemlocations[i].collected = res;
|
||||
gamedata->collected[i] = res;
|
||||
if (res)
|
||||
++somethingUnlocked;
|
||||
}
|
||||
|
|
@ -385,7 +383,7 @@ UINT8 M_AnySecretUnlocked(void)
|
|||
|
||||
for (i = 0; i < MAXUNLOCKABLES; ++i)
|
||||
{
|
||||
if (!unlockables[i].nocecho && unlockables[i].unlocked)
|
||||
if (!unlockables[i].nocecho && gamedata->unlocked[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -412,7 +410,7 @@ UINT8 M_SecretUnlocked(INT32 type)
|
|||
|
||||
for (i = 0; i < MAXUNLOCKABLES; ++i)
|
||||
{
|
||||
if (unlockables[i].type == type && unlockables[i].unlocked != CHADYES)
|
||||
if (unlockables[i].type == type && gamedata->unlocked[i] != CHADYES)
|
||||
return !CHADYES;
|
||||
}
|
||||
return CHADYES;
|
||||
|
|
@ -435,7 +433,7 @@ UINT8 M_MapLocked(INT32 mapnum)
|
|||
if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0)
|
||||
return false;
|
||||
|
||||
if (!unlockables[mapheaderinfo[mapnum-1]->unlockrequired].unlocked)
|
||||
if (!gamedata->unlocked[mapheaderinfo[mapnum-1]->unlockrequired])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -447,12 +445,12 @@ INT32 M_CountEmblems(void)
|
|||
INT32 found = 0, i;
|
||||
for (i = 0; i < numemblems; ++i)
|
||||
{
|
||||
if (emblemlocations[i].collected)
|
||||
if (gamedata->collected[i])
|
||||
found++;
|
||||
}
|
||||
for (i = 0; i < numextraemblems; ++i)
|
||||
{
|
||||
if (extraemblems[i].collected)
|
||||
if (gamedata->extraCollected[i])
|
||||
found++;
|
||||
}
|
||||
return found;
|
||||
|
|
@ -469,12 +467,12 @@ UINT8 M_GotEnoughEmblems(INT32 number)
|
|||
INT32 i, gottenemblems = 0;
|
||||
for (i = 0; i < numemblems; ++i)
|
||||
{
|
||||
if (emblemlocations[i].collected)
|
||||
if (gamedata->collected[i])
|
||||
if (++gottenemblems >= number) return true;
|
||||
}
|
||||
for (i = 0; i < numextraemblems; ++i)
|
||||
{
|
||||
if (extraemblems[i].collected)
|
||||
if (gamedata->extraCollected[i])
|
||||
if (++gottenemblems >= number) return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
41
src/m_cond.h
41
src/m_cond.h
|
|
@ -52,8 +52,6 @@ typedef struct
|
|||
{
|
||||
UINT32 numconditions; /// <- number of conditions.
|
||||
condition_t *condition; /// <- All conditionals to be checked.
|
||||
UINT8 achieved; /// <- Whether this conditional has been achieved already or not.
|
||||
/// (Conditional checking is skipped if true -- it's assumed you can't relock an unlockable)
|
||||
} conditionset_t;
|
||||
|
||||
// Emblem information
|
||||
|
|
@ -79,7 +77,6 @@ typedef struct
|
|||
INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin)
|
||||
char *stringVar; ///< String version
|
||||
char hint[110]; ///< Hint for emblem hints menu
|
||||
UINT8 collected; ///< Do you have this emblem?
|
||||
} emblem_t;
|
||||
typedef struct
|
||||
{
|
||||
|
|
@ -89,7 +86,6 @@ typedef struct
|
|||
UINT8 showconditionset; ///< Condition set that shows this emblem.
|
||||
UINT8 sprite; ///< emblem sprite to use, 0 - 25
|
||||
UINT16 color; ///< skincolor to use
|
||||
UINT8 collected; ///< Do you have this emblem?
|
||||
} extraemblem_t;
|
||||
|
||||
// Unlockable information
|
||||
|
|
@ -104,7 +100,6 @@ typedef struct
|
|||
char *stringVar;
|
||||
UINT8 nocecho;
|
||||
UINT8 nochecklist;
|
||||
UINT8 unlocked;
|
||||
} unlockable_t;
|
||||
|
||||
#define SECRET_NONE 0 // Does nil. Use with levels locked by UnlockRequired
|
||||
|
|
@ -135,6 +130,35 @@ typedef struct
|
|||
#define MAXEXTRAEMBLEMS 16
|
||||
#define MAXUNLOCKABLES 32
|
||||
|
||||
// GAMEDATA STRUCTURE
|
||||
// Everything that would get saved in gamedata.dat
|
||||
typedef struct
|
||||
{
|
||||
// WHENEVER OR NOT WE'RE READY TO SAVE
|
||||
boolean loaded;
|
||||
|
||||
// CONDITION SETS ACHIEVED
|
||||
boolean achieved[MAXCONDITIONSETS];
|
||||
|
||||
// EMBLEMS COLLECTED
|
||||
boolean collected[MAXEMBLEMS];
|
||||
|
||||
// EXTRA EMBLEMS COLLECTED
|
||||
boolean extraCollected[MAXEXTRAEMBLEMS];
|
||||
|
||||
// UNLOCKABLES UNLOCKED
|
||||
boolean unlocked[MAXUNLOCKABLES];
|
||||
|
||||
// # OF TIMES THE GAME HAS BEEN BEATEN
|
||||
UINT32 timesBeaten;
|
||||
|
||||
// PLAY TIME
|
||||
UINT32 totalplaytime;
|
||||
UINT32 matchesplayed;
|
||||
} gamedata_t;
|
||||
|
||||
extern gamedata_t *gamedata;
|
||||
|
||||
extern conditionset_t conditionSets[MAXCONDITIONSETS];
|
||||
extern emblem_t emblemlocations[MAXEMBLEMS];
|
||||
extern extraemblem_t extraemblems[MAXEXTRAEMBLEMS];
|
||||
|
|
@ -145,6 +169,8 @@ extern INT32 numextraemblems;
|
|||
|
||||
extern UINT32 unlocktriggers;
|
||||
|
||||
void M_NewGameDataStruct(void);
|
||||
|
||||
// Condition set setup
|
||||
void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2);
|
||||
|
||||
|
|
@ -155,8 +181,7 @@ void M_ClearSecrets(void);
|
|||
// Updating conditions and unlockables
|
||||
void M_CheckUnlockConditions(void);
|
||||
UINT8 M_CheckCondition(condition_t *cn);
|
||||
UINT8 M_UpdateUnlockablesAndExtraEmblems(void);
|
||||
void M_SilentUpdateUnlockablesAndEmblems(void);
|
||||
boolean M_UpdateUnlockablesAndExtraEmblems(boolean silent);
|
||||
UINT8 M_CheckLevelEmblems(void);
|
||||
UINT8 M_CompletionEmblems(void);
|
||||
|
||||
|
|
@ -182,4 +207,4 @@ UINT8 M_GotLowEnoughTime(INT32 tictime);
|
|||
INT32 M_UnlockableSkinNum(unlockable_t *unlock);
|
||||
INT32 M_EmblemSkinNum(emblem_t *emblem);
|
||||
|
||||
#define M_Achieved(a) ((a) >= MAXCONDITIONSETS || conditionSets[a].achieved)
|
||||
#define M_Achieved(a) ((a) >= MAXCONDITIONSETS || gamedata->achieved[a])
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "doomtype.h"
|
||||
#include "doomstat.h" // totalplaytime
|
||||
#include "m_cond.h" // gamedata->totalplaytime
|
||||
|
||||
#include "m_random.h"
|
||||
#include "m_fixed.h"
|
||||
|
|
@ -372,5 +372,5 @@ void P_ClearRandom(UINT32 seed)
|
|||
*/
|
||||
UINT32 M_RandomizedSeed(void)
|
||||
{
|
||||
return ((totalplaytime & 0xFFFF) << 16) | M_RandomFixed();
|
||||
return ((gamedata->totalplaytime & 0xFFFF) << 16) | M_RandomFixed();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -504,8 +504,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (demo.playback || special->health > MAXEMBLEMS)
|
||||
return;
|
||||
|
||||
emblemlocations[special->health-1].collected = true;
|
||||
M_UpdateUnlockablesAndExtraEmblems();
|
||||
gamedata->collected[special->health-1] = true;
|
||||
M_UpdateUnlockablesAndExtraEmblems(true);
|
||||
G_SaveGameData();
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11969,7 +11969,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj)
|
|||
emcolor = M_GetEmblemColor(&emblemlocations[j]); // workaround for compiler complaint about bad function casting
|
||||
mobj->color = (UINT16)emcolor;
|
||||
|
||||
if (emblemlocations[j].collected)
|
||||
if (gamedata->collected[j])
|
||||
{
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->flags |= MF_NOCLIP;
|
||||
|
|
|
|||
|
|
@ -7567,7 +7567,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
{
|
||||
mapheaderinfo[gamemap-1]->mapvisited |= MV_VISITED;
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
S_StartSound(NULL, sfx_ncitem);
|
||||
G_SaveGameData();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1502,7 +1502,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
|||
CONS_Debug(DBG_GAMELOGIC, "Unlockable check (sidedef %hu): bad unlockable ID %d\n", triggerline->sidenum[0], unlockid);
|
||||
return false;
|
||||
}
|
||||
else if (!(unlockables[unlockid].unlocked))
|
||||
else if (!(gamedata->unlocked[unlockid]))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
|
@ -2763,7 +2763,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
unlocktriggers |= 1 << trigid;
|
||||
|
||||
// Unlocked something?
|
||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
G_SaveGameData(); // only save if unlocked something
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "st_stuff.h"
|
||||
#include "p_polyobj.h"
|
||||
#include "m_random.h"
|
||||
#include "m_cond.h" // gamedata->playtime
|
||||
#include "lua_script.h"
|
||||
#include "lua_hook.h"
|
||||
#include "m_perfstats.h"
|
||||
|
|
@ -628,7 +629,7 @@ void P_Ticker(boolean run)
|
|||
|
||||
// Keep track of how long they've been playing!
|
||||
if (!demo.playback) // Don't increment if a demo is playing.
|
||||
totalplaytime++;
|
||||
gamedata->totalplaytime++;
|
||||
|
||||
// formality so kitemcap gets updated properly each frame.
|
||||
P_RunKartItems();
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ UINT8 *R_GetSkinAvailabilities(boolean demolock)
|
|||
if (unlockables[i].type != SECRET_SKIN)
|
||||
continue;
|
||||
|
||||
if (unlockables[i].unlocked != true && !demolock)
|
||||
if (gamedata->unlocked[i] != true && !demolock)
|
||||
continue;
|
||||
|
||||
skinid = M_UnlockableSkinNum(&unlockables[i]);
|
||||
|
|
@ -250,7 +250,7 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum, boolean demoskins)
|
|||
}
|
||||
|
||||
// Use the unlockables table directly
|
||||
return (boolean)(unlockables[i].unlocked);
|
||||
return (boolean)(gamedata->unlocked[i]);
|
||||
}
|
||||
|
||||
// returns true if the skin name is found (loaded from pwad)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue