mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-28 04:51:42 +00:00
WIP - Dynamic Roulette
This commit is contained in:
parent
b51f4d28a9
commit
b388c48be7
4 changed files with 403 additions and 151 deletions
|
|
@ -819,7 +819,7 @@ consvar_t cv_fuzz = OnlineCheat("fuzz", "Off").on_off().description("Human playe
|
||||||
|
|
||||||
consvar_t cv_kartdebugamount = OnlineCheat("debugitemamount", "1").min_max(1, 255).description("If debugitem, give multiple copies of an item");
|
consvar_t cv_kartdebugamount = OnlineCheat("debugitemamount", "1").min_max(1, 255).description("If debugitem, give multiple copies of an item");
|
||||||
consvar_t cv_kartdebugbots = OnlineCheat("debugbots", "Off").on_off().description("Bot AI debugger");
|
consvar_t cv_kartdebugbots = OnlineCheat("debugbots", "Off").on_off().description("Bot AI debugger");
|
||||||
consvar_t cv_kartdebugdistribution = OnlineCheat("debugitemodds", "Off").on_off().description("Show items that the roulette can roll");
|
consvar_t cv_kartdebugdistribution = OnlineCheat("debugitemodds", "0").min_max(0, 2).description("Show items that the roulette can roll");
|
||||||
consvar_t cv_kartdebughuddrop = OnlineCheat("debugitemdrop", "Off").on_off().description("Players drop paper items when damaged in any way");
|
consvar_t cv_kartdebughuddrop = OnlineCheat("debugitemdrop", "Off").on_off().description("Players drop paper items when damaged in any way");
|
||||||
|
|
||||||
consvar_t cv_kartdebugbotwhip = OnlineCheat("debugbotwhip", "Off").on_off().description("Disable bot ring and item pickups");
|
consvar_t cv_kartdebugbotwhip = OnlineCheat("debugbotwhip", "Off").on_off().description("Disable bot ring and item pickups");
|
||||||
|
|
|
||||||
|
|
@ -1061,7 +1061,7 @@ static patch_t *K_GetCachedItemPatch(INT32 item, UINT8 offset)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static patch_t *K_GetSmallStaticCachedItemPatch(kartitems_t item)
|
patch_t *K_GetSmallStaticCachedItemPatch(kartitems_t item)
|
||||||
{
|
{
|
||||||
UINT8 offset;
|
UINT8 offset;
|
||||||
|
|
||||||
|
|
@ -5698,6 +5698,8 @@ static void K_drawDistributionDebugger(void)
|
||||||
|
|
||||||
K_FillItemRouletteData(stplyr, &rouletteData, false);
|
K_FillItemRouletteData(stplyr, &rouletteData, false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < rouletteData.itemListLen; i++)
|
for (i = 0; i < rouletteData.itemListLen; i++)
|
||||||
{
|
{
|
||||||
const kartitems_t item = static_cast<kartitems_t>(rouletteData.itemList[i]);
|
const kartitems_t item = static_cast<kartitems_t>(rouletteData.itemList[i]);
|
||||||
|
|
@ -5729,14 +5731,14 @@ static void K_drawDistributionDebugger(void)
|
||||||
y += space;
|
y += space;
|
||||||
}
|
}
|
||||||
|
|
||||||
V_DrawString((x >> FRACBITS) + 20, 10, V_SNAPTOTOP, va("speed = %u", rouletteData.speed));
|
V_DrawRightAlignedString(320 - (x >> FRACBITS), 10, V_SNAPTOTOP, va("speed = %u", rouletteData.speed));
|
||||||
|
|
||||||
V_DrawString((x >> FRACBITS) + 20, 22, V_SNAPTOTOP, va("baseDist = %u", rouletteData.baseDist));
|
V_DrawRightAlignedString(320 - (x >> FRACBITS), 22, V_SNAPTOTOP, va("baseDist = %u", rouletteData.baseDist));
|
||||||
V_DrawString((x >> FRACBITS) + 20, 30, V_SNAPTOTOP, va("dist = %u", rouletteData.dist));
|
V_DrawRightAlignedString(320 - (x >> FRACBITS), 30, V_SNAPTOTOP, va("dist = %u", rouletteData.dist));
|
||||||
|
|
||||||
V_DrawString((x >> FRACBITS) + 20, 42, V_SNAPTOTOP, va("firstDist = %u", rouletteData.firstDist));
|
V_DrawRightAlignedString(320 - (x >> FRACBITS), 42, V_SNAPTOTOP, va("firstDist = %u", rouletteData.firstDist));
|
||||||
V_DrawString((x >> FRACBITS) + 20, 50, V_SNAPTOTOP, va("secondDist = %u", rouletteData.secondDist));
|
V_DrawRightAlignedString(320 - (x >> FRACBITS), 50, V_SNAPTOTOP, va("secondDist = %u", rouletteData.secondDist));
|
||||||
V_DrawString((x >> FRACBITS) + 20, 58, V_SNAPTOTOP, va("secondToFirst = %u", rouletteData.secondToFirst));
|
V_DrawRightAlignedString(320 - (x >> FRACBITS), 58, V_SNAPTOTOP, va("secondToFirst = %u", rouletteData.secondToFirst));
|
||||||
|
|
||||||
#ifndef ITEM_LIST_SIZE
|
#ifndef ITEM_LIST_SIZE
|
||||||
Z_Free(rouletteData.itemList);
|
Z_Free(rouletteData.itemList);
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,8 @@ void K_ClearPersistentMessages(void);
|
||||||
void K_ClearPersistentMessageForPlayer(player_t *player);
|
void K_ClearPersistentMessageForPlayer(player_t *player);
|
||||||
void K_TickMessages(void);
|
void K_TickMessages(void);
|
||||||
|
|
||||||
|
patch_t *K_GetSmallStaticCachedItemPatch(kartitems_t item);
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PLAYERTAG_NONE,
|
PLAYERTAG_NONE,
|
||||||
|
|
|
||||||
534
src/k_roulette.c
534
src/k_roulette.c
|
|
@ -51,6 +51,7 @@
|
||||||
#include "k_objects.h"
|
#include "k_objects.h"
|
||||||
#include "k_grandprix.h"
|
#include "k_grandprix.h"
|
||||||
#include "k_specialstage.h"
|
#include "k_specialstage.h"
|
||||||
|
#include "k_hud.h" // distribution debugger
|
||||||
|
|
||||||
// Magic number distance for use with item roulette tiers
|
// Magic number distance for use with item roulette tiers
|
||||||
#define DISTVAR (2048)
|
#define DISTVAR (2048)
|
||||||
|
|
@ -75,6 +76,111 @@
|
||||||
#define ROULETTE_SPEED_TIMEATTACK (9)
|
#define ROULETTE_SPEED_TIMEATTACK (9)
|
||||||
#define ROULETTE_SPEED_VERSUS_SLOWEST (12)
|
#define ROULETTE_SPEED_VERSUS_SLOWEST (12)
|
||||||
|
|
||||||
|
static UINT32 K_DynamicItemOddsRace[NUMKARTRESULTS-1][2] =
|
||||||
|
{
|
||||||
|
// distance, duplication tolerance
|
||||||
|
{43, 9}, // sneaker
|
||||||
|
{73, 12}, // rocketsneaker
|
||||||
|
{70, 19}, // invincibility
|
||||||
|
{18, 6}, // banana
|
||||||
|
{17, 3}, // eggmark
|
||||||
|
{21, 14}, // orbinaut
|
||||||
|
{26, 7}, // jawz
|
||||||
|
{29, 8}, // mine
|
||||||
|
{10, 3}, // landmine
|
||||||
|
{35, 4}, // ballhog
|
||||||
|
{68, 6}, // selfpropelledbomb
|
||||||
|
{58, 7}, // grow
|
||||||
|
{71, 8}, // shrink
|
||||||
|
{10, 1}, // lightningshield
|
||||||
|
{30, 4}, // bubbleshield
|
||||||
|
{76, 9}, // flameshield
|
||||||
|
{10, 3}, // hyudoro
|
||||||
|
{0, 0}, // pogospring
|
||||||
|
{17, 4}, // superring
|
||||||
|
{0, 0}, // kitchensink
|
||||||
|
{10, 3}, // droptarget
|
||||||
|
{53, 5}, // gardentop
|
||||||
|
{0, 0}, // gachabom
|
||||||
|
{44, 9}, // dualsneaker
|
||||||
|
{61, 12}, // triplesneaker
|
||||||
|
{25, 2}, // triplebanana
|
||||||
|
{30, 1}, // tripleorbinaut
|
||||||
|
{40, 2}, // quadorbinaut
|
||||||
|
{40, 4}, // dualjawz
|
||||||
|
{0, 0}, // triplegachabom
|
||||||
|
};
|
||||||
|
|
||||||
|
static UINT32 K_DynamicItemOddsBattle[NUMKARTRESULTS-1][2] =
|
||||||
|
{
|
||||||
|
// distance, duplication tolerance
|
||||||
|
{20, 1}, // sneaker
|
||||||
|
{0, 0}, // rocketsneaker
|
||||||
|
{20, 1}, // invincibility
|
||||||
|
{0, 0}, // banana
|
||||||
|
{0, 0}, // eggmark
|
||||||
|
{10, 2}, // orbinaut
|
||||||
|
{12, 4}, // jawz
|
||||||
|
{13, 3}, // mine
|
||||||
|
{0, 0}, // landmine
|
||||||
|
{13, 3}, // ballhog
|
||||||
|
{0, 0}, // selfpropelledbomb
|
||||||
|
{15, 2}, // grow
|
||||||
|
{0, 0}, // shrink
|
||||||
|
{0, 0}, // lightningshield
|
||||||
|
{10, 1}, // bubbleshield
|
||||||
|
{0, 0}, // flameshield
|
||||||
|
{0, 0}, // hyudoro
|
||||||
|
{0, 0}, // pogospring
|
||||||
|
{0, 0}, // superring
|
||||||
|
{0, 0}, // kitchensink
|
||||||
|
{0, 0}, // droptarget
|
||||||
|
{0, 0}, // gardentop
|
||||||
|
{10, 5}, // gachabom
|
||||||
|
{0, 0}, // dualsneaker
|
||||||
|
{20, 1}, // triplesneaker
|
||||||
|
{0, 0}, // triplebanana
|
||||||
|
{10, 2}, // tripleorbinaut
|
||||||
|
{13, 3}, // quadorbinaut
|
||||||
|
{13, 3}, // dualjawz
|
||||||
|
{10, 2}, // triplegachabom
|
||||||
|
};
|
||||||
|
|
||||||
|
static UINT32 K_DynamicItemOddsSpecial[NUMKARTRESULTS-1][2] =
|
||||||
|
{
|
||||||
|
// distance, duplication tolerance
|
||||||
|
{15, 2}, // sneaker
|
||||||
|
{0, 0}, // rocketsneaker
|
||||||
|
{0, 0}, // invincibility
|
||||||
|
{0, 0}, // banana
|
||||||
|
{0, 0}, // eggmark
|
||||||
|
{20, 3}, // orbinaut
|
||||||
|
{15, 2}, // jawz
|
||||||
|
{0, 0}, // mine
|
||||||
|
{0, 0}, // landmine
|
||||||
|
{0, 0}, // ballhog
|
||||||
|
{70, 1}, // selfpropelledbomb
|
||||||
|
{0, 0}, // grow
|
||||||
|
{0, 0}, // shrink
|
||||||
|
{0, 0}, // lightningshield
|
||||||
|
{0, 0}, // bubbleshield
|
||||||
|
{0, 0}, // flameshield
|
||||||
|
{0, 0}, // hyudoro
|
||||||
|
{0, 0}, // pogospring
|
||||||
|
{0, 0}, // superring
|
||||||
|
{0, 0}, // kitchensink
|
||||||
|
{0, 0}, // droptarget
|
||||||
|
{0, 0}, // gardentop
|
||||||
|
{0, 0}, // gachabom
|
||||||
|
{35, 2}, // dualsneaker
|
||||||
|
{0, 0}, // triplesneaker
|
||||||
|
{0, 0}, // triplebanana
|
||||||
|
{35, 2}, // tripleorbinaut
|
||||||
|
{0, 0}, // quadorbinaut
|
||||||
|
{35, 2}, // dualjawz
|
||||||
|
{0, 0}, // triplegachabom
|
||||||
|
};
|
||||||
|
|
||||||
static UINT8 K_KartItemOddsRace[NUMKARTRESULTS-1][8] =
|
static UINT8 K_KartItemOddsRace[NUMKARTRESULTS-1][8] =
|
||||||
{
|
{
|
||||||
{ 0, 0, 2, 3, 4, 0, 0, 0 }, // Sneaker
|
{ 0, 0, 2, 3, 4, 0, 0, 0 }, // Sneaker
|
||||||
|
|
@ -1207,6 +1313,169 @@ static void K_CalculateRouletteSpeed(itemroulette_t *const roulette)
|
||||||
roulette->tics = roulette->speed = ROULETTE_SPEED_FASTEST + FixedMul(ROULETTE_SPEED_SLOWEST - ROULETTE_SPEED_FASTEST, total);
|
roulette->tics = roulette->speed = ROULETTE_SPEED_FASTEST + FixedMul(ROULETTE_SPEED_SLOWEST - ROULETTE_SPEED_FASTEST, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean K_IsItemFirstOnly(kartitems_t item)
|
||||||
|
{
|
||||||
|
switch (item)
|
||||||
|
{
|
||||||
|
case KITEM_LANDMINE:
|
||||||
|
case KITEM_LIGHTNINGSHIELD:
|
||||||
|
case KITEM_HYUDORO:
|
||||||
|
case KITEM_DROPTARGET:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean K_IsItemFirstPermitted(kartitems_t item)
|
||||||
|
{
|
||||||
|
if (K_IsItemFirstOnly(item))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
switch (item)
|
||||||
|
{
|
||||||
|
case KITEM_BANANA:
|
||||||
|
case KITEM_EGGMAN:
|
||||||
|
case KITEM_ORBINAUT:
|
||||||
|
case KITEM_SUPERRING:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Which items are disallowed for THIS player?
|
||||||
|
static boolean K_ShouldPlayerAllowItem(kartitems_t item, const player_t *player)
|
||||||
|
{
|
||||||
|
if (!(gametyperules & GTR_CIRCUIT))
|
||||||
|
return true;
|
||||||
|
if (specialstageinfo.valid == true)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (player->position == 1)
|
||||||
|
return K_IsItemFirstPermitted(item);
|
||||||
|
else
|
||||||
|
return !K_IsItemFirstOnly(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean K_IsItemPower(kartitems_t item)
|
||||||
|
{
|
||||||
|
switch (item)
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
case KITEM_HYUDORO:
|
||||||
|
case KRITEM_TRIPLEBANANA:
|
||||||
|
case KITEM_FLAMESHIELD:
|
||||||
|
case KITEM_GARDENTOP:
|
||||||
|
case KITEM_SHRINK:
|
||||||
|
case KITEM_LIGHTNINGSHIELD:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Which items are disallowed for ALL players?
|
||||||
|
static boolean K_ShouldAllowItem(kartitems_t item, const itemroulette_t *roulette)
|
||||||
|
{
|
||||||
|
if (!(gametyperules & GTR_CIRCUIT))
|
||||||
|
return true;
|
||||||
|
if (specialstageinfo.valid == true)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
boolean notNearEnd = false;
|
||||||
|
boolean cooldownOnStart = false;
|
||||||
|
|
||||||
|
switch (item)
|
||||||
|
{
|
||||||
|
case KITEM_BANANA:
|
||||||
|
case KITEM_EGGMAN:
|
||||||
|
case KITEM_SUPERRING:
|
||||||
|
{
|
||||||
|
notNearEnd = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case KITEM_HYUDORO:
|
||||||
|
case KRITEM_TRIPLEBANANA:
|
||||||
|
{
|
||||||
|
notNearEnd = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case KITEM_INVINCIBILITY:
|
||||||
|
case KITEM_MINE:
|
||||||
|
case KITEM_GROW:
|
||||||
|
case KITEM_BUBBLESHIELD:
|
||||||
|
{
|
||||||
|
cooldownOnStart = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case KITEM_FLAMESHIELD:
|
||||||
|
case KITEM_GARDENTOP:
|
||||||
|
{
|
||||||
|
cooldownOnStart = true;
|
||||||
|
notNearEnd = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case KITEM_SPB:
|
||||||
|
{
|
||||||
|
cooldownOnStart = true;
|
||||||
|
notNearEnd = true;
|
||||||
|
// TODO forcing, just disable for now
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case KITEM_SHRINK:
|
||||||
|
{
|
||||||
|
cooldownOnStart = true;
|
||||||
|
notNearEnd = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case KITEM_LIGHTNINGSHIELD:
|
||||||
|
{
|
||||||
|
cooldownOnStart = true;
|
||||||
|
if ((gametyperules & GTR_CIRCUIT) && spbplace != -1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cooldownOnStart && (leveltime < (30*TICRATE) + starttime))
|
||||||
|
return false;
|
||||||
|
if (notNearEnd && (roulette != NULL && roulette->baseDist < ENDDIST))
|
||||||
|
return false;
|
||||||
|
if (K_DenyShieldOdds(item))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (roulette && roulette->autoroulette == true)
|
||||||
|
{
|
||||||
|
if (K_DenyAutoRouletteOdds(item))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette, boolean ringbox)
|
void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette, boolean ringbox)
|
||||||
|
|
||||||
|
|
@ -1382,7 +1651,9 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet
|
||||||
// actually calculate actual item reels.
|
// actually calculate actual item reels.
|
||||||
roulette->preexpdist = K_GetItemRouletteDistance(player, roulette->playing);
|
roulette->preexpdist = K_GetItemRouletteDistance(player, roulette->playing);
|
||||||
roulette->dist = roulette->preexpdist;
|
roulette->dist = roulette->preexpdist;
|
||||||
roulette->dist = FixedMul(roulette->preexpdist, max(player->exp, FRACUNIT/2));
|
|
||||||
|
if (gametyperules & GTR_CIRCUIT)
|
||||||
|
roulette->dist = FixedMul(roulette->preexpdist, max(player->exp, FRACUNIT/2));
|
||||||
|
|
||||||
// == EVERYTHING FUCKED BELOW THIS LINE
|
// == EVERYTHING FUCKED BELOW THIS LINE
|
||||||
|
|
||||||
|
|
@ -1391,148 +1662,63 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet
|
||||||
UINT32 deltas[NUMKARTRESULTS]; // how different is that strength from target?
|
UINT32 deltas[NUMKARTRESULTS]; // how different is that strength from target?
|
||||||
UINT32 candidates[NUMKARTRESULTS]; // how many of this item should we try to insert?
|
UINT32 candidates[NUMKARTRESULTS]; // how many of this item should we try to insert?
|
||||||
UINT32 dupetolerance[NUMKARTRESULTS]; // how willing are we to select this item after already selecting it? higher values = lower dupe penalty
|
UINT32 dupetolerance[NUMKARTRESULTS]; // how willing are we to select this item after already selecting it? higher values = lower dupe penalty
|
||||||
UINT32 duplicates[NUMKARTRESULTS]; // how many copies of this item are already waiting to be inserted?
|
|
||||||
boolean permit[NUMKARTRESULTS]; // is this item allowed?
|
boolean permit[NUMKARTRESULTS]; // is this item allowed?
|
||||||
boolean firstonly[NUMKARTRESULTS]; // is this item only first?
|
|
||||||
boolean nofirst[NUMKARTRESULTS]; // is this item never for first?
|
|
||||||
|
|
||||||
// Items permissible?
|
boolean rival = (player->bot && (player->botvars.rival || cv_levelskull.value));
|
||||||
|
boolean mothfilter = true; // strip unusually weak items from reel?
|
||||||
|
UINT8 reelsize = 15;
|
||||||
|
UINT32 humanscaler = 200;
|
||||||
|
|
||||||
|
// Cache which items are permissible
|
||||||
for (i = 1; i < NUMKARTRESULTS; i++)
|
for (i = 1; i < NUMKARTRESULTS; i++)
|
||||||
{
|
{
|
||||||
permit[i] = true;
|
permit[i] = K_ShouldAllowItem(i, roulette);
|
||||||
|
|
||||||
boolean notNearEnd = false;
|
// CONS_Printf("%s permit prepass %d\n", cv_items[i-1].name, permit[i]);
|
||||||
boolean powerItem = false;
|
|
||||||
boolean cooldownOnStart = false;
|
|
||||||
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
case KITEM_BANANA:
|
|
||||||
case KITEM_EGGMAN:
|
|
||||||
case KITEM_SUPERRING:
|
|
||||||
{
|
|
||||||
notNearEnd = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case KITEM_ROCKETSNEAKER:
|
if (permit[i])
|
||||||
case KITEM_JAWZ:
|
permit[i] = K_ShouldPlayerAllowItem(i, player);
|
||||||
case KITEM_LANDMINE:
|
|
||||||
case KITEM_DROPTARGET:
|
|
||||||
case KITEM_BALLHOG:
|
|
||||||
case KRITEM_TRIPLESNEAKER:
|
|
||||||
case KRITEM_TRIPLEORBINAUT:
|
|
||||||
case KRITEM_QUADORBINAUT:
|
|
||||||
case KRITEM_DUALJAWZ:
|
|
||||||
{
|
|
||||||
powerItem = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case KITEM_HYUDORO:
|
// CONS_Printf("%s permit postpass %d\n", cv_items[i-1].name, permit[i]);
|
||||||
case KRITEM_TRIPLEBANANA:
|
|
||||||
{
|
|
||||||
powerItem = true;
|
|
||||||
notNearEnd = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case KITEM_INVINCIBILITY:
|
|
||||||
case KITEM_MINE:
|
|
||||||
case KITEM_GROW:
|
|
||||||
case KITEM_BUBBLESHIELD:
|
|
||||||
{
|
|
||||||
cooldownOnStart = true;
|
|
||||||
powerItem = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case KITEM_FLAMESHIELD:
|
|
||||||
case KITEM_GARDENTOP:
|
|
||||||
{
|
|
||||||
cooldownOnStart = true;
|
|
||||||
powerItem = true;
|
|
||||||
notNearEnd = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case KITEM_SPB:
|
|
||||||
{
|
|
||||||
cooldownOnStart = true;
|
|
||||||
notNearEnd = true;
|
|
||||||
// TODO forcing, just disable for now
|
|
||||||
permit[i] = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case KITEM_SHRINK:
|
|
||||||
{
|
|
||||||
cooldownOnStart = true;
|
|
||||||
powerItem = true;
|
|
||||||
notNearEnd = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case KITEM_LIGHTNINGSHIELD:
|
|
||||||
{
|
|
||||||
cooldownOnStart = true;
|
|
||||||
powerItem = true;
|
|
||||||
if ((gametyperules & GTR_CIRCUIT) && spbplace != -1)
|
|
||||||
{
|
|
||||||
permit[i] = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cooldownOnStart && (leveltime < (30*TICRATE) + starttime))
|
|
||||||
permit[i] = false;
|
|
||||||
if (notNearEnd && (roulette != NULL && roulette->baseDist < ENDDIST))
|
|
||||||
permit[i] = false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// invent some bullshit Ps based on existing useodds, temp
|
// 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++)
|
||||||
{
|
{
|
||||||
powers[i] = 0;
|
if (gametyperules & GTR_BUMPERS)
|
||||||
dupetolerance[i] = 0;
|
|
||||||
UINT32 entries = 0;
|
|
||||||
firstonly[i] = true;
|
|
||||||
nofirst[i] = true;
|
|
||||||
for (j = 0; j < 8; j++)
|
|
||||||
{
|
{
|
||||||
if (K_KartItemOddsRace[i-1][j] > 0)
|
powers[i] = humanscaler * K_DynamicItemOddsBattle[i-1][0];
|
||||||
{
|
dupetolerance[i] = K_DynamicItemOddsBattle[i-1][1];
|
||||||
powers[i] += (j+1) * DISTVAR * K_KartItemOddsRace[i-1][j];
|
mothfilter = false;
|
||||||
entries += K_KartItemOddsRace[i-1][j];
|
}
|
||||||
if (j > 0)
|
else if (specialstageinfo.valid == true)
|
||||||
firstonly[i] = false;
|
{
|
||||||
if (j == 0)
|
powers[i] = humanscaler * K_DynamicItemOddsSpecial[i-1][0];
|
||||||
nofirst[i] = false;
|
dupetolerance[i] = K_DynamicItemOddsSpecial[i-1][1];
|
||||||
}
|
reelsize = 8;
|
||||||
|
mothfilter = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
powers[i] = humanscaler * K_DynamicItemOddsRace[i-1][0];
|
||||||
|
dupetolerance[i] = K_DynamicItemOddsRace[i-1][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
dupetolerance[i] += entries;
|
if (K_IsItemPower(i) && rival)
|
||||||
|
powers[i] = 3 * powers[i] / 4;
|
||||||
if (entries)
|
if (K_IsItemPower(i) && franticitems)
|
||||||
powers[i] /= entries;
|
powers[i] = 3 * powers[i] / 4;
|
||||||
|
|
||||||
// CONS_Printf("%s: %d - %d - FO %d - NF %d\n", cv_items[i-1].name, powers[i], dupetolerance[i], firstonly[i], nofirst[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// temp - null stuff that doesn't have odds, then distance correct
|
// null stuff that doesn't have odds
|
||||||
for (i = 1; i < NUMKARTRESULTS; i++)
|
for (i = 1; i < NUMKARTRESULTS; i++)
|
||||||
{
|
{
|
||||||
if (powers[i] == 0)
|
if (powers[i] == 0)
|
||||||
|
{
|
||||||
|
// CONS_Printf("%s nulled\n", cv_items[i-1].name);
|
||||||
permit[i] = false;
|
permit[i] = false;
|
||||||
else
|
}
|
||||||
powers[i] -= DISTVAR;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// stupid hack for test run / no waypoints
|
|
||||||
if (player->position == 1)
|
|
||||||
targetpower = 0;
|
|
||||||
|
|
||||||
// Starting deltas
|
// Starting deltas
|
||||||
for (i = 1; i < NUMKARTRESULTS; i++)
|
for (i = 1; i < NUMKARTRESULTS; i++)
|
||||||
|
|
@ -1542,11 +1728,14 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet
|
||||||
// CONS_Printf("starting delta for %s is %d\n", cv_items[i-1].name, deltas[i]);
|
// CONS_Printf("starting delta for %s is %d\n", cv_items[i-1].name, deltas[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT8 added = 0;
|
||||||
|
UINT32 totalreelpower = 0;
|
||||||
|
|
||||||
// let's start finding items to list
|
// let's start finding items to list
|
||||||
for (i = 0; i < 15; i++)
|
for (i = 0; i < reelsize; i++)
|
||||||
{
|
{
|
||||||
UINT32 lowestdelta = INT32_MAX;
|
UINT32 lowestdelta = INT32_MAX;
|
||||||
size_t lowestindex = 0;
|
size_t bestitem = 0;
|
||||||
|
|
||||||
// CONS_Printf("LOOP %d\n", i);
|
// CONS_Printf("LOOP %d\n", i);
|
||||||
|
|
||||||
|
|
@ -1555,7 +1744,7 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet
|
||||||
// (but ignore items that aren't allowed now)
|
// (but ignore items that aren't allowed now)
|
||||||
for (j = 1; j < NUMKARTRESULTS; j++)
|
for (j = 1; j < NUMKARTRESULTS; j++)
|
||||||
{
|
{
|
||||||
// CONS_Printf("precheck %s, FO %d NF %d CD %d\n", cv_items[j-1].name, firstonly[j], nofirst[j], K_GetItemCooldown(j));
|
// CONS_Printf("precheck %s, perm %d CD %d\n", cv_items[j-1].name, permit[j], K_GetItemCooldown(j));
|
||||||
|
|
||||||
if (!permit[j])
|
if (!permit[j])
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1563,40 +1752,97 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet
|
||||||
continue;
|
continue;
|
||||||
if (!K_ItemEnabled(j))
|
if (!K_ItemEnabled(j))
|
||||||
continue;
|
continue;
|
||||||
if (firstonly[j] && player->position > 1)
|
|
||||||
continue;
|
|
||||||
if (nofirst[j] && player->position == 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// CONS_Printf("checking %s, delta %d\n", cv_items[j-1].name, deltas[j]);
|
// CONS_Printf("checking %s, delta %d\n", cv_items[j-1].name, deltas[j]);
|
||||||
|
|
||||||
if (lowestdelta > deltas[j])
|
if (lowestdelta > deltas[j])
|
||||||
{
|
{
|
||||||
lowestindex = j;
|
bestitem = j;
|
||||||
lowestdelta = deltas[j];
|
lowestdelta = deltas[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// couldn't find an item? goodbye lol
|
// couldn't find an item? goodbye lol
|
||||||
if (lowestindex == 0)
|
if (bestitem == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// UINT32 deltapenalty = (DISTVAR*4)^(candidates[bestitem])/dupetolerance[bestitem];
|
||||||
|
UINT32 deltapenalty = 4*DISTVAR*(1+candidates[bestitem])/dupetolerance[bestitem];
|
||||||
|
|
||||||
|
if (K_IsItemPower(i) && rival)
|
||||||
|
deltapenalty = 3 * deltapenalty / 4;
|
||||||
|
if (K_IsItemPower(i) && franticitems)
|
||||||
|
deltapenalty = 3 * deltapenalty / 4;
|
||||||
|
|
||||||
|
if (cv_kartdebugdistribution.value > 1)
|
||||||
|
{
|
||||||
|
UINT16 BASE_X = 18;
|
||||||
|
UINT16 BASE_Y = 5+12*i;
|
||||||
|
INT32 FLAGS = V_SNAPTOTOP|V_SNAPTOLEFT;
|
||||||
|
// V_DrawThinString(BASE_X + 100, BASE_Y, FLAGS, va("%s", cv_items[lowestindex-1].name));
|
||||||
|
V_DrawThinString(BASE_X + 35, BASE_Y, FLAGS, va("P%d", powers[bestitem]/humanscaler));
|
||||||
|
V_DrawThinString(BASE_X + 65, BASE_Y, FLAGS, va("D%d", deltas[bestitem]/humanscaler));
|
||||||
|
V_DrawThinString(BASE_X + 20, BASE_Y, FLAGS, va("%d", dupetolerance[bestitem]));
|
||||||
|
//V_DrawThinString(BASE_X + 70, BASE_Y, FLAGS, va("+%d", deltapenalty));
|
||||||
|
V_DrawFixedPatch(BASE_X*FRACUNIT, (BASE_Y-7)*FRACUNIT, (FRACUNIT >> 1), FLAGS, K_GetSmallStaticCachedItemPatch(bestitem), NULL);
|
||||||
|
UINT8 amount = K_ItemResultToAmount(bestitem);
|
||||||
|
if (amount > 1)
|
||||||
|
{
|
||||||
|
V_DrawThinString(BASE_X, BASE_Y, FLAGS, va("x%d", amount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// otherwise, prep it to be added and give it a duplicaton penalty,
|
// otherwise, prep it to be added and give it a duplicaton penalty,
|
||||||
// so that a different item is more likely to be inserted next
|
// so that a different item is more likely to be inserted next
|
||||||
candidates[lowestindex]++;
|
candidates[bestitem]++;
|
||||||
duplicates[lowestindex]++;
|
deltas[bestitem] += deltapenalty;
|
||||||
deltas[lowestindex] += (DISTVAR*6/dupetolerance[lowestindex])^(duplicates[lowestindex]);
|
|
||||||
|
totalreelpower += powers[bestitem];
|
||||||
|
added++;
|
||||||
|
|
||||||
// CONS_Printf("added %s with candidates %d\n", cv_items[lowestindex-1].name, candidates[lowestindex]);
|
// CONS_Printf("added %s with candidates %d\n", cv_items[lowestindex-1].name, candidates[lowestindex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT8 debugcount = 0;
|
||||||
|
UINT32 meanreelpower = totalreelpower/max(added, 1);
|
||||||
|
|
||||||
// set up the list indices used to random-shuffle the ro ulette
|
// set up the list indices used to random-shuffle the ro ulette
|
||||||
for (i = 1; i < NUMKARTRESULTS; i++)
|
for (i = 1; i < NUMKARTRESULTS; i++)
|
||||||
{
|
{
|
||||||
spawnChance[i] = (
|
// filter items vastly too weak for this reel
|
||||||
totalSpawnChance += candidates[i]
|
boolean reject = (powers[i] + DISTVAR < meanreelpower);
|
||||||
);
|
|
||||||
|
if (!mothfilter)
|
||||||
|
reject = false;
|
||||||
|
|
||||||
|
if (cv_kartdebugdistribution.value && candidates[i])
|
||||||
|
{
|
||||||
|
UINT16 BASE_X = 280;
|
||||||
|
UINT16 BASE_Y = 5+12*debugcount;
|
||||||
|
INT32 FLAGS = V_SNAPTOTOP|V_SNAPTORIGHT;
|
||||||
|
|
||||||
|
V_DrawThinString(BASE_X - 12, 5, FLAGS, va("%d", targetpower/humanscaler));
|
||||||
|
|
||||||
|
for(UINT8 k = 0; k < candidates[i]; k++)
|
||||||
|
V_DrawFixedPatch((BASE_X + 3*k)*FRACUNIT, (BASE_Y-7)*FRACUNIT, (FRACUNIT >> 1), FLAGS, K_GetSmallStaticCachedItemPatch(i), NULL);
|
||||||
|
|
||||||
|
UINT8 amount = K_ItemResultToAmount(i);
|
||||||
|
if (amount > 1)
|
||||||
|
{
|
||||||
|
V_DrawThinString(BASE_X, BASE_Y, FLAGS, va("x%d", amount));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reject)
|
||||||
|
V_DrawThinString(BASE_X, BASE_Y, FLAGS|V_60TRANS, va("WEAK"));
|
||||||
|
debugcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reject)
|
||||||
|
{
|
||||||
|
spawnChance[i] = (
|
||||||
|
totalSpawnChance += candidates[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalSpawnChance == 0)
|
if (totalSpawnChance == 0)
|
||||||
|
|
@ -1607,8 +1853,10 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the same item reel given the same inputs.
|
/*
|
||||||
// P_SetRandSeed(PR_ITEM_ROULETTE, ITEM_REEL_SEED);
|
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)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue