diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f938c0119..6b9c0e043 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2572,15 +2572,19 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r if ((netgame || multiplayer) && !((gametype == newgametype) && (gametypedefaultrules[newgametype] & GTR_CAMPAIGN))) FLS = false; - if (grandprixinfo.gp == true) - { - // Too lazy to change the input value for every instance of this function....... - pencoremode = grandprixinfo.encore; - } - else if (bossinfo.boss == true) + // Too lazy to change the input value for every instance of this function....... + if (bossinfo.boss == true) { pencoremode = bossinfo.encore; } + else if (specialStage.active == true) + { + pencoremode = specialStage.encore; + } + else if (grandprixinfo.gp == true) + { + pencoremode = grandprixinfo.encore; + } if (delay != 2) { @@ -4946,6 +4950,8 @@ Lagless_OnChange (void) } UINT32 timelimitintics = 0; +UINT32 extratimeintics = 0; +UINT32 secretextratime = 0; /** Deals with a timelimit change by printing the change to the console. * If the gametype is single player, cooperative, or race, the timelimit is @@ -5752,6 +5758,10 @@ void Command_Retry_f(void) { CONS_Printf(M_GetText("This only works in singleplayer games.\n")); } + else if (grandprixinfo.gp == true && grandprixinfo.eventmode != GPEVENT_NONE) + { + CONS_Printf(M_GetText("You can't retry right now!\n")); + } else { M_ClearMenus(true); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index d6aa7fa5b..266d73395 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -55,7 +55,7 @@ extern consvar_t cv_itemrespawn; extern consvar_t cv_pointlimit; extern consvar_t cv_timelimit; extern consvar_t cv_numlaps; -extern UINT32 timelimitintics; +extern UINT32 timelimitintics, extratimeintics, secretextratime; extern consvar_t cv_allowexitlevel; extern consvar_t cv_autobalance; diff --git a/src/g_game.c b/src/g_game.c index d8a245ae5..ffca15ce6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -58,6 +58,7 @@ #include "k_respawn.h" #include "k_grandprix.h" #include "k_boss.h" +#include "k_specialstage.h" #include "k_bot.h" #include "doomstat.h" @@ -2297,6 +2298,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) botdiffincrease = players[player].botvars.diffincrease; botrival = players[player].botvars.rival; + totalring = players[player].totalring; + xtralife = players[player].xtralife; + pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE)); // SRB2kart @@ -2315,13 +2319,11 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) nocontrol = 0; laps = 0; latestlap = 0; - totalring = 0; roundscore = 0; exiting = 0; khudfinish = 0; khudcardanimation = 0; starpostnum = 0; - xtralife = 0; follower = NULL; } @@ -2358,7 +2360,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) laps = players[player].laps; latestlap = players[player].latestlap; - totalring = players[player].totalring; roundscore = players[player].roundscore; exiting = players[player].exiting; @@ -2375,8 +2376,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) starpostnum = players[player].starpostnum; - xtralife = players[player].xtralife; - follower = players[player].follower; pflags |= (players[player].pflags & (PF_STASIS|PF_ELIMINATED|PF_NOCONTEST|PF_FAULT|PF_LOSTLIFE)); @@ -2919,7 +2918,7 @@ void G_ExitLevel(void) } } } - else if (grandprixinfo.gp == true) + else if (grandprixinfo.gp == true && grandprixinfo.eventmode == GPEVENT_NONE) { youlost = (grandprixinfo.wonround != true); } @@ -3233,14 +3232,14 @@ boolean G_GametypeUsesLives(void) if (modeattacking || metalrecording) // NOT in Record Attack return false; - if (bossinfo.boss == true) // Fighting a boss? + if ((grandprixinfo.gp == true) // In Grand Prix + && (gametype == GT_RACE) // NOT in bonus round + && grandprixinfo.eventmode == GPEVENT_NONE) // NOT in bonus { return true; } - if ((grandprixinfo.gp == true) // In Grand Prix - && (gametype == GT_RACE) // NOT in bonus round - && !G_IsSpecialStage(gamemap)) // NOT in special stage + if (bossinfo.boss == true) // Fighting a boss? { return true; } @@ -3723,14 +3722,94 @@ static void G_GetNextMap(void) } else { - if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels) // On final map + INT32 lastgametype = gametype; + + // 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) + { + grandprixinfo.eventmode = GPEVENT_NONE; + + G_SetGametype(GT_RACE); + if (gametype != lastgametype) + D_GameTypeChanged(lastgametype); + + specialStage.active = false; + bossinfo.boss = false; + } + // Special stage + else if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels) + { + INT16 totaltotalring = 0; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (players[i].spectator) + continue; + if (players[i].bot) + continue; + totaltotalring += players[i].totalring; + } + + if (totaltotalring >= 50) + { + const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_SPECIAL]; + if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum] + && mapheaderinfo[cupLevelNum]->typeoflevel & (TOL_SPECIAL|TOL_BOSS|TOL_BATTLE)) + { + grandprixinfo.eventmode = GPEVENT_SPECIAL; + nextmap = cupLevelNum; + } + } + } + else if (grandprixinfo.roundnum == (grandprixinfo.cup->numlevels+1)/2) // 3 for a 5-map cup + { + // todo any other condition? + { + const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_BONUS]; + if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum] + && mapheaderinfo[cupLevelNum]->typeoflevel & (TOL_BOSS|TOL_BATTLE)) + { + grandprixinfo.eventmode = GPEVENT_BONUS; + nextmap = cupLevelNum; + } + } + } + + if (grandprixinfo.eventmode != GPEVENT_NONE) + { + // nextmap is set above + const INT32 newtol = mapheaderinfo[nextmap]->typeoflevel; + + if (newtol & TOL_SPECIAL) + { + specialStage.active = true; + specialStage.encore = grandprixinfo.encore; + } + else //(if newtol & (TOL_BATTLE|TOL_BOSS)) -- safe to assume?? + { + G_SetGametype(GT_BATTLE); + if (gametype != lastgametype) + D_GameTypeChanged(lastgametype); + if (newtol & TOL_BOSS) + { + K_ResetBossInfo(); + bossinfo.boss = true; + bossinfo.encore = grandprixinfo.encore; + } + } + } + else if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels) // On final map { nextmap = NEXTMAP_CEREMONY; // ceremonymap } else { // Proceed to next map - const INT32 cupLevelNum =grandprixinfo.cup->cachedlevels[grandprixinfo.roundnum]; + const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[grandprixinfo.roundnum]; if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum]) { diff --git a/src/k_battle.c b/src/k_battle.c index 1a4680842..cb27d9a41 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -182,7 +182,13 @@ void K_CheckBumpers(void) K_KartUpdatePosition(&players[i]); for (i = 0; i < MAXPLAYERS; i++) // and it can't be merged with this loop because it needs to be all updated before exiting... multi-loops suck... + { + if (!playeringame[i]) + continue; + if (players[i].spectator) + continue; P_DoPlayerExit(&players[i]); + } } void K_CheckEmeralds(player_t *player) diff --git a/src/k_bot.c b/src/k_bot.c index 1b5a183b0..895fefdbe 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -1261,18 +1261,12 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) INT32 turnamt = 0; line_t *botController = NULL; - // Can't build a ticcmd if we aren't spawned... - if (!player->mo) - { - return; - } - // Remove any existing controls memset(cmd, 0, sizeof(ticcmd_t)); - if (gamestate != GS_LEVEL) + if (gamestate != GS_LEVEL || !player->mo || player->spectator) { - // Not in a level. + // Not in the level. return; } diff --git a/src/k_grandprix.c b/src/k_grandprix.c index 0fe0e557f..af4e33e68 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -332,6 +332,16 @@ void K_UpdateGrandPrixBots(void) UINT16 newrivalscore = 0; UINT8 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || !players[i].bot) + { + continue; + } + + players[i].spectator = (grandprixinfo.eventmode != GPEVENT_NONE); + } + // Find the rival. for (i = 0; i < MAXPLAYERS; i++) { @@ -518,9 +528,11 @@ void K_RetireBots(void) UINT8 i; - if (grandprixinfo.gp == true && grandprixinfo.roundnum >= grandprixinfo.cup->numlevels) + if (grandprixinfo.gp == true + && ((grandprixinfo.roundnum >= grandprixinfo.cup->numlevels) + || grandprixinfo.eventmode != GPEVENT_NONE)) { - // Was last map, no replacement. + // No replacement. return; } @@ -576,18 +588,13 @@ void K_RetireBots(void) { player_t *bot = NULL; - if (!playeringame[i] || !players[i].bot) + if (!playeringame[i] || !players[i].bot || players[i].spectator) { continue; } bot = &players[i]; - if (bot->spectator) - { - continue; - } - if (bot->pflags & PF_NOCONTEST) { UINT8 skinnum = defaultbotskin; diff --git a/src/k_grandprix.h b/src/k_grandprix.h index 64085fa00..cc8527508 100644 --- a/src/k_grandprix.h +++ b/src/k_grandprix.h @@ -16,6 +16,10 @@ #include "doomdef.h" #include "doomstat.h" +#define GPEVENT_NONE 0 +#define GPEVENT_BONUS 1 +#define GPEVENT_SPECIAL 2 + extern struct grandprixinfo { boolean gp; ///< If true, then we are in a Grand Prix. @@ -26,6 +30,7 @@ extern struct grandprixinfo boolean masterbots; ///< If true, all bots should be max difficulty (Master Mode) boolean initalize; ///< If true, we need to initialize a new session. boolean wonround; ///< If false, then we retry the map instead of going to the next. + UINT8 eventmode; ///< See GPEVENT_ constants } grandprixinfo; diff --git a/src/k_hud.c b/src/k_hud.c index 7329d8398..ff319b89b 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -12,6 +12,7 @@ #include "k_hud.h" #include "k_kart.h" #include "k_battle.h" +#include "k_grandprix.h" #include "k_boss.h" #include "k_color.h" #include "k_director.h" @@ -1406,7 +1407,15 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI else { drawtime = timelimitintics - drawtime; - if (drawtime < 5*TICRATE) + if (secretextratime) + ; + else if (extratimeintics) + { + jitter = 2; + if (leveltime & 1) + jitter = -jitter; + } + else if (drawtime < 5*TICRATE) { jitter = 1; if (drawtime & 2) @@ -3904,7 +3913,7 @@ static void K_drawBattleFullscreen(void) if (K_IsPlayerLosing(stplyr)) p = kp_battlelose; - else if (stplyr->position == 1) + else if (stplyr->position == 1 && (!battlecapsules || numtargets >= maptargets)) p = kp_battlewin; V_DrawFixedPatch(x<spectator) // FREE PLAY? + // FREE PLAY? { UINT8 i; @@ -3961,11 +3970,11 @@ static void K_drawBattleFullscreen(void) { if (i == displayplayers[0]) continue; - if (playeringame[i] && !stplyr->spectator) - return; + if (playeringame[i] && !players[i].spectator) + break; } - if (LUA_HudEnabled(hud_freeplay)) + if (i != MAXPLAYERS) K_drawKartFreePlay(); } } @@ -4359,8 +4368,13 @@ static void K_drawTrickCool(void) void K_drawKartFreePlay(void) { - // no splitscreen support because it's not FREE PLAY if you have more than one player in-game - // (you fool, you can take splitscreen online. :V) + // Doesn't support splitscreens higher than 2 for real estate reasons. + + if (!LUA_HudEnabled(hud_freeplay)) + return; + + if (modeattacking || grandprixinfo.gp || bossinfo.boss || stplyr->spectator) + return; if (lt_exitticker < TICRATE/2) return; @@ -4369,7 +4383,7 @@ void K_drawKartFreePlay(void) return; V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - 72, // mirror the laps thingy - LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, "FREE PLAY"); + LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN, "FREE PLAY"); } static void @@ -4733,11 +4747,8 @@ void K_drawKartHUD(void) V_DrawScaledPatch(BASEVIDWIDTH/2 - (SHORT(kp_yougotem->width)/2), 32, V_HUDTRANS, kp_yougotem); // Draw FREE PLAY. - if (islonesome && !modeattacking && !bossinfo.boss && !stplyr->spectator) - { - if (LUA_HudEnabled(hud_freeplay)) - K_drawKartFreePlay(); - } + if (islonesome) + K_drawKartFreePlay(); if (r_splitscreen == 0 && (stplyr->pflags & PF_WRONGWAY) && ((leveltime / 8) & 1)) { diff --git a/src/k_kart.c b/src/k_kart.c index 7616ee3c6..3957fa72e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -40,6 +40,7 @@ #include "k_collide.h" #include "k_follower.h" #include "k_objects.h" +#include "k_grandprix.h" #include "k_specialstage.h" // SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H: @@ -158,6 +159,29 @@ void K_TimerInit(void) // NOW you can try to spawn in the Battle capsules, if there's not enough players for a match K_BattleInit(); + timelimitintics = extratimeintics = secretextratime = 0; + if ((gametyperules & GTR_TIMELIMIT) && !bossinfo.boss) + { + if (!K_CanChangeRules()) + { + if (grandprixinfo.gp) + { + timelimitintics = (20*TICRATE); + } + else + { + timelimitintics = timelimits[gametype] * (60*TICRATE); + } + } + else +#ifndef TESTOVERTIMEINFREEPLAY + if (!battlecapsules) +#endif + { + timelimitintics = cv_timelimit.value * (60*TICRATE); + } + } + if (inDuel == true) { K_SpawnDuelOnlyItems(); @@ -331,10 +355,10 @@ boolean K_IsPlayerLosing(player_t *player) INT32 winningpos = 1; UINT8 i, pcount = 0; - if (battlecapsules && player->bumpers <= 0) - return true; // DNF in break the capsules + if (battlecapsules && numtargets == 0) + return true; // Didn't even TRY? - if (bossinfo.boss) + if (battlecapsules || bossinfo.boss) return (player->bumpers <= 0); // anything short of DNF is COOL if (player->position == 1) diff --git a/src/p_enemy.c b/src/p_enemy.c index 827e42c8e..14e17e558 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4032,9 +4032,10 @@ void A_AttractChase(mobj_t *actor) if ( actor->tracer->player && actor->tracer->health - && actor->tracer->player->itemtype == KITEM_LIGHTNINGSHIELD - && RINGTOTAL(actor->tracer->player) < 20 - && !(actor->tracer->player->pflags & PF_RINGLOCK) + && (gametyperules & GTR_SPHERES) + || (actor->tracer->player->itemtype == KITEM_LIGHTNINGSHIELD + && RINGTOTAL(actor->tracer->player) < 20 + && !(actor->tracer->player->pflags & PF_RINGLOCK)) //&& P_CheckSight(actor, actor->tracer) ) { diff --git a/src/p_inter.c b/src/p_inter.c index 838cdd25f..9d0c5de68 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -603,19 +603,37 @@ void P_CheckTimeLimit(void) { INT32 i; + if (exitcountdown) + return; + if (!timelimitintics) return; -#ifndef TESTOVERTIMEINFREEPLAY - if (battlecapsules && (grandprixinfo.gp == false)) - return; -#endif - - if (!(gametyperules & GTR_TIMELIMIT)) - return; - - if (bossinfo.boss == true) - return; + if (secretextratime) + { + secretextratime--; + timelimitintics++; + } + else if (extratimeintics) + { + timelimitintics++; + if (leveltime & 1) + ; + else + { + if (extratimeintics > 20) + { + extratimeintics -= 20; + timelimitintics += 20; + } + else + { + timelimitintics += extratimeintics; + extratimeintics = 0; + } + S_StartSound(NULL, sfx_ptally); + } + } if (leveltime < (timelimitintics + starttime)) return; @@ -705,16 +723,19 @@ void P_CheckPointLimit(void) { INT32 i; - if (!cv_pointlimit.value) + if (exitcountdown) return; - if (!(multiplayer || netgame)) + if (!K_CanChangeRules()) + return; + + if (!cv_pointlimit.value) return; if (!(gametyperules & GTR_POINTLIMIT)) return; - if (bossinfo.boss == true) + if (battlecapsules) return; // pointlimit is nonzero, check if it's been reached by this player @@ -1422,19 +1443,21 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget case MT_BATTLECAPSULE: { + UINT8 i; mobj_t *cur; + angle_t dir = 0; - numtargets++; target->fuse = 16; target->flags |= MF_NOCLIP|MF_NOCLIPTHING; if (inflictor) { - P_Thrust(target, - R_PointToAngle2(inflictor->x, inflictor->y, target->x, target->y), - P_AproxDistance(inflictor->momx, inflictor->momy) / 12 - ); + dir = R_PointToAngle2(inflictor->x, inflictor->y, target->x, target->y); + P_Thrust(target, dir, P_AproxDistance(inflictor->momx, inflictor->momy)/12); } + else if (source) + dir = R_PointToAngle2(source->x, source->y, target->x, target->y); + target->momz += 8 * target->scale * P_MobjFlip(target); target->flags &= ~MF_NOGRAVITY; @@ -1467,12 +1490,47 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget S_StartSound(target, sfx_mbs60); - // All targets busted! - if (numtargets >= maptargets) + if ((gametyperules & GTR_POINTLIMIT) && (source && source->player)) { - UINT8 i; + /*mobj_t * ring; + for (i = 0; i < 2; i++) + { + dir += (ANGLE_MAX/3); + ring = P_SpawnMobj(target->x, target->y, target->z, MT_RING); + ring->angle = dir; + P_InstaThrust(ring, dir, 16*ring->scale); + ring->momz = 8 * target->scale * P_MobjFlip(target); + P_SetTarget(&ring->tracer, source); + source->player->pickuprings++; + }*/ + + P_AddPlayerScore(source->player, 1); + K_SpawnBattlePoints(source->player, NULL, 1); + } + + // All targets busted! + if (++numtargets >= maptargets) + { + boolean givelife = false; for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; P_DoPlayerExit(&players[i]); + if (!grandprixinfo.gp) + continue; + P_GivePlayerLives(&players[i], 1); + givelife = true; + } + + if (givelife) + S_StartSound(NULL, sfx_cdfm73); + } + else if (timelimitintics) + { + S_StartSound(NULL, sfx_s221); + extratimeintics += 10*TICRATE; + secretextratime = TICRATE/2; } } break; diff --git a/src/p_saveg.c b/src/p_saveg.c index 3f3828051..db3d38f28 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4596,6 +4596,10 @@ static void P_NetArchiveMisc(boolean resending) WRITEUINT32(save_p, starttime); WRITEUINT8(save_p, numbulbs); + WRITEUINT32(save_p, timelimitintics); + WRITEUINT32(save_p, extratimeintics); + WRITEUINT32(save_p, secretextratime); + // Is it paused? if (paused) WRITEUINT8(save_p, 0x2f); diff --git a/src/p_setup.c b/src/p_setup.c index a8c35596f..fd80fec57 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3565,7 +3565,7 @@ static void P_InitLevelSettings(void) // SRB2Kart: map load variables if (grandprixinfo.gp == true) { - if (gametype == GT_BATTLE) + if ((gametyperules & GTR_BUMPERS)) { gamespeed = KARTSPEED_EASY; } @@ -3584,7 +3584,10 @@ static void P_InitLevelSettings(void) else if (modeattacking) { // Just play it safe and set everything - gamespeed = KARTSPEED_HARD; + if ((gametyperules & GTR_BUMPERS)) + gamespeed = KARTSPEED_EASY; + else + gamespeed = KARTSPEED_HARD; franticitems = false; } else @@ -3843,7 +3846,6 @@ static void P_InitPlayers(void) static void P_InitGametype(void) { size_t i; - boolean canchangerules = K_CanChangeRules(); spectateGriefed = 0; K_CashInPowerLevels(); // Pushes power level changes even if intermission was skipped @@ -3855,7 +3857,7 @@ static void P_InitGametype(void) if (gametyperules & GTR_CIRCUIT) { - if (canchangerules && cv_numlaps.value + if (K_CanChangeRules() && cv_numlaps.value && (!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) || (mapheaderinfo[gamemap - 1]->numlaps > cv_numlaps.value))) { @@ -3875,22 +3877,6 @@ static void P_InitGametype(void) numlaps = 0; } - if ((gametyperules & GTR_TIMELIMIT) && !bossinfo.boss) - { - if (!canchangerules) - { - timelimitintics = timelimits[gametype] * (60*TICRATE); - } - else - { - timelimitintics = cv_timelimit.value * (60*TICRATE); - } - } - else - { - timelimitintics = 0; - } - wantedcalcdelay = wantedfrequency*2; for (i = 0; i < NUMKARTITEMS-1; i++) diff --git a/src/p_user.c b/src/p_user.c index 418ac6543..af117a685 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -505,7 +505,6 @@ INT32 P_GivePlayerRings(player_t *player, INT32 num_rings) num_rings -= (test+20); player->rings += num_rings; - //player->totalring += num_rings; // Used for GP lives later -- maybe you might want to move this earlier to discourage ring debt... return num_rings; } @@ -1263,75 +1262,78 @@ void P_DoPlayerExit(player_t *player) player->exiting = 1; - if ((gametyperules & GTR_CIRCUIT)) // If in Race Mode, allow + if (!player->spectator) { - K_KartUpdatePosition(player); - - if (cv_kartvoices.value) + if ((gametyperules & GTR_CIRCUIT)) // If in Race Mode, allow { - if (P_IsDisplayPlayer(player)) + K_KartUpdatePosition(player); + + if (cv_kartvoices.value) { - sfxenum_t sfx_id; - if (losing) - sfx_id = ((skin_t *)player->mo->skin)->soundsid[S_sfx[sfx_klose].skinsound]; - else - sfx_id = ((skin_t *)player->mo->skin)->soundsid[S_sfx[sfx_kwin].skinsound]; - S_StartSound(NULL, sfx_id); - } - else - { - if (losing) - S_StartSound(player->mo, sfx_klose); - else - S_StartSound(player->mo, sfx_kwin); - } - } - - if (!K_CanChangeRules() || cv_inttime.value > 0) - P_EndingMusic(player); - - if (P_CheckRacers() && !exitcountdown) - exitcountdown = raceexittime+1; - } - else if ((gametyperules & GTR_BUMPERS)) // Battle Mode exiting - { - if (!exitcountdown) - exitcountdown = battleexittime+1; - P_EndingMusic(player); - } - else // Accidental death safeguard??? - { - if (!exitcountdown) - exitcountdown = raceexittime+2; - } - - if (grandprixinfo.gp == true) - { - if (player->bot) - { - // Bots are going to get harder... :) - K_IncreaseBotDifficulty(player); - } - else if (!losing) - { - const UINT8 lifethreshold = 20; - UINT8 extra = 0; - - // YOU WIN - grandprixinfo.wonround = true; - - // Increase your total rings - if (RINGTOTAL(player) > 0) - { - player->totalring += RINGTOTAL(player); - - extra = player->totalring / lifethreshold; - - if (extra > player->xtralife) + if (P_IsDisplayPlayer(player)) { - P_GivePlayerLives(player, extra - player->xtralife); - S_StartSound(NULL, sfx_cdfm73); - player->xtralife = extra; + sfxenum_t sfx_id; + if (losing) + sfx_id = ((skin_t *)player->mo->skin)->soundsid[S_sfx[sfx_klose].skinsound]; + else + sfx_id = ((skin_t *)player->mo->skin)->soundsid[S_sfx[sfx_kwin].skinsound]; + S_StartSound(NULL, sfx_id); + } + else + { + if (losing) + S_StartSound(player->mo, sfx_klose); + else + S_StartSound(player->mo, sfx_kwin); + } + } + + if (!K_CanChangeRules() || cv_inttime.value > 0) + P_EndingMusic(player); + + if (P_CheckRacers() && !exitcountdown) + exitcountdown = raceexittime+1; + } + else if ((gametyperules & GTR_BUMPERS)) // Battle Mode exiting + { + if (!exitcountdown) + exitcountdown = battleexittime+1; + P_EndingMusic(player); + } + else // Accidental death safeguard??? + { + if (!exitcountdown) + exitcountdown = raceexittime+2; + } + + if (grandprixinfo.gp == true) + { + if (player->bot) + { + // Bots are going to get harder... :) + K_IncreaseBotDifficulty(player); + } + else if (!losing) + { + const UINT8 lifethreshold = 20; + UINT8 extra = 0; + + // YOU WIN + grandprixinfo.wonround = true; + + // Increase your total rings + if (RINGTOTAL(player) > 0) + { + player->totalring += RINGTOTAL(player); + + extra = player->totalring / lifethreshold; + + if (extra > player->xtralife) + { + P_GivePlayerLives(player, extra - player->xtralife); + S_StartSound(NULL, sfx_cdfm73); + player->xtralife = extra; + } } } } diff --git a/src/st_stuff.c b/src/st_stuff.c index d46da54b5..abdd232fb 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -437,6 +437,7 @@ static patch_t *tcol2; static patch_t *tcroundbar; static patch_t *tcround; +static patch_t *tcbonus; static patch_t *tccircletop; static patch_t *tccirclebottom; @@ -446,6 +447,8 @@ static patch_t *tcbanner; static patch_t *tcbanner2; static patch_t *tcroundnum[10]; +static patch_t *tcroundbonus; + static patch_t *tcactnum[10]; static patch_t *tcact; @@ -495,6 +498,7 @@ static void ST_cacheLevelTitle(void) tcroundbar = (patch_t *)W_CachePatchName("TCBB0", PU_HUDGFX); tcround = (patch_t *)W_CachePatchName("TCROUND", PU_HUDGFX); + tcbonus = (patch_t *)W_CachePatchName("TCBONUS", PU_HUDGFX); tccircletop = (patch_t *)W_CachePatchName("TCSN1", PU_HUDGFX); tccirclebottom =(patch_t *)W_CachePatchName("TCSN2", PU_HUDGFX); @@ -514,6 +518,7 @@ static void ST_cacheLevelTitle(void) sprintf(buf, "TT_RND%d", i); tcroundnum[i-1] = (patch_t *)W_CachePatchName(buf, PU_HUDGFX); } + tcroundbonus = (patch_t *)W_CachePatchName("TT_RNDB", PU_HUDGFX); // Cache act # for (i=0; i < 10; i++) @@ -579,7 +584,7 @@ void ST_runTitleCard(void) { boolean run = !(paused || P_AutoPause()); INT32 auxticker; - boolean gp = (grandprixinfo.gp && grandprixinfo.roundnum); // check whether we're in grandprix + boolean gp = (marathonmode || (grandprixinfo.gp && grandprixinfo.roundnum)); if (!G_IsTitleCardAvailable()) return; @@ -764,7 +769,7 @@ void ST_drawTitleCard(void) char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *zonttl = mapheaderinfo[gamemap-1]->zonttl; // SRB2kart UINT8 actnum = mapheaderinfo[gamemap-1]->actnum; - boolean gp = (grandprixinfo.gp && grandprixinfo.roundnum); + boolean gp = (marathonmode || (grandprixinfo.gp && grandprixinfo.roundnum)); INT32 acttimer; fixed_t actscale; @@ -895,7 +900,9 @@ void ST_drawTitleCard(void) V_DrawFixedPatch(roundx*FRACUNIT, ((-32) + (lt_ticker%32))*FRACUNIT, FRACUNIT, V_SNAPTOTOP|V_SNAPTOLEFT, tcroundbar, NULL); // Draw ROUND text if (gp) - V_DrawFixedPatch((roundx+10)*FRACUNIT, roundy*FRACUNIT, FRACUNIT, V_SNAPTOTOP|V_SNAPTOLEFT, tcround, NULL); + V_DrawFixedPatch((roundx+10)*FRACUNIT, roundy*FRACUNIT, FRACUNIT, V_SNAPTOTOP|V_SNAPTOLEFT, + ((grandprixinfo.gp && grandprixinfo.eventmode) ? tcbonus : tcround), + NULL); // round num background V_DrawFixedPatch(roundnumx*FRACUNIT, roundnumy*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tccirclebg, NULL); @@ -912,9 +919,31 @@ void ST_drawTitleCard(void) } } - // If possible, draw round number - if (gp && grandprixinfo.roundnum > 0 && grandprixinfo.roundnum < 11) // Check boundaries JUST IN CASE. - V_DrawFixedPatch(roundnumx*FRACUNIT, roundnumy*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tcroundnum[grandprixinfo.roundnum-1], NULL); + // If possible, draw round number/icon + if (gp) + { + patch_t *roundico = NULL; + if (marathonmode) + ; // TODO: Ruby + else switch (grandprixinfo.eventmode) + { + case GPEVENT_BONUS: + roundico = tcroundbonus; + break; + /*case GPEVENT_SPECIAL: + ; // TODO: Emerald/mount + break;*/ + case GPEVENT_NONE: + if (grandprixinfo.roundnum > 0 && grandprixinfo.roundnum < 11) // Check boundaries JUST IN CASE. + roundico = tcroundnum[grandprixinfo.roundnum-1]; + break; + default: + break; + } + + if (roundico) + V_DrawFixedPatch(roundnumx*FRACUNIT, roundnumy*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, roundico, NULL); + } // Draw both halves of the egg V_DrawFixedPatch(eggx1*FRACUNIT, eggy1*FRACUNIT, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, tccircletop, NULL); diff --git a/src/y_inter.c b/src/y_inter.c index c0fbd8588..f943d09d4 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -753,21 +753,26 @@ void Y_DetermineIntermissionType(void) // set to int_none initially intertype = int_none; - if (intermissiontypes[gametype] != int_none) - intertype = intermissiontypes[gametype]; - else if (gametype == GT_RACE) + if (gametype == GT_RACE) intertype = int_race; else if (gametype == GT_BATTLE) { - UINT8 i = 0, nump = 0; - for (i = 0; i < MAXPLAYERS; i++) + if (grandprixinfo.gp == true && bossinfo.boss == false) + intertype = int_none; + else { - if (!playeringame[i] || players[i].spectator) - continue; - nump++; + UINT8 i = 0, nump = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + nump++; + } + intertype = (nump < 2 ? int_battletime : int_battle); } - intertype = (nump < 2 ? int_battletime : int_battle); } + else //if (intermissiontypes[gametype] != int_none) + intertype = intermissiontypes[gametype]; } //