From a44576ad8d0b9c8b75de28f531f2b233c66c3f58 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 31 Aug 2023 21:55:25 +0100 Subject: [PATCH] Fix some issues with Rings in Grand Prix - Store a netsynced SINT8 `hudrings` on the player struct which stores the last rings the player has during play - So this doesn't get updated after you finish the level - Fixes the issue where the bot ghost that inhabits your body after finishing will use your rings, muddying how many you took into the total - Fixed order of operations that prevented lives earned with GP rings from being given - Also uses hudrings for consistency - Make the life-give context in P_DoPlayerExit cleaner - GPEVENT_NONE - no GTR_SPHERES --- src/d_player.h | 1 + src/k_grandprix.c | 2 +- src/k_hud.c | 12 ++++++------ src/k_kart.c | 12 ++++++++++-- src/p_saveg.c | 2 ++ src/p_user.c | 39 +++++++++++++++++++++++---------------- 6 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 292ec12f4..611b72f57 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -652,6 +652,7 @@ struct player_t // player's ring count SINT8 rings; + SINT8 hudrings; // The above is only updated during play, this is locked after finishing UINT8 pickuprings; // Number of rings being picked up before added to the counter (prevents rings from being deleted forever over 20) UINT8 ringdelay; // (0 to 3) - 3 tic delay between every ring usage UINT16 ringboost; // Ring boost timer diff --git a/src/k_grandprix.c b/src/k_grandprix.c index e4ab54aab..b5cf2772b 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -877,7 +877,7 @@ void K_PlayerFinishGrandPrix(player_t *player) grandprixinfo.wonround = true; // Increase your total rings - INT32 ringtotal = RINGTOTAL(player); + INT32 ringtotal = player->hudrings; if (ringtotal > 0) { if (ringtotal > 20) diff --git a/src/k_hud.c b/src/k_hud.c index 5b64059d3..6d02327fe 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2608,15 +2608,15 @@ static void K_drawRingCounter(boolean gametypeinfoshown) boolean colorring = false; INT32 ringx = 0, fy = 0; - rn[0] = ((abs(stplyr->rings) / 10) % 10); - rn[1] = (abs(stplyr->rings) % 10); + rn[0] = ((abs(stplyr->hudrings) / 10) % 10); + rn[1] = (abs(stplyr->hudrings) % 10); - if (stplyr->rings <= 0 && (leveltime/5 & 1)) // In debt + if (stplyr->hudrings <= 0 && (leveltime/5 & 1)) // In debt { ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE); colorring = true; } - else if (stplyr->rings >= 20) // Maxed out + else if (stplyr->hudrings >= 20) // Maxed out ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE); if (stplyr->karthud[khud_ringframe] > RINGANIM_FLIPFRAME) @@ -2673,7 +2673,7 @@ static void K_drawRingCounter(boolean gametypeinfoshown) V_DrawMappedPatch(fr+ringx, fy-3, V_HUDTRANS|V_SLIDEIN|splitflags|ringflip, kp_smallring[ringanim_realframe], (colorring ? ringmap : NULL)); - if (stplyr->rings < 0) // Draw the minus for ring debt + if (stplyr->hudrings < 0) // Draw the minus for ring debt V_DrawMappedPatch(fr+7, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_ringdebtminussmall, ringmap); V_DrawMappedPatch(fr+11, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[rn[0]], ringmap); @@ -2716,7 +2716,7 @@ static void K_drawRingCounter(boolean gametypeinfoshown) V_DrawMappedPatch(LAPS_X+ringx+7, fy-5, V_HUDTRANS|V_SLIDEIN|splitflags|ringflip, kp_ring[ringanim_realframe], (colorring ? ringmap : NULL)); - if (stplyr->rings < 0) // Draw the minus for ring debt + if (stplyr->hudrings < 0) // Draw the minus for ring debt { V_DrawMappedPatch(LAPS_X+23, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_ringdebtminus, ringmap); V_DrawMappedPatch(LAPS_X+29, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[rn[0]], ringmap); diff --git a/src/k_kart.c b/src/k_kart.c index 31567ea1a..1cfece7a2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7437,6 +7437,8 @@ static void K_UpdateInvincibilitySounds(player_t *player) #undef STOPTHIS } +// This function is not strictly for non-netsynced properties. +// It's just a convenient name for things that don't stop during hitlag. void K_KartPlayerHUDUpdate(player_t *player) { if (player->karthud[khud_lapanimation]) @@ -7487,6 +7489,12 @@ void K_KartPlayerHUDUpdate(player_t *player) if (!(gametyperules & GTR_SPHERES)) { + if (!player->exiting + && !(player->pflags & (PF_NOCONTEST|PF_ELIMINATED))) + { + player->hudrings = player->rings; + } + if (player->mo && player->mo->hitlag <= 0) { // 0 is the fast spin animation, set at 30 tics of ring boost or higher! @@ -7522,7 +7530,7 @@ void K_KartPlayerHUDUpdate(player_t *player) if (player->karthud[khud_ringspblock] >= 14) // debt animation { - if ((player->rings > 0) // Get out of 0 ring animation + if ((player->hudrings > 0) // Get out of 0 ring animation && (normalanim == 3 || normalanim == 10)) // on these transition frames. player->karthud[khud_ringspblock] = normalanim; else @@ -7530,7 +7538,7 @@ void K_KartPlayerHUDUpdate(player_t *player) } else // normal animation { - if ((player->rings <= 0) // Go into 0 ring animation + if ((player->hudrings <= 0) // Go into 0 ring animation && (player->karthud[khud_ringspblock] == 1 || player->karthud[khud_ringspblock] == 8)) // on these transition frames. player->karthud[khud_ringspblock] = debtanim; else diff --git a/src/p_saveg.c b/src/p_saveg.c index 2c2e3ce11..a2f198286 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -457,6 +457,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].sadtimer); WRITESINT8(save->p, players[i].rings); + WRITESINT8(save->p, players[i].hudrings); WRITEUINT8(save->p, players[i].pickuprings); WRITEUINT8(save->p, players[i].ringdelay); WRITEUINT16(save->p, players[i].ringboost); @@ -882,6 +883,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].sadtimer = READUINT8(save->p); players[i].rings = READSINT8(save->p); + players[i].hudrings = READSINT8(save->p); players[i].pickuprings = READUINT8(save->p); players[i].ringdelay = READUINT8(save->p); players[i].ringboost = READUINT16(save->p); diff --git a/src/p_user.c b/src/p_user.c index 389689c69..0e0a356b8 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1290,6 +1290,29 @@ void P_DoPlayerExit(player_t *player, pflags_t flags) { ClearFakePlayerSkin(player); + if (!(gametyperules & GTR_SPHERES)) + { + player->hudrings = RINGTOTAL(player); + if (player->hudrings > 20) + player->hudrings = 20; + + if (grandprixinfo.gp == true + && grandprixinfo.eventmode == GPEVENT_NONE + && player->bot == false && losing == false) + { + const UINT8 lifethreshold = 20; + + const UINT8 oldExtra = player->totalring / lifethreshold; + const UINT8 extra = (player->totalring + player->hudrings) / lifethreshold; + + if (extra > oldExtra) + { + S_StartSound(NULL, sfx_cdfm73); + player->xtralife = (extra - oldExtra); + } + } + } + if ((gametyperules & GTR_CIRCUIT)) // Special Race-like handling { K_UpdateAllPlayerPositions(); @@ -1323,22 +1346,6 @@ void P_DoPlayerExit(player_t *player, pflags_t flags) { G_BeginLevelExit(); } - - if (grandprixinfo.gp == true - && (roundqueue.size && roundqueue.position < roundqueue.size) // Not the last map of GP - && player->bot == false && losing == false) - { - const UINT8 lifethreshold = 20; - - const UINT8 oldExtra = player->totalring / lifethreshold; - const UINT8 extra = (player->totalring + RINGTOTAL(player)) / lifethreshold; - - if (extra > oldExtra) - { - S_StartSound(NULL, sfx_cdfm73); - player->xtralife = (extra - oldExtra); - } - } } if (demo.playback == false)