From b55d299fdbb7b8bf0a7b962af34c22f31fb0c9f2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 22 Nov 2022 00:39:53 -0500 Subject: [PATCH] Implement the Special Stage item table --- src/k_hud.c | 20 +---- src/k_kart.c | 196 +++++++++++++++++++++++++++++++--------------- src/k_kart.h | 1 + src/k_objects.h | 1 + src/objects/ufo.c | 14 ++++ 5 files changed, 149 insertions(+), 83 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 4a5644442..6a79a94e1 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4570,25 +4570,7 @@ static void K_drawDistributionDebugger(void) bestbumper = players[i].bumpers; } - // 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; - } - } - - pdis = K_ScaleItemDistance(pdis, pingame); - - if (stplyr->bot && stplyr->botvars.rival) - { - // Rival has better odds :) - pdis = (15 * pdis) / 14; - } + pdis = K_GetItemRouletteDistance(stplyr, pingame); useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper); diff --git a/src/k_kart.c b/src/k_kart.c index f781c64cb..2505d7ea8 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -485,8 +485,6 @@ static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS][2] = { 5, 1 } // Jawz x2 }; -// TODO: add back when this gets used -#if 0 static UINT8 K_KartItemOddsSpecial[NUMKARTRESULTS-1][4] = { //M N O P @@ -519,7 +517,6 @@ static UINT8 K_KartItemOddsSpecial[NUMKARTRESULTS-1][4] = { 0, 0, 1, 1 }, // Orbinaut x4 { 0, 0, 1, 1 } // Jawz x2 }; -#endif #define DISTVAR (2048) // Magic number distance for use with item roulette tiers #define SPBSTARTDIST (6*DISTVAR) // Distance when SPB can start appearing @@ -797,6 +794,11 @@ INT32 K_KartGetItemOdds( I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table newodds = K_KartItemOddsBattle[item-1][pos]; } + else if (specialStage.active == true) + { + I_Assert(pos < 4); // Ditto + newodds = K_KartItemOddsSpecial[item-1][pos]; + } else { I_Assert(pos < 8); // Ditto @@ -902,29 +904,32 @@ INT32 K_KartGetItemOdds( cooldownOnStart = true; notNearEnd = true; - if (firstDist < ENDDIST*2 // No SPB when 1st is almost done - || isFirst == true) // No SPB for 1st ever + if (specialStage.active == false) { - newodds = 0; - } - else - { - const UINT32 dist = max(0, ((signed)secondToFirst) - SPBSTARTDIST); - const UINT32 distRange = SPBFORCEDIST - SPBSTARTDIST; - const UINT8 maxOdds = 20; - fixed_t multiplier = (dist * FRACUNIT) / distRange; - - if (multiplier < 0) + if (firstDist < ENDDIST*2 // No SPB when 1st is almost done + || isFirst == true) // No SPB for 1st ever { - multiplier = 0; + newodds = 0; } - - if (multiplier > FRACUNIT) + else { - multiplier = FRACUNIT; - } + const UINT32 dist = max(0, ((signed)secondToFirst) - SPBSTARTDIST); + const UINT32 distRange = SPBFORCEDIST - SPBSTARTDIST; + const UINT8 maxOdds = 20; + fixed_t multiplier = (dist * FRACUNIT) / distRange; - newodds = FixedMul(maxOdds * 4, multiplier); + if (multiplier < 0) + { + multiplier = 0; + } + + if (multiplier > FRACUNIT) + { + multiplier = FRACUNIT; + } + + newodds = FixedMul(maxOdds * 4, multiplier); + } } break; @@ -1005,6 +1010,7 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum UINT8 useodds = 0; UINT8 disttable[14]; UINT8 distlen = 0; + UINT8 totalsize = 0; boolean oddsvalid[8]; // Unused now, oops :V @@ -1015,10 +1021,15 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum UINT8 j; boolean available = false; - if (gametype == GT_BATTLE && i > 1) + if (specialStage.active == true && i > 3) { oddsvalid[i] = false; - break; + continue; + } + else if (gametype == GT_BATTLE && i > 1) + { + oddsvalid[i] = false; + continue; } for (j = 1; j < NUMKARTRESULTS; j++) @@ -1039,6 +1050,7 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum } #define SETUPDISTTABLE(odds, num) \ + totalsize++;\ if (oddsvalid[odds]) \ for (i = num; i; --i) \ disttable[distlen++] = odds; @@ -1063,26 +1075,44 @@ UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbum } else { - SETUPDISTTABLE(0,1); - SETUPDISTTABLE(1,1); - SETUPDISTTABLE(2,1); - SETUPDISTTABLE(3,2); - SETUPDISTTABLE(4,2); - SETUPDISTTABLE(5,3); - SETUPDISTTABLE(6,3); - SETUPDISTTABLE(7,1); + UINT32 itotaldis = 0; + + if (specialStage.active == true) // Special Stages + { + SETUPDISTTABLE(0,1); + SETUPDISTTABLE(1,2); + SETUPDISTTABLE(2,3); + SETUPDISTTABLE(3,1); + } + else // Race + { + SETUPDISTTABLE(0,1); + SETUPDISTTABLE(1,1); + SETUPDISTTABLE(2,1); + SETUPDISTTABLE(3,2); + SETUPDISTTABLE(4,2); + SETUPDISTTABLE(5,3); + SETUPDISTTABLE(6,3); + SETUPDISTTABLE(7,1); + } + + itotaldis = DISTVAR * (((totalsize - 2) * distlen) / totalsize); if (pdis == 0) + { useodds = disttable[0]; - else if (pdis > DISTVAR * ((12 * distlen) / 14)) + } + else if (pdis > itotaldis) + { useodds = disttable[distlen-1]; + } else { - for (i = 1; i < 13; i++) + for (i = 1; i < totalsize-1; i++) { - if (pdis <= DISTVAR * ((i * distlen) / 14)) + if (pdis <= DISTVAR * ((i * distlen) / totalsize)) { - useodds = disttable[((i * distlen) / 14)]; + useodds = disttable[((i * distlen) / totalsize)]; break; } } @@ -1118,6 +1148,11 @@ INT32 K_GetRollingRouletteItem(player_t *player) odds_row = K_KartItemOddsBattle[0]; odds_row_size = sizeof K_KartItemOddsBattle[0]; } + else if (specialStage.active == true) + { + odds_row = K_KartItemOddsSpecial[0]; + odds_row_size = sizeof K_KartItemOddsSpecial[0]; + } else { odds_row = K_KartItemOddsRace[0]; @@ -1160,6 +1195,11 @@ boolean K_ForcedSPB(player_t *player) return false; } + if (specialStage.active == true) + { + return false; + } + if (player->position <= 1) { return false; @@ -1216,6 +1256,61 @@ boolean K_ForcedSPB(player_t *player) return (secondToFirst >= SPBFORCEDIST); } +UINT32 K_GetItemRouletteDistance(player_t *player, UINT8 pingame) +{ + UINT32 pdis = 0; + + if (specialStage.active == true) + { + UINT32 ufoDis = K_GetSpecialUFODistance(); + + if (player->distancetofinish <= ufoDis) + { + // You're ahead of the UFO. + pdis = 0; + } + else + { + // Subtract the UFO's distance from your distance! + pdis = player->distancetofinish - ufoDis; + } + } + else + { + UINT8 i; + 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_ScaleItemDistance(pdis, pingame); + + if (player->bot && player->botvars.rival) + { + // Rival has better odds :) + pdis = (15 * pdis) / 14; + } + + return pdis; +} + static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) { INT32 i; @@ -1271,34 +1366,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) else if (!(player->itemroulette >= (TICRATE*3))) return; - 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_ScaleItemDistance(pdis, pingame); - - if (player->bot && player->botvars.rival) - { - // Rival has better odds :) - pdis = (15 * pdis) / 14; - } + pdis = K_GetItemRouletteDistance(player, pingame); // SPECIAL CASE No. 1: // Fake Eggman items @@ -1331,7 +1399,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) // SPECIAL CASE No. 3: // Record Attack / alone mashing behavior - if (modeattacking || pingame == 1) + if ((modeattacking || pingame == 1) && (specialStage.active == false)) { if (gametype == GT_RACE) { diff --git a/src/k_kart.h b/src/k_kart.h index a5d2b0185..b12da338e 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -55,6 +55,7 @@ UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers); INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, fixed_t mashed, boolean bot, boolean rival); INT32 K_GetRollingRouletteItem(player_t *player); boolean K_ForcedSPB(player_t *player); +UINT32 K_GetItemRouletteDistance(player_t *player, UINT8 pingame); INT32 K_GetShieldFromItem(INT32 item); SINT8 K_ItemResultToType(SINT8 getitem); UINT8 K_ItemResultToAmount(SINT8 getitem); diff --git a/src/k_objects.h b/src/k_objects.h index 127435c91..7564fcc20 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -57,5 +57,6 @@ void Obj_DuelBombInit(mobj_t *bomb); /* Special Stage UFO */ void Obj_SpecialUFOThinker(mobj_t *bomb); mobj_t *Obj_CreateSpecialUFO(void); +UINT32 K_GetSpecialUFODistance(void); #endif/*k_objects_H*/ diff --git a/src/objects/ufo.c b/src/objects/ufo.c index 8b5dfaf6a..3d2ad68d7 100644 --- a/src/objects/ufo.c +++ b/src/objects/ufo.c @@ -22,6 +22,7 @@ #include "../g_game.h" #include "../z_zone.h" #include "../k_waypoint.h" +#include "../k_specialstage.h" #define UFO_BASE_SPEED (12 * FRACUNIT) // UFO's slowest speed. #define UFO_SPEEDUP (FRACUNIT) @@ -373,3 +374,16 @@ mobj_t *Obj_CreateSpecialUFO(void) return InitSpecialUFO(startWaypoint); } + +UINT32 K_GetSpecialUFODistance(void) +{ + if (specialStage.active == true) + { + if (specialStage.ufo != NULL && P_MobjWasRemoved(specialStage.ufo) == false) + { + return (UINT32)ufo_distancetofinish(specialStage.ufo); + } + } + + return UINT32_MAX; +}