Merge branch 'blankart-dev' into openalclassic
This commit is contained in:
commit
d64c36bbf7
68 changed files with 4447 additions and 3691 deletions
|
|
@ -87,10 +87,16 @@ option(SRB2_CONFIG_PROFILEMODE "Compile for profiling (GCC only)." OFF)
|
|||
option(SRB2_CONFIG_TRACY "Compile with Tracy profiling enabled" OFF)
|
||||
option(SRB2_CONFIG_ASAN "Compile with AddressSanitizer (libasan)." OFF)
|
||||
option(SRB2_CONFIG_UBSAN "Compile with UndefinedBehaviorSanitizer (libubsan)." OFF)
|
||||
option(SRB2_CONFIG_NOVERIFYIWADS "Compile with IWAD verification turned off." OFF)
|
||||
set(SRB2_CONFIG_ASSET_DIRECTORY "" CACHE PATH "Path to directory that contains all asset files for the installer. If set, assets will be part of installation and cpack.")
|
||||
option(SRB2_CONFIG_LTO "Enable link time optimizations, improves performance at the cost of longer link times." ON)
|
||||
option(SRB2_CONFIG_TIDY "Enable clang tiny, checks compiled code for issues at the cost of longer compile times." OFF)
|
||||
|
||||
if(SRB2_CONFIG_NOVERIFYIWADS)
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DNOVERIFYIWADS)
|
||||
endif()
|
||||
|
||||
|
||||
if(SRB2_CONFIG_ENABLE_TESTS)
|
||||
# https://github.com/catchorg/Catch2
|
||||
CPMAddPackage(
|
||||
|
|
|
|||
64
extras/Items.md
Normal file
64
extras/Items.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# Items
|
||||
|
||||
BlanKart features its own collection of both new items and toggleable alternate takes on existing SRB2Kart v1 items. Most new items also appear in Ring Racers, but function significantly differently. This wiki page will cover all necessary information for these items.
|
||||
|
||||
## Alternate Items
|
||||
|
||||
Alternative items are secondary versions of existing SRB2Kart items that **reinterpret them in (mostly) unique ways**. As BlanKart develops further, more alternate items may appear.
|
||||
|
||||
To toggle on/off these alternate versions, you can do so with the following commands:
|
||||
|
||||
- ``altitem_invincibility`` (for Invincibility)
|
||||
- ``altitem_shrink`` (for Shrink)
|
||||
|
||||
### Alt. Invincibility (Power: Occupies Slot)
|
||||
Invincibility, in its normal form, is a power item that appears in the lower ranks, letting players cut through offroad and spin out opponents with prejudice. **Alt. Invincibility** works significantly different, trading its aggression for speed and optimized recovery.
|
||||
|
||||
To begin, Alt. Invincibility's item odds work as an inversion of the Self-Propelled Bomb's: Like how the S.P.B. only appears when first is extremely far ahead of the pack, Alt. Invincibility only reveals itself to players who are **extremely far behind the pack**. In some extreme cases, Alt. Invincibilty will override the race-start cooldown to power-up players already left in the dust.
|
||||
|
||||
Unlike the standard Invincibility, **you can't damage players with Alt. Invincibility**, instead bumping them like you would normally.
|
||||
|
||||
Its time limit (and power) is directly tied to your distance from the "cluster player", the player closest to the largest collection on the map of (losing) players. If you notice yourself falling super far behind on the minimap, you're likely to roll Alt. Invincibility. **The further the distance, the stronger your invincibility**, and the faster you'll go. Think of it like a non-autopilot version of Mario Kart's Bullet Bill, or Sonic Racing's Drill Wisp. _Make huge comebacks, and don't lose hope!_
|
||||
|
||||
Do note, though: Alt. Invincibility is designed as a "gap closer", and not traditional catchup. Once you pass the cluster player, the timer **decreases at an exponentially fast rate**; don't count on it to let you steal wins from the leader!
|
||||
|
||||
As you run out of power (your Invincibility drops below 5 seconds), **offroad will gradually begin to affect you again**. A warning signal usually sounds as your invincibility is about to run out, as well. Be careful when you see the rainbow color begin to fade!
|
||||
|
||||
If you want something else, or your invincibility is running low, hold ITEM to cancel your Invincibility; the same as you would Grow.
|
||||
|
||||
### Alt. Shrink (Power)
|
||||
Shrink, in its normal form, functions much like Mario Kart's Lightning item. Most servers keep it off due to how frequent and disruptive it is to races.
|
||||
|
||||
**Alt. Shrink** forgoes that and turns it into an inversion of Grow! In its alternate form, Shrink appears as a **midpack power item**, shrinking you to a dimunitive size and increasing your acceleration and top speed, whilist **doubling the amount of nearly every item** you roll while under its effects. With some luck, you can roll impressive items and put pressure on first!
|
||||
|
||||
Be careful, though: running into anyone while in this state **will flip you over** and significantly cut your speed. Nimble dodging is required to make the most of this item!
|
||||
|
||||
## New Items
|
||||
|
||||
### Bubble Shield (Defense: Occupies Slot)
|
||||
This is an item that appears around the upper-midpack of any race. This item's focus is **defense**.
|
||||
|
||||
When a player holds onto this shield, they can inflate the shield to protect themselves from items.
|
||||
As the shield is used more, and takes damage from items and player bumps, it **cracks more and more until finally shattering**. Some item interactions, like a snipe from a Banana or Orbinaut, make it **shatter right away**!
|
||||
|
||||
Hold down ITEM to inflate the shield. Once you let go, it slowly deflates. As long as it's in an inflated state--be it inflating or deflating--you can **protect yourself from items** without spinning out.
|
||||
While in an _uninflated_ state, however, the Bubble Shield can let you **nullify only one item hit**, shattering itself in the process.
|
||||
|
||||
If you hold ITEM for too long, you'll **overinflate the shield**, causing it to shatter, no matter the amount of health it still had. That's not all bad, though; you'll get a nice speed boost, and be temporarily invulnerable to hazards and items; proximity mines are no match!
|
||||
|
||||
The Bubble Shield also makes your bumps stronger: if you bump into another player, you won't rebound, but they will. If your shield isn't inflated while bumping other players, it'll **take severe damage** from the bump. Careful play is key with this shield!
|
||||
|
||||
### Flame Shield (Offense+Boost: Occupies Slot)
|
||||
This is an item that appears around the lower-midpack of any race.
|
||||
|
||||
The Flame Shield can be used by holding down ITEM.
|
||||
|
||||
When in use, a **Flamometer** appears next to your character. The Flamometer shows how much you're charging the shield, and how much fuel you have left.
|
||||
The fuel gauge is constantly depleting once the Flame Shield is first used. As you hold ITEM; you'll increase the Flame Shield's boost power, but it'll **use up whatever fuel you have** at the moment.
|
||||
|
||||
If you overcharge the Flame Shield, the Flamometer **catches fire**, and you'll gain no extra boost power, but can more easily cut through offroad. If you pace yourself, you can make this item last very long.
|
||||
|
||||
If you run into players while charging your Flame Shield, **you'll flip them over**, making them lose a significant amount of speed. You however, rush right through them.
|
||||
|
||||
### Land Mine (Drop Behind)
|
||||
This is an item exclusive to first. Drop a discreet mine onto the track; anyone who runs into it **flips over and loses speed**.
|
||||
|
|
@ -132,7 +132,7 @@ k_bot.cpp
|
|||
k_botitem.cpp
|
||||
k_botsearch.cpp
|
||||
k_cluster.cpp
|
||||
k_odds.c
|
||||
k_items.c
|
||||
k_grandprix.c
|
||||
k_boss.c
|
||||
k_hud.c
|
||||
|
|
|
|||
|
|
@ -188,9 +188,6 @@ extern CV_PossibleValue_t CV_Natural[];
|
|||
#define KARTGP_MASTER 4 // Not a speed setting, gives hard speed with maxed out bots
|
||||
#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[];
|
||||
// Invincibility types.
|
||||
#define KARTINVIN_LEGACY 0
|
||||
#define KARTINVIN_ALTERN 1
|
||||
|
||||
extern consvar_t cv_execversion;
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@
|
|||
#define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291
|
||||
#define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b
|
||||
#define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9
|
||||
#define ASSET_HASH_MAIN_PK3 0x26b5dde340bc9059
|
||||
#define ASSET_HASH_MAIN_PK3 0x9dc33fb314952e03
|
||||
#define ASSET_HASH_MAPPATCH_PK3 0xd4d4ce4a090d5473
|
||||
#define ASSET_HASH_BONUSCHARS_KART 0x60e6f13d822a7461
|
||||
#ifdef USE_PATCH_FILE
|
||||
|
|
@ -1861,7 +1861,7 @@ void D_SRB2Main(void)
|
|||
if (WADNAMECHECK(word))
|
||||
{
|
||||
if (!(pstartmap = wadnamemap))
|
||||
I_Error("Bad '%s' level warp; pstartmap (%d) != wadnamemap (%d)).\n"
|
||||
I_Error("Bad '%s' level warp; pstartmap (%d) != wadnamemap (%d).\n"
|
||||
#if defined (_WIN32)
|
||||
"Are you using MSDOS 8.3 filenames in Zone Builder?\n"
|
||||
"\n"
|
||||
|
|
|
|||
108
src/d_netcmd.c
108
src/d_netcmd.c
|
|
@ -68,6 +68,7 @@
|
|||
#include "m_perfstats.h"
|
||||
#include "g_party.h"
|
||||
#include "k_specialstage.h"
|
||||
#include "k_items.h"
|
||||
|
||||
#define CV_RESTRICT CV_NETVAR
|
||||
|
||||
|
|
@ -166,7 +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 KartBumpSpark_OnChange(void);
|
||||
|
||||
static void Schedule_OnChange(void);
|
||||
|
|
@ -383,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);
|
||||
|
|
@ -499,6 +470,10 @@ consvar_t cv_kartstacking_grow_speedboost = CVAR_INIT ("vanillaboost_grow_speedb
|
|||
consvar_t cv_kartstacking_grow_accelboost = CVAR_INIT ("vanillaboost_grow_accelboost", "0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
|
||||
consvar_t cv_kartstacking_grow_stackable = CVAR_INIT ("vanillaboost_grow_stackable", "Off", CV_NETVAR|CV_GUARD, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_kartstacking_altshrink_speedboost = CVAR_INIT ("vanillaboost_altshrink_speedboost", "0.50", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
|
||||
consvar_t cv_kartstacking_altshrink_accelboost = CVAR_INIT ("vanillaboost_altshrink_accelboost", "0.15", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
|
||||
consvar_t cv_kartstacking_altshrink_stackable = CVAR_INIT ("vanillaboost_altshrink_stackable", "On", CV_NETVAR|CV_GUARD, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_kartstacking_bubble_speedboost = CVAR_INIT ("vanillaboost_bubble_speedboost", "0.35", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
|
||||
consvar_t cv_kartstacking_bubble_accelboost = CVAR_INIT ("vanillaboost_bubble_accelboost", "8.0", CV_NETVAR|CV_CHEAT|CV_FLOAT|CV_GUARD, CV_Unsigned, NULL);
|
||||
consvar_t cv_kartstacking_bubble_stackable = CVAR_INIT ("vanillaboost_bubble_stackable", "Off", CV_NETVAR|CV_GUARD, CV_OnOff, NULL);
|
||||
|
|
@ -588,7 +563,7 @@ consvar_t cv_kartantibump = CVAR_INIT ("kartantibump", "0", CV_NETVAR|CV_CALL|CV
|
|||
// Odds distancing
|
||||
#define MAXODDSDIST ((INT32_MAX / FRACUNIT) / 2)
|
||||
static CV_PossibleValue_t distvar_cons_t[] = {{1, "MIN"}, {MAXODDSDIST, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_kartoddsdist = CVAR_INIT ("kartoddsdist", "987", CV_NETVAR|CV_CHEAT|CV_GUARD, distvar_cons_t, NULL);
|
||||
consvar_t cv_kartoddsdist = CVAR_INIT ("kartoddsdist", "1480", CV_NETVAR|CV_CHEAT|CV_GUARD, distvar_cons_t, NULL);
|
||||
consvar_t cv_kartlegacyoddsdist = CVAR_INIT ("kartlegacyoddsdist", "1050", CV_NETVAR|CV_CHEAT|CV_GUARD, distvar_cons_t, NULL);
|
||||
|
||||
// SPB distance
|
||||
|
|
@ -597,9 +572,12 @@ 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
|
||||
|
||||
// Invincibility modifiers
|
||||
static CV_PossibleValue_t invintype_cons_t[] = {{0, "Legacy"}, {1, "Alternative"}, {0, NULL}};
|
||||
consvar_t cv_kartinvintype = CVAR_INIT ("kartinvintype", "Legacy", CV_NETVAR|CV_CALL, invintype_cons_t, KartInvinType_OnChange);
|
||||
// SPB Rush toggle; toggles on/off the more aggressive "pressure" odds when an SPB is active
|
||||
consvar_t cv_kartspbrush = CVAR_INIT ("kartspbrush", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||
|
||||
// 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);
|
||||
|
||||
// How far the player must be from the cluster to begin frequently rolling Invincibility.
|
||||
static CV_PossibleValue_t invindist_cons_t[] = {{1, "MIN"}, {32000, "MAX"}, {0, NULL}};
|
||||
|
|
@ -621,23 +599,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);
|
||||
|
|
@ -1274,6 +1236,7 @@ void D_RegisterClientCommands(void)
|
|||
|
||||
CV_RegisterVar(&cv_growmusic);
|
||||
CV_RegisterVar(&cv_supermusic);
|
||||
CV_RegisterVar(&cv_altshrinkmusic);
|
||||
|
||||
CV_RegisterVar(&cv_songcredits);
|
||||
CV_RegisterVar(&cv_tutorialprompt);
|
||||
|
|
@ -1340,6 +1303,7 @@ void D_RegisterClientCommands(void)
|
|||
|
||||
CV_RegisterVar(&cv_invincmusicfade);
|
||||
CV_RegisterVar(&cv_growmusicfade);
|
||||
CV_RegisterVar(&cv_altshrinkmusicfade);
|
||||
|
||||
CV_RegisterVar(&cv_resetspecialmusic);
|
||||
|
||||
|
|
@ -6220,16 +6184,15 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
|
||||
case CHEAT_GIVEITEM: {
|
||||
SINT8 item = READSINT8(*cp);
|
||||
UINT8 item = READUINT8(*cp);
|
||||
UINT8 amt = READUINT8(*cp);
|
||||
|
||||
item = max(item, KITEM_SAD);
|
||||
item = min(item, NUMKARTITEMS - 1);
|
||||
item = min(item, numkartitems - 1);
|
||||
|
||||
K_StripItems(player);
|
||||
|
||||
// Cancel roulette if rolling
|
||||
player->itemroulette = KROULETTE_DISABLED;
|
||||
player->itemroulette = 0;
|
||||
|
||||
player->itemtype = item;
|
||||
player->itemamount = amt;
|
||||
|
|
@ -6240,10 +6203,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" : DEH_KartItemName(item), amt));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -6528,8 +6488,6 @@ static void Command_KartGiveItem_f(void)
|
|||
const char *name;
|
||||
INT32 item;
|
||||
|
||||
const char * str;
|
||||
|
||||
int i;
|
||||
|
||||
ac = COM_Argc();
|
||||
|
|
@ -6541,7 +6499,7 @@ static void Command_KartGiveItem_f(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
item = NUMKARTITEMS;
|
||||
item = numkartitems;
|
||||
|
||||
name = COM_Argv(1);
|
||||
|
||||
|
|
@ -6557,18 +6515,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(DEH_KartItemName(i), name) != NULL)
|
||||
{
|
||||
CONS_Printf("\x83\t%s\n", str);
|
||||
item = kartdebugitem_cons_t[i].value;
|
||||
CONS_Printf("\x83\t%s\n", DEH_KartItemName(i));
|
||||
item = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (item < NUMKARTITEMS)
|
||||
if (item < numkartitems)
|
||||
{
|
||||
INT32 amt;
|
||||
|
||||
|
|
@ -7816,24 +7774,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 KartBumpSpark_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules(false) == false)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -202,7 +175,6 @@ extern consvar_t cv_kartexplosion_limitlifetime;
|
|||
extern consvar_t cv_kartexplosion_limitlifetime_cap;
|
||||
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;
|
||||
|
|
@ -230,6 +202,8 @@ extern consvar_t cv_kartlegacyoddsdist;
|
|||
extern consvar_t cv_kartspbdist;
|
||||
extern consvar_t cv_kartlegacyspbdist;
|
||||
|
||||
extern consvar_t cv_kartspbrush;
|
||||
|
||||
extern consvar_t cv_encorevotes;
|
||||
|
||||
extern consvar_t cv_votetime;
|
||||
|
|
|
|||
101
src/d_player.h
101
src/d_player.h
|
|
@ -58,14 +58,6 @@ typedef enum
|
|||
PST_REBORN
|
||||
} playerstate_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IF_USERINGS = 1, // Have to be not holding the item button to change from using rings to using items (or vice versa) - prevents weirdness
|
||||
IF_ITEMOUT = 1<<1, // Are you holding an item out?
|
||||
IF_EGGMANOUT = 1<<2, // Eggman mark held, separate from IF_ITEMOUT so it doesn't stop you from getting items
|
||||
IF_HOLDREADY = 1<<3, // Hold button-style item is ready to activate
|
||||
} itemflags_t;
|
||||
|
||||
//
|
||||
// Player internal flags
|
||||
//
|
||||
|
|
@ -137,71 +129,13 @@ 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,
|
||||
|
||||
NUMKARTRESULTS
|
||||
} kartitems_t;
|
||||
|
||||
typedef enum {
|
||||
KROULETTE_DISABLED,
|
||||
KROULETTE_ACTIVE,
|
||||
} kartroulette_t;
|
||||
|
||||
typedef enum {
|
||||
KROULETTETYPE_NORMAL,
|
||||
KROULETTETYPE_KARMA,
|
||||
KROULETTETYPE_EGGMAN,
|
||||
} kartroulettetype_t;
|
||||
|
||||
typedef enum {
|
||||
KITEMBLINKMODE_NORMAL,
|
||||
KITEMBLINKMODE_MASHED,
|
||||
KITEMBLINKMODE_KARMA,
|
||||
} kartitemblinkmode_t;
|
||||
IF_USERINGS = 1, // Have to be not holding the item button to change from using rings to using items (or vice versa) - prevents weirdness
|
||||
IF_ITEMOUT = 1<<1, // Are you holding an item out?
|
||||
IF_EGGMANOUT = 1<<2, // Eggman mark held, separate from IF_ITEMOUT so it doesn't stop you from getting items
|
||||
IF_HOLDREADY = 1<<3, // Hold button-style item is ready to activate
|
||||
} itemflags_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
@ -660,20 +594,24 @@ struct player_t
|
|||
UINT16 draftleeway; // Leniency timer before removing draft power
|
||||
SINT8 lastdraft; // (-1 to 15) - Last player being drafted
|
||||
|
||||
UINT8 tripwireState; // see tripwirestate_t
|
||||
UINT8 tripwirePass; // see tripwirepass_t
|
||||
UINT8 tripwireState; // see tripwirestate_t
|
||||
UINT8 tripwirePass; // see tripwirepass_t
|
||||
UINT16 tripwireLeniency; // When reaching a state that lets you go thru tripwire, you get an extra second leniency after it ends to still go through it.
|
||||
UINT8 tripwireReboundDelay; // When failing Tripwire, brieftly lock out speed-based tripwire pass (anti-cheese)
|
||||
|
||||
UINT16 itemroulette; // Used for the roulette when deciding what item to give you (was "pw_kartitem")
|
||||
UINT16 previtemroulette; // Used determining when to give rings after hitting item boxes
|
||||
UINT16 itemroulette; // Used for the roulette when deciding what item to give you (was "pw_kartitem")
|
||||
UINT16 previtemroulette; // Used determining when to give rings after hitting item boxes
|
||||
UINT16 itemblink; // Item flashing after roulette, serves as a mashing indicator. Also prevents item from being stolen.
|
||||
UINT16 itemblinkmode; // Type of flashing: 0 = white (normal), 1 = red (mashing), 2 = rainbow (enhanced items)
|
||||
UINT8 roulettetype; // Used for the roulette, for deciding type (0 = normal, 1 = better, 2 = eggman mark)
|
||||
UINT8 roulettetype; // Used for the roulette, for deciding type (0 = normal, 1 = better, 2 = eggman mark)
|
||||
|
||||
// Item held stuff
|
||||
SINT8 itemtype; // KITEM_ constant for item number
|
||||
UINT8 itemamount; // Amount of said item
|
||||
UINT8 itemtype; // KITEM_ constant for item number
|
||||
UINT8 itemamount; // Amount of said item
|
||||
itemflags_t itemflags; // holds IF_flags (see itemstate_t)
|
||||
tic_t itemusecooldown; // timer for which the player is locked out of using an item or mashing the item roulette (implementation of xItemLib setPlayerItemCooldown)
|
||||
tic_t itemusecooldownmax; // most recent highest value for itemusecooldown, mainly used for HUD rendering currently
|
||||
|
||||
SINT8 throwdir; // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir")
|
||||
|
||||
UINT8 sadtimer; // How long you've been sad
|
||||
|
|
@ -724,13 +662,14 @@ struct player_t
|
|||
fixed_t slopeaccel; // Handle slopeboost accel
|
||||
|
||||
INT16 growshrinktimer; // > 0 = Big, < 0 = small
|
||||
INT16 altshrinktimeshit; // (Alt. Shrink) How many times were you flipped over while shrunk?
|
||||
INT16 growcancel; // Duration of grow canceling
|
||||
INT16 squishedtimer; // Duration of being squished
|
||||
|
||||
UINT16 rocketsneakertimer; // Rocket Sneaker duration timer
|
||||
|
||||
UINT16 invincibilitytimer; // Invincibility timer
|
||||
UINT16 maxinvincibilitytime; // (Alternate) Initial time for Invincibility, used for the item bar.
|
||||
UINT16 invincibilitytimer; // Invincibility timer
|
||||
UINT16 maxinvincibilitytime; // (Alternate) Initial time for Invincibility, used for the item bar.
|
||||
UINT16 invincibilitybottleneck; // (Alternate) Prevents breakaways by gradienting towards a heavier decrement.
|
||||
INT16 invincibilitycancel; // (Alternate) Duration of Invincibility canceling.
|
||||
UINT8 invincibilitywarning; // (Alternate) "Timer warning" boolean to signal Alt. Invin. is running out.
|
||||
|
|
@ -836,8 +775,6 @@ struct player_t
|
|||
UINT8 typing_duration; // How long since resumed timer
|
||||
|
||||
UINT8 kickstartaccel;
|
||||
|
||||
UINT8 itemflags; // holds IF_flags (see itemstate_t)
|
||||
|
||||
fixed_t outrun; // Milky Way road effect
|
||||
UINT8 outruntime; // Used to bypass the speed cap for fall off
|
||||
|
|
|
|||
|
|
@ -439,6 +439,26 @@ 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 (fastncmp("KITEM_",word,6)) {
|
||||
p = word+6;
|
||||
if (fastcmp(p, "LIGHTNINGSHIELD"))
|
||||
{
|
||||
lua_pushinteger(L, KITEM_THUNDERSHIELD);
|
||||
return 1;
|
||||
}
|
||||
if (fastcmp(p, "SAD"))
|
||||
{
|
||||
lua_pushinteger(L, MAXKARTITEMS);
|
||||
return 1;
|
||||
}
|
||||
i = DEH_FindKartItem(p);
|
||||
if (i != MAXKARTITEMS)
|
||||
{
|
||||
CacheAndPushConstant(L, word, 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);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
231
src/deh_soc.c
231
src/deh_soc.c
|
|
@ -53,6 +53,7 @@
|
|||
#include "filesrch.h" // refreshdirmenu
|
||||
#include "k_follower.h"
|
||||
#include "doomstat.h" // MAXMUSNAMES
|
||||
#include "k_items.h"
|
||||
|
||||
// Loops through every constant and operation in word and performs its calculations, returning the final value.
|
||||
fixed_t get_number(const char *word)
|
||||
|
|
@ -3694,7 +3695,7 @@ void readfollower(MYFILE *f)
|
|||
char *s;
|
||||
char *word, *word2, dname[SKINNAMESIZE+1];
|
||||
char *tmp;
|
||||
char testname[SKINNAMESIZE];
|
||||
char testname[SKINNAMESIZE+1];
|
||||
|
||||
boolean nameset;
|
||||
INT32 fallbackstate = 0;
|
||||
|
|
@ -4035,6 +4036,211 @@ void readweather(MYFILE *f, INT32 num)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
#define WARN(str, ...) deh_warning("KartItem %s: " str, strbuf_get(kartitemnames, item->info.nameofs), __VA_ARGS__)
|
||||
#define WARN0(str) deh_warning("KartItem %s: " str, strbuf_get(kartitemnames, item->info.nameofs))
|
||||
void readkartitem(MYFILE *f, kartitem_t *item)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word = s;
|
||||
char *word2;
|
||||
char *tmp;
|
||||
INT32 i;
|
||||
|
||||
do if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
// First remove trailing newline, if there is one
|
||||
tmp = strchr(s, '\n');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
if (s == tmp)
|
||||
continue; // Skip comment lines, but don't break.
|
||||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
word2 = (tmp += 2);
|
||||
strupr(word2);
|
||||
|
||||
if (fastcmp(word, "BIGPATCHES") || fastcmp(word, "SMALLPATCHES"))
|
||||
{
|
||||
kartitemgraphics_t *graphics = &item->graphics[word[0] == 'B' ? 0 : 1];
|
||||
|
||||
if (graphics == &item->graphics[0] && item->spritedef.numframes > 0)
|
||||
{
|
||||
Z_Free(item->spritedef.spriteframes);
|
||||
memset(&item->spritedef, 0, sizeof(item->spritedef));
|
||||
}
|
||||
for (i = 0; i < graphics->numpatches; i++)
|
||||
{
|
||||
Z_Free(graphics->patchnames[i]);
|
||||
Patch_Free(graphics->patches[i]);
|
||||
graphics->patches[i] = NULL;
|
||||
}
|
||||
|
||||
tmp = strtok(word2,",");
|
||||
for (graphics->numpatches = 0; graphics->numpatches < MAXITEMPATCHES;)
|
||||
{
|
||||
graphics->patchnames[graphics->numpatches++] = Z_StrDup(tmp);
|
||||
if ((tmp = strtok(NULL,",")) == NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "FLAGS") || fastcmp(word, "FLAGSALT"))
|
||||
{
|
||||
item->flags[word[5] == 'A' ? 1 : 0] = get_number(word2);
|
||||
}
|
||||
else
|
||||
WARN("unknown word '%s'", word);
|
||||
}
|
||||
while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
Z_Free(s);
|
||||
}
|
||||
#undef WARN
|
||||
#undef WARN0
|
||||
|
||||
#define WARN(str, ...) deh_warning("KartResult %s: " str, result->cvar->name, __VA_ARGS__)
|
||||
#define WARN0(str) deh_warning("KartResult %s: " str, result->cvar->name)
|
||||
void readkartresult(MYFILE *f, kartresult_t *result)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word = s;
|
||||
char *word2;
|
||||
char *tmp;
|
||||
|
||||
do if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
// First remove trailing newline, if there is one
|
||||
tmp = strchr(s, '\n');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
if (s == tmp)
|
||||
continue; // Skip comment lines, but don't break.
|
||||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
word2 = tmp + 2;
|
||||
//strupr(word2);
|
||||
|
||||
if (fastcmp(word, "TYPE"))
|
||||
{
|
||||
if (result->isalt)
|
||||
{
|
||||
WARN0("can't set type for alternate result");
|
||||
continue;
|
||||
}
|
||||
result->type = get_kartitem(word2);
|
||||
}
|
||||
else if (fastcmp(word, "AMOUNT"))
|
||||
{
|
||||
if (result->isalt)
|
||||
{
|
||||
WARN0("can't set amount for alternate result");
|
||||
continue;
|
||||
}
|
||||
result->amount = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "ISALT"))
|
||||
{
|
||||
result->isalt = (boolean)(atoi(word2) || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word, "FLAGS"))
|
||||
{
|
||||
result->flags = get_number(word2);
|
||||
}
|
||||
else if (fastncmp(word, "ODDS", 4))
|
||||
{
|
||||
UINT8 oddstable;
|
||||
if (fastcmp(word+4, "RACE"))
|
||||
oddstable = ODDS_RACE;
|
||||
else if (fastcmp(word+4, "BATTLE"))
|
||||
oddstable = ODDS_BATTLE;
|
||||
else if (fastcmp(word+4, "SPECIAL"))
|
||||
oddstable = ODDS_SPECIAL;
|
||||
else
|
||||
{
|
||||
WARN("unknown word '%s'", word);
|
||||
continue;
|
||||
}
|
||||
|
||||
UINT8 *odds = result->odds[oddstable];
|
||||
memset(odds, 0, sizeof(*odds)*MAXODDS);
|
||||
tmp = strtok(word2,",");
|
||||
for (UINT8 i = 0; i <= MAXODDS; i++)
|
||||
{
|
||||
if (i == oddstablemax[oddstable])
|
||||
{
|
||||
WARN("odds table %s is limited to %d odds", word+4, oddstablemax[oddstable]);
|
||||
continue;
|
||||
}
|
||||
odds[i] = atoi(tmp);
|
||||
if ((tmp = strtok(NULL,",")) == NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (fastncmp(word, "UNIQUEODDS", 10))
|
||||
{
|
||||
UINT8 oddstable;
|
||||
if (fastcmp(word+10, "RACE"))
|
||||
oddstable = ODDS_RACE;
|
||||
else if (fastcmp(word+10, "BATTLE"))
|
||||
oddstable = ODDS_BATTLE;
|
||||
else if (fastcmp(word+10, "SPECIAL"))
|
||||
oddstable = ODDS_SPECIAL;
|
||||
|
||||
else
|
||||
{
|
||||
WARN("unknown word '%s'", word);
|
||||
continue;
|
||||
}
|
||||
|
||||
result->unique_odds[oddstable] = get_useoddsfunc(word2);
|
||||
}
|
||||
else if (fastcmp(word, "COOLDOWNTIME"))
|
||||
{
|
||||
result->basecooldown = atoi(word2) * TICRATE;
|
||||
}
|
||||
else if (fastcmp(word, "DISPLAYNAME"))
|
||||
{
|
||||
result->displayname = Z_StrDup(word2);
|
||||
}
|
||||
else
|
||||
WARN("unknown word '%s'", word);
|
||||
}
|
||||
while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
Z_Free(s);
|
||||
}
|
||||
#undef WARN
|
||||
#undef WARN0
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
|
@ -4192,6 +4398,29 @@ preciptype_t get_precip(const char *word)
|
|||
return PRECIP_NONE;
|
||||
}
|
||||
|
||||
kartitemtype_e get_kartitem(const char *word)
|
||||
{ // Returns the value of KITEM_ enumerations
|
||||
kartitemtype_e i;
|
||||
if (fastncmp("KITEM_",word,6))
|
||||
word += 6; // take off the KITEM_
|
||||
i = DEH_FindKartItem(word);
|
||||
if (i == MAXKARTITEMS)
|
||||
deh_warning("Couldn't find kartitem named 'KITEM_%s'", word);
|
||||
return i;
|
||||
}
|
||||
|
||||
useoddsfunc_f *get_useoddsfunc(const char *word)
|
||||
{ // Returns the value of KO_ enumerations
|
||||
size_t i;
|
||||
if (fastncmp("KO_",word,3))
|
||||
word += 3; // take off the KO_
|
||||
for (i = 0; USEODDS_FUNCS[i].name; i++)
|
||||
if (fasticmp(word, USEODDS_FUNCS[i].name))
|
||||
return USEODDS_FUNCS[i].func;
|
||||
deh_warning("Couldn't find odds function named 'KO_%s'",word);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// \todo Make ANY of this completely over-the-top math craziness obey the order of operations.
|
||||
static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; }
|
||||
static fixed_t op_div(fixed_t a, fixed_t b) { return a/b; }
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "fastcmp.h"
|
||||
#include "lua_script.h" // Reluctantly included for LUA_EvalMath
|
||||
#include "d_clisrv.h"
|
||||
#include "k_items.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_light.h"
|
||||
|
|
@ -62,6 +63,8 @@ menudrawer_f *get_menudrawer(const char *word);
|
|||
//INT16 get_gametype(const char *word);
|
||||
//powertype_t get_power(const char *word);
|
||||
skincolornum_t get_skincolor(const char *word);
|
||||
kartitemtype_e get_kartitem(const char *word);
|
||||
useoddsfunc_f *get_useoddsfunc(const char *word);
|
||||
|
||||
void readwipes(MYFILE *f);
|
||||
void readmaincfg(MYFILE *f);
|
||||
|
|
@ -91,6 +94,8 @@ void readcupheader(MYFILE *f, cupheader_t *cup);
|
|||
void readfollower(MYFILE *f);
|
||||
preciptype_t get_precip(const char *word);
|
||||
void readweather(MYFILE *f, INT32 num);
|
||||
void readkartitem(MYFILE *f, kartitem_t *item);
|
||||
void readkartresult(MYFILE *f, kartresult_t *result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ strbuf_t *statenames;
|
|||
strbuf_t *mobjnames;
|
||||
strbuf_t *skincolornames;
|
||||
strbuf_t *menunames;
|
||||
strbuf_t *kartitemnames;
|
||||
UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway.
|
||||
|
||||
const char *DEH_MobjtypeName(mobjtype_t i)
|
||||
|
|
@ -62,6 +63,11 @@ const char *DEH_MenutypeName(menutype_t i)
|
|||
return strbuf_get(menunames, menudefs[i].info.nameofs);
|
||||
}
|
||||
|
||||
const char *DEH_KartItemName(kartitemtype_e i)
|
||||
{
|
||||
return strbuf_get(kartitemnames, kartitems[i].info.nameofs);
|
||||
}
|
||||
|
||||
mobjtype_t DEH_FindMobjtype(const char *word)
|
||||
{
|
||||
mobjtype_t i;
|
||||
|
|
@ -114,6 +120,19 @@ menutype_t DEH_FindMenutype(const char *word)
|
|||
return MAXMENUTYPES;
|
||||
}
|
||||
|
||||
kartitemtype_e DEH_FindKartItem(const char *word)
|
||||
{
|
||||
kartitemtype_e i;
|
||||
UINT32 hash = HASH32(word, strlen(word));
|
||||
for (i = 0; i < numkartitems; i++) {
|
||||
if (hash != kartitems[i].info.namehash)
|
||||
continue;
|
||||
if (fastcmp(word, DEH_KartItemName(i)))
|
||||
return i;
|
||||
}
|
||||
return MAXKARTITEMS;
|
||||
}
|
||||
|
||||
struct flickytypes_s FLICKYTYPES[] = {
|
||||
{"BLUEBIRD", MT_FLICKY_01}, // Flicky (Flicky)
|
||||
{"RABBIT", MT_FLICKY_02}, // Pocky (1)
|
||||
|
|
@ -796,6 +815,7 @@ struct menu_routine_s const MENU_ROUTINES[] = {
|
|||
{ "RESETCONTROLS", &MR_ResetControls },
|
||||
{ "CHANGECONTROL", &MR_ChangeControl },
|
||||
{ "ASSIGNJOYSTICK", &MR_AssignJoystick },
|
||||
{ "SETUPMONITORTOGGLES", &MR_SetupMonitorToggles },
|
||||
{ "HANDLEMONITORTOGGLES", &MR_HandleMonitorToggles },
|
||||
{ "RESTARTAUDIO", &MR_RestartAudio },
|
||||
{ "ENTERVIEWSERVER", &MR_EnterViewServer },
|
||||
|
|
@ -837,6 +857,12 @@ struct menu_drawer_s const MENU_DRAWERS[] = {
|
|||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
struct odds_func_s const USEODDS_FUNCS[] = {
|
||||
{ "ALTINVINODDS", &KO_AltInvinOdds },
|
||||
{ "SPBRACEODDS", &KO_SPBRaceOdds },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
struct int_const_s const INT_CONST[] = {
|
||||
// If a mod removes some variables here,
|
||||
// please leave the names in-tact and just set
|
||||
|
|
@ -1512,21 +1538,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},
|
||||
{"NUMKARTRESULTS",NUMKARTRESULTS},
|
||||
|
||||
// kartshields_t
|
||||
{"KSHIELD_NONE",KSHIELD_NONE},
|
||||
{"KSHIELD_THUNDER",KSHIELD_THUNDER},
|
||||
|
|
@ -1535,22 +1546,34 @@ 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},
|
||||
|
||||
// kartroulettetype_t
|
||||
// kartroulettetype_e
|
||||
{"KROULETTETYPE_NORMAL",KROULETTETYPE_NORMAL},
|
||||
{"KROULETTETYPE_KARMA",KROULETTETYPE_KARMA},
|
||||
{"KROULETTETYPE_EGGMAN",KROULETTETYPE_EGGMAN},
|
||||
|
||||
// kartitemblinkmode_t
|
||||
{"KITEMBLINKMODE_NORMAL",KITEMBLINKMODE_NORMAL},
|
||||
{"KITEMBLINKMODE_MASHED",KITEMBLINKMODE_MASHED},
|
||||
{"KITEMBLINKMODE_KARMA",KITEMBLINKMODE_KARMA},
|
||||
// kartitemblink_e
|
||||
{"KITEMBLINK_NORMAL",KITEMBLINK_NORMAL},
|
||||
{"KITEMBLINK_MASHED",KITEMBLINK_MASHED},
|
||||
{"KITEMBLINK_KARMA",KITEMBLINK_KARMA},
|
||||
{"KITEMBLINK_DEBUG",KITEMBLINK_DEBUG},
|
||||
|
||||
// kartitemflags_e
|
||||
{"KIF_UNIQUESLOT",KIF_UNIQUESLOT},
|
||||
{"KIF_UNIQUEDROP",KIF_UNIQUEDROP},
|
||||
{"KIF_UNIQUE",KIF_UNIQUE},
|
||||
{"KIF_ANIMATED",KIF_ANIMATED},
|
||||
{"KIF_DARKBG",KIF_DARKBG},
|
||||
{"KIF_COLPATCH2PLAYER",KIF_COLPATCH2PLAYER},
|
||||
{"KIF_HIDEFROMROULETTE",KIF_HIDEFROMROULETTE},
|
||||
|
||||
// kartresultflags_e
|
||||
{"KRF_INDIRECTITEM",KRF_INDIRECTITEM},
|
||||
{"KRF_POWERITEM",KRF_POWERITEM},
|
||||
{"KRF_COOLDOWNONSTART",KRF_COOLDOWNONSTART},
|
||||
{"KRF_NOTNEAREND",KRF_NOTNEAREND},
|
||||
{"KRF_NOTFORBOTTOM",KRF_NOTFORBOTTOM},
|
||||
{"KRF_RUNNERAUGMENT",KRF_RUNNERAUGMENT},
|
||||
{"KRF_HIDEFROMSPB",KRF_HIDEFROMSPB},
|
||||
|
||||
// kartspinoutflags_t
|
||||
{"KSPIN_THRUST",KSPIN_THRUST},
|
||||
|
|
@ -1684,10 +1707,6 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"FACE_MINIMAP", FACE_MINIMAP},
|
||||
{"NUMFACES", NUMFACES},
|
||||
|
||||
// invintype
|
||||
{"KARTINVIN_LEGACY", KARTINVIN_LEGACY},
|
||||
{"KARTINVIN_ALTERN", KARTINVIN_ALTERN},
|
||||
|
||||
// k_waypoint.h values
|
||||
{"DEFAULT_WAYPOINT_RADIUS",DEFAULT_WAYPOINT_RADIUS},
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "lua_script.h"
|
||||
#include "strbuf.h"
|
||||
#include "m_menu.h" // menutype_t
|
||||
#include "k_items.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -30,17 +31,20 @@ extern strbuf_t *statenames;
|
|||
extern strbuf_t *mobjnames;
|
||||
extern strbuf_t *skincolornames;
|
||||
extern strbuf_t *menunames;
|
||||
extern strbuf_t *kartitemnames;
|
||||
extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway.
|
||||
|
||||
const char *DEH_MobjtypeName(mobjtype_t i);
|
||||
const char *DEH_StateName(statenum_t i);
|
||||
const char *DEH_SkincolorName(skincolornum_t i);
|
||||
const char *DEH_MenutypeName(menutype_t i);
|
||||
const char *DEH_KartItemName(kartitemtype_e i);
|
||||
|
||||
mobjtype_t DEH_FindMobjtype(const char *word);
|
||||
statenum_t DEH_FindState(const char *word);
|
||||
skincolornum_t DEH_FindSkincolor(const char *word);
|
||||
menutype_t DEH_FindMenutype(const char *word);
|
||||
kartitemtype_e DEH_FindKartItem(const char *word);
|
||||
|
||||
struct flickytypes_s {
|
||||
const char *name;
|
||||
|
|
@ -67,6 +71,11 @@ struct menu_drawer_s {
|
|||
menudrawer_f *drawer;
|
||||
};
|
||||
|
||||
struct odds_func_s {
|
||||
const char *name;
|
||||
useoddsfunc_f *func;
|
||||
};
|
||||
|
||||
struct int_const_s {
|
||||
const char *n;
|
||||
// has to be able to hold both fixed_t and angle_t, so drastic measure!!
|
||||
|
|
@ -97,6 +106,7 @@ extern const char *const KARTHUD_LIST[];
|
|||
extern const char *const HUDITEMS_LIST[];
|
||||
extern struct menu_routine_s const MENU_ROUTINES[];
|
||||
extern struct menu_drawer_s const MENU_DRAWERS[];
|
||||
extern struct odds_func_s const USEODDS_FUNCS[];
|
||||
|
||||
extern struct int_const_s const INT_CONST[];
|
||||
|
||||
|
|
|
|||
|
|
@ -376,6 +376,22 @@ INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out)
|
|||
*out = nummenutypes++;
|
||||
return 0;
|
||||
}
|
||||
else if (fastcmp(type, "KITEM"))
|
||||
{
|
||||
*out = DEH_FindKartItem(word);
|
||||
if (*out != MAXKARTITEMS)
|
||||
return 0; // already allocated
|
||||
|
||||
if (numkartitems == MAXKARTITEMS) {
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free kartitem slots!\n");
|
||||
return -1;
|
||||
}
|
||||
CONS_Printf("Kartitem KITEM_%s allocated.\n",word);
|
||||
DEH_Link(word, &kartitems[numkartitems].info, &kartitemnames);
|
||||
K_RegisterItem(numkartitems);
|
||||
*out = numkartitems++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
|
@ -750,6 +766,27 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "KARTITEM"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
i = get_kartitem(word2); // find a kartitem by name
|
||||
if (i >= (mainfile ? 0 : 1) && i < numkartitems)
|
||||
readkartitem(f, &kartitems[i]);
|
||||
else
|
||||
{
|
||||
// zero-based, but let's start at 1
|
||||
deh_warning("KartItem number %d out of range (1 - %d)", i, numkartitems-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else if (fastncmp(word, "KARTRESULT", 10))
|
||||
{
|
||||
boolean alternate = fastcmp(word, "KARTRESULTALT");
|
||||
kartresult_t *result = K_GetKartResultAlt(word2, alternate);
|
||||
if (result == NULL)
|
||||
result = K_RegisterResult(word2, alternate);
|
||||
readkartresult(f, result);
|
||||
}
|
||||
else if (fastcmp(word, "WEATHER") || fastcmp(word, "PRECIP") || fastcmp(word, "PRECIPITATION"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
|
|
|
|||
|
|
@ -665,7 +665,6 @@ extern INT32 cheats;
|
|||
// SRB2kart
|
||||
extern UINT8 numlaps;
|
||||
extern UINT8 gamespeed;
|
||||
extern UINT8 invintype;
|
||||
extern boolean franticitems;
|
||||
extern boolean encoremode, prevencoremode;
|
||||
extern boolean comeback;
|
||||
|
|
@ -673,8 +672,6 @@ extern boolean comeback;
|
|||
extern SINT8 mostwanted;
|
||||
extern SINT8 battlewanted[4];
|
||||
extern tic_t wantedcalcdelay;
|
||||
extern tic_t indirectitemcooldown;
|
||||
//extern tic_t hyubgone;
|
||||
extern tic_t mapreset;
|
||||
extern boolean thwompsactive;
|
||||
extern UINT8 lastLowestLap;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by Vivian "toastergrl" Grannell.
|
||||
// Copyright (C) 2025 by Kart Krew.
|
||||
// Copyright (C) 2025 by "Anonimus".
|
||||
// Copyright (C) 2025 by "yama".
|
||||
// Copyright (C) 2025 Blankart Team.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by Vivian "toastergrl" Grannell.
|
||||
// Copyright (C) 2025 by Kart Krew.
|
||||
// Copyright (C) 2025 by "Anonimus".
|
||||
// Copyright (C) 2025 by "yama".
|
||||
// Copyright (C) 2025 Blankart Team.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
|
|
|
|||
|
|
@ -890,7 +890,7 @@ const char *blancredits[] = {
|
|||
"\"GenericHeroGuy\"",
|
||||
"\"Alug\"",
|
||||
"\"Indev\"",
|
||||
"\"Anonimus\" aka \"yama\"",
|
||||
"\"yama\"",
|
||||
"\"minenice\"",
|
||||
"",
|
||||
"\1Support Programming",
|
||||
|
|
@ -899,7 +899,7 @@ const char *blancredits[] = {
|
|||
"",
|
||||
"\1Item Programming",
|
||||
"\"NepDisk\"",
|
||||
"\"Anonimus\" aka \"yama\"",
|
||||
"\"yama\"",
|
||||
"",
|
||||
"\1External Programming",
|
||||
"\"Hanicef\"",
|
||||
|
|
@ -922,7 +922,7 @@ const char *blancredits[] = {
|
|||
"",
|
||||
"\1Item Design",
|
||||
"\"NepDisk\"",
|
||||
"\"Anonimus\" aka \"yama\"",
|
||||
"\"yama\"",
|
||||
"\"GenericHeroGuy\"",
|
||||
"",
|
||||
"\1Design Support",
|
||||
|
|
@ -937,7 +937,7 @@ const char *blancredits[] = {
|
|||
"\"Jin\"",
|
||||
"\"NepDisk\"",
|
||||
"\"Mayo\"",
|
||||
"\"Anonimus\" aka \"yama\"",
|
||||
"\"yama\"",
|
||||
"",
|
||||
"\1New HUD Art",
|
||||
"\"Spee\"",
|
||||
|
|
@ -966,7 +966,7 @@ const char *blancredits[] = {
|
|||
"\1Super Special SIGSEGV Search and Smash Squad",
|
||||
"\"NepDisk\"",
|
||||
"\"GenericHeroGuy\"",
|
||||
"\"Anonimus\" aka \"yama\"",
|
||||
"\"yama\"",
|
||||
"\"MotoBugger\"",
|
||||
"\"Rim Jobless\"",
|
||||
"\"Toad The Fungus\"",
|
||||
|
|
@ -982,7 +982,7 @@ const char *blancredits[] = {
|
|||
"\"JonUD\"",
|
||||
"\"MotoBugger\"",
|
||||
"\"Toad The Fungus\"",
|
||||
"\"Anonimus\" aka \"yama\"",
|
||||
"\"yama\"",
|
||||
"\"luna\"",
|
||||
"\"swift\"",
|
||||
"\"Rim Jobless\"",
|
||||
|
|
|
|||
18
src/g_game.c
18
src/g_game.c
|
|
@ -61,7 +61,7 @@
|
|||
#include "k_boss.h"
|
||||
#include "k_specialstage.h"
|
||||
#include "k_bot.h"
|
||||
#include "k_odds.h"
|
||||
#include "k_items.h"
|
||||
#include "doomstat.h"
|
||||
#include "acs/interface.h"
|
||||
#include "k_director.h"
|
||||
|
|
@ -295,7 +295,6 @@ INT32 cheats; //for multiplayer cheat commands
|
|||
// Cvars that we don't want changed mid-game
|
||||
UINT8 numlaps; // Removed from Cvar hell
|
||||
UINT8 gamespeed; // Game's current speed (or difficulty, or cc, or etc); 0 for easy, 1 for normal, 2 for hard
|
||||
UINT8 invintype; // How Invincibility functions. 0 for Legacy/Vanilla, 1 for Alternative.
|
||||
boolean encoremode = false; // Encore Mode currently enabled?
|
||||
boolean prevencoremode;
|
||||
boolean franticitems; // Frantic items currently enabled?
|
||||
|
|
@ -310,8 +309,6 @@ SINT8 pickedvote; // What vote the host rolls
|
|||
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
|
||||
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
|
||||
|
|
@ -442,11 +439,13 @@ consvar_t cv_showfreeplay = CVAR_INIT ("showfreeplay", "On", CV_SAVE, CV_OnOff,
|
|||
static CV_PossibleValue_t powermusic_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "SFX"}, {0, NULL}};
|
||||
consvar_t cv_growmusic = CVAR_INIT ("growmusic", "On", CV_SAVE, powermusic_cons_t, NULL);
|
||||
consvar_t cv_supermusic = CVAR_INIT ("supermusic", "On", CV_SAVE, powermusic_cons_t, NULL);
|
||||
consvar_t cv_altshrinkmusic = CVAR_INIT ("altshrinkmusic", "On", CV_SAVE, powermusic_cons_t, NULL);
|
||||
|
||||
consvar_t cv_invertmouse = CVAR_INIT ("invertmouse", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_invincmusicfade = CVAR_INIT ("invincmusicfade", "300", CV_SAVE, CV_Unsigned, NULL);
|
||||
consvar_t cv_growmusicfade = CVAR_INIT ("growmusicfade", "500", CV_SAVE, CV_Unsigned, NULL);
|
||||
consvar_t cv_altshrinkmusicfade = CVAR_INIT ("altshrinkmusicfade", "500", CV_SAVE, CV_Unsigned, NULL);
|
||||
|
||||
consvar_t cv_resetspecialmusic = CVAR_INIT ("resetspecialmusic", "Yes", CV_SAVE, CV_YesNo, NULL);
|
||||
|
||||
|
|
@ -2807,8 +2806,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
// SRB2kart
|
||||
if (betweenmaps || leveltime <= starttime || spectator == true)
|
||||
{
|
||||
itemroulette = KROULETTE_DISABLED;
|
||||
previtemroulette = KROULETTE_DISABLED;
|
||||
itemroulette = 0;
|
||||
previtemroulette = 0;
|
||||
roulettetype = KROULETTETYPE_NORMAL;
|
||||
itemtype = 0;
|
||||
itemamount = 0;
|
||||
|
|
@ -2848,8 +2847,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
}
|
||||
else
|
||||
{
|
||||
itemroulette = (players[player].itemroulette > KROULETTE_DISABLED ? KROULETTE_ACTIVE : KROULETTE_DISABLED);
|
||||
previtemroulette = (players[player].previtemroulette > KROULETTE_DISABLED ? KROULETTE_ACTIVE : KROULETTE_DISABLED);
|
||||
itemroulette = players[player].itemroulette > 0 ? 1 : 0;
|
||||
previtemroulette = players[player].previtemroulette > 0 ? 1 : 0;
|
||||
roulettetype = players[player].roulettetype;
|
||||
|
||||
if (players[player].itemflags & IF_ITEMOUT)
|
||||
|
|
@ -2864,7 +2863,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
}
|
||||
|
||||
// Keep Shrink status, remove Grow status
|
||||
if (players[player].growshrinktimer < 0)
|
||||
// Alt. Shrink is a powerup, so don't keep that.
|
||||
if (players[player].growshrinktimer < 0 && !K_IsKartItemAlternate(KITEM_SHRINK))
|
||||
growshrinktimer = players[player].growshrinktimer;
|
||||
else
|
||||
growshrinktimer = 0;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime,
|
|||
extern consvar_t cv_shoutname, cv_shoutcolor, cv_autoshout;
|
||||
extern consvar_t cv_songcredits;
|
||||
extern consvar_t cv_showfreeplay;
|
||||
extern consvar_t cv_growmusic, cv_supermusic;
|
||||
extern consvar_t cv_growmusic, cv_supermusic, cv_altshrinkmusic;
|
||||
|
||||
extern consvar_t cv_pauseifunfocused;
|
||||
|
||||
|
|
@ -88,6 +88,7 @@ extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_gu
|
|||
|
||||
extern consvar_t cv_invincmusicfade;
|
||||
extern consvar_t cv_growmusicfade;
|
||||
extern consvar_t cv_altshrinkmusicfade;
|
||||
|
||||
extern consvar_t cv_resetspecialmusic;
|
||||
|
||||
|
|
|
|||
|
|
@ -336,6 +336,16 @@ void K_DisplayItemTimers(void)
|
|||
true,
|
||||
}
|
||||
);
|
||||
timers.push_back(
|
||||
{ // item cooldown
|
||||
"itemusecooldown",
|
||||
(INT32)stplyr->itemusecooldown,
|
||||
//{qche("K_ISFLMS")},
|
||||
{qche("SERVLOCK")},
|
||||
1, /*-15, -15,*/ -4, -2,
|
||||
false, false
|
||||
}
|
||||
);
|
||||
|
||||
/*timers.push_back(
|
||||
{ // dead
|
||||
|
|
|
|||
|
|
@ -977,11 +977,20 @@ void HWR_PrecacheLevel(void)
|
|||
// Precache flats.
|
||||
HWR_PrecacheLevelFlats();
|
||||
|
||||
// prevent timeouts
|
||||
NetKeepAlive();
|
||||
|
||||
// Precache textures.
|
||||
HWR_PrecacheLevelTextures();
|
||||
|
||||
// prevent timeouts
|
||||
NetKeepAlive();
|
||||
|
||||
// Precache sprites.
|
||||
//HWR_PrecacheLevelSprites();
|
||||
|
||||
// prevent timeouts
|
||||
//NetKeepAlive();
|
||||
}
|
||||
|
||||
void HWR_LoadMapTextures(size_t pnumtextures)
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "../k_kart.h"
|
||||
#include "../r_fps.h"
|
||||
#include "../r_plane.h" // R_FlatDimensionsFromLumpSize
|
||||
#include "../k_items.h"
|
||||
|
||||
#define R_FAKEFLOORS
|
||||
#define HWPRECIP
|
||||
|
|
@ -295,7 +296,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
|
|||
}
|
||||
|
||||
// Clamp the light level, since it can sometimes go out of the 0-255 range from animations
|
||||
light_level = min(max(light_level, cv_glsecbright.value), 255);
|
||||
light_level = min(max(light_level, cv_secbright.value), 255);
|
||||
|
||||
V_CubeApply(&tint_color.s.red, &tint_color.s.green, &tint_color.s.blue);
|
||||
V_CubeApply(&fade_color.s.red, &fade_color.s.green, &fade_color.s.blue);
|
||||
|
|
@ -4789,6 +4790,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2];
|
||||
#ifdef ROTSPRITE
|
||||
sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2];
|
||||
#endif
|
||||
}
|
||||
else if (thing->sprite == SPR_ITEM)
|
||||
{
|
||||
sprdef = &kartitems[thing->threshold > 0 && thing->threshold < numkartitems ? thing->threshold : 0].spritedef;
|
||||
#ifdef ROTSPRITE
|
||||
sprinfo = &spriteinfo[SPR_UNKN];
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
@ -4905,9 +4913,9 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
const fixed_t visoffymul = (vflip ? -FRACUNIT : FRACUNIT);
|
||||
|
||||
if (R_ThingIsUsingBakedOffsets(thing))
|
||||
if (R_ThingIsUsingBakedOffsets(interptarg))
|
||||
{
|
||||
R_RotateSpriteOffsetsByPitchRoll(thing,
|
||||
R_RotateSpriteOffsetsByPitchRoll(interptarg,
|
||||
vflip,
|
||||
hflip,
|
||||
&interp,
|
||||
|
|
|
|||
|
|
@ -97,7 +97,6 @@ extern consvar_t cv_glcoronasize;
|
|||
#endif
|
||||
|
||||
extern consvar_t cv_glshaders, cv_glallowshaders;
|
||||
extern consvar_t cv_glsecbright;
|
||||
extern consvar_t cv_glmodels;
|
||||
|
||||
// SRB2Kart: We don't like these options.
|
||||
|
|
|
|||
25
src/info.c
25
src/info.c
|
|
@ -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 :^)
|
||||
|
|
@ -116,6 +117,12 @@ static const char *hardcodemenus =
|
|||
#undef _
|
||||
;
|
||||
|
||||
static const char *hardcodeitems =
|
||||
#define _(name, ...) #name "\0"
|
||||
#include "info/kartitems.h"
|
||||
#undef _
|
||||
;
|
||||
|
||||
void P_ResetData(INT32 flags)
|
||||
{
|
||||
INT32 i;
|
||||
|
|
@ -233,4 +240,22 @@ 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));
|
||||
|
||||
numkartitems = KITEM_FIRSTFREESLOT;
|
||||
|
||||
if (kartitemnames)
|
||||
Z_Free(kartitemnames);
|
||||
kartitemnames = strbuf_alloc();
|
||||
name = hardcodeitems;
|
||||
for (i = 0; i < KITEM_FIRSTFREESLOT; i++, name += strlen(name)+1)
|
||||
{
|
||||
DEH_Link(name, &kartitems[i].info, &kartitemnames);
|
||||
K_RegisterItem(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
21
src/info/kartitems.h
Normal file
21
src/info/kartitems.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
_(NONE)
|
||||
_(SNEAKER)
|
||||
_(ROCKETSNEAKER)
|
||||
_(INVINCIBILITY)
|
||||
_(BANANA)
|
||||
_(EGGMAN)
|
||||
_(ORBINAUT)
|
||||
_(JAWZ)
|
||||
_(MINE)
|
||||
_(BALLHOG)
|
||||
_(SPB)
|
||||
_(GROW)
|
||||
_(SHRINK)
|
||||
_(THUNDERSHIELD)
|
||||
_(HYUDORO)
|
||||
_(POGOSPRING)
|
||||
_(KITCHENSINK)
|
||||
_(SUPERRING)
|
||||
_(LANDMINE)
|
||||
_(BUBBLESHIELD)
|
||||
_(FLAMESHIELD)
|
||||
|
|
@ -602,7 +602,11 @@ _(SMOLDERING) // New explosion
|
|||
_(BOOMEXPLODE)
|
||||
_(BOOMPARTICLE)
|
||||
|
||||
_(LANDMINE) // Land Mine
|
||||
// Land Mine
|
||||
_(LANDMINE)
|
||||
// Egg Mine
|
||||
// _(EGGMINE_CAPSULE)
|
||||
// _(EGGMINE_SHIELD)
|
||||
|
||||
_(BALLHOG) // Ballhog
|
||||
_(BALLHOGBOOM)
|
||||
|
|
@ -614,7 +618,7 @@ _(THUNDERSHIELD) // Shields
|
|||
_(BUBBLESHIELD)
|
||||
_(FLAMESHIELD)
|
||||
_(BUBBLESHIELDTRAP)
|
||||
_(BUBBLESHLD_DEBRIS)
|
||||
_(BUBBLESHIELD_DEBRIS)
|
||||
|
||||
_(SINK) // Kitchen Sink Stuff
|
||||
_(SINK_SHIELD)
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ _(pstop)
|
|||
_(steam1)
|
||||
_(steam2)
|
||||
_(wbreak)
|
||||
_(ambmac)
|
||||
_(spsmsh)
|
||||
|
||||
_(rainin)
|
||||
_(litng1)
|
||||
|
|
@ -114,7 +112,6 @@ _(dmpain)
|
|||
_(drown)
|
||||
_(fizzle)
|
||||
_(gbeep)
|
||||
_(wepfir)
|
||||
_(ghit)
|
||||
_(gloop)
|
||||
_(gspray)
|
||||
|
|
@ -126,19 +123,12 @@ _(lose)
|
|||
_(lvpass)
|
||||
_(mindig)
|
||||
_(mixup)
|
||||
_(monton)
|
||||
_(pogo)
|
||||
_(pop)
|
||||
_(rail1)
|
||||
_(rail2)
|
||||
_(rlaunc)
|
||||
_(shield)
|
||||
_(wirlsg)
|
||||
_(forcsg)
|
||||
_(frcssg)
|
||||
_(elemsg)
|
||||
_(armasg)
|
||||
_(attrsg)
|
||||
_(shldls)
|
||||
_(spdpad)
|
||||
_(spkdth)
|
||||
|
|
@ -154,24 +144,8 @@ _(trfire)
|
|||
_(trpowr)
|
||||
_(turhit)
|
||||
_(wdjump)
|
||||
_(shrpsp)
|
||||
_(shrpgo)
|
||||
_(mswarp)
|
||||
_(mspogo)
|
||||
_(boingf)
|
||||
_(corkp)
|
||||
_(corkh)
|
||||
_(alart)
|
||||
_(vwre)
|
||||
_(bowl)
|
||||
_(chuchu)
|
||||
//sfx_bsnipe,
|
||||
_(sprong)
|
||||
_(lvfal1)
|
||||
_(pscree)
|
||||
_(iceb)
|
||||
_(shattr)
|
||||
_(antiri)
|
||||
|
||||
// Menu, interface
|
||||
_(chchng)
|
||||
|
|
@ -185,16 +159,12 @@ _(radio)
|
|||
_(wepchg)
|
||||
_(wtrdng)
|
||||
_(zelda)
|
||||
_(adderr)
|
||||
_(notadd)
|
||||
_(addfil)
|
||||
|
||||
// NiGHTS
|
||||
_(ideya)
|
||||
_(xideya) // Xmas
|
||||
_(nbmper)
|
||||
_(nxbump) // Xmas
|
||||
_(ncchip)
|
||||
_(ncitem)
|
||||
_(nxitem) // Xmas
|
||||
_(ngdone)
|
||||
|
|
@ -210,14 +180,6 @@ _(hoop3)
|
|||
_(hidden)
|
||||
_(prloop)
|
||||
_(timeup)
|
||||
_(ngjump)
|
||||
_(peww)
|
||||
|
||||
// Halloween
|
||||
_(lntsit)
|
||||
_(lntdie)
|
||||
_(pumpkn)
|
||||
_(ghosty)
|
||||
|
||||
// Mario
|
||||
_(koopfr)
|
||||
|
|
@ -400,7 +362,6 @@ _(s26f)
|
|||
_(s270)
|
||||
|
||||
// S3&K sounds
|
||||
_(s3k2b)
|
||||
_(s3k33)
|
||||
_(s3k34)
|
||||
_(s3k35)
|
||||
|
|
@ -522,21 +483,6 @@ _(s3ka8)
|
|||
_(s3ka9)
|
||||
_(s3kaa)
|
||||
_(s3kab)
|
||||
_(s3kab1)
|
||||
_(s3kab2)
|
||||
_(s3kab3)
|
||||
_(s3kab4)
|
||||
_(s3kab5)
|
||||
_(s3kab6)
|
||||
_(s3kab7)
|
||||
_(s3kab8)
|
||||
_(s3kab9)
|
||||
_(s3kaba)
|
||||
_(s3kabb)
|
||||
_(s3kabc)
|
||||
_(s3kabd)
|
||||
_(s3kabe)
|
||||
_(s3kabf)
|
||||
_(s3kac)
|
||||
_(s3kad)
|
||||
_(s3kae)
|
||||
|
|
@ -845,18 +791,6 @@ _(itfree)
|
|||
_(dbgsal)
|
||||
_(bhurry) // mine: wasn't here already?
|
||||
|
||||
// Chaining Sound
|
||||
_(bstchn)
|
||||
|
||||
// Low Ring Sound
|
||||
_(ringlw)
|
||||
|
||||
// Flip Over Sound
|
||||
_(flipos)
|
||||
|
||||
// Shout message sound effect
|
||||
_(sysmsg)
|
||||
|
||||
// Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy...
|
||||
// Engine class A - Low Speed, Low Weight
|
||||
_(krta00)
|
||||
|
|
@ -997,3 +931,82 @@ _(kbost2)
|
|||
_(kslow)
|
||||
_(khitem)
|
||||
_(kgloat)
|
||||
|
||||
// Relocated 2.2 sounds to fix magic numbers in v1 maps
|
||||
_(ambmac)
|
||||
_(spsmsh)
|
||||
|
||||
_(wepfir)
|
||||
|
||||
_(monton)
|
||||
|
||||
_(wirlsg)
|
||||
_(forcsg)
|
||||
_(frcssg)
|
||||
_(elemsg)
|
||||
_(armasg)
|
||||
_(attrsg)
|
||||
|
||||
_(shrpsp)
|
||||
_(shrpgo)
|
||||
|
||||
_(boingf)
|
||||
_(corkp)
|
||||
_(corkh)
|
||||
_(alart)
|
||||
_(vwre)
|
||||
_(bowl)
|
||||
_(chuchu)
|
||||
_(sprong)
|
||||
_(lvfal1)
|
||||
_(pscree)
|
||||
_(iceb)
|
||||
_(shattr)
|
||||
_(antiri)
|
||||
|
||||
_(adderr)
|
||||
_(notadd)
|
||||
_(addfil)
|
||||
|
||||
_(ncchip)
|
||||
|
||||
_(ngjump)
|
||||
_(peww)
|
||||
|
||||
// Halloween
|
||||
_(lntsit)
|
||||
_(lntdie)
|
||||
_(pumpkn)
|
||||
_(ghosty)
|
||||
|
||||
_(s3k2b)
|
||||
|
||||
_(s3kab1)
|
||||
_(s3kab2)
|
||||
_(s3kab3)
|
||||
_(s3kab4)
|
||||
_(s3kab5)
|
||||
_(s3kab6)
|
||||
_(s3kab7)
|
||||
_(s3kab8)
|
||||
_(s3kab9)
|
||||
_(s3kaba)
|
||||
_(s3kabb)
|
||||
_(s3kabc)
|
||||
_(s3kabd)
|
||||
_(s3kabe)
|
||||
_(s3kabf)
|
||||
|
||||
// New Blan sounds
|
||||
|
||||
// Chaining Sound
|
||||
_(bstchn)
|
||||
|
||||
// Low Ring Sound
|
||||
_(ringlw)
|
||||
|
||||
// Flip Over Sound
|
||||
_(flipos)
|
||||
|
||||
// Shout message sound effect
|
||||
_(sysmsg)
|
||||
|
|
|
|||
|
|
@ -493,9 +493,6 @@ _(ARRO) // player arrows
|
|||
_(ITEM) // base item
|
||||
_(ITMO) // Multi-Orbinaut
|
||||
_(ITMI) // Invincibility
|
||||
_(ITSN) // Multi-Sneaker
|
||||
_(ITBA) // Multi-Banana
|
||||
_(ITJA) // Multi-Jawz
|
||||
_(ITMN)
|
||||
_(WANT)
|
||||
|
||||
|
|
|
|||
|
|
@ -2816,6 +2816,11 @@ _(SLOWBOOM10)
|
|||
_(LANDMINE)
|
||||
_(LANDMINE_EXPLODE)
|
||||
|
||||
// Egg mine
|
||||
// _(EGGMINE)
|
||||
// _(EGGMINE_POP)
|
||||
// _(EGGMINE_SHIELD)
|
||||
|
||||
// Ballhog
|
||||
_(BALLHOG1)
|
||||
_(BALLHOG2)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -305,6 +305,14 @@ static void K_ItemConfirmForTarget(botdata_t *bd, const player_t *bot, const pla
|
|||
}
|
||||
}
|
||||
|
||||
/// @brief checks if given bot isn't prevented from using items due to item cooldowns
|
||||
/// @param bot bot to check cooldowns for
|
||||
/// @return if bot is able to use item-related actions (using items or mashing the roulette)
|
||||
static boolean K_CheckBotItemCooldown(const player_t *bot)
|
||||
{
|
||||
return bot->itemusecooldown <= 0;
|
||||
}
|
||||
|
||||
|
||||
// Presses the item button & aim buttons for the bot.
|
||||
// dir - Aiming direction: 1 for forwards, -1 for backwards, 0 for neutral.
|
||||
|
|
@ -958,7 +966,8 @@ static void K_BotItemFlame(botdata_t *bd, const player_t *player)
|
|||
{
|
||||
ZoneScoped;
|
||||
|
||||
if (player->flametimer >= (itemtime*3)-5)
|
||||
// if we're smart enough, allow overheating the flame shield if we want to go off-road
|
||||
if (player->flametimer >= (itemtime*3)-5 && !(K_ApplyOffroad(player) && player->botvars.difficulty >= 6))
|
||||
{
|
||||
bd->itemdelay = 5;
|
||||
}
|
||||
|
|
@ -1155,7 +1164,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(K_GetKartResult("superring")))
|
||||
{
|
||||
// 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.
|
||||
|
|
@ -1201,7 +1210,7 @@ void K_BotItemUsage(botdata_t *bd, const player_t *player)
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (K_CanHandleItemDelay(bd, player))
|
||||
{
|
||||
bd->itemdelay--;
|
||||
|
|
@ -1209,6 +1218,8 @@ void K_BotItemUsage(botdata_t *bd, const player_t *player)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!K_CheckBotItemCooldown(player)) return;
|
||||
|
||||
if (player->itemroulette)
|
||||
{
|
||||
// Mashing behaviors
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
116
src/k_collide.c
116
src/k_collide.c
|
|
@ -7,7 +7,7 @@
|
|||
#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
|
||||
|
|
@ -256,10 +256,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
|
|||
}
|
||||
else
|
||||
{
|
||||
K_DropItems(t2->player); //K_StripItems(t2->player);
|
||||
//K_StripOther(t2->player);
|
||||
t2->player->itemroulette = KROULETTE_ACTIVE;
|
||||
t2->player->roulettetype = KROULETTETYPE_EGGMAN;
|
||||
K_StartRoulette(t2->player, KROULETTETYPE_EGGMAN);
|
||||
}
|
||||
|
||||
if (t2->player->flamestore && (K_GetShieldFromPlayer(t2->player) == KSHIELD_FLAME))
|
||||
|
|
@ -515,6 +512,12 @@ static inline BlockItReturn_t PIT_ThunderShieldAttack(mobj_t *thing)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (thing->type == MT_SPB) // If you destroy a SPB, you don't get the luxury of a cooldown.
|
||||
{
|
||||
spbplace = -1;
|
||||
K_SetIndirectItemCooldown(0);
|
||||
}
|
||||
|
||||
P_DamageMobj(thing, lightningSource, lightningSource, 1, DMG_VOLTAGE|DMG_CANTHURTSELF);
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
|
@ -573,12 +576,13 @@ static void K_BubbleShieldCollideDrain(player_t *player, mobj_t *bubble, INT16 d
|
|||
static boolean K_BubbleReflectingTrapItem(const mobj_t *t)
|
||||
{
|
||||
return t->type == MT_BANANA || (t->type == MT_ORBINAUT && t->flags2 & MF2_AMBUSH) || t->type == MT_JAWZ_DUD ||
|
||||
t->type == MT_EGGMANITEM || t->type == MT_SSMINE || t->type == MT_SSMINE_SHIELD || t->type == MT_LANDMINE;
|
||||
t->type == MT_EGGMANITEM || t->type == MT_SSMINE || t->type == MT_SSMINE_SHIELD || t->type == MT_LANDMINE;// ||
|
||||
// t->type == MT_EGGMINE_CAPSULE || t->type == MT_EGGMINE_SHIELD;
|
||||
}
|
||||
|
||||
static boolean K_StrongPlayerBump(const player_t *player)
|
||||
{
|
||||
return (((K_GetKartInvinType() == KARTINVIN_LEGACY) && (player->invincibilitytimer))
|
||||
return (((!K_IsKartItemAlternate(KITEM_INVINCIBILITY)) && (player->invincibilitytimer))
|
||||
|| (player->growshrinktimer > 0));
|
||||
}
|
||||
|
||||
|
|
@ -636,7 +640,7 @@ boolean K_BubbleShieldCanReflect(mobj_t *t)
|
|||
{
|
||||
return (t->type == MT_ORBINAUT || t->type == MT_JAWZ || t->type == MT_JAWZ_DUD
|
||||
|| t->type == MT_BANANA || t->type == MT_EGGMANITEM || t->type == MT_BALLHOG
|
||||
|| t->type == MT_SSMINE || t->type == MT_LANDMINE || t->type == MT_SINK
|
||||
|| t->type == MT_SSMINE || t->type == MT_LANDMINE || t->type == MT_SINK //|| t->type == MT_EGGMINE_CAPSULE
|
||||
|| t->type == MT_KART_LEFTOVER
|
||||
|| t->type == MT_PLAYER);
|
||||
}
|
||||
|
|
@ -656,6 +660,7 @@ static INT16 K_GetBubbleDamage(mobj_t* itm)
|
|||
{
|
||||
case MT_EGGMANITEM:
|
||||
case MT_BALLHOG:
|
||||
// case MT_EGGMINE_CAPSULE:
|
||||
// Experiment: Let Bubble Shields hard-counter Ballhogs and Eggboxes.
|
||||
dmg = 0;
|
||||
break;
|
||||
|
|
@ -820,7 +825,7 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
boolean t2Condition = false;
|
||||
|
||||
// Rim suggestion: Flipover damage is negligible at best, just cull it from Invincibility as a whole.
|
||||
if (K_GetKartInvinType() == KARTINVIN_LEGACY)
|
||||
if (!K_IsKartItemAlternate(KITEM_INVINCIBILITY))
|
||||
{
|
||||
t1Condition = (t1->player->invincibilitytimer > 0);
|
||||
t2Condition = (t2->player->invincibilitytimer > 0);
|
||||
|
|
@ -832,7 +837,7 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
K_DoInstashield(t2->player);
|
||||
return false;
|
||||
}
|
||||
else if (K_GetKartInvinType() == KARTINVIN_LEGACY)
|
||||
else if (!K_IsKartItemAlternate(KITEM_INVINCIBILITY))
|
||||
{
|
||||
if (t1Condition == true && t2Condition == false)
|
||||
{
|
||||
|
|
@ -857,19 +862,40 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
{
|
||||
if (G_CompatLevel(0x0008) || !hyudoroT1)
|
||||
{
|
||||
switch (cv_kartairsquish.value)
|
||||
if ((t2->player) && (K_IsAltShrunk(t2->player)) &&
|
||||
(!(t1->player && t1->player->growshrinktimer > 0)))
|
||||
{
|
||||
case 1:
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_SQUISH);
|
||||
return true;
|
||||
break;
|
||||
case 2:
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_FLIPOVER);
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
// Alt. Shrink: Just make the player flip over.
|
||||
if (P_DamageMobj(t2, NULL, NULL, 1, DMG_FLIPOVER))
|
||||
{
|
||||
K_AltShrinkPityIncrease(t2->player);
|
||||
t2->player->altshrinktimeshit++;
|
||||
|
||||
P_InstaThrust(t2, K_MomentumAngle(t2), K_Momentum2D(t2) / 3);
|
||||
|
||||
K_PlayPainSound(t2, NULL);
|
||||
}
|
||||
}
|
||||
if (P_IsObjectOnGround(t1) && P_IsObjectOnGround(t2))
|
||||
{
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_SQUISH);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cv_kartairsquish.value)
|
||||
{
|
||||
case 1:
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_SQUISH);
|
||||
return true;
|
||||
break;
|
||||
case 2:
|
||||
P_DamageMobj(t2, t1, t1, 1, DMG_FLIPOVER);
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -878,20 +904,42 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
if (G_CompatLevel(0x0008) || !hyudoroT2)
|
||||
{
|
||||
// shitty code duplication 🥲
|
||||
switch (cv_kartairsquish.value)
|
||||
|
||||
if ((t1->player) && (K_IsAltShrunk(t1->player)) &&
|
||||
(!(t2->player && t2->player->growshrinktimer > 0)))
|
||||
{
|
||||
case 1:
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_SQUISH);
|
||||
return true;
|
||||
break;
|
||||
case 2:
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_FLIPOVER);
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
// Alt. Shrink: Just make the player flip over.
|
||||
if (P_DamageMobj(t1, NULL, NULL, 1, DMG_FLIPOVER))
|
||||
{
|
||||
K_AltShrinkPityIncrease(t1->player);
|
||||
t1->player->altshrinktimeshit++;
|
||||
|
||||
P_InstaThrust(t1, K_MomentumAngle(t1), K_Momentum2D(t1) / 3);
|
||||
|
||||
K_PlayPainSound(t1, NULL);
|
||||
}
|
||||
}
|
||||
else if (P_IsObjectOnGround(t1) && P_IsObjectOnGround(t2))
|
||||
{
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_SQUISH);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cv_kartairsquish.value)
|
||||
{
|
||||
case 1:
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_SQUISH);
|
||||
return true;
|
||||
break;
|
||||
case 2:
|
||||
P_DamageMobj(t1, t2, t2, 1, DMG_FLIPOVER);
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
527
src/k_hud.c
527
src/k_hud.c
|
|
@ -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"
|
||||
|
|
@ -181,33 +181,12 @@ static patch_t *kp_wantedreticle;
|
|||
static patch_t *kp_minimapdot;
|
||||
|
||||
static patch_t *kp_itembg[8];
|
||||
static patch_t *kp_itemalt[4];
|
||||
static patch_t *kp_itemtimer[2];
|
||||
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];
|
||||
static patch_t *kp_check[11];
|
||||
|
||||
static patch_t *kp_eggnum[4];
|
||||
|
||||
|
|
@ -540,95 +519,54 @@ 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[4], "K_ITBC");
|
||||
HU_UpdatePatch(&kp_itembg[5], "K_ITBCD");
|
||||
HU_UpdatePatch(&kp_itemtimer[0], "K_ITIMER");
|
||||
HU_UpdatePatch(&kp_itemmulsticker[0], "K_ITMUL");
|
||||
HU_UpdatePatch(&kp_itemmulsticker[2], "K_ITMULC");
|
||||
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[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_itemalt[0], "K_ALTITM");
|
||||
HU_UpdatePatch(&kp_itemalt[1], "K_ALTITS");
|
||||
HU_UpdatePatch(&kp_itemalt[2], "K_ALTIMM");
|
||||
HU_UpdatePatch(&kp_itemalt[3], "K_ALTISM");
|
||||
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[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 < 2; j++)
|
||||
{
|
||||
kartitemgraphics_t *graphics = &item->graphics[j];
|
||||
for (INT32 k = 0; k < graphics->numpatches; k++)
|
||||
{
|
||||
if (graphics->patches[k] == NULL)
|
||||
{
|
||||
// have to manually do this because HU_UpdatePatch only checks graphics from added WADs during partadd
|
||||
// UUUUUGGGGGGGHHHHHHHHHHHHHHHHHHh
|
||||
lumpnum_t lump = W_CheckNumForName(graphics->patchnames[k]);
|
||||
graphics->patches[k] = lump == LUMPERROR ? missingpat : W_CachePatchNum(lump, PU_HUDGFX);
|
||||
}
|
||||
else
|
||||
HU_UpdatePatch(&graphics->patches[k], graphics->patchnames[k]);
|
||||
}
|
||||
}
|
||||
R_AddKartItemSprites(item);
|
||||
}
|
||||
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");
|
||||
for (i = 0; i < 6; i++)
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
buffer[7] = '1'+i;
|
||||
HU_UpdatePatch(&kp_check[i], "%s", buffer);
|
||||
}
|
||||
HU_UpdatePatch(&kp_check[10], "K_CHECKA");
|
||||
|
||||
// Eggman warning numbers
|
||||
sprintf(buffer, "K_EGGNx");
|
||||
|
|
@ -723,103 +661,6 @@ void K_LoadKartHUDGraphics(void)
|
|||
}
|
||||
}
|
||||
|
||||
// For the item toggle menu
|
||||
const char *K_GetItemPatch(UINT8 item, boolean tiny)
|
||||
{
|
||||
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
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//}
|
||||
|
||||
INT32 ITEM_X, ITEM_Y; // Item Window
|
||||
|
|
@ -890,6 +731,12 @@ patch_t *K_getItemMulPatch(boolean small)
|
|||
return K_UseColorHud() ? kp_itemmulsticker[2+ofs] : kp_itemmulsticker[ofs];
|
||||
}
|
||||
|
||||
patch_t *K_getItemAltPatch(boolean small, boolean multimode)
|
||||
{
|
||||
UINT8 ofs = (small ? 1 : 0) + (multimode ? 2 : 0);
|
||||
return kp_itemalt[ofs];
|
||||
}
|
||||
|
||||
// This version of the function was prototyped in Lua by Nev3r ... a HUGE thank you goes out to them!
|
||||
void K_ObjectTracking(trackingResult_t *result, const vector3_t *point, boolean reverse)
|
||||
{
|
||||
|
|
@ -1322,6 +1169,32 @@ static void K_DrawItemBar(INT32 fx, INT32 fy, INT32 fflags, fixed_t itembar, UIN
|
|||
V_DrawFixedFill(x+2*FRACUNIT, y+FRACUNIT, max(0, length - 2*FRACUNIT), FRACUNIT, colors[0]|fflags); // the shine
|
||||
}
|
||||
|
||||
// TODO: use an actual patch overlay and clip it instead of using a rect, now that an actual patch can be added for this
|
||||
static void K_DrawItemCooldown(INT32 fx, INT32 fy, INT32 fflags, tic_t timer, tic_t maxtimer)
|
||||
{
|
||||
const boolean fourp = r_splitscreen > 1;
|
||||
const INT32 rectTopFour = 13*FRACUNIT;
|
||||
INT32 rectTop = 10*FRACUNIT;
|
||||
INT32 rectSize = 40*FRACUNIT;
|
||||
fixed_t prog = FixedDiv(timer, maxtimer);
|
||||
INT32 length = min(rectSize, FixedMul(rectSize, prog));
|
||||
if (timer > 0 && maxtimer > 0)
|
||||
{
|
||||
if (fourp)
|
||||
{
|
||||
rectTop = 14*FRACUNIT;
|
||||
rectSize = 20*FRACUNIT;
|
||||
length = min(rectSize, FixedMul(rectSize, prog));
|
||||
|
||||
V_DrawFixedFill(fx + rectTop, fy + rectTopFour + (rectSize - length), rectSize, length, 2|fflags);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawFixedFill(fx + rectTop, fy + rectTop + (rectSize - length), rectSize, length, 2|fflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// see also MT_PLAYERARROW mobjthinker in p_mobj.c
|
||||
static void K_drawKartItem(void)
|
||||
{
|
||||
|
|
@ -1330,19 +1203,18 @@ 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;
|
||||
fixed_t itembar = -1, flamebar = -1;
|
||||
UINT16 localcolor = SKINCOLOR_NONE;
|
||||
SINT8 colormode = TC_RAINBOW;
|
||||
UINT8 *colmap = NULL;
|
||||
UINT8 *colormap = NULL;
|
||||
boolean flipamount = false; // Used for 3P/4P splitscreen to flip item amount stuff
|
||||
boolean isalt = false;
|
||||
|
||||
if (stplyr->itemroulette)
|
||||
{
|
||||
|
|
@ -1351,26 +1223,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 +1234,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 +1254,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 +1262,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 +1271,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,11 +1281,11 @@ 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;
|
||||
}
|
||||
else if ((stplyr->invincibilitytimer) && (K_GetKartInvinType() == KARTINVIN_ALTERN))
|
||||
else if ((stplyr->invincibilitytimer) && (K_IsKartItemAlternate(KITEM_INVINCIBILITY)))
|
||||
{
|
||||
itembar = FixedDiv(stplyr->invincibilitytimer, max(1, stplyr->maxinvincibilitytime));
|
||||
|
||||
|
|
@ -1441,13 +1293,16 @@ static void K_drawKartItem(void)
|
|||
flamebar = FixedDiv(stplyr->invincibilitycancel, 26);
|
||||
|
||||
if (leveltime & 1)
|
||||
localpatch = localinv;
|
||||
{
|
||||
localpatch = K_GetCachedItemPatch(KITEM_INVINCIBILITY, tiny, 0);
|
||||
isalt = true;
|
||||
}
|
||||
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,53 +1316,22 @@ static void K_drawKartItem(void)
|
|||
else if (stplyr->sadtimer > 0)
|
||||
{
|
||||
if (leveltime & 2)
|
||||
localpatch = kp_sadface[offset];
|
||||
localpatch = K_GetCachedItemPatch(MAXKARTITEMS, tiny, 0);
|
||||
else
|
||||
localpatch = kp_nodraw;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stplyr->itemamount <= 0)
|
||||
if (stplyr->itemamount <= 0 && stplyr->itemusecooldown <= 0)
|
||||
return;
|
||||
|
||||
switch(stplyr->itemtype)
|
||||
{
|
||||
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*/
|
||||
localpatch = K_GetCachedItemPatch(stplyr->itemtype, tiny, stplyr->itemamount);
|
||||
if (localpatch == NULL)
|
||||
localpatch = kp_nodraw; // diagnose underflows
|
||||
else if (K_IsKartItemAlternate(stplyr->itemtype))
|
||||
isalt = true;
|
||||
|
||||
default:
|
||||
localpatch = K_GetCachedItemPatch(stplyr->itemtype, offset);
|
||||
|
||||
if (localpatch == NULL)
|
||||
localpatch = kp_nodraw; // diagnose underflows
|
||||
break;
|
||||
}
|
||||
dark = K_GetItemFlags(stplyr->itemtype) & KIF_DARKBG;
|
||||
|
||||
if ((stplyr->itemflags & IF_ITEMOUT) && !(leveltime & 1))
|
||||
localpatch = kp_nodraw;
|
||||
|
|
@ -1519,10 +1343,11 @@ static void K_drawKartItem(void)
|
|||
|
||||
switch (stplyr->itemblinkmode)
|
||||
{
|
||||
case 2:
|
||||
case KITEMBLINK_DEBUG:
|
||||
case KITEMBLINK_KARMA:
|
||||
localcolor = K_RainbowColor(leveltime);
|
||||
break;
|
||||
case 1:
|
||||
case KITEMBLINK_MASHED:
|
||||
localcolor = SKINCOLOR_RED;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1532,7 +1357,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;
|
||||
|
|
@ -1540,7 +1365,14 @@ static void K_drawKartItem(void)
|
|||
fflags = info.flags;
|
||||
flipamount = info.flipamount;
|
||||
if (localcolor != SKINCOLOR_NONE)
|
||||
{
|
||||
colmap = R_GetTranslationColormap(colormode, localcolor, GTC_CACHE);
|
||||
}
|
||||
else if (K_GetItemFlags(stplyr->itemtype) & KIF_COLPATCH2PLAYER)
|
||||
{
|
||||
colmap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE);
|
||||
}
|
||||
|
||||
if (K_UseColorHud())
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
|
||||
|
||||
|
|
@ -1551,10 +1383,11 @@ static void K_drawKartItem(void)
|
|||
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 = (offset ? 6 : 10);
|
||||
UINT8 fancystep = tiny ? 6 : 10;
|
||||
fixed_t fancyoffset = (stplyr->itemroulette % 3)-1;
|
||||
|
||||
if (fancyoffset != 0)
|
||||
|
|
@ -1567,12 +1400,21 @@ static void K_drawKartItem(void)
|
|||
}
|
||||
|
||||
// Then, the numbers:
|
||||
if (stplyr->itemamount >= numberdisplaymin && !stplyr->itemroulette)
|
||||
if (stplyr->itemamount >= K_GetItemNumberDisplayMin(stplyr->itemtype, tiny) && !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)
|
||||
|
||||
// draw minecraft-style cooldown
|
||||
K_DrawItemCooldown(fx, fy, V_HUDTRANSHALF|fflags, stplyr->itemusecooldown, stplyr->itemusecooldownmax);
|
||||
|
||||
if (isalt)
|
||||
{
|
||||
V_DrawFixedPatch(fx<<FRACBITS, fy<<FRACBITS, FRACUNIT, V_HUDTRANS|fflags, K_getItemAltPatch(tiny, true), colmap);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -1584,7 +1426,16 @@ static void K_drawKartItem(void)
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch(fx<<FRACBITS, rfy, FRACUNIT, fancyflags, 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_ClearClipRect();
|
||||
|
||||
|
|
@ -1598,7 +1449,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)
|
||||
|
|
@ -2102,7 +1953,7 @@ static boolean K_drawKartPositionFaces(void)
|
|||
|
||||
V_DrawMappedPatch(FACE_X + offsets.x, Y + offsets.y, V_HUDTRANS|V_SNAPTOLEFT, facerank, colormap);
|
||||
|
||||
if ((players[rankplayer[i]].invincibilitytimer) && (K_GetKartInvinType() == KARTINVIN_ALTERN))
|
||||
if ((players[rankplayer[i]].invincibilitytimer) && (K_IsKartItemAlternate(KITEM_INVINCIBILITY)))
|
||||
{
|
||||
colormap = R_GetTranslationColormap(TC_BLINK, K_AltInvincibilityColor(leveltime / 2), GTC_CACHE);
|
||||
invinchudtrans = K_InvincibilityHUDVisibility(players[rankplayer[i]].invincibilitytimer);
|
||||
|
|
@ -2488,7 +2339,7 @@ static void K_DrawServerMods(INT32 x, INT32 y)
|
|||
{"Bump Drift", 0, NULL, K_GetBumpSpark() > 0, true},
|
||||
{"Bump Spark", 0, NULL, K_GetBumpSpark() > BUMPSPARK_NOCHARGE, true},
|
||||
{"Bump Spring", 0, &cv_kartbumpspring, -1, true},
|
||||
{"Alt. Invin.", 0, NULL, K_GetKartInvinType() == KARTINVIN_ALTERN, true}
|
||||
{"Alt. Invin.", 0, NULL, K_IsKartItemAlternate(KITEM_INVINCIBILITY), true}
|
||||
};
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
|
|
@ -3414,7 +3265,15 @@ static void K_drawKartPlayerCheck(void)
|
|||
pnum++; // white frames
|
||||
}
|
||||
|
||||
if (checkplayer->itemtype == KITEM_GROW || checkplayer->growshrinktimer > 0)
|
||||
if (checkplayer->itemtype == KITEM_FLAMESHIELD || checkplayer->flametimer > 0)
|
||||
{
|
||||
pnum += 8;
|
||||
}
|
||||
else if (K_IsAltShrunk(checkplayer) && (checkplayer->itemtype == KITEM_SHRINK || checkplayer->growshrinktimer < 0))
|
||||
{
|
||||
pnum += 6;
|
||||
}
|
||||
else if (checkplayer->itemtype == KITEM_GROW || checkplayer->growshrinktimer > 0)
|
||||
{
|
||||
pnum += 4;
|
||||
}
|
||||
|
|
@ -4335,9 +4194,9 @@ static void K_drawKartMinimap(void)
|
|||
|
||||
invingradient = K_InvincibilityGradient(players[i].invincibilitytimer);
|
||||
|
||||
if ((players[i].invincibilitytimer) && ((invingradient > (FRACUNIT/2)) || (K_GetKartInvinType() == KARTINVIN_LEGACY)))
|
||||
if ((players[i].invincibilitytimer) && ((invingradient > (FRACUNIT/2)) || (!K_IsKartItemAlternate(KITEM_INVINCIBILITY))))
|
||||
{
|
||||
usecolor = ((K_GetKartInvinType() == KARTINVIN_ALTERN) ? K_AltInvincibilityColor(leveltime / 2) : K_RainbowColor(leveltime / 2));
|
||||
usecolor = ((K_IsKartItemAlternate(KITEM_INVINCIBILITY)) ? K_AltInvincibilityColor(leveltime / 2) : K_RainbowColor(leveltime / 2));
|
||||
colorizeplayer = true;
|
||||
}
|
||||
else
|
||||
|
|
@ -4370,7 +4229,7 @@ static void K_drawKartMinimap(void)
|
|||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, workingPic, colormap, &iconoffsets);
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if ((K_GetKartInvinType() == KARTINVIN_ALTERN) &&
|
||||
if ((K_IsKartItemAlternate(KITEM_INVINCIBILITY)) &&
|
||||
(players[i].invincibilitytimer) && (invingradient))
|
||||
{
|
||||
// Draw Alt. Invin. sparkles
|
||||
|
|
@ -4665,7 +4524,7 @@ static void K_drawKartMinimap(void)
|
|||
|
||||
if ((players[localplayers[i]].invincibilitytimer) &&
|
||||
((invingradient > (FRACUNIT / 2)) ||
|
||||
(K_GetKartInvinType() == KARTINVIN_LEGACY)))
|
||||
(!K_IsKartItemAlternate(KITEM_INVINCIBILITY))))
|
||||
{
|
||||
usecolor = (K_RainbowColor(leveltime / 2));
|
||||
colorizeplayer = true;
|
||||
|
|
@ -4735,7 +4594,7 @@ static void K_drawKartMinimap(void)
|
|||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, workingPic, colormap, &iconoffsets);
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if ((!nocontest) && (K_GetKartInvinType() == KARTINVIN_ALTERN) &&
|
||||
if ((!nocontest) && (K_IsKartItemAlternate(KITEM_INVINCIBILITY)) &&
|
||||
(players[localplayers[i]].invincibilitytimer) && (invingradient))
|
||||
{
|
||||
// Draw Alt. Invin. sparkles
|
||||
|
|
@ -5758,48 +5617,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,41 +5648,43 @@ 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(K_GetKartResult("superring")))
|
||||
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 < NUMKARTRESULTS; item++)
|
||||
INT32 itemodds[MAXKARTRESULTS];
|
||||
kartroulette_t roulette = {
|
||||
.pdis = pdis,
|
||||
.playerpos = stplyr->position,
|
||||
.pos = useodds,
|
||||
.ourDist = stplyr->distancetofinish,
|
||||
.clusterDist = stplyr->distancefromcluster,
|
||||
.mashed = 0,
|
||||
.spbrush = spbrush,
|
||||
.bot = stplyr->bot,
|
||||
.rival = stplyr->bot && stplyr->botvars.rival,
|
||||
.inBottom = K_IsPlayerLosing(stplyr),
|
||||
};
|
||||
|
||||
K_KartGetItemOdds(&roulette, itemodds);
|
||||
|
||||
for (i = 0; i < numkartresults; i++)
|
||||
{
|
||||
INT32 itemodds;
|
||||
INT32 amount;
|
||||
kartresult_t *result = &kartresults[i];
|
||||
|
||||
itemodds = K_KartGetItemOdds(
|
||||
useodds, item,
|
||||
stplyr->distancetofinish,
|
||||
stplyr->distancefromcluster,
|
||||
0,
|
||||
spbrush, stplyr->bot, (stplyr->bot && stplyr->botvars.rival),
|
||||
K_IsPlayerLosing(stplyr)
|
||||
);
|
||||
|
||||
if (itemodds <= 0)
|
||||
if (itemodds[i] <= 0 && roulette.forceme[i] == 0) // At the very least display forced items; that info's also important.
|
||||
continue;
|
||||
|
||||
V_DrawScaledPatch(x, y, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, K_GetSmallStaticCachedItemPatch(item));
|
||||
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)
|
||||
{
|
||||
V_DrawString(x+24, y+31, V_SPLITSCREEN|V_ALLOWLOWERCASE|V_HUDTRANS|V_SNAPTOTOP, va("x%d", amount));
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(x, y, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, K_GetCachedItemPatch(result->type, true, 0));
|
||||
if (result->isalt)
|
||||
V_DrawScaledPatch(x+2, y, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, W_CachePatchName("K_ALTITS", PU_CACHE));
|
||||
V_DrawThinString(x+11, y+31, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, roulette.forceme[i] ? va("\x85" "FRC(%d)" "\x80 ", roulette.forceme[i]) : va("%d", itemodds[i]));
|
||||
if (result->amount > 1)
|
||||
V_DrawString(x+24, y+31, V_SPLITSCREEN|V_ALLOWLOWERCASE|V_HUDTRANS|V_SNAPTOTOP, va("x%d", result->amount));
|
||||
|
||||
x += 32;
|
||||
if (x >= 297)
|
||||
|
|
@ -5880,6 +5705,22 @@ static void K_drawDistributionDebugger(void)
|
|||
if (K_LegacyOddsMode())
|
||||
V_DrawSmallString(70, 0, V_SPLITSCREEN|V_HUDTRANS|V_SNAPTOTOP, "Legacy Distance Mode");
|
||||
|
||||
// cooldown timer debugging
|
||||
x = 240;
|
||||
y = 160;
|
||||
for (i = 0; i < numkartresults; i++)
|
||||
{
|
||||
kartresult_t *result = &kartresults[i];
|
||||
if (result->cooldown > 0 && result->isalt == K_IsKartItemAlternate(result->type))
|
||||
{
|
||||
INT32 color = result->flags & KRF_INDIRECTITEM ? V_ORANGEMAP : K_GetItemFlags(result->type) & KIF_UNIQUE ? V_YELLOWMAP : 0;
|
||||
V_DrawScaledPatch(x, y, V_HUDTRANS|V_SNAPTOBOTTOM, K_GetCachedItemPatch(result->type, true, 0));
|
||||
if (result->amount > 1)
|
||||
V_DrawThinString(x+30, y+30, V_ALLOWLOWERCASE|V_HUDTRANS|V_SNAPTOBOTTOM|V_6WIDTHSPACE, va("x%d", result->amount));
|
||||
V_DrawString(x+11, y+31, V_HUDTRANS|V_SNAPTOBOTTOM|color, va("%u", result->cooldown/TICRATE));
|
||||
x -= 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void K_drawCheckpointDebugger(void)
|
||||
|
|
|
|||
|
|
@ -89,13 +89,13 @@ typedef struct
|
|||
|
||||
patch_t *K_getItemBoxPatch(boolean small, boolean dark);
|
||||
patch_t *K_getItemMulPatch(boolean small);
|
||||
patch_t *K_getItemAltPatch(boolean small, boolean multimode);
|
||||
void K_getItemBoxDrawinfo(drawinfo_t *out);
|
||||
void K_getLapsDrawinfo(drawinfo_t *out);
|
||||
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);
|
||||
|
|
|
|||
2414
src/k_items.c
Normal file
2414
src/k_items.c
Normal file
File diff suppressed because it is too large
Load diff
217
src/k_items.h
Normal file
217
src/k_items.h
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
// BLANKART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2018-2025 by Kart Krew.
|
||||
// Copyright (C) 2025 by "yama".
|
||||
// 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"
|
||||
#include "r_defs.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
|
||||
{
|
||||
#define _(name, ...) KITEM_##name,
|
||||
#include "info/kartitems.h"
|
||||
#undef _
|
||||
KITEM_FIRSTFREESLOT,
|
||||
KITEM_LASTFREESLOT = 126,
|
||||
MAXKARTITEMS
|
||||
} ATTRPACK kartitemtype_e;
|
||||
|
||||
#define MAXKARTRESULTS 255
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KITEMBLINK_NORMAL,
|
||||
KITEMBLINK_MASHED,
|
||||
KITEMBLINK_KARMA,
|
||||
KITEMBLINK_DEBUG,
|
||||
} kartitemblink_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KROULETTETYPE_NORMAL,
|
||||
KROULETTETYPE_KARMA,
|
||||
KROULETTETYPE_EGGMAN,
|
||||
} kartroulettetype_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ODDS_RACE,
|
||||
ODDS_BATTLE,
|
||||
ODDS_SPECIAL,
|
||||
MAXODDSTABLES
|
||||
} ATTRPACK kartoddstable_e;
|
||||
|
||||
// item flags for usage and HUD
|
||||
typedef enum
|
||||
{
|
||||
KIF_UNIQUESLOT = 1<<0, // Prevents the item from being rolled if in a player's item slot
|
||||
KIF_UNIQUEDROP = 1<<1, // Prevents the item from being rolled if it exists as a dropped item
|
||||
KIF_UNIQUE = KIF_UNIQUESLOT|KIF_UNIQUEDROP,
|
||||
|
||||
KIF_ANIMATED = 1<<2, // animate patches instead of using diffrent patches for different amounts (inversion of xItemLib's XIF_ICONFORAMT)
|
||||
KIF_DARKBG = 1<<3, // use dark item roulette BG
|
||||
KIF_COLPATCH2PLAYER = 1<<4, // colourize patch to player
|
||||
KIF_HIDEFROMROULETTE = 1<<5, // don't show this item in the roulette (inversion of xItem's showInRoulette item flag)
|
||||
} ATTRPACK kartitemflags_e;
|
||||
|
||||
// result flags relevant to the roulette
|
||||
typedef enum
|
||||
{
|
||||
KRF_INDIRECTITEM = 1<<0, // This result's item affects others indirectly. All results with this flag share a single cooldown timer.
|
||||
KRF_POWERITEM = 1<<1, // This result is a "power item". This activates "frantic item" toggle related functionality.
|
||||
KRF_COOLDOWNONSTART = 1<<2, // This result should not appear at the beginning of a race. (Usually really powerful crowd-breaking items)
|
||||
KRF_NOTNEAREND = 1<<3, // This result should not appear at the end of a race. (Usually trap items that lose their effectiveness)
|
||||
KRF_NOTFORBOTTOM = 1<<4, // After the first 30 seconds, this result stops appearing for losing players. (Usually items that feel less effective at these positions)
|
||||
KRF_RUNNERAUGMENT = 1<<5, // This result's odds are affected by the severity of 1st place's frontrun. (Very likely only for SPBs, but who knows?)
|
||||
KRF_HIDEFROMSPB = 1<<6, // This result refuses to appear when a Self-Propelled Bomb is active in a race or battle.
|
||||
} ATTRPACK kartresultflags_e;
|
||||
|
||||
// Unique useodds function
|
||||
typedef INT32 (useoddsfunc_f)(INT32 odds, const kartroulette_t *roulette, const kartresult_t *result, UINT8 *forceme);
|
||||
|
||||
#define MAXITEMPATCHES 10
|
||||
|
||||
struct kartitemgraphics_t
|
||||
{
|
||||
UINT8 numpatches;
|
||||
char *patchnames[MAXITEMPATCHES];
|
||||
patch_t *patches[MAXITEMPATCHES];
|
||||
};
|
||||
|
||||
struct kartitem_t
|
||||
{
|
||||
dehinfo_t info;
|
||||
kartitemflags_e flags[2];
|
||||
kartitemgraphics_t graphics[2];
|
||||
spritedef_t spritedef;
|
||||
|
||||
consvar_t *altcvar; // if not NULL, an altitem exists
|
||||
boolean altenabled;
|
||||
|
||||
// note: could be how we do this?
|
||||
// int (*oddsOverrideFunc)(player_t *p, int pos, int mashed, boolean spbrush, fixed_t seconddist, int pingame, int pexiting);
|
||||
// int (*resultOverrideFunc)(player_t *p);
|
||||
};
|
||||
|
||||
struct kartresult_t
|
||||
{
|
||||
// this block is shared by all item variants
|
||||
consvar_t *cvar; // contains name
|
||||
kartitemtype_e type;
|
||||
UINT8 amount;
|
||||
|
||||
char *displayname;
|
||||
boolean isalt; // is alt (i salt)
|
||||
kartresultflags_e flags;
|
||||
UINT8 odds[MAXODDSTABLES][MAXODDS];
|
||||
|
||||
// Functions that tell the game to use unique means of rolling these items.
|
||||
// If NULL, the functions never execute.
|
||||
useoddsfunc_f *unique_odds[MAXODDSTABLES];
|
||||
|
||||
tic_t basecooldown, cooldown;
|
||||
};
|
||||
|
||||
// contains all data for a call to K_KartGetItemOdds
|
||||
struct kartroulette_t
|
||||
{
|
||||
UINT32 pdis; // the player's PDIS value
|
||||
SINT8 playerpos; // the player's position
|
||||
UINT8 pos; // position in the odds table (why is this just "pos"???)
|
||||
UINT32 ourDist; // the player's finish line distance
|
||||
UINT32 clusterDist; // distance to cluster
|
||||
fixed_t mashed;
|
||||
boolean spbrush;
|
||||
boolean bot;
|
||||
boolean rival;
|
||||
boolean inBottom;
|
||||
|
||||
// output: which results are being forced into a player's item slot for one reason or another. Higher value = higher priority.
|
||||
UINT8 forceme[MAXKARTRESULTS];
|
||||
|
||||
// extras for useodds functions
|
||||
UINT8 pingame;
|
||||
UINT8 pexiting;
|
||||
UINT32 firstDist;
|
||||
};
|
||||
|
||||
extern kartitem_t kartitems[MAXKARTITEMS];
|
||||
extern UINT8 numkartitems;
|
||||
extern kartresult_t kartresults[MAXKARTRESULTS];
|
||||
extern UINT8 numkartresults;
|
||||
extern UINT8 oddstablemax[MAXODDSTABLES];
|
||||
|
||||
void K_RegisterItem(kartitemtype_e itemtype);
|
||||
kartresult_t *K_RegisterResult(const char *name, boolean alternate);
|
||||
kartresult_t *K_GetKartResultAlt(const char *name, boolean alternate);
|
||||
#define K_GetKartResult(name) K_GetKartResultAlt(name, false)
|
||||
void K_SetupItemOdds(void);
|
||||
boolean K_ItemResultEnabled(const kartresult_t *result);
|
||||
boolean K_IsKartItemAlternate(kartitemtype_e itemtype);
|
||||
kartitemflags_e K_GetItemFlags(kartitemtype_e itemtype);
|
||||
UINT8 K_GetItemNumberDisplayMin(kartitemtype_e type, boolean tiny);
|
||||
patch_t *K_GetCachedItemPatch(kartitemtype_e type, boolean tiny, UINT8 amount);
|
||||
|
||||
void K_AwardPlayerItem(player_t *player, kartitemtype_e type, UINT8 amount, kartitemblink_e blink);
|
||||
void K_UpdateMobjItemOverlay(mobj_t *part, kartitemtype_e itemType, UINT8 itemCount);
|
||||
void K_UpdateItemCooldown(void);
|
||||
tic_t K_GetIndirectItemCooldown(void);
|
||||
void K_SetIndirectItemCooldown(tic_t cooldown);
|
||||
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_GetRollingRouletteItem(player_t *player);
|
||||
void K_KartItemRoulette(player_t *player, ticcmd_t *cmd);
|
||||
void K_StartRoulette(player_t *player, kartroulettetype_e roulettetype);
|
||||
|
||||
void K_SetPlayerItemCooldown(player_t *player, tic_t timer, boolean force);
|
||||
|
||||
useoddsfunc_f KO_AltInvinOdds;
|
||||
useoddsfunc_f KO_SPBRaceOdds;
|
||||
|
||||
void K_DoThunderShield(player_t *player);
|
||||
void K_BreakBubbleShield(player_t* player);
|
||||
INT16 K_GetShrinkTime(const player_t *player);
|
||||
boolean K_IsAltShrunk(const player_t *player);
|
||||
void K_AltShrinkPityIncrease(player_t *player);
|
||||
|
||||
void K_PlayerItemThink(player_t *player, boolean onground);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
void K_KartGetItemOdds(kartroulette_t *roulette, INT32 outodds[static MAXKARTRESULTS]);
|
||||
#endif
|
||||
|
||||
#endif // __K_ITEMS__
|
||||
1065
src/k_kart.c
1065
src/k_kart.c
File diff suppressed because it is too large
Load diff
16
src/k_kart.h
16
src/k_kart.h
|
|
@ -33,6 +33,7 @@ Make sure this matches the actual number of states
|
|||
#define SHRINK_SCALE ((6*FRACUNIT)/8)
|
||||
|
||||
#define BASEINVINTIME (10 * TICRATE)
|
||||
#define MININVINTIME (7 * TICRATE)
|
||||
|
||||
#define AUTORESPAWN_TIME (TICRATE/2)
|
||||
#define AUTORESPAWN_THRESHOLD (TICRATE/4)
|
||||
|
|
@ -126,6 +127,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)
|
||||
|
|
@ -254,12 +260,14 @@ void K_DoSneaker(player_t *player, INT32 type);
|
|||
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound);
|
||||
fixed_t K_InvincibilityGradient(UINT16 time);
|
||||
UINT16 K_GetInvincibilityTime(player_t *player);
|
||||
fixed_t K_GetInvincibilitySpeed(UINT16 time);
|
||||
fixed_t K_GetInvincibilityAccel(UINT16 time);
|
||||
void K_DoInvincibility(player_t *player, tic_t time);
|
||||
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source);
|
||||
void K_UpdateHnextList(player_t *player, boolean clean);
|
||||
void K_DropHnextList(player_t *player);
|
||||
void K_PopPlayerShield(player_t *player);
|
||||
boolean K_IsBubbleDefending(player_t *player);
|
||||
boolean K_IsBubbleDefending(const player_t *player);
|
||||
void K_RemoveBubbleHealth(player_t *player, INT16 sub);
|
||||
boolean K_CheckBubbleChip(const mobj_t *mobj);
|
||||
void K_RepairOrbitChain(mobj_t *orbit);
|
||||
|
|
@ -295,6 +303,7 @@ void K_SpawnWaterTrail(mobj_t *mobj);
|
|||
boolean K_ItemMobjAllowedtoWaterRun(mobj_t *item);
|
||||
void K_SetTireGrease(player_t *player, tic_t tics);
|
||||
boolean K_SlopeResistance(const player_t *player);
|
||||
void K_RemoveGrowShrink(player_t *player);
|
||||
void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
|
||||
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed, boolean karmabomb);
|
||||
|
|
@ -313,8 +322,6 @@ SINT8 K_Sliptiding(const player_t *player);
|
|||
fixed_t K_PlayerBaseFriction(const player_t *player, fixed_t original);
|
||||
void K_MoveKartPlayer(player_t *player, boolean onground);
|
||||
void K_CheckSpectateStatus(boolean considermapreset);
|
||||
UINT8 K_GetInvincibilityItemFrame(void);
|
||||
UINT8 K_GetMultItemFrame(UINT8 count, UINT8 max);
|
||||
boolean K_IsSPBInGame(void);
|
||||
|
||||
// sound stuff for lua
|
||||
|
|
@ -344,7 +351,6 @@ boolean K_DraftingActive(void);
|
|||
boolean K_AirDropActive(void);
|
||||
boolean K_ItemLitterActive(void);
|
||||
boolean K_ItemPushingActive(void);
|
||||
boolean K_GetKartInvinType(void);
|
||||
INT32 K_GetBumpSpark(void);
|
||||
boolean K_BoostChain(player_t *player, INT32 timer, boolean chainsound);
|
||||
INT32 K_ChainOrDeincrementTime(player_t *player, INT32 timer, INT32 deincrement, boolean chainsound);
|
||||
|
|
@ -352,8 +358,6 @@ boolean K_UsingLegacyCheckpoints(void);
|
|||
boolean K_UsingPatchedMap(void);
|
||||
INT32 K_CheckpointThreshold(boolean roundup);
|
||||
|
||||
void K_UpdateMobjItemOverlay(mobj_t *part, SINT8 itemType, UINT8 itemCount);
|
||||
|
||||
fixed_t K_BoostRescale(fixed_t value,fixed_t oldmin,fixed_t oldmax,fixed_t newmin,fixed_t newmax);
|
||||
void K_DoBoost(player_t *player, fixed_t speedboost, fixed_t accelboost, boolean stack, boolean visible);
|
||||
void K_ClearBoost(player_t *player);
|
||||
|
|
|
|||
1561
src/k_odds.c
1561
src/k_odds.c
File diff suppressed because it is too large
Load diff
72
src/k_odds.h
72
src/k_odds.h
|
|
@ -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__
|
||||
|
|
@ -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
|
||||
|
|
@ -1418,7 +1418,7 @@ static int lib_pMovePlayer(lua_State *L)
|
|||
static int lib_pDoPlayerExit(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
pflags_t flags = luaL_checkinteger(L, 2);
|
||||
pflags_t flags = lua_isnoneornil(L, 2) ? 0 : luaL_checkinteger(L, 2);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!player)
|
||||
|
|
@ -4026,10 +4026,44 @@ 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;
|
||||
}
|
||||
|
||||
static int lib_kIsKartItemAlternate(lua_State *L)
|
||||
{
|
||||
kartitemtype_e item = (kartitemtype_e)luaL_optinteger(L, 1, KITEM_NONE);
|
||||
// HUDSAFE
|
||||
|
||||
if (item <= 0 || item >= numkartitems)
|
||||
return luaL_error(L, "item number %d out of range (0 - %d)", item, numkartitems-1);
|
||||
|
||||
lua_pushboolean(L, K_IsKartItemAlternate(item));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kIsAltShrunk(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
||||
//HUDSAFE
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
lua_pushboolean(L, K_IsAltShrunk(player));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -4102,7 +4136,7 @@ static int lib_kSetIndirectItemCountdown(lua_State *L)
|
|||
{
|
||||
tic_t c = (tic_t)luaL_checkinteger(L, 1);
|
||||
NOHUD
|
||||
indirectitemcooldown = c;
|
||||
K_SetIndirectItemCooldown(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -4111,48 +4145,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")->cooldown = 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 +4223,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)
|
||||
{
|
||||
|
|
@ -4312,6 +4301,33 @@ static int lib_kGetNewSpeed(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kInvincibilityGradient(lua_State *L)
|
||||
{
|
||||
UINT16 time = (UINT16)luaL_checkinteger(L, 1);
|
||||
// HUDSAFE
|
||||
|
||||
lua_pushinteger(L, K_InvincibilityGradient(time));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetInvincibilitySpeed(lua_State *L)
|
||||
{
|
||||
UINT16 time = (UINT16)luaL_checkinteger(L, 1);
|
||||
// HUDSAFE
|
||||
|
||||
lua_pushinteger(L, K_GetInvincibilitySpeed(time));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetInvincibilityAccel(lua_State *L)
|
||||
{
|
||||
UINT16 time = (UINT16)luaL_checkinteger(L, 1);
|
||||
// HUDSAFE
|
||||
|
||||
lua_pushinteger(L, K_GetInvincibilityAccel(time));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_k3dKartMovement(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
|
@ -5053,6 +5069,17 @@ static int lib_kTerrainHasAffect(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kSetPlayerItemCooldown(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
tic_t c = (tic_t)luaL_checkinteger(L, 2);
|
||||
boolean force = lua_optboolean(L, 3);
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
K_SetPlayerItemCooldown(player, c, force);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static luaL_Reg lib[] = {
|
||||
{"print", lib_print},
|
||||
{"chatprint", lib_chatprint},
|
||||
|
|
@ -5337,13 +5364,12 @@ static luaL_Reg lib[] = {
|
|||
{"K_GetKartAccel",lib_kGetKartAccel},
|
||||
{"K_GetKartFlashing",lib_kGetKartFlashing},
|
||||
{"K_GetItemPatch",lib_kGetItemPatch},
|
||||
{"K_IsKartItemAlternate",lib_kIsKartItemAlternate},
|
||||
{"K_IsAltShrunk", lib_kIsAltShrunk},
|
||||
{"K_SetRaceCountdown",lib_kSetRaceCountdown},
|
||||
{"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,13 +5384,15 @@ 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},
|
||||
{"K_BoostChain",lib_kBoostChain},
|
||||
{"K_ChainOrDeincrementTime",lib_kChainOrDeincrementTime},
|
||||
{"K_GetNewSpeed", lib_kGetNewSpeed},
|
||||
{"K_InvincibilityGradient", lib_kInvincibilityGradient},
|
||||
{"K_GetInvincibilitySpeed", lib_kGetInvincibilitySpeed},
|
||||
{"K_GetInvincibilityAccel", lib_kGetInvincibilityAccel},
|
||||
{"K_3dKartMovement", lib_k3dKartMovement},
|
||||
{"K_MomentumAngle", lib_kMomentumAngle},
|
||||
{"K_GetKartSpeedFromStat", lib_kGetKartSpeedFromStat},
|
||||
|
|
@ -5435,6 +5463,9 @@ static luaL_Reg lib[] = {
|
|||
{"K_HandleFootstepParticles", lib_kHandleFootstepParticles},
|
||||
{"K_UpdateTerrainOverlay", lib_kUpdateTerrainOverlay},
|
||||
{"K_TerrainHasAffect", lib_kTerrainHasAffect},
|
||||
|
||||
// k_items
|
||||
{"K_SetPlayerItemCooldown", lib_kSetPlayerItemCooldown},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2012-2022 by Sonic Team Junior.
|
||||
|
|
@ -40,6 +39,7 @@ automatically.
|
|||
X (MobjFuse),/* when mobj->fuse runs out */\
|
||||
X (MobjThinker),/* P_MobjThinker, P_SceneryThinker */\
|
||||
X (BossThinker),/* P_GenericBossThinker */\
|
||||
X (MobjScaleChange),/*SRB2KART*/\
|
||||
X (ShouldDamage),/* P_DamageMobj (Should mobj take damage?) */\
|
||||
X (ShouldSpin),/* P_DamageMobj (Should mobj take spinout damage?) */\
|
||||
X (ShouldExplode),/* P_DamageMobj (Should mobj take explosion damage?) */\
|
||||
|
|
@ -86,6 +86,9 @@ automatically.
|
|||
X (BotJoin),\
|
||||
X (GPRankPoints),/* K_CalculateGPRankPoints */\
|
||||
X (AddonLoaded),\
|
||||
X (PlayerItem),/*SRB2KART*/\
|
||||
X (KartHyudoro),/*SRB2KART*/\
|
||||
X (KartSneaker),/*SRB2KART*/\
|
||||
|
||||
#define STRING_HOOK_LIST(X) \
|
||||
X (SpecialExecute),\
|
||||
|
|
@ -171,6 +174,12 @@ int LUA_HookGPRankPoints(UINT8 position, UINT8 numplayers, INT16 *points);
|
|||
int LUA_HookShouldJingleContinue(player_t *, const char *musname);
|
||||
int LUA_HookMusicChange(const char *oldname, struct MusicChange *);
|
||||
|
||||
// Item shit
|
||||
boolean LUA_HookPlayerItem(player_t *player, UINT8 itemType, boolean wasHoldingItem, boolean *force);
|
||||
boolean LUA_HookKartHyudoro(player_t *player, INT32 *target, boolean sink); // SRB2Kart: Hook for K_DoHyudoroSteal and overriding its results.
|
||||
boolean LUA_HookMobjScaleChange(mobj_t *target, fixed_t newscale, fixed_t oldscale); // SRB2Kart: Hook for P_SetScale.
|
||||
boolean LUA_HookKartSneaker(player_t *player, int type); // SRB2Kart: Hook for K_DoSneaker.
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1260,3 +1260,115 @@ int LUA_HookMusicChange(const char *oldname, struct MusicChange *param)
|
|||
|
||||
return hook.status;
|
||||
}
|
||||
|
||||
// Allows to both override default behavior and force action. I don't like it but thats how it works
|
||||
// in CEP and neptune. Fuckal whyyyyyyyyy
|
||||
typedef struct {
|
||||
boolean override;
|
||||
boolean force;
|
||||
} TrueForce_State;
|
||||
|
||||
static void res_trueforce(Hook_State *hook)
|
||||
{
|
||||
TrueForce_State *state = (TrueForce_State*)hook->userdata;
|
||||
|
||||
if (lua_isboolean(gL, -2))
|
||||
state->override = lua_toboolean(gL, -2);
|
||||
|
||||
if (lua_isboolean(gL, -1))
|
||||
state->force = lua_toboolean(gL, -1);
|
||||
};
|
||||
|
||||
boolean LUA_HookPlayerItem(player_t *player, UINT8 itemType, boolean wasHoldingItem, boolean *force)
|
||||
{
|
||||
Hook_State hook;
|
||||
TrueForce_State state = {0};
|
||||
|
||||
if (prepare_hook(&hook, 0, HOOK(PlayerItem)))
|
||||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
lua_pushinteger(gL, itemType);
|
||||
lua_pushboolean(gL, wasHoldingItem);
|
||||
|
||||
hook.userdata = &state;
|
||||
|
||||
call_hooks(&hook, 2, res_trueforce);
|
||||
}
|
||||
|
||||
*force = state.force;
|
||||
return state.override;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
INT32 *target;
|
||||
boolean force_sink;
|
||||
} KartHyudoro_State;
|
||||
|
||||
static void res_karthyudoro(Hook_State *hook)
|
||||
{
|
||||
KartHyudoro_State *state = (KartHyudoro_State*)hook->userdata;
|
||||
|
||||
if (lua_isnumber(gL, -2))
|
||||
*state->target = lua_tonumber(gL, -2);
|
||||
else if (lua_isuserdata(gL, -2))
|
||||
{
|
||||
player_t *player = *(player_t**)luaL_checkudata(gL, -2, META_PLAYER);
|
||||
*state->target = player - players;
|
||||
}
|
||||
|
||||
if (lua_isboolean(gL, -1))
|
||||
state->force_sink = lua_toboolean(gL, -1);
|
||||
}
|
||||
|
||||
boolean LUA_HookKartHyudoro(player_t *player, INT32 *target, boolean sink)
|
||||
{
|
||||
Hook_State hook;
|
||||
KartHyudoro_State state = {0};
|
||||
state.target = target;
|
||||
|
||||
if (prepare_hook(&hook, 0, HOOK(KartHyudoro)))
|
||||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
if (*target >= 0)
|
||||
LUA_PushUserdata(gL, &players[*target], META_PLAYER);
|
||||
else
|
||||
lua_pushnil(gL);
|
||||
lua_pushboolean(gL, sink);
|
||||
|
||||
hook.userdata = &state;
|
||||
|
||||
call_hooks(&hook, 2, res_karthyudoro);
|
||||
}
|
||||
|
||||
return state.force_sink;
|
||||
|
||||
}
|
||||
|
||||
boolean LUA_HookMobjScaleChange(mobj_t *target, fixed_t newscale, fixed_t oldscale)
|
||||
{
|
||||
Hook_State hook;
|
||||
if (prepare_mobj_hook(&hook, false, MOBJ_HOOK(MobjScaleChange), target->type))
|
||||
{
|
||||
LUA_PushUserdata(gL, target, META_MOBJ);
|
||||
lua_pushfixed(gL, newscale);
|
||||
lua_pushfixed(gL, oldscale);
|
||||
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
||||
boolean LUA_HookKartSneaker(player_t *player, int type)
|
||||
{
|
||||
Hook_State hook;
|
||||
if (prepare_hook(&hook, false, HOOK(KartSneaker)))
|
||||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
// Type of sneaker: 0 - perfect/panel, 1 - regular sneaker, 2 - rocket sneaker.
|
||||
lua_pushinteger(gL, type);
|
||||
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
|
||||
return hook.status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,7 +178,8 @@ static const char *const camera_opt[] = {
|
|||
|
||||
enum hudpatch {
|
||||
hudpatch_item = 0,
|
||||
hudpatch_itemmul
|
||||
hudpatch_itemmul,
|
||||
hudpatch_itemalt
|
||||
};
|
||||
|
||||
static const char *const hud_patch_options[] = {
|
||||
|
|
@ -411,6 +412,9 @@ static int libd_getSpritePatch(lua_State *L)
|
|||
if (i == SPR_PLAY) // Use getSprite2Patch instead!
|
||||
return 0;
|
||||
|
||||
if (i == SPR_ITEM) // Use... uhhhhh...
|
||||
return 0;
|
||||
|
||||
sprdef = &sprites[i];
|
||||
|
||||
// set frame number
|
||||
|
|
@ -1184,7 +1188,7 @@ static int libd_getColorHudPatch(lua_State *L)
|
|||
enum hudpatch option = luaL_checkoption(L, 1, NULL, hud_patch_options);
|
||||
patch_t *patch;
|
||||
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
|
||||
boolean small, dark;
|
||||
boolean small, dark, multi;
|
||||
|
||||
switch (option) {
|
||||
case hudpatch_item:
|
||||
|
|
@ -1198,6 +1202,11 @@ static int libd_getColorHudPatch(lua_State *L)
|
|||
small = lua_optboolean(L, 2);
|
||||
patch = K_getItemMulPatch(small);
|
||||
break;
|
||||
case hudpatch_itemalt:
|
||||
small = lua_optboolean(L, 2);
|
||||
multi = lua_optboolean(L, 3);
|
||||
patch = K_getItemAltPatch(small, multi);
|
||||
break;
|
||||
default:
|
||||
return 0; // you shouldn't be here
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,6 +249,8 @@ enum player_e
|
|||
player_roulettetype,
|
||||
player_itemtype,
|
||||
player_itemamount,
|
||||
player_itemusecooldown,
|
||||
player_itemusecooldownmax,
|
||||
player_throwdir,
|
||||
player_sadtimer,
|
||||
player_rings,
|
||||
|
|
@ -285,6 +287,10 @@ enum player_e
|
|||
player_squishedtimer,
|
||||
player_rocketsneakertimer,
|
||||
player_invincibilitytimer,
|
||||
player_maxinvincibilitytime,
|
||||
player_invincibilitybottleneck,
|
||||
player_invincibilitycancel,
|
||||
player_invincibilitywarning,
|
||||
player_eggmanexplode,
|
||||
player_eggmanblame,
|
||||
player_bananadrag,
|
||||
|
|
@ -453,6 +459,8 @@ static const char *const player_opt[] = {
|
|||
"roulettetype",
|
||||
"itemtype",
|
||||
"itemamount",
|
||||
"itemusecooldown",
|
||||
"itemusecooldownmax",
|
||||
"throwdir",
|
||||
"sadtimer",
|
||||
"rings",
|
||||
|
|
@ -489,6 +497,10 @@ static const char *const player_opt[] = {
|
|||
"squishedtimer",
|
||||
"rocketsneakertimer",
|
||||
"invincibilitytimer",
|
||||
"maxinvincibilitytime",
|
||||
"invincibilitybottleneck",
|
||||
"invincibilitycancel",
|
||||
"invincibilitywarning", // This gets cast to a boolean in Lua.
|
||||
"eggmanexplode",
|
||||
"eggmanblame",
|
||||
"bananadrag",
|
||||
|
|
@ -855,6 +867,12 @@ static int player_get(lua_State *L)
|
|||
case player_itemamount:
|
||||
lua_pushinteger(L, plr->itemamount);
|
||||
break;
|
||||
case player_itemusecooldown:
|
||||
lua_pushinteger(L, plr->itemusecooldown);
|
||||
break;
|
||||
case player_itemusecooldownmax:
|
||||
lua_pushinteger(L, plr->itemusecooldownmax);
|
||||
break;
|
||||
case player_throwdir:
|
||||
lua_pushinteger(L, plr->throwdir);
|
||||
break;
|
||||
|
|
@ -963,6 +981,19 @@ static int player_get(lua_State *L)
|
|||
case player_invincibilitytimer:
|
||||
lua_pushinteger(L, plr->invincibilitytimer);
|
||||
break;
|
||||
case player_maxinvincibilitytime:
|
||||
lua_pushinteger(L, plr->maxinvincibilitytime);
|
||||
break;
|
||||
case player_invincibilitybottleneck:
|
||||
// Push as an INT16 due to the negative value signal systems.
|
||||
lua_pushinteger(L, (INT16)plr->invincibilitybottleneck);
|
||||
break;
|
||||
case player_invincibilitycancel:
|
||||
lua_pushinteger(L, plr->invincibilitycancel);
|
||||
break;
|
||||
case player_invincibilitywarning:
|
||||
lua_pushboolean(L, (boolean)plr->invincibilitywarning);
|
||||
break;
|
||||
case player_eggmanexplode:
|
||||
lua_pushinteger(L, plr->eggmanexplode);
|
||||
break;
|
||||
|
|
@ -1568,6 +1599,12 @@ static int player_set(lua_State *L)
|
|||
case player_itemamount:
|
||||
plr->itemamount = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case player_itemusecooldown:
|
||||
plr->itemusecooldown = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case player_itemusecooldownmax:
|
||||
plr->itemusecooldownmax = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case player_throwdir:
|
||||
plr->throwdir = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
|
|
@ -1667,14 +1704,34 @@ static int player_set(lua_State *L)
|
|||
plr->growcancel = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case player_squishedtimer:
|
||||
plr->squishedtimer = luaL_checkinteger(L, 3);
|
||||
{
|
||||
// Unsquish for the ease of Lua programmers
|
||||
INT16 squishtimer = (INT16)luaL_checkinteger(L, 3);
|
||||
|
||||
if (squishtimer == 0)
|
||||
plr->mo->spriteyscale = FRACUNIT;
|
||||
|
||||
plr->squishedtimer = squishtimer;
|
||||
break;
|
||||
}
|
||||
case player_rocketsneakertimer:
|
||||
plr->rocketsneakertimer = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case player_invincibilitytimer:
|
||||
plr->invincibilitytimer = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case player_maxinvincibilitytime:
|
||||
// For most other cases, I'd just say: "it's your funeral". Not for this one.
|
||||
return NOSET;
|
||||
case player_invincibilitybottleneck:
|
||||
plr->invincibilitybottleneck = (UINT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case player_invincibilitycancel:
|
||||
plr->invincibilitycancel = (INT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case player_invincibilitywarning:
|
||||
plr->invincibilitywarning = (UINT8)luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case player_eggmanexplode:
|
||||
plr->eggmanexplode = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
|
|
@ -2455,8 +2512,14 @@ static int kartstuff_set(lua_State *L)
|
|||
plr->growshrinktimer = CLAMP(i, INT16_MIN, INT16_MAX);
|
||||
break;
|
||||
case k_squishedtimer:
|
||||
{
|
||||
// Unsquish for the ease of Lua programmers
|
||||
if (i == 0)
|
||||
plr->mo->spriteyscale = FRACUNIT;
|
||||
|
||||
plr->squishedtimer = CLAMP(i, INT16_MIN, INT16_MAX);
|
||||
break;
|
||||
}
|
||||
case k_rocketsneakertimer:
|
||||
plr->rocketsneakertimer = CLAMP(i, 0, UINT16_MAX);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -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")->cooldown);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"encoremode")) {
|
||||
lua_pushboolean(L, encoremode);
|
||||
|
|
@ -436,7 +433,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
lua_pushinteger(L, wantedcalcdelay);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"indirectitemcooldown")) {
|
||||
lua_pushinteger(L, indirectitemcooldown);
|
||||
lua_pushinteger(L, K_GetIndirectItemCooldown());
|
||||
return 1;
|
||||
} else if (fastcmp(word,"thwompsactive")) {
|
||||
lua_pushboolean(L, thwompsactive);
|
||||
|
|
@ -562,11 +559,9 @@ int LUA_WriteGlobals(lua_State *L, const char *word)
|
|||
else if (fastcmp(word,"exitcountdown"))
|
||||
exitcountdown = (tic_t)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word,"indirectitemcooldown"))
|
||||
indirectitemcooldown = (tic_t)luaL_checkinteger(L, 2);
|
||||
K_SetIndirectItemCooldown(luaL_checkinteger(L, 2));
|
||||
else if (fastcmp(word,"hyubgone"))
|
||||
{
|
||||
K_SetBGone(KITEM_HYUDORO, (tic_t)luaL_checkinteger(L, 2));
|
||||
}
|
||||
K_GetKartResult("hyudoro")->cooldown = (tic_t)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word,"starttime"))
|
||||
starttime = (tic_t)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word,"introtime"))
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
#define __M_FIXED__
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "doomdef.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
|
@ -84,6 +86,53 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t DoubleToFixed(double f)
|
|||
return (fixed_t)(f * FRACUNIT);
|
||||
}
|
||||
|
||||
/** \brief Converts seconds (in tics) to fixed-point number values; 1 second is 1 fracunit.
|
||||
|
||||
\param t (tic_t) time
|
||||
|
||||
\return (fixed_t) seconds as fracunits
|
||||
*/
|
||||
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t SecsToFixed(tic_t t)
|
||||
{
|
||||
return (fixed_t)(((UINT64)t * FRACUNIT) / (TICRATE));
|
||||
}
|
||||
|
||||
/** \brief Converts tens of seconds (in tics) to fixed-point number values; 10 seconds is 1
|
||||
fracunit.
|
||||
|
||||
\param t (tic_t) time
|
||||
|
||||
\return (fixed_t) tens of seconds as fracunits
|
||||
*/
|
||||
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t SecsToFixedTens(tic_t t)
|
||||
{
|
||||
return (fixed_t)(((UINT64)t * FRACUNIT) / (10 * TICRATE));
|
||||
}
|
||||
|
||||
/** \brief 64-bit version of SecsToFixed. Converts seconds (in tics) to fixed-point number values; 1
|
||||
second is 1 fracunit.
|
||||
|
||||
\param t (tic_t) time
|
||||
|
||||
\return (sint64_t) seconds as fracunits
|
||||
*/
|
||||
FUNCMATH FUNCINLINE static ATTRINLINE INT64 SecsToFixed64(tic_t t)
|
||||
{
|
||||
return (INT64)(((UINT64)t * FRACUNIT) / (TICRATE));
|
||||
}
|
||||
|
||||
/** \brief 64-bit version of SecsToFixedTens. Converts tens of seconds (in tics) to fixed-point
|
||||
number values; 10 seconds is 1 fracunit.
|
||||
|
||||
\param t (tic_t) time
|
||||
|
||||
\return (sint64_t) tens of seconds as fracunits
|
||||
*/
|
||||
FUNCMATH FUNCINLINE static ATTRINLINE INT64 SecsToFixedTens64(tic_t t)
|
||||
{
|
||||
return (INT64)(((UINT64)t * FRACUNIT) / (10 * TICRATE));
|
||||
}
|
||||
|
||||
// for backwards compat
|
||||
#define FIXED_TO_FLOAT(x) FixedToFloat(x) // (((float)(x)) / ((float)FRACUNIT))
|
||||
#define FLOAT_TO_FIXED(f) FloatToFixed(f) // (fixed_t)((f) * ((float)FRACUNIT))
|
||||
|
|
|
|||
222
src/m_menu.c
222
src/m_menu.c
|
|
@ -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
|
||||
|
|
@ -8317,6 +8317,56 @@ INT32 MR_CameraSetup(INT32 arg)
|
|||
|
||||
static tic_t shitsfree = 0;
|
||||
|
||||
INT32 MR_SetupMonitorToggles(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
const INT32 height = 4;
|
||||
menu_t *menudef = &menudefs[MN_OP_MONITORTOGGLE];
|
||||
|
||||
// in the interest of not rushing the implementation of menu frames...
|
||||
// leak the memory. every single time.
|
||||
// (i dont think this actually leaks anything lol)
|
||||
// (unless someone adds menuitems to this menu for some stupid reason)
|
||||
menudef->numitems = 0;
|
||||
|
||||
for (UINT8 i = 0; i <= numkartresults; i++)
|
||||
{
|
||||
kartresult_t *result = i < 3 ? &kartresults[i] : i == 3 ? NULL : &kartresults[i - 1];
|
||||
if (result != NULL && result->isalt)
|
||||
continue;
|
||||
|
||||
menudef->menuitems = Z_Realloc(menudef->menuitems, sizeof(menuitem_t)*(menudef->numitems+1), PU_STATIC, NULL);
|
||||
menuitem_t *item = menudef->menuitems + menudef->numitems++;
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
item->argument = 1;
|
||||
item->patch = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
item->argument = 0;
|
||||
item->patch = result->cvar->name;
|
||||
if (kartitems[result->type].altcvar != NULL)
|
||||
item->tooltip = "Press BACKSPACE to swap variants.";
|
||||
else if (result->type == KITEM_SUPERRING && cv_kartrings.value == 0)
|
||||
item->tooltip = "Rings must be enabled in Gameplay Mods!";
|
||||
}
|
||||
}
|
||||
|
||||
while (menudef->numitems % height != 0)
|
||||
{
|
||||
menudef->menuitems = Z_Realloc(menudef->menuitems, sizeof(menuitem_t)*(menudef->numitems+1), PU_STATIC, NULL);
|
||||
menuitem_t *item = menudef->menuitems + menudef->numitems++;
|
||||
|
||||
item->argument = 2;
|
||||
item->patch = "";
|
||||
}
|
||||
|
||||
menudef->x = 136 - FixedMul(max(0, min((menudef->numitems - 1) / height, 7)), TICRATE*FRACUNIT/2);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MD_DrawMonitorToggles(void)
|
||||
{
|
||||
const INT32 edges = 4;
|
||||
|
|
@ -8327,8 +8377,18 @@ 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;
|
||||
const char *displayname;
|
||||
|
||||
// INCREDIBLY goofy hack, but I don't wanna have to pass a "use cvar or altenabled"
|
||||
// flag to literally ALL of the item functions just for the sake of the menu
|
||||
boolean oldalt[MAXKARTITEMS];
|
||||
for (i = 0; i < numkartitems; i++)
|
||||
{
|
||||
kartitem_t *item = &kartitems[i];
|
||||
oldalt[i] = item->altenabled;
|
||||
item->altenabled = item->altcvar != NULL && item->altcvar->value == 1;
|
||||
}
|
||||
|
||||
M_DrawMenuTitle();
|
||||
|
||||
|
|
@ -8353,7 +8413,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,74 +8424,56 @@ void MD_DrawMonitorToggles(void)
|
|||
{
|
||||
onx = x;
|
||||
ony = y;
|
||||
y += spacing;
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef ITEMTOGGLEBOTTOMRIGHT
|
||||
if (currentMenu->menuitems[thisitem].argument == 255)
|
||||
switch (currentMenu->menuitems[thisitem].argument)
|
||||
{
|
||||
case 2:
|
||||
V_DrawScaledPatch(x, y, V_TRANSLUCENT, W_CachePatchName("K_ISBG", PU_CACHE));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (currentMenu->menuitems[thisitem].argument == 0)
|
||||
{
|
||||
case 1:
|
||||
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);
|
||||
const kartresult_t *result = K_GetKartResult(currentMenu->menuitems[thisitem].patch);
|
||||
const kartitem_t *item = &kartitems[result->type];
|
||||
boolean enabled = result->cvar->value == 1;
|
||||
|
||||
switch (currentMenu->menuitems[thisitem].argument)
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (result->type == KITEM_SUPERRING && cv_kartrings.value == 0)
|
||||
enabled = false;
|
||||
|
||||
if (cv->value)
|
||||
translucent = enabled ? 0 : V_TRANSLUCENT;
|
||||
|
||||
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 (result->amount >= K_GetItemNumberDisplayMin(result->type, true))
|
||||
{
|
||||
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_DrawString(x+24, y+31, V_ALLOWLOWERCASE|translucent, va("x%d", drawnum));
|
||||
V_DrawScaledPatch(x, y, translucent, K_GetCachedItemPatch(result->type, true, result->amount));
|
||||
V_DrawString(x+24, y+31, V_ALLOWLOWERCASE|translucent, va("x%d", result->amount));
|
||||
}
|
||||
else
|
||||
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));
|
||||
|
||||
y += spacing;
|
||||
if (item->altenabled)
|
||||
V_DrawScaledPatch(x, y, 0, W_CachePatchName("K_ALTITS", PU_CACHE));
|
||||
}
|
||||
|
||||
x += spacing;
|
||||
y = currentMenu->y+(spacing/4);
|
||||
}
|
||||
|
||||
switch (currentMenu->menuitems[itemOn].argument)
|
||||
{
|
||||
#ifdef ITEMTOGGLEBOTTOMRIGHT
|
||||
if (currentMenu->menuitems[itemOn].argument == 255)
|
||||
case 2:
|
||||
{
|
||||
displayname = "---";
|
||||
V_DrawScaledPatch(onx-1, ony-2, V_TRANSLUCENT, W_CachePatchName("K_ITBG", PU_CACHE));
|
||||
if (shitsfree)
|
||||
{
|
||||
|
|
@ -8442,58 +8484,69 @@ void MD_DrawMonitorToggles(void)
|
|||
trans = (10-shitsfree)<<V_ALPHASHIFT;
|
||||
V_DrawScaledPatch(onx-1, ony-2, trans, W_CachePatchName("K_ITFREE", PU_CACHE));
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (currentMenu->menuitems[itemOn].argument == 0)
|
||||
case 1:
|
||||
{
|
||||
displayname = "Toggle All";
|
||||
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));
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
{
|
||||
cv = KartItemCVars[currentMenu->menuitems[itemOn].argument-1];
|
||||
translucent = (cv->value ? 0 : V_TRANSLUCENT);
|
||||
const kartresult_t *result = K_GetKartResult(currentMenu->menuitems[itemOn].patch);
|
||||
const kartitem_t *item = &kartitems[result->type];
|
||||
boolean enabled = result->cvar->value == 1;
|
||||
|
||||
switch (currentMenu->menuitems[itemOn].argument)
|
||||
{
|
||||
case KRITEM_TENFOLDBANANA:
|
||||
drawnum = 10;
|
||||
break;
|
||||
default:
|
||||
drawnum = 0;
|
||||
break;
|
||||
}
|
||||
if (result->type == KITEM_SUPERRING && cv_kartrings.value == 0)
|
||||
enabled = false;
|
||||
|
||||
if (cv->value)
|
||||
displayname = result->displayname;
|
||||
translucent = enabled ? 0 : V_TRANSLUCENT;
|
||||
|
||||
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 (result->amount >= K_GetItemNumberDisplayMin(result->type, false))
|
||||
{
|
||||
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));
|
||||
V_DrawKartString(onx+37, ony+34, translucent, va("%d", result->amount));
|
||||
}
|
||||
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->altenabled ? 0 : V_TRANSLUCENT;
|
||||
V_DrawScaledPatch(onx-1, ony-2, translucent, W_CachePatchName("K_ALTITM", PU_CACHE));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (shitsfree)
|
||||
if (renderisnewtic && shitsfree)
|
||||
shitsfree--;
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y, MENUCAPS|highlightflags, va("* %s *", currentMenu->menuitems[itemOn].text));
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y, MENUCAPS|highlightflags, va("* %s *", displayname));
|
||||
|
||||
M_DrawMenuTooltips();
|
||||
|
||||
for (i = 0; i < numkartitems; i++)
|
||||
kartitems[i].altenabled = oldalt[i];
|
||||
}
|
||||
|
||||
INT32 MR_HandleMonitorToggles(INT32 choice)
|
||||
{
|
||||
const INT32 width = 6, height = 4;
|
||||
const INT32 height = 4;
|
||||
const INT32 width = currentMenu->numitems/height;
|
||||
INT32 column = itemOn/height, row = itemOn%height;
|
||||
INT16 next;
|
||||
UINT8 i;
|
||||
kartresult_t *result = K_GetKartResult(currentMenu->menuitems[itemOn].patch);
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
|
|
@ -8542,8 +8595,7 @@ INT32 MR_HandleMonitorToggles(INT32 choice)
|
|||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
#ifdef ITEMTOGGLEBOTTOMRIGHT
|
||||
if (currentMenu->menuitems[itemOn].argument == 255)
|
||||
if (currentMenu->menuitems[itemOn].argument == 2)
|
||||
{
|
||||
//S_StartSound(NULL, sfx_s26d);
|
||||
if (!shitsfree)
|
||||
|
|
@ -8552,29 +8604,41 @@ INT32 MR_HandleMonitorToggles(INT32 choice)
|
|||
S_StartSound(NULL, sfx_itfree);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (currentMenu->menuitems[itemOn].argument == 0)
|
||||
else if (currentMenu->menuitems[itemOn].argument == 1)
|
||||
{
|
||||
INT32 v = cv_sneaker.value;
|
||||
INT32 v = K_ItemResultEnabled(K_GetKartResult("sneaker")) ? 1 : 0;
|
||||
S_StartSound(NULL, sfx_s1b4);
|
||||
for (i = 0; i < NUMKARTRESULTS-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);
|
||||
if (result->type == KITEM_SUPERRING && cv_kartrings.value == 0)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s231);
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound(NULL, sfx_s1ba);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -323,6 +323,7 @@ INT32 MR_HandleMusicTest(INT32 choice);
|
|||
INT32 MR_ResetControls(INT32 choice);
|
||||
INT32 MR_ChangeControl(INT32 arg);
|
||||
INT32 MR_AssignJoystick(INT32 arg);
|
||||
INT32 MR_SetupMonitorToggles(INT32 choice);
|
||||
INT32 MR_HandleMonitorToggles(INT32 choice);
|
||||
INT32 MR_RestartAudio(INT32 choice);
|
||||
INT32 MR_EnterViewServer(INT32 choice);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -10838,7 +10839,7 @@ void A_ItemPop(void *thing)
|
|||
|
||||
if (!((gametyperules & GTR_BUMPERS) && actor->target->player->bumper <= 0) && !itembreaker)
|
||||
{
|
||||
actor->target->player->itemroulette = KROULETTE_ACTIVE;
|
||||
K_StartRoulette(actor->target->player, KROULETTETYPE_NORMAL);
|
||||
}
|
||||
else if (itembreaker)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -147,7 +147,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
|
|||
if (player->stealingtimer || player->stolentimer
|
||||
|| player->rocketsneakertimer
|
||||
|| player->eggmanexplode
|
||||
|| ((K_GetKartInvinType() == KARTINVIN_ALTERN) && (player->invincibilitytimer))
|
||||
|| ((K_IsKartItemAlternate(KITEM_INVINCIBILITY)) && (player->invincibilitytimer))
|
||||
|| (player->growshrinktimer > 0)
|
||||
|| player->flametimer)
|
||||
return false;
|
||||
|
|
@ -459,8 +459,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|
||||
special->target->player->karmadelay = comebacktime;
|
||||
|
||||
player->itemroulette = KROULETTE_ACTIVE;
|
||||
player->roulettetype = KROULETTETYPE_KARMA;
|
||||
K_StartRoulette(player, KROULETTETYPE_KARMA);
|
||||
}
|
||||
else if (special->target->player->karmamode == 2 && P_CanPickupItem(player, 2))
|
||||
{
|
||||
|
|
@ -495,11 +494,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|
||||
special->target->player->karmadelay = comebacktime;
|
||||
|
||||
K_DropItems(player); //K_StripItems(player);
|
||||
//K_StripOther(player);
|
||||
|
||||
player->itemroulette = KROULETTE_ACTIVE;
|
||||
player->roulettetype = KROULETTETYPE_EGGMAN;
|
||||
K_StartRoulette(player, KROULETTETYPE_EGGMAN);
|
||||
|
||||
if (special->target->player->eggmanblame >= 0
|
||||
&& special->target->player->eggmanblame < MAXPLAYERS
|
||||
|
|
@ -591,8 +586,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->bumper <= 0))
|
||||
return;
|
||||
|
||||
player->itemroulette = KROULETTE_ACTIVE;
|
||||
player->roulettetype = KROULETTETYPE_KARMA;
|
||||
K_StartRoulette(player, KROULETTETYPE_KARMA);
|
||||
|
||||
// Karma fireworks
|
||||
for (i = 0; i < 5; i++)
|
||||
|
|
@ -1742,25 +1736,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
|
||||
{
|
||||
player->itemtype = KITEM_SAD;
|
||||
player->itemamount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->itemtype = target->threshold;
|
||||
if (K_GetShieldFromPlayer(player) != KSHIELD_NONE) // never give more than 1 shield
|
||||
player->itemamount = 1;
|
||||
else
|
||||
player->itemamount = max(1, target->movecount);
|
||||
}
|
||||
player->itemblink = TICRATE;
|
||||
player->itemblinkmode = KITEMBLINKMODE_NORMAL;
|
||||
player->itemroulette = KROULETTE_DISABLED;
|
||||
player->roulettetype = KROULETTETYPE_NORMAL;
|
||||
if (P_IsDisplayPlayer(player))
|
||||
S_StartSound(NULL, sfx_itrolf);
|
||||
K_AwardPlayerItem(player, target->threshold, max(1, target->movecount), KITEMBLINK_NORMAL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
267
src/p_mobj.c
267
src/p_mobj.c
|
|
@ -15,6 +15,7 @@
|
|||
#include "d_netcmd.h"
|
||||
#include "d_think.h"
|
||||
#include "dehacked.h"
|
||||
#include "deh_tables.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "doomtype.h"
|
||||
|
|
@ -51,7 +52,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
|
||||
|
|
@ -1228,6 +1229,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
case MT_EGGMANITEM:
|
||||
case MT_SSMINE:
|
||||
case MT_LANDMINE:
|
||||
// case MT_EGGMINE_CAPSULE:
|
||||
case MT_SINK:
|
||||
if (mo->extravalue2 > 0)
|
||||
{
|
||||
|
|
@ -4164,8 +4166,8 @@ static void P_RefreshItemCapsuleParts(mobj_t *mobj)
|
|||
mobj_t *part;
|
||||
UINT32 newRenderFlags = 0;
|
||||
|
||||
if (itemType < 1 || itemType >= NUMKARTITEMS)
|
||||
itemType = KITEM_SAD;
|
||||
if (itemType < 1 || itemType >= numkartitems)
|
||||
itemType = MAXKARTITEMS;
|
||||
|
||||
part = mobj;
|
||||
while (!P_MobjWasRemoved(part->hnext))
|
||||
|
|
@ -4185,40 +4187,8 @@ static void P_RefreshItemCapsuleParts(mobj_t *mobj)
|
|||
K_UpdateMobjItemOverlay(part, itemType, mobj->movecount);
|
||||
|
||||
// update number frame
|
||||
if (K_GetShieldFromItem(itemType) != KSHIELD_NONE) // shields don't stack, so don't show a number
|
||||
;
|
||||
else
|
||||
{
|
||||
switch (itemType)
|
||||
{
|
||||
case KITEM_SNEAKER:
|
||||
if (mobj->movecount - 1 > K_GetMultItemFrame(mobj->movecount, 2))
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
case KITEM_ORBINAUT: // only display the number when the sprite no longer changes
|
||||
if (mobj->movecount - 1 > K_GetMultItemFrame(mobj->movecount, 3))
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
case KITEM_BANANA: // only display the number when the sprite no longer changes
|
||||
if (mobj->movecount - 1 > K_GetMultItemFrame(mobj->movecount, 3))
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
case KITEM_JAWZ: // only display the number when the sprite no longer changes
|
||||
if (mobj->movecount - 1 > K_GetMultItemFrame(mobj->movecount, 1))
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
case KITEM_SUPERRING: // always display the number, and multiply it by 5
|
||||
count = mobj->movecount * 5;
|
||||
break;
|
||||
case KITEM_SAD: // never display the number
|
||||
case KITEM_SPB:
|
||||
break;
|
||||
default:
|
||||
if (mobj->movecount > 1)
|
||||
count = mobj->movecount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mobj->movecount >= K_GetItemNumberDisplayMin(itemType, false))
|
||||
count = mobj->movecount;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
|
|
@ -6192,6 +6162,9 @@ void P_SetScale2(mobj_t *mobj, fixed_t newscale, boolean compat)
|
|||
|
||||
oldscale = mobj->scale; //keep for adjusting stuff below
|
||||
|
||||
if (LUA_HookMobjScaleChange(mobj, newscale, oldscale) || P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
|
||||
mobj->scale = newscale;
|
||||
|
||||
if (compat)
|
||||
|
|
@ -6513,6 +6486,7 @@ boolean P_IsKartFieldItem(INT32 type)
|
|||
case MT_JAWZ_DUD:
|
||||
case MT_SSMINE:
|
||||
case MT_LANDMINE:
|
||||
// case MT_EGGMINE_CAPSULE:
|
||||
case MT_BALLHOG:
|
||||
case MT_BUBBLESHIELDTRAP:
|
||||
case MT_SINK:
|
||||
|
|
@ -7408,6 +7382,19 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
break;
|
||||
case MT_BUBBLESHIELD_DEBRIS:
|
||||
mobj->rollangle += ANG1 * 4;
|
||||
|
||||
if (P_IsObjectOnGround(mobj) && mobj->health > 0)
|
||||
{
|
||||
// "Despawn" and play the glass landing sound.
|
||||
if (mobj->extravalue1 == 0)
|
||||
S_StartSoundAtVolume(mobj, mobj->info->deathsound, 192);
|
||||
P_KillMobj(mobj, NULL, NULL, DMG_NORMAL);
|
||||
mobj->fuse = TICRATE;
|
||||
}
|
||||
|
||||
goto dofuse;
|
||||
case MT_SMOLDERING:
|
||||
if (leveltime % 2 == 0)
|
||||
{
|
||||
|
|
@ -7607,101 +7594,79 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
|
||||
if (!(mobj->renderflags & RF_DONTDRAW))
|
||||
{
|
||||
const INT32 numberdisplaymin = ((mobj->target->player->itemtype == KITEM_ORBINAUT) ? 5 : 2);
|
||||
statenum_t statenum = S_PLAYERARROW_BOX;
|
||||
kartitemtype_e itemtype = mobj->target->player->itemtype;
|
||||
UINT8 itemamount = 0;
|
||||
boolean hide = false;
|
||||
|
||||
// Set it to use the correct states for its condition
|
||||
if (mobj->target->player->itemroulette)
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = K_GetRollingRouletteItem(mobj->target->player) | FF_FULLBRIGHT;
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
itemtype = K_GetRollingRouletteItem(mobj->target->player);
|
||||
}
|
||||
else if (mobj->target->player->stealingtimer < 0)
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO;
|
||||
if (leveltime & 2)
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
itemtype = KITEM_HYUDORO;
|
||||
hide = leveltime & 2;
|
||||
}
|
||||
else if ((mobj->target->player->stealingtimer > 0) && (leveltime & 2))
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO;
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
itemtype = KITEM_HYUDORO;
|
||||
}
|
||||
else if (mobj->target->player->eggmanexplode > 1)
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_EGGMAN;
|
||||
if (leveltime & 1)
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
itemtype = KITEM_EGGMAN;
|
||||
hide = leveltime & 1;
|
||||
}
|
||||
else if (mobj->target->player->rocketsneakertimer > 1)
|
||||
{
|
||||
//itembar = mobj->target->player->rocketsneakertimer; -- not today satan
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_ROCKETSNEAKER;
|
||||
if (leveltime & 1)
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
itemtype = KITEM_ROCKETSNEAKER;
|
||||
hide = leveltime & 1;
|
||||
}
|
||||
else if (mobj->target->player->flametimer > 1)
|
||||
{
|
||||
//itembar = mobj->target->player->flametimer; -- not today satan
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_FLAMESHIELD;
|
||||
if (leveltime & 1)
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
itemtype = KITEM_FLAMESHIELD;
|
||||
hide = leveltime & 1;
|
||||
}
|
||||
else if (mobj->target->player->growshrinktimer > 0)
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_GROW;
|
||||
|
||||
if (leveltime & 1)
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
itemtype = KITEM_GROW;
|
||||
hide = leveltime & 1;
|
||||
}
|
||||
else if (mobj->target->player->itemtype && mobj->target->player->itemamount > 0)
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
itemtype = mobj->target->player->itemtype;
|
||||
itemamount = mobj->target->player->itemamount;
|
||||
hide = mobj->target->player->itemflags & IF_ITEMOUT && leveltime & 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
statenum = S_PLAYERARROW;
|
||||
}
|
||||
|
||||
K_UpdateMobjItemOverlay(mobj->tracer, mobj->target->player->itemtype,mobj->target->player->itemamount);
|
||||
|
||||
if (mobj->target->player->itemflags & IF_ITEMOUT)
|
||||
{
|
||||
if (leveltime & 1)
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
P_SetMobjState(mobj, statenum);
|
||||
if (statenum == S_PLAYERARROW_BOX)
|
||||
{
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
K_UpdateMobjItemOverlay(mobj->tracer, itemtype, itemamount);
|
||||
mobj->tracer->threshold = itemtype; // sorry, i have to
|
||||
mobj->tracer->frame &= ~FF_PAPERSPRITE;
|
||||
if (hide)
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
else
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW);
|
||||
P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM);
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
|
||||
mobj->tracer->destscale = scale;
|
||||
|
||||
if (mobj->target->player->itemamount >= numberdisplaymin
|
||||
if (mobj->target->player->itemamount >= K_GetItemNumberDisplayMin(mobj->target->player->itemtype, false)
|
||||
&& mobj->target->player->itemamount <= 10) // Meh, too difficult to support greater than this; convert this to a decent HUD object and then maybe :V
|
||||
{
|
||||
mobj_t *number = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY);
|
||||
|
|
@ -7717,6 +7682,10 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
P_SetMobjState(numx, S_PLAYERARROW_X);
|
||||
P_SetScale(numx, mobj->scale);
|
||||
numx->destscale = scale;
|
||||
|
||||
// ugh... overlays....
|
||||
number->old_z = number->z += FixedMul(number->state->var2 * FRACUNIT, mobj->scale);
|
||||
numx->old_z = numx->z += FixedMul(number->state->var2 * FRACUNIT, mobj->scale);
|
||||
}
|
||||
|
||||
if (K_IsPlayerWanted(mobj->target->player) && mobj->movecount != 1)
|
||||
|
|
@ -7847,6 +7816,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
}
|
||||
/* FALLTHRU */
|
||||
default:
|
||||
dofuse:
|
||||
if (mobj->fuse)
|
||||
{ // Scenery object fuse! Very basic!
|
||||
mobj->fuse--;
|
||||
|
|
@ -8013,6 +7983,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
|
|||
case MT_BANANA:
|
||||
case MT_EGGMANITEM:
|
||||
case MT_LANDMINE:
|
||||
// case MT_EGGMINE_CAPSULE:
|
||||
case MT_SPB:
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
|
|
@ -8440,11 +8411,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
}
|
||||
}
|
||||
|
||||
if (mobj->threshold == KITEM_SPB || mobj->threshold == KITEM_SHRINK)
|
||||
{
|
||||
indirectitemcooldown = 20*TICRATE;
|
||||
}
|
||||
|
||||
K_UpdateMobjItemOverlay(mobj, mobj->threshold, mobj->movecount);
|
||||
break;
|
||||
}
|
||||
|
|
@ -8480,12 +8446,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
|| mobj->movecount != part->movecount) // change the capsule properties if the item type or amount is updated
|
||||
P_RefreshItemCapsuleParts(mobj);
|
||||
|
||||
// animate invincibility capsules
|
||||
K_UpdateMobjItemOverlay(part, mobj->threshold, mobj->movecount);
|
||||
|
||||
if (mobj->threshold == KITEM_INVINCIBILITY)
|
||||
{
|
||||
mobj->color = K_RainbowColor(leveltime);
|
||||
part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetInvincibilityItemFrame();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MT_ORBINAUT:
|
||||
|
|
@ -8715,8 +8679,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->threshold--;
|
||||
break;
|
||||
case MT_SPB:
|
||||
indirectitemcooldown = 20*TICRATE;
|
||||
/* FALLTHRU */
|
||||
case MT_BALLHOG:
|
||||
{
|
||||
mobj_t *ghost = P_SpawnGhostMobj(mobj);
|
||||
|
|
@ -8805,6 +8767,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
if (mobj->threshold > 0)
|
||||
mobj->threshold--;
|
||||
break;
|
||||
// case MT_EGGMINE_CAPSULE:
|
||||
// todo
|
||||
// decrement fuse while on ground
|
||||
// when fuse runs out pop open and spawn a land mine
|
||||
break;
|
||||
case MT_SPBEXPLOSION:
|
||||
mobj->health--;
|
||||
break;
|
||||
|
|
@ -9218,18 +9185,17 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
angle_t a = mobj->angle + ((i & 1) ? ANGLE_180 : 0);
|
||||
fixed_t ws = player->mo->scale/4 + scale/4;
|
||||
mobj_t *wave;
|
||||
|
||||
wave = P_SpawnMobj(
|
||||
(player->mo->x - player->mo->momx) + P_ReturnThrustX(NULL, a, mobj->radius - (21*ws)),
|
||||
(player->mo->y - player->mo->momy) + P_ReturnThrustY(NULL, a, mobj->radius - (21*ws)),
|
||||
(player->mo->x - player->mo->momx) + P_ReturnThrustX(NULL, a, mobj->radius - (5*scale)),
|
||||
(player->mo->y - player->mo->momy) + P_ReturnThrustY(NULL, a, mobj->radius - (5*scale)),
|
||||
(player->mo->z - player->mo->momz), MT_THOK);
|
||||
|
||||
wave->colorized = true;
|
||||
wave->color = SKINCOLOR_BLUE;
|
||||
wave->flags &= ~(MF_NOCLIPHEIGHT|MF_NOGRAVITY);
|
||||
P_SetScale(wave, (wave->destscale = ws));
|
||||
P_SetScale(wave, (wave->destscale = scale/3));
|
||||
|
||||
P_SetMobjState(wave, S_SPLISH1);
|
||||
|
||||
|
|
@ -9300,45 +9266,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->flags |= MF_NOCLIP|MF_NOCLIPTHING;
|
||||
break;
|
||||
}
|
||||
case MT_BUBBLESHLD_DEBRIS:
|
||||
{
|
||||
statenum_t curstate;
|
||||
curstate = ((mobj->tics == 1) ? (mobj->state->nextstate) : ((statenum_t)(mobj->state-states)));
|
||||
|
||||
if (curstate != S_INVISIBLE)
|
||||
{
|
||||
mobj->rollangle += ANG1 * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->rollangle = 0;
|
||||
}
|
||||
|
||||
if ((P_IsObjectOnGround(mobj)) && (!mobj->threshold))
|
||||
{
|
||||
mobj->threshold = (TICRATE / 2);
|
||||
|
||||
if (curstate != S_INVISIBLE)
|
||||
{
|
||||
// "Despawn" and play the glass landing sound.
|
||||
if (mobj->extravalue1 == 0)
|
||||
S_StartSoundAtVolume(mobj, mobj->info->activesound, 128);
|
||||
P_SetMobjState(mobj, S_INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (mobj->threshold)
|
||||
{
|
||||
mobj->threshold--;
|
||||
|
||||
if (!mobj->threshold)
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MT_FLAMESHIELD:
|
||||
{
|
||||
statenum_t curstate;
|
||||
|
|
@ -10926,6 +10853,8 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
|||
case MT_SSMINE:
|
||||
case MT_SSMINE_SHIELD:
|
||||
case MT_LANDMINE:
|
||||
// case MT_EGGMINE_CAPSULE:
|
||||
// case MT_EGGMINE_SHIELD:
|
||||
case MT_BALLHOG:
|
||||
case MT_SINK:
|
||||
case MT_ROCKETSNEAKER:
|
||||
|
|
@ -11352,7 +11281,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
P_SetTarget(&spawn->target, mobj);
|
||||
break;
|
||||
}
|
||||
case MT_BUBBLESHLD_DEBRIS:
|
||||
case MT_BUBBLESHIELD_DEBRIS:
|
||||
{
|
||||
statenum_t shardset[] = {S_BUBBLEDEBRIS_1, S_BUBBLEDEBRIS_2, S_BUBBLEDEBRIS_3, S_BUBBLEDEBRIS_4, S_BUBBLEDEBRIS_5};
|
||||
P_SetMobjState(mobj, shardset[P_RandomRange(0, 4)]);
|
||||
|
|
@ -11370,7 +11299,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
|
||||
|
|
@ -12787,7 +12716,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))
|
||||
|
|
@ -13645,9 +13574,39 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
if (!P_IsObjectOnGround(mobj))
|
||||
mobj->flags |= MF_NOGRAVITY;
|
||||
|
||||
// Angle = item type
|
||||
if (mthing->args[0] > 0 && mthing->args[0] < NUMKARTITEMS)
|
||||
mobj->threshold = mthing->args[0];
|
||||
// Item type
|
||||
static kartitemtype_e rrtypes[] = {
|
||||
KITEM_SNEAKER,
|
||||
KITEM_ROCKETSNEAKER,
|
||||
KITEM_INVINCIBILITY,
|
||||
KITEM_BANANA,
|
||||
KITEM_EGGMAN,
|
||||
KITEM_ORBINAUT,
|
||||
KITEM_JAWZ,
|
||||
KITEM_MINE,
|
||||
MAXKARTITEMS, // LANDMINE
|
||||
KITEM_BALLHOG,
|
||||
KITEM_SPB,
|
||||
KITEM_GROW,
|
||||
KITEM_SHRINK,
|
||||
KITEM_THUNDERSHIELD,
|
||||
KITEM_BUBBLESHIELD,
|
||||
KITEM_FLAMESHIELD,
|
||||
KITEM_HYUDORO,
|
||||
KITEM_POGOSPRING,
|
||||
KITEM_SUPERRING,
|
||||
KITEM_KITCHENSINK,
|
||||
MAXKARTITEMS, // DROPTARGET
|
||||
MAXKARTITEMS, // GARDENTOP
|
||||
MAXKARTITEMS, // GACHABOM
|
||||
MAXKARTITEMS, // STONESHOE
|
||||
MAXKARTITEMS, // TOXOMISTER
|
||||
};
|
||||
|
||||
if (mthing->stringargs[0] != NULL)
|
||||
mobj->threshold = DEH_FindKartItem(mthing->stringargs[0]);
|
||||
else if (mapnamespace == MNS_RINGRACERS && mthing->args[0] > 0 && (size_t)mthing->args[0] < sizeof(rrtypes)/sizeof(*rrtypes))
|
||||
mobj->threshold = rrtypes[mthing->args[0] - 1];
|
||||
|
||||
// Parameter = extra items (x5 for rings)
|
||||
mobj->movecount += mthing->args[1];
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
#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"
|
||||
|
|
@ -776,6 +776,9 @@ static void P_NetSyncPlayers(savebuffer_t *save)
|
|||
// Wall Transfer bonus
|
||||
SYNCBOOLEAN(players[i].walltransfered);
|
||||
SYNC(players[i].walltransferboost);
|
||||
|
||||
SYNC(players[i].itemusecooldown);
|
||||
SYNC(players[i].itemusecooldownmax);
|
||||
}
|
||||
TracyCZoneEnd(__zone);
|
||||
}
|
||||
|
|
@ -3939,6 +3942,10 @@ static boolean P_NetSyncMisc(savebuffer_t *save, boolean resending)
|
|||
|
||||
SYNC(gametype);
|
||||
|
||||
#if MAXPLAYERS > 32
|
||||
#error Update playeringame syncing please
|
||||
#endif
|
||||
|
||||
if (save->write)
|
||||
{
|
||||
UINT32 pig = 0;
|
||||
|
|
@ -4182,7 +4189,6 @@ static boolean P_NetSyncMisc(savebuffer_t *save, boolean resending)
|
|||
SYNCBOOLEAN(itemlittering);
|
||||
SYNCBOOLEAN(itempushing);
|
||||
SYNC(bumpsparkactive);
|
||||
SYNC(invintype);
|
||||
SYNC(antibumptime);
|
||||
|
||||
for (i = 0; i < sizeof(votelevels)/sizeof(*votelevels); i++)
|
||||
|
|
@ -4267,14 +4273,12 @@ static boolean P_NetSyncMisc(savebuffer_t *save, boolean resending)
|
|||
SYNC(battlewanted[i]);
|
||||
|
||||
SYNC(wantedcalcdelay);
|
||||
SYNC(indirectitemcooldown);
|
||||
|
||||
for (i = 0; i < NUMKARTRESULTS; i++)
|
||||
{
|
||||
// hyubgone
|
||||
//SYNC(ItemBGone[i][GONER_BASECOOLDOWN]);
|
||||
SYNC(ItemBGone[i][GONER_CURRCOOLDOWN]);
|
||||
}
|
||||
for (i = 0; i < numkartitems; i++)
|
||||
SYNC(kartitems[i].altenabled);
|
||||
|
||||
for (i = 0; i < numkartresults; i++)
|
||||
SYNC(kartresults[i].cooldown);
|
||||
|
||||
SYNC(mapreset);
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@
|
|||
#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"
|
||||
|
|
@ -8071,7 +8071,6 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
|
|||
itempushing = true;
|
||||
|
||||
bumpsparkactive = (UINT8)cv_kartbumpspark.value;
|
||||
invintype = (UINT8)cv_kartinvintype.value;
|
||||
|
||||
antibumptime = (tic_t)cv_kartantibump.value * TICRATE;
|
||||
|
||||
|
|
@ -8398,13 +8397,8 @@ static void P_InitGametype(void)
|
|||
numlaps = K_RaceLapCount(gamemap - 1);
|
||||
|
||||
wantedcalcdelay = wantedfrequency*2;
|
||||
indirectitemcooldown = 0;
|
||||
|
||||
for (i = 0; i < NUMKARTRESULTS; i++)
|
||||
{
|
||||
// hyubgone
|
||||
ItemBGone[i][GONER_CURRCOOLDOWN] = 0;
|
||||
}
|
||||
K_SetupItemOdds();
|
||||
|
||||
mapreset = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
// SRB2kart
|
||||
#include "k_kart.h"
|
||||
#include "k_items.h"
|
||||
#include "console.h" // CON_LogMessage
|
||||
#include "k_terrain.h"
|
||||
#include "acs/interface.h"
|
||||
|
|
@ -9222,7 +9223,8 @@ boolean P_AllowFriction(mobj_t *mobj)
|
|||
if (mobj->player->invincibilitytimer
|
||||
|| mobj->player->hyudorotimer
|
||||
|| mobj->player->sneakertimer
|
||||
|| mobj->player->growshrinktimer > 0)
|
||||
|| mobj->player->growshrinktimer > 0
|
||||
|| K_IsAltShrunk(mobj->player))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
22
src/p_tick.c
22
src/p_tick.c
|
|
@ -42,7 +42,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
|
||||
|
|
@ -897,25 +897,7 @@ void P_Ticker(boolean run)
|
|||
if (exitcountdown > 1)
|
||||
exitcountdown--;
|
||||
|
||||
if (indirectitemcooldown > 0)
|
||||
indirectitemcooldown--;
|
||||
|
||||
for (i = 0; i < NUMKARTRESULTS; i++)
|
||||
{
|
||||
// hyubgone
|
||||
if (K_GetBGone(i, false) > 0)
|
||||
{
|
||||
ItemBGone[i][GONER_CURRCOOLDOWN]--;
|
||||
}
|
||||
}
|
||||
|
||||
if (gametyperules & GTR_RACEODDS)
|
||||
{
|
||||
// Shield cooldowns
|
||||
K_KartHandleShieldCooldown(KITEM_THUNDERSHIELD);
|
||||
K_KartHandleShieldCooldown(KITEM_BUBBLESHIELD);
|
||||
K_KartHandleShieldCooldown(KITEM_FLAMESHIELD);
|
||||
}
|
||||
K_UpdateItemCooldown();
|
||||
|
||||
K_BossInfoTicker();
|
||||
|
||||
|
|
|
|||
18
src/p_user.c
18
src/p_user.c
|
|
@ -61,7 +61,7 @@
|
|||
#include "k_terrain.h" // K_SpawnSplashForMobj
|
||||
#include "k_color.h"
|
||||
#include "k_follower.h"
|
||||
#include "k_odds.h"
|
||||
#include "k_items.h"
|
||||
#include "g_party.h"
|
||||
|
||||
#include "acs/interface.h"
|
||||
|
|
@ -831,6 +831,9 @@ void P_RestoreMusic(player_t *player)
|
|||
{ wantedmus = 1; bestlocaltimer = players[p].growshrinktimer; } \
|
||||
else if (players[p].invincibilitytimer > bestlocaltimer) \
|
||||
{ wantedmus = 2; bestlocaltimer = players[p].invincibilitytimer; } \
|
||||
else if ((K_IsKartItemAlternate(KITEM_SHRINK)) && \
|
||||
(K_GetShrinkTime(&players[p]) > bestlocaltimer)) \
|
||||
{ wantedmus = 3; bestlocaltimer = K_GetShrinkTime(&players[p]); } \
|
||||
}
|
||||
setbests(localplayertable[0]);
|
||||
setbests(localplayertable[1]);
|
||||
|
|
@ -848,6 +851,9 @@ void P_RestoreMusic(player_t *player)
|
|||
wantedmus = 1;
|
||||
else if (player->invincibilitytimer > 1)
|
||||
wantedmus = 2;
|
||||
else if ((K_IsKartItemAlternate(KITEM_SHRINK)) &&
|
||||
(K_GetShrinkTime(player) > 1))
|
||||
wantedmus = 3;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -864,6 +870,12 @@ void P_RestoreMusic(player_t *player)
|
|||
S_ChangeMusicInternal("kinvnc", true);
|
||||
S_SetRestoreMusicFadeInCvar(&cv_invincmusicfade);
|
||||
}
|
||||
// Item - Shrink (Alternative)
|
||||
else if ((wantedmus == 3) && cv_altshrinkmusic.value == 1)
|
||||
{
|
||||
S_ChangeMusicInternal("kshrnk", true);
|
||||
S_SetRestoreMusicFadeInCvar(&cv_altshrinkmusicfade);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
|
|
@ -2286,7 +2298,7 @@ void P_MovePlayer(player_t *player)
|
|||
if ((player->invincibilitytimer > 0) &&
|
||||
(((leveltime %
|
||||
max(1, 10 - FixedMul(9, K_InvincibilityGradient(player->invincibilitytimer)))) == 0) ||
|
||||
(K_GetKartInvinType() == KARTINVIN_LEGACY)))
|
||||
(!K_IsKartItemAlternate(KITEM_INVINCIBILITY))))
|
||||
{
|
||||
K_SpawnSparkleTrail(player->mo);
|
||||
}
|
||||
|
|
@ -2483,7 +2495,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
|
|||
if (mo->type == MT_SPB) // If you destroy a SPB, you don't get the luxury of a cooldown.
|
||||
{
|
||||
spbplace = -1;
|
||||
indirectitemcooldown = 0;
|
||||
K_SetIndirectItemCooldown(0);
|
||||
}
|
||||
|
||||
if (mo->flags & MF_BOSS) //don't OHKO bosses nor players!
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ static CV_PossibleValue_t fov_cons_t[] = {{60*FRACUNIT, "MIN"}, {179*FRACUNIT, "
|
|||
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card
|
||||
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
|
||||
static CV_PossibleValue_t secbright_cons_t[] = {{0, "MIN"}, {255, "MAX"}, {0, NULL}};
|
||||
|
||||
static void Fov_OnChange(void);
|
||||
|
||||
|
|
@ -182,6 +183,8 @@ consvar_t cv_fov[MAXSPLITSCREENPLAYERS] = {
|
|||
// Okay, whoever said homremoval causes a performance hit should be shot.
|
||||
consvar_t cv_homremoval = CVAR_INIT ("homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL);
|
||||
|
||||
consvar_t cv_secbright = CVAR_INIT ("r_secbright", "0", CV_SAVE, secbright_cons_t, NULL);
|
||||
|
||||
consvar_t cv_maxportals = CVAR_INIT ("maxportals", "2", CV_SAVE, maxportals_cons_t, NULL);
|
||||
|
||||
consvar_t cv_renderstats = CVAR_INIT ("renderstats", "Off", 0, CV_OnOff, NULL);
|
||||
|
|
@ -1780,6 +1783,7 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_shadow);
|
||||
CV_RegisterVar(&cv_skybox);
|
||||
CV_RegisterVar(&cv_ffloorclip);
|
||||
CV_RegisterVar(&cv_secbright);
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ extern consvar_t cv_fov[MAXSPLITSCREENPLAYERS];
|
|||
extern consvar_t cv_skybox;
|
||||
extern consvar_t cv_tailspickup;
|
||||
extern consvar_t cv_debugfinishline;
|
||||
extern consvar_t cv_secbright;
|
||||
|
||||
extern consvar_t cv_sloperoll;
|
||||
extern consvar_t cv_sliptidetilt;
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
@ -84,7 +85,7 @@ static angle_t R_PlayerSpriteRotation(player_t *player, player_t *viewPlayer)
|
|||
// Hacky boolean to check if we're the rainbow Invincibility overlay
|
||||
boolean R_IsOverlayingInvinciblePlayer(mobj_t* mobj)
|
||||
{
|
||||
return ((K_GetKartInvinType() == KARTINVIN_ALTERN) && (mobj->type == MT_OVERLAY) &&
|
||||
return ((K_IsKartItemAlternate(KITEM_INVINCIBILITY)) && (mobj->type == MT_OVERLAY) &&
|
||||
(mobj->target) && (mobj->extravalue2) && (mobj->target->player) &&
|
||||
(mobj->target->player->invincibilitytimer));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1038,7 +1038,7 @@ void R_DrawSinglePlane(drawspandata_t *ds, visplane_t *pl, boolean allow_paralle
|
|||
spanfunctype = SPANDRAWFUNC_SPLAT;
|
||||
|
||||
if (pl->polyobj->translucency == 0 || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
light = std::max((pl->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
else
|
||||
light = LIGHTLEVELS-1;
|
||||
}
|
||||
|
|
@ -1079,16 +1079,17 @@ void R_DrawSinglePlane(drawspandata_t *ds, visplane_t *pl, boolean allow_paralle
|
|||
}
|
||||
|
||||
if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
light = std::max((pl->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
else
|
||||
light = LIGHTLEVELS-1;
|
||||
}
|
||||
else if (pl->ffloor->fofflags & FOF_FOG)
|
||||
{
|
||||
spanfunctype = SPANDRAWFUNC_FOG;
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
light = std::max((pl->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
}
|
||||
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
light = std::max((pl->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
|
||||
debug = SW_HI_FOFPLANES;
|
||||
}
|
||||
|
|
@ -1147,6 +1148,8 @@ void R_DrawSinglePlane(drawspandata_t *ds, visplane_t *pl, boolean allow_paralle
|
|||
vidwidth, vidwidth);
|
||||
}
|
||||
}
|
||||
else
|
||||
light = std::max((pl->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
}
|
||||
|
||||
ds->currentplane = pl;
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
|
|||
if ((R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == false)
|
||||
|| (rlight->flags & FOF_FOG)
|
||||
|| (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = std::max((rlight->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
else
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
|
||||
|
|
@ -919,9 +919,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
|
||||
// Check if the current light effects the colormap/lightlevel
|
||||
if (pfloor->fofflags & FOF_FOG)
|
||||
rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
rlight->lightnum = std::max((pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
else
|
||||
rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
rlight->lightnum = std::max((rlight->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
|
||||
if (pfloor->fofflags & FOF_FOG || rlight->flags & FOF_FOG || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
|
||||
;
|
||||
|
|
@ -937,14 +937,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
{
|
||||
// Get correct light level!
|
||||
if ((frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = std::max((frontsector->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
else if (pfloor->fofflags & FOF_FOG)
|
||||
lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = std::max((pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
else if (R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == true)
|
||||
lightnum = LIGHTLEVELS-1;
|
||||
else
|
||||
lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
|
||||
->lightlevel >> LIGHTSEGSHIFT;
|
||||
lightnum = std::max((R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
|
||||
->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
|
||||
if (pfloor->fofflags & FOF_FOG || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
;
|
||||
|
|
@ -1556,7 +1556,7 @@ static void R_RenderSegLoop (drawcolumndata_t* dc)
|
|||
for (i = 0; i < dc->numlights; i++)
|
||||
{
|
||||
INT32 lightnum;
|
||||
lightnum = (dc->lightlist[i].lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = std::max((dc->lightlist[i].lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
|
||||
if (dc->lightlist[i].extra_colormap)
|
||||
;
|
||||
|
|
@ -2665,7 +2665,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
// use different light tables
|
||||
// for horizontal / vertical / diagonal
|
||||
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = std::max((frontsector->lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
|
||||
if (P_ApplyLightOffset(lightnum, frontsector))
|
||||
lightnum += curline->lightOffset;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include "k_color.h"
|
||||
#include "k_kart.h"
|
||||
#include "r_fps.h"
|
||||
#include "k_items.h"
|
||||
|
||||
#define MINZ (FRACUNIT*16)
|
||||
#define BASEYCENTER (BASEVIDHEIGHT/2)
|
||||
|
|
@ -283,6 +284,57 @@ void R_AddKartFaces(skin_t *skin)
|
|||
}
|
||||
#undef NUMFACES
|
||||
|
||||
// dear god... what a mess...
|
||||
void R_AddKartItemSprites(kartitem_t *item)
|
||||
{
|
||||
spritedef_t *spritedef = &item->spritedef;
|
||||
memset(sprtemp, 0xff, sizeof(sprtemp));
|
||||
spritename = "ITEM";
|
||||
maxframe = spritedef->numframes - 1;
|
||||
|
||||
const kartitemgraphics_t *graphics = &item->graphics[0];
|
||||
for (UINT8 i = 0; i < graphics->numpatches; i++)
|
||||
{
|
||||
lumpnum_t lumpnum = W_CheckNumForName(graphics->patchnames[i]);
|
||||
if (lumpnum == LUMPERROR)
|
||||
I_Error("R_AddKartItemSprites: missing patch %s", graphics->patchnames[i]);
|
||||
|
||||
spritecachedinfo[numspritelumps].width = graphics->patches[i]->width<<FRACBITS;
|
||||
spritecachedinfo[numspritelumps].offset = graphics->patches[i]->leftoffset<<FRACBITS;
|
||||
spritecachedinfo[numspritelumps].topoffset = graphics->patches[i]->topoffset<<FRACBITS;
|
||||
spritecachedinfo[numspritelumps].height = graphics->patches[i]->height<<FRACBITS;
|
||||
|
||||
// center it... i think
|
||||
spritecachedinfo[numspritelumps].offset += 25*FRACUNIT;
|
||||
spritecachedinfo[numspritelumps].topoffset += 50*FRACUNIT;
|
||||
|
||||
// BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer
|
||||
spritecachedinfo[numspritelumps].topoffset += FEETADJUST;
|
||||
|
||||
R_InstallSpriteLump(WADFILENUM(lumpnum), LUMPNUM(lumpnum), numspritelumps, i, ROT_L, 0);
|
||||
R_InstallSpriteLump(WADFILENUM(lumpnum), LUMPNUM(lumpnum), numspritelumps, i, ROT_R, 1);
|
||||
R_IncrementSpriteLumps();
|
||||
}
|
||||
|
||||
maxframe++;
|
||||
|
||||
// allocate space for the frames present and copy sprtemp to it
|
||||
if (spritedef->numframes && // has been allocated
|
||||
spritedef->numframes < maxframe) // more frames are defined ?
|
||||
{
|
||||
Z_Free(spritedef->spriteframes);
|
||||
spritedef->spriteframes = NULL;
|
||||
}
|
||||
|
||||
// allocate this sprite's frames
|
||||
if (!spritedef->spriteframes)
|
||||
spritedef->spriteframes =
|
||||
static_cast<spriteframe_t*>(Z_Malloc(maxframe * sizeof (*spritedef->spriteframes), PU_STATIC, NULL));
|
||||
|
||||
spritedef->numframes = maxframe;
|
||||
memcpy(spritedef->spriteframes, sprtemp, maxframe*sizeof (spriteframe_t));
|
||||
}
|
||||
|
||||
// Install a single sprite, given its identifying name (4 chars)
|
||||
//
|
||||
// (originally part of R_AddSpriteDefs)
|
||||
|
|
@ -1268,7 +1320,7 @@ static void R_SplitSprite(vissprite_t *sprite)
|
|||
newsprite->cut = static_cast<spritecut_e>(newsprite->cut | SC_TOP);
|
||||
if (!(sector->lightlist[i].caster->fofflags & FOF_NOSHADE))
|
||||
{
|
||||
lightnum = (*sector->lightlist[i].lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = std::max((*sector->lightlist[i].lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
|
||||
if (lightnum < 0)
|
||||
spritelights = scalelight[0];
|
||||
|
|
@ -1787,6 +1839,22 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
sprdef = &sprites[thing->sprite];
|
||||
#ifdef ROTSPRITE
|
||||
sprinfo = &spriteinfo[thing->sprite];
|
||||
#endif
|
||||
frame = thing->frame&FF_FRAMEMASK;
|
||||
}
|
||||
}
|
||||
else if (thing->sprite == SPR_ITEM)
|
||||
{
|
||||
sprdef = &kartitems[thing->threshold > 0 && thing->threshold < numkartitems ? thing->threshold : 0].spritedef;
|
||||
sprinfo = &spriteinfo[SPR_UNKN];
|
||||
|
||||
if (frame >= sprdef->numframes) {
|
||||
CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid kartitem sprite frame %zu\n"), frame);
|
||||
thing->sprite = states[S_UNKNOWN].sprite;
|
||||
thing->frame = states[S_UNKNOWN].frame;
|
||||
sprdef = &sprites[thing->sprite];
|
||||
#ifdef ROTSPRITE
|
||||
sprinfo = &spriteinfo[thing->sprite];
|
||||
#endif
|
||||
frame = thing->frame&FF_FRAMEMASK;
|
||||
}
|
||||
|
|
@ -1932,9 +2000,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
const fixed_t visoffymul = (vflip ? -FRACUNIT : FRACUNIT);
|
||||
|
||||
if (R_ThingIsUsingBakedOffsets(thing))
|
||||
if (R_ThingIsUsingBakedOffsets(interptarg))
|
||||
{
|
||||
R_RotateSpriteOffsetsByPitchRoll(thing,
|
||||
R_RotateSpriteOffsetsByPitchRoll(interptarg,
|
||||
vflip,
|
||||
hflip,
|
||||
&interp,
|
||||
|
|
@ -2286,7 +2354,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
lightnum = thing->subsector->sector->lightlevel;
|
||||
}
|
||||
|
||||
lightnum = (lightnum + R_ThingLightLevel(thing)) >> LIGHTSEGSHIFT;
|
||||
lightnum = std::max((lightnum + R_ThingLightLevel(thing)) >> LIGHTSEGSHIFT, cv_secbright.value);
|
||||
|
||||
if (maplighting.directional == true && P_SectorUsesDirectionalLighting(thing->subsector->sector))
|
||||
{
|
||||
|
|
@ -2712,7 +2780,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
{
|
||||
if (sec->heightsec == -1) lightlevel = sec->lightlevel;
|
||||
|
||||
lightnum = (lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = std::max((lightlevel >> LIGHTSEGSHIFT), cv_secbright.value);
|
||||
|
||||
if (lightnum < 0)
|
||||
spritelights = scalelight[0];
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ extern "C" {
|
|||
#define FEETADJUST (4<<FRACBITS) // R_AddSingleSpriteDef
|
||||
|
||||
void R_AddKartFaces(skin_t *skin);
|
||||
void R_AddKartItemSprites(kartitem_t *item);
|
||||
boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump);
|
||||
|
||||
//faB: find sprites in wadfile, replace existing, add new ones
|
||||
|
|
|
|||
|
|
@ -208,6 +208,12 @@ TYPEDEF (waypoint_t);
|
|||
TYPEDEF (mapUserProperty_t);
|
||||
TYPEDEF (mapUserProperties_t);
|
||||
|
||||
// k_items.h
|
||||
TYPEDEF (kartitem_t);
|
||||
TYPEDEF (kartresult_t);
|
||||
TYPEDEF (kartitemgraphics_t);
|
||||
TYPEDEF (kartroulette_t);
|
||||
|
||||
// lua_hudlib_drawlist.h
|
||||
typedef struct huddrawlist_s *huddrawlist_h;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue