implement xitem-next's version of fancy roulette

now even fancier
This commit is contained in:
minenice55 2025-11-17 23:48:22 -05:00
parent e9d7843b91
commit 50b6e919fe
3 changed files with 68 additions and 33 deletions

View file

@ -97,7 +97,6 @@ consvar_t cv_colorizedhud = CVAR_INIT ("colorizedhud", "On", CV_SAVE, CV_OnOff,
consvar_t cv_colorizeditembox = CVAR_INIT ("colorizeditembox", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_darkitembox = CVAR_INIT ("darkitembox", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_showfinishedplayers = CVAR_INIT ("showfinishedplayers", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_fancyroulette = CVAR_INIT ("fancyroulette", "Off", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_smoothposition = CVAR_INIT ("smoothposition", "On", CV_SAVE, CV_OnOff, NULL);
static CV_PossibleValue_t driftgauge_cons_t[] = {{0, "Off"}, {1, "Spee"}, {2, "Achii"}, {3, "Wifi"}, {4, "Chaotix"}, {5, "Numbers"}, {6, "Legacy"}, {7, "Legacy Small"}, {8, "Legacy Large Numbers"}, {9, "Large Num"}, {0, NULL}};
consvar_t cv_driftgauge = CVAR_INIT ("kartdriftgauge", "Off", CV_SAVE, driftgauge_cons_t, NULL);
@ -254,13 +253,16 @@ void K_RegisterKartHUDStuff(void)
CV_RegisterVar(&cv_colorizeditembox);
CV_RegisterVar(&cv_darkitembox);
CV_RegisterVar(&cv_showfinishedplayers);
CV_RegisterVar(&cv_fancyroulette);
CV_RegisterVar(&cv_smoothposition);
CV_RegisterVar(&cv_driftgauge);
CV_RegisterVar(&cv_driftgaugeoffset);
CV_RegisterVar(&cv_newtabranking);
CV_RegisterVar(&cv_draftindicator);
CV_RegisterVar(&cv_showstats);
// k_items.c
CV_RegisterVar(&cv_fancyroulette);
CV_RegisterVar(&cv_fancyroulettespeed);
}
void K_LoadKartHUDGraphics(void)
@ -1378,27 +1380,6 @@ static void K_drawKartItem(void)
V_DrawMappedPatch(fx, fy, V_HUDTRANS|fflags, localbg, colormap);
//V_SetClipRect((fx + 10) << FRACBITS, (fy + 10) << FRACBITS, 30 << FRACBITS, 30 << FRACBITS, V_HUDTRANS|V_SLIDEIN|fflags);
fixed_t rfy = fy<<FRACBITS;
INT32 fancyflags = V_HUDTRANS|fflags;
// mine: TODO - implement even nicer version from xItemLib-next
if (cv_fancyroulette.value && stplyr->itemroulette && !stplyr->deadtimer)
{
fixed_t frac = R_GetTimeFrac(RTF_LEVEL);
UINT8 fancystep = tiny ? 6 : 10;
fixed_t fancyoffset = (stplyr->itemroulette % 3)-1;
if (fancyoffset != 0)
{
fancyflags &= ~V_HUDTRANS;
fancyflags |=V_HUDTRANSHALF;
}
rfy += (fancystep * fancyoffset * FRACUNIT) + FixedMul(fancystep*FRACUNIT, frac) - fancystep/2*FRACUNIT;
}
// Then, the numbers:
if (stplyr->itemamount >= K_GetItemNumberDisplayMin(stplyr->itemtype, tiny) && !stplyr->itemroulette)
{
@ -1425,20 +1406,50 @@ static void K_drawKartItem(void)
V_DrawKartString(fx+38, fy+36, V_HUDTRANS|fflags, va("%d", stplyr->itemamount));
}
}
else if (cv_fancyroulette.value && stplyr->itemroulette)// xitem-next styled animated roulette
{
fixed_t rfy = fy<<FRACBITS;
INT32 fancyflags = V_HUDTRANS|fflags;
INT32 hudtrans = cv_translucenthud.value;
INT32 animlength = cv_fancyroulettespeed.value;
INT32 alpha = 0;
INT32 shift = tiny ? 16 : 32;
fixed_t shiftprog;
INT32 baseitem;
V_SetClipRect((fx + 8) << FRACBITS, (fy + 8) << FRACBITS, 34 << FRACBITS, 34 << FRACBITS, V_HUDTRANS|fflags);
for (int rouletteshift = -1; rouletteshift <= 2; rouletteshift++)
{
shiftprog = (FRACUNIT * -rouletteshift) + (FixedDiv(stplyr->itemroulette, animlength) % FRACUNIT);
alpha = (FixedMul((abs(shiftprog) * 10), FixedDiv(hudtrans << FRACBITS, 10 << FRACBITS)) >> FRACBITS)+(10-hudtrans);
rfy = (fy<<FRACBITS) + shift*shiftprog;
if (0 > alpha) alpha = 0;
if (alpha >= 10) alpha = 10;
fancyflags = (alpha<<V_ALPHASHIFT)|fflags;
baseitem = K_GetRollingRouletteItemOffset(stplyr, rouletteshift, animlength);
localpatch = K_GetCachedItemPatch(baseitem, tiny, 0);
V_DrawFixedPatch(fx<<FRACBITS, rfy, FRACUNIT, fancyflags, localpatch, colmap);
}
V_ClearClipRect();
// draw minecraft-style cooldown
K_DrawItemCooldown(fx, fy, V_HUDTRANSHALF|fflags, stplyr->itemusecooldown, stplyr->itemusecooldownmax);
}
else
{
V_DrawFixedPatch(fx<<FRACBITS, rfy, FRACUNIT, fancyflags, localpatch, colmap);
V_DrawFixedPatch(fx<<FRACBITS, fy<<FRACBITS, FRACUNIT, V_HUDTRANS|fflags, localpatch, colmap);
// draw minecraft-style cooldown
K_DrawItemCooldown(fx, fy, V_HUDTRANSHALF|fflags, stplyr->itemusecooldown, stplyr->itemusecooldownmax);
// TODO: Some proper check for if an alt has unique graphics
if (isalt)
V_DrawFixedPatch(fx<<FRACBITS, rfy, FRACUNIT, fancyflags, K_getItemAltPatch(tiny, false), colmap);
V_DrawFixedPatch(fx<<FRACBITS, fy<<FRACBITS, FRACUNIT, V_HUDTRANS|fflags, K_getItemAltPatch(tiny, false), colmap);
}
//V_ClearClipRect();
// Extensible meter, currently used by Invincibilty, Grow, Rocket Sneakers and Flame Shield
// ...aren't you forgetting something?
if (itembar != -1)

View file

@ -70,6 +70,9 @@ static CV_PossibleValue_t kartitemvariant_cons_t[] = {{0, "Legacy"}, {1, "Altern
#define REALMAXBATTLEPROB 10
#define MAXBATTLEPROBABILITY (REALMAXBATTLEPROB * BATTLEODDSMUL)
consvar_t cv_fancyroulette = CVAR_INIT ("fancyroulette", "Off", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_fancyroulettespeed = CVAR_INIT ("fancyroulettespeed", "5", CV_SAVE, CV_Natural, NULL);
void K_RegisterItem(kartitemtype_e itemtype)
{
kartdebugitem_cons_t[itemtype].strvalue = DEH_KartItemName(itemtype);
@ -975,10 +978,23 @@ UINT8 K_FindUseodds(const player_t *player, fixed_t mashed, UINT32 pdis, UINT8 b
return min(MAXODDS - 1, useodds);
}
UINT16 roulette_size;
INT32 K_GetRollingRouletteItem(player_t *player)
{
UINT8* translation = K_GetRollableItems();
return translation[(player->itemroulette / 3) % roulette_size];
}
INT32 K_GetRollingRouletteItemOffset(player_t *player, INT16 offset, INT32 animspeed)
{
UINT8* translation = K_GetRollableItems();
INT32 icon = ((player->itemroulette + animspeed)/animspeed);
return translation[((icon + offset + roulette_size) % roulette_size)];
}
UINT8* K_GetRollableItems(void)
{
static UINT8 translation[MAXKARTRESULTS];
static UINT16 roulette_size;
static INT16 odds_cached = -1;
@ -1012,12 +1028,10 @@ INT32 K_GetRollingRouletteItem(player_t *player)
if (j == numseen && memcmp(result->odds[oddstable], EMPTYODDS, sizeof(EMPTYODDS)))
translation[roulette_size++] = seen[numseen++] = result->type;
}
roulette_size *= 3;
odds_cached = gametype;
}
return translation[(player->itemroulette % roulette_size) / 3];
return translation;
}
// Legacy odds are fickle and finicky, so we exaggerate distances
@ -1250,6 +1264,7 @@ void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
fixed_t mashed = 0;
boolean dontforcespb = false;
boolean spbrush = false;
INT32 roulettespeed = 3;
// This makes the roulette cycle through items - if this is 0, you shouldn't be here.
if (!player->itemroulette)
@ -1273,9 +1288,13 @@ void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
dontforcespb = true;
// This makes the roulette produce the random noises.
if ((player->itemroulette % 3) == 1 && P_IsDisplayPlayer(player))
if (cv_fancyroulette.value)
{
#define PLAYROULETTESND S_StartSound(NULL, sfx_itrol1 + ((player->itemroulette / 3) % 8))
roulettespeed = cv_fancyroulettespeed.value;
}
if ((player->itemroulette % roulettespeed) == 1 && P_IsDisplayPlayer(player))
{
#define PLAYROULETTESND S_StartSound(NULL, sfx_itrol1 + ((player->itemroulette / roulettespeed) % 8))
for (i = 0; i <= r_splitscreen; i++)
{
if (player == &players[displayplayers[i]] && players[displayplayers[i]].itemroulette)

View file

@ -160,6 +160,9 @@ struct kartroulette_t
UINT32 firstDist;
};
extern consvar_t cv_fancyroulette;
extern consvar_t cv_fancyroulettespeed;
extern kartitem_t kartitems[MAXKARTITEMS];
extern UINT8 numkartitems;
extern kartresult_t kartresults[MAXKARTRESULTS];
@ -190,6 +193,8 @@ UINT32 K_CalculatePDIS(const player_t *player, UINT8 numPlayers, boolean *spbrus
UINT8 K_FindUseodds(const player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper, boolean spbrush);
UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers, boolean spbrush);
INT32 K_GetRollingRouletteItem(player_t *player);
INT32 K_GetRollingRouletteItemOffset(player_t *player, INT16 offset, INT32 animspeed);
UINT8* K_GetRollableItems(void);
void K_KartItemRoulette(player_t *player, ticcmd_t *cmd);
void K_StartRoulette(player_t *player, kartroulettetype_e roulettetype);