From d57632e71e4d4e52fc0c7424ae4aa6cc9bced05d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Apr 2021 15:21:45 -0400 Subject: [PATCH 1/6] Change the scaling for different player counts Made more extreme for less than 8, made less extreme for more than 8. 2P: x1.25ish -> x2.5ish 16P: x0.68 -> x0.75 --- src/k_kart.c | 191 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 137 insertions(+), 54 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index e8cc80d7c..aa0834326 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -491,6 +491,57 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem) } } +static fixed_t K_ItemOddsScale(UINT8 numPlayers, boolean spbrush) +{ + const UINT8 basePlayer = 8; // The player count we design most of the game around. + UINT8 playerCount = (spbrush ? 2 : numPlayers); + fixed_t playerScaling = 0; + + // Then, it multiplies it further if the player count isn't equal to basePlayer. + // This is done to make low player count races more interesting and high player count rates more fair. + // (If you're in SPB mode and in 2nd place, it acts like it's a 1v1, so the catch-up game is not weakened.) + if (playerCount < basePlayer) + { + // Less than basePlayer: increase odds significantly. + // 2P: x2.5 + playerScaling = ((basePlayer - playerCount) * (basePlayer - playerCount)) * (FRACUNIT / 14); + } + else if (playerCount > basePlayer) + { + // More than basePlayer: reduce odds slightly. + // 16P: x0.75 + playerScaling = (basePlayer - playerCount) * (FRACUNIT / 32); + } + + return playerScaling; +} + +static UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers, boolean spbrush) +{ + if (mapobjectscale != FRACUNIT) + { + // Bring back to normal scale, so that + distance = FixedDiv(distance * FRACUNIT, mapobjectscale) / FRACUNIT; + } + + if (franticitems == true) + { + // Frantic items arbritrarily make distances shorter, for crazier items. + distance = (15 * distance) / 14; + } + + if (numPlayers > 0) + { + // Items get crazier with the fewer players that you have. + distance = FixedMul( + distance * FRACUNIT, + FRACUNIT + (K_ItemOddsScale(numPlayers, spbrush) / 2) + ) / FRACUNIT; + } + + return distance; +} + /** \brief Item Roulette for Kart \param player player object passed from P_KartPlayerThink @@ -502,9 +553,17 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, { INT32 newodds; INT32 i; + UINT8 pingame = 0, pexiting = 0; + SINT8 first = -1, second = -1; - INT32 secondist = 0; + UINT32 firstdist = UINT32_MAX; + UINT32 secondist = UINT32_MAX; + + boolean powerItem = false; + boolean cooldownOnStart = false; + boolean indirectItem = false; + INT32 shieldtype = KSHIELD_NONE; I_Assert(item > KITEM_NONE); // too many off by one scenarioes. @@ -557,35 +616,19 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, if (first != -1 && second != -1) // calculate 2nd's distance from 1st, for SPB { - secondist = players[second].distancetofinish - players[first].distancetofinish; - if (franticitems) - secondist = (15 * secondist) / 14; - secondist = ((28 + (8-pingame)) * secondist) / 28; + firstdist = players[first].distancetofinish; + + if (mapobjectscale != FRACUNIT) + { + firstdist = FixedDiv(firstdist * FRACUNIT, mapobjectscale) / FRACUNIT; + } + + secondist = K_ScaleItemDistance( + players[second].distancetofinish - players[first].distancetofinish, + pingame, spbrush + ); } - // POWERITEMODDS handles all of the "frantic item" related functionality, for all of our powerful items. - // First, it multiplies it by 2 if franticitems is true; easy-peasy. - // Next, it multiplies it again if it's in SPB mode and 2nd needs to apply pressure to 1st. - // Then, it multiplies it further if the player count isn't equal to 8. - // This is done to make low player count races more interesting and high player count rates more fair. - // (2P normal would be about halfway between 8P normal and 8P frantic.) - // (This scaling is not done for SPB Rush, so that catchup strength is not weakened.) - // Lastly, it *divides* it by your mashed value, which was determined in K_KartItemRoulette, for lesser items needed in a pinch. - -#define PLAYERSCALING (8 - (spbrush ? 2 : pingame)) - -#define POWERITEMODDS(odds) {\ - if (franticitems) \ - odds *= 2; \ - if (rival) \ - odds *= 2; \ - odds = FixedMul(odds * FRACUNIT, FRACUNIT + ((PLAYERSCALING * FRACUNIT) / 25)) / FRACUNIT; \ - if (mashed > 0) \ - odds = FixedDiv(odds * FRACUNIT, FRACUNIT + mashed) / FRACUNIT; \ -} - -#define COOLDOWNONSTART (leveltime < (30*TICRATE)+starttime) - /* if (bot) { @@ -640,21 +683,21 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, case KRITEM_TRIPLEORBINAUT: case KRITEM_QUADORBINAUT: case KRITEM_DUALJAWZ: - POWERITEMODDS(newodds); + powerItem = true; break; case KITEM_INVINCIBILITY: case KITEM_MINE: case KITEM_GROW: case KITEM_BUBBLESHIELD: case KITEM_FLAMESHIELD: - if (COOLDOWNONSTART) - newodds = 0; - else - POWERITEMODDS(newodds); + cooldownOnStart = true; + powerItem = true; break; case KITEM_SPB: - if ((indirectitemcooldown > 0) || COOLDOWNONSTART - || (first != -1 && players[first].distancetofinish < 8*DISTVAR)) // No SPB near the end of the race + cooldownOnStart = true; + indirectItem = true; + + if (firstdist < 8*DISTVAR) // No SPB near the end of the race { newodds = 0; } @@ -671,26 +714,73 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, } break; case KITEM_SHRINK: - if ((indirectitemcooldown > 0) || COOLDOWNONSTART || (pingame-1 <= pexiting)) + cooldownOnStart = true; + powerItem = true; + indirectItem = true; + + if (pingame-1 <= pexiting) newodds = 0; - else - POWERITEMODDS(newodds); break; case KITEM_THUNDERSHIELD: - if (spbplace != -1 || COOLDOWNONSTART) + cooldownOnStart = true; + powerItem = true; + + if (spbplace != -1) newodds = 0; - else - POWERITEMODDS(newodds); break; case KITEM_HYUDORO: - if ((hyubgone > 0) || COOLDOWNONSTART) + cooldownOnStart = true; + + if (hyubgone > 0) newodds = 0; break; default: break; } -#undef POWERITEMODDS + 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. + 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; + } + + if (rival == true) + { + // The Rival bot gets frantic-like items, also :p + 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; } @@ -872,28 +962,21 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) } } - if (mapobjectscale != FRACUNIT) - pdis = FixedDiv(pdis * FRACUNIT, mapobjectscale) / FRACUNIT; - - if (franticitems) // Frantic items make the distances between everyone artifically higher, for crazier items - { - pdis = (15 * pdis) / 14; - } - - 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 (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 pdis = (3 * pdis) / 2; spbrush = true; } + pdis = K_ScaleItemDistance(pdis, pingame, spbrush); + if (player->bot && player->botvars.rival) { // Rival has better odds :) pdis = (15 * pdis) / 14; } - pdis = ((28 + (8-pingame)) * pdis) / 28; // scale with player count - // SPECIAL CASE No. 1: // Fake Eggman items if (player->roulettetype == 2) From c99b1466ea7fb3e515194400ff80d75cd0864235 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Apr 2021 17:41:02 -0400 Subject: [PATCH 2/6] Fix comments --- src/k_kart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index aa0834326..52328502e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -520,13 +520,13 @@ static UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers, boolean spb { if (mapobjectscale != FRACUNIT) { - // Bring back to normal scale, so that + // Bring back to normal scale. distance = FixedDiv(distance * FRACUNIT, mapobjectscale) / FRACUNIT; } if (franticitems == true) { - // Frantic items arbritrarily make distances shorter, for crazier items. + // Frantic items pretends everyone's farther apart, for crazier items. distance = (15 * distance) / 14; } From 54bdea086a040c1046bb5fe39f30ed4d90c0543f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Apr 2021 20:03:01 -0400 Subject: [PATCH 3/6] SPB has rainbow item animation when forced onto you --- src/k_kart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 52328502e..4215fadd8 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1083,11 +1083,11 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) { K_KartGetItemResult(player, KITEM_SPB); player->karthud[khud_itemblink] = TICRATE; - player->karthud[khud_itemblinkmode] = (mashed ? 1 : 0); + player->karthud[khud_itemblinkmode] = 2; player->itemroulette = 0; player->roulettetype = 0; if (P_IsDisplayPlayer(player)) - S_StartSound(NULL, (mashed ? sfx_itrolm : sfx_itrolf)); + S_StartSound(NULL, sfx_itrolk); return; } From db43239ca37d280a9020a4ea0bf486e113531530 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 23 Apr 2021 20:57:14 -0400 Subject: [PATCH 4/6] Fix debug distribution crash --- src/k_hud.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/k_hud.c b/src/k_hud.c index c2b29fe3d..eb46d20e4 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4023,6 +4023,7 @@ static void K_drawDistributionDebugger(void) kp_superring[1], kp_kitchensink[1], + kp_sneaker[1], kp_sneaker[1], kp_banana[1], kp_banana[1], @@ -4105,6 +4106,9 @@ static void K_drawDistributionDebugger(void) case KRITEM_DUALJAWZ: amount = 2; break; + case KRITEM_DUALSNEAKER: + amount = 2; + break; default: amount = 3; break; From 2ea9164cb1fe82a1b81ddc36925d7a5fc6bc6296 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Apr 2021 00:14:14 -0400 Subject: [PATCH 5/6] Fix natural SPB, prevent getting bananas at the end of the race --- src/k_hud.c | 18 ++++--- src/k_kart.c | 148 ++++++++++++++++++++++++++++++--------------------- src/k_kart.h | 4 +- 3 files changed, 100 insertions(+), 70 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index eb46d20e4..d4910b524 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4063,28 +4063,32 @@ static void K_drawDistributionDebugger(void) } } - if (franticitems) // Frantic items make the distances between everyone artifically higher, for crazier items - pdis = (15 * pdis) / 14; - - if (spbplace != -1 && stplyr->position == spbplace+1) // SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell + if (spbplace != -1 && stplyr->position == spbplace+1) { + // SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell pdis = (3 * pdis) / 2; spbrush = true; } + pdis = K_ScaleItemDistance(pdis, pingame, spbrush); + if (stplyr->bot && stplyr->botvars.rival) { // Rival has better odds :) pdis = (15 * pdis) / 14; } - pdis = ((28 + (8-pingame)) * pdis) / 28; // scale with player count - useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper, spbrush); for (i = 1; i < NUMKARTRESULTS; i++) { - const INT32 itemodds = K_KartGetItemOdds(useodds, i, 0, spbrush, stplyr->bot, (stplyr->bot && stplyr->botvars.rival)); + INT32 itemodds = K_KartGetItemOdds( + useodds, i, + stplyr->distancetofinish, + 0, + spbrush, stplyr->bot, (stplyr->bot && stplyr->botvars.rival) + ); + if (itemodds <= 0) continue; diff --git a/src/k_kart.c b/src/k_kart.c index 4215fadd8..57eb7c40e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -348,7 +348,7 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS-1][8] = /*Mine*/ { 0, 2, 3, 1, 0, 0, 0, 0 }, // Mine /*Land Mine*/ { 4, 0, 0, 0, 0, 0, 0, 0 }, // Land Mine /*Ballhog*/ { 0, 0, 2, 1, 0, 0, 0, 0 }, // Ballhog - /*Self-Propelled Bomb*/ { 0, 1, 2, 3, 4, 2, 2, 0 }, // Self-Propelled Bomb + /*Self-Propelled Bomb*/ { 0, 0, 0, 0, 0, 2, 4, 0 }, // Self-Propelled Bomb /*Grow*/ { 0, 0, 0, 1, 2, 3, 0, 0 }, // Grow /*Shrink*/ { 0, 0, 0, 0, 0, 0, 2, 0 }, // Shrink /*Thunder Shield*/ { 1, 2, 0, 0, 0, 0, 0, 0 }, // Thunder Shield @@ -400,6 +400,9 @@ static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] = }; #define DISTVAR (2048) // Magic number distance for use with item roulette tiers +#define SPBSTARTDIST (5*DISTVAR) // Distance when SPB is forced onto 2nd place +#define SPBFORCEDIST (15*DISTVAR) // Distance when SPB is forced onto 2nd place +#define ENDDIST (12*DISTVAR) // Distance when the game stops giving you bananas // Array of states to pick the starting point of the animation, based on the actual time left for invincibility. static INT32 K_SparkleTrailStartStates[KART_NUMINVSPARKLESANIM][2] = { @@ -491,7 +494,7 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem) } } -static fixed_t K_ItemOddsScale(UINT8 numPlayers, boolean spbrush) +fixed_t K_ItemOddsScale(UINT8 numPlayers, boolean spbrush) { const UINT8 basePlayer = 8; // The player count we design most of the game around. UINT8 playerCount = (spbrush ? 2 : numPlayers); @@ -516,7 +519,7 @@ static fixed_t K_ItemOddsScale(UINT8 numPlayers, boolean spbrush) return playerScaling; } -static UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers, boolean spbrush) +UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers, boolean spbrush) { if (mapobjectscale != FRACUNIT) { @@ -549,7 +552,11 @@ static UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers, boolean spb \return void */ -INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, boolean bot, boolean rival) +INT32 K_KartGetItemOdds( + UINT8 pos, SINT8 item, + UINT32 ourDist, + fixed_t mashed, + boolean spbrush, boolean bot, boolean rival) { INT32 newodds; INT32 i; @@ -557,12 +564,13 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, UINT8 pingame = 0, pexiting = 0; SINT8 first = -1, second = -1; - UINT32 firstdist = UINT32_MAX; - UINT32 secondist = UINT32_MAX; + UINT32 firstDist = UINT32_MAX; + UINT32 secondToFirst = UINT32_MAX; boolean powerItem = false; boolean cooldownOnStart = false; boolean indirectItem = false; + boolean notNearEnd = false; INT32 shieldtype = KSHIELD_NONE; @@ -572,6 +580,24 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, if (!KartItemCVars[item-1]->value && !modeattacking) return 0; + /* + if (bot) + { + // TODO: Item use on bots should all be passed-in functions. + // Instead of manually inserting these, it should return 0 + // for any items without an item use function supplied + + switch (item) + { + case KITEM_SNEAKER: + break; + default: + return 0; + } + } + */ + (void)bot; + if (gametype == GT_BATTLE) { I_Assert(pos < 6); // DO NOT allow positions past the bounds of the table @@ -616,75 +642,41 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, if (first != -1 && second != -1) // calculate 2nd's distance from 1st, for SPB { - firstdist = players[first].distancetofinish; + firstDist = players[first].distancetofinish; if (mapobjectscale != FRACUNIT) { - firstdist = FixedDiv(firstdist * FRACUNIT, mapobjectscale) / FRACUNIT; + firstDist = FixedDiv(firstDist * FRACUNIT, mapobjectscale) / FRACUNIT; } - secondist = K_ScaleItemDistance( + secondToFirst = K_ScaleItemDistance( players[second].distancetofinish - players[first].distancetofinish, pingame, spbrush ); } - /* - if (bot) - { - // TODO: Item use on bots should all be passed-in functions. - // Instead of manually inserting these, it should return 0 - // for any items without an item use function supplied - - switch (item) - { - case KITEM_SNEAKER: - case KITEM_ROCKETSNEAKER: - case KITEM_INVINCIBILITY: - case KITEM_BANANA: - case KITEM_EGGMAN: - case KITEM_ORBINAUT: - case KITEM_JAWZ: - case KITEM_MINE: - case KITEM_LANDMINE: - case KITEM_BALLHOG: - case KITEM_SPB: - case KITEM_GROW: - case KITEM_SHRINK: - case KITEM_HYUDORO: - case KITEM_SUPERRING: - case KITEM_THUNDERSHIELD: - case KITEM_BUBBLESHIELD: - case KITEM_FLAMESHIELD: - case KRITEM_DUALSNEAKER: - case KRITEM_TRIPLESNEAKER: - case KRITEM_TRIPLEBANANA: - case KRITEM_TENFOLDBANANA: - case KRITEM_TRIPLEORBINAUT: - case KRITEM_QUADORBINAUT: - case KRITEM_DUALJAWZ: - break; - default: - return 0; - } - } - */ - (void)bot; - switch (item) { + case KITEM_BANANA: + case KITEM_EGGMAN: + case KITEM_SUPERRING: + notNearEnd = true; + break; case KITEM_ROCKETSNEAKER: case KITEM_JAWZ: case KITEM_LANDMINE: case KITEM_BALLHOG: case KRITEM_TRIPLESNEAKER: - case KRITEM_TRIPLEBANANA: - case KRITEM_TENFOLDBANANA: case KRITEM_TRIPLEORBINAUT: case KRITEM_QUADORBINAUT: case KRITEM_DUALJAWZ: powerItem = true; break; + case KRITEM_TRIPLEBANANA: + case KRITEM_TENFOLDBANANA: + powerItem = true; + notNearEnd = true; + break; case KITEM_INVINCIBILITY: case KITEM_MINE: case KITEM_GROW: @@ -696,19 +688,24 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, case KITEM_SPB: cooldownOnStart = true; indirectItem = true; + notNearEnd = true; - if (firstdist < 8*DISTVAR) // No SPB near the end of the race + if (firstDist < ENDDIST) // No SPB near the end of the race { newodds = 0; } else { - INT32 multiplier = (secondist - (5*DISTVAR)) / DISTVAR; + const INT32 distFromStart = max(0, secondToFirst - SPBSTARTDIST); + const INT32 distRange = SPBFORCEDIST - SPBSTARTDIST; + const INT32 mulMax = 3; + + INT32 multiplier = (distFromStart * mulMax) / distRange; if (multiplier < 0) multiplier = 0; - if (multiplier > 3) - multiplier = 3; + if (multiplier > mulMax) + multiplier = mulMax; newodds *= multiplier; } @@ -717,6 +714,7 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, cooldownOnStart = true; powerItem = true; indirectItem = true; + notNearEnd = true; if (pingame-1 <= pexiting) newodds = 0; @@ -730,6 +728,7 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, break; case KITEM_HYUDORO: cooldownOnStart = true; + notNearEnd = true; if (hyubgone > 0) newodds = 0; @@ -751,7 +750,12 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, } else if ((cooldownOnStart == true) && (leveltime < (30*TICRATE)+starttime)) { - // This item should not appear at the beginning of a race. + // 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)) + { + // This item should not appear at the end of a race. (Usually trap items that lose their effectiveness) newodds = 0; } else if (powerItem == true) @@ -811,7 +815,12 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum for (j = 1; j < NUMKARTRESULTS; j++) { - if (K_KartGetItemOdds(i, j, mashed, spbrush, player->bot, (player->bot && player->botvars.rival)) > 0) + if (K_KartGetItemOdds( + i, j, + player->distancetofinish, + mashed, + spbrush, player->bot, (player->bot && player->botvars.rival) + ) > 0) { available = true; break; @@ -1077,7 +1086,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) // SPECIAL CASE No. 5: // Force SPB onto 2nd if they get too far behind - if ((gametyperules & GTR_CIRCUIT) && player->position == 2 && pdis > (DISTVAR*8) + if ((gametyperules & GTR_CIRCUIT) && player->position == 2 && pdis > SPBFORCEDIST && spbplace == -1 && !indirectitemcooldown && !dontforcespb && cv_selfpropelledbomb.value) { @@ -1100,7 +1109,14 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) useodds = K_FindUseodds(player, mashed, pdis, bestbumper, spbrush); for (i = 1; i < NUMKARTRESULTS; i++) - spawnchance[i] = (totalspawnchance += K_KartGetItemOdds(useodds, i, mashed, spbrush, player->bot, (player->bot && player->botvars.rival))); + { + spawnchance[i] = (totalspawnchance += K_KartGetItemOdds( + useodds, i, + player->distancetofinish, + mashed, + spbrush, player->bot, (player->bot && player->botvars.rival)) + ); + } // Award the player whatever power is rolled if (totalspawnchance > 0) @@ -5374,7 +5390,15 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 useodds = amount; for (i = 1; i < NUMKARTRESULTS; i++) - spawnchance[i] = (totalspawnchance += K_KartGetItemOdds(useodds, i, 0, false, false, false)); + { + spawnchance[i] = (totalspawnchance += K_KartGetItemOdds( + useodds, i, + UINT32_MAX, + 0, + false, false, false + ) + ); + } if (totalspawnchance > 0) { diff --git a/src/k_kart.h b/src/k_kart.h index d0668450e..7299ac765 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -34,7 +34,9 @@ fixed_t K_GetKartGameSpeedScalar(SINT8 value); extern consvar_t *KartItemCVars[NUMKARTRESULTS-1]; UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper, boolean spbrush); -INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, boolean bot, boolean rival); +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, fixed_t mashed, boolean spbrush, boolean bot, boolean rival); INT32 K_GetShieldFromItem(INT32 item); fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against); boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2); From 9504b6011e4c01ef93637a6ef266aeb0dbd83298 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Apr 2021 00:16:57 -0400 Subject: [PATCH 6/6] Make it linear instead of exponential --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 57eb7c40e..c78d094e7 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -507,7 +507,7 @@ fixed_t K_ItemOddsScale(UINT8 numPlayers, boolean spbrush) { // Less than basePlayer: increase odds significantly. // 2P: x2.5 - playerScaling = ((basePlayer - playerCount) * (basePlayer - playerCount)) * (FRACUNIT / 14); + playerScaling = (basePlayer - playerCount) * (FRACUNIT / 4); } else if (playerCount > basePlayer) {