Restore some Battle stuff

This commit is contained in:
Antonio Martinez 2024-08-20 23:28:27 -07:00
parent b3abb8ca37
commit 9e90cb80dd
3 changed files with 48 additions and 337 deletions

View file

@ -7413,8 +7413,32 @@ void K_DropHnextList(player_t *player)
SINT8 K_GetTotallyRandomResult(UINT8 useodds) SINT8 K_GetTotallyRandomResult(UINT8 useodds)
{ {
// TODO INT32 spawnchance[NUMKARTRESULTS];
return 0; 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) mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT16 amount)

View file

@ -181,41 +181,8 @@ static UINT32 K_DynamicItemOddsSpecial[NUMKARTRESULTS-1][2] =
{0, 0}, // triplegachabom {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, 1 }, // Sneaker
{ 0, 0 }, // Rocket Sneaker { 0, 0 }, // Rocket Sneaker
@ -249,40 +216,6 @@ static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS-1][2] =
{ 2, 0 } // Gachabom x3 { 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[] = static kartitems_t K_KartItemReelSpecialEnd[] =
{ {
KITEM_SUPERRING, 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. second place players.
Input Arguments:- Input Arguments:-
@ -702,7 +635,7 @@ static boolean K_DenyAutoRouletteOdds(kartitems_t item)
Return:- Return:-
New item odds. 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); I_Assert(roulette != NULL);
@ -728,273 +661,29 @@ static fixed_t K_AdjustSPBOdds(const itemroulette_t *roulette, UINT8 position)
multiplier = FRACUNIT; 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) INT32 K_KartGetBattleOdds(const player_t *player, UINT8 pos, kartitems_t item)
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)
See header file for description. 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; fixed_t newOdds = 0;
I_Assert(item > KITEM_NONE); // too many off by one scenarioes. I_Assert(item > KITEM_NONE); // too many off by one scenarioes.
I_Assert(item < NUMKARTRESULTS); I_Assert(item < NUMKARTRESULTS);
if (player != NULL) I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table
{ newOdds = K_KartLegacyBattleOdds[item-1][pos];
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];
}
newOdds <<= FRACBITS; 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; return newOdds;
} }
@ -1659,7 +1348,12 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet
if (gametyperules & GTR_CIRCUIT) if (gametyperules & GTR_CIRCUIT)
roulette->dist = FixedMul(roulette->preexpdist, max(player->exp, FRACUNIT/2)); 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 targetpower = roulette->dist; // fill roulette with items around this value!
UINT32 powers[NUMKARTRESULTS]; // how strong is each item? 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 rival = (player->bot && (player->botvars.rival || cv_levelskull.value));
boolean mothfilter = true; // strip unusually weak items from reel? boolean mothfilter = true; // strip unusually weak items from reel?
UINT8 reelsize = 15; UINT8 reelsize = 15; // How many items to attempt to add in prepass?
UINT32 humanscaler = 250; UINT32 humanscaler = 250; // Scaler that converts "useodds" style distances in odds tables to raw distances.
for (i = 0; i < MAXPLAYERS; ++i) 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 // temp - i have no fucking clue how pointers work i am so sorry
for (i = 1; i < NUMKARTRESULTS; i++) for (i = 1; i < NUMKARTRESULTS; i++)
{ {
// NOTE: Battle odds are underspecified, we don't invoke roulettes in this mode!
if (gametyperules & GTR_BUMPERS) if (gametyperules & GTR_BUMPERS)
{ {
powers[i] = humanscaler * K_DynamicItemOddsBattle[i-1][0]; powers[i] = humanscaler * K_DynamicItemOddsBattle[i-1][0];
@ -1860,11 +1555,6 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet
return; 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 // and insert all of our candidates into the roulette in a random order
while (totalSpawnChance > 0) while (totalSpawnChance > 0)
{ {

View file

@ -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 Gets legacy item priority.
an item bracket, and adjusted for special Currently used only for Battle monitors/spawners.
factors (such as Frantic Items).
Input Arguments:- Input Arguments:-
player - The player we intend to give the item to later. player - The player we intend to give the item to later.
Can be NULL for generic use. 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. pos - The item bracket we are in.
item - The item to give. item - The item to give.
@ -97,7 +94,7 @@ botItemPriority_e K_GetBotItemPriority(kartitems_t result);
into the roulette. 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);
/*-------------------------------------------------- /*--------------------------------------------------