From f5f85cc3e4ebca13d9ca38eebfb64d8742fa3af9 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 22 Mar 2023 20:49:33 -0700 Subject: [PATCH 1/2] Refactor lives and rank increase to occur at level end transition, not when the player finishes Fixes exploiting retries after finishing in good standing to farm lives and rank. These are now applied when you can no longer retry. Extra life sound effect still plays as soon as you finish the race. --- src/g_game.c | 8 ++++++++ src/k_grandprix.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ src/k_grandprix.h | 15 +++++++++++++++ src/p_setup.c | 2 ++ src/p_user.c | 47 +++++++++------------------------------------ 5 files changed, 83 insertions(+), 38 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 59ed90232..7fe496b38 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3206,6 +3206,14 @@ void G_ExitLevel(void) } else if (grandprixinfo.gp == true && grandprixinfo.eventmode == GPEVENT_NONE) { + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + { + K_PlayerFinishGrandPrix(&players[i]); + } + } + doretry = (grandprixinfo.wonround != true); } diff --git a/src/k_grandprix.c b/src/k_grandprix.c index bc4779386..cb7085cc2 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -18,6 +18,7 @@ #include "k_bot.h" #include "k_kart.h" #include "m_random.h" +#include "p_local.h" #include "r_things.h" struct grandprixinfo grandprixinfo; @@ -741,3 +742,51 @@ boolean K_CanChangeRules(boolean allowdemos) return true; } + +/*-------------------------------------------------- + void K_PlayerFinishGrandPrix(player_t *player); + + See header file for description. +--------------------------------------------------*/ +void K_PlayerFinishGrandPrix(player_t *player) +{ + if (player->exiting == false) + { + // You did not finish + return; + } + + if (player->bot) + { + // Bots are going to get harder... :) + K_IncreaseBotDifficulty(player); + return; + } + + if (K_IsPlayerLosing(player)) + { + return; + } + + // YOU WIN + grandprixinfo.wonround = true; + + // Increase your total rings + if (RINGTOTAL(player) > 0) + { + player->totalring += RINGTOTAL(player); + grandprixinfo.rank.rings += RINGTOTAL(player); + } + + if (grandprixinfo.eventmode == GPEVENT_NONE) + { + grandprixinfo.rank.winPoints += K_CalculateGPRankPoints(player->position, grandprixinfo.rank.totalPlayers); + grandprixinfo.rank.laps += player->lapPoints; + } + else if (grandprixinfo.eventmode == GPEVENT_SPECIAL) + { + grandprixinfo.rank.specialWon = true; + } + + P_GivePlayerLives(player, player->xtralife); +} diff --git a/src/k_grandprix.h b/src/k_grandprix.h index efa251246..80f659809 100644 --- a/src/k_grandprix.h +++ b/src/k_grandprix.h @@ -192,6 +192,21 @@ void K_PlayerLoseLife(player_t *player); boolean K_CanChangeRules(boolean allowdemos); +/*-------------------------------------------------- + void K_PlayerFinishGrandPrix(player_t *player); + + Increases rank and bot difficulties, wins the round. + + Input Arguments:- + player - Player to do this for. + + Return:- + None +--------------------------------------------------*/ + +void K_PlayerFinishGrandPrix(player_t *player); + + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/p_setup.c b/src/p_setup.c index 7e95d7455..5a38e57b6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7402,6 +7402,8 @@ static void P_InitPlayers(void) { G_SpawnPlayer(i); } + + players[i].xtralife = 0; // extra lives do not ever carry over from the previous round } K_UpdateAllPlayerPositions(); diff --git a/src/p_user.c b/src/p_user.c index 98e5b92c2..2a9e006ec 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1334,46 +1334,17 @@ void P_DoPlayerExit(player_t *player) exitcountdown = raceexittime+2; } - if (grandprixinfo.gp == true) + if (grandprixinfo.gp == true && player->bot == false && losing == false) { - if (player->bot) + const UINT8 lifethreshold = 20; + + const UINT8 oldExtra = player->totalring / lifethreshold; + const UINT8 extra = (player->totalring + RINGTOTAL(player)) / lifethreshold; + + if (extra > oldExtra) { - // 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); - grandprixinfo.rank.rings += RINGTOTAL(player); - - extra = player->totalring / lifethreshold; - - if (extra > player->xtralife) - { - P_GivePlayerLives(player, extra - player->xtralife); - S_StartSound(NULL, sfx_cdfm73); - player->xtralife = extra; - } - } - - if (grandprixinfo.eventmode == GPEVENT_NONE) - { - grandprixinfo.rank.winPoints += K_CalculateGPRankPoints(player->position, grandprixinfo.rank.totalPlayers); - grandprixinfo.rank.laps += player->lapPoints; - } - else if (grandprixinfo.eventmode == GPEVENT_SPECIAL) - { - grandprixinfo.rank.specialWon = true; - } + S_StartSound(NULL, sfx_cdfm73); + player->xtralife = (extra - oldExtra); } } } From b7d1996a15c1ed84b0efcd35dc8e502171912fde Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 22 Mar 2023 20:54:58 -0700 Subject: [PATCH 2/2] Do not let retries be buffered on intermission to instantly retry the next round --- src/p_setup.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index 5a38e57b6..1be72d23b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7476,6 +7476,8 @@ static void P_InitGametype(void) lastLowestLap = 0; spbplace = -1; + G_ClearRetryFlag(); + // Start recording replay in multiplayer with a temp filename //@TODO I'd like to fix dedis crashing when recording replays for the future too... if (gamestate == GS_LEVEL && !demo.playback && multiplayer && !dedicated)