From 99895433468452d135d66b2a7cd21bb5a474ea10 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 22 Nov 2023 00:34:39 +0000 Subject: [PATCH] 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` --- src/deh_soc.c | 80 ++++++++++++++++++++++++++++++++++++++++----- src/m_cond.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++---- src/m_cond.h | 2 ++ 3 files changed, 157 insertions(+), 14 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 86b36931b..974532c24 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2464,6 +2464,20 @@ void readunlockable(MYFILE *f, INT32 num) 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. static void conditiongetparam(char **params, UINT8 paramid, char **spos) { @@ -2690,6 +2704,63 @@ static void readcondition(UINT16 set, UINT32 id, char *word2) re = -1; 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") || (++offset && fastcmp(params[0], "ALLSUPER")) || (++offset && fastcmp(params[0], "ALLEMERALDS"))) @@ -2907,14 +2978,7 @@ static void readcondition(UINT16 set, UINT32 id, char *word2) re = -1; if (!fastcmp(params[1], "ANY")) { - cupheader_t *cup = kartcupheaders; - UINT32 hash = quickncasehash(params[1], MAXCUPNAME); - while (cup) - { - if (hash == cup->namehash && !strcmp(cup->name, params[1])) - break; - cup = cup->next; - } + cupheader_t *cup = SOChelper_cupbyname(params[1]); if (!cup) { diff --git a/src/m_cond.c b/src/m_cond.c index c3cfda79a..4928f0407 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -1388,6 +1388,39 @@ boolean M_CheckCondition(condition_t *cn, player_t *player) 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_ALLSUPER: case UC_ALLEMERALDS: @@ -2120,6 +2153,50 @@ static const char *M_GetConditionString(condition_t *cn) 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_ALLSUPER: 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 { - speedtext = " on Normal difficulty"; + speedtext = " on Normal"; } else*/ if (cn->requirement == KARTSPEED_HARD) { - speedtext = " on Hard difficulty"; + speedtext = " on Hard"; } else if (cn->requirement == KARTGP_MASTER) { if (M_SecretUnlocked(SECRET_MASTERMODE, true)) - speedtext = " on Master difficulty"; + speedtext = " on Master"; else speedtext = " on ???"; } @@ -2401,16 +2478,16 @@ static const char *M_GetConditionString(condition_t *cn) if (cn->requirement == KARTSPEED_NORMAL) { - speedtext = "on Normal difficulty"; + speedtext = "on Normal"; } else if (cn->requirement == KARTSPEED_HARD) { - speedtext = "on Hard difficulty"; + speedtext = "on Hard"; } else if (cn->requirement == KARTGP_MASTER) { if (M_SecretUnlocked(SECRET_MASTERMODE, true)) - speedtext = "on Master difficulty"; + speedtext = "on Master"; else speedtext = "on ???"; } diff --git a/src/m_cond.h b/src/m_cond.h index d7445a5aa..e79a28676 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -47,6 +47,8 @@ typedef enum UC_CHARACTERWINS, // CHARACTERWINS [character] [x rounds] + UC_ALLCUPRECORDS, // ALLCUPRECORDS [cup to complete up to] [minimum position] [minimum difficulty] + UC_ALLCHAOS, // ALLCHAOS [minimum difficulty] UC_ALLSUPER, // ALLSUPER [minimum difficulty] UC_ALLEMERALDS, // ALLEMERALDS [minimum difficulty]