Merge branch 'enhance-drop' into 'master'

Do fast transfer fall with C, add FX

See merge request kart-krew-dev/ring-racers-internal!2665
This commit is contained in:
Oni VelocitOni 2025-07-03 01:31:02 +00:00
commit 2111d9edf0
7 changed files with 104 additions and 25 deletions

View file

@ -139,9 +139,12 @@ typedef enum
PF2_SELFDEAFEN = 1<<2,
PF2_SERVERMUTE = 1<<3,
PF2_SERVERDEAFEN = 1<<4,
PF2_STRICTFASTFALL = 1<<5, // Fastfall only with C, never with A+X. Profile preference.
PF2_ALWAYSDAMAGED = 1<<6, // Ignore invulnerability or clash conditions when evaulating damage (P_DamageMobj). Unset after use!
PF2_BUBBLECONTACT = 1<<7, // ACHTUNG VERY BAD HACK - Don't allow Bubble Shield to contact certain objects unless this is a fresh blowup.
PF2_SUPERTRANSFERVFX = 1<<8, // Don't respawn the "super transfer available" VFX.
} pflags2_t;
typedef enum
@ -1114,7 +1117,6 @@ struct player_t
fixed_t outrun; // Milky Way road effect
fixed_t transfer; // Tired of Ramp Park fastfalls
boolean transfersound;
uint8_t public_key[PUBKEYLENGTH];

View file

@ -461,6 +461,14 @@ std::optional<TargetTracking::Tooltip> object_tooltip(const mobj_t* mobj)
);
case MT_PLAYER:
{
if (stplyr->fastfall == 0 && K_CanSuperTransfer(stplyr))
return Tooltip(
TextElement(
TextElement().parse("<c_animated>").font(splitfont))
)
.offset3d(0, 0, 64 * mobj->scale * P_MobjFlip(mobj));
return conditional(
mobj->player == stplyr && stplyr->icecube.frozen,
[&] { return Tooltip(TextElement(
@ -470,6 +478,7 @@ std::optional<TargetTracking::Tooltip> object_tooltip(const mobj_t* mobj)
)).offset3d(0, 0, 64 * mobj->scale * P_MobjFlip(mobj)); }
// I will be trying to figure out why the return value didn't accept a straightforward call to parse() for the rest of my life (apprx. 15 seconds)
);
}
default:
return {};

View file

@ -7635,6 +7635,13 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound)
}
}
boolean K_CanSuperTransfer(player_t *player)
{
if (!player->transfer)
return false;
return (abs(player->mo->momz) < (2*abs(player->transfer)/4)) || (player->mo->momz > 0) != (player->transfer > 0);
}
static void K_ThrowLandMine(player_t *player)
{
mobj_t *landMine;
@ -9565,16 +9572,16 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
K_TryMoveBackupItem(player);
if (onground || player->transfer < 10*player->mo->scale)
if (onground && player->transfer)
{
player->fastfall = 0;
player->transfer = 0;
player->transfersound = false;
player->pflags2 &= ~PF2_SUPERTRANSFERVFX;
}
if (player->transfer)
{
boolean eligible = (abs(player->mo->momz) < (2*abs(player->transfer)/4)) || (player->mo->momz > 0) != (player->transfer > 0);
if ((player->cmd.buttons & BT_ACCELERATE) && eligible)
if (player->fastfall)
{
fixed_t fuckfactor = FRACUNIT;
fixed_t transfergravity = 10*FRACUNIT/100;
@ -9587,11 +9594,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
{
fuckfactor = FRACUNIT/2;
}
else if (!player->transfersound)
{
S_StartSound(player->mo, sfx_ggfall);
player->transfersound = true;
}
fixed_t sx, sy;
sx = P_RandomRange(PR_DECORATION, -48, 48)*FRACUNIT;
@ -9612,6 +9614,18 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
{
if (leveltime % 2)
K_SpawnFireworkTrail(player->mo);
if (K_CanSuperTransfer(player) && !(player->pflags2 & PF2_SUPERTRANSFERVFX))
{
if (P_IsDisplayPlayer(player))
S_StartSound(player->mo, sfx_gshdc);
mobj_t *gainax = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_GAINAX);
gainax->movedir = 0;
P_SetTarget(&gainax->target, player->mo);
P_SetMobjState(gainax, S_GAINAX_MID1);
gainax->flags2 |= MF2_BOSSNOTRAP;
player->pflags2 |= PF2_SUPERTRANSFERVFX;
}
}
}
@ -12800,6 +12814,13 @@ boolean K_PlayerEBrake(const player_t *player)
return false;
}
// A little gross, but when fastfalling from a transfer, we are "transferring" for 1 tic of landing.
// Prevents a single tic of ebrake friction janking everything out.
if (player->transfer && player->mo && !P_MobjWasRemoved(player->mo) && P_IsObjectOnGround(player->mo))
{
return false;
}
if (player->fastfall != 0)
{
return true;
@ -13205,18 +13226,33 @@ static void K_KartSpindash(player_t *player)
if (player->fastfall == 0)
{
// Starting fastfall...
// ...unless this is a macro input with a strict profile.
// Then this is probably an attempted brakedrift or e-brake.
if (player->pflags2 & PF2_STRICTFASTFALL)
if (!(player->cmd.buttons & BT_SPINDASH))
return;
// Factors 3D momentum.
player->fastfallBase = FixedHypot(player->speed, player->mo->momz);
if (K_CanSuperTransfer(player))
{
S_StartSound(player->mo, sfx_ggfall);
}
else
{
player->transfer = 0;
}
}
// Update fastfall.
player->fastfall = player->mo->momz;
player->spindash = 0;
P_ResetPitchRoll(player->mo);
if (!player->transfer)
P_ResetPitchRoll(player->mo);
return;
}
@ -13315,6 +13351,7 @@ boolean K_FastFallBounce(player_t *player)
// Handle fastfall bounce.
if (player->fastfall != 0)
{
//CONS_Printf("ffb\n");
const fixed_t maxBounce = mapobjectscale * 10;
const fixed_t minBounce = mapobjectscale;
fixed_t bounce = 2 * abs(player->fastfall) / 3;
@ -13439,7 +13476,7 @@ static void K_AirFailsafe(player_t *player)
// Accel inputs queue air-failsafe for when they're released,
// as long as they're not part of a fastfall attempt.
if ((buttons & (BT_ACCELERATE|BT_BRAKE)) == BT_ACCELERATE || K_GetForwardMove(player) != 0)
if ((buttons & (BT_ACCELERATE|BT_BRAKE)) == BT_ACCELERATE || K_GetForwardMove(player) != 0 || (player->fastfall && player->transfer))
{
player->pflags |= PF_AIRFAILSAFE;
return;

View file

@ -352,6 +352,8 @@ fixed_t K_TeamComebackMultiplier(player_t *player);
void K_ApplyStun(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype);
boolean K_CanSuperTransfer(player_t *player);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -274,8 +274,6 @@ static int player_get(lua_State *L)
lua_pushboolean(L, plr->analoginput);
else if (fastcmp(field,"transfer"))
lua_pushboolean(L, plr->transfer);
else if (fastcmp(field,"transfersound"))
lua_pushboolean(L, plr->transfersound);
else if (fastcmp(field,"markedfordeath"))
lua_pushboolean(L, plr->markedfordeath);
else if (fastcmp(field,"incontrol"))
@ -933,8 +931,6 @@ static int player_set(lua_State *L)
plr->analoginput = luaL_checkboolean(L, 3);
else if (fastcmp(field,"transfer"))
plr->transfer = luaL_checkboolean(L, 3);
else if (fastcmp(field,"transfersound"))
plr->transfersound = luaL_checkboolean(L, 3);
else if (fastcmp(field,"markedfordeath"))
plr->markedfordeath = luaL_checkboolean(L, 3);
else if (fastcmp(field,"dotrickfx"))

View file

@ -1197,7 +1197,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
{
gravityadd *= 3;
}
else if (mo->player->fastfall != 0)
else if (mo->player->fastfall != 0 && mo->player->transfer == 0)
{
// Fast falling
@ -1801,8 +1801,15 @@ boolean P_XYMovement(mobj_t *mo)
mo->momz = transfermomz;
if (mo->player)
{
mo->player->transfer = transfermomz;
S_StartSound(mo, sfx_s3k98);
if (abs(transfermomz) > 10*mo->scale)
{
mo->player->transfer = transfermomz;
S_StartSound(mo, sfx_s3k98);
}
else
{
mo->player->transfer = 0;
}
}
mo->standingslope = NULL;
@ -8211,26 +8218,53 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->z + (mobj->target->height * P_MobjFlip(mobj)));
break;
case MT_GAINAX:
{
boolean vfx = !!(mobj->flags2 & MF2_BOSSNOTRAP);
if (!mobj->target || P_MobjWasRemoved(mobj->target) // sanity
|| !mobj->target->player // ditto
|| !mobj->target->player->glanceDir // still glancing?
|| mobj->target->player->aizdriftturn // only other circumstance where can glance
|| ((K_GetKartButtons(mobj->target->player) & BT_LOOKBACK) != BT_LOOKBACK)) // it's a lookback indicator...
|| !mobj->target->player) // ditto
{
P_RemoveMobj(mobj);
return false;
}
if (!vfx)
{
if (!mobj->target->player->glanceDir // still glancing?
|| mobj->target->player->aizdriftturn // only other circumstance where can glance
|| ((K_GetKartButtons(mobj->target->player) & BT_LOOKBACK) != BT_LOOKBACK)) // it's a lookback indicator...
{
P_RemoveMobj(mobj);
return false;
}
}
if (vfx)
{
if (P_IsObjectOnGround(mobj->target) || mobj->target->player->fastfall
|| !K_CanSuperTransfer(mobj->target->player))
{
P_RemoveMobj(mobj);
return false;
}
}
mobj->angle = mobj->target->player->drawangle;
mobj->z = mobj->target->z;
K_MatchGenericExtraFlags(mobj, mobj->target);
mobj->renderflags = (mobj->renderflags & ~RF_DONTDRAW)|K_GetPlayerDontDrawFlag(mobj->target->player);
if (vfx)
mobj->renderflags ^= INT32_MAX;
P_MoveOrigin(mobj, mobj->target->x + FixedMul(34 * mapobjectscale, FINECOSINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)),
mobj->target->y + FixedMul(34 * mapobjectscale, FINESINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)),
mobj->z + (32 * mapobjectscale * P_MobjFlip(mobj)));
if (vfx)
break;
{
statenum_t gainaxstate = mobj->state-states;
if (gainaxstate == S_GAINAX_TINY)
@ -8254,6 +8288,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
}
break;
}
case MT_FLAMESHIELDPAPER:
if (!mobj->target || P_MobjWasRemoved(mobj->target))
{

View file

@ -696,7 +696,6 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEFIXED(save->p, players[i].outrun);
WRITEFIXED(save->p, players[i].transfer);
WRITEUINT8(save->p, players[i].transfersound);
WRITEUINT8(save->p, players[i].rideroid);
WRITEUINT8(save->p, players[i].rdnodepull);
@ -1358,7 +1357,6 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].outrun = READFIXED(save->p);
players[i].transfer = READFIXED(save->p);
players[i].transfersound = READUINT8(save->p);
players[i].rideroid = (boolean)READUINT8(save->p);
players[i].rdnodepull = (boolean)READUINT8(save->p);