From 6554c8bfb1f7e2746a867713b20cbe9d106ddf62 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 15 Dec 2022 02:13:46 -0500 Subject: [PATCH] Improve scope handling of the roulette All of the player_t references are now full-const instead of const pointer after a certain point. This is because I've made two mistakes so far of modifying the player with this, when it's supposed to be safe to call for HUD as well. Also uses this split to add a more efficient way to prevent multi-Shrink/SPB. Also handles NULL player better, for the sake of Battle's K_CreatePaperItem. --- src/k_hud.c | 2 +- src/k_kart.c | 2 +- src/k_roulette.c | 91 +++++++++++++++++++++++++++--------------------- src/k_roulette.h | 5 +-- src/p_enemy.c | 2 +- src/p_inter.c | 2 +- 6 files changed, 59 insertions(+), 45 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 49bb6aa07..7c1d94e42 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4560,7 +4560,7 @@ static void K_drawDistributionDebugger(void) return; } - K_StartItemRoulette(stplyr, &rouletteData); + K_FillItemRouletteData(stplyr, &rouletteData); for (i = 0; i < rouletteData.itemListLen; i++) { diff --git a/src/k_kart.c b/src/k_kart.c index b512a64c3..3bce71c54 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6063,7 +6063,7 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 useodds = amount; - K_StartItemRoulette(stplyr, &rouletteData); + K_FillItemRouletteData(NULL, &rouletteData); for (i = 1; i < NUMKARTRESULTS; i++) { diff --git a/src/k_roulette.c b/src/k_roulette.c index b77659be6..6d59f1ec3 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -251,10 +251,15 @@ static UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers) return distance; } -static UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 numPlayers) +static UINT32 K_GetItemRouletteDistance(const player_t *player, UINT8 numPlayers) { UINT32 pdis = 0; + if (player == NULL) + { + return 0; + } + #if 0 if (specialStage.active == true) { @@ -316,7 +321,7 @@ static UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 numPlayers \return void */ -INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item) +INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item) { boolean bot = false; boolean rival = false; @@ -329,7 +334,7 @@ INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, boolean notNearEnd = false; fixed_t newOdds = 0; - size_t i, j; + size_t i; I_Assert(roulette != NULL); @@ -401,29 +406,6 @@ INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, } } - if (K_ItemSingularity(item) == true) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] == false || players[i].spectator == true) - { - continue; - } - - if (players[i].itemRoulette.active == true) - { - for (j = 0; j < players[i].itemRoulette.itemListLen; j++) - { - if (players[i].itemRoulette.itemList[j] == item) - { - // Don't add if someone is already rolling for it. - return 0; - } - } - } - } - } - if (gametype == GT_BATTLE) { I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table @@ -587,7 +569,7 @@ INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, return newOdds; } -static UINT8 K_FindUseodds(player_t *const player, itemroulette_t *const roulette) +static UINT8 K_FindUseodds(const player_t *player, itemroulette_t *const roulette) { UINT8 i; UINT8 useOdds = 0; @@ -667,7 +649,7 @@ static UINT8 K_FindUseodds(player_t *const player, itemroulette_t *const roulett return useOdds; } -static boolean K_ForcedSPB(player_t *const player, itemroulette_t *const roulette) +static boolean K_ForcedSPB(const player_t *player, itemroulette_t *const roulette) { if (K_ItemEnabled(KITEM_SPB) == false) { @@ -679,6 +661,11 @@ static boolean K_ForcedSPB(player_t *const player, itemroulette_t *const roulett return false; } + if (player == NULL) + { + return false; + } + if (player->position <= 1) { return false; @@ -805,10 +792,15 @@ static void K_PushToRouletteItemList(itemroulette_t *const roulette, kartitems_t roulette->itemListLen++; } -static void K_AddItemToReel(player_t *const player, itemroulette_t *const roulette, kartitems_t item) +static void K_AddItemToReel(const player_t *player, itemroulette_t *const roulette, kartitems_t item) { K_PushToRouletteItemList(roulette, item); + if (player == NULL) + { + return; + } + // If we're in ring debt, pad out the reel with // a BUNCH of Super Rings. if (K_ItemEnabled(KITEM_SUPERRING) == true @@ -819,16 +811,12 @@ static void K_AddItemToReel(player_t *const player, itemroulette_t *const roulet } } -static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *const roulette) +static void K_CalculateRouletteSpeed(itemroulette_t *const roulette) { fixed_t frontRun = 0; fixed_t progress = 0; fixed_t total = 0; - // Make them select their item after a little while. - // One of the few instances of bot RNG, would be nice to remove it. - player->botvars.itemdelay = P_RandomRange(PR_UNDEFINED, TICRATE, TICRATE*3); - if (modeattacking || roulette->playing <= 1) { // Time Attack rules; use a consistent speed. @@ -869,7 +857,7 @@ static void K_CalculateRouletteSpeed(player_t *const player, itemroulette_t *con roulette->tics = roulette->speed = ROULETTE_SPEED_FASTEST + FixedMul(ROULETTE_SPEED_SLOWEST - ROULETTE_SPEED_FASTEST, total); } -void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) +void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette) { UINT32 spawnChance[NUMKARTRESULTS] = {0}; UINT32 totalSpawnChance = 0; @@ -882,9 +870,11 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) K_InitRoulette(roulette); - roulette->baseDist = K_UndoMapScaling(player->distancetofinish); - - K_CalculateRouletteSpeed(player, roulette); + if (player != NULL) + { + roulette->baseDist = K_UndoMapScaling(player->distancetofinish); + K_CalculateRouletteSpeed(roulette); + } // SPECIAL CASE No. 1: // Give only the debug item if specified @@ -1010,10 +1000,33 @@ void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette) } } +void K_StartItemRoulette(player_t *const player) +{ + itemroulette_t *const roulette = &player->itemRoulette; + size_t i; + + K_FillItemRouletteData(player, roulette); + + // Make the bots select their item after a little while. + // One of the few instances of bot RNG, would be nice to remove it. + player->botvars.itemdelay = P_RandomRange(PR_UNDEFINED, TICRATE, TICRATE*3); + + // Prevent further duplicates of items that + // are intended to only have one out at a time. + for (i = 0; i < roulette->itemListLen; i++) + { + kartitems_t item = roulette->itemList[i]; + if (K_ItemSingularity(item) == true) + { + K_SetItemCooldown(item, TICRATE<<4); + } + } +} + void K_StartEggmanRoulette(player_t *const player) { itemroulette_t *const roulette = &player->itemRoulette; - K_StartItemRoulette(player, roulette); + K_StartItemRoulette(player); roulette->eggman = true; } diff --git a/src/k_roulette.h b/src/k_roulette.h index b1664643c..fbc6d4a4b 100644 --- a/src/k_roulette.h +++ b/src/k_roulette.h @@ -19,9 +19,10 @@ boolean K_ItemEnabled(SINT8 item); boolean K_ItemSingularity(kartitems_t item); -INT32 K_KartGetItemOdds(player_t *const player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); +INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); +void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette); -void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette); +void K_StartItemRoulette(player_t *const player); void K_StartEggmanRoulette(player_t *const player); #define ROULETTE_SPACING (36 << FRACBITS) diff --git a/src/p_enemy.c b/src/p_enemy.c index 636eb500a..3c45a1d2e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13048,7 +13048,7 @@ void A_ItemPop(mobj_t *actor) } else if (locvar1 == 0) { - K_StartItemRoulette(actor->target->player, &actor->target->player->itemRoulette); + K_StartItemRoulette(actor->target->player); } // Here at mapload in battle? diff --git a/src/p_inter.c b/src/p_inter.c index 2c05f5732..6400b9d35 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -412,7 +412,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)) return; - K_StartItemRoulette(player, &player->itemRoulette); + K_StartItemRoulette(player); // Karma fireworks for (i = 0; i < 5; i++)