diff --git a/src/deh_soc.c b/src/deh_soc.c index 1455f0641..f23c71970 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -3095,9 +3095,25 @@ void readcupheader(MYFILE *f, cupheader_t *cup) } else if (fastcmp(word, "BONUSGAME")) { - Z_Free(cup->levellist[CUPCACHE_BONUS]); - cup->levellist[CUPCACHE_BONUS] = Z_StrDup(word2); - cup->cachedlevels[CUPCACHE_BONUS] = NEXTMAP_INVALID; + while (cup->numbonus > 0) + { + 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")) { diff --git a/src/doomstat.h b/src/doomstat.h index bf9e7b17e..3338e9b76 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -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. #define MAXLEVELLIST 5 #define CUPCACHE_BONUS MAXLEVELLIST -#define CUPCACHE_SPECIAL MAXLEVELLIST+1 -#define CUPCACHE_MAX CUPCACHE_SPECIAL+1 +#define MAXBONUSLIST 2 +#define CUPCACHE_SPECIAL (CUPCACHE_BONUS+MAXBONUSLIST) +#define CUPCACHE_MAX (CUPCACHE_SPECIAL+1) typedef struct cupheader_s { @@ -354,6 +355,7 @@ typedef struct cupheader_s char *levellist[CUPCACHE_MAX]; ///< List of levels that belong to this cup INT16 cachedlevels[CUPCACHE_MAX]; ///< IDs in levellist, bonusgame, and specialstage 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) SINT8 unlockrequired; ///< An unlockable is required to select this cup. -1 for no unlocking required. struct cupheader_s *next; ///< Next cup in linked list diff --git a/src/g_game.c b/src/g_game.c index f0f53ca43..fe73d8ae6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3747,11 +3747,16 @@ static void G_GetNextMap(void) else { 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. // 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. - if (netgame || grandprixinfo.eventmode != GPEVENT_NONE) + if (netgame) + ; + else if (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? { - const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_BONUS]; + const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_BONUS + bonusindex]; if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum] && mapheaderinfo[cupLevelNum]->typeoflevel & (TOL_BOSS|TOL_BATTLE)) {