From 9016f654401a8beda8b7a01e61747a59e27b15e7 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 14 Oct 2022 18:34:34 +0100 Subject: [PATCH] Support alternate gameplay events during GP - Implementation details: - grandprixinfo.eventmode is the reference point - All bots have spectator applied and removed at map start depending on eventmode, and I've done my best to guard against side effects of not removing them entirely - You shouldn't turn off grandprixinfo.gp when turning on things like specialStage.active or bossinfo.boss when pursuing eventmode behaviour - Probably needs to be integrated into XD_MAP for any future netplay support, is currently disabled. - You technically don't have to assign a Capsules map to be the bonus and a Special Stage to be the special. A Capsules map can be assigned to a Special Stage too, and a Boss can be assigned to either of them. - Special Stages are still just as incomplete as they were before. - Break the Capsules has special behaviour. - Timelimit starts at 20 seconds. - Earn 10 seconds (plus a little extra cheaty time) every capsule you destroy. - WIN + extra life if you bust all the capsules, COOL if you get some but run out of time, LOSE if you lose your bumper or run out of time without breaking a single capsule. - Supposed to also give you rings, but ran into a LOT of difficulty with this and didn't want to commit half-baked stuff, so it'll be a later project. Also: - Fix a long standing bug where totalring was reset between maps, preventing the sum from adding up across GP rounds and depriving you of extra lives you were owed. - Fix an issue where Break the Capsules record attack was KARTSPEED_HARD. - Send timelimitintics in savegames, since it's handled seperately now. --- src/d_netcmd.c | 18 ++++--- src/d_netcmd.h | 2 +- src/g_game.c | 17 +++--- src/k_battle.c | 6 +++ src/k_bot.c | 10 +--- src/k_grandprix.c | 23 +++++--- src/k_grandprix.h | 5 ++ src/k_hud.c | 31 ++++++----- src/k_kart.c | 31 +++++++++-- src/p_enemy.c | 7 +-- src/p_inter.c | 101 +++++++++++++++++++++++++++++++---- src/p_saveg.c | 4 ++ src/p_setup.c | 15 ++++-- src/p_user.c | 133 ++++++++++++++++++++++++---------------------- src/st_stuff.c | 7 ++- src/y_inter.c | 23 ++++---- 16 files changed, 295 insertions(+), 138 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 253e69822..e84767c1f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2502,15 +2502,15 @@ 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 (grandprixinfo.gp == true) + { + pencoremode = grandprixinfo.encore; + } if (delay != 2) { @@ -4876,6 +4876,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 @@ -5499,6 +5501,10 @@ void Command_Retry_f(void) { CONS_Printf(M_GetText("This only works in Grand Prix or Mission Mode.\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 ed99fe2e4..fe80fe7c2 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -42,7 +42,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 f7188379e..51aee1efc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2243,6 +2243,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 @@ -2261,7 +2264,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) nocontrol = 0; laps = 0; latestlap = 0; - totalring = 0; roundscore = 0; exiting = 0; khudcardanimation = 0; @@ -2305,7 +2307,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; @@ -2316,8 +2317,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) prevcheck = players[player].prevcheck; prevcheck = players[player].nextcheck; - xtralife = players[player].xtralife; - follower = players[player].follower; pflags |= (players[player].pflags & (PF_STASIS|PF_ELIMINATED|PF_NOCONTEST|PF_LOSTLIFE)); @@ -2863,7 +2862,7 @@ void G_ExitLevel(void) } } } - else if (grandprixinfo.gp == true) + else if (grandprixinfo.gp == true && grandprixinfo.eventmode == GPEVENT_NONE) { youlost = (grandprixinfo.wonround != true); } @@ -3179,14 +3178,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; } diff --git a/src/k_battle.c b/src/k_battle.c index 14ecfabf5..046693613 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -172,7 +172,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 7c261114a..9f3d106be 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -1108,18 +1108,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 61493b27e..266a4169d 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -340,6 +340,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++) { @@ -526,9 +536,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; } @@ -584,18 +596,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 9d1a58647..4a47e6382 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" @@ -3823,7 +3824,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; @@ -3880,11 +3881,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(); } } @@ -4261,8 +4262,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; @@ -4270,8 +4276,8 @@ void K_drawKartFreePlay(void) if (((leveltime-lt_endtime) % TICRATE) < TICRATE/2) return; - V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - (12*9), // mirror the laps thingy - LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, "FREE PLAY"); + V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - 72, // mirror the laps thingy + LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN, "FREE PLAY"); } static void @@ -4667,11 +4673,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 ed814df11..7e127b726 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -43,6 +43,7 @@ #include "k_collide.h" #include "k_follower.h" #include "k_objects.h" +#include "k_grandprix.h" // SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H: // gamespeed is cc (0 for easy, 1 for normal, 2 for hard) @@ -89,6 +90,30 @@ 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); + } + } + //CONS_Printf("numbulbs set to %d (%d players, %d spectators) on tic %d\n", numbulbs, numPlayers, numspec, leveltime); } UINT32 K_GetPlayerDontDrawFlag(player_t *player) @@ -266,10 +291,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 f02c7f155..94af3729d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4054,9 +4054,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 841216f53..b298dd3e2 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -657,9 +657,6 @@ void P_CheckTimeLimit(void) { INT32 i; - if (!cv_timelimit.value) - return; - #ifndef TESTOVERTIMEINFREEPLAY if (battlecapsules) // capsules override any time limit settings return; @@ -670,6 +667,38 @@ void P_CheckTimeLimit(void) if (bossinfo.boss == true) return; + + if (exitcountdown) + return; + + if (!timelimitintics) + 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; @@ -761,16 +790,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 @@ -1447,12 +1479,24 @@ 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) + { + 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; + cur = target->hnext; while (cur && !P_MobjWasRemoved(cur)) @@ -1475,12 +1519,49 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget cur = cur->hnext; } - // All targets busted! - if (numtargets >= maptargets) + S_StartSound(target, sfx_mbs60); + + 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 5193e549c..02d392d71 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4558,6 +4558,10 @@ static void P_NetArchiveMisc(boolean resending) WRITEUINT32(save_p, introtime); WRITEUINT32(save_p, starttime); + 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 883abf974..e78a91962 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3770,7 +3770,7 @@ static void P_InitLevelSettings(boolean reloadinggamestate) // SRB2Kart: map load variables if (grandprixinfo.gp == true) { - if (gametype == GT_BATTLE) + if ((gametyperules & GTR_BUMPERS)) { gamespeed = KARTSPEED_EASY; } @@ -3791,7 +3791,10 @@ static void P_InitLevelSettings(boolean reloadinggamestate) 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; comeback = true; } @@ -4085,6 +4088,8 @@ static void P_InitPlayers(void) static void P_InitGametype(void) { + size_t i; + spectateGriefed = 0; K_CashInPowerLevels(); // Pushes power level changes even if intermission was skipped @@ -4097,7 +4102,7 @@ static void P_InitGametype(void) numlaps = 0; if (gametyperules & GTR_CIRCUIT) { - if ((netgame || multiplayer) && cv_numlaps.value + if (K_CanChangeRules() && cv_numlaps.value && (!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) || (mapheaderinfo[gamemap - 1]->numlaps > cv_numlaps.value))) { @@ -4108,6 +4113,10 @@ static void P_InitGametype(void) numlaps = mapheaderinfo[gamemap - 1]->numlaps; } } + else + { + numlaps = 0; + } wantedcalcdelay = wantedfrequency*2; indirectitemcooldown = 0; diff --git a/src/p_user.c b/src/p_user.c index ec6cf1333..551f86942 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -507,7 +507,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; } @@ -1267,72 +1266,80 @@ void P_DoPlayerExit(player_t *player) K_PlayerLoseLife(player); } - if ((gametyperules & GTR_CIRCUIT)) // If in Race Mode, allow + player->exiting = 1; + + if (!player->spectator) { - player->exiting = raceexittime+2; - 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 (cv_inttime.value > 0) - P_EndingMusic(player); - - if (P_CheckRacers()) - player->exiting = raceexittime+1; - } - else if ((gametyperules & GTR_BUMPERS)) // Battle Mode exiting - { - player->exiting = battleexittime+1; - P_EndingMusic(player); - } - else - player->exiting = raceexittime+2; // Accidental death safeguard??? - - 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 753d26dcc..cdea67d74 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -438,6 +438,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; @@ -447,6 +448,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; @@ -496,6 +499,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); @@ -515,6 +519,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++) @@ -580,7 +585,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; diff --git a/src/y_inter.c b/src/y_inter.c index 19097bac1..62f77fa04 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -897,21 +897,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]; } //