diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e6c9d57b3..7b664e3e8 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2844,7 +2844,7 @@ static void Got_Mapcmd(const UINT8 **cp, INT32 playernum) && mapnumber == gamemap); if (pforcespecialstage // Forced. || (caughtretry && grandprixinfo.eventmode == GPEVENT_SPECIAL) // Catch retries of forced. - || (gametyperules & (GTR_BOSS|GTR_CATCHER))) // Conventional rules. + || (roundqueue.size == 0 && (gametyperules & (GTR_BOSS|GTR_CATCHER)))) // Force convention for the (queue)map command. { grandprixinfo.eventmode = GPEVENT_SPECIAL; diff --git a/src/g_game.c b/src/g_game.c index 74d7a2564..9645bad8e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3782,7 +3782,7 @@ void G_UpdateVisited(void) return; // Neither for tutorial skip material - if (nextmapoverride == NEXTMAP_TUTORIALCHALLENGE+1 || tutorialchallenge != TUTORIALSKIP_NONE) + if (tutorialchallenge != TUTORIALSKIP_NONE) return; // Check if every local player wiped out. @@ -3841,7 +3841,7 @@ void G_HandleSaveLevel(boolean removecondition) || roundqueue.size == 0) return; - if (roundqueue.position == 1 + if ((roundqueue.position == 1 && roundqueue.entries[0].overridden == false) || players[consoleplayer].lives <= 1) // because a life is lost on reload goto doremove; @@ -4032,14 +4032,64 @@ void G_GetNextMap(void) nextmap = (nextmapoverride-1); setalready = true; - // Roundqueue integration: Override the current entry! - if (nextmap < nummapheaders - && roundqueue.position > 0 - && roundqueue.position <= roundqueue.size) + // Tutorial Challenge behaviour + if ( + netgame == false + && gametype == GT_TUTORIAL + && nextmap == NEXTMAP_TUTORIALCHALLENGE + && ( + !gamedata + || gamedata->enteredtutorialchallenge == false + || M_GameTrulyStarted() == true + ) + ) { - UINT8 entry = roundqueue.position-1; - roundqueue.entries[entry].mapnum = nextmap; - roundqueue.entries[entry].overridden = true; + nextmap = G_MapNumber(tutorialchallengemap); + if (nextmap < nummapheaders) + { + tutorialchallenge = TUTORIALSKIP_INPROGRESS; + gamedata->enteredtutorialchallenge = true; + // A gamedata save will happen on successful level enter + + // Also set character, color, and follower from profile + + } + } + + if (nextmap < nummapheaders && mapheaderinfo[nextmap]) + { + if (tutorialchallenge == TUTORIALSKIP_INPROGRESS + || (mapheaderinfo[nextmap]->typeoflevel & G_TOLFlag(gametype)) == 0) + { + INT32 lastgametype = gametype; + INT32 newgametype = G_GuessGametypeByTOL(mapheaderinfo[nextmap]->typeoflevel); + if (newgametype == -1) + newgametype = GT_RACE; // sensible default + + G_SetGametype(newgametype); + D_GameTypeChanged(lastgametype); + } + + // Roundqueue integration: Override the current entry! + if (roundqueue.position > 0 + && roundqueue.position <= roundqueue.size) + { + UINT8 entry = roundqueue.position-1; + + if (grandprixinfo.gp) + { + K_RejiggerGPRankData( + &grandprixinfo.rank, + roundqueue.entries[entry].mapnum, + roundqueue.entries[entry].gametype, + nextmap, + gametype); + } + + roundqueue.entries[entry].mapnum = nextmap; + roundqueue.entries[entry].gametype = gametype; + roundqueue.entries[entry].overridden = true; + } } } else if (roundqueue.size > 0) @@ -4094,7 +4144,7 @@ void G_GetNextMap(void) // Handle primary queue position update. roundqueue.position++; - if (grandprixinfo.gp == false || gametype == roundqueue.entries[0].gametype) + if (grandprixinfo.gp == false || gametype == GT_RACE) // roundqueue.entries[0].gametype { roundqueue.roundnum++; } @@ -4485,30 +4535,36 @@ static void G_DoCompleted(void) { // Return to whence you came with your tail between your legs tutorialchallenge = TUTORIALSKIP_FAILED; + + INT32 lastgametype = gametype; G_SetGametype(GT_TUTORIAL); + D_GameTypeChanged(lastgametype); + nextmapoverride = prevmap+1; } else { // Proceed. + // ~toast 161123 (5 years of srb2kart, woooouuuu) nextmapoverride = NEXTMAP_TITLE+1; + tutorialchallenge = TUTORIALSKIP_NONE; - gamedata->finishedtutorialchallenge = true; + if (!gamedata->finishedtutorialchallenge) + { + gamedata->finishedtutorialchallenge = true; - M_UpdateUnlockablesAndExtraEmblems(true, true); - gamedata->deferredsave = true; + M_UpdateUnlockablesAndExtraEmblems(true, true); + gamedata->deferredsave = true; + } } } else { - // The "else" might not be strictly needed, but I don't - // want the "challenge" map to be considered visited before it's your time. - // ~toast 161123 (5 years of srb2kart, woooouuuu) - prevmap = gamemap-1; tutorialchallenge = TUTORIALSKIP_NONE; } // This can now be set. + prevmap = gamemap-1; legitimateexit = false; if (!demo.playback) @@ -4587,31 +4643,6 @@ void G_AfterIntermission(void) // void G_NextLevel(void) { - if ( - gametype == GT_TUTORIAL - && nextmap == NEXTMAP_TUTORIALCHALLENGE - && ( - !gamedata - || gamedata->enteredtutorialchallenge == false - || M_GameTrulyStarted() == true - ) - ) - { - nextmap = G_MapNumber(tutorialchallengemap); - if ( - nextmap < nummapheaders - && mapheaderinfo[nextmap] != NULL - && mapheaderinfo[nextmap]->typeoflevel != 0 - ) - { - tutorialchallenge = TUTORIALSKIP_INPROGRESS; - G_SetGametype(G_GuessGametypeByTOL(mapheaderinfo[nextmap]->typeoflevel)); - - gamedata->enteredtutorialchallenge = true; - // A gamedata save will happen on successful level enter - } - } - if (nextmap >= NEXTMAP_SPECIAL) { G_EndGame(); @@ -4836,7 +4867,7 @@ void G_DirtyGameData(void) // Can be called by the startup code or the menu task. // -#define SAV_VERSIONMINOR 4 +#define SAV_VERSIONMINOR 5 void G_LoadGame(void) { diff --git a/src/info.c b/src/info.c index 7883d74bd..d5cc66b0a 100644 --- a/src/info.c +++ b/src/info.c @@ -19476,7 +19476,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 0, // damage sfx_None, // activesound - MF_SCENERY|MF_NOCLIPTHING|MF_NOGRAVITY, // flags + MF_SCENERY|MF_NOCLIPTHING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 7ed6d593a..826a1c0f2 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -2291,6 +2291,8 @@ struct PositionFacesInfo bool near_goal() const { + if (g_pointlimit == 0) + return false; constexpr tic_t kThreshold = 5; return std::max(kThreshold, g_pointlimit) - kThreshold <= top_score(); } @@ -2405,7 +2407,7 @@ void PositionFacesInfo::draw_1p() } // Draw GOAL - UINT8 skull = g_pointlimit <= stplyr->roundscore; + bool skull = g_pointlimit && (g_pointlimit <= stplyr->roundscore); INT32 height = i*18; INT32 GOAL_Y = Y-height; @@ -2424,7 +2426,7 @@ void PositionFacesInfo::draw_1p() if (leveltime % 16 < 8) V_DrawScaledPatch(FACE_X-5, GOAL_Y-32, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_goaltext1p); } - else + else if (g_pointlimit) { using srb2::Draw; Draw(FACE_X+8.5, GOAL_Y-15) @@ -2545,7 +2547,7 @@ void PositionFacesInfo::draw_1p() colormap = NULL; - if (g_pointlimit <= players[rankplayer[i]].roundscore) + if (g_pointlimit && g_pointlimit <= players[rankplayer[i]].roundscore) { if (leveltime % 8 < 4) { @@ -2579,6 +2581,9 @@ void PositionFacesInfo::draw_4p_battle(int x, int y, INT32 flags) UINT8 skull = [] { + if (g_pointlimit == 0) + return 0; + int party = G_PartySize(consoleplayer); for (int i = 0; i < party; ++i) { @@ -2594,7 +2599,7 @@ void PositionFacesInfo::draw_4p_battle(int x, int y, INT32 flags) skincolornum_t vomit = vomit_color(); (vomit ? row.colormap(vomit) : row).patch(kp_goal[skull][1]); - if (!skull) + if (!skull && g_pointlimit) { row.xy(8.5, 5).align(Draw::Align::kCenter).text("{:02}", g_pointlimit); } @@ -2606,7 +2611,7 @@ void PositionFacesInfo::draw_4p_battle(int x, int y, INT32 flags) const player_t& p = players[rankplayer[i]]; col.colormap(p.skin, static_cast(p.skincolor)).patch(faceprefix[p.skin][FACE_MINIMAP]); - bool dance = g_pointlimit <= p.roundscore; + bool dance = g_pointlimit && (g_pointlimit <= p.roundscore); bool flash = dance && leveltime % 8 < 4; ( flash ? @@ -3486,20 +3491,21 @@ static void K_drawKartBumpersOrKarma(void) else { const UINT8 bumpers = K_Bumpers(stplyr); + const bool dance = g_pointlimit && (g_pointlimit <= stplyr->roundscore); V_DrawMappedPatch(fx-1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap); using srb2::Draw; Draw row = Draw(fx+12, fy).flags(V_HUDTRANS|V_SLIDEIN|splitflags).font(Draw::Font::kPing); row.text("{:02}", bumpers); - if (g_pointlimit <= stplyr->roundscore && leveltime % 8 < 4) + if (dance && leveltime % 8 < 4) { row = row.colorize(SKINCOLOR_TANGERINE); } row.xy(10, -2).patch(kp_pts[1]); row .x(31) - .flags(g_pointlimit <= stplyr->roundscore ? V_STRINGDANCE : 0) + .flags(dance ? V_STRINGDANCE : 0) .text("{:02}", stplyr->roundscore); } } @@ -3518,6 +3524,7 @@ static void K_drawKartBumpersOrKarma(void) else { const UINT8 bumpers = K_Bumpers(stplyr); + const bool dance = g_pointlimit && (g_pointlimit <= stplyr->roundscore); if (r_splitscreen == 0) { @@ -3530,14 +3537,14 @@ static void K_drawKartBumpersOrKarma(void) using srb2::Draw; Draw row = Draw(LAPS_X+12+23+1, fy+3).flags(V_HUDTRANS|V_SLIDEIN|splitflags).font(Draw::Font::kThinTimer); row.text("{:02}", bumpers); - if (g_pointlimit <= stplyr->roundscore && leveltime % 8 < 4) + if (dance && leveltime % 8 < 4) { row = row.colorize(SKINCOLOR_TANGERINE); } row.xy(12, -2).patch(kp_pts[0]); row .x(12+27) - .flags(g_pointlimit <= stplyr->roundscore ? V_STRINGDANCE : 0) + .flags(dance ? V_STRINGDANCE : 0) .text("{:02}", stplyr->roundscore); } } diff --git a/src/k_menudraw.c b/src/k_menudraw.c index c64e9cf25..d1a44c962 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -6927,18 +6927,38 @@ static void M_DrawChallengePreview(INT32 x, INT32 y) } case SECRET_MAP: { - const char *gtname = "INVALID HEADER"; + boolean validdraw = false; + const char *gtname = "Find your prize..."; UINT16 mapnum = M_UnlockableMapNum(ref); - K_DrawMapThumbnail( - (x-50)<= nummapheaders + || mapheaderinfo[mapnum] == NULL + || mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU) { + gtname = "INVALID HEADER"; + } + else if ( + ( // Check for visitation + (mapheaderinfo[mapnum]->menuflags & LF2_NOVISITNEEDED) + || (mapheaderinfo[mapnum]->records.mapvisited & MV_VISITED) + ) && ( // Check for completion + !(mapheaderinfo[mapnum]->menuflags & LF2_FINISHNEEDED) + || (mapheaderinfo[mapnum]->records.mapvisited & MV_BEATEN) + ) + ) + { + validdraw = true; + } + + if (validdraw) + { + K_DrawMapThumbnail( + (x-50)<typeoflevel); if (guessgt == -1) @@ -6964,6 +6984,15 @@ static void M_DrawChallengePreview(INT32 x, INT32 y) } } } + else + { + V_DrawFixedPatch( + (x-50)<lumpnum; + virtres_t *virt = NULL; + + if (lp == LUMPERROR) + { + return 0; + } + + virt = vres_GetMap(lp); + if (virt == NULL) + { + return 0; + } + virtlump_t *textmap = vres_Find(virt, "TEXTMAP"); g_rankCapsules_udmf = (textmap != NULL); g_rankCapsules_count = 0; - if (RankCapsules_LoadMapData(virt) == true) + if (RankCapsules_LoadMapData(virt) == false) { - return g_rankCapsules_count; + g_rankCapsules_count = 0; } - return 0; + vres_Free(virt); + + return g_rankCapsules_count; } /*-------------------------------------------------- @@ -332,22 +348,7 @@ void gpRank_t::Init(void) 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; - } - - totalPrisons += RankCapsules_CountFromMap(virt); - vres_Free(virt); + totalPrisons += RankCapsules_CountFromMap(cupLevelNum); } } } @@ -357,6 +358,120 @@ void K_InitGrandPrixRank(gpRank_t *rankData) rankData->Init(); } +/*-------------------------------------------------- + void K_RejiggerGPRankData(gpRank_t *rankData, UINT16 removedmap, UINT16 removedgt, UINT16 addedmap, UINT16 addedgt) + + See header file for description. +--------------------------------------------------*/ +void gpRank_t::Rejigger(UINT16 removedmap, UINT16 removedgt, UINT16 addedmap, UINT16 addedgt) +{ + INT32 i; + UINT32 deltaPoints = 0; + + if ((removedgt == GT_RACE) != (addedgt == GT_RACE)) + { + for (i = 0; i < numPlayers; i++) + { + deltaPoints += K_CalculateGPRankPoints(i + 1, totalPlayers); + } + + if (addedgt == GT_RACE) + totalPoints += deltaPoints; + else if (totalPoints > deltaPoints) + totalPoints -= deltaPoints; + else + totalPoints = 0; + } + + INT32 deltaLaps = 0; + INT32 deltaPrisons = 0; + INT32 deltaRings = 0; + + if (removedmap < nummapheaders && mapheaderinfo[removedmap] != NULL + && removedgt < numgametypes && gametypes[removedgt]) + { + if (removedgt == GT_RACE) + { + // AGH CAN'T USE, gametype already possibly not GT_RACE... + //deltaLaps -= K_RaceLapCount(removedmap); + if (cv_numlaps.value == -1) + deltaLaps -= mapheaderinfo[removedmap]->numlaps; + else + deltaLaps -= cv_numlaps.value; + } + if ((gametypes[removedgt]->rules & GTR_SPHERES) == 0) + { + deltaRings -= 20 * numPlayers; + } + if (gametypes[removedgt]->rules & GTR_PRISONS) + { + deltaPrisons -= RankCapsules_CountFromMap(removedmap); + } + } + + if (addedmap < nummapheaders && mapheaderinfo[addedmap] != NULL + && addedgt < numgametypes && gametypes[addedgt]) + { + if (addedgt == GT_RACE) + { + deltaLaps += K_RaceLapCount(addedmap); + } + if ((gametypes[addedgt]->rules & GTR_SPHERES) == 0) + { + deltaRings += 20 * numPlayers; + } + if (gametypes[addedgt]->rules & GTR_PRISONS) + { + deltaPrisons += RankCapsules_CountFromMap(addedmap); + } + } + + if (deltaLaps) + { + INT32 workingTotalLaps = totalLaps; + + // +1, since 1st place laps are worth 2 pts. + for (i = 0; i < numPlayers+1; i++) + { + workingTotalLaps += deltaLaps; + } + + if (workingTotalLaps > 0) + totalLaps = workingTotalLaps; + else + totalLaps = 0; + + deltaLaps += laps; + if (deltaLaps > 0) + laps = deltaLaps; + else + laps = 0; + } + + if (deltaPrisons) + { + deltaPrisons += totalPrisons; + if (deltaPrisons > 0) + totalPrisons = deltaPrisons; + else + totalPrisons = 0; + } + + if (deltaRings) + { + deltaRings += totalRings; + if (totalRings > 0) + totalRings = deltaRings; + else + totalRings = 0; + } +} + +void K_RejiggerGPRankData(gpRank_t *rankData, UINT16 removedmap, UINT16 removedgt, UINT16 addedmap, UINT16 addedgt) +{ + rankData->Rejigger(removedmap, removedgt, addedmap, addedgt); +} + /*-------------------------------------------------- void K_UpdateGPRank(gpRank_t *rankData) diff --git a/src/k_rank.h b/src/k_rank.h index ede1f5fa0..330c70a87 100644 --- a/src/k_rank.h +++ b/src/k_rank.h @@ -75,6 +75,7 @@ struct gpRank_t #ifdef __cplusplus void Init(void); + void Rejigger(UINT16 removedmap, UINT16 removedgt, UINT16 addedmap, UINT16 addedgt); void Update(void); #endif }; @@ -113,6 +114,26 @@ extern "C" { void K_InitGrandPrixRank(gpRank_t *rankData); +/*-------------------------------------------------- + void K_RejiggerGPRankData(gpRank_t *rankData, UINT16 removedmap, UINT16 removedgt, UINT16 addedmap, UINT16 addedgt) + + Recalculates rank requirements for overriden round. + + Input Arguments:- + rankData - Pointer to struct that contains all + of the information required to calculate GP rank. + removedmap - Level ID for round extracted + removedgt - Gametype ID for round extracted + addedmap - Level ID for round extracted + addedgt - Gametype ID for round extracted + + Return:- + N/A +--------------------------------------------------*/ + +void K_RejiggerGPRankData(gpRank_t *rankData, UINT16 removedmap, UINT16 removedgt, UINT16 addedmap, UINT16 addedgt); + + /*-------------------------------------------------- void K_UpdateGPRank(gpRank_t *rankData) diff --git a/src/menus/transient/cup-select.c b/src/menus/transient/cup-select.c index 0d7c0a474..5c80ad536 100644 --- a/src/menus/transient/cup-select.c +++ b/src/menus/transient/cup-select.c @@ -68,8 +68,9 @@ static void M_StartCup(UINT8 entry) SplitScreen_OnChange(); } - if (entry == 0) + if (entry == UINT8_MAX) { + entry = 0; memset(&grandprixinfo, 0, sizeof(struct grandprixinfo)); // read our dummy cvars @@ -116,7 +117,7 @@ static void M_StartCup(UINT8 entry) } // Skip Bonus rounds. - if (roundqueue.entries[entry].gametype != roundqueue.entries[0].gametype + if (roundqueue.entries[entry].gametype != GT_RACE // roundqueue.entries[0].gametype && roundqueue.entries[entry].rankrestricted == false) { G_GetNextMap(); // updates position in the roundqueue @@ -187,7 +188,7 @@ static void M_GPBackup(INT32 choice) return; } - M_StartCup(0); + M_StartCup(UINT8_MAX); } void M_CupSelectHandler(INT32 choice) @@ -306,7 +307,7 @@ void M_CupSelectHandler(INT32 choice) return; } - M_StartCup(0); + M_StartCup(UINT8_MAX); } else if (count == 1 && levellist.levelsearch.timeattack == true) { diff --git a/src/menus/transient/pause-replay.c b/src/menus/transient/pause-replay.c index abb0e89cf..ab30bac23 100644 --- a/src/menus/transient/pause-replay.c +++ b/src/menus/transient/pause-replay.c @@ -60,6 +60,22 @@ void M_EndModeAttackRun(void) return; } + if (nextmapoverride != 0) + { + M_StartMessage( + "Secret Exit", + va( + "No finish time was recorded.\n" + "Secrets don't work in Record modes!\n" + "Try again in %s.\n", + (gametype == GT_RACE) + ? "Grand Prix or Match Race" + : "Grand Prix" + ), + NULL, MM_NOTHING, NULL, NULL + ); + } + Command_ExitGame_f(); // Clear a bunch of state if (!modeattacking) diff --git a/src/p_saveg.c b/src/p_saveg.c index d73c20231..72b0bdf3e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -6056,6 +6056,8 @@ static inline void P_ArchiveMisc(savebuffer_t *save) UINT8 i; UINT16 mapnum; + UINT16 gtnum; + for (i = 0; i < roundqueue.size; i++) { mapnum = roundqueue.entries[i].mapnum; @@ -6067,6 +6069,18 @@ static inline void P_ArchiveMisc(savebuffer_t *save) if (roundqueue.entries[i].overridden == true) { WRITESTRINGL(save->p, mapheaderinfo[mapnum]->lumpname, MAXMAPLUMPNAME); + + gtnum = roundqueue.entries[i].gametype; + if (gtnum < numgametypes && gametypes[gtnum]) + { + WRITESTRINGL(save->p, gametypes[roundqueue.entries[i].gametype]->name, MAXGAMETYPELENGTH); + } + else + { + // Unrecoverable, so we at least try to provide a debugging hint + const char *badgtstr = va("bad GT %03d on save?", gtnum); // ~20ch vs 32 (MAXGAMETYPELENGTH as of writing) + WRITESTRINGL(save->p, badgtstr, MAXGAMETYPELENGTH); + } } else { @@ -6274,6 +6288,8 @@ static boolean P_UnArchiveSPGame(savebuffer_t *save) UINT8 i, j; UINT16 mapnum; + INT32 gtnum; + for (i = 0; i < roundqueue.size; i++) { roundqueue.entries[i].overridden = (boolean)READUINT8(save->p); @@ -6286,13 +6302,27 @@ static boolean P_UnArchiveSPGame(savebuffer_t *save) } char mapname[MAXMAPLUMPNAME]; + char gtname[MAXGAMETYPELENGTH]; READSTRINGL(save->p, mapname, MAXMAPLUMPNAME); + READSTRINGL(save->p, gtname, MAXGAMETYPELENGTH); + mapnum = G_MapNumber(mapname); if (mapnum < nummapheaders) { roundqueue.entries[i].mapnum = mapnum; + + gtnum = G_GetGametypeByName(gtname); + if (gtnum == -1) + { + CONS_Alert(CONS_ERROR, "P_UnArchiveSPGame: Cup \"%s\"'s level composition is invalid (unknown gametype \"%s\" at overridden entry %u/%u).\n", cupname, gtname, i, roundqueue.size); + return false; + } + + roundqueue.entries[i].gametype = gtnum; + + // Success, don't fall through to failure continue; } } @@ -6312,7 +6342,10 @@ static boolean P_UnArchiveSPGame(savebuffer_t *save) if (mapnum < nummapheaders && mapheaderinfo[mapnum] != NULL) { if (mapheaderinfo[mapnum]->lumpnamehash == val) + { + // Success, don't fall through to failure continue; + } } } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 13f838604..bb9639f82 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -8407,7 +8407,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) // Special stage & record attack retry fade to white // This is handled BEFORE sounds are stopped. - if (G_IsModeAttackRetrying() && !demo.playback && gametype != GT_VERSUS) + if (G_IsModeAttackRetrying() && !demo.playback && (gametyperules & GTR_BOSS) == 0) { ranspecialwipe = 2; //wipestyleflags |= (WSF_FADEOUT|WSF_TOWHITE); @@ -8485,7 +8485,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) levelfadecol = 0; wipetype = wipe_encore_towhite; } - else if (skipstats == 1) + else if (skipstats == 1 && (gametyperules & GTR_BOSS) == 0) { // MapWarp if (ranspecialwipe != 2) diff --git a/src/p_user.c b/src/p_user.c index 956bf7d37..b03547ac8 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -598,13 +598,15 @@ void P_EndingMusic(void) UINT8 bestPos = UINT8_MAX; player_t *bestPlayer = NULL; - SINT8 i; + SINT8 i = MAXPLAYERS; // See G_DoCompleted and Y_DetermineIntermissionType boolean nointer = ((modeattacking && (players[consoleplayer].pflags & PF_NOCONTEST)) || (grandprixinfo.gp == true && grandprixinfo.eventmode != GPEVENT_NONE)); - for (i = 0; i < MAXPLAYERS; i++) + if (K_CheckBossIntro()) + ; + else for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator) @@ -691,34 +693,37 @@ void P_EndingMusic(void) nointer = true; } } + else if (K_IsPlayerLosing(bestPlayer) == true) + { + jingle = "_lose"; + + if (G_GametypeUsesLives() == true) + { + // A retry will be happening + nointer = true; + } + } else { - if (K_IsPlayerLosing(bestPlayer) == true) + if (K_CheckBossIntro() == true) { - jingle = "_lose"; - - if (G_GametypeUsesLives() == true) - { - // A retry will be happening - nointer = true; - } + jingle = "VSENT"; } - else if (bestPlayer->position == 1) - { - jingle = "_first"; - } - else if (K_IsPlayerLosing(bestPlayer) == false) - { - jingle = "_win"; - } - - if (modeattacking && !K_IsPlayerLosing(bestPlayer)) + else if (modeattacking) { if (players[consoleplayer].realtime < oldbest && oldbest != (tic_t)UINT32_MAX) jingle = "newrec"; else jingle = "norec"; } + else if (bestPlayer->position == 1) + { + jingle = "_first"; + } + else + { + jingle = "_win"; + } } skippingposition: diff --git a/src/y_inter.cpp b/src/y_inter.cpp index 688afbd8c..7c8a71d94 100644 --- a/src/y_inter.cpp +++ b/src/y_inter.cpp @@ -1328,7 +1328,7 @@ void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations, else if ( roundqueue.entries[i].overridden == true || (grandprixinfo.gp == true - && roundqueue.entries[i].gametype != roundqueue.entries[0].gametype) + && roundqueue.entries[i].gametype != GT_RACE) // roundqueue.entries[0].gametype ) { if ((gametypes[roundqueue.entries[i].gametype]->rules & GTR_PRISONS) == GTR_PRISONS)