From 7081ffd509cb914d739dd9f3fffc7c690fffede7 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 13 Dec 2022 22:19:37 +0000 Subject: [PATCH] Fixes and changes for Emblem system - New `flags` field - Permits coexistence of var and flags - `notMedal` boolean is now `GE_NOTMEDAL` - New `GE_TIMED` flag - Disappears `var` tics after `starttime` - Improved M_GetConditionString handling for specific Emblem grabs - More explicit error handling for invalid Emblem --- src/deh_soc.c | 4 ++-- src/deh_tables.c | 3 ++- src/info.c | 2 +- src/m_cond.c | 41 +++++++++++++++++++++++++++++++++++++++-- src/m_cond.h | 16 ++++++++-------- src/p_mobj.c | 38 +++++++++++++++++++++++++++++++------- 6 files changed, 83 insertions(+), 21 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index d66d568df..c0ebb7d9c 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2164,8 +2164,8 @@ void reademblemdata(MYFILE *f, INT32 num) emblemlocations[num-1].var = get_number(word2); } - else if (fastcmp(word, "NOTMEDAL")) - emblemlocations[num-1].notMedal = (boolean)(value != 0 || word2[0] == 'T' || word2[0] == 'Y'); + else if (fastcmp(word, "FLAGS")) + emblemlocations[num-1].flags = get_number(word2); else deh_warning("Emblem %d: unknown word '%s'", num, word); } diff --git a/src/deh_tables.c b/src/deh_tables.c index ab0ef138b..6767e81ca 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -6341,7 +6341,8 @@ struct int_const_s const INT_CONST[] = { {"SF_X2AWAYSOUND",SF_X2AWAYSOUND}, // Global emblem var flags - // none in kart yet + {"GE_NOTMEDAL", GE_NOTMEDAL}, + {"GE_TIMED", GE_TIMED}, // Map emblem var flags {"ME_ENCORE",ME_ENCORE}, diff --git a/src/info.c b/src/info.c index 3c6612ac4..6708b528a 100644 --- a/src/info.c +++ b/src/info.c @@ -7985,7 +7985,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance diff --git a/src/m_cond.c b/src/m_cond.c index d9694db8b..cf10e499b 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -655,6 +655,42 @@ static const char *M_GetConditionString(condition_t *cn) work = va("Get the %s Medal for %s", skincolors[emblemlocations[i].color].name, title); break; case ET_GLOBAL: + { + const char *astr, *colorstr, *medalstr; + + if (emblemlocations[i].flags & GE_NOTMEDAL) + { + astr = "a "; + colorstr = ""; + medalstr = "secret"; + } + else if (emblemlocations[i].color <= 0 || emblemlocations[i].color >= numskincolors) + { + Z_Free(title); + return va("INVALID MEDAL COLOR \"%d:%d:%d\"", cn->requirement, emblemlocations[i].tag, checkLevel); + } + else + { + astr = "the "; + colorstr = skincolors[emblemlocations[i].color].name; + medalstr = " Medal"; + } + + if (emblemlocations[i].flags & GE_TIMED) + { + work = va("Find %s%s%s in %s before %i:%02i.%02i", + astr, colorstr, medalstr, title, + G_TicsToMinutes(emblemlocations[i].var, true), + G_TicsToSeconds(emblemlocations[i].var), + G_TicsToCentiseconds(emblemlocations[i].var)); + } + else + { + work = va("Find %s%s%s in %s", + astr, colorstr, medalstr, title); + } + break; + } default: work = va("Find a secret in %s", title); break; @@ -941,7 +977,7 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa continue; levelnum = checkLevel; - embtype = emblemlocations[i].var; + embtype = emblemlocations[i].flags; flags = MV_BEATEN; if (embtype & ME_ENCORE) @@ -1067,7 +1103,8 @@ INT32 M_CountMedals(boolean all) INT32 found = 0, i; for (i = 0; i < numemblems; ++i) { - if (emblemlocations[i].notMedal) + if ((emblemlocations[i].type == ET_GLOBAL) + && (emblemlocations[i].flags & GE_NOTMEDAL)) continue; if (!all && !gamedata->collected[i]) continue; diff --git a/src/m_cond.h b/src/m_cond.h index 99e3492b9..045772f12 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -55,17 +55,17 @@ struct conditionset_t }; // Emblem information -#define ET_GLOBAL 0 // Emblem with a position in space -#define ET_MAP 1 // Beat the map -#define ET_TIME 2 // Get the time +#define ET_GLOBAL 0 // Emblem with a position in space +#define ET_MAP 1 // Beat the map +#define ET_TIME 2 // Get the time //#define ET_DEVTIME 3 // Time, but the value is tied to a Time Trial demo, not pre-defined // Global emblem flags -// (N/A to Kart yet) -//#define GE_OH 1 +#define GE_NOTMEDAL 1 // Doesn't count towards number of medals +#define GE_TIMED 2 // Disappears after var time // Map emblem flags -#define ME_ENCORE 1 +#define ME_ENCORE 1 // Achieve in Encore struct emblem_t { @@ -74,9 +74,9 @@ struct emblem_t char * level; ///< Level on which this emblem can be found. UINT8 sprite; ///< emblem sprite to use, 0 - 25 UINT16 color; ///< skincolor to use - INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin) + INT32 flags; ///< GE or ME constants + INT32 var; ///< If needed, specifies extra information char *stringVar; ///< String version - boolean notMedal; ///< Not a Medal? }; // Unlockable information diff --git a/src/p_mobj.c b/src/p_mobj.c index e4b5fc86d..1019bf7f7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6931,17 +6931,38 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } break; case MT_EMBLEM: + { + INT32 trans = 0; + + mobj->frame &= ~FF_TRANSMASK; + mobj->renderflags &= ~RF_TRANSMASK; + if (P_EmblemWasCollected(mobj->health - 1) || !P_CanPickupEmblem(&players[consoleplayer], mobj->health - 1)) { - mobj->frame |= (tr_trans50 << FF_TRANSSHIFT); + trans = tr_trans50; + mobj->renderflags |= (tr_trans50 << RF_TRANSSHIFT); } - else + + if (mobj->reactiontime > 0 + && leveltime > starttime) { - mobj->frame &= ~FF_TRANSMASK; + INT32 diff = mobj->reactiontime - (signed)(leveltime - starttime); + if (diff < 10) + { + if (diff <= 0) + { + P_RemoveMobj(mobj); + return false; + } + + trans = max(trans, 10-diff); + } } - if (mobj->flags2 & MF2_NIGHTSPULL) - P_NightsItemChase(mobj); + + mobj->renderflags |= (trans << RF_TRANSSHIFT); + break; + } case MT_FLOATINGITEM: { mobj->pitch = mobj->roll = 0; @@ -12008,7 +12029,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) if (!emblem) { - CONS_Debug(DBG_GAMELOGIC, "No map emblem for map %d with tag %d found!\n", gamemap, Tag_FGet(&mthing->tags)); + CONS_Alert(CONS_WARNING, "P_SetupEmblem: No map emblem for map %d with tag %d found!\n", gamemap, Tag_FGet(&mthing->tags)); return false; } @@ -12023,7 +12044,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) mobj->frame &= ~FF_TRANSMASK; - if (emblemlocations[j].type == ET_GLOBAL) + if (emblemlocations[j].flags & GE_TIMED) { mobj->reactiontime = emblemlocations[j].var; } @@ -12471,7 +12492,10 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean case MT_EMBLEM: { if (!P_SetupEmblem(mthing, mobj)) + { + P_RemoveMobj(mobj); return false; + } break; } case MT_SKYBOX: