Subsonic Adjustments

This commit is contained in:
Oni VelocitOni 2025-09-26 17:58:02 +00:00 committed by AJ Martinez
parent b7f8afd5ef
commit 8f4a698a35
11 changed files with 185 additions and 21 deletions

View file

@ -383,7 +383,7 @@ typedef enum
#define TUMBLEBOUNCES 3
#define TUMBLEGRAVITY (4*FRACUNIT)
#define TRIPWIRETIME (15)
#define TRIPWIRETIME (50)
#define BALLHOGINCREMENT (7)
@ -821,6 +821,7 @@ struct player_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 tripwireAirLeniency; // Timer that elongates tripwire leniency when in midair.
UINT8 fakeBoost; // Some items need to grant tripwire pass briefly, even when their effect is thrust/instathrust. This is a fake boost type to control that.
UINT16 subsonicleniency; // Keep the subsonic visual for just a little bit when your sonic boom is visible
itemroulette_t itemRoulette; // Item roulette data

View file

@ -1599,6 +1599,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_AMPBURST",
// Tripwire VFX on player for bumping it or passing it
"S_SONICBOOM",
"S_TRIPWIREOK",
"S_TRIPWIRELOCKOUT",
@ -3597,6 +3599,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_AMPAURA",
"MT_AMPBURST",
"MT_SONICBOOM",
"MT_TRIPWIREOK",
"MT_TRIPWIRELOCKOUT",

View file

@ -614,6 +614,7 @@ char sprnames[NUMSPRITES + 1][5] =
"EXPC",
"TWBB",
"TWOK",
"TW_L",
@ -2225,6 +2226,7 @@ state_t states[NUMSTATES] =
{SPR_AMPD, FF_FULLBRIGHT|FF_ANIMATE|0, -1, {NULL}, 4, 2, S_NULL}, // S_AMPAURA
{SPR_AMPB, FF_FULLBRIGHT|FF_ADD|FF_PAPERSPRITE|2, -1, {NULL}, 4, 2, S_NULL}, // S_AMPBURST
{SPR_TWBB, FF_ADD|FF_PAPERSPRITE|0, -1, {NULL}, 0, 0, S_NULL}, // S_SONICBOOM
{SPR_TWOK, FF_FULLBRIGHT|FF_ANIMATE|0, 56, {NULL}, 55, 1, S_NULL}, // S_TRIPWIREOK
{SPR_TW_L, FF_FULLBRIGHT|FF_ANIMATE|0, 56, {NULL}, 55, 1, S_NULL}, // S_TRIPWIRELOCKOUT
@ -13998,6 +14000,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_SONICBOOM
-1, // doomednum
S_SONICBOOM, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
67*FRACUNIT, // radius
67*FRACUNIT, // height
1, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},
{ // MT_TRIPWIREOK
-1, // doomednum
S_TRIPWIREOK, // spawnstate

View file

@ -1155,6 +1155,7 @@ typedef enum sprite
SPR_EXPC,
SPR_TWBB, // Sonic Boom
SPR_TWOK, // Tripwire OK
SPR_TW_L, // Tripwire Lockout
@ -2681,6 +2682,7 @@ typedef enum state
S_AMPAURA,
S_AMPBURST,
S_SONICBOOM,
S_TRIPWIREOK,
S_TRIPWIRELOCKOUT,
@ -4706,6 +4708,7 @@ typedef enum mobj_type
MT_AMPAURA,
MT_AMPBURST,
MT_SONICBOOM,
MT_TRIPWIREOK,
MT_TRIPWIRELOCKOUT,

View file

@ -3171,6 +3171,7 @@ boolean K_SlopeResistance(const player_t *player)
fixed_t K_PlayerTripwireSpeedThreshold(const player_t *player)
{
fixed_t required_speed = 2 * K_GetKartSpeed(player, false, false); // 200%
if (K_LegacyRingboost(player))
@ -3182,15 +3183,48 @@ fixed_t K_PlayerTripwireSpeedThreshold(const player_t *player)
if (modeattacking && !(gametyperules & GTR_CATCHER))
required_speed = 4 * K_GetKartSpeed(player, false, false);
if ((gametyperules & GTR_CIRCUIT) && !K_Cooperative() && M_NotFreePlay() && !modeattacking)
if ((gametyperules & GTR_CIRCUIT) && !K_Cooperative() && M_NotFreePlay() && !modeattacking)
{
required_speed += FixedMul(required_speed, K_PlayerScamPercentage(player, 2)); // Proration: Players near 1st need more speed!
}
/*
All of this will be for making Sonic Boom easier when you're drowning in the back, like a "reverse" proration
*/
if (player->offroad && K_ApplyOffroad(player))
{
// Increase to 300% if you're lawnmowering.
required_speed = (required_speed * 3) / 2;
#define REVERSED_SONICBOOM_PRORATION (30000)
#define MAX_SONICBOOM_REDUCTION (7*FRACUNIT/8)
UINT32 dist = K_GetItemRouletteDistance(player, D_NumPlayersInRace());
if (dist > REVERSED_SONICBOOM_PRORATION)
{
dist = REVERSED_SONICBOOM_PRORATION;
}
fixed_t distfactor = FixedDiv(dist, REVERSED_SONICBOOM_PRORATION); //
fixed_t sonicboom_aid = Easing_InCubic(distfactor, FRACUNIT, MAX_SONICBOOM_REDUCTION);
required_speed = FixedMul(sonicboom_aid, required_speed);
/*
And then all of this will be for making it harder when you're in scam range, actual proration
*/
required_speed += FixedMul(required_speed, K_PlayerScamPercentage(player, 3/2));
if(player->position == 1)
{
required_speed = 9 * K_GetKartSpeed(player, false, false); // Seek employment
}
/*
if (!K_PlayerUsesBotMovement(player)) // Sonic Boom debug
{
//CONS_Printf("Sonic Boom threshold: %d percent, IN FRACUNIT: %d \n", ((required_speed *100) / K_GetKartSpeed(player, false, false)), required_speed);
CONS_Printf("D=%d DF=%d SBA=%d RS=%d RRS=%d\n", dist, distfactor, sonicboom_aid, required_speed, required_speed * 100 / K_GetKartSpeed(player, false, false));
}
*/
#undef REVERSED_SONICBOOM_PRORATION
#undef MAX_SONICBOOM_REDUCTION
}
if (player->botvars.rubberband > FRACUNIT && K_PlayerUsesBotMovement(player) == true)
@ -9688,7 +9722,7 @@ static void K_UpdateTripwire(player_t *player)
tripwirepass_t triplevel = K_TripwirePassConditions(player);
boolean mightplaysound = false;
if (triplevel != TRIPWIRE_NONE)
if (triplevel != TRIPWIRE_NONE) // Sonic Boom, able to pass tripwire
{
if (!boostExists)
{
@ -9894,7 +9928,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
{
mobj_t *ghost;
ghost = P_SpawnGhostMobj(player->mo);
ghost->extravalue1 = player->numboosts+1;
ghost->extravalue1 = player->numboosts;
ghost->extravalue2 = (leveltime % ghost->extravalue1);
ghost->fuse = ghost->extravalue1;
ghost->renderflags |= RF_FULLBRIGHT;

View file

@ -76,7 +76,7 @@ Make sure this matches the actual number of states
#define EARLY_ITEM_FLICKER (NUMTRANSMAPS)
#define TRIPWIRE_OK_SOUND (sfx_s3k40)
#define TRIPWIRE_OK_SOUND (sfx_sonbo2)
#define TRIPWIRE_NG_SOUND (sfx_gshaf)
// 2023-08-26 +ang20 to Sal's OG values to make them friendlier - Tyron

View file

@ -375,6 +375,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->tripwirePass);
else if (fastcmp(field,"fakeboost"))
lua_pushinteger(L, plr->fakeBoost);
else if (fastcmp(field,"subsonicleniency"))
lua_pushinteger(L, plr->subsonicleniency);
else if (fastcmp(field,"tripwireleniency"))
lua_pushinteger(L, plr->tripwireLeniency);
else if (fastcmp(field,"tripwireairleniency"))
@ -1040,6 +1042,8 @@ static int player_set(lua_State *L)
plr->tripwirePass = luaL_checkinteger(L, 3);
else if (fastcmp(field,"fakeboost"))
plr->fakeBoost = luaL_checkinteger(L, 3);
else if (fastcmp(field,"subsonicleniency"))
plr->subsonicleniency = luaL_checkinteger(L, 3);
else if (fastcmp(field,"tripwireleniency"))
plr->tripwireLeniency = luaL_checkinteger(L, 3);
else if (fastcmp(field,"tripwireairleniency"))

View file

@ -7997,7 +7997,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
}
}
break;
case MT_TRIPWIREAPPROACH: {
case MT_TRIPWIREAPPROACH: { // Subsonic Visuals
if (!mobj->target || !mobj->target->health || !mobj->target->player)
{
P_RemoveMobj(mobj);
@ -8007,17 +8007,53 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj_t *target = mobj->target;
player_t *player = target->player;
fixed_t myspeed = (player->speed);
boolean In_A_Race = ((gametyperules & GTR_CIRCUIT) && !K_Cooperative() && M_NotFreePlay() && !modeattacking); // If you're in a real race.
boolean prorated_sonicboom_alert = (K_PlayerTripwireSpeedThreshold(player) > 2 * K_GetKartSpeed(player, false, false)) ; // If you're being prorated.
fixed_t maxspeed = K_PlayerTripwireSpeedThreshold(player); // Centered at this speed.
fixed_t minspeed = max(2 * maxspeed / 4, 16 * K_GetKartSpeed(player, false, false) / 10); // Starts appearing at this speed.
fixed_t minspeed = max(2 * maxspeed / 4, 7 * K_GetKartSpeed(player, false, false) / 5); // Starts appearing at this speed.
fixed_t alertspeed = 9 * maxspeed / 10; // When to flash?
fixed_t frontoffset = 5*target->scale; // How far in front?
fixed_t percentvisible = 0;
if (myspeed > minspeed)
{
percentvisible = min(FRACUNIT, FixedDiv(myspeed - minspeed, maxspeed - minspeed));
}
if (myspeed >= maxspeed || player->tripwireLeniency)
percentvisible = 0;
{
player->subsonicleniency++; // Subsonic visual stays for a bit during tripwire leniency
if(player->subsonicleniency == 1 && player->tripwireLeniency && myspeed >= maxspeed && !S_SoundPlaying(player->mo, sfx_gsha7)) // Don't play during superring too
{
mobj_t *boost = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height/2, MT_SONICBOOM);
boost->momx = player->mo->momx/2;
boost->momy = player->mo->momy/2;
boost->momz = player->mo->momz/2;
boost->angle = player->mo->angle + ANGLE_90;
boost->scalespeed = boost->scale;
boost->destscale = boost->scale*8;
//sonicboom->color = SKINCOLOR_WHITE;
boost->fuse = 8;
}
}
else
{
player->subsonicleniency = 0; // Goes back down otherwise
}
if (player->subsonicleniency >= (3*TICRATE))
{
percentvisible = 0; // Once it stays long enough, no longer visible
}
#if 0
if (!K_PlayerUsesBotMovement(player))
{
CONS_Printf("SSL=%d, PV=%d\n", player->subsonicleniency, percentvisible);
}
#endif
#if 0
fixed_t hang = 85*FRACUNIT/100; // Dampen inward movement past a certain point
@ -8045,8 +8081,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_InstaScale(mobj, FixedMul(target->scale, easedscale));
K_MatchGenericExtraFlagsNoInterp(mobj, target);
UINT8 maxtranslevel = NUMTRANSMAPS - 2;
UINT8 maxtranslevel = NUMTRANSMAPS;
UINT8 trans = FixedInt(FixedMul(percentvisible, FRACUNIT*(maxtranslevel+1)));
//UINT8 trans = FixedInt(FixedMul(percentvisible - player->subsonicleniency * FRACUNIT/100, FRACUNIT*(maxtranslevel+1)));
if (trans > maxtranslevel)
trans = maxtranslevel;
trans = NUMTRANSMAPS - trans;
@ -8060,13 +8098,52 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->renderflags |= RF_PAPERSPRITE;
mobj->colorized = true;
if (myspeed > alertspeed)
mobj->color = (leveltime & 1) ? SKINCOLOR_LILAC : SKINCOLOR_JAWZ;
else
mobj->color = SKINCOLOR_WHITE;
/*
if (!K_PlayerUsesBotMovement(player))
{
CONS_Printf("In_A_Race=%d, Prorated_SonicBoom_Alert=%d\n", In_A_Race, prorated_sonicboom_alert);
}
*/
if (In_A_Race == true && prorated_sonicboom_alert == true)
{
mobj->color = (leveltime & 1) ? SKINCOLOR_KETCHUP : SKINCOLOR_RED; // If you're being prorated we flash red
trans = trans*2;
}
else if (myspeed > alertspeed)
mobj->color = (leveltime & 1) ? SKINCOLOR_LILAC : SKINCOLOR_JAWZ; // If the Subsonic lines meet we flash tripwire colors
else
mobj->color = SKINCOLOR_WHITE; // Default
mobj->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(player));
// Alright, let's just handle all the sfx down here
if (P_IsDisplayPlayer(player))
{
UINT8 MIN_VOLUME = 25;
UINT8 MAX_VOLUME = 75;
UINT8 volume = FixedRescale(myspeed, minspeed, maxspeed, Easing_Linear, MIN_VOLUME, MAX_VOLUME);
if (myspeed >= minspeed && myspeed < maxspeed)
{
S_StopSoundByID(mobj, sfx_sonbo1);
if(!S_SoundPlaying(mobj, sfx_sonbo3))
S_StartSoundAtVolume(mobj, sfx_sonbo3, volume); // Subsonic SFX
}
else if (myspeed >= maxspeed || player->tripwireLeniency)
{
S_StopSoundByID(mobj, sfx_sonbo3);
if(!S_SoundPlaying(mobj, sfx_sonbo1))
S_StartSoundAtVolume(mobj, sfx_sonbo1, MAX_VOLUME); // SonicBoom lingering SFX
}
else
{
S_StopSoundByID(mobj, sfx_sonbo1);
S_StopSoundByID(mobj, sfx_sonbo3);
}
}
break;
}
case MT_TRIPWIREBOOST: {

View file

@ -533,6 +533,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT16(save->p, players[i].tripwireLeniency);
WRITEUINT8(save->p, players[i].tripwireAirLeniency);
WRITEUINT8(save->p, players[i].fakeBoost);
WRITEUINT16(save->p, players[i].subsonicleniency);
WRITESINT8(save->p, players[i].itemtype);
WRITEUINT8(save->p, players[i].itemamount);
@ -1212,6 +1213,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].tripwireLeniency = READUINT16(save->p);
players[i].tripwireAirLeniency = READUINT8(save->p);
players[i].fakeBoost = READUINT8(save->p);
players[i].subsonicleniency = READUINT16(save->p);
players[i].itemtype = READSINT8(save->p);
players[i].itemamount = READUINT8(save->p);

View file

@ -1164,12 +1164,18 @@ sfxinfo_t S_sfx[NUMSFX] =
{"gate04", false, 32, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"gate05", false, 32, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
// Wavedash
{"waved1", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"waved2", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"waved3", false, 32, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"waved4", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"waved5", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
// Sonic Boom & Subsonic
{"sonbo1", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"sonbo2", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"sonbo3", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
// Passing sounds
{"pass01", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"pass02", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},

View file

@ -1239,6 +1239,11 @@ typedef enum
sfx_waved3,
sfx_waved4,
sfx_waved5,
// Sonic Boom & Subsonic
sfx_sonbo1,
sfx_sonbo2,
sfx_sonbo3,
// Passing sounds
sfx_pass01,