diff --git a/src/k_hud.c b/src/k_hud.c index 00604431f..4ac961110 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -5422,137 +5422,7 @@ static void K_drawDistributionDebugger(void) bestbumper = players[i].bumper; } - if (!K_UsingLegacyCheckpoints()) - { - // lovely double loop...... - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator - && players[i].position == 1) - { - // This player is first! Yay! - pdis = stplyr->distancetofinish - players[i].distancetofinish; - break; - } - } - } - else - { - // Pain and fucking suffering. - SINT8 sortedPlayers[MAXPLAYERS]; - UINT8 sortLength = 0; - - memset(sortedPlayers, -1, sizeof(sortedPlayers)); - - if (stplyr->mo != NULL && P_MobjWasRemoved(stplyr->mo) == false) - { - // Sort all of the players ahead of you. - // Then tally up their distances in a conga line. - - // This will create a much more consistent item - // distance algorithm than the "spider web" thing - // that it was doing before. - - // Add yourself to the list. - // You'll always be the end of the list, - // so we can also calculate the length here. - sortedPlayers[ stplyr->position - 1 ] = stplyr - players; - sortLength = stplyr->position; - - // Will only need to do this if there's goint to be - // more than yourself in the list. - if (sortLength > 1) - { - SINT8 firstIndex = -1; - SINT8 secondIndex = -1; - INT32 startFrom = INT32_MAX; - - // Add all of the other players. - for (i = 0; i < MAXPLAYERS; i++) - { - INT32 pos = INT32_MAX; - - if (!playeringame[i] || players[i].spectator) - { - continue; - } - - if (players[i].mo == NULL || P_MobjWasRemoved(players[i].mo) == true) - { - continue; - } - - pos = players[i].position; - - if (pos <= 0 || pos > MAXPLAYERS) - { - // Invalid position. - continue; - } - - if (pos >= stplyr->position) - { - // Tied / behind us. - // Also handles ourselves, obviously. - continue; - } - - // Ties are done with port priority, if there are any. - if (sortedPlayers[ pos - 1 ] == -1) - { - sortedPlayers[ pos - 1 ] = i; - } - } - - // The chance of this list having gaps is improbable, - // but not impossible. So we need to spend some extra time - // to prevent the gaps from mattering. - for (i = 0; i < sortLength-1; i++) - { - if (sortedPlayers[i] >= 0 && sortedPlayers[i] < MAXPLAYERS) - { - // First valid index in the list found. - firstIndex = sortedPlayers[i]; - - // Start the next loop after this player. - startFrom = i + 1; - break; - } - } - - if (firstIndex >= 0 && firstIndex < MAXPLAYERS - && startFrom < sortLength) - { - // First index is valid, so we can - // start comparing the players. - - player_t *firstPlayer = NULL; - player_t *secondPlayer = NULL; - - for (i = startFrom; i < sortLength; i++) - { - if (sortedPlayers[i] >= 0 && sortedPlayers[i] < MAXPLAYERS) - { - secondIndex = sortedPlayers[i]; - - firstPlayer = &players[firstIndex]; - secondPlayer = &players[secondIndex]; - - // Add the distance to the player behind you. - pdis += P_AproxDistance(P_AproxDistance( - firstPlayer->mo->x - secondPlayer->mo->x, - firstPlayer->mo->y - secondPlayer->mo->y), - firstPlayer->mo->z - secondPlayer->mo->z) / FRACUNIT; - - // Advance to next index. - firstIndex = secondIndex; - } - } - } - } - } - - } + pdis = K_CalculateInitalPDIS(stplyr); if (spbplace != -1 && stplyr->position == spbplace+1) { @@ -5570,10 +5440,7 @@ static void K_drawDistributionDebugger(void) pdis = (15 * pdis) / 14; } - if (K_UsingLegacyCheckpoints()) - useodds = K_FindLegacyUseodds(stplyr, 0, pingame, bestbumper, spbrush, dontforcespb); - else - useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper, spbrush); + useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper, spbrush); if (pingame == 1) { @@ -5583,30 +5450,20 @@ static void K_drawDistributionDebugger(void) V_DrawScaledPatch(x, y, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, K_GetSmallStaticCachedItemPatch(KITEM_SNEAKER)); V_DrawThinString(x+11, y+31, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, va("%d", 200)); } - else if (useodds == 69) - { - V_DrawScaledPatch(x, y, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, K_GetSmallStaticCachedItemPatch(KITEM_SPB)); - V_DrawThinString(x+11, y+31, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, va("%d", 200)); - - } else { - for (item = 1; item < NUMKARTRESULTS; item++) { INT32 itemodds; INT32 amount; - if (K_UsingLegacyCheckpoints()) - itemodds = K_KartGetLegacyItemOdds(useodds, item, stplyr->distancefromcluster, 0, spbrush); - else - itemodds = K_KartGetItemOdds( - useodds, item, - stplyr->distancetofinish, - stplyr->distancefromcluster, - 0, - spbrush, stplyr->bot, (stplyr->bot && stplyr->botvars.rival) - ); + itemodds = K_KartGetItemOdds( + useodds, item, + stplyr->distancetofinish, + stplyr->distancefromcluster, + 0, + spbrush, stplyr->bot, (stplyr->bot && stplyr->botvars.rival) + ); if (itemodds <= 0) continue; @@ -5633,8 +5490,6 @@ static void K_drawDistributionDebugger(void) if (pingame == 1) V_DrawString(0, 0, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, "TA MODE"); - else if (useodds == 69) - V_DrawString(0, 0, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, "FORCED SPB"); else V_DrawString(0, 0, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, va("USEODDS %d", useodds)); diff --git a/src/k_odds.c b/src/k_odds.c index d9f4bb613..34697f02e 100644 --- a/src/k_odds.c +++ b/src/k_odds.c @@ -591,7 +591,7 @@ INT32 K_KartGetItemOdds( // This item should not appear at the beginning of a race. (Usually really powerful crowd-breaking items) newodds = 0; } - else if ((notNearEnd == true) && (ourDist < ENDDIST)) + else if (!K_UsingLegacyCheckpoints() && (notNearEnd == true) && (ourDist < ENDDIST)) { // This item should not appear at the end of a race. (Usually trap items that lose their effectiveness) newodds = 0; @@ -627,203 +627,6 @@ INT32 K_KartGetItemOdds( return newodds; } -INT32 K_KartGetLegacyItemOdds(UINT8 pos, SINT8 item, fixed_t clusterDist, fixed_t mashed, boolean spbrush) -{ - INT32 newodds; - INT32 i; - UINT8 pingame = 0, pexiting = 0; - SINT8 first = -1, second = -1; - UINT32 secondToFirst = 0; - INT32 shieldtype = KSHIELD_NONE; - - boolean powerItem = false; - boolean cooldownOnStart = false; - boolean indirectItem = false; - - I_Assert(item > KITEM_NONE); // too many off by one scenarioes. - - if (!KartItemCVars[item-1]->value && !modeattacking) - return 0; - - INT32 oddsmul = BASEODDSMUL; - - if (gametyperules & GTR_BATTLEODDS) - { - newodds = K_KartItemOddsBattle[item-1][pos]; - oddsmul = BATTLEODDSMUL; - } - else if (gametyperules & GTR_RACEODDS) - newodds = K_KartItemOddsRace[item-1][pos]; - else - newodds = 0; - - // Blow up the odds with a multiplier. - newodds *= oddsmul; - - shieldtype = K_GetShieldFromItem(item); - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - - if (!(gametyperules & GTR_BUMPERS) || players[i].bumper) - pingame++; - - if (players[i].exiting) - pexiting++; - - if (shieldtype != KSHIELD_NONE && ((shieldtype == K_GetShieldFromItem(players[i].itemtype)) - || (shieldtype == K_GetShieldFromPlayer(&players[i])))) - { - // Don't allow more than one of each shield type at a time - return 0; - } - - if (players[i].mo && gametype == GT_RACE) - { - if (players[i].position == 1 && first == -1) - first = i; - if (players[i].position == 2 && second == -1) - second = i; - } - } - - if (first != -1 && second != -1) // calculate 2nd's distance from 1st, for SPB - { - secondToFirst = P_AproxDistance(P_AproxDistance(players[first].mo->x - players[second].mo->x, - players[first].mo->y - players[second].mo->y), - players[first].mo->z - players[second].mo->z) / FRACUNIT; - secondToFirst = K_ScaleItemDistance(secondToFirst, pingame, spbrush); - } - - switch (item) - { - case KITEM_ROCKETSNEAKER: - case KITEM_JAWZ: - case KITEM_BALLHOG: - case KITEM_LANDMINE: - case KRITEM_TRIPLESNEAKER: - case KRITEM_TRIPLEBANANA: - case KRITEM_TENFOLDBANANA: - case KRITEM_TRIPLEORBINAUT: - case KRITEM_QUADORBINAUT: - case KRITEM_DUALJAWZ: - powerItem = true; - break; - case KITEM_INVINCIBILITY: - if ((K_GetKartInvinType() == KARTINVIN_ALTERN) && (gametyperules & GTR_RACEODDS)) - { - // It's a power item, yes, but we don't want mashing to lessen - // its chances, so we lie to the game's face. - // Nonetheless, apply the start cooldown. - cooldownOnStart = true; - - // Unique odds for Invincibility. In legacy waypointing, - // its odds are doubled. - newodds = K_KartGetInvincibilityOdds(clusterDist) * 2; - - newodds *= BASEODDSMUL; - break; - } - /*FALLTHRU*/ - case KITEM_MINE: - case KITEM_GROW: - case KITEM_BUBBLESHIELD: - case KITEM_FLAMESHIELD: - cooldownOnStart = true; - powerItem = true; - break; - case KITEM_SPB: - cooldownOnStart = true; - indirectItem = true; - //powerItem = true; - - if (pexiting > 0) - { - newodds = 0; - } - else if (pos != 9) // Force SPB - { - const INT32 distFromStart = max(secondToFirst - SPBSTARTDIST , 0); - const INT32 distRange = SPBFORCEDIST - SPBSTARTDIST; - const fixed_t mulMax = 3*FRACUNIT; - - fixed_t multiplier = (distFromStart * mulMax) / distRange; - - if (multiplier < 0) - multiplier = 0; - - if (multiplier > mulMax) - multiplier = mulMax; - - newodds = FixedMul(newodds * FRACUNIT, multiplier) / FRACUNIT; - } - break; - case KITEM_SHRINK: - cooldownOnStart = true; - powerItem = true; - indirectItem = true; - - if (pingame-1 <= pexiting) - newodds = 0; - break; - case KITEM_THUNDERSHIELD: - cooldownOnStart = true; - powerItem = true; - break; - case KITEM_HYUDORO: - cooldownOnStart = true; - - if (hyubgone > 0) - newodds = 0; - break; - default: - break; - } - - if (newodds == 0) - { - // Nothing else we want to do with odds matters at this point :p - return newodds; - } - - if ((indirectItem == true) && (indirectitemcooldown > 0)) - { - // Too many items that act indirectly in a match can feel kind of bad. - newodds = 0; - } - else if ((cooldownOnStart == true) && (leveltime < (30*TICRATE)+starttime)) - { - // This item should not appear at the beginning of a race. (Usually really powerful crowd-breaking items) - newodds = 0; - } - else if (powerItem == true) - { - // This item is a "power item". This activates "frantic item" toggle related functionality. - fixed_t fracOdds = newodds * FRACUNIT; - - if (franticitems == true) - { - // First, power items multiply their odds by 2 if frantic items are on; easy-peasy. - fracOdds *= 2; - } - - fracOdds = FixedMul(fracOdds, FRACUNIT + K_ItemOddsScale(pingame, spbrush)); - - if (mashed > 0) - { - // Lastly, it *divides* it based on your mashed value, so that power items are less likely when you mash. - fracOdds = FixedDiv(fracOdds, FRACUNIT + mashed); - } - - newodds = fracOdds / FRACUNIT; - } - - return newodds; -} - - //{ SRB2kart Roulette Code - Distance Based, yes waypoints UINT8 K_FindUseodds(const player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper, boolean spbrush) @@ -959,278 +762,6 @@ UINT8 K_FindUseodds(const player_t *player, fixed_t mashed, UINT32 pdis, UINT8 b return useodds; } -INT32 K_FindLegacyUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT32 bestbumper, boolean spbrush, boolean dontforcespb) -{ - fixed_t oddsfac = max(FRACUNIT, (MAXODDS * FRACUNIT) / 8); - INT32 oddsdiv = (MAXODDS - 1) * 2; - - SINT8 sortedPlayers[MAXPLAYERS]; - UINT8 sortLength = 0; - - UINT32 pdis = 0; - - UINT8 disttable[oddsdiv]; - UINT8 distlen = 0; - - boolean oddsvalid[MAXODDS]; - INT32 useodds = 0; - - INT32 i, j; - - // Unused now, oops :V - (void)bestbumper; - - for (i = 0; i < MAXODDS; i++) - { - boolean available = false; - - if ((gametyperules & GTR_BATTLEODDS) && i > 1) - { - oddsvalid[i] = false; - break; - } - - for (j = 1; j < NUMKARTRESULTS; j++) - { - - if (K_KartGetLegacyItemOdds(i, j, player->distancefromcluster, mashed, spbrush) > 0) - { - available = true; - break; - } - - } - - oddsvalid[i] = available; - } - - memset(sortedPlayers, -1, sizeof(sortedPlayers)); - - if (player->mo != NULL && P_MobjWasRemoved(player->mo) == false) - { - // Sort all of the players ahead of you. - // Then tally up their distances in a conga line. - - // This will create a much more consistent item - // distance algorithm than the "spider web" thing - // that it was doing before. - - // Add yourself to the list. - // You'll always be the end of the list, - // so we can also calculate the length here. - sortedPlayers[ player->position - 1 ] = player - players; - sortLength = player->position; - - // Will only need to do this if there's goint to be - // more than yourself in the list. - if (sortLength > 1) - { - SINT8 firstIndex = -1; - SINT8 secondIndex = -1; - INT32 startFrom = INT32_MAX; - - // Add all of the other players. - for (i = 0; i < MAXPLAYERS; i++) - { - INT32 pos = INT32_MAX; - - if (!playeringame[i] || players[i].spectator) - { - continue; - } - - if (players[i].mo == NULL || P_MobjWasRemoved(players[i].mo) == true) - { - continue; - } - - pos = players[i].position; - - if (pos <= 0 || pos > MAXPLAYERS) - { - // Invalid position. - continue; - } - - if (pos >= player->position) - { - // Tied / behind us. - // Also handles ourselves, obviously. - continue; - } - - // Ties are done with port priority, if there are any. - if (sortedPlayers[ pos - 1 ] == -1) - { - sortedPlayers[ pos - 1 ] = i; - } - } - - // The chance of this list having gaps is improbable, - // but not impossible. So we need to spend some extra time - // to prevent the gaps from mattering. - for (i = 0; i < sortLength-1; i++) - { - if (sortedPlayers[i] >= 0 && sortedPlayers[i] < MAXPLAYERS) - { - // First valid index in the list found. - firstIndex = sortedPlayers[i]; - - // Start the next loop after this player. - startFrom = i + 1; - break; - } - } - - if (firstIndex >= 0 && firstIndex < MAXPLAYERS - && startFrom < sortLength) - { - // First index is valid, so we can - // start comparing the players. - - player_t *firstPlayer = NULL; - player_t *secondPlayer = NULL; - - for (i = startFrom; i < sortLength; i++) - { - if (sortedPlayers[i] >= 0 && sortedPlayers[i] < MAXPLAYERS) - { - secondIndex = sortedPlayers[i]; - - firstPlayer = &players[firstIndex]; - secondPlayer = &players[secondIndex]; - - // Add the distance to the player behind you. - pdis += P_AproxDistance(P_AproxDistance( - firstPlayer->mo->x - secondPlayer->mo->x, - firstPlayer->mo->y - secondPlayer->mo->y), - firstPlayer->mo->z - secondPlayer->mo->z) / FRACUNIT; - - // Advance to next index. - firstIndex = secondIndex; - } - } - } - } - } - -#define SETUPDISTTABLE(odds, num) \ - if (oddsvalid[odds]) \ - for (i = num; i; --i) \ - { \ - disttable[distlen++] = odds; \ - distlen = min(oddsdiv - 1, distlen); \ - } - - if (gametyperules & GTR_BATTLEODDS) // Battle Mode - { - if (player->roulettetype == KROULETTETYPE_KARMA && oddsvalid[1] == true) - { - // 1 is the extreme odds of player-controlled "Karma" items - useodds = 1; - } - else - { - useodds = 0; - - if (oddsvalid[0] == false && oddsvalid[1] == true) - { - // try to use karma odds as a fallback - useodds = 1; - } - } - } - else - { - INT32 tablediv = FixedMul(2, oddsfac); - INT32 jj; - - // "Why j instead of i"? - // Using i causes an infinite loop due to SETUPDISTTABLE. Yep. - for (j = 0; j < MAXODDS; j++) - { - if (j == (MAXODDS - 1)) - { - // Attempt to replicate vanilla behavior; Useodds 8 is set up like this. - SETUPDISTTABLE(j,1); - } - else - { - jj = max(1, ((j - 3) / tablediv) + 1); - - if (jj < 1) - { - jj = 1; - } - - //CONS_Printf("SETUPDISTTABLE(%d, %d)\n", j, jj); - - SETUPDISTTABLE(j,jj); - } - } - - /*SETUPDISTTABLE(0,1); - SETUPDISTTABLE(1,1); - SETUPDISTTABLE(2,1); - SETUPDISTTABLE(3,2); - SETUPDISTTABLE(4,2); - SETUPDISTTABLE(5,3); - SETUPDISTTABLE(6,3); - SETUPDISTTABLE(7,1);*/ - - pdis = K_ScaleItemDistance(pdis, pingame, spbrush); - - const INT32 usedistvar = FixedDiv(DISTVAR, oddsfac); - - if (player->bot && player->botvars.rival) - { - // Rival has better odds :) - pdis = (15 * pdis) / 14; - } - - if (pingame == 1 && oddsvalid[0]) - { - // Record Attack / FREE PLAY - useodds = 0; - } - else if (pdis <= 0) - { - // 1st place - useodds = disttable[0]; - } - else if (player->position == 2 && pdis > SPBFORCEDIST - && spbplace == -1 && !indirectitemcooldown && !dontforcespb) - { - // Force SPB in 2nd - useodds = 69; - } - - else if (pdis > (UINT32)DISTVAR * ((12 * distlen) / oddsdiv)) - { - // Back of the pack - useodds = disttable[distlen-1]; - } - else - { - for (i = 1; i < (oddsdiv - 1); i++) - { - INT32 distcalc = min(distlen-1, (i * distlen) / oddsdiv); - if (pdis <= (unsigned)(usedistvar * distcalc)) - { - useodds = disttable[distcalc]; - break; - } - } - } - } - -#undef SETUPDISTTABLE - - //CONS_Printf("Got useodds %d. (position: %d, distance: %u)\n", useodds, player->position, pdis); - - return useodds; -} - INT32 K_GetRollingRouletteItem(player_t *player) { static UINT8 translation[NUMKARTITEMS-1]; @@ -1279,6 +810,153 @@ INT32 K_GetRollingRouletteItem(player_t *player) return translation[(player->itemroulette % roulette_size) / 3]; } +UINT32 K_CalculateInitalPDIS(const player_t *player) +{ + UINT8 i; + UINT32 pdis = 0; + + if (!K_UsingLegacyCheckpoints()) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator + && players[i].position == 1) + { + // This player is first! Yay! + + if (player->distancetofinish <= players[i].distancetofinish) + { + // Guess you're in first / tied for first? + pdis = 0; + } + else + { + // Subtract 1st's distance from your distance, to get your distance from 1st! + pdis = player->distancetofinish - players[i].distancetofinish; + } + break; + } + } + } + else + { + SINT8 sortedPlayers[MAXPLAYERS]; + UINT8 sortLength = 0; + + memset(sortedPlayers, -1, sizeof(sortedPlayers)); + + if (player->mo != NULL && P_MobjWasRemoved(player->mo) == false) + { + // Sort all of the players ahead of you. + // Then tally up their distances in a conga line. + + // This will create a much more consistent item + // distance algorithm than the "spider web" thing + // that it was doing before. + + // Add yourself to the list. + // You'll always be the end of the list, + // so we can also calculate the length here. + sortedPlayers[ player->position - 1 ] = player - players; + sortLength = player->position; + + // Will only need to do this if there's goint to be + // more than yourself in the list. + if (sortLength > 1) + { + SINT8 firstIndex = -1; + SINT8 secondIndex = -1; + INT32 startFrom = INT32_MAX; + + // Add all of the other players. + for (i = 0; i < MAXPLAYERS; i++) + { + INT32 pos = INT32_MAX; + + if (!playeringame[i] || players[i].spectator) + { + continue; + } + + if (players[i].mo == NULL || P_MobjWasRemoved(players[i].mo) == true) + { + continue; + } + + pos = players[i].position; + + if (pos <= 0 || pos > MAXPLAYERS) + { + // Invalid position. + continue; + } + + if (pos >= player->position) + { + // Tied / behind us. + // Also handles ourselves, obviously. + continue; + } + + // Ties are done with port priority, if there are any. + if (sortedPlayers[ pos - 1 ] == -1) + { + sortedPlayers[ pos - 1 ] = i; + } + } + + // The chance of this list having gaps is improbable, + // but not impossible. So we need to spend some extra time + // to prevent the gaps from mattering. + for (i = 0; i < sortLength-1; i++) + { + if (sortedPlayers[i] >= 0 && sortedPlayers[i] < MAXPLAYERS) + { + // First valid index in the list found. + firstIndex = sortedPlayers[i]; + + // Start the next loop after this player. + startFrom = i + 1; + break; + } + } + + if (firstIndex >= 0 && firstIndex < MAXPLAYERS + && startFrom < sortLength) + { + // First index is valid, so we can + // start comparing the players. + + player_t *firstPlayer = NULL; + player_t *secondPlayer = NULL; + + for (i = startFrom; i < sortLength; i++) + { + if (sortedPlayers[i] >= 0 && sortedPlayers[i] < MAXPLAYERS) + { + secondIndex = sortedPlayers[i]; + + firstPlayer = &players[firstIndex]; + secondPlayer = &players[secondIndex]; + + // Add the distance to the player behind you. + pdis += P_AproxDistance(P_AproxDistance( + firstPlayer->mo->x - secondPlayer->mo->x, + firstPlayer->mo->y - secondPlayer->mo->y), + firstPlayer->mo->z - secondPlayer->mo->z) / FRACUNIT; + + // Advance to next index. + firstIndex = secondIndex; + } + } + } + } + } + } + + return pdis; +} + void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) { INT32 i; @@ -1341,50 +1019,23 @@ void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) else if (!(player->itemroulette >= (TICRATE*3))) return; - if (!(K_UsingLegacyCheckpoints())) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator - && players[i].position == 1) - { - // This player is first! Yay! - - if (player->distancetofinish <= players[i].distancetofinish) - { - // Guess you're in first / tied for first? - pdis = 0; - } - else - { - // Subtract 1st's distance from your distance, to get your distance from 1st! - pdis = player->distancetofinish - players[i].distancetofinish; - } - break; - } - } - } + pdis = K_CalculateInitalPDIS(player); if (spbplace != -1 && player->position == spbplace+1) { // SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell - if (!(K_UsingLegacyCheckpoints())) - pdis = (3 * pdis) / 2; + pdis = (3 * pdis) / 2; spbrush = true; } - if (!(K_UsingLegacyCheckpoints())) + pdis = K_ScaleItemDistance(pdis, pingame, spbrush); + + if (player->bot && player->botvars.rival) { - pdis = K_ScaleItemDistance(pdis, pingame, spbrush); - - if (player->bot && player->botvars.rival) - { - // Rival has better odds :) - pdis = (15 * pdis) / 14; - } + // Rival has better odds :) + pdis = (15 * pdis) / 14; } - // SPECIAL CASE No. 1: // Fake Eggman items if (player->roulettetype == KROULETTETYPE_EGGMAN) @@ -1502,38 +1153,11 @@ void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) } } - if (!(K_UsingLegacyCheckpoints())) - { - // SPECIAL CASE No. 6: - // Force SPB onto 2nd if they get too far behind - if ((gametyperules & GTR_CIRCUIT) && player->position == 2 && pdis > SPBFORCEDIST - && spbplace == -1 && !indirectitemcooldown && !dontforcespb - && cv_selfpropelledbomb.value) - { - K_KartGetItemResult(player, KITEM_SPB); - player->itemblink = TICRATE; - player->itemblinkmode = KITEMBLINKMODE_KARMA; - player->itemroulette = KROULETTE_DISABLED; - player->roulettetype = KROULETTETYPE_NORMAL; - if (P_IsDisplayPlayer(player)) - S_StartSound(NULL, sfx_itrolk); - return; - } - } - - // NOW that we're done with all of those specialized cases, we can move onto the REAL item roulette tables. - // Initializes existing spawnchance values - for (i = 0; i < NUMKARTRESULTS; i++) - spawnchance[i] = 0; - - // Split into another function for a debug function below - // Use a legacy version for maps not using waypoints. - if (K_UsingLegacyCheckpoints()) - useodds = K_FindLegacyUseodds(player, mashed, pingame, bestbumper, spbrush, dontforcespb); - else - useodds = K_FindUseodds(player, mashed, pdis, bestbumper, spbrush); - - if (useodds == 69) + // SPECIAL CASE No. 6: + // Force SPB onto 2nd if they get too far behind + if ((gametyperules & GTR_CIRCUIT) && player->position == 2 && pdis > SPBFORCEDIST + && spbplace == -1 && !indirectitemcooldown && !dontforcespb + && cv_selfpropelledbomb.value) { K_KartGetItemResult(player, KITEM_SPB); player->itemblink = TICRATE; @@ -1545,23 +1169,24 @@ void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) return; } + // NOW that we're done with all of those specialized cases, we can move onto the REAL item roulette tables. + // Initializes existing spawnchance values + for (i = 0; i < NUMKARTRESULTS; i++) + spawnchance[i] = 0; + + // Split into another function for a debug function below + useodds = K_FindUseodds(player, mashed, pdis, bestbumper, spbrush); + for (i = 1; i < NUMKARTRESULTS; i++) { - if (K_UsingLegacyCheckpoints()) - { - spawnchance[i] = (totalspawnchance += K_KartGetLegacyItemOdds(useodds, i, player->distancefromcluster, mashed, spbrush)); - } - else - { - spawnchance[i] = (totalspawnchance += K_KartGetItemOdds( - useodds, i, - player->distancetofinish, - player->distancefromcluster, - mashed, - spbrush, player->bot, (player->bot && player->botvars.rival)) - ); - } + spawnchance[i] = (totalspawnchance += K_KartGetItemOdds( + useodds, i, + player->distancetofinish, + player->distancefromcluster, + mashed, + spbrush, player->bot, (player->bot && player->botvars.rival)) + ); } // Award the player whatever power is rolled diff --git a/src/k_odds.h b/src/k_odds.h index 859d12d2b..3e8fc88bc 100644 --- a/src/k_odds.h +++ b/src/k_odds.h @@ -30,12 +30,10 @@ extern "C" { extern consvar_t *KartItemCVars[NUMKARTRESULTS-1]; +UINT32 K_CalculateInitalPDIS(const player_t *player); UINT8 K_FindUseodds(const player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper, boolean spbrush); -INT32 K_FindLegacyUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT32 bestbumper, boolean spbrush, boolean dontforcespb); -fixed_t K_ItemOddsScale(UINT8 numPlayers, boolean spbrush); UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers, boolean spbrush); INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, UINT32 clusterDist, fixed_t mashed, boolean spbrush, boolean bot, boolean rival); -INT32 K_KartGetLegacyItemOdds(UINT8 pos, SINT8 item, fixed_t clusterDist, fixed_t mashed, boolean spbrush); INT32 K_GetRollingRouletteItem(player_t *player); SINT8 K_ItemResultToType(SINT8 getitem); UINT8 K_ItemResultToAmount(SINT8 getitem);