From 9e90cb80dddff777f79f62b8f03050fc8979d495 Mon Sep 17 00:00:00 2001 From: Antonio Martinez Date: Tue, 20 Aug 2024 23:28:27 -0700 Subject: [PATCH] Restore some Battle stuff --- src/k_kart.c | 28 +++- src/k_roulette.c | 346 +++-------------------------------------------- src/k_roulette.h | 11 +- 3 files changed, 48 insertions(+), 337 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 6e2bd674b..d16b3604c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7413,8 +7413,32 @@ void K_DropHnextList(player_t *player) SINT8 K_GetTotallyRandomResult(UINT8 useodds) { - // TODO - return 0; + INT32 spawnchance[NUMKARTRESULTS]; + INT32 totalspawnchance = 0; + INT32 i; + + memset(spawnchance, 0, sizeof (spawnchance)); + + for (i = 1; i < NUMKARTRESULTS; i++) + { + // Avoid calling K_FillItemRouletteData since that + // function resets PR_ITEM_ROULETTE. + spawnchance[i] = ( + totalspawnchance += K_KartGetBattleOdds(NULL, useodds, i) + ); + } + + if (totalspawnchance > 0) + { + totalspawnchance = P_RandomKey(PR_ITEM_ROULETTE, totalspawnchance); + for (i = 0; i < NUMKARTRESULTS && spawnchance[i] <= totalspawnchance; i++); + } + else + { + i = KITEM_SAD; + } + + return i; } mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT16 amount) diff --git a/src/k_roulette.c b/src/k_roulette.c index 4c66b3291..5d67884c4 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -181,41 +181,8 @@ static UINT32 K_DynamicItemOddsSpecial[NUMKARTRESULTS-1][2] = {0, 0}, // triplegachabom }; -static UINT8 K_KartItemOddsRace[NUMKARTRESULTS-1][8] = -{ - { 0, 0, 2, 3, 4, 0, 0, 0 }, // Sneaker - { 0, 0, 0, 0, 0, 3, 4, 5 }, // Rocket Sneaker - { 0, 0, 0, 0, 2, 5, 5, 7 }, // Invincibility - { 2, 3, 1, 0, 0, 0, 0, 0 }, // Banana - { 1, 2, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor - { 5, 5, 2, 2, 0, 0, 0, 0 }, // Orbinaut - { 0, 4, 2, 1, 0, 0, 0, 0 }, // Jawz - { 0, 3, 3, 2, 0, 0, 0, 0 }, // Mine - { 3, 0, 0, 0, 0, 0, 0, 0 }, // Land Mine - { 0, 0, 2, 2, 0, 0, 0, 0 }, // Ballhog - { 0, 0, 0, 0, 0, 2, 4, 0 }, // Self-Propelled Bomb - { 0, 0, 0, 0, 2, 5, 0, 0 }, // Grow - { 0, 0, 0, 0, 0, 2, 4, 2 }, // Shrink - { 1, 0, 0, 0, 0, 0, 0, 0 }, // Lightning Shield - { 0, 1, 2, 1, 0, 0, 0, 0 }, // Bubble Shield - { 0, 0, 0, 0, 0, 1, 3, 5 }, // Flame Shield - { 3, 0, 0, 0, 0, 0, 0, 0 }, // Hyudoro - { 0, 0, 0, 0, 0, 0, 0, 0 }, // Pogo Spring - { 2, 1, 1, 0, 0, 0, 0, 0 }, // Super Ring - { 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink - { 3, 0, 0, 0, 0, 0, 0, 0 }, // Drop Target - { 0, 0, 0, 1, 2, 2, 0, 0 }, // Garden Top - { 0, 0, 0, 0, 0, 0, 0, 0 }, // Gachabom - { 0, 0, 2, 3, 3, 1, 0, 0 }, // Sneaker x2 - { 0, 0, 0, 0, 4, 4, 4, 0 }, // Sneaker x3 - { 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3 - { 0, 0, 1, 0, 0, 0, 0, 0 }, // Orbinaut x3 - { 0, 0, 0, 2, 0, 0, 0, 0 }, // Orbinaut x4 - { 0, 0, 1, 2, 1, 0, 0, 0 }, // Jawz x2 - { 0, 0, 0, 0, 0, 0, 0, 0 } // Gachabom x3 -}; -static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS-1][2] = +static UINT8 K_KartLegacyBattleOdds[NUMKARTRESULTS-1][2] = { { 0, 1 }, // Sneaker { 0, 0 }, // Rocket Sneaker @@ -249,40 +216,6 @@ static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS-1][2] = { 2, 0 } // Gachabom x3 }; -static UINT8 K_KartItemOddsSpecial[NUMKARTRESULTS-1][4] = -{ - { 1, 1, 0, 0 }, // Sneaker - { 0, 0, 0, 0 }, // Rocket Sneaker - { 0, 0, 0, 0 }, // Invincibility - { 0, 0, 0, 0 }, // Banana - { 0, 0, 0, 0 }, // Eggman Monitor - { 1, 1, 1, 0 }, // Orbinaut - { 1, 1, 0, 0 }, // Jawz - { 0, 0, 0, 0 }, // Mine - { 0, 0, 0, 0 }, // Land Mine - { 0, 0, 0, 0 }, // Ballhog - { 0, 0, 0, 1 }, // Self-Propelled Bomb - { 0, 0, 0, 0 }, // Grow - { 0, 0, 0, 0 }, // Shrink - { 0, 0, 0, 0 }, // Lightning Shield - { 0, 0, 0, 0 }, // Bubble Shield - { 0, 0, 0, 0 }, // Flame Shield - { 0, 0, 0, 0 }, // Hyudoro - { 0, 0, 0, 0 }, // Pogo Spring - { 0, 0, 0, 0 }, // Super Ring - { 0, 0, 0, 0 }, // Kitchen Sink - { 0, 0, 0, 0 }, // Drop Target - { 0, 0, 0, 0 }, // Garden Top - { 0, 0, 0, 0 }, // Gachabom - { 0, 0, 1, 1 }, // Sneaker x2 - { 0, 0, 0, 0 }, // Sneaker x3 - { 0, 0, 0, 0 }, // Banana x3 - { 0, 0, 1, 1 }, // Orbinaut x3 - { 0, 0, 0, 0 }, // Orbinaut x4 - { 0, 0, 1, 1 }, // Jawz x2 - { 0, 0, 0, 0 } // Gachabom x3 -}; - static kartitems_t K_KartItemReelSpecialEnd[] = { KITEM_SUPERRING, @@ -688,9 +621,9 @@ static boolean K_DenyAutoRouletteOdds(kartitems_t item) } /*-------------------------------------------------- - static fixed_t K_AdjustSPBOdds(const itemroulette_t *roulette, UINT8 position) + static fixed_t K_PercentSPBOdds(const itemroulette_t *roulette, UINT8 position) - Adjust odds of SPB according to distances of first and + Provide odds of SPB according to distances of first and second place players. Input Arguments:- @@ -702,7 +635,7 @@ static boolean K_DenyAutoRouletteOdds(kartitems_t item) Return:- New item odds. --------------------------------------------------*/ -static fixed_t K_AdjustSPBOdds(const itemroulette_t *roulette, UINT8 position) +static fixed_t K_PercentSPBOdds(const itemroulette_t *roulette, UINT8 position) { I_Assert(roulette != NULL); @@ -728,273 +661,29 @@ static fixed_t K_AdjustSPBOdds(const itemroulette_t *roulette, UINT8 position) multiplier = FRACUNIT; } - return FixedMul(maxOdds, multiplier); + return multiplier; } } -typedef struct { - boolean powerItem; - boolean cooldownOnStart; - boolean notNearEnd; - - // gameplay state - boolean rival; // player is a bot Rival -} itemconditions_t; /*-------------------------------------------------- - static fixed_t K_AdjustItemOddsToConditions(fixed_t newOdds, const itemconditions_t *conditions, const itemroulette_t *roulette) - - Adjust item odds to certain group conditions. - - Input Arguments:- - newOdds - The item odds to adjust. - conditions - The conditions state. - roulette - The roulette data that we intend to - insert this item into. - - Return:- - New item odds. ---------------------------------------------------*/ -static fixed_t K_AdjustItemOddsToConditions(fixed_t newOdds, const itemconditions_t *conditions, const itemroulette_t *roulette) -{ - // TODO - return newOdds; - - // None if this applies outside of Race modes (for now?) - if ((gametyperules & GTR_CIRCUIT) == 0) - { - return newOdds; - } - - if ((conditions->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 ((conditions->notNearEnd == true) && (roulette != NULL && roulette->baseDist < ENDDIST)) - { - // This item should not appear at the end of a race. (Usually trap items that lose their effectiveness) - newOdds = 0; - } - else if (conditions->powerItem == true) - { - // This item is a "power item". This activates "frantic item" toggle related functionality. - if (franticitems == true) - { - // First, power items multiply their odds by 2 if frantic items are on; easy-peasy. - newOdds *= 2; - } - - if (conditions->rival == true) - { - // The Rival bot gets frantic-like items, also :p - newOdds *= 2; - } - - if (roulette != NULL) - { - newOdds = FixedMul(newOdds, FRACUNIT + K_ItemOddsScale(roulette->playing)); - } - } - - return newOdds; -} - -/*-------------------------------------------------- - INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item) + INT32 K_KartGetBattleOdds(const player_t *player, UINT8 pos, kartitems_t item) See header file for description. --------------------------------------------------*/ -INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item) +INT32 K_KartGetBattleOdds(const player_t *player, UINT8 pos, kartitems_t item) { - boolean bot = false; - UINT8 position = 0; - - itemconditions_t conditions = { - .powerItem = false, - .cooldownOnStart = false, - .notNearEnd = false, - .rival = false, - }; - fixed_t newOdds = 0; I_Assert(item > KITEM_NONE); // too many off by one scenarioes. I_Assert(item < NUMKARTRESULTS); - if (player != NULL) - { - bot = player->bot; - conditions.rival = (bot == true && (player->botvars.rival || cv_levelskull.value)); - position = player->position; - } - - if (K_ItemEnabled(item) == false) - { - return 0; - } - - if (K_GetItemCooldown(item) > 0) - { - // Cooldown is still running, don't give another. - 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 (K_DenyShieldOdds(item)) - { - return 0; - } - - if (roulette && roulette->autoroulette == true) - { - if (K_DenyAutoRouletteOdds(item)) - { - return 0; - } - } - - if (gametype == GT_BATTLE) - { - I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table - newOdds = K_KartItemOddsBattle[item-1][pos]; - } - else if (specialstageinfo.valid == true) - { - I_Assert(pos < 4); // Ditto - newOdds = K_KartItemOddsSpecial[item-1][pos]; - } - else - { - I_Assert(pos < 8); // Ditto - newOdds = K_KartItemOddsRace[item-1][pos]; - } + I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table + newOdds = K_KartLegacyBattleOdds[item-1][pos]; newOdds <<= FRACBITS; - switch (item) - { - case KITEM_BANANA: - case KITEM_EGGMAN: - case KITEM_SUPERRING: - { - conditions.notNearEnd = true; - break; - } - - case KITEM_ROCKETSNEAKER: - case KITEM_JAWZ: - case KITEM_LANDMINE: - case KITEM_DROPTARGET: - case KITEM_BALLHOG: - case KRITEM_TRIPLESNEAKER: - case KRITEM_TRIPLEORBINAUT: - case KRITEM_QUADORBINAUT: - case KRITEM_DUALJAWZ: - { - conditions.powerItem = true; - break; - } - - case KITEM_HYUDORO: - case KRITEM_TRIPLEBANANA: - { - conditions.powerItem = true; - conditions.notNearEnd = true; - break; - } - - case KITEM_INVINCIBILITY: - case KITEM_MINE: - case KITEM_GROW: - case KITEM_BUBBLESHIELD: - { - conditions.cooldownOnStart = true; - conditions.powerItem = true; - break; - } - - case KITEM_FLAMESHIELD: - case KITEM_GARDENTOP: - { - conditions.cooldownOnStart = true; - conditions.powerItem = true; - conditions.notNearEnd = true; - break; - } - - case KITEM_SPB: - { - conditions.cooldownOnStart = true; - conditions.notNearEnd = true; - - if (roulette != NULL && - (gametyperules & GTR_CIRCUIT) && - specialstageinfo.valid == false) - { - newOdds = K_AdjustSPBOdds(roulette, position); - } - break; - } - - case KITEM_SHRINK: - { - conditions.cooldownOnStart = true; - conditions.powerItem = true; - conditions.notNearEnd = true; - - if (roulette != NULL && - (gametyperules & GTR_CIRCUIT) && - roulette->playing - 1 <= roulette->exiting) - { - return 0; - } - break; - } - - case KITEM_LIGHTNINGSHIELD: - { - conditions.cooldownOnStart = true; - conditions.powerItem = true; - - if ((gametyperules & GTR_CIRCUIT) && spbplace != -1) - { - return 0; - } - break; - } - - default: - { - break; - } - } - - if (newOdds == 0) - { - // Nothing else we want to do with odds matters at this point :p - return newOdds; - } - - newOdds = FixedInt(FixedRound(K_AdjustItemOddsToConditions(newOdds, &conditions, roulette))); return newOdds; } @@ -1659,7 +1348,12 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet if (gametyperules & GTR_CIRCUIT) roulette->dist = FixedMul(roulette->preexpdist, max(player->exp, FRACUNIT/2)); - // == EVERYTHING FUCKED BELOW THIS LINE + // Dynamic Roulette. Oh boy! + + // STAGE 1: Determine what items are permissible + // STAGE 2: Determine the item that's most appropriate for our distance from leader + // STAGE 3: Pick that item, then penalize it + // STAGE 4: Repeat 3 until the reel is full, then cram everything in UINT32 targetpower = roulette->dist; // fill roulette with items around this value! UINT32 powers[NUMKARTRESULTS]; // how strong is each item? @@ -1670,8 +1364,8 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet boolean rival = (player->bot && (player->botvars.rival || cv_levelskull.value)); boolean mothfilter = true; // strip unusually weak items from reel? - UINT8 reelsize = 15; - UINT32 humanscaler = 250; + UINT8 reelsize = 15; // How many items to attempt to add in prepass? + UINT32 humanscaler = 250; // Scaler that converts "useodds" style distances in odds tables to raw distances. for (i = 0; i < MAXPLAYERS; ++i) { @@ -1697,6 +1391,7 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet // temp - i have no fucking clue how pointers work i am so sorry for (i = 1; i < NUMKARTRESULTS; i++) { + // NOTE: Battle odds are underspecified, we don't invoke roulettes in this mode! if (gametyperules & GTR_BUMPERS) { powers[i] = humanscaler * K_DynamicItemOddsBattle[i-1][0]; @@ -1860,11 +1555,6 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet return; } - /* - if (cv_kartdebugdistribution.value) - P_SetRandSeed(PR_ITEM_ROULETTE, ITEM_REEL_SEED); - */ - // and insert all of our candidates into the roulette in a random order while (totalSpawnChance > 0) { diff --git a/src/k_roulette.h b/src/k_roulette.h index 058562cb6..f05354e93 100644 --- a/src/k_roulette.h +++ b/src/k_roulette.h @@ -78,17 +78,14 @@ botItemPriority_e K_GetBotItemPriority(kartitems_t result); /*-------------------------------------------------- - INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); + INT32 K_KartGetBattleOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); - Gets the frequency an item should show up in - an item bracket, and adjusted for special - factors (such as Frantic Items). + Gets legacy item priority. + Currently used only for Battle monitors/spawners. Input Arguments:- player - The player we intend to give the item to later. Can be NULL for generic use. - roulette - The roulette data that we intend to - insert this item into. pos - The item bracket we are in. item - The item to give. @@ -97,7 +94,7 @@ botItemPriority_e K_GetBotItemPriority(kartitems_t result); into the roulette. --------------------------------------------------*/ -INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); +INT32 K_KartGetBattleOdds(const player_t *player, UINT8 pos, kartitems_t item); /*--------------------------------------------------