From 7521e42e62f1bedb3b3da9ec119044595a0ccca0 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Wed, 3 Jan 2024 12:24:33 -0600 Subject: [PATCH] Add automedal time configs and calculation --- src/deh_soc.c | 2 +- src/deh_tables.c | 6 +++++ src/doomstat.h | 1 + src/g_game.c | 10 +++++++- src/g_game.h | 2 +- src/m_cond.c | 8 +++++++ src/m_cond.h | 6 +++++ src/p_setup.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 93 insertions(+), 3 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 2e11d2ba2..9ccee0746 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2279,7 +2279,7 @@ void reademblemdata(MYFILE *f, INT32 num) emblemlocations[num-1].type = (UINT8)value; } else if (fastcmp(word, "TAG")) - emblemlocations[num-1].tag = (INT16)value; + emblemlocations[num-1].tag = get_number(word2); else if (fastcmp(word, "MAPNAME")) { emblemlocations[num-1].level = Z_StrDup(word2); diff --git a/src/deh_tables.c b/src/deh_tables.c index 135b79456..116a69770 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -6916,6 +6916,12 @@ struct int_const_s const INT_CONST[] = { {"ME_ENCORE",ME_ENCORE}, {"ME_SPBATTACK",ME_SPBATTACK}, + // Automedal SOC tags + {"AUTOMEDAL_BRONZE",AUTOMEDAL_BRONZE}, + {"AUTOMEDAL_SILVER",AUTOMEDAL_SILVER}, + {"AUTOMEDAL_GOLD",AUTOMEDAL_GOLD}, + {"AUTOMEDAL_PLATINUM",AUTOMEDAL_PLATINUM}, + // p_local.h constants {"FLOATSPEED",FLOATSPEED}, {"MAXSTEPMOVE",MAXSTEPMOVE}, diff --git a/src/doomstat.h b/src/doomstat.h index 738a3a22e..92f4dce2d 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -483,6 +483,7 @@ struct mapheader_t UINT8 ghostCount; ///< Count of valid staff ghosts UINT32 ghostBriefSize; ///< Size of ghostBrief vector allocation staffbrief_t **ghostBrief; ///< Valid staff ghosts, pointers are owned + tic_t automedaltime[4]; ///< Auto Medal times derived from ghost times, best to worst recorddata_t records; ///< Stores completion/record attack data diff --git a/src/g_game.c b/src/g_game.c index 80d027280..dfc57ddfb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -313,7 +313,7 @@ boolean thwompsactive; // Thwomps activate on lap 2 UINT8 lastLowestLap; // Last lowest lap, for activating race lap executors SINT8 spbplace; // SPB exists, give the person behind better items boolean rainbowstartavailable; // Boolean, keeps track of if the rainbow start was gotten -tic_t linecrossed; // For Time Attack +tic_t linecrossed; // For Time Attack boolean inDuel; // Boolean, keeps track of if it is a 1v1 // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) @@ -482,8 +482,16 @@ bademblem: else stickermedalinfo.timetoreach = mapheaderinfo[map]->ghostBrief[emblem->tag-1]->time; } + else if (emblem->tag < 0 && emblem->tag >= -4) + { + // Use auto medal times for emblem tags from -4 to -1 + int index = -emblem->tag - 1; // 0 is Platinum, 3 is Bronze + stickermedalinfo.timetoreach = mapheaderinfo[map]->automedaltime[index]; + } else + { stickermedalinfo.timetoreach = emblem->var; + } } } diff --git a/src/g_game.h b/src/g_game.h index 9bf444b34..f66b665f0 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -212,7 +212,7 @@ void G_UseContinue(void); void G_AfterIntermission(void); void G_EndGame(void); // moved from y_inter.c/h and renamed -#define MAXMEDALVISIBLECOUNT 3 +#define MAXMEDALVISIBLECOUNT 4 extern struct stickermedalinfo { UINT8 visiblecount; diff --git a/src/m_cond.c b/src/m_cond.c index e170f8fe6..c37a43ea6 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -3160,6 +3160,14 @@ UINT16 M_CheckLevelEmblems(void) res = (G_GetBestTime(levelnum) <= mapheaderinfo[checkLevel]->ghostBrief[tag-1]->time); } + else if (tag < 0 && tag >= -4) + { + // Use auto medal times for emblem tags from -4 to -1 + int index = -tag - 1; // 0 is Platinum, 3 is Bronze + tic_t time = mapheaderinfo[checkLevel]->automedaltime[index]; + + res = (G_GetBestTime(levelnum) <= time); + } else { res = (G_GetBestTime(levelnum) <= (unsigned)valToReach); diff --git a/src/m_cond.h b/src/m_cond.h index 5c91a5a33..95d0ef934 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -185,6 +185,12 @@ struct conditionset_t #define ME_ENCORE 1 // Achieve in Encore #define ME_SPBATTACK 2 // Achieve in SPB Attack +// Automedal SOC tags +#define AUTOMEDAL_BRONZE -4 +#define AUTOMEDAL_SILVER -3 +#define AUTOMEDAL_GOLD -2 +#define AUTOMEDAL_PLATINUM -1 + struct emblem_t { UINT8 type; ///< Emblem type diff --git a/src/p_setup.cpp b/src/p_setup.cpp index b85bde86e..6e9e225c5 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -13,6 +13,7 @@ #include #include +#include #include @@ -492,6 +493,10 @@ static void P_ClearSingleMapHeaderInfo(INT16 num) mapheaderinfo[num]->ghostBrief = NULL; mapheaderinfo[num]->ghostCount = 0; mapheaderinfo[num]->ghostBriefSize = 0; + mapheaderinfo[num]->automedaltime[0] = 1; + mapheaderinfo[num]->automedaltime[1] = 2; + mapheaderinfo[num]->automedaltime[2] = 3; + mapheaderinfo[num]->automedaltime[3] = 4; } /** Allocates a new map-header structure. @@ -8848,6 +8853,60 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l return lumpinfo; } +static void P_DeriveAutoMedalTimes(mapheader_t& map) +{ + // Gather staff ghost times + std::vector stafftimes; + for (int i = 0; i < map.ghostCount; i++) + { + tic_t time = map.ghostBrief[i]->time; + if (time <= 0) + { + continue; + } + + stafftimes.push_back(map.ghostBrief[i]->time); + } + + if (stafftimes.empty()) + { + // Use fallback times + map.automedaltime[0] = 1; + map.automedaltime[1] = 2; + map.automedaltime[2] = 3; + map.automedaltime[3] = 4; + return; + } + + std::sort(stafftimes.begin(), stafftimes.end()); + + // Auto Platinum is the best staff ghost time + // Auto Gold is the median staff ghost time + // Silver and Bronze are 10% longer successively + + tic_t best = stafftimes.at(0); + tic_t gold = stafftimes.at(stafftimes.size() / 2); + if (gold == best) + { + gold += 1; + } + tic_t silver = static_cast(std::ceil(gold * 1.1f)); + if (silver == gold) + { + silver += 1; + } + tic_t bronze = static_cast(std::ceil(silver * 1.1f)); + if (bronze == silver) + { + bronze += 1; + } + + map.automedaltime[0] = best; + map.automedaltime[1] = gold; + map.automedaltime[2] = silver; + map.automedaltime[3] = bronze; +} + lumpnum_t wadnamelump = LUMPERROR; INT16 wadnamemap = 0; // gamemap based @@ -9024,6 +9083,8 @@ UINT8 P_InitMapData(void) } } + P_DeriveAutoMedalTimes(*mapheaderinfo[i]); + vres_Free(virtmap); } }