Merge branch 'double-bonus' into 'master'

Multiple BonusGame support

See merge request KartKrew/Kart!781
This commit is contained in:
Oni 2022-11-27 01:57:13 +00:00
commit e34b4f031b
3 changed files with 33 additions and 8 deletions

View file

@ -3095,9 +3095,25 @@ void readcupheader(MYFILE *f, cupheader_t *cup)
} }
else if (fastcmp(word, "BONUSGAME")) else if (fastcmp(word, "BONUSGAME"))
{ {
Z_Free(cup->levellist[CUPCACHE_BONUS]); while (cup->numbonus > 0)
cup->levellist[CUPCACHE_BONUS] = Z_StrDup(word2); {
cup->cachedlevels[CUPCACHE_BONUS] = NEXTMAP_INVALID; cup->numbonus--;
Z_Free(cup->levellist[CUPCACHE_BONUS + cup->numbonus]);
cup->levellist[CUPCACHE_BONUS + cup->numbonus] = NULL;
}
tmp = strtok(word2,",");
do {
if (cup->numbonus >= MAXBONUSLIST)
{
deh_warning("%s Cup: reached max bonus list (%d)\n", cup->name, MAXBONUSLIST);
break;
}
cup->levellist[CUPCACHE_BONUS + cup->numbonus] = Z_StrDup(tmp);
cup->cachedlevels[CUPCACHE_BONUS + cup->numbonus] = NEXTMAP_INVALID;
cup->numbonus++;
} while((tmp = strtok(NULL,",")) != NULL);
} }
else if (fastcmp(word, "SPECIALSTAGE")) else if (fastcmp(word, "SPECIALSTAGE"))
{ {

View file

@ -343,8 +343,9 @@ typedef struct
// Keep in mind that it may encourage people making overly long cups just because they "can", and would be a waste of memory. // Keep in mind that it may encourage people making overly long cups just because they "can", and would be a waste of memory.
#define MAXLEVELLIST 5 #define MAXLEVELLIST 5
#define CUPCACHE_BONUS MAXLEVELLIST #define CUPCACHE_BONUS MAXLEVELLIST
#define CUPCACHE_SPECIAL MAXLEVELLIST+1 #define MAXBONUSLIST 2
#define CUPCACHE_MAX CUPCACHE_SPECIAL+1 #define CUPCACHE_SPECIAL (CUPCACHE_BONUS+MAXBONUSLIST)
#define CUPCACHE_MAX (CUPCACHE_SPECIAL+1)
typedef struct cupheader_s typedef struct cupheader_s
{ {
@ -354,6 +355,7 @@ typedef struct cupheader_s
char *levellist[CUPCACHE_MAX]; ///< List of levels that belong to this cup char *levellist[CUPCACHE_MAX]; ///< List of levels that belong to this cup
INT16 cachedlevels[CUPCACHE_MAX]; ///< IDs in levellist, bonusgame, and specialstage INT16 cachedlevels[CUPCACHE_MAX]; ///< IDs in levellist, bonusgame, and specialstage
UINT8 numlevels; ///< Number of levels defined in levellist UINT8 numlevels; ///< Number of levels defined in levellist
UINT8 numbonus; ///< Number of bonus stages defined
UINT8 emeraldnum; ///< ID of Emerald to use for special stage (1-7 for Chaos Emeralds, 8-14 for Super Emeralds, 0 for no emerald) UINT8 emeraldnum; ///< ID of Emerald to use for special stage (1-7 for Chaos Emeralds, 8-14 for Super Emeralds, 0 for no emerald)
SINT8 unlockrequired; ///< An unlockable is required to select this cup. -1 for no unlocking required. SINT8 unlockrequired; ///< An unlockable is required to select this cup. -1 for no unlocking required.
struct cupheader_s *next; ///< Next cup in linked list struct cupheader_s *next; ///< Next cup in linked list

View file

@ -3747,11 +3747,16 @@ static void G_GetNextMap(void)
else else
{ {
INT32 lastgametype = gametype; INT32 lastgametype = gametype;
// 5 levels, 2 bonus stages: after rounds 2 and 4 (but flexible enough to accomodate other solutions)
UINT8 bonusmodulo = (grandprixinfo.cup->numlevels+1)/(grandprixinfo.cup->numbonus+1);
UINT8 bonusindex = (grandprixinfo.roundnum / bonusmodulo) - 1;
// If we're in a GP event, don't immediately follow it up with another. // If we're in a GP event, don't immediately follow it up with another.
// I also suspect this will not work with online GP so I'm gonna prevent it right now. // I also suspect this will not work with online GP so I'm gonna prevent it right now.
// The server might have to communicate eventmode (alongside other GP data) in XD_MAP later. // The server might have to communicate eventmode (alongside other GP data) in XD_MAP later.
if (netgame || grandprixinfo.eventmode != GPEVENT_NONE) if (netgame)
;
else if (grandprixinfo.eventmode != GPEVENT_NONE)
{ {
grandprixinfo.eventmode = GPEVENT_NONE; grandprixinfo.eventmode = GPEVENT_NONE;
@ -3789,11 +3794,13 @@ static void G_GetNextMap(void)
} }
} }
} }
else if (grandprixinfo.roundnum == (grandprixinfo.cup->numlevels+1)/2) // 3 for a 5-map cup else if ((grandprixinfo.cup->numbonus > 0)
&& (grandprixinfo.roundnum % bonusmodulo) == 0
&& bonusindex < MAXBONUSLIST)
{ {
// todo any other condition? // todo any other condition?
{ {
const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_BONUS]; const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_BONUS + bonusindex];
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum] if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum]
&& mapheaderinfo[cupLevelNum]->typeoflevel & (TOL_BOSS|TOL_BATTLE)) && mapheaderinfo[cupLevelNum]->typeoflevel & (TOL_BOSS|TOL_BATTLE))
{ {