From 5a9281ecfb88d182c452ead17ad78d79cd2b26c1 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 11 Mar 2023 23:56:58 +0000 Subject: [PATCH] Three new UCRP's - UCRP_ISDIFFICULTY - Example: IsDifficulty Hard - "on Hard difficulty" - Does what it says on the tin - You can't specify Easy because there is nothing easier than Easy - Does it based on the GPsetting if in grand prix, or the level setting otherwise - UCRP_PODIUMCUP - Example: PodiumCup Ring - "complete RING CUP" - Example: PodiumCup Barrier Silver - "get Silver or better on BARRIER CUP" - Example: PodiumCup Goggles S - "get grade S on GOGGLES CUP" - Basically a monolithic cup completion handler. - Only happens after rankings begins in Podium ceremony. - UCRP_PODIUMEMERALD - Example: PodiumEmerald - "collect the Emerald" - Get the Emerald to the ceremony and this is yours. - UCRP_PODIUMPRIZE - Example: PodiumPrize - "collect the prize" - LITERALLY identical to PodiumEmerald except the string - Doing it seperately from PodiumCup means we can't check whether that cup uses an Emerald or another Catcher Prize automagically --- src/deh_soc.c | 81 ++++++++++++++++++++++++++++++++++++++ src/k_podium.c | 26 +++++++++++- src/k_podium.h | 32 +++++++++++++++ src/m_cond.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++- src/m_cond.h | 5 +++ 5 files changed, 247 insertions(+), 2 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 57ff7e6a9..e1318a429 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2597,6 +2597,87 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) } #endif } + else if (fastcmp(params[0], "ISDIFFICULTY")) + { + //PARAMCHECK(1); + ty = UCRP_ISDIFFICULTY; + re = KARTSPEED_NORMAL; + if (params[1]) + { + if (fastcmp(params[1], "NORMAL")) + ; + else if (fastcmp(params[1], "HARD")) + x1 = KARTSPEED_HARD; + else if (fastcmp(params[1], "MASTER")) + x1 = KARTGP_MASTER; + else + { + deh_warning("gamespeed requirement \"%s\" invalid for condition ID %d", params[1], id+1); + return; + } + } + } + else if (fastcmp(params[0], "PODIUMCUP")) + { + PARAMCHECK(1); + ty = UCRP_PODIUMCUP; + { + cupheader_t *cup = kartcupheaders; + while (cup) + { + if (!strcmp(cup->name, params[1])) + break; + cup = cup->next; + } + + if (!cup) + { + deh_warning("Invalid cup %s for condition ID %d", params[1], id+1); + return; + } + + re = cup->id; + } + + if (params[2]) + { + if (params[2][0] && !params[2][1]) + { + x2 = 1; + + switch (params[2][0]) + { + case 'E': { x1 = GRADE_E; break; } + case 'D': { x1 = GRADE_D; break; } + case 'C': { x1 = GRADE_C; break; } + case 'B': { x1 = GRADE_B; break; } + case 'A': { x1 = GRADE_A; break; } + case 'S': { x1 = GRADE_S; break; } + default: + deh_warning("Invalid grade %s for condition ID %d", params[2], id+1); + return; + } + } + else if ((offset=0) || fastcmp(params[2], "GOLD") + || (++offset && fastcmp(params[2], "SILVER")) + || (++offset && fastcmp(params[2], "BRONZE"))) + { + x1 = offset + 1; + } + else + { + deh_warning("Invalid cup result %s for condition ID %d", params[2], id+1); + return; + } + + } + } + else if ((offset=0) || fastcmp(params[0], "PODIUMEMERALD") + || (++offset && fastcmp(params[0], "PODIUMPRIZE"))) + { + //PARAMCHECK(1); + ty = UCRP_PODIUMEMERALD + offset; + } else if ((offset=0) || fastcmp(params[0], "FINISHCOOL") || (++offset && fastcmp(params[0], "FINISHALLCAPSULES")) || (++offset && fastcmp(params[0], "NOCONTEST"))) diff --git a/src/k_podium.c b/src/k_podium.c index 0d6b23e5b..807b7f5a4 100644 --- a/src/k_podium.c +++ b/src/k_podium.c @@ -13,7 +13,6 @@ #include "k_podium.h" #include "doomdef.h" -#include "doomstat.h" #include "d_main.h" #include "d_netcmd.h" #include "f_finale.h" @@ -69,6 +68,31 @@ boolean K_PodiumSequence(void) return (gamestate == GS_CEREMONY); } +/*-------------------------------------------------- + boolean K_PodiumRanking(void) + + See header file for description. +--------------------------------------------------*/ +boolean K_PodiumRanking(void) +{ + return (gamestate == GS_CEREMONY && podiumData.ranking == true); +} + +/*-------------------------------------------------- + boolean K_PodiumGrade(void) + + See header file for description. +--------------------------------------------------*/ +gp_rank_e K_PodiumGrade(void) +{ + if (K_PodiumSequence() == false) + { + return 0; + } + + return podiumData.grade; +} + /*-------------------------------------------------- UINT8 K_GetPodiumPosition(player_t *player) diff --git a/src/k_podium.h b/src/k_podium.h index 08357dd02..d7b04e3e4 100644 --- a/src/k_podium.h +++ b/src/k_podium.h @@ -14,6 +14,7 @@ #define __K_PODIUM__ #include "doomtype.h" +#include "doomstat.h" // gp_rank_e #include "d_event.h" #include "p_mobj.h" @@ -37,6 +38,37 @@ extern "C" { boolean K_PodiumSequence(void); +/*-------------------------------------------------- + boolean K_PodiumRanking(void); + + Returns whenver or not we are in the podium + final state. + + Input Arguments:- + N/A + + Return:- + true if we're in GS_CEREMONY, otherwise false. +--------------------------------------------------*/ + +boolean K_PodiumRanking(void); + + +/*-------------------------------------------------- + boolean K_PodiumGrade(void) + + Returns the podium grade. + + Input Arguments:- + N/A + + Return:- + gp_rank_e constant if we're in GS_CEREMONY, otherwise 0. +--------------------------------------------------*/ + +gp_rank_e K_PodiumGrade(void); + + /*-------------------------------------------------- UINT8 K_GetPodiumPosition(player_t *player); diff --git a/src/m_cond.c b/src/m_cond.c index 39b760ffa..26e43d797 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -29,6 +29,7 @@ #include "k_grandprix.h" // grandprixinfo #include "k_battle.h" // battlecapsules #include "k_specialstage.h" // specialstageinfo +#include "k_podium.h" #include "k_pwrlv.h" #include "k_profiles.h" @@ -795,6 +796,29 @@ boolean M_CheckCondition(condition_t *cn, player_t *player) return (gamemap == cn->requirement+1); case UCRP_ISCHARACTER: return (player->skin == cn->requirement); + case UCRP_ISDIFFICULTY: + if (grandprixinfo.gp == false) + return (gamespeed >= cn->requirement); + if (cn->requirement == KARTGP_MASTER) + return (grandprixinfo.masterbots == true); + return (grandprixinfo.gamespeed >= cn->requirement); + + case UCRP_PODIUMCUP: + if (K_PodiumRanking() == false) + return false; + if (grandprixinfo.cup == NULL + || grandprixinfo.cup->id != cn->requirement) + return false; + if (cn->extrainfo2) + return (K_PodiumGrade() >= (unsigned)cn->requirement); + if (cn->extrainfo1 != 0) + return (player->position != 0 + && player->position <= cn->extrainfo1); + return true; + case UCRP_PODIUMEMERALD: + case UCRP_PODIUMPRIZE: + return (K_PodiumRanking() == true + && grandprixinfo.rank.specialWon == true); case UCRP_FINISHCOOL: return (player->exiting @@ -1241,6 +1265,85 @@ static const char *M_GetConditionString(condition_t *cn) if (cn->requirement < 0 || !skins[cn->requirement].realname[0]) return va("INVALID CHAR CONDITION \"%d:%d\"", cn->type, cn->requirement); return va("as %s", skins[cn->requirement].realname); + case UCRP_ISDIFFICULTY: + { + const char *speedtext = "", *orbetter = ""; + + if (cn->requirement == KARTSPEED_NORMAL) + { + speedtext = "on Normal difficulty"; + //if (M_SecretUnlocked(SECRET_HARDSPEED, true)) + orbetter = " or better"; + } + else if (cn->requirement == KARTSPEED_HARD) + { + speedtext = "on Hard difficulty"; + if (M_SecretUnlocked(SECRET_MASTERMODE, true)) + orbetter = " or better"; + } + else if (cn->requirement == KARTGP_MASTER) + { + if (M_SecretUnlocked(SECRET_MASTERMODE, true)) + speedtext = "on Master difficulty"; + else + speedtext = "on ???"; + } + + return va("%s%s", speedtext, orbetter); + } + + case UCRP_PODIUMCUP: + { + cupheader_t *cup; + const char *completetype = "complete", *orbetter = ""; + + if (cn->extrainfo2) + { + switch (cn->requirement) + { + case GRADE_E: { completetype = "get grade E"; break; } + case GRADE_D: { completetype = "get grade D"; break; } + case GRADE_C: { completetype = "get grade C"; break; } + case GRADE_B: { completetype = "get grade B"; break; } + case GRADE_A: { completetype = "get grade A"; break; } + case GRADE_S: { completetype = "get grade S"; break; } + default: { break; } + } + + if (cn->requirement < GRADE_S) + orbetter = " or better in"; + else + orbetter = " in"; + } + else if (cn->extrainfo1 == 0) + ; + else if (cn->extrainfo1 == 1) + completetype = "get Gold in"; + else + { + if (cn->extrainfo1 == 2) + completetype = "get Silver"; + else if (cn->extrainfo1 == 3) + completetype = "get Bronze"; + orbetter = " or better in"; + } + + for (cup = kartcupheaders; cup; cup = cup->next) + { + if (cup->id != cn->requirement) + continue; + return va("%s%s %s CUP", completetype, orbetter, cup->name); + } + return va("INVALID CUP CONDITION \"%d:%d\"", cn->type, cn->requirement); + } + case UCRP_PODIUMEMERALD: + if (!gamedata->everseenspecial) + return "???"; + return "collect the Emerald"; + case UCRP_PODIUMPRIZE: + if (!gamedata->everseenspecial) + return "???"; + return "collect the prize"; case UCRP_FINISHCOOL: return "finish in good standing"; @@ -1455,7 +1558,7 @@ boolean M_UpdateUnlockablesAndExtraEmblems(boolean loud) response |= true; } - if (!demo.playback && Playing() && (gamestate == GS_LEVEL)) + if (!demo.playback && Playing() && (gamestate == GS_LEVEL || K_PodiumRanking() == true)) { for (i = 0; i <= splitscreen; i++) { diff --git a/src/m_cond.h b/src/m_cond.h index 4cbe8a678..f908cb1d0 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -73,6 +73,11 @@ typedef enum UCRP_ISMAP, // gamemap == [map] UCRP_ISCHARACTER, // character == [skin] + UCRP_ISDIFFICULTY, // difficulty >= [difficulty] + + UCRP_PODIUMCUP, // cup == [cup] [optional: >= grade OR place] + UCRP_PODIUMEMERALD, // Get to podium sequence with that cup's emerald + UCRP_PODIUMPRIZE, // Get to podium sequence with that cup's bonus (alternate string version of UCRP_PODIUMEMERALD UCRP_FINISHCOOL, // Finish in good standing UCRP_FINISHALLCAPSULES, // Break all capsules