Alt Shrink

* Player gains a big speed boost
* Anything that would squish a shrunken player in Legacy (save for Grow players) flips them over here
* Most items rolled are doubled: singles become doubles, doubles become quadruples, and you can roll 6 bananas
* Certain multi items (3sneaker, 3orbi and 4orbi, 2jawz, decanana, ballhog) do NOT get doubled for balance reasons
* Shrunken players get rival bot odds, making their rolls more aggressive and frantic
This commit is contained in:
Anonimus 2025-11-04 23:44:23 -05:00
parent beb2ed5f97
commit 47fced5c09
15 changed files with 420 additions and 73 deletions

View file

@ -134,6 +134,7 @@ k_botitem.cpp
k_botsearch.cpp
k_cluster.cpp
k_odds.c
k_altshrink.c
k_grandprix.c
k_boss.c
k_hud.c

View file

@ -188,7 +188,7 @@ 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.
// Invincibility types. FIXME: Make this a more generalized name eventually (please...)
#define KARTINVIN_LEGACY 0
#define KARTINVIN_ALTERN 1

View file

@ -68,6 +68,7 @@
#include "m_perfstats.h"
#include "g_party.h"
#include "k_specialstage.h"
#include "k_altshrink.h"
#define CV_RESTRICT CV_NETVAR
@ -167,6 +168,7 @@ static void KartItemPush_OnChange(void);
static void KartAntiBump_OnChange(void);
static void KartItemBreaker_OnChange(void);
static void KartInvinType_OnChange(void);
static void KartShrinkType_OnChange(void);
static void KartBumpSpark_OnChange(void);
static void Schedule_OnChange(void);
@ -499,6 +501,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.56", 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);
@ -594,9 +600,14 @@ 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);
// Items with alternative types
static CV_PossibleValue_t kartitemtype_cons_t[] = {{KARTINVIN_LEGACY, "Legacy"}, {KARTINVIN_ALTERN, "Alternative"}, {0, NULL}};
consvar_t cv_kartinvintype = CVAR_INIT ("kartinvintype", "Legacy", CV_NETVAR|CV_CALL, kartitemtype_cons_t, KartInvinType_OnChange);
consvar_t cv_kartshrinktype = CVAR_INIT ("kartshrinktype", "Legacy", CV_NETVAR|CV_CALL, kartitemtype_cons_t, KartShrinkType_OnChange);
// 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", "13", 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}};
@ -1271,6 +1282,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);
@ -1337,6 +1349,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_invincmusicfade);
CV_RegisterVar(&cv_growmusicfade);
CV_RegisterVar(&cv_altshrinkmusicfade);
CV_RegisterVar(&cv_resetspecialmusic);
@ -7831,6 +7844,24 @@ static void KartInvinType_OnChange(void)
}
}
static void KartShrinkType_OnChange(void)
{
if (K_CanChangeRules(false) == false)
{
return;
}
if (leveltime < starttime)
{
CONS_Printf(M_GetText("Shrink type has been changed to \"%s\".\n"), cv_kartshrinktype.string);
shrinktype = (UINT8)cv_kartshrinktype.value;
}
else
{
CONS_Printf(M_GetText("Shrink type will be changed to \"%s\" next round.\n"), cv_kartshrinktype.string);
}
}
static void KartBumpSpark_OnChange(void)
{
if (K_CanChangeRules(false) == false)

View file

@ -724,6 +724,7 @@ 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

View file

@ -62,6 +62,7 @@
#include "k_specialstage.h"
#include "k_bot.h"
#include "k_odds.h"
#include "k_altshrink.h"
#include "doomstat.h"
#include "acs/interface.h"
#include "k_director.h"
@ -442,11 +443,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);
@ -2864,7 +2867,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 (K_IsLegacyShrunk(&players[player]))
growshrinktimer = players[player].growshrinktimer;
else
growshrinktimer = 0;

View file

@ -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;

81
src/k_altshrink.c Normal file
View file

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

70
src/k_altshrink.h Normal file
View file

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

View file

@ -2,6 +2,7 @@
/// \brief SRB2Kart item collision hooks
#include "k_collide.h"
#include "k_altshrink.h"
#include "k_stats.h"
#include "doomstat.h"
#include "doomtype.h"
@ -857,19 +858,37 @@ 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++;
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 +897,39 @@ 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++;
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;
}

