mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
gamedata->roundsplayed: Split into multiple roughly-gametype-aligned categories
- Race, Capsule, Battle, Special, Custom
- All categories can now be used for Rounds Played condition
- UCRP_SEALEDSTAR now hides if you haven't beaten a single Sealed Star yet
In addition, introduce M_ClearStats
- As more statistics get added, clearing them manually in G_LoadGameData and M_EraseDataResponse is just going to get annoying
- Change around the options on the Erase Data screen to
- Make it clear that erasing all game data won't clear your Profiles
- Add an option to clear stats by themselves, rather than only permitting via complete gamedata wipe
- Move to the "Challenges" terminology over SRB2's "Secrets" terminology
- Move some entries that were previously handled in M_ClearSecrets into M_ClearStats
This commit is contained in:
parent
22f9467e71
commit
e994b920c6
6 changed files with 197 additions and 47 deletions
|
|
@ -2363,13 +2363,44 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((offset=0) || fastcmp(params[0], "PLAYTIME")
|
if (fastcmp(params[0], "PLAYTIME"))
|
||||||
|| (++offset && fastcmp(params[0], "MATCHESPLAYED")))
|
|
||||||
{
|
{
|
||||||
PARAMCHECK(1);
|
PARAMCHECK(1);
|
||||||
ty = UC_PLAYTIME + offset;
|
ty = UC_PLAYTIME + offset;
|
||||||
re = atoi(params[1]);
|
re = atoi(params[1]);
|
||||||
}
|
}
|
||||||
|
else if (fastcmp(params[0], "ROUNDSPLAYED"))
|
||||||
|
{
|
||||||
|
PARAMCHECK(1);
|
||||||
|
ty = UC_ROUNDSPLAYED;
|
||||||
|
re = atoi(params[1]);
|
||||||
|
x1 = GDGT_MAX;
|
||||||
|
|
||||||
|
if (re == 0)
|
||||||
|
{
|
||||||
|
deh_warning("Rounds played requirement is %d for condition ID %d", re, id+1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params[2])
|
||||||
|
{
|
||||||
|
if (fastcmp(params[2], "RACE"))
|
||||||
|
x1 = GDGT_RACE;
|
||||||
|
else if (fastcmp(params[2], "BATTLE"))
|
||||||
|
x1 = GDGT_BATTLE;
|
||||||
|
else if (fastcmp(params[2], "CAPSULE"))
|
||||||
|
x1 = GDGT_CAPSULES;
|
||||||
|
else if (fastcmp(params[2], "SPECIAL"))
|
||||||
|
x1 = GDGT_SPECIAL;
|
||||||
|
else if (fastcmp(params[2], "CUSTOM"))
|
||||||
|
x1 = GDGT_CUSTOM;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
deh_warning("gametype requirement \"%s\" invalid for condition ID %d", params[2], id+1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (fastcmp(params[0], "TOTALRINGS"))
|
else if (fastcmp(params[0], "TOTALRINGS"))
|
||||||
{
|
{
|
||||||
PARAMCHECK(1);
|
PARAMCHECK(1);
|
||||||
|
|
|
||||||
35
src/g_game.c
35
src/g_game.c
|
|
@ -3994,8 +3994,18 @@ static void G_DoCompleted(void)
|
||||||
|
|
||||||
if (legitimateexit && !demo.playback && !mapreset) // (yes you're allowed to unlock stuff this way when the game is modified)
|
if (legitimateexit && !demo.playback && !mapreset) // (yes you're allowed to unlock stuff this way when the game is modified)
|
||||||
{
|
{
|
||||||
|
UINT8 roundtype = GDGT_CUSTOM;
|
||||||
|
|
||||||
|
if (gametype == GT_RACE)
|
||||||
|
roundtype = GDGT_RACE;
|
||||||
|
else if (gametype == GT_BATTLE)
|
||||||
|
roundtype = (battlecapsules ? GDGT_CAPSULES : GDGT_BATTLE);
|
||||||
|
else if (gametype == GT_SPECIAL || gametype == GT_VERSUS)
|
||||||
|
roundtype = GDGT_SPECIAL;
|
||||||
|
|
||||||
|
gamedata->roundsplayed[roundtype]++;
|
||||||
|
|
||||||
// Done before forced addition of PF_NOCONTEST to make UCRP_NOCONTEST harder to achieve
|
// Done before forced addition of PF_NOCONTEST to make UCRP_NOCONTEST harder to achieve
|
||||||
gamedata->matchesplayed++;
|
|
||||||
M_UpdateUnlockablesAndExtraEmblems(true);
|
M_UpdateUnlockablesAndExtraEmblems(true);
|
||||||
gamedata->deferredsave = true;
|
gamedata->deferredsave = true;
|
||||||
}
|
}
|
||||||
|
|
@ -4348,12 +4358,9 @@ void G_LoadGameData(void)
|
||||||
// to new gamedata
|
// to new gamedata
|
||||||
// see also M_EraseDataResponse
|
// see also M_EraseDataResponse
|
||||||
G_ClearRecords(); // records
|
G_ClearRecords(); // records
|
||||||
|
M_ClearStats(); // statistics
|
||||||
M_ClearSecrets(); // emblems, unlocks, maps visited, etc
|
M_ClearSecrets(); // emblems, unlocks, maps visited, etc
|
||||||
|
|
||||||
gamedata->totalplaytime = 0;
|
|
||||||
gamedata->matchesplayed = 0;
|
|
||||||
gamedata->totalrings = 0;
|
|
||||||
|
|
||||||
if (M_CheckParm("-nodata"))
|
if (M_CheckParm("-nodata"))
|
||||||
{
|
{
|
||||||
// Don't load at all.
|
// Don't load at all.
|
||||||
|
|
@ -4398,16 +4405,24 @@ void G_LoadGameData(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
gamedata->totalplaytime = READUINT32(save.p);
|
gamedata->totalplaytime = READUINT32(save.p);
|
||||||
gamedata->matchesplayed = READUINT32(save.p);
|
|
||||||
|
|
||||||
if (versionMinor > 1)
|
if (versionMinor > 1)
|
||||||
{
|
{
|
||||||
gamedata->totalrings = READUINT32(save.p);
|
gamedata->totalrings = READUINT32(save.p);
|
||||||
|
|
||||||
|
for (i = 0; i < GDGT_MAX; i++)
|
||||||
|
{
|
||||||
|
gamedata->roundsplayed[i] = READUINT32(save.p);
|
||||||
|
}
|
||||||
|
|
||||||
gamedata->crashflags = READUINT8(save.p);
|
gamedata->crashflags = READUINT8(save.p);
|
||||||
if (gamedata->crashflags & GDCRASH_LAST)
|
if (gamedata->crashflags & GDCRASH_LAST)
|
||||||
gamedata->crashflags |= GDCRASH_ANY;
|
gamedata->crashflags |= GDCRASH_ANY;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
save.p += 4; // no direct equivalent to matchesplayed
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Quick & dirty hash for what mod this save file is for.
|
// Quick & dirty hash for what mod this save file is for.
|
||||||
|
|
@ -4574,7 +4589,7 @@ void G_SaveGameData(boolean dirty)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
length = (4+1+4+4+4+1+4+(MAXEMBLEMS+(MAXUNLOCKABLES*2)+MAXCONDITIONSETS)+4+4+2);
|
length = (4+1+4+4+(4*GDGT_MAX)+1+4+(MAXEMBLEMS+(MAXUNLOCKABLES*2)+MAXCONDITIONSETS)+4+4+2);
|
||||||
if (gamedata->challengegrid)
|
if (gamedata->challengegrid)
|
||||||
{
|
{
|
||||||
length += gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT;
|
length += gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT;
|
||||||
|
|
@ -4592,9 +4607,13 @@ void G_SaveGameData(boolean dirty)
|
||||||
WRITEUINT32(save.p, GD_VERSIONCHECK); // 4
|
WRITEUINT32(save.p, GD_VERSIONCHECK); // 4
|
||||||
WRITEUINT8(save.p, GD_VERSIONMINOR); // 1
|
WRITEUINT8(save.p, GD_VERSIONMINOR); // 1
|
||||||
WRITEUINT32(save.p, gamedata->totalplaytime); // 4
|
WRITEUINT32(save.p, gamedata->totalplaytime); // 4
|
||||||
WRITEUINT32(save.p, gamedata->matchesplayed); // 4
|
|
||||||
WRITEUINT32(save.p, gamedata->totalrings); // 4
|
WRITEUINT32(save.p, gamedata->totalrings); // 4
|
||||||
|
|
||||||
|
for (i = 0; i < GDGT_MAX; i++) // 4 * GDGT_MAX
|
||||||
|
{
|
||||||
|
WRITEUINT32(save.p, gamedata->roundsplayed[i]);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
UINT8 crashflags = (gamedata->crashflags & GDCRASH_ANY);
|
UINT8 crashflags = (gamedata->crashflags & GDCRASH_ANY);
|
||||||
if (dirty)
|
if (dirty)
|
||||||
|
|
|
||||||
|
|
@ -5523,10 +5523,30 @@ void M_DrawStatistics(void)
|
||||||
sprintf(beststr, "%u", gamedata->totalrings);
|
sprintf(beststr, "%u", gamedata->totalrings);
|
||||||
}
|
}
|
||||||
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 32, V_6WIDTHSPACE, va("%s collected", beststr));
|
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 32, V_6WIDTHSPACE, va("%s collected", beststr));
|
||||||
beststr[0] = 0;
|
|
||||||
|
|
||||||
V_DrawThinString(20, 42, V_6WIDTHSPACE|V_ALLOWLOWERCASE|highlightflags, "Total Matches:");
|
beststr[0] = 0;
|
||||||
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 42, V_6WIDTHSPACE, va("%i played", gamedata->matchesplayed));
|
V_DrawThinString(20, 42, V_6WIDTHSPACE|V_ALLOWLOWERCASE|highlightflags, "Total Rounds:");
|
||||||
|
|
||||||
|
strcat(beststr, va("%u Race", gamedata->roundsplayed[GDGT_RACE]));
|
||||||
|
|
||||||
|
if (gamedata->roundsplayed[GDGT_CAPSULES] > 0)
|
||||||
|
{
|
||||||
|
strcat(beststr, va(", %u Capsule", gamedata->roundsplayed[GDGT_CAPSULES]));
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(beststr, va(", %u Battle", gamedata->roundsplayed[GDGT_BATTLE]));
|
||||||
|
|
||||||
|
if (gamedata->roundsplayed[GDGT_SPECIAL] > 0)
|
||||||
|
{
|
||||||
|
strcat(beststr, va(", %u Special", gamedata->roundsplayed[GDGT_SPECIAL]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gamedata->roundsplayed[GDGT_CUSTOM] > 0)
|
||||||
|
{
|
||||||
|
strcat(beststr, va(", %u Custom", gamedata->roundsplayed[GDGT_CUSTOM]));
|
||||||
|
}
|
||||||
|
|
||||||
|
V_DrawRightAlignedThinString(BASEVIDWIDTH-20, 42, V_6WIDTHSPACE, beststr);
|
||||||
|
|
||||||
if (!statisticsmenu.maplist)
|
if (!statisticsmenu.maplist)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
80
src/m_cond.c
80
src/m_cond.c
|
|
@ -524,6 +524,17 @@ void M_ClearConditionSet(UINT8 set)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear ALL secrets.
|
// Clear ALL secrets.
|
||||||
|
void M_ClearStats(void)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
gamedata->totalplaytime = 0;
|
||||||
|
gamedata->totalrings = 0;
|
||||||
|
for (i = 0; i < GDGT_MAX; ++i)
|
||||||
|
gamedata->roundsplayed[i] = 0;
|
||||||
|
gamedata->timesBeaten = 0;
|
||||||
|
gamedata->crashflags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void M_ClearSecrets(void)
|
void M_ClearSecrets(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
@ -544,9 +555,6 @@ void M_ClearSecrets(void)
|
||||||
gamedata->challengegrid = NULL;
|
gamedata->challengegrid = NULL;
|
||||||
gamedata->challengegridwidth = 0;
|
gamedata->challengegridwidth = 0;
|
||||||
|
|
||||||
gamedata->timesBeaten = 0;
|
|
||||||
gamedata->crashflags = 0;
|
|
||||||
|
|
||||||
// Re-unlock any always unlocked things
|
// Re-unlock any always unlocked things
|
||||||
M_UpdateUnlockablesAndExtraEmblems(false);
|
M_UpdateUnlockablesAndExtraEmblems(false);
|
||||||
}
|
}
|
||||||
|
|
@ -627,8 +635,22 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
||||||
{
|
{
|
||||||
case UC_PLAYTIME: // Requires total playing time >= x
|
case UC_PLAYTIME: // Requires total playing time >= x
|
||||||
return (gamedata->totalplaytime >= (unsigned)cn->requirement);
|
return (gamedata->totalplaytime >= (unsigned)cn->requirement);
|
||||||
case UC_MATCHESPLAYED: // Requires any level completed >= x times
|
case UC_ROUNDSPLAYED: // Requires any level completed >= x times
|
||||||
return (gamedata->matchesplayed >= (unsigned)cn->requirement);
|
{
|
||||||
|
if (cn->extrainfo1 == GDGT_MAX)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
UINT32 sum = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < GDGT_MAX; i++)
|
||||||
|
{
|
||||||
|
sum += gamedata->roundsplayed[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (sum >= (unsigned)cn->requirement);
|
||||||
|
}
|
||||||
|
return (gamedata->roundsplayed[cn->extrainfo1] >= (unsigned)cn->requirement);
|
||||||
|
}
|
||||||
case UC_TOTALRINGS: // Requires grabbing >= x rings
|
case UC_TOTALRINGS: // Requires grabbing >= x rings
|
||||||
return (gamedata->totalrings >= (unsigned)cn->requirement);
|
return (gamedata->totalrings >= (unsigned)cn->requirement);
|
||||||
case UC_POWERLEVEL: // Requires power level >= x on a certain gametype
|
case UC_POWERLEVEL: // Requires power level >= x on a certain gametype
|
||||||
|
|
@ -834,33 +856,70 @@ static const char *M_GetConditionString(condition_t *cn)
|
||||||
switch (cn->type)
|
switch (cn->type)
|
||||||
{
|
{
|
||||||
case UC_PLAYTIME: // Requires total playing time >= x
|
case UC_PLAYTIME: // Requires total playing time >= x
|
||||||
|
|
||||||
return va("Play for %i:%02i:%02i",
|
return va("Play for %i:%02i:%02i",
|
||||||
G_TicsToHours(cn->requirement),
|
G_TicsToHours(cn->requirement),
|
||||||
G_TicsToMinutes(cn->requirement, false),
|
G_TicsToMinutes(cn->requirement, false),
|
||||||
G_TicsToSeconds(cn->requirement));
|
G_TicsToSeconds(cn->requirement));
|
||||||
case UC_MATCHESPLAYED: // Requires any level completed >= x times
|
|
||||||
return va("Play %d Rounds", cn->requirement);
|
case UC_ROUNDSPLAYED: // Requires any level completed >= x times
|
||||||
|
|
||||||
|
if (cn->extrainfo1 == GDGT_MAX)
|
||||||
|
work = "";
|
||||||
|
else if (cn->extrainfo1 != GDGT_RACE
|
||||||
|
&& cn->extrainfo1 != GDGT_BATTLE
|
||||||
|
&& cn->extrainfo1 != GDGT_CUSTOM
|
||||||
|
&& gamedata->roundsplayed[cn->extrainfo1] == 0)
|
||||||
|
work = " ???";
|
||||||
|
else switch (cn->extrainfo1)
|
||||||
|
{
|
||||||
|
case GDGT_RACE:
|
||||||
|
work = " Race";
|
||||||
|
break;
|
||||||
|
case GDGT_CAPSULES:
|
||||||
|
work = " Capsule";
|
||||||
|
break;
|
||||||
|
case GDGT_BATTLE:
|
||||||
|
work = " Battle";
|
||||||
|
break;
|
||||||
|
case GDGT_SPECIAL:
|
||||||
|
work = " Special";
|
||||||
|
break;
|
||||||
|
case GDGT_CUSTOM:
|
||||||
|
work = " custom gametype";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return va("INVALID GAMETYPE CONDITION \"%d:%d:%d\"", cn->type, cn->extrainfo1, cn->requirement);
|
||||||
|
}
|
||||||
|
|
||||||
|
return va("Play %d%s Round%s", cn->requirement, work,
|
||||||
|
(cn->requirement == 1 ? "" : "s"));
|
||||||
|
|
||||||
case UC_TOTALRINGS: // Requires collecting >= x rings
|
case UC_TOTALRINGS: // Requires collecting >= x rings
|
||||||
if (cn->requirement >= 1000000)
|
if (cn->requirement >= 1000000)
|
||||||
return va("Collect %u,%u,%u Rings", (cn->requirement/1000000), (cn->requirement/1000)%1000, (cn->requirement%1000));
|
return va("Collect %u,%u,%u Rings", (cn->requirement/1000000), (cn->requirement/1000)%1000, (cn->requirement%1000));
|
||||||
if (cn->requirement >= 1000)
|
if (cn->requirement >= 1000)
|
||||||
return va("Collect %u,%u Rings", (cn->requirement/1000), (cn->requirement%1000));
|
return va("Collect %u,%u Rings", (cn->requirement/1000), (cn->requirement%1000));
|
||||||
return va("Collect %u Rings", cn->requirement);
|
return va("Collect %u Rings", cn->requirement);
|
||||||
|
|
||||||
case UC_POWERLEVEL: // Requires power level >= x on a certain gametype
|
case UC_POWERLEVEL: // Requires power level >= x on a certain gametype
|
||||||
return va("Get a PWR of %d in %s", cn->requirement,
|
return va("Get a PWR of %d in %s", cn->requirement,
|
||||||
(cn->extrainfo1 == PWRLV_RACE)
|
(cn->extrainfo1 == PWRLV_RACE)
|
||||||
? "Race"
|
? "Race"
|
||||||
: "Battle");
|
: "Battle");
|
||||||
|
|
||||||
case UC_GAMECLEAR: // Requires game beaten >= x times
|
case UC_GAMECLEAR: // Requires game beaten >= x times
|
||||||
if (cn->requirement > 1)
|
if (cn->requirement > 1)
|
||||||
return va("Beat game %d times", cn->requirement);
|
return va("Beat game %d times", cn->requirement);
|
||||||
else
|
else
|
||||||
return va("Beat the game");
|
return va("Beat the game");
|
||||||
|
|
||||||
case UC_OVERALLTIME: // Requires overall time <= x
|
case UC_OVERALLTIME: // Requires overall time <= x
|
||||||
return va("Get overall time of %i:%02i:%02i",
|
return va("Get overall time of %i:%02i:%02i",
|
||||||
G_TicsToHours(cn->requirement),
|
G_TicsToHours(cn->requirement),
|
||||||
G_TicsToMinutes(cn->requirement, false),
|
G_TicsToMinutes(cn->requirement, false),
|
||||||
G_TicsToSeconds(cn->requirement));
|
G_TicsToSeconds(cn->requirement));
|
||||||
|
|
||||||
case UC_MAPVISITED: // Requires map x to be visited
|
case UC_MAPVISITED: // Requires map x to be visited
|
||||||
case UC_MAPBEATEN: // Requires map x to be beaten
|
case UC_MAPBEATEN: // Requires map x to be beaten
|
||||||
case UC_MAPENCORE: // Requires map x to be beaten in encore
|
case UC_MAPENCORE: // Requires map x to be beaten in encore
|
||||||
|
|
@ -876,6 +935,7 @@ static const char *M_GetConditionString(condition_t *cn)
|
||||||
Z_Free(title);
|
Z_Free(title);
|
||||||
return work;
|
return work;
|
||||||
}
|
}
|
||||||
|
|
||||||
case UC_MAPTIME: // Requires time on map <= x
|
case UC_MAPTIME: // Requires time on map <= x
|
||||||
{
|
{
|
||||||
if (cn->extrainfo1 >= nummapheaders || !mapheaderinfo[cn->extrainfo1])
|
if (cn->extrainfo1 >= nummapheaders || !mapheaderinfo[cn->extrainfo1])
|
||||||
|
|
@ -890,8 +950,10 @@ static const char *M_GetConditionString(condition_t *cn)
|
||||||
Z_Free(title);
|
Z_Free(title);
|
||||||
return work;
|
return work;
|
||||||
}
|
}
|
||||||
|
|
||||||
case UC_TOTALMEDALS: // Requires number of emblems >= x
|
case UC_TOTALMEDALS: // Requires number of emblems >= x
|
||||||
return va("Get %d medals", cn->requirement);
|
return va("Get %d medals", cn->requirement);
|
||||||
|
|
||||||
case UC_EMBLEM: // Requires emblem x to be obtained
|
case UC_EMBLEM: // Requires emblem x to be obtained
|
||||||
{
|
{
|
||||||
INT32 checkLevel;
|
INT32 checkLevel;
|
||||||
|
|
@ -987,7 +1049,9 @@ static const char *M_GetConditionString(condition_t *cn)
|
||||||
case UCRP_PREFIX_BREAKTHECAPSULES:
|
case UCRP_PREFIX_BREAKTHECAPSULES:
|
||||||
return "BREAK THE CAPSULES:";
|
return "BREAK THE CAPSULES:";
|
||||||
case UCRP_PREFIX_SEALEDSTAR:
|
case UCRP_PREFIX_SEALEDSTAR:
|
||||||
return "SEALED STAR:";
|
if (gamedata->roundsplayed[GDGT_SPECIAL] == 0)
|
||||||
|
return NULL;
|
||||||
|
return "SEALED STARS:";
|
||||||
|
|
||||||
case UCRP_PREFIX_ISMAP:
|
case UCRP_PREFIX_ISMAP:
|
||||||
if (cn->requirement >= nummapheaders || !mapheaderinfo[cn->requirement])
|
if (cn->requirement >= nummapheaders || !mapheaderinfo[cn->requirement])
|
||||||
|
|
|
||||||
14
src/m_cond.h
14
src/m_cond.h
|
|
@ -29,7 +29,7 @@ extern "C" {
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
UC_PLAYTIME, // PLAYTIME [tics]
|
UC_PLAYTIME, // PLAYTIME [tics]
|
||||||
UC_MATCHESPLAYED, // SRB2Kart: MATCHESPLAYED [x played]
|
UC_ROUNDSPLAYED, // ROUNDSPLAYED [x played]
|
||||||
UC_TOTALRINGS, // TOTALRINGS [x collected]
|
UC_TOTALRINGS, // TOTALRINGS [x collected]
|
||||||
UC_POWERLEVEL, // SRB2Kart: POWERLEVEL [power level to reach] [gametype, "0" for race, "1" for battle]
|
UC_POWERLEVEL, // SRB2Kart: POWERLEVEL [power level to reach] [gametype, "0" for race, "1" for battle]
|
||||||
UC_GAMECLEAR, // GAMECLEAR <x times>
|
UC_GAMECLEAR, // GAMECLEAR <x times>
|
||||||
|
|
@ -191,6 +191,15 @@ typedef enum
|
||||||
// This is the largest number of 9s that will fit in UINT32.
|
// This is the largest number of 9s that will fit in UINT32.
|
||||||
#define GDMAX_RINGS 999999999
|
#define GDMAX_RINGS 999999999
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GDGT_RACE,
|
||||||
|
GDGT_BATTLE,
|
||||||
|
GDGT_CAPSULES,
|
||||||
|
GDGT_SPECIAL,
|
||||||
|
GDGT_CUSTOM,
|
||||||
|
GDGT_MAX
|
||||||
|
} roundsplayed_t;
|
||||||
|
|
||||||
// GAMEDATA STRUCTURE
|
// GAMEDATA STRUCTURE
|
||||||
// Everything that would get saved in gamedata.dat
|
// Everything that would get saved in gamedata.dat
|
||||||
struct gamedata_t
|
struct gamedata_t
|
||||||
|
|
@ -218,7 +227,7 @@ struct gamedata_t
|
||||||
|
|
||||||
// PLAY TIME
|
// PLAY TIME
|
||||||
UINT32 totalplaytime;
|
UINT32 totalplaytime;
|
||||||
UINT32 matchesplayed;
|
UINT32 roundsplayed[GDGT_MAX];
|
||||||
UINT32 totalrings;
|
UINT32 totalrings;
|
||||||
|
|
||||||
// Funny
|
// Funny
|
||||||
|
|
@ -267,6 +276,7 @@ void M_UpdateConditionSetsPending(void);
|
||||||
// Clearing secrets
|
// Clearing secrets
|
||||||
void M_ClearConditionSet(UINT8 set);
|
void M_ClearConditionSet(UINT8 set);
|
||||||
void M_ClearSecrets(void);
|
void M_ClearSecrets(void);
|
||||||
|
void M_ClearStats(void);
|
||||||
|
|
||||||
// Updating conditions and unlockables
|
// Updating conditions and unlockables
|
||||||
boolean M_CheckCondition(condition_t *cn, player_t *player);
|
boolean M_CheckCondition(condition_t *cn, player_t *player);
|
||||||
|
|
|
||||||
|
|
@ -6,27 +6,31 @@
|
||||||
#include "../m_cond.h" // Condition Sets
|
#include "../m_cond.h" // Condition Sets
|
||||||
#include "../f_finale.h"
|
#include "../f_finale.h"
|
||||||
|
|
||||||
|
#define EC_CHALLENGES 0x01
|
||||||
|
#define EC_STATISTICS 0x02
|
||||||
|
#define EC_TIMEATTACK 0x04
|
||||||
|
#define EC_ALLGAME (EC_CHALLENGES|EC_STATISTICS|EC_TIMEATTACK)
|
||||||
|
|
||||||
menuitem_t OPTIONS_DataErase[] =
|
menuitem_t OPTIONS_DataErase[] =
|
||||||
{
|
{
|
||||||
|
{IT_STRING | IT_CALL, "Erase Challenges Data", "Be careful! What's deleted is gone forever!",
|
||||||
|
NULL, {.routine = M_EraseData}, EC_CHALLENGES, 0},
|
||||||
|
|
||||||
|
{IT_STRING | IT_CALL, "Erase Statistics Data", "Be careful! What's deleted is gone forever!",
|
||||||
|
NULL, {.routine = M_EraseData}, EC_STATISTICS, 0},
|
||||||
|
|
||||||
{IT_STRING | IT_CALL, "Erase Time Attack Data", "Be careful! What's deleted is gone forever!",
|
{IT_STRING | IT_CALL, "Erase Time Attack Data", "Be careful! What's deleted is gone forever!",
|
||||||
NULL, {.routine = M_EraseData}, 0, 0},
|
NULL, {.routine = M_EraseData}, EC_TIMEATTACK, 0},
|
||||||
|
|
||||||
{IT_STRING | IT_CALL, "Erase Unlockable Data", "Be careful! What's deleted is gone forever!",
|
{IT_STRING | IT_CALL, "\x85\x45rase all Game Data", "Be careful! What's deleted is gone forever!",
|
||||||
NULL, {.routine = M_EraseData}, 0, 0},
|
NULL, {.routine = M_EraseData}, EC_ALLGAME, 0},
|
||||||
|
|
||||||
{IT_SPACE | IT_NOTHING, NULL, NULL,
|
{IT_SPACE | IT_NOTHING, NULL, NULL,
|
||||||
NULL, {NULL}, 0, 0},
|
NULL, {NULL}, 0, 0},
|
||||||
|
|
||||||
{IT_STRING | IT_CALL, "Erase Profile Data...", "Select a Profile to erase.",
|
{IT_STRING | IT_CALL, "Erase a Profile...", "Select a Profile to erase.",
|
||||||
NULL, {.routine = M_CheckProfileData}, 0, 0},
|
NULL, {.routine = M_CheckProfileData}, 0, 0},
|
||||||
|
|
||||||
{IT_SPACE | IT_NOTHING, NULL, NULL,
|
|
||||||
NULL, {NULL}, 0, 0},
|
|
||||||
|
|
||||||
{IT_STRING | IT_CALL, "\x85\x45rase all Data", "Be careful! What's deleted is gone forever!",
|
|
||||||
NULL, {.routine = M_EraseData}, 0, 0},
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_t OPTIONS_DataEraseDef = {
|
menu_t OPTIONS_DataEraseDef = {
|
||||||
|
|
@ -54,16 +58,12 @@ static void M_EraseDataResponse(INT32 ch)
|
||||||
|
|
||||||
// Delete the data
|
// Delete the data
|
||||||
// see also G_LoadGameData
|
// see also G_LoadGameData
|
||||||
if (optionsmenu.erasecontext == 2)
|
// We do these in backwards order to prevent things from being immediately re-unlocked.
|
||||||
{
|
if (optionsmenu.erasecontext & EC_TIMEATTACK)
|
||||||
// SRB2Kart: This actually needs to be done FIRST, so that you don't immediately regain playtime/matches secrets
|
|
||||||
gamedata->totalplaytime = 0;
|
|
||||||
gamedata->matchesplayed = 0;
|
|
||||||
gamedata->totalrings = 0;
|
|
||||||
}
|
|
||||||
if (optionsmenu.erasecontext != 1)
|
|
||||||
G_ClearRecords();
|
G_ClearRecords();
|
||||||
if (optionsmenu.erasecontext != 0)
|
if (optionsmenu.erasecontext & EC_STATISTICS)
|
||||||
|
M_ClearStats();
|
||||||
|
if (optionsmenu.erasecontext & EC_CHALLENGES)
|
||||||
M_ClearSecrets();
|
M_ClearSecrets();
|
||||||
|
|
||||||
F_StartIntro();
|
F_StartIntro();
|
||||||
|
|
@ -73,15 +73,21 @@ static void M_EraseDataResponse(INT32 ch)
|
||||||
void M_EraseData(INT32 choice)
|
void M_EraseData(INT32 choice)
|
||||||
{
|
{
|
||||||
const char *eschoice, *esstr = M_GetText("Are you sure you want to erase\n%s?\n\nPress (A) to confirm or (B) to cancel\n");
|
const char *eschoice, *esstr = M_GetText("Are you sure you want to erase\n%s?\n\nPress (A) to confirm or (B) to cancel\n");
|
||||||
|
(void)choice;
|
||||||
|
|
||||||
optionsmenu.erasecontext = (UINT8)choice;
|
optionsmenu.erasecontext = (UINT8)currentMenu->menuitems[itemOn].mvar1;
|
||||||
|
|
||||||
if (choice == 0)
|
if (optionsmenu.erasecontext == EC_CHALLENGES)
|
||||||
|
eschoice = M_GetText("Challenges data");
|
||||||
|
else if (optionsmenu.erasecontext == EC_STATISTICS)
|
||||||
|
eschoice = M_GetText("Statistics data");
|
||||||
|
else if (optionsmenu.erasecontext == EC_TIMEATTACK)
|
||||||
eschoice = M_GetText("Time Attack data");
|
eschoice = M_GetText("Time Attack data");
|
||||||
else if (choice == 1)
|
else if (optionsmenu.erasecontext == EC_ALLGAME)
|
||||||
eschoice = M_GetText("Secrets data");
|
|
||||||
else
|
|
||||||
eschoice = M_GetText("ALL game data");
|
eschoice = M_GetText("ALL game data");
|
||||||
|
else
|
||||||
|
eschoice = va("[misconfigured erasecontext %d]", optionsmenu.erasecontext);
|
||||||
|
|
||||||
|
|
||||||
M_StartMessage(va(esstr, eschoice), FUNCPTRCAST(M_EraseDataResponse), MM_YESNO);
|
M_StartMessage(va(esstr, eschoice), FUNCPTRCAST(M_EraseDataResponse), MM_YESNO);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue