Item refactor, part 1

Too much shit to explain, read the diff (you should anyway!)
Very sloppy, expect lots of fixes
TODO: SOC it all, separate "active odds" table, how to handle alt items
This commit is contained in:
GenericHeroGuy 2025-11-06 22:57:21 +01:00
parent 8bae1b3c91
commit efac1d27c2
37 changed files with 917 additions and 1481 deletions

View file

@ -133,8 +133,7 @@ k_bot.cpp
k_botitem.cpp
k_botsearch.cpp
k_cluster.cpp
k_odds.c
k_altshrink.c
k_items.c
k_grandprix.c
k_boss.c
k_hud.c

View file

@ -189,10 +189,6 @@ extern CV_PossibleValue_t CV_Natural[];
#define KARTGP_NIGHTMARE 5 // Not a speed setting, gives expert speed with maxed out bots
extern CV_PossibleValue_t kartspeed_cons_t[], gpdifficulty_cons_t[];
// Alternative item types.
#define KARTITEM_NORMAL 0
#define KARTITEM_ALTERN 1
extern consvar_t cv_execversion;
extern consvar_t cv_resetnetvars;

View file

@ -68,7 +68,7 @@
#include "m_perfstats.h"
#include "g_party.h"
#include "k_specialstage.h"
#include "k_altshrink.h"
#include "k_items.h"
#define CV_RESTRICT CV_NETVAR
@ -167,9 +167,6 @@ static void KartItemLitter_OnChange(void);
static void KartItemPush_OnChange(void);
static void KartAntiBump_OnChange(void);
static void KartItemBreaker_OnChange(void);
static void KartInvinType_OnChange(void);
static void KartEggmanType_OnChange(void);
static void KartShrinkType_OnChange(void);
static void KartBumpSpark_OnChange(void);
static void Schedule_OnChange(void);
@ -386,35 +383,6 @@ consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save
#endif
// SRB2kart
consvar_t cv_sneaker = CVAR_INIT ("sneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_rocketsneaker = CVAR_INIT ("rocketsneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_invincibility = CVAR_INIT ("invincibility", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_banana = CVAR_INIT ("banana", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_eggmanmonitor = CVAR_INIT ("eggmanmonitor", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_orbinaut = CVAR_INIT ("orbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_jawz = CVAR_INIT ("jawz", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_mine = CVAR_INIT ("mine", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_ballhog = CVAR_INIT ("ballhog", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_selfpropelledbomb = CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_grow = CVAR_INIT ("grow", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_shrink = CVAR_INIT ("shrink", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_thundershield = CVAR_INIT ("thundershield", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_hyudoro = CVAR_INIT ("hyudoro", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_pogospring = CVAR_INIT ("pogospring", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_kitchensink = CVAR_INIT ("kitchensink", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_superring = CVAR_INIT ("superring", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_landmine = CVAR_INIT ("landmine", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_bubbleshield = CVAR_INIT ("bubbleshield", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_flameshield = CVAR_INIT ("flameshield", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_dualsneaker = CVAR_INIT ("dualsneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_triplesneaker = CVAR_INIT ("triplesneaker", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_triplebanana = CVAR_INIT ("triplebanana", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_decabanana = CVAR_INIT ("decabanana", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_tripleorbinaut = CVAR_INIT ("tripleorbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_quadorbinaut = CVAR_INIT ("quadorbinaut", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_dualjawz = CVAR_INIT ("dualjawz", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
static CV_PossibleValue_t kartminimap_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
consvar_t cv_kartminimap = CVAR_INIT ("kartminimap", "4", CV_SAVE, kartminimap_cons_t, NULL);
consvar_t cv_kartcheck = CVAR_INIT ("kartcheck", "Yes", CV_SAVE, CV_YesNo, NULL);
@ -601,12 +569,6 @@ consvar_t cv_kartspbdist = CVAR_INIT ("kartspbdist", "4432", CV_NETVAR|CV_CHEAT|
consvar_t cv_kartlegacyspbdist = CVAR_INIT ("kartlegacyspbdist", "2216", CV_NETVAR|CV_CHEAT|CV_GUARD, spbdist_cons_t, NULL);
#undef MAXODDSDIST
// Items with alternative types
static CV_PossibleValue_t kartitemtype_cons_t[] = {{KARTITEM_NORMAL, "Legacy"}, {KARTITEM_ALTERN, "Alternative"}, {0, NULL}};
consvar_t cv_kartinvintype = CVAR_INIT ("kartinvintype", "Legacy", CV_NETVAR|CV_CALL, kartitemtype_cons_t, KartInvinType_OnChange);
consvar_t cv_kartshrinktype = CVAR_INIT ("kartshrinktype", "Legacy", CV_NETVAR|CV_CALL, kartitemtype_cons_t, KartShrinkType_OnChange);
consvar_t cv_karteggmantype = CVAR_INIT ("karteggmantype", "Legacy", CV_NETVAR|CV_CALL, kartitemtype_cons_t, KartEggmanType_OnChange);
// Time limit for Alt. Shrink
static CV_PossibleValue_t altshrinktime_cons_t[] = {{0, "MIN"}, {(INT16_MAX / TICRATE), "MAX"}, {0, NULL}};
consvar_t cv_kartaltshrinktime = CVAR_INIT ("kartaltshrinktime", "14", CV_NETVAR|CV_CHEAT|CV_GUARD, altshrinktime_cons_t, NULL);
@ -631,23 +593,7 @@ consvar_t cv_kartflame_offroadburn = CVAR_INIT ("kartflame_offroadburn", "Off",
static CV_PossibleValue_t kartairsquish_cons_t[] = {{1, "Squish"}, {2, "Flip-over"}, {0, "None"}, {0, NULL}};
consvar_t cv_kartairsquish = CVAR_INIT ("kartairsquish", "None", CV_NETVAR, kartairsquish_cons_t, NULL);
static CV_PossibleValue_t kartdebugitem_cons_t[] =
{
#define FOREACH( name, n ) { n, #name }
KART_ITEM_ITERATOR,
#undef FOREACH
{0}
};
consvar_t cv_kartdebugitem = CVAR_INIT ("kartdebugitem", "NONE", CV_NETVAR|CV_CHEAT, kartdebugitem_cons_t, NULL);
static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
consvar_t cv_kartdebugamount = CVAR_INIT ("kartdebugamount", "1", CV_NETVAR|CV_CHEAT, kartdebugamount_cons_t, NULL);
consvar_t cv_kartdebugshrink = CVAR_INIT ("kartdebugshrink", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
#ifdef DEVELOP
#define VALUE "Yes"
#else
#define VALUE "No"
#endif
#undef VALUE
consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
@ -6235,8 +6181,7 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum)
SINT8 item = READSINT8(*cp);
UINT8 amt = READUINT8(*cp);
item = max(item, KITEM_SAD);
item = min(item, NUMKARTITEMS - 1);
item = CLAMP(item, KITEM_SAD, numkartitems - 1);
K_StripItems(player);
@ -6252,10 +6197,7 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum)
}
else
{
// FIXME: we should have actual KITEM_ name array
const char *itemname = cv_kartdebugitem.PossibleValue[1 + item].strvalue;
CV_CheaterWarning(playernum, va("give item %s x%d", itemname, amt));
CV_CheaterWarning(playernum, va("give item %s x%d", item < 0 ? "SAD" : kartitems[item].name, amt));
}
break;
}
@ -6540,8 +6482,6 @@ static void Command_KartGiveItem_f(void)
const char *name;
INT32 item;
const char * str;
int i;
ac = COM_Argc();
@ -6553,7 +6493,7 @@ static void Command_KartGiveItem_f(void)
}
else
{
item = NUMKARTITEMS;
item = numkartitems;
name = COM_Argv(1);
@ -6569,18 +6509,18 @@ static void Command_KartGiveItem_f(void)
CONS_Printf("\x83" "Autocomplete:\n");
/* then do very loose partial matching */
for (i = 0; ( str = kartdebugitem_cons_t[i].strvalue ); ++i)
for (i = 0; i < numkartitems; i++)
{
if (strcasestr(str, name) != NULL)
if (strcasestr(kartitems[i].name, name) != NULL)
{
CONS_Printf("\x83\t%s\n", str);
item = kartdebugitem_cons_t[i].value;
CONS_Printf("\x83\t%s\n", kartitems[i].name);
item = i;
}
}
}
}
if (item < NUMKARTITEMS)
if (item < numkartitems)
{
INT32 amt;
@ -7828,60 +7768,6 @@ static void KartItemBreaker_OnChange(void)
}
}
static void KartInvinType_OnChange(void)
{
if (K_CanChangeRules(false) == false)
{
return;
}
if (leveltime < starttime)
{
CONS_Printf(M_GetText("Invincibility type has been changed to \"%s\".\n"), cv_kartinvintype.string);
invintype = (UINT8)cv_kartinvintype.value;
}
else
{
CONS_Printf(M_GetText("Invincibility type will be changed to \"%s\" next round.\n"), cv_kartinvintype.string);
}
}
static void KartShrinkType_OnChange(void)
{
if (K_CanChangeRules(false) == false)
{
return;
}
if (leveltime < starttime)
{
CONS_Printf(M_GetText("Shrink type has been changed to \"%s\".\n"), cv_kartshrinktype.string);
shrinktype = (UINT8)cv_kartshrinktype.value;
}
else
{
CONS_Printf(M_GetText("Shrink type will be changed to \"%s\" next round.\n"), cv_kartshrinktype.string);
}
}
static void KartEggmanType_OnChange(void)
{
if (K_CanChangeRules(false) == false)
{
return;
}
if (leveltime < starttime)
{
CONS_Printf(M_GetText("Eggman Monitor type has been changed to \"%s\".\n"), cv_karteggmantype.string);
eggmantype = (UINT8)cv_karteggmantype.value;
}
else
{
CONS_Printf(M_GetText("Eggman Monitor type will be changed to \"%s\" next round.\n"), cv_karteggmantype.string);
}
}
static void KartBumpSpark_OnChange(void)
{
if (K_CanChangeRules(false) == false)

View file

@ -72,38 +72,6 @@ extern consvar_t cv_spectatorreentry, cv_antigrief;
extern consvar_t cv_debugtraversemax;
#endif
// SRB2kart items
extern consvar_t
cv_sneaker,
cv_rocketsneaker,
cv_invincibility,
cv_banana,
cv_eggmanmonitor,
cv_orbinaut,
cv_jawz,
cv_mine,
cv_ballhog,
cv_selfpropelledbomb,
cv_grow,
cv_shrink,
cv_thundershield,
cv_hyudoro,
cv_pogospring,
cv_kitchensink,
cv_superring,
cv_landmine,
cv_bubbleshield,
cv_flameshield;
extern consvar_t
cv_dualsneaker,
cv_triplesneaker,
cv_triplebanana,
cv_decabanana,
cv_tripleorbinaut,
cv_quadorbinaut,
cv_dualjawz;
extern consvar_t cv_kartminimap;
extern consvar_t cv_kartcheck;
extern consvar_t cv_kartinvinsfx;
@ -160,6 +128,11 @@ extern consvar_t cv_kartstacking_bubble_speedboost;
extern consvar_t cv_kartstacking_bubble_accelboost;
extern consvar_t cv_kartstacking_bubble_stackable;
extern consvar_t cv_kartaltshrinktime;
extern consvar_t cv_kartstacking_altshrink_speedboost;
extern consvar_t cv_kartstacking_altshrink_accelboost;
extern consvar_t cv_kartstacking_altshrink_stackable;
extern consvar_t cv_kartstacking_start_speedboost;
extern consvar_t cv_kartstacking_start_accelboost;
extern consvar_t cv_kartstacking_start_stackable;
@ -200,7 +173,6 @@ extern consvar_t cv_kartbumpspark;
extern consvar_t cv_kartbumpspring;
extern consvar_t cv_kartslipdash;
extern consvar_t cv_kartslopeboost;
extern consvar_t cv_kartinvintype;
extern consvar_t cv_kartinvindist;
extern consvar_t cv_kartinvindistmul;
extern consvar_t cv_kartinvin_maxtime;

View file

@ -137,61 +137,6 @@ typedef enum
CR_ZOOMTUBE,
} carrytype_t; // carry
/*
To use: #define FOREACH( name, number )
Do with it whatever you want.
Run this macro, then #undef FOREACH afterward
*/
#define KART_ITEM_ITERATOR \
FOREACH (SAD, -1),\
FOREACH (NONE, 0),\
FOREACH (SNEAKER, 1),\
FOREACH (ROCKETSNEAKER, 2),\
FOREACH (INVINCIBILITY, 3),\
FOREACH (BANANA, 4),\
FOREACH (EGGMAN, 5),\
FOREACH (ORBINAUT, 6),\
FOREACH (JAWZ, 7),\
FOREACH (MINE, 8),\
FOREACH (BALLHOG, 9),\
FOREACH (SPB, 10),\
FOREACH (GROW, 11),\
FOREACH (SHRINK, 12),\
FOREACH (THUNDERSHIELD, 13),\
FOREACH (HYUDORO, 14),\
FOREACH (POGOSPRING, 15),\
FOREACH (KITCHENSINK, 16),\
FOREACH (SUPERRING, 17),\
FOREACH (LANDMINE, 18),\
FOREACH (BUBBLESHIELD, 19),\
FOREACH (FLAMESHIELD, 20)
typedef enum
{
#define FOREACH( name, n ) KITEM_ ## name = n
KART_ITEM_ITERATOR,
#undef FOREACH
NUMKARTITEMS,
// Additional roulette numbers, only used for K_KartGetItemResult
KRITEM_DUALSNEAKER = NUMKARTITEMS,
KRITEM_TRIPLESNEAKER,
KRITEM_TRIPLEBANANA,
KRITEM_TENFOLDBANANA,
KRITEM_TRIPLEORBINAUT,
KRITEM_QUADORBINAUT,
KRITEM_DUALJAWZ,
NUMBASEKARTRESULTS,
// alt items implemented as separate things
KAITEM_EGGMINE = NUMBASEKARTRESULTS, // also landmine
KAITEM_ALTERNSHRINK,
NUMKARTRESULTS
} kartitems_t;
typedef enum {
KROULETTE_DISABLED,
KROULETTE_ACTIVE,

View file

@ -439,6 +439,20 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
}
return luaL_error(L, "karthud '%s' could not be found.\n", word);
}
else if (mathlib && fastncmp("KITEM_",word,6)) {
p = word+6;
if (fastcmp(p, "LIGHTNINGSHIELD"))
{
lua_pushinteger(L, KITEM_THUNDERSHIELD);
return 1;
}
for (i = 0; i < numkartitems; i++)
if (fastcmp(p, kartitems[i].name)) {
lua_pushinteger(L, i);
return 1;
}
return luaL_error(L, "kartitem '%s' could not be found.\n", word);
}
else if (fastncmp("SKINCOLOR_",word,10)) {
p = word+10;
i = DEH_FindSkincolor(p);

View file

@ -27,6 +27,7 @@ extern "C" {
#include "fastcmp.h"
#include "lua_script.h"
#include "lua_libs.h"
#include "k_items.h"
#include "dehacked.h"
#include "deh_tables.h"

View file

@ -1511,24 +1511,6 @@ struct int_const_s const INT_CONST[] = {
{"BASEVIDWIDTH", BASEVIDWIDTH},
{"BASEVIDHEIGHT", BASEVIDHEIGHT},
// SRB2Kart
// kartitems_t
#define FOREACH( name, n ) { TOSTR (KITEM_ ## name), KITEM_ ## name }
KART_ITEM_ITERATOR, // Actual items (can be set for k_itemtype)
#undef FOREACH
{"NUMKARTITEMS",NUMKARTITEMS},
{"KRITEM_DUALSNEAKER",KRITEM_DUALSNEAKER}, // Additional roulette IDs (not usable for much in Lua besides K_GetItemPatch)
{"KRITEM_TRIPLESNEAKER",KRITEM_TRIPLESNEAKER},
{"KRITEM_TRIPLEBANANA",KRITEM_TRIPLEBANANA},
{"KRITEM_TENFOLDBANANA",KRITEM_TENFOLDBANANA},
{"KRITEM_TRIPLEORBINAUT",KRITEM_TRIPLEORBINAUT},
{"KRITEM_QUADORBINAUT",KRITEM_QUADORBINAUT},
{"KRITEM_DUALJAWZ",KRITEM_DUALJAWZ},
{"NUMBASEKARTRESULTS",NUMBASEKARTRESULTS},
{"KAITEM_EGGMINE", KAITEM_EGGMINE},
{"KAITEM_ALTERNSHRINK", KAITEM_ALTERNSHRINK},
{"NUMKARTRESULTS",NUMKARTRESULTS},
// kartshields_t
{"KSHIELD_NONE",KSHIELD_NONE},
{"KSHIELD_THUNDER",KSHIELD_THUNDER},
@ -1537,9 +1519,6 @@ struct int_const_s const INT_CONST[] = {
{"KSHIELD_FLAME",KSHIELD_FLAME},
{"NUMKARTSHIELDS",NUMKARTSHIELDS},
// kartitems_t
{"KITEM_LIGHTNINGSHIELD",KITEM_THUNDERSHIELD},
// kartroulette_t
{"KROULETTE_DISABLED",KROULETTE_DISABLED},
{"KROULETTE_ACTIVE",KROULETTE_ACTIVE},
@ -1685,9 +1664,6 @@ struct int_const_s const INT_CONST[] = {
{"FACE_WANTED", FACE_WANTED},
{"FACE_MINIMAP", FACE_MINIMAP},
{"NUMFACES", NUMFACES},
// alt item type
{"KARTITEM_NORMAL", KARTITEM_NORMAL},
{"KARTITEM_ALTERN", KARTITEM_ALTERN},
// k_waypoint.h values
{"DEFAULT_WAYPOINT_RADIUS",DEFAULT_WAYPOINT_RADIUS},

View file

@ -669,9 +669,6 @@ extern boolean franticitems;
extern boolean encoremode, prevencoremode;
extern boolean comeback;
extern UINT8 invintype;
extern UINT8 eggmantype;
extern SINT8 mostwanted;
extern SINT8 battlewanted[4];
extern tic_t wantedcalcdelay;

View file

@ -61,8 +61,7 @@
#include "k_boss.h"
#include "k_specialstage.h"
#include "k_bot.h"
#include "k_odds.h"
#include "k_altshrink.h"
#include "k_items.h"
#include "doomstat.h"
#include "acs/interface.h"
#include "k_director.h"
@ -300,9 +299,6 @@ boolean encoremode = false; // Encore Mode currently enabled?
boolean prevencoremode;
boolean franticitems; // Frantic items currently enabled?
boolean comeback; // Battle Mode's karma comeback is on/off
// alt item values
UINT8 invintype; // How Invincibility functions. 0 for Legacy/Vanilla, 1 for Alternative.
UINT8 eggmantype; // How Eggman Monitor functions. 0 for Legacy/Vanilla, 1 for Alternative (Egg Mine).
// Voting system
INT16 votelevels[12][2]; // Levels that were rolled by the host
@ -314,7 +310,7 @@ SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points
SINT8 mostwanted; // The "most wanted" (first in line) player.
tic_t wantedcalcdelay; // Time before it recalculates WANTED
tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded
// hyubgone was taken out back. See k_odds.c
// hyubgone was taken out back. See k_items.c
tic_t mapreset; // Map reset delay when enough players have joined an empty game
boolean thwompsactive; // Thwomps activate on lap 2
UINT8 lastLowestLap; // Last lowest lap, for activating race lap executors

View file

@ -20,6 +20,7 @@
#include "d_main.h"
#include "m_menu.h"
#include "deh_tables.h"
#include "k_items.h"
// Hey, moron! If you wanna change this table, you can just change the sprite enum in info/sprites.h,
// so you don't have to copy and paste the list of sprite names back in here :^)
@ -233,4 +234,13 @@ void P_ResetData(INT32 flags)
for (i = 0; i < MN_FIRSTFREESLOT; i++, name += strlen(name)+1)
DEH_Link(name, &menudefs[i].info, &menunames);
}
// kartitems
if (init)
{
memset(kartitems, 0, sizeof(kartitems));
K_InitializeItems();
numkartitems = KITEM_FIRSTFREESLOT;
}
}

View file

@ -1,82 +0,0 @@
// BLANKART
//-----------------------------------------------------------------------------
/// \file k_altshrink.c
/// \brief Alternative Shrink item type functions.
#include "doomdef.h"
#include "doomtype.h"
#include "doomstat.h"
#include "command.h"
#include "console.h"
#include "d_player.h"
#include "k_kart.h"
#include "k_altshrink.h"
#include "k_cluster.hpp"
#include "m_fixed.h"
#include "p_local.h"
UINT8 shrinktype; // How Shrink functions. 0 for Legacy/Vanilla, 1 for Alternative.
void K_UpdateShrinkType(void)
{
if (leveltime < starttime)
{
CONS_Printf(M_GetText("Shrink type has been changed to \"%s\".\n"), cv_kartshrinktype.string);
}
shrinktype = (UINT8)cv_kartshrinktype.value;
}
/** \brief Depending on the Shrink type set, this returns true or false if the player is shrunk.
\param player (player_t) Player to test shrunken status for
\param legacy (boolean) Legacy shrink?
\return void
*/
boolean K_IsShrunkMode(const player_t *player, boolean legacy)
{
boolean shrunk = K_IsShrunk(player);
boolean legacytype = (!K_IsKartItemAlternate(KITEM_SHRINK));
if (legacy)
{
return ((shrunk) && (legacytype));
}
return ((shrunk) && (!legacytype));
}
#define ALTSHRINK_EPSILON (320 * FRACUNIT)
#define NEIGHBOR_IFRAMES (TICRATE / 2)
#define BASE_IFRAMES (2 * TICRATE)
void K_AltShrinkIFrames(player_t *player)
{
vector3_t tempclusterpoint;
// Find neighbors
INT32 N = K_CountNeighboringPlayers(player, ALTSHRINK_EPSILON, &tempclusterpoint);
// For every neighbor, add some iframes for a clean breakaway.
player->flashing = (UINT16)min((INT32)(UINT16_MAX), BASE_IFRAMES + (NEIGHBOR_IFRAMES * N));
}
#define PITY_SHRINKINCREASE_BASE (3)
#define PITY_SHRINKINCREASE (TICRATE / 2)
void K_AltShrinkPityIncrease(player_t *player)
{
// Increase your shrink timer by a little bit for every player you run into.
INT32 shrinktime = (UINT32)(K_GetShrinkTime(player));
fixed_t dimin = FRACUNIT;
dimin = max(0, 5 - player->altshrinktimeshit) * FRACUNIT / 5;
shrinktime = min(INT16_MAX, shrinktime + PITY_SHRINKINCREASE_BASE + FixedMul(PITY_SHRINKINCREASE, dimin));
player->growshrinktimer = ((INT16)shrinktime) * -1;
}

View file

@ -1,60 +0,0 @@
// BLANKART
//-----------------------------------------------------------------------------
/// \file k_altshrink.h
/// \brief Alternative Shrink item type functions.
#ifndef __K_ALTSHRINK__
#define __K_ALTSHRINK__
#include "doomdef.h"
#include "d_player.h" // Need for player_t
#include "command.h" // Need for player_t
#include "m_fixed.h"
#include "k_kart.h"
extern consvar_t cv_kartaltshrinktime;
extern consvar_t cv_kartshrinktype;
extern consvar_t cv_kartstacking_altshrink_speedboost;
extern consvar_t cv_kartstacking_altshrink_accelboost;
extern consvar_t cv_kartstacking_altshrink_stackable;
extern UINT8 shrinktype;
#define ALTSHRINKTIME CV_Get(&cv_kartaltshrinktime)
#define SHRINKSPEEDBOOST CV_Get(&cv_kartstacking_altshrink_speedboost)
#define SHRINKACCELBOOST CV_Get(&cv_kartstacking_altshrink_accelboost)
#define SHRINKSTACKABLE CV_Get(&cv_kartstacking_altshrink_stackable)
/** \brief Returns true or false if the player is shrunk.
\param player (player_t) Player to test shrunken status for
\return Is this player shrunk?
*/
FUNCINLINE static ATTRINLINE boolean K_IsShrunk(const player_t *player)
{
return (player->growshrinktimer < 0);
}
FUNCINLINE static ATTRINLINE INT16 K_GetShrinkTime(player_t *player)
{
return (player->growshrinktimer * -1);
}
FUNCINLINE static ATTRINLINE fixed_t K_AccomodateShrinkScaling(fixed_t x)
{
return FixedDiv(x, SHRINK_SCALE);
}
boolean K_IsShrunkMode(const player_t *player, boolean legacy);
#define K_IsLegacyShrunk(player) (K_IsShrunkMode(player, true))
#define K_IsAltShrunk(player) (K_IsShrunkMode(player, false))
void K_UpdateShrinkType(void);
void K_AltShrinkIFrames(player_t *player);
void K_AltShrinkPityIncrease(player_t *player);
#endif // __K_ALTSHRINK__

View file

@ -44,6 +44,7 @@
#include "blan/b_soc.h"
#include "v_video.h" // for debugging
#include "k_waypoint.h"
#include "k_items.h"
consvar_t cv_forcebots = CVAR_INIT ("kartforcebots", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
consvar_t cv_botcontrol = CVAR_INIT ("kartbotcontrol", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);

View file

@ -29,7 +29,7 @@
#include "m_random.h"
#include "r_things.h" // numskins
#include "m_easing.h"
#include "k_odds.h"
#include "k_items.h"
#include "k_waypoint.h"
// Looks for players around the bot, and presses the item button
@ -1155,7 +1155,7 @@ static void K_BotItemRouletteMash(botdata_t *bd, const player_t *player)
}
}
if (player->rings < 0 && cv_superring.value && K_RingsActive())
if (player->rings < 0 && K_ItemResultEnabled("superring") && K_RingsActive())
{
// Uh oh, we need a loan!
// It'll be better in the long run for bots to lose an item set for 5-15 free rings.

View file

@ -33,6 +33,7 @@
#include "p_slopes.h" // P_GetZAt
#include "m_perfstats.h"
#include "k_objects.h"
#include "k_items.h"
#include "blan/b_soc.h"

View file

@ -2,13 +2,12 @@
/// \brief SRB2Kart item collision hooks
#include "k_collide.h"
#include "k_altshrink.h"
#include "k_stats.h"
#include "doomstat.h"
#include "doomtype.h"
#include "p_mobj.h"
#include "k_kart.h"
#include "k_odds.h"
#include "k_items.h"
#include "p_local.h"
#include "s_sound.h"
#include "r_main.h" // R_PointToAngle2, R_PointToDist2

View file

@ -17,7 +17,7 @@
#include "k_boss.h"
#include "k_color.h"
#include "k_director.h"
#include "k_odds.h"
#include "k_items.h"
#include "p_mobj.h"
#include "screen.h"
#include "doomtype.h"
@ -186,26 +186,6 @@ static patch_t *kp_itemmulsticker[4];
static patch_t *kp_itemx;
static patch_t *kp_sadface[2];
static patch_t *kp_sneaker[4];
static patch_t *kp_rocketsneaker[2];
static patch_t *kp_invincibility[13];
static patch_t *kp_banana[5];
static patch_t *kp_eggman[2];
static patch_t *kp_orbinaut[5];
static patch_t *kp_jawz[3];
static patch_t *kp_mine[2];
static patch_t *kp_ballhog[2];
static patch_t *kp_selfpropelledbomb[2];
static patch_t *kp_grow[2];
static patch_t *kp_shrink[2];
static patch_t *kp_thundershield[2];
static patch_t *kp_hyudoro[2];
static patch_t *kp_pogospring[2];
static patch_t *kp_kitchensink[2];
static patch_t *kp_superring[2];
static patch_t *kp_landmine[2];
static patch_t *kp_bubbleshield[2];
static patch_t *kp_flameshield[2];
static patch_t *kp_check[6];
@ -540,87 +520,31 @@ void K_LoadKartHUDGraphics(void)
// Kart Item Windows
HU_UpdatePatch(&kp_itembg[0], "K_ITBG");
HU_UpdatePatch(&kp_itembg[1], "K_ITBGD");
HU_UpdatePatch(&kp_itembg[2], "K_ISBG");
HU_UpdatePatch(&kp_itembg[3], "K_ISBGD");
HU_UpdatePatch(&kp_itembg[4], "K_ITBC");
HU_UpdatePatch(&kp_itembg[5], "K_ITBCD");
HU_UpdatePatch(&kp_itembg[6], "K_ISBC");
HU_UpdatePatch(&kp_itembg[7], "K_ISBCD");
HU_UpdatePatch(&kp_itemtimer[0], "K_ITIMER");
HU_UpdatePatch(&kp_itemtimer[1], "K_ISIMER");
HU_UpdatePatch(&kp_itemmulsticker[0], "K_ITMUL");
HU_UpdatePatch(&kp_itemmulsticker[1], "K_ISMUL");
HU_UpdatePatch(&kp_itemmulsticker[2], "K_ITMULC");
HU_UpdatePatch(&kp_itemmulsticker[3], "K_ISMULC");
HU_UpdatePatch(&kp_itemx, "K_ITX");
HU_UpdatePatch(&kp_sadface[0], "K_ITSAD");
HU_UpdatePatch(&kp_sneaker[0], "K_ITSHOE");
HU_UpdatePatch(&kp_sneaker[1], "K_ITSHO2");
HU_UpdatePatch(&kp_sneaker[2], "K_ITSHO3");
HU_UpdatePatch(&kp_rocketsneaker[0], "K_ITRSHE");
sprintf(buffer, "K_ITINVx");
for (i = 0; i < 7; i++)
{
buffer[7] = '1'+i;
HU_UpdatePatch(&kp_invincibility[i], "%s", buffer);
}
HU_UpdatePatch(&kp_banana[0], "K_ITBANA");
HU_UpdatePatch(&kp_banana[1], "K_ITBAN2");
HU_UpdatePatch(&kp_banana[2], "K_ITBAN3");
HU_UpdatePatch(&kp_banana[3], "K_ITBAN4");
HU_UpdatePatch(&kp_eggman[0], "K_ITEGGM");
sprintf(buffer, "K_ITORBx");
for (i = 0; i < 4; i++)
{
buffer[7] = '1'+i;
HU_UpdatePatch(&kp_orbinaut[i], "%s", buffer);
}
HU_UpdatePatch(&kp_jawz[0], "K_ITJAWZ");
HU_UpdatePatch(&kp_jawz[1], "K_ITJAW2");
HU_UpdatePatch(&kp_mine[0], "K_ITMINE");
HU_UpdatePatch(&kp_ballhog[0], "K_ITBHOG");
HU_UpdatePatch(&kp_selfpropelledbomb[0], "K_ITSPB");
HU_UpdatePatch(&kp_grow[0], "K_ITGROW");
HU_UpdatePatch(&kp_shrink[0], "K_ITSHRK");
HU_UpdatePatch(&kp_thundershield[0], "K_ITTHNS");
HU_UpdatePatch(&kp_hyudoro[0], "K_ITHYUD");
HU_UpdatePatch(&kp_pogospring[0], "K_ITPOGO");
HU_UpdatePatch(&kp_kitchensink[0], "K_ITSINK");
HU_UpdatePatch(&kp_superring[0], "K_ITRING");
HU_UpdatePatch(&kp_landmine[0], "K_ITLNDM");
HU_UpdatePatch(&kp_bubbleshield[0], "K_ITBUBS");
HU_UpdatePatch(&kp_flameshield[0], "K_ITFLMS");
// Splitscreen
HU_UpdatePatch(&kp_itembg[2], "K_ISBG");
HU_UpdatePatch(&kp_itembg[3], "K_ISBGD");
HU_UpdatePatch(&kp_itembg[6], "K_ISBC");
HU_UpdatePatch(&kp_itembg[7], "K_ISBCD");
HU_UpdatePatch(&kp_itemtimer[1], "K_ISIMER");
HU_UpdatePatch(&kp_itemmulsticker[1], "K_ISMUL");
HU_UpdatePatch(&kp_itemmulsticker[3], "K_ISMULC");
HU_UpdatePatch(&kp_sadface[1], "K_ISSAD");
HU_UpdatePatch(&kp_sneaker[3], "K_ISSHOE");
HU_UpdatePatch(&kp_rocketsneaker[1], "K_ISRSHE");
sprintf(buffer, "K_ISINVx");
for (i = 0; i < 6; i++)
for (i = 0; i < numkartitems; i++)
{
buffer[7] = '1'+i;
HU_UpdatePatch(&kp_invincibility[i+7], "%s", buffer);
kartitem_t *item = &kartitems[i];
for (j = 0; j < item->graphics[0].numpatches; j++)
HU_UpdatePatch(&item->graphics[0].patches[j], item->graphics[0].patchnames[j]);
for (j = 0; j < item->graphics[1].numpatches; j++)
HU_UpdatePatch(&item->graphics[1].patches[j], item->graphics[1].patchnames[j]);
}
HU_UpdatePatch(&kp_banana[4], "K_ISBANA");
HU_UpdatePatch(&kp_eggman[1], "K_ISEGGM");
HU_UpdatePatch(&kp_orbinaut[4], "K_ISORBN");
HU_UpdatePatch(&kp_jawz[2], "K_ISJAWZ");
HU_UpdatePatch(&kp_mine[1], "K_ISMINE");
HU_UpdatePatch(&kp_ballhog[1], "K_ISBHOG");
HU_UpdatePatch(&kp_selfpropelledbomb[1], "K_ISSPB");
HU_UpdatePatch(&kp_grow[1], "K_ISGROW");
HU_UpdatePatch(&kp_shrink[1], "K_ISSHRK");
HU_UpdatePatch(&kp_thundershield[1], "K_ISTHNS");
HU_UpdatePatch(&kp_hyudoro[1], "K_ISHYUD");
HU_UpdatePatch(&kp_pogospring[1], "K_ISPOGO");
HU_UpdatePatch(&kp_kitchensink[1], "K_ISSINK");
HU_UpdatePatch(&kp_superring[1], "K_ISRING");
HU_UpdatePatch(&kp_landmine[1], "K_ISLNDM");
HU_UpdatePatch(&kp_bubbleshield[1], "K_ISBUBS");
HU_UpdatePatch(&kp_flameshield[1], "K_ISFLMS");
// CHECK indicators
sprintf(buffer, "K_CHECKx");
@ -723,101 +647,20 @@ void K_LoadKartHUDGraphics(void)
}
}
// For the item toggle menu
const char *K_GetItemPatch(UINT8 item, boolean tiny)
patch_t *K_GetCachedItemPatch(SINT8 type, boolean tiny, UINT8 amount)
{
switch (item)
{
case KITEM_SNEAKER:
return (tiny ? "K_ISSHOE" : "K_ITSHOE");
case KITEM_ROCKETSNEAKER:
return (tiny ? "K_ISRSHE" : "K_ITRSHE");
case KITEM_INVINCIBILITY:
return (tiny ? "K_ISINV1" : "K_ITINV1");
case KITEM_BANANA:
return (tiny ? "K_ISBANA" : "K_ITBANA");
case KITEM_EGGMAN:
return (tiny ? "K_ISEGGM" : "K_ITEGGM");
case KITEM_ORBINAUT:
return (tiny ? "K_ISORBN" : "K_ITORB1");
case KITEM_JAWZ:
return (tiny ? "K_ISJAWZ" : "K_ITJAWZ");
case KITEM_MINE:
return (tiny ? "K_ISMINE" : "K_ITMINE");
case KITEM_BALLHOG:
return (tiny ? "K_ISBHOG" : "K_ITBHOG");
case KITEM_SPB:
return (tiny ? "K_ISSPB" : "K_ITSPB");
case KITEM_GROW:
return (tiny ? "K_ISGROW" : "K_ITGROW");
case KITEM_SHRINK:
return (tiny ? "K_ISSHRK" : "K_ITSHRK");
case KITEM_THUNDERSHIELD:
return (tiny ? "K_ISTHNS" : "K_ITTHNS");
case KITEM_HYUDORO:
return (tiny ? "K_ISHYUD" : "K_ITHYUD");
case KITEM_POGOSPRING:
return (tiny ? "K_ISPOGO" : "K_ITPOGO");
case KITEM_KITCHENSINK:
return (tiny ? "K_ISSINK" : "K_ITSINK");
case KITEM_SUPERRING:
return (tiny ? "K_ISRING" : "K_ITRING");
case KITEM_LANDMINE:
return (tiny ? "K_ISLNDM" : "K_ITLNDM");
case KITEM_BUBBLESHIELD:
return (tiny ? "K_ISBUBS" : "K_ITBUBS");
case KITEM_FLAMESHIELD:
return (tiny ? "K_ISFLMS" : "K_ITFLMS");
case KRITEM_DUALSNEAKER:
return (tiny ? "K_ISSHOE" : "K_ITSHO2");
case KRITEM_TRIPLESNEAKER:
return (tiny ? "K_ISSHOE" : "K_ITSHO3");
case KRITEM_TRIPLEORBINAUT:
return (tiny ? "K_ISORBN" : "K_ITORB3");
case KRITEM_DUALJAWZ:
return (tiny ? "K_ISJAWZ" : "K_ITJAW2");
case KRITEM_TRIPLEBANANA:
return (tiny ? "K_ISBANA" : "K_ITBAN3");
case KRITEM_TENFOLDBANANA:
return (tiny ? "K_ISBANA" : "K_ITBAN4");
case KRITEM_QUADORBINAUT:
return (tiny ? "K_ISORBN" : "K_ITORB4");
default:
return (tiny ? "K_ISSAD" : "K_ITSAD");
}
}
static patch_t *K_GetCachedItemPatch(INT32 item, UINT8 offset)
{
patch_t **kp[1 + NUMKARTITEMS] = {
kp_sadface,
NULL,
kp_sneaker,
kp_rocketsneaker,
kp_invincibility,
kp_banana,
kp_eggman,
kp_orbinaut,
kp_jawz,
kp_mine,
kp_ballhog,
kp_selfpropelledbomb,
kp_grow,
kp_shrink,
kp_thundershield,
kp_hyudoro,
kp_pogospring,
kp_kitchensink,
kp_superring,
kp_landmine,
kp_bubbleshield,
kp_flameshield,
};
if (item == KITEM_SAD || (item > KITEM_NONE && item < NUMKARTITEMS))
return kp[item - KITEM_SAD][offset];
else
if (type == KITEM_SAD)
return tiny ? kp_sadface[1] : kp_sadface[0];
else if (type <= KITEM_NONE || type >= numkartitems)
return NULL;
kartitem_t *item = &kartitems[type];
kartitemgraphics_t *graphics = &item->graphics[tiny ? 1 : 0];
if (item->animated)
return graphics->patches[(leveltime % (graphics->numpatches*3)) / 3];
else
return graphics->patches[CLAMP(amount - 1, 0, graphics->numpatches - 1)];
}
//}
@ -1330,10 +1173,9 @@ static void K_drawKartItem(void)
// Why write V_DrawScaledPatch calls over and over when they're all the same?
// Set to 'no item' just in case.
const UINT8 offset = ((r_splitscreen > 1) ? 1 : 0);
const boolean tiny = r_splitscreen > 1;
patch_t *localpatch = kp_nodraw;
patch_t *localbg;
patch_t *localinv = ((offset) ? kp_invincibility[((leveltime % (6*3)) / 3) + 7] : kp_invincibility[(leveltime % (7*3)) / 3]);
boolean dark = false;
INT32 fx = 0, fy = 0, fflags = 0; // final coords for hud and flags...
INT32 numberdisplaymin = 2;
@ -1351,26 +1193,7 @@ static void K_drawKartItem(void)
if (K_GetHudColor())
localcolor = K_GetHudColor();
switch (item)
{
case KITEM_SNEAKER:
localpatch = kp_sneaker[offset ? 3: 0];
break;
case KITEM_BANANA:
localpatch = kp_banana[offset ? 4: 0];
break;
case KITEM_ORBINAUT:
localpatch = kp_orbinaut[3+offset];
break;
case KITEM_JAWZ:
localpatch = kp_jawz[offset ? 2: 0];
break;
case KITEM_INVINCIBILITY:
localpatch = localinv;
break;
default:
localpatch = K_GetCachedItemPatch(item, offset);
}
localpatch = K_GetCachedItemPatch(item, tiny, 0);
}
else
{
@ -1381,18 +1204,18 @@ static void K_drawKartItem(void)
if (stplyr->stolentimer > 0)
{
if (leveltime & 2)
localpatch = kp_hyudoro[offset];
localpatch = K_GetCachedItemPatch(KITEM_HYUDORO, tiny, 0);
else
localpatch = kp_nodraw;
}
else if ((stplyr->stealingtimer > 0) && (leveltime & 2))
{
localpatch = kp_hyudoro[offset];
localpatch = K_GetCachedItemPatch(KITEM_HYUDORO, tiny, 0);
}
else if (stplyr->eggmanexplode > 1)
{
if (leveltime & 1)
localpatch = kp_eggman[offset];
localpatch = K_GetCachedItemPatch(KITEM_EGGMAN, tiny, 0);
else
localpatch = kp_nodraw;
}
@ -1401,7 +1224,7 @@ static void K_drawKartItem(void)
itembar = FixedDiv(stplyr->rocketsneakertimer, itemtime*3);
if (leveltime & 1)
localpatch = kp_rocketsneaker[offset];
localpatch = K_GetCachedItemPatch(KITEM_ROCKETSNEAKER, tiny, 0);
else
localpatch = kp_nodraw;
}
@ -1409,7 +1232,6 @@ static void K_drawKartItem(void)
{
itembar = FixedDiv(stplyr->flametimer, itemtime*3);
flamebar = FixedDiv(stplyr->flamestore, FLAMESTOREMAX);
localbg = kp_itembg[offset+1];
dark = true;
if ((stplyr->flamestore >= FLAMESTOREMAX-1) && (leveltime & 1))
@ -1419,7 +1241,7 @@ static void K_drawKartItem(void)
}
if (leveltime & 1)
localpatch = kp_flameshield[offset];
localpatch = K_GetCachedItemPatch(KITEM_FLAMESHIELD, tiny, 0);
else
localpatch = kp_nodraw;
}
@ -1429,7 +1251,7 @@ static void K_drawKartItem(void)
itembar = FixedDiv(stplyr->growcancel, 26);
if (leveltime & 1)
localpatch = kp_grow[offset];
localpatch = K_GetCachedItemPatch(KITEM_GROW, tiny, 0);
else
localpatch = kp_nodraw;
}
@ -1441,13 +1263,13 @@ static void K_drawKartItem(void)
flamebar = FixedDiv(stplyr->invincibilitycancel, 26);
if (leveltime & 1)
localpatch = localinv;
localpatch = K_GetCachedItemPatch(KITEM_INVINCIBILITY, tiny, 0);
else
localpatch = kp_nodraw;
}
else if (K_GetShieldFromPlayer(stplyr) == KSHIELD_BUBBLE)
{
localpatch = kp_bubbleshield[offset];
localpatch = K_GetCachedItemPatch(KITEM_BUBBLESHIELD, tiny, 0);
dark = true;
if (stplyr->bubbleblowup > 0 && leveltime & 1)
@ -1461,7 +1283,7 @@ static void K_drawKartItem(void)
else if (stplyr->sadtimer > 0)
{
if (leveltime & 2)
localpatch = kp_sadface[offset];
localpatch = kp_sadface[tiny ? 1 : 0];
else
localpatch = kp_nodraw;
}
@ -1470,43 +1292,15 @@ static void K_drawKartItem(void)
if (stplyr->itemamount <= 0)
return;
switch(stplyr->itemtype)
localpatch = K_GetCachedItemPatch(stplyr->itemtype, tiny, stplyr->itemamount);
if (localpatch == NULL)
localpatch = kp_nodraw; // diagnose underflows
if (stplyr->itemtype > 0 && stplyr->itemtype < numkartitems)
{
case KITEM_SNEAKER:
localpatch = kp_sneaker[(offset ? 3 : min(stplyr->itemamount-1, 2))];
numberdisplaymin = 4;
numberdisplaymin = offset ? 2 : 4;
break;
case KITEM_INVINCIBILITY:
localpatch = localinv;
localbg = kp_itembg[offset+1];
break;
case KITEM_BANANA:
localpatch = kp_banana[(offset ? 4 : min(stplyr->itemamount-1, 3))];
numberdisplaymin = offset ? 2 : 5;
break;
case KITEM_ORBINAUT:
localpatch = kp_orbinaut[(offset ? 4 : min(stplyr->itemamount-1, 3))];
numberdisplaymin = offset ? 2 : 5;
break;
case KITEM_JAWZ:
localpatch = kp_jawz[(offset ? 2 : min(stplyr->itemamount-1, 1))];
numberdisplaymin = 3;
numberdisplaymin = offset ? 2 : 3;
break;
case KITEM_SPB:
case KITEM_THUNDERSHIELD:
case KITEM_BUBBLESHIELD:
case KITEM_FLAMESHIELD:
dark = true;
/*FALLTHRU*/
default:
localpatch = K_GetCachedItemPatch(stplyr->itemtype, offset);
if (localpatch == NULL)
localpatch = kp_nodraw; // diagnose underflows
break;
kartitem_t *item = &kartitems[stplyr->itemtype];
numberdisplaymin = item->animated ? 2 : item->graphics[tiny ? 1 : 0].numpatches + 1;
dark = item->darkbg;
}
if ((stplyr->itemflags & IF_ITEMOUT) && !(leveltime & 1))
@ -1532,7 +1326,7 @@ static void K_drawKartItem(void)
}
}
localbg = K_getItemBoxPatch((boolean)offset, dark);
localbg = K_getItemBoxPatch(tiny, dark);
drawinfo_t info;
K_getItemBoxDrawinfo(&info);
fx = info.x;
@ -1554,7 +1348,7 @@ static void K_drawKartItem(void)
if (cv_fancyroulette.value && stplyr->itemroulette && !stplyr->deadtimer)
{
fixed_t frac = R_GetTimeFrac(RTF_LEVEL);
UINT8 fancystep = (offset ? 6 : 10);
UINT8 fancystep = tiny ? 6 : 10;
fixed_t fancyoffset = (stplyr->itemroulette % 3)-1;
if (fancyoffset != 0)
@ -1569,10 +1363,10 @@ static void K_drawKartItem(void)
// Then, the numbers:
if (stplyr->itemamount >= numberdisplaymin && !stplyr->itemroulette)
{
localbg = K_getItemMulPatch((boolean)offset);
localbg = K_getItemMulPatch(tiny);
V_DrawMappedPatch(fx + (flipamount ? 48 : 0), fy, V_HUDTRANS|fflags|(flipamount ? V_FLIP : 0), localbg, colormap); // flip this graphic for p2 and p4 in split and shift it.
V_DrawFixedPatch(fx<<FRACBITS, fy<<FRACBITS, FRACUNIT, V_HUDTRANS|fflags, localpatch, colmap);
if (offset)
if (tiny)
if (flipamount) // reminder that this is for 3/4p's right end of the screen.
V_DrawString(fx+2, fy+31, V_ALLOWLOWERCASE|V_HUDTRANS|fflags, va("x%d", stplyr->itemamount));
else
@ -1598,7 +1392,7 @@ static void K_drawKartItem(void)
// Quick Eggman numbers
if (stplyr->eggmanexplode > 1)
V_DrawScaledPatch(fx+17, fy+13-offset, V_HUDTRANS|fflags, kp_eggnum[min(3, G_TicsToSeconds(stplyr->eggmanexplode))]);
V_DrawScaledPatch(fx+17, fy+13-(tiny ? 1 : 0), V_HUDTRANS|fflags, kp_eggnum[min(3, G_TicsToSeconds(stplyr->eggmanexplode))]);
}
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode)
@ -5758,48 +5552,12 @@ K_drawMiniPing (void)
}
}
static patch_t *K_GetSmallStaticCachedItemPatch(kartitems_t item)
{
UINT8 offset;
item = K_ItemResultToType(item);
switch (item)
{
case KITEM_INVINCIBILITY:
offset = 7;
break;
case KITEM_BANANA:
offset = 4;
break;
case KITEM_ORBINAUT:
offset = 4;
break;
case KITEM_JAWZ:
offset = 2;
break;
case KITEM_SNEAKER:
offset = 3;
break;
default:
offset = 1;
}
return K_GetCachedItemPatch(item, offset);
}
static void K_drawDistributionDebugger(void)
{
UINT8 useodds = 0;
UINT8 pingame = 0, bestbumper = 0;
UINT32 pdis = 0;
INT32 i;
INT32 item;
INT32 x = -9, y = -9;
//boolean dontforcespb = false;
boolean spbrush = false;
@ -5825,21 +5583,19 @@ static void K_drawDistributionDebugger(void)
if (pingame == 1)
{
if (stplyr->itemroulette && (stplyr->cmd.buttons & BT_ATTACK) && cv_superring.value && (K_RingsActive() == true))
V_DrawScaledPatch(x, y, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, K_GetSmallStaticCachedItemPatch(KITEM_SUPERRING));
if (stplyr->itemroulette && stplyr->cmd.buttons & BT_ATTACK && K_ItemResultEnabled("superring") && K_RingsActive())
V_DrawScaledPatch(x, y, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, K_GetCachedItemPatch(KITEM_SUPERRING, true, 0));
else
V_DrawScaledPatch(x, y, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, K_GetSmallStaticCachedItemPatch(KITEM_SNEAKER));
V_DrawScaledPatch(x, y, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, K_GetCachedItemPatch(KITEM_SNEAKER, true, 0));
V_DrawThinString(x+11, y+31, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, va("%d", 200));
}
else
{
for (item = 1; item < NUMBASEKARTRESULTS; item++)
for (i = 0; i < numkartresults; i++)
{
INT32 itemodds;
INT32 amount;
itemodds = K_KartGetItemOdds(
useodds, item,
kartresult_t *result = &kartresults[i];
INT32 itemodds = K_KartGetItemOdds(
useodds, result,
stplyr->distancetofinish,
stplyr->distancefromcluster,
0,
@ -5850,14 +5606,13 @@ static void K_drawDistributionDebugger(void)
if (itemodds <= 0)
continue;
V_DrawScaledPatch(x, y, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, K_GetSmallStaticCachedItemPatch(item));
V_DrawScaledPatch(x, y, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, K_GetCachedItemPatch(result->type, true, 0));
V_DrawThinString(x+11, y+31, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, va("%d", itemodds));
// Display amount for multi-items
amount = K_ItemResultToAmount(item);
if (amount > 1)
if (result->amount > 1)
{
V_DrawString(x+24, y+31, V_SPLITSCREEN|V_ALLOWLOWERCASE|V_HUDTRANS|V_SNAPTOTOP, va("x%d", amount));
V_DrawString(x+24, y+31, V_SPLITSCREEN|V_ALLOWLOWERCASE|V_HUDTRANS|V_SNAPTOTOP, va("x%d", result->amount));
}

View file

@ -95,11 +95,11 @@ void K_getRingsDrawinfo(drawinfo_t *out);
void K_getMinimapDrawinfo(drawinfo_t *out);
void K_getSlipstreamDrawinfo(drawinfo_t *out);
void K_getLivesnStatsDrawinfo(drawinfo_t *out);
const char *K_GetItemPatch(UINT8 item, boolean tiny);
void K_ReloadHUDColorCvar(void);
boolean K_UseColorHud(void);
UINT8 K_GetHudColor(void);
void K_LoadKartHUDGraphics(void);
patch_t *K_GetCachedItemPatch(SINT8 type, boolean tiny, UINT8 amount);
void K_drawKartHUD(void);
void K_drawKartFreePlay(void);
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode);

File diff suppressed because it is too large Load diff

147
src/k_items.h Normal file
View file

@ -0,0 +1,147 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2018-2025 by Kart Krew.
// Copyright (C) 2025 by "Anonimus".
// Copyright (C) 2025 Blankart Team.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file k_items.h
/// \brief Kart item systems.
#ifndef __K_ITEMS__
#define __K_ITEMS__
#include "doomdef.h"
#include "doomtype.h"
#ifdef __cplusplus
extern "C" {
#endif
// Max odds count
#define MAXODDS 16
// Distance variables
#define DISTVAR CV_Get(&cv_kartoddsdist)
#define DISTVAR_LEGACY CV_Get(&cv_kartlegacyoddsdist)
#define SPBDISTVAR CV_Get(&cv_kartspbdist)
#define SPBDISTVAR_LEGACY CV_Get(&cv_kartlegacyspbdist)
typedef enum
{
KITEM_SAD = -1,
KITEM_NONE = 0,
KITEM_SNEAKER,
KITEM_ROCKETSNEAKER,
KITEM_INVINCIBILITY,
KITEM_BANANA,
KITEM_EGGMAN,
KITEM_ORBINAUT,
KITEM_JAWZ,
KITEM_MINE,
KITEM_BALLHOG,
KITEM_SPB,
KITEM_GROW,
KITEM_SHRINK,
KITEM_THUNDERSHIELD,
KITEM_HYUDORO,
KITEM_POGOSPRING,
KITEM_KITCHENSINK,
KITEM_SUPERRING,
KITEM_LANDMINE,
KITEM_BUBBLESHIELD,
KITEM_FLAMESHIELD,
KITEM_FIRSTFREESLOT,
KITEM_LASTFREESLOT = 126,
MAXKARTITEMS
} ATTRPACK kartitemtype_e;
#define MAXKARTRESULTS 255
typedef enum
{
ODDS_RACE,
ODDS_BATTLE,
ODDS_SPECIAL,
MAXODDSTABLES
} ATTRPACK kartoddstable_e;
struct kartitemgraphics_t
{
UINT8 numpatches;
const char **patchnames;
patch_t **patches;
};
struct kartitem_t
{
const char *name;
consvar_t *altcvar;
kartitemgraphics_t graphics[2];
boolean animated;
boolean darkbg;
};
enum
{
KRF_INDIRECTITEM = 1<<0,
KRF_POWERITEM = 1<<1,
KRF_COOLDOWNONSTART = 1<<2,
KRF_NOTNEAREND = 1<<3,
KRF_NOTFORBOTTOM = 1<<4,
};
struct kartresult_t
{
const char *name;
consvar_t *cvar;
kartitemtype_e type;
UINT8 amount;
UINT8 odds[MAXODDSTABLES][MAXODDS];
UINT8 flags;
tic_t basebgone, bgone;
};
extern kartitem_t kartitems[MAXKARTITEMS];
extern UINT8 numkartitems;
extern kartresult_t kartresults[MAXKARTRESULTS];
extern UINT8 numkartresults;
kartresult_t *K_GetKartResult(const char *name);
void K_InitializeItems(void);
boolean K_ItemResultEnabled(const char *name);
void K_SetupItemOdds(void);
void K_KartHandleShieldCooldown(kartitemtype_e item);
boolean K_LegacyOddsMode(void);
UINT32 K_GetCongaLineDistance(const player_t *player, UINT8 startPos);
UINT32 K_CalculateInitalPDIS(const player_t *player, UINT8 pingame);
UINT32 K_CalculatePDIS(const player_t *player, UINT8 numPlayers, boolean *spbrush);
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_KartGetItemOdds(UINT8 pos, const kartresult_t *result, UINT32 ourDist, UINT32 clusterDist, fixed_t mashed, boolean spbrush, boolean bot, boolean rival, boolean inBottom);
INT32 K_GetRollingRouletteItem(player_t *player);
void K_KartItemRoulette(player_t *player, ticcmd_t *cmd);
boolean K_IsShrunk(const player_t *player);
INT16 K_GetShrinkTime(player_t *player);
fixed_t K_AccomodateShrinkScaling(fixed_t x);
boolean K_IsShrunkMode(const player_t *player, boolean legacy);
#define K_IsLegacyShrunk(player) (K_IsShrunkMode(player, true))
#define K_IsAltShrunk(player) (K_IsShrunkMode(player, false))
void K_AltShrinkIFrames(player_t *player);
void K_AltShrinkPityIncrease(player_t *player);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __K_ITEMS__

View file

@ -64,9 +64,8 @@
#include "k_follower.h"
#include "k_grandprix.h"
#include "k_cluster.hpp"
#include "k_odds.h"
#include "k_items.h"
#include "k_specialstage.h"
#include "k_altshrink.h"
#include "h_timers.h"
#include "blan/b_soc.h"
@ -233,37 +232,6 @@ angle_t K_ReflectAngle(angle_t yourangle, angle_t theirangle, fixed_t yourspeed,
void K_RegisterKartStuff(void)
{
CV_RegisterVar(&cv_sneaker);
CV_RegisterVar(&cv_rocketsneaker);
CV_RegisterVar(&cv_invincibility);
CV_RegisterVar(&cv_banana);
CV_RegisterVar(&cv_eggmanmonitor);
CV_RegisterVar(&cv_orbinaut);
CV_RegisterVar(&cv_jawz);
CV_RegisterVar(&cv_mine);
CV_RegisterVar(&cv_ballhog);
CV_RegisterVar(&cv_selfpropelledbomb);
CV_RegisterVar(&cv_grow);
CV_RegisterVar(&cv_shrink);
CV_RegisterVar(&cv_thundershield);
CV_RegisterVar(&cv_hyudoro);
CV_RegisterVar(&cv_pogospring);
CV_RegisterVar(&cv_kitchensink);
// Nu-ITEMS
CV_RegisterVar(&cv_superring);
CV_RegisterVar(&cv_landmine); // FIXME: Kill it.
CV_RegisterVar(&cv_bubbleshield);
CV_RegisterVar(&cv_flameshield);
CV_RegisterVar(&cv_dualsneaker);
CV_RegisterVar(&cv_triplesneaker);
CV_RegisterVar(&cv_triplebanana);
CV_RegisterVar(&cv_decabanana);
CV_RegisterVar(&cv_tripleorbinaut);
CV_RegisterVar(&cv_quadorbinaut);
CV_RegisterVar(&cv_dualjawz);
CV_RegisterVar(&cv_kartminimap);
CV_RegisterVar(&cv_kartcheck);
CV_RegisterVar(&cv_kartinvinsfx);
@ -289,8 +257,6 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartusepwrlv);
CV_RegisterVar(&cv_votetime);
CV_RegisterVar(&cv_kartdebugitem);
CV_RegisterVar(&cv_kartdebugamount);
CV_RegisterVar(&cv_kartdebugshrink);
CV_RegisterVar(&cv_kartdebugdistribution);
CV_RegisterVar(&cv_kartdebughuddrop);
@ -415,10 +381,8 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartslopeboost);
CV_RegisterVar(&cv_kartshrinktype);
CV_RegisterVar(&cv_kartaltshrinktime);
CV_RegisterVar(&cv_kartinvintype);
CV_RegisterVar(&cv_kartinvindist);
CV_RegisterVar(&cv_kartinvindistmul);
@ -4742,7 +4706,7 @@ static void K_DoHyudoroSteal(player_t *player)
prandom = P_RandomFixed();
S_StartSound(player->mo, sfx_s3k92);
if (sink && numplayers > 0 && cv_kitchensink.value) // BEHOLD THE KITCHEN SINK
if (sink && numplayers > 0 && K_ItemResultEnabled("kitchensink")) // BEHOLD THE KITCHEN SINK
{
player->hyudorotimer = hyu;
player->stealingtimer = stealtime;
@ -5538,7 +5502,7 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8
if (type == 0)
{
UINT8 useodds = 0;
INT32 spawnchance[NUMBASEKARTRESULTS];
INT32 spawnchance[MAXKARTRESULTS];
INT32 totalspawnchance = 0;
INT32 i;
@ -5546,10 +5510,10 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8
useodds = amount;
for (i = 1; i < NUMBASEKARTRESULTS; i++)
for (i = 0; i < numkartresults; i++)
{
spawnchance[i] = (totalspawnchance += K_KartGetItemOdds(
useodds, i,
useodds, &kartresults[i],
UINT32_MAX,
0,
0,
@ -5561,30 +5525,29 @@ mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8
if (totalspawnchance > 0)
{
totalspawnchance = P_RandomKey(totalspawnchance);
for (i = 0; i < NUMBASEKARTRESULTS && spawnchance[i] <= totalspawnchance; i++);
for (i = 0; i < numkartresults && spawnchance[i] <= totalspawnchance; i++);
// TODO: this is bad!
// K_KartGetItemResult requires a player
// but item roulette will need rewritten to change this
const UINT8 newType = K_ItemResultToType(i);
const UINT8 newAmount = K_ItemResultToAmount(i);
const kartresult_t *result = &kartresults[i];
if (newAmount > 1)
if (result->amount > 1)
{
UINT8 j;
for (j = 0; j < newAmount-1; j++)
for (j = 0; j < result->amount-1; j++)
{
K_CreatePaperItem(
x, y, z,
angle, flip,
newType, 1
result->type, 1
);
}
}
drop->threshold = newType;
drop->threshold = result->type;
drop->movecount = 1;
}
else
@ -11507,30 +11470,10 @@ boolean K_ItemPushingActive(void)
return itempushing;
}
boolean K_GetKartInvinType(void)
{
return invintype;
}
boolean K_IsKartItemAlternate(UINT8 itemtype)
{
switch (itemtype)
{
case KITEM_INVINCIBILITY:
return invintype == KARTITEM_ALTERN;
break;
case KITEM_EGGMAN:
return eggmantype == KARTITEM_ALTERN;
break;
case KITEM_SHRINK:
return shrinktype == KARTITEM_ALTERN;
break;
default:
return false;
break;
}
return false;
return itemtype >= 0 && itemtype < numkartitems
&& kartitems[itemtype].altcvar != NULL && kartitems[itemtype].altcvar->value == 1;
}
boolean K_UsingLegacyCheckpoints(void)

View file

@ -126,6 +126,11 @@ extern vector3_t clusterpoint, clusterdtf;
#define FLAMEACCELBOOST CV_Get(&cv_kartstacking_flame_accelboost)
#define FLAMESTACKABLE CV_Get(&cv_kartstacking_flame_stackable)
#define ALTSHRINKTIME CV_Get(&cv_kartaltshrinktime)
#define SHRINKSPEEDBOOST CV_Get(&cv_kartstacking_altshrink_speedboost)
#define SHRINKACCELBOOST CV_Get(&cv_kartstacking_altshrink_accelboost)
#define SHRINKSTACKABLE CV_Get(&cv_kartstacking_altshrink_stackable)
#define STARTSPEEDBOOST CV_Get(&cv_kartstacking_start_speedboost)
#define STARTACCELBOOST CV_Get(&cv_kartstacking_start_accelboost)
#define STARTSTACKABLE CV_Get(&cv_kartstacking_start_stackable)
@ -344,7 +349,6 @@ boolean K_DraftingActive(void);
boolean K_AirDropActive(void);
boolean K_ItemLitterActive(void);
boolean K_ItemPushingActive(void);
boolean K_GetKartInvinType(void);
boolean K_IsKartItemAlternate(UINT8 itemtype);
INT32 K_GetBumpSpark(void);
boolean K_BoostChain(player_t *player, INT32 timer, boolean chainsound);

View file

@ -1,72 +0,0 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2018-2025 by Kart Krew.
// Copyright (C) 2025 by "Anonimus".
// Copyright (C) 2025 Blankart Team.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file k_odds.hpp
/// \brief Kart item odds systems.
#ifndef __K_ODDS__
#define __K_ODDS__
#include "command.h" // Need for player_t
#include "doomdef.h"
#include "doomtype.h"
#include "d_player.h" // Need for player_t
#include "d_ticcmd.h"
#include "m_fixed.h"
#ifdef __cplusplus
extern "C" {
#endif
// Max odds count
#define MAXODDS 16
// Distance variables
#define DISTVAR CV_Get(&cv_kartoddsdist)
#define DISTVAR_LEGACY CV_Get(&cv_kartlegacyoddsdist)
#define SPBDISTVAR CV_Get(&cv_kartspbdist)
#define SPBDISTVAR_LEGACY CV_Get(&cv_kartlegacyspbdist)
extern consvar_t *KartItemCVars[NUMKARTRESULTS-1];
// Goner; tracks how long an item should be "gone" for.
// AKA a time-based cooldown so Hyudoro and whatever else piss off to prevent
// spamming.
typedef enum goner_sect_e {
GONER_BASECOOLDOWN = 0,
GONER_CURRCOOLDOWN = 1,
} goner_sect_t;
extern tic_t ItemBGone[NUMKARTRESULTS][2];
void K_SetBGone(SINT8 item, tic_t time);
void K_SetBGoneToBase(SINT8 item);
tic_t K_GetBGone(SINT8 item, boolean base);
void K_KartHandleShieldCooldown(SINT8 item);
boolean K_LegacyOddsMode(void);
UINT32 K_GetCongaLineDistance(const player_t *player, UINT8 startPos);
UINT32 K_CalculateInitalPDIS(const player_t *player, UINT8 pingame);
UINT32 K_CalculatePDIS(const player_t *player, UINT8 numPlayers, boolean *spbrush);
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_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, UINT32 clusterDist, fixed_t mashed, boolean spbrush, boolean bot, boolean rival, boolean inBottom);
INT32 K_GetRollingRouletteItem(player_t *player);
SINT8 K_ItemResultToType(SINT8 getitem);
UINT8 K_ItemResultToAmount(SINT8 getitem);
void K_KartItemRoulette(player_t *player, ticcmd_t *cmd);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __K_ODDS__

View file

@ -33,7 +33,7 @@
#include "k_color.h"
#include "k_hud.h"
#include "k_waypoint.h"
#include "k_odds.h"
#include "k_items.h"
#include "d_netcmd.h" // IsPlayerAdmin
#include "m_menu.h" // Player Setup menu color stuff
#include "p_spec.h" // P_StartQuake
@ -4026,10 +4026,20 @@ static int lib_kGetKartFlashing(lua_State *L)
static int lib_kGetItemPatch(lua_State *L)
{
UINT8 item = (UINT8)luaL_optinteger(L, 1, KITEM_NONE);
kartitemtype_e item = (kartitemtype_e)luaL_optinteger(L, 1, KITEM_NONE);
boolean tiny = lua_optboolean(L, 2);
//HUDSAFE
lua_pushstring(L, K_GetItemPatch(item, tiny));
// TODO: compatmode KRITEM
const char *sad = tiny ? "K_ISSAD" : "K_ITSAD";
if (item <= 0 || item >= numkartitems)
{
lua_pushstring(L, sad);
return 1;
}
kartitemgraphics_t *graphics = &kartitems[item].graphics[tiny ? 1 : 0];
lua_pushstring(L, graphics->numpatches == 0 ? sad : graphics->patchnames[0]);
return 1;
}
@ -4111,48 +4121,10 @@ static int lib_kSetHyuCountdown(lua_State *L)
{
tic_t c = (tic_t)luaL_checkinteger(L, 1);
NOHUD
K_SetBGone(KITEM_HYUDORO, c);
K_GetKartResult("hyudoro")->bgone = c;
return 0;
}
static int lib_kSetBGone(lua_State *L)
{
SINT8 item = (SINT8)luaL_checkinteger(L, 1);
tic_t c = (tic_t)luaL_checkinteger(L, 2);
NOHUD
if (item < KITEM_SNEAKER || item > (NUMKARTRESULTS - 1))
{
luaL_error(L, "given item ID is outside bgone range");
}
K_SetBGone(item, c);
return 0;
}
static int lib_kSetBGoneToBase(lua_State *L)
{
SINT8 item = (SINT8)luaL_checkinteger(L, 1);
NOHUD
if (item < KITEM_SNEAKER || item > (NUMKARTRESULTS - 1))
{
luaL_error(L, "given item ID is outside bgone range");
}
K_SetBGoneToBase(item);
return 0;
}
static int lib_kGetBGone(lua_State *L)
{
SINT8 item = (SINT8)luaL_checkinteger(L, 1);
boolean base = lua_isnoneornil(L, 2) ? false : luaL_checkboolean(L, 2);
NOHUD
if (item < KITEM_SNEAKER || item > (NUMKARTRESULTS - 1))
{
luaL_error(L, "given item ID is outside bgone range");
}
lua_pushinteger(L, K_GetBGone(item, base));
return 1;
}
// Checks if the floor closet floor under an object would be safe to respawn/land on.
static int lib_kSafeRespawnPosition(lua_State *L)
{
@ -4227,13 +4199,6 @@ static int lib_kItemLitterActive(lua_State *L)
return 1;
}
// Grabs the currently active invintype.
static int lib_kGetKartInvinType(lua_State *L)
{
lua_pushinteger(L, K_GetKartInvinType());
return 1;
}
// Gets the currently active bumpspark type.
static int lib_kGetBumpSpark(lua_State *L)
{
@ -5341,9 +5306,6 @@ static luaL_Reg lib[] = {
{"K_SetExitCountdown",lib_kSetExitCountdown},
{"K_SetIndirectItemCooldown",lib_kSetIndirectItemCountdown},
{"K_SetHyudoroCooldown",lib_kSetHyuCountdown},
{"K_SetBGone", lib_kSetBGone},
{"K_SetBGoneToBase", lib_kSetBGoneToBase},
{"K_GetBGone", lib_kGetBGone},
{"K_SafeRespawnPosition",lib_kSafeRespawnPosition},
{"K_GetCollideAngle",lib_kGetCollideAngle},
@ -5358,7 +5320,6 @@ static luaL_Reg lib[] = {
{"K_AirDropActive",lib_kAirDropActive},
{"K_ItemLitterActive",lib_kItemLitterActive},
{"K_GetBumpSpark",lib_kGetBumpSpark},
{"K_GetKartInvinType",lib_kGetKartInvinType},
{"K_UsingLegacyCheckpoints",lib_kUsingLegacyCheckpoints},
{"K_DoBoost",lib_kDoBoost},
{"K_ClearBoost",lib_kClearBoost},

View file

@ -27,7 +27,7 @@
#include "p_slopes.h" // for P_SlopeById and slopelist
#include "p_polyobj.h" // polyobj_t, PolyObjects
#include "k_battle.h"
#include "k_odds.h"
#include "k_items.h"
#include "k_waypoint.h"
#ifdef LUA_ALLOW_BYTECODE
#include "d_netfil.h" // for LUA_DumpFile
@ -417,11 +417,8 @@ int LUA_PushGlobals(lua_State *L, const char *word)
} else if (fastcmp(word,"itempushing")) {
lua_pushboolean(L, itempushing); // hmm... i think this should be a boolean
return 1;
} else if (fastcmp(word,"invintype")) {
lua_pushinteger(L, invintype);
return 1;
} else if (fastcmp(word,"hyubgone")) {
lua_pushinteger(L, K_GetBGone(KITEM_HYUDORO, false));
lua_pushinteger(L, K_GetKartResult("hyudoro")->bgone);
return 1;
} else if (fastcmp(word,"encoremode")) {
lua_pushboolean(L, encoremode);
@ -564,9 +561,7 @@ int LUA_WriteGlobals(lua_State *L, const char *word)
else if (fastcmp(word,"indirectitemcooldown"))
indirectitemcooldown = (tic_t)luaL_checkinteger(L, 2);
else if (fastcmp(word,"hyubgone"))
{
K_SetBGone(KITEM_HYUDORO, (tic_t)luaL_checkinteger(L, 2));
}
K_GetKartResult("hyudoro")->bgone = (tic_t)luaL_checkinteger(L, 2);
else if (fastcmp(word,"starttime"))
starttime = (tic_t)luaL_checkinteger(L, 2);
else if (fastcmp(word,"introtime"))

View file

@ -67,7 +67,7 @@
#include "i_sound.h"
#include "k_hud.h" // SRB2kart
#include "k_kart.h"
#include "k_odds.h" // KartItemCVars
#include "k_items.h" // KartItemCVars
#include "k_pwrlv.h"
#include "k_stats.h" // SRB2kart
#include "d_player.h" // KITEM_ constants
@ -8327,8 +8327,7 @@ void MD_DrawMonitorToggles(void)
INT32 leftdraw, rightdraw, totaldraw;
INT32 x = currentMenu->x, y = currentMenu->y+(spacing/4);
INT32 onx = 0, ony = 0;
consvar_t *cv;
INT32 i, translucent, drawnum;
INT32 i, translucent, drawnum, arg;
M_DrawMenuTitle();
@ -8353,7 +8352,7 @@ void MD_DrawMonitorToggles(void)
{
INT32 j;
for (j = 0; j < height; j++)
for (j = 0; j < height; j++, y += spacing)
{
const INT32 thisitem = (i*height)+j;
@ -8364,64 +8363,45 @@ void MD_DrawMonitorToggles(void)
{
onx = x;
ony = y;
y += spacing;
continue;
}
#ifdef ITEMTOGGLEBOTTOMRIGHT
if (currentMenu->menuitems[thisitem].argument == 255)
arg = currentMenu->menuitems[thisitem].argument;
if (arg == 255)
{
V_DrawScaledPatch(x, y, V_TRANSLUCENT, W_CachePatchName("K_ISBG", PU_CACHE));
continue;
}
#endif
if (currentMenu->menuitems[thisitem].argument == 0)
else if (arg == 0)
{
V_DrawScaledPatch(x, y, 0, W_CachePatchName("K_ISBG", PU_CACHE));
V_DrawScaledPatch(x, y, 0, W_CachePatchName("K_ISTOGL", PU_CACHE));
continue;
}
cv = KartItemCVars[currentMenu->menuitems[thisitem].argument-1];
translucent = (cv->value ? 0 : V_TRANSLUCENT);
switch (currentMenu->menuitems[thisitem].argument)
else if (arg <= 0 && arg > numkartresults)
{
case KRITEM_DUALSNEAKER:
case KRITEM_DUALJAWZ:
drawnum = 2;
break;
case KRITEM_TRIPLESNEAKER:
case KRITEM_TRIPLEBANANA:
case KRITEM_TRIPLEORBINAUT:
drawnum = 3;
break;
case KRITEM_QUADORBINAUT:
drawnum = 4;
break;
case KRITEM_TENFOLDBANANA:
drawnum = 10;
break;
default:
drawnum = 0;
break;
continue;
}
if (cv->value)
kartresult_t *result = &kartresults[arg - 1];
kartitem_t *item = &kartitems[result->type];
boolean enabled = K_ItemResultEnabled(result->name);
translucent = enabled ? 0 : V_TRANSLUCENT;
drawnum = item->animated ? 0 : CLAMP(result->amount, 0, item->graphics[1].numpatches - 1);
if (enabled)
V_DrawScaledPatch(x, y, 0, W_CachePatchName("K_ISBG", PU_CACHE));
else
V_DrawScaledPatch(x, y, 0, W_CachePatchName("K_ISBGD", PU_CACHE));
if (drawnum != 0)
if (drawnum > 1)
{
V_DrawScaledPatch(x, y, 0, W_CachePatchName("K_ISMUL", PU_CACHE));
V_DrawScaledPatch(x, y, translucent, W_CachePatchName(K_GetItemPatch(currentMenu->menuitems[thisitem].argument, true), PU_CACHE));
V_DrawScaledPatch(x, y, translucent, K_GetCachedItemPatch(result->type, true, result->amount));
V_DrawString(x+24, y+31, V_ALLOWLOWERCASE|translucent, va("x%d", drawnum));
}
else
V_DrawScaledPatch(x, y, translucent, W_CachePatchName(K_GetItemPatch(currentMenu->menuitems[thisitem].argument, true), PU_CACHE));
y += spacing;
V_DrawScaledPatch(x, y, translucent, K_GetCachedItemPatch(result->type, true, result->amount));
}
x += spacing;
@ -8429,8 +8409,8 @@ void MD_DrawMonitorToggles(void)
}
{
#ifdef ITEMTOGGLEBOTTOMRIGHT
if (currentMenu->menuitems[itemOn].argument == 255)
arg = currentMenu->menuitems[itemOn].argument;
if (arg == 255)
{
V_DrawScaledPatch(onx-1, ony-2, V_TRANSLUCENT, W_CachePatchName("K_ITBG", PU_CACHE));
if (shitsfree)
@ -8443,46 +8423,43 @@ void MD_DrawMonitorToggles(void)
V_DrawScaledPatch(onx-1, ony-2, trans, W_CachePatchName("K_ITFREE", PU_CACHE));
}
}
else
#endif
if (currentMenu->menuitems[itemOn].argument == 0)
else if (arg == 0)
{
V_DrawScaledPatch(onx-1, ony-2, 0, W_CachePatchName("K_ITBG", PU_CACHE));
V_DrawScaledPatch(onx-1, ony-2, 0, W_CachePatchName("K_ITTOGL", PU_CACHE));
}
else
else if (arg > 0 && arg <= numkartresults)
{
cv = KartItemCVars[currentMenu->menuitems[itemOn].argument-1];
translucent = (cv->value ? 0 : V_TRANSLUCENT);
kartresult_t *result = &kartresults[arg - 1];
kartitem_t *item = &kartitems[result->type];
boolean enabled = K_ItemResultEnabled(result->name);
translucent = enabled ? 0 : V_TRANSLUCENT;
drawnum = item->animated ? 0 : CLAMP(result->amount, 0, item->graphics[0].numpatches - 1);
switch (currentMenu->menuitems[itemOn].argument)
{
case KRITEM_TENFOLDBANANA:
drawnum = 10;
break;
default:
drawnum = 0;
break;
}
if (cv->value)
if (enabled)
V_DrawScaledPatch(onx-1, ony-2, 0, W_CachePatchName("K_ITBG", PU_CACHE));
else
V_DrawScaledPatch(onx-1, ony-2, 0, W_CachePatchName("K_ITBGD", PU_CACHE));
if (drawnum != 0)
if (drawnum > 1)
{
V_DrawScaledPatch(onx-1, ony-2, 0, W_CachePatchName("K_ITMUL", PU_CACHE));
V_DrawScaledPatch(onx-1, ony-2, translucent, W_CachePatchName(K_GetItemPatch(currentMenu->menuitems[itemOn].argument, false), PU_CACHE));
V_DrawScaledPatch(onx-1, ony-2, translucent, K_GetCachedItemPatch(result->type, false, result->amount));
V_DrawScaledPatch(onx+27, ony+39, translucent, W_CachePatchName("K_ITX", PU_CACHE));
V_DrawKartString(onx+37, ony+34, translucent, va("%d", drawnum));
}
else
V_DrawScaledPatch(onx-1, ony-2, translucent, W_CachePatchName(K_GetItemPatch(currentMenu->menuitems[itemOn].argument, false), PU_CACHE));
V_DrawScaledPatch(onx-1, ony-2, translucent, K_GetCachedItemPatch(result->type, false, result->amount));
if (item->altcvar != NULL)
{
translucent = item->altcvar->value == 1 ? 0 : V_TRANSLUCENT;
V_DrawScaledPatch(onx-1, ony-2, translucent, W_CachePatchName("K_ALTITM", PU_CACHE));
}
}
}
if (shitsfree)
if (renderisnewtic && shitsfree)
shitsfree--;
V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y, MENUCAPS|highlightflags, va("* %s *", currentMenu->menuitems[itemOn].text));
@ -8493,7 +8470,11 @@ INT32 MR_HandleMonitorToggles(INT32 choice)
const INT32 width = 6, height = 4;
INT32 column = itemOn/height, row = itemOn%height;
INT16 next;
UINT8 i;
kartresult_t *result = NULL;
INT32 arg = currentMenu->menuitems[itemOn].argument;
if (arg > 0 && arg <= numkartresults)
result = &kartresults[arg - 1];
switch (choice)
{
@ -8542,8 +8523,7 @@ INT32 MR_HandleMonitorToggles(INT32 choice)
break;
case KEY_ENTER:
#ifdef ITEMTOGGLEBOTTOMRIGHT
if (currentMenu->menuitems[itemOn].argument == 255)
if (choice == 255)
{
//S_StartSound(NULL, sfx_s26d);
if (!shitsfree)
@ -8552,29 +8532,34 @@ INT32 MR_HandleMonitorToggles(INT32 choice)
S_StartSound(NULL, sfx_itfree);
}
}
else
#endif
if (currentMenu->menuitems[itemOn].argument == 0)
else if (choice == 0)
{
INT32 v = cv_sneaker.value;
INT32 v = K_ItemResultEnabled("sneaker") ? 1 : 0;
S_StartSound(NULL, sfx_s1b4);
for (i = 0; i < NUMBASEKARTRESULTS-1; i++)
for (UINT8 i = 0; i < numkartresults; i++)
{
if (KartItemCVars[i]->value == v)
CV_AddValue(KartItemCVars[i], 1);
if (kartresults[i].cvar->value == v)
CV_AddValue(kartresults[i].cvar, 1);
}
}
else
else if (result != NULL)
{
S_StartSound(NULL, sfx_s1ba);
CV_AddValue(KartItemCVars[currentMenu->menuitems[itemOn].argument-1], 1);
CV_AddValue(result->cvar, 1);
}
break;
case KEY_BACKSPACE:
if (result != NULL && kartitems[result->type].altcvar != NULL)
{
S_StartSound(NULL, sfx_s3kb7);
CV_AddValue(kartitems[result->type].altcvar, 1);
}
break;
default:
return false;
}
return true;
}

View file

@ -30,6 +30,7 @@
#include "k_waypoint.h"
#include "k_battle.h"
#include "k_collide.h"
#include "k_items.h"
#ifdef HW3SOUND
#include "hardware/hw3sound.h"

View file

@ -39,7 +39,7 @@
#include "k_boss.h"
#include "p_spec.h"
#include "k_objects.h"
#include "k_odds.h"
#include "k_items.h"
#include "acs/interface.h"
// CTF player names
@ -1742,7 +1742,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
break;
}
if (target->threshold < 1 || target->threshold >= NUMKARTITEMS) // bruh moment prevention
if (target->threshold < 1 || target->threshold >= numkartitems) // bruh moment prevention
{
player->itemtype = KITEM_SAD;
player->itemamount = 1;

View file

@ -50,7 +50,7 @@
#include "k_terrain.h"
#include "k_collide.h"
#include "k_objects.h"
#include "k_odds.h"
#include "k_items.h"
#include "k_waypoint.h"
// BlanKart
@ -4166,7 +4166,7 @@ static void P_RefreshItemCapsuleParts(mobj_t *mobj)
mobj_t *part;
UINT32 newRenderFlags = 0;
if (itemType < 1 || itemType >= NUMKARTITEMS)
if (itemType < 1 || itemType >= numkartitems)
itemType = KITEM_SAD;
part = mobj;
@ -11385,7 +11385,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
else if (P_RandomChance(FRACUNIT/3))
mobj->threshold = KITEM_ORBINAUT;
else
mobj->threshold = P_RandomRange(1, NUMKARTITEMS - 1);
mobj->threshold = P_RandomRange(1, numkartitems - 1);
mobj->movecount = P_RandomChance(FRACUNIT/3) ? 1 : P_RandomKey(32) + 1;
#else
mobj->threshold = KITEM_SUPERRING; // default item is super ring
@ -12807,7 +12807,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
}
case MT_ITEMCAPSULE:
{
boolean isRingCapsule = (mthing->args[0] < 1 || mthing->args[0] == KITEM_SUPERRING || mthing->args[0] >= NUMKARTITEMS);
boolean isRingCapsule = mthing->args[0] < 1 || mthing->args[0] == KITEM_SUPERRING || mthing->args[0] >= numkartitems;
// don't spawn ring capsules in with rings off.
if (isRingCapsule && (K_RingsActive() == false))
@ -13666,7 +13666,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
mobj->flags |= MF_NOGRAVITY;
// Angle = item type
if (mthing->args[0] > 0 && mthing->args[0] < NUMKARTITEMS)
if (mthing->args[0] > 0 && mthing->args[0] < numkartitems)
mobj->threshold = mthing->args[0];
// Parameter = extra items (x5 for rings)

View file

@ -41,11 +41,10 @@
#include "k_battle.h"
#include "k_pwrlv.h"
#include "k_terrain.h"
#include "k_odds.h"
#include "k_items.h"
#include "acs/interface.h"
#include "g_party.h"
#include "k_waypoint.h"
#include "k_altshrink.h"
#include <tracy/tracy/TracyC.h>
@ -4099,8 +4098,6 @@ static boolean P_NetSyncMisc(savebuffer_t *save, boolean resending)
SYNCBOOLEAN(itemlittering);
SYNCBOOLEAN(itempushing);
SYNC(bumpsparkactive);
SYNC(invintype);
SYNC(shrinktype);
SYNC(antibumptime);
for (i = 0; i < sizeof(votelevels)/sizeof(*votelevels); i++)
@ -4187,11 +4184,11 @@ static boolean P_NetSyncMisc(savebuffer_t *save, boolean resending)
SYNC(wantedcalcdelay);
SYNC(indirectitemcooldown);
for (i = 0; i < NUMKARTRESULTS; i++)
for (i = 0; i < numkartresults; i++)
{
// hyubgone
//SYNC(ItemBGone[i][GONER_BASECOOLDOWN]);
SYNC(ItemBGone[i][GONER_CURRCOOLDOWN]);
//SYNC(kartresults[i].basebgone);
SYNC(kartresults[i].bgone);
}
SYNC(mapreset);

View file

@ -103,13 +103,12 @@
#include "k_terrain.h" // TRF_TRIPWIRE
#include "k_brightmap.h"
#include "k_director.h" // K_InitDirector
#include "k_odds.h" // ItemBGone
#include "k_items.h"
#include "acs/interface.h"
#include "doomstat.h" // MAXMUSNAMES
#include "k_mapuser.h"
#include "p_deepcopy.h"
#include "k_specialstage.h"
#include "k_altshrink.h"
#include "blan/b_soc.h"
@ -8072,11 +8071,12 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
itempushing = true;
bumpsparkactive = (UINT8)cv_kartbumpspark.value;
invintype = (UINT8)cv_kartinvintype.value;
K_UpdateShrinkType();
antibumptime = (tic_t)cv_kartantibump.value * TICRATE;
if (!reloadinggamestate)
K_SetupItemOdds();
// emerald hunt
hunt1 = hunt2 = hunt3 = NULL;
@ -8402,10 +8402,10 @@ static void P_InitGametype(void)
wantedcalcdelay = wantedfrequency*2;
indirectitemcooldown = 0;
for (i = 0; i < NUMKARTRESULTS; i++)
for (i = 0; i < numkartresults; i++)
{
// hyubgone
ItemBGone[i][GONER_CURRCOOLDOWN] = 0;
kartresults[i].bgone = 0;
}
mapreset = 0;

View file

@ -44,7 +44,7 @@
// SRB2kart
#include "k_kart.h"
#include "k_altshrink.h"
#include "k_items.h"
#include "console.h" // CON_LogMessage
#include "k_terrain.h"
#include "acs/interface.h"

View file

@ -41,7 +41,7 @@
#include "k_director.h"
#include "acs/interface.h"
#include "k_bot.h" // K_BotTicker
#include "k_odds.h" // ItemBGone
#include "k_items.h" // ItemBGone
#include "k_specialstage.h"
#ifdef PARANOIA
@ -902,13 +902,11 @@ void P_Ticker(boolean run)
if (indirectitemcooldown > 0)
indirectitemcooldown--;
for (i = 0; i < NUMKARTRESULTS; i++)
for (i = 0; i < numkartresults; i++)
{
// hyubgone
if (K_GetBGone(i, false) > 0)
{
ItemBGone[i][GONER_CURRCOOLDOWN]--;
}
if (kartresults[i].bgone > 0)
kartresults[i].bgone--;
}
if (gametyperules & GTR_RACEODDS)

View file

@ -61,8 +61,7 @@
#include "k_terrain.h" // K_SpawnSplashForMobj
#include "k_color.h"
#include "k_follower.h"
#include "k_odds.h"
#include "k_altshrink.h"
#include "k_items.h"
#include "g_party.h"
#include "acs/interface.h"

View file

@ -18,6 +18,7 @@
#include "p_tick.h"
#include "typedef.h"
#include "r_fps.h"
#include "k_items.h"
#ifdef ROTSPRITE
fixed_t rollcosang[ROTANGLES];

View file

@ -208,6 +208,11 @@ TYPEDEF (waypoint_t);
TYPEDEF (mapUserProperty_t);
TYPEDEF (mapUserProperties_t);
// k_items.h
TYPEDEF (kartitem_t);
TYPEDEF (kartresult_t);
TYPEDEF (kartitemgraphics_t);
// lua_hudlib_drawlist.h
typedef struct huddrawlist_s *huddrawlist_h;