View file

@ -66,6 +66,7 @@
#include "k_cluster.hpp"
#include "k_odds.h"
#include "k_specialstage.h"
#include "k_altshrink.h"
#include "h_timers.h"
#include "blan/b_soc.h"
@ -345,6 +346,10 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartstacking_grow_accelboost);
CV_RegisterVar(&cv_kartstacking_grow_stackable);
CV_RegisterVar(&cv_kartstacking_altshrink_speedboost);
CV_RegisterVar(&cv_kartstacking_altshrink_accelboost);
CV_RegisterVar(&cv_kartstacking_altshrink_stackable);
CV_RegisterVar(&cv_kartstacking_bubble_speedboost);
CV_RegisterVar(&cv_kartstacking_bubble_accelboost);
CV_RegisterVar(&cv_kartstacking_bubble_stackable);
@ -410,6 +415,9 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartslopeboost);
CV_RegisterVar(&cv_kartshrinktype);
CV_RegisterVar(&cv_kartaltshrinktime);
CV_RegisterVar(&cv_kartinvintype);
CV_RegisterVar(&cv_kartinvindist);
CV_RegisterVar(&cv_kartinvindistmul);
@ -1597,7 +1605,7 @@ static void K_RespawnChecker(player_t *player)
}
else if (player->respawn == 1)
{
if (player->growshrinktimer < 0)
if (K_IsShrunk(player))
{
player->mo->scalespeed = mapobjectscale/TICRATE;
player->mo->destscale = (6*mapobjectscale)/8;
@ -2665,6 +2673,14 @@ static void K_GetKartBoostPower(player_t *player)
K_DoBoost(player, GROWSPEEDBOOST, GROWACCELBOOST, GROWSTACKABLE, GROWSTACKABLE); // + 20% top speed, + 0% acceleration
}
if (K_IsAltShrunk(player)) // Alt. Shrink
{
fixed_t shrinkspeed = K_AccomodateShrinkScaling(SHRINKSPEEDBOOST);
fixed_t shrinkaccel = K_AccomodateShrinkScaling(SHRINKACCELBOOST);
K_DoBoost(player, FixedMul(shrinkspeed, GROW_SCALE), FixedMul(shrinkaccel, GROW_SCALE), SHRINKSTACKABLE, SHRINKSTACKABLE); // + 45% top speed, + 200% acceleration
}
if (player->bubbleboost) // Bubble Shield popping boost
{
K_DoBoost(player, BUBBLESPEEDBOOST, BUBBLEACCELBOOST, BUBBLESTACKABLE, BUBBLESTACKABLE); // + 35% top speed, + 800% acceleration
@ -3324,7 +3340,7 @@ static void K_RemoveGrowShrink(player_t *player)
{
if (player->growshrinktimer > 0) // Play Shrink noise
S_StartSound(player->mo, sfx_kc59);
else if (player->growshrinktimer < 0) // Play Grow noise
else if (K_IsShrunk(player)) // Play Grow noise
S_StartSound(player->mo, sfx_kc5a);
K_KartResetPlayerColor(player);
@ -3351,8 +3367,8 @@ void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source)
player->squishedtimer = TICRATE;
// Reduce Shrink timer
if (player->growshrinktimer < 0)
// Reduce Shrink timer for Legacy Shrink
if (K_IsLegacyShrunk(player))
{
player->growshrinktimer += TICRATE;
if (player->growshrinktimer >= 0)
@ -5073,6 +5089,44 @@ void K_DoInvincibility(player_t *player, tic_t time)
P_RestoreMusic(player);
}
static void K_DoGrowShrink(player_t *player, boolean shrinking)
{
player->mo->scalespeed = mapobjectscale/TICRATE;
player->mo->destscale = FixedMul(mapobjectscale, (shrinking) ? SHRINK_SCALE : GROW_SCALE);
if (K_PlayerShrinkCheat(player) == true)
{
player->mo->destscale = FixedMul(player->mo->destscale, SHRINK_SCALE);
}
if ((shrinking) && (ALTSHRINKTIME > 0))
{
player->growshrinktimer = ALTSHRINKTIME * -TICRATE;
}
else
{
player->growshrinktimer = (gametyperules & GTR_CLOSERPLAYERS ? 8 : 12) * ((shrinking) ? -TICRATE : TICRATE);
}
if (player->invincibilitytimer > 0)
{
; // invincibility has priority in P_RestoreMusic, no point in starting here
}
else if (P_IsLocalPlayer(player) == true)
{
S_ChangeMusicSpecial((shrinking) ? "kshrnk" : "kgrow");
}
else //used to be "if (P_IsDisplayPlayer(player) == false)"
{
if (!shrinking)
{
S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow));
}
}
P_RestoreMusic(player);
}
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source)
{
mobj_t *cachenext;
@ -6366,6 +6420,7 @@ static void K_UpdateInvincibilitySounds(player_t *player)
sfxnum = cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow;
else if (player->invincibilitytimer > 0 && (!localplayer || cv_supermusic.value == 2))
sfxnum = cv_kartinvinsfx.value ? sfx_alarmi : sfx_kinvnc;
// FIXME: Does Alt. Shrink need an alarm?
}
if (sfxnum != sfx_None && !S_SoundPlaying(player->mo, sfxnum))
@ -7375,7 +7430,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
{
if (player->growshrinktimer > 0)
player->growshrinktimer--;
if (player->growshrinktimer < 0)
if (K_IsShrunk(player))
player->growshrinktimer++;
// Back to normal
@ -7709,7 +7764,7 @@ void K_KartResetPlayerColor(player_t *player)
if (player->growshrinktimer % 5 == 0)
{
player->mo->colorized = true;
player->mo->color = (player->growshrinktimer < 0 ? SKINCOLOR_CREAMSICLE : SKINCOLOR_PERIWINKLE);
player->mo->color = (K_IsShrunk(player) ? SKINCOLOR_CREAMSICLE : SKINCOLOR_PERIWINKLE);
fullbright = true;
goto finalise;
}
@ -8984,8 +9039,11 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue)
if (K_SlipdashActive() && K_Sliptiding(player)) // slight handling boost based on weight
turnvalue = FixedMul(turnvalue, FRACUNIT + (10 - player->kartweight)*FRACUNIT/48);
if (player->invincibilitytimer || player->sneakertimer || player->bubbleboost || player->growshrinktimer > 0)
turnvalue = FixedMul(turnvalue, FixedDiv(5*FRACUNIT, 4*FRACUNIT));
if (player->invincibilitytimer || player->sneakertimer || player->bubbleboost ||
player->growshrinktimer > 0 || K_IsAltShrunk(player))
{
turnvalue = FixedMul(turnvalue, FixedDiv(5 * FRACUNIT, 4 * FRACUNIT));
}
if (player->flamedash && player->flamestore) // Reduce turning
{
@ -10769,39 +10827,24 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
{
player->itemamount--;
if (player->growshrinktimer < 0)
if (K_IsLegacyShrunk(player))
{
// If you're shrunk, then "grow" will just make you normal again.
// If you're shrunk, then "grow" will just make you normal again...
K_RemoveGrowShrink(player);
}
else
{
// ...in Legacy mode.
// Alt. Shrink's a powerup, so Grow overrides!
if (K_IsAltShrunk(player))
{
player->growshrinktimer = 0; // Paranoia
}
K_PlayPowerGloatSound(player->mo);
player->mo->scalespeed = mapobjectscale/TICRATE;
player->mo->destscale = FixedMul(mapobjectscale, GROW_SCALE);
K_DoGrowShrink(player, false);
if (K_PlayerShrinkCheat(player) == true)
{
player->mo->destscale = FixedMul(player->mo->destscale, SHRINK_SCALE);
}
player->growshrinktimer = (gametyperules & GTR_CLOSERPLAYERS ? 8 : 12) * TICRATE;
if (player->invincibilitytimer > 0)
{
; // invincibility has priority in P_RestoreMusic, no point in starting here
}
else if (P_IsLocalPlayer(player) == true)
{
S_ChangeMusicSpecial("kgrow");
}
else //used to be "if (P_IsDisplayPlayer(player) == false)"
{
S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow));
}
P_RestoreMusic(player);
S_StartSound(player->mo, sfx_kc5a);
}
@ -10811,7 +10854,18 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
case KITEM_SHRINK:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
{
K_DoShrink(player);
if (K_AltShrinkActive())
{
K_DoGrowShrink(player, true);
K_AltShrinkIFrames(player);
S_StartSound(player->mo, sfx_kc46);
}
else
{
K_DoShrink(player);
}
player->itemamount--;
K_PlayPowerGloatSound(player->mo);
K_BotResetItemConfirm(player, false);
@ -11023,12 +11077,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_RemoveMobj(player->shieldtracer);
}
if (player->growshrinktimer == 0)
player->altshrinktimeshit = 0;
if (player->growshrinktimer <= 0)
player->growcancel = -1;
if (player->itemtype == KITEM_SPB
|| player->itemtype == KITEM_SHRINK
|| player->growshrinktimer < 0)
|| K_IsLegacyShrunk(player))
indirectitemcooldown = 20*TICRATE;
if (player->hyudorotimer > 0)

View file

@ -33,6 +33,7 @@
#include "k_bot.h"
#include "k_kart.h"
#include "k_waypoint.h"
#include "k_altshrink.h"
#include "k_cluster.hpp"
#include "k_odds.h"
@ -120,6 +121,11 @@ static UINT8 K_KartItemOddsRace[NUMKARTRESULTS-1][MAXODDS] =
{ 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // Jawz x2
};
static UINT8 altshrinkodds[MAXODDS] =
{ 0, 0, 0, 0, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0};
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
//B C D E F G H I J K L M N O P Q
static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS][2] =
{
//R S
@ -203,7 +209,7 @@ tic_t ItemBGone[NUMKARTRESULTS][2] =
{ 10, 0 }, // Ballhog
{ 20, 0 }, // Self-Propelled Bomb
{ 3, 0 }, // Grow
{ 20, 0 }, // Shrink
{ 5, 0 }, // Shrink
{ 0, 0 }, // Thunder Shield
{ 20, 0 }, // Hyudoro
{ 0, 0 }, // Pogo Spring
@ -394,6 +400,24 @@ UINT8 K_ItemResultToAmount(SINT8 getitem)
}
}
/** \brief Prevent overpowered rolls while under the effects of Alt. Shrink.
\param item the item to check
\return Don't double for this item?
*/
static boolean K_DontDoubleMyItems(SINT8 item)
{
return ((item == KITEM_BALLHOG) || (item == KRITEM_TENFOLDBANANA)
|| (item == KRITEM_TRIPLEORBINAUT)
|| (item == KRITEM_QUADORBINAUT) || (item == KRITEM_TRIPLESNEAKER)
|| (item == KRITEM_DUALJAWZ) || (item == KITEM_SPB)
|| (item == KITEM_INVINCIBILITY) || (item == KITEM_GROW)
|| (item == KITEM_BUBBLESHIELD) || (item == KITEM_FLAMESHIELD)
|| (item == KITEM_ROCKETSNEAKER) || (item == KITEM_SHRINK)
|| (item == KITEM_HYUDORO));
}
/** \brief Item Roulette for Kart
\param player player
@ -403,10 +427,11 @@ UINT8 K_ItemResultToAmount(SINT8 getitem)
*/
static void K_KartGetItemResult(player_t *player, SINT8 getitem)
{
if (getitem == KITEM_SPB || getitem == KITEM_SHRINK) // Indirect items
if (getitem == KITEM_SPB || (getitem == KITEM_SHRINK && (!K_AltShrinkActive()))) // Indirect items
{
indirectitemcooldown = 20*TICRATE;
if (K_GetBGone(getitem, true) > 0) // Item cooldowns
}
else if (K_GetBGone(getitem, true) > 0) // Item cooldowns
{
K_SetBGoneToBase(getitem);
}
@ -415,6 +440,12 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem)
player->itemtype = K_ItemResultToType(getitem);
UINT8 itemamount = K_ItemResultToAmount(getitem);
if (K_IsAltShrunk(player) && (!K_DontDoubleMyItems(getitem)))
{
itemamount *= 2;
}
if (cv_kartdebugitem.value != KITEM_NONE && cv_kartdebugitem.value == player->itemtype && cv_kartdebugamount.value > 1)
itemamount = cv_kartdebugamount.value;
player->itemamount = itemamount;
@ -638,7 +669,11 @@ INT32 K_KartGetItemOdds(
else if (gametyperules & GTR_RACEODDS)
{
I_Assert(pos < MAXODDS); // Ditto
newodds = K_KartItemOddsRace[item-1][pos];
if (item == KITEM_SHRINK && K_AltShrinkActive())
newodds = altshrinkodds[pos]; // Alt. Shrink has unique odds, since it's a power item.
else
newodds = K_KartItemOddsRace[item-1][pos];
}
else
{
@ -820,7 +855,11 @@ INT32 K_KartGetItemOdds(
case KITEM_SHRINK:
cooldownOnStart = true;
powerItem = true;
indirectItem = true;
if (!K_AltShrinkActive())
indirectItem = true;
// "Why keep this for Alt. Shrink?" Bag. Ging.
notNearEnd = true;
if (pingame-1 <= pexiting)
@ -920,10 +959,17 @@ UINT8 K_FindUseodds(const player_t *player, fixed_t mashed, UINT32 pdis, UINT8 b
UINT8 disttable[oddsdiv];
UINT8 distlen = 0;
boolean oddsvalid[MAXODDS];
boolean rivalodds = false;
// Unused now, oops :V
(void)bestbumper;
if ((player->bot && player->botvars.rival) || K_IsAltShrunk(player))
{
// Rival bots and players using Alt. Shrink get crazier items.
rivalodds = true;
}
for (i = 0; i < MAXODDS; i++)
{
boolean available = false;
@ -943,7 +989,7 @@ UINT8 K_FindUseodds(const player_t *player, fixed_t mashed, UINT32 pdis, UINT8 b
mashed,
spbrush,
player->bot,
(player->bot && player->botvars.rival),
rivalodds,
K_IsPlayerLosing(player)
) > 0)
{

View file

@ -45,6 +45,7 @@
#include "acs/interface.h"
#include "g_party.h"
#include "k_waypoint.h"
#include "k_altshrink.h"
#include <tracy/tracy/TracyC.h>
@ -4099,6 +4100,7 @@ static boolean P_NetSyncMisc(savebuffer_t *save, boolean resending)
SYNCBOOLEAN(itempushing);
SYNC(bumpsparkactive);
SYNC(invintype);
SYNC(shrinktype);
SYNC(antibumptime);
for (i = 0; i < sizeof(votelevels)/sizeof(*votelevels); i++)

View file

@ -109,6 +109,7 @@
#include "k_mapuser.h"
#include "p_deepcopy.h"
#include "k_specialstage.h"
#include "k_altshrink.h"
#include "blan/b_soc.h"
@ -8072,6 +8073,7 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
bumpsparkactive = (UINT8)cv_kartbumpspark.value;
invintype = (UINT8)cv_kartinvintype.value;
K_UpdateShrinkType();
antibumptime = (tic_t)cv_kartantibump.value * TICRATE;

View file

@ -44,6 +44,7 @@
// SRB2kart
#include "k_kart.h"
#include "k_altshrink.h"
#include "console.h" // CON_LogMessage
#include "k_terrain.h"
#include "acs/interface.h"
@ -9189,7 +9190,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;

View file

@ -62,6 +62,7 @@
#include "k_color.h"
#include "k_follower.h"
#include "k_odds.h"
#include "k_altshrink.h"
#include "g_party.h"
#include "acs/interface.h"
@ -831,6 +832,8 @@ 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_AltShrinkActive()) && (K_GetShrinkTime(&players[p]) > bestlocaltimer)) \
{ wantedmus = 3; bestlocaltimer = K_GetShrinkTime(&players[p]); } \
}
setbests(localplayertable[0]);
setbests(localplayertable[1]);
@ -848,6 +851,8 @@ void P_RestoreMusic(player_t *player)
wantedmus = 1;
else if (player->invincibilitytimer > 1)
wantedmus = 2;
else if ((K_AltShrinkActive()) && (K_GetShrinkTime(player) > 1))
wantedmus = 3;
}
}
@ -864,6 +869,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