Add automedal time configs and calculation

This commit is contained in:
Eidolon 2024-01-03 12:24:33 -06:00
parent e2cbf06fa7
commit 7521e42e62
8 changed files with 93 additions and 3 deletions

View file

@ -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);

View file

@ -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},

View file

@ -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

View file

@ -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;
}
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -13,6 +13,7 @@
#include <algorithm>
#include <string>
#include <vector>
#include <fmt/format.h>
@ -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<tic_t> 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<tic_t>(std::ceil(gold * 1.1f));
if (silver == gold)
{
silver += 1;
}
tic_t bronze = static_cast<tic_t>(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);
}
}