UC_ALLCUPRECORDS

New condition for tracking multiple cups' windata.
`Condition1 = AllCupRecords RR_Egg Bronze`
- All cups up to Egg Cup must be completed at Bronze or better
`Condition1 = AllCupRecords`
- All cups in the game must be completed
`Condition1 = AllCupRecords All Any Master`
- All cups in the game must be completed on Master mode`
This commit is contained in:
toaster 2023-11-22 00:34:39 +00:00
parent 21f152989d
commit 9989543346
3 changed files with 157 additions and 14 deletions

View file

@ -2464,6 +2464,20 @@ void readunlockable(MYFILE *f, INT32 num)
Z_Free(s); Z_Free(s);
} }
// Todo: Own func
static cupheader_t *SOChelper_cupbyname(char *name)
{
cupheader_t *cup = kartcupheaders;
UINT32 hash = quickncasehash(name, MAXCUPNAME);
while (cup)
{
if (hash == cup->namehash && !strcmp(cup->name, name))
return cup;
cup = cup->next;
}
return NULL;
}
// This is a home-grown strtok(" ") equivalent so we can isolate the first chunk without destroying the rest of the line. // This is a home-grown strtok(" ") equivalent so we can isolate the first chunk without destroying the rest of the line.
static void conditiongetparam(char **params, UINT8 paramid, char **spos) static void conditiongetparam(char **params, UINT8 paramid, char **spos)
{ {
@ -2690,6 +2704,63 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
re = -1; re = -1;
x1 = atoi(params[2]); x1 = atoi(params[2]);
} }
else if (fastcmp(params[0], "ALLCUPRECORDS"))
{
ty = UC_ALLCUPRECORDS;
re = -1;
x1 = 0;
x2 = KARTSPEED_EASY;
if (params[1])
{
if (!fastcmp(params[1], "ALL"))
{
cupheader_t *cup = SOChelper_cupbyname(params[1]);
if (!cup)
{
deh_warning("Invalid cup %s for condition ID %d", params[1], id+1);
return;
}
re = cup->id;
}
if (params[2])
{
if (!fastcmp(params[1], "ANY"))
{
if ((offset=0) || fastcmp(params[2], "GOLD")
|| (++offset && fastcmp(params[2], "SILVER"))
|| (++offset && fastcmp(params[2], "BRONZE")))
{
x1 = offset + 1;
}
else
{
deh_warning("placement requirement \"%s\" invalid for condition ID %d", params[2], id+1);
return;
}
}
if (params[3])
{
if (fastcmp(params[3], "NORMAL"))
x2 = KARTSPEED_NORMAL;
else if (fastcmp(params[3], "HARD"))
x2 = KARTSPEED_HARD;
else if (fastcmp(params[3], "MASTER"))
x2 = KARTGP_MASTER;
else
{
deh_warning("gamespeed requirement \"%s\" invalid for condition ID %d", params[3], id+1);
return;
}
}
}
}
}
else if ((offset=0) || fastcmp(params[0], "ALLCHAOS") else if ((offset=0) || fastcmp(params[0], "ALLCHAOS")
|| (++offset && fastcmp(params[0], "ALLSUPER")) || (++offset && fastcmp(params[0], "ALLSUPER"))
|| (++offset && fastcmp(params[0], "ALLEMERALDS"))) || (++offset && fastcmp(params[0], "ALLEMERALDS")))
@ -2907,14 +2978,7 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
re = -1; re = -1;
if (!fastcmp(params[1], "ANY")) if (!fastcmp(params[1], "ANY"))
{ {
cupheader_t *cup = kartcupheaders; cupheader_t *cup = SOChelper_cupbyname(params[1]);
UINT32 hash = quickncasehash(params[1], MAXCUPNAME);
while (cup)
{
if (hash == cup->namehash && !strcmp(cup->name, params[1]))
break;
cup = cup->next;
}
if (!cup) if (!cup)
{ {

View file

@ -1388,6 +1388,39 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
return (skins[cn->requirement].records.wins >= (UINT32)cn->extrainfo1); return (skins[cn->requirement].records.wins >= (UINT32)cn->extrainfo1);
case UC_ALLCUPRECORDS:
{
cupheader_t *cup;
UINT8 difficulty = cn->extrainfo2;
if (gamestate == GS_LEVEL)
return false; // this one could be laggy with many cups available
if (difficulty > KARTGP_MASTER)
difficulty = KARTGP_MASTER;
for (cup = kartcupheaders; cup; cup = cup->next)
{
// Ok, achieved up to the desired cup.
if (cn->requirement == cup->id)
return true;
cupwindata_t *windata = &cup->windata[cn->extrainfo2];
// Did you actually get it?
if (windata->best_placement == 0)
return false;
// Sufficient placement?
if (cn->extrainfo1 && windata->best_placement > cn->extrainfo1)
return false;
}
// If we ended up here, check we were looking for all cups achieved.
return (cn->requirement == -1);
}
case UC_ALLCHAOS: case UC_ALLCHAOS:
case UC_ALLSUPER: case UC_ALLSUPER:
case UC_ALLEMERALDS: case UC_ALLEMERALDS:
@ -2120,6 +2153,50 @@ static const char *M_GetConditionString(condition_t *cn)
work); work);
} }
case UC_ALLCUPRECORDS:
{
const char *completetype = "Complete", *orbetter = "", *specialtext = NULL, *speedtext = "";
if (cn->extrainfo1 == 0)
;
else if (cn->extrainfo1 == 1)
completetype = "get Gold over";
else
{
if (cn->extrainfo1 == 2)
completetype = "get Silver";
else if (cn->extrainfo1 == 3)
completetype = "get Bronze";
orbetter = " or better over";
}
if (cn->extrainfo2 == KARTSPEED_NORMAL)
{
speedtext = " on Normal";
}
else if (cn->extrainfo2 == KARTSPEED_HARD)
{
speedtext = " on Hard";
}
else if (cn->extrainfo2 == KARTGP_MASTER)
{
if (M_SecretUnlocked(SECRET_MASTERMODE, true))
speedtext = " on Master";
else
speedtext = " on ???";
}
if (cn->requirement == -1)
specialtext = "every Cup";
else if (M_CupSecondRowLocked() == true && cn->requirement+1 >= CUPMENU_COLUMNS)
specialtext = "the first ??? Cups";
if (specialtext != NULL)
return va("GRAND PRIX: %s%s %s%s", completetype, orbetter, specialtext, speedtext);
return va("GRAND PRIX: %s%s the first %d Cups%s", completetype, orbetter, cn->requirement, speedtext);
}
case UC_ALLCHAOS: case UC_ALLCHAOS:
case UC_ALLSUPER: case UC_ALLSUPER:
case UC_ALLEMERALDS: case UC_ALLEMERALDS:
@ -2138,17 +2215,17 @@ static const char *M_GetConditionString(condition_t *cn)
/*if (cn->requirement == KARTSPEED_NORMAL) -- Emeralds can not be collected on Easy /*if (cn->requirement == KARTSPEED_NORMAL) -- Emeralds can not be collected on Easy
{ {
speedtext = " on Normal difficulty"; speedtext = " on Normal";
} }
else*/ else*/
if (cn->requirement == KARTSPEED_HARD) if (cn->requirement == KARTSPEED_HARD)
{ {
speedtext = " on Hard difficulty"; speedtext = " on Hard";
} }
else if (cn->requirement == KARTGP_MASTER) else if (cn->requirement == KARTGP_MASTER)
{ {
if (M_SecretUnlocked(SECRET_MASTERMODE, true)) if (M_SecretUnlocked(SECRET_MASTERMODE, true))
speedtext = " on Master difficulty"; speedtext = " on Master";
else else
speedtext = " on ???"; speedtext = " on ???";
} }
@ -2401,16 +2478,16 @@ static const char *M_GetConditionString(condition_t *cn)
if (cn->requirement == KARTSPEED_NORMAL) if (cn->requirement == KARTSPEED_NORMAL)
{ {
speedtext = "on Normal difficulty"; speedtext = "on Normal";
} }
else if (cn->requirement == KARTSPEED_HARD) else if (cn->requirement == KARTSPEED_HARD)
{ {
speedtext = "on Hard difficulty"; speedtext = "on Hard";
} }
else if (cn->requirement == KARTGP_MASTER) else if (cn->requirement == KARTGP_MASTER)
{ {
if (M_SecretUnlocked(SECRET_MASTERMODE, true)) if (M_SecretUnlocked(SECRET_MASTERMODE, true))
speedtext = "on Master difficulty"; speedtext = "on Master";
else else
speedtext = "on ???"; speedtext = "on ???";
} }

View file

@ -47,6 +47,8 @@ typedef enum
UC_CHARACTERWINS, // CHARACTERWINS [character] [x rounds] UC_CHARACTERWINS, // CHARACTERWINS [character] [x rounds]
UC_ALLCUPRECORDS, // ALLCUPRECORDS [cup to complete up to] [minimum position] [minimum difficulty]
UC_ALLCHAOS, // ALLCHAOS [minimum difficulty] UC_ALLCHAOS, // ALLCHAOS [minimum difficulty]
UC_ALLSUPER, // ALLSUPER [minimum difficulty] UC_ALLSUPER, // ALLSUPER [minimum difficulty]
UC_ALLEMERALDS, // ALLEMERALDS [minimum difficulty] UC_ALLEMERALDS, // ALLEMERALDS [minimum difficulty]