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++)