Search bonus maps to calculate total capsules

No more moving goalpost! This means we can put it on the intermission screen and not just the final rankings screen.
This commit is contained in:
Sally Coolatta 2023-03-04 19:02:40 -05:00
parent cf20e2e831
commit 57f53a5531
2 changed files with 255 additions and 2 deletions

View file

@ -781,7 +781,6 @@ void K_BattleInit(boolean singleplayercontext)
P_SpawnMapThing(mt);
}
g_gpRank.totalCapsules += maptargets;
battlecapsules = true;
}

View file

@ -20,9 +20,240 @@
#include "k_kart.h"
#include "m_random.h"
#include "r_things.h"
#include "fastcmp.h"
#include "byteptr.h"
gpRank_t g_gpRank = {0};
// I was ALMOST tempted to start tearing apart all
// of the map loading code and turning it into C++
// and making it properly split between read-only
// and true level loading and clean up all of the
// global variable garbage it uses ... but I stopped
// myself. So here's code duplication hell instead.
static UINT32 g_rankCapsules_mapthingsPos[UINT16_MAX];
static size_t g_rankCapsules_nummapthings = 0;
static boolean g_rankCapsules_udmf = false;
static UINT32 g_rankCapsules_count = 0;
/*--------------------------------------------------
static void RankCapsules_TextmapCount(size_t size)
Counts the number of map things and records
the structure positions, for the result of
RankCapsules_CountFromMap.
Input Arguments:-
size - Length of the TEXTMAP lump.
Return:-
N/A
--------------------------------------------------*/
static UINT32 RankCapsules_TextmapCount(size_t size)
{
const char *tkn = M_TokenizerRead(0);
UINT8 brackets = 0;
g_rankCapsules_nummapthings = 0;
// Look for namespace at the beginning.
if (!fastcmp(tkn, "namespace"))
{
return false;
}
// Check if namespace is valid.
tkn = M_TokenizerRead(0);
while ((tkn = M_TokenizerRead(0)) && M_TokenizerGetEndPos() < size)
{
// Avoid anything inside bracketed stuff, only look for external keywords.
if (brackets)
{
if (fastcmp(tkn, "}"))
brackets--;
}
else if (fastcmp(tkn, "{"))
brackets++;
// Check for valid fields.
else if (fastcmp(tkn, "thing"))
g_rankCapsules_mapthingsPos[g_rankCapsules_nummapthings++] = M_TokenizerGetEndPos();
}
if (brackets)
{
return false;
}
return true;
}
/*--------------------------------------------------
static void RankCapsules_LoadTextmap(void)
Loads UDMF map data for the result of
RankCapsules_CountFromMap.
--------------------------------------------------*/
static void RankCapsules_LoadTextmap(void)
{
size_t i;
for (i = 0; i < g_rankCapsules_nummapthings; i++)
{
const char *param, *val;
M_TokenizerSetEndPos(g_rankCapsules_mapthingsPos[i]);
param = M_TokenizerRead(0);
if (!fastcmp(param, "{"))
{
continue;
}
while (true)
{
param = M_TokenizerRead(0);
if (fastcmp(param, "}"))
{
break;
}
val = M_TokenizerRead(1);
if (fastcmp(param, "type"))
{
UINT16 type = atol(val);
if (type == mobjinfo[MT_BATTLECAPSULE].doomednum)
{
g_rankCapsules_count++;
}
break;
}
}
}
}
/*--------------------------------------------------
static void RankCapsules_LoadThingsLump(UINT8 *data)
Loads binary map data for the result of
RankCapsules_CountFromMap.
Input Arguments:-
data - Pointer to a THINGS lump.
Return:-
N/A
--------------------------------------------------*/
static void RankCapsules_LoadThingsLump(UINT8 *data)
{
size_t i;
for (i = 0; i < g_rankCapsules_nummapthings; i++)
{
UINT16 type = 0;
data += 2; // x
data += 2; // y
data += 2; // angle
type = READUINT16(data); // type
type &= 4095;
data += 2; // options
if (type == mobjinfo[MT_BATTLECAPSULE].doomednum)
{
g_rankCapsules_count++;
}
}
}
/*--------------------------------------------------
static boolean RankCapsules_LoadMapData(const virtres_t *virt)
Loads either UDMF or binary map data, for the
result of RankCapsules_CountFromMap.
Input Arguments:-
virt - Pointer to the map's virtual resource.
Return:-
true if we could successfully load the map data,
otherwise false.
--------------------------------------------------*/
static boolean RankCapsules_LoadMapData(const virtres_t *virt)
{
virtlump_t *virtthings = NULL;
// Count map data.
if (g_rankCapsules_udmf) // Count how many entries for each type we got in textmap.
{
virtlump_t *textmap = vres_Find(virt, "TEXTMAP");
M_TokenizerOpen((char *)textmap->data);
if (!RankCapsules_TextmapCount(textmap->size))
{
M_TokenizerClose();
return false;
}
}
else
{
virtthings = vres_Find(virt, "THINGS");
if (!virtthings)
{
return false;
}
// Traditional doom map format just assumes the number of elements from the lump sizes.
g_rankCapsules_nummapthings = virtthings->size / (5 * sizeof (INT16));
}
// Load map data.
if (g_rankCapsules_udmf)
{
RankCapsules_LoadTextmap();
M_TokenizerClose();
}
else
{
RankCapsules_LoadThingsLump(virtthings->data);
}
return true;
}
/*--------------------------------------------------
static UINT32 RankCapsules_CountFromMap(const virtres_t *virt)
Counts the number of capsules in a map, without
needing to fully load it.
Input Arguments:-
virt - Pointer to the map's virtual resource.
Return:-
Number of MT_BATTLECAPSULE instances found.
--------------------------------------------------*/
static UINT32 RankCapsules_CountFromMap(const virtres_t *virt)
{
virtlump_t *textmap = vres_Find(virt, "TEXTMAP");
g_rankCapsules_udmf = (textmap != NULL);
g_rankCapsules_count = 0;
if (RankCapsules_LoadMapData(virt) == true)
{
return g_rankCapsules_count;
}
return 0;
}
/*--------------------------------------------------
void K_InitGrandPrixRank(gpRank_t *rankData)
@ -83,7 +314,30 @@ void K_InitGrandPrixRank(gpRank_t *rankData)
rankData->totalLaps += laps;
}
// Total capsules will need to be calculated as you enter the bonus stages...
// Search through all of the cup's bonus levels
// for an accurate count of how many capsules they have.
for (i = 0; i < grandprixinfo.cup->numbonus; i++)
{
const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_BONUS + i];
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum] != NULL)
{
lumpnum_t lp = mapheaderinfo[cupLevelNum]->lumpnum;
virtres_t *virt = NULL;
if (lp == LUMPERROR)
{
continue;
}
virt = vres_GetMap(lp);
if (virt == NULL)
{
continue;
}
rankData->totalCapsules += RankCapsules_CountFromMap(virt);
}
}
}
/*--------------------------------------------------