From 764141946db0c2080164b19058b185d57e2feabc Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 5 Oct 2023 14:23:46 +0100 Subject: [PATCH] M_GetConditionString cleanup - Remove pointless "BUILDCONDITIONTITLE" macro for M_BuildConditionTitle - Replace simple R_SkinUsable checks with M_GetConditionCharacter - Supports knowing a character's name via them being the Rival for a currently unlocked character, if that Challenge doesn't require them unlocked to interact --- src/m_cond.c | 70 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/src/m_cond.c b/src/m_cond.c index 38bebcc28..b0fb857b4 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -1274,6 +1274,54 @@ static char *M_BuildConditionTitle(UINT16 map) return title; } +static const char *M_GetConditionCharacter(INT32 skin, boolean directlyrequires) +{ + // First we check for direct unlock. + boolean permitname = R_SkinUsable(-1, skin, false); + + if (permitname == false && directlyrequires == false) + { + // If there's no direct unlock, we CAN check for if the + // character is the Rival of somebody we DO have unlocked... + + UINT8 i, j; + for (i = 0; i < numskins; i++) + { + if (i == skin) + continue; + + if (R_SkinUsable(-1, i, false) == false) + continue; + + for (j = 0; j < SKINRIVALS; j++) + { + const char *rivalname = skins[i].rivals[j]; + INT32 rivalnum = R_SkinAvailable(rivalname); + + if (rivalnum != skin) + continue; + + // We can see this character as a Rival! + break; + } + + if (j == SKINRIVALS) + continue; + + // "break" our way up the nesting... + break; + } + + // We stopped before the end, we can see it! + if (i != numskins) + permitname = true; + } + + return (permitname) + ? skins[skin].realname + : "???"; +} + static const char *M_GetNthType(UINT8 position) { if (position == 1) @@ -1294,8 +1342,6 @@ static const char *M_GetConditionString(condition_t *cn) // If this function returns NULL, it stops building the condition and just does ???'s. -#define BUILDCONDITIONTITLE(i) (M_BuildConditionTitle(i)) - switch (cn->type) { case UC_PLAYTIME: // Requires total playing time >= x @@ -1366,7 +1412,7 @@ static const char *M_GetConditionString(condition_t *cn) if (cn->requirement >= nummapheaders || !mapheaderinfo[cn->requirement]) return va("INVALID MAP CONDITION \"%d:%d\"", cn->type, cn->requirement); - title = BUILDCONDITIONTITLE(cn->requirement); + title = M_BuildConditionTitle(cn->requirement); if (cn->type == UC_MAPSPBATTACK) prefix = (M_SecretUnlocked(SECRET_SPBATTACK, true) ? "SPB ATTACK: " : "???: "); @@ -1393,7 +1439,7 @@ static const char *M_GetConditionString(condition_t *cn) if (cn->extrainfo1 >= nummapheaders || !mapheaderinfo[cn->extrainfo1]) return va("INVALID MAP CONDITION \"%d:%d:%d\"", cn->type, cn->extrainfo1, cn->requirement); - title = BUILDCONDITIONTITLE(cn->extrainfo1); + title = M_BuildConditionTitle(cn->extrainfo1); work = va("beat %s in %i:%02i.%02i", title, G_TicsToMinutes(cn->requirement, true), G_TicsToSeconds(cn->requirement), @@ -1407,9 +1453,7 @@ static const char *M_GetConditionString(condition_t *cn) { if (cn->requirement < 0 || !skins[cn->requirement].realname[0]) return va("INVALID CHAR CONDITION \"%d:%d:%d\"", cn->type, cn->requirement, cn->extrainfo1); - work = (R_SkinUsable(-1, cn->requirement, false)) - ? skins[cn->requirement].realname - : "???"; + work = M_GetConditionCharacter(cn->requirement, true); return va("win %d Round%s as %s", cn->extrainfo1, cn->extrainfo1 == 1 ? "" : "s", @@ -1465,7 +1509,7 @@ static const char *M_GetConditionString(condition_t *cn) if (checkLevel >= nummapheaders || !mapheaderinfo[checkLevel]) return va("INVALID MEDAL MAP \"%d:%d\"", cn->requirement, checkLevel); - title = BUILDCONDITIONTITLE(checkLevel); + title = M_BuildConditionTitle(checkLevel); switch (emblemlocations[i].type) { case ET_MAP: @@ -1600,7 +1644,7 @@ static const char *M_GetConditionString(condition_t *cn) if (cn->requirement >= nummapheaders || !mapheaderinfo[cn->requirement]) return va("INVALID MAP CONDITION \"%d:%d\":", cn->type, cn->requirement); - title = BUILDCONDITIONTITLE(cn->requirement); + title = M_BuildConditionTitle(cn->requirement); work = va("%s:", title); Z_Free(title); return work; @@ -1608,16 +1652,14 @@ static const char *M_GetConditionString(condition_t *cn) if (cn->requirement >= nummapheaders || !mapheaderinfo[cn->requirement]) return va("INVALID MAP CONDITION \"%d:%d\"", cn->type, cn->requirement); - title = BUILDCONDITIONTITLE(cn->requirement); + title = M_BuildConditionTitle(cn->requirement); work = va("on %s", title); Z_Free(title); return work; case UCRP_ISCHARACTER: if (cn->requirement < 0 || !skins[cn->requirement].realname[0]) return va("INVALID CHAR CONDITION \"%d:%d\"", cn->type, cn->requirement); - work = (R_SkinUsable(-1, cn->requirement, false)) - ? skins[cn->requirement].realname - : "???"; + work = M_GetConditionCharacter(cn->requirement, true); return va("as %s", work); case UCRP_ISENGINECLASS: return va("with engine class %c", 'A' + cn->requirement); @@ -1757,8 +1799,6 @@ static const char *M_GetConditionString(condition_t *cn) } // UC_MAPTRIGGER and UC_CONDITIONSET are explicitly very hard to support proper descriptions for return va("UNSUPPORTED CONDITION \"%d\"", cn->type); - -#undef BUILDCONDITIONTITLE } char *M_BuildConditionSetString(UINT16 unlockid)