mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Fast falling
E-Brake in the air for x4 gravity, at the cost of a tiny bounce on landing.
This commit is contained in:
parent
1e9b95e546
commit
bc538a066f
11 changed files with 180 additions and 71 deletions
|
|
@ -443,6 +443,8 @@ typedef struct player_s
|
|||
fixed_t spindashspeed; // Spindash release speed
|
||||
UINT8 spindashboost; // Spindash release boost timer
|
||||
|
||||
fixed_t fastfall; // Fast fall momentum
|
||||
|
||||
UINT8 numboosts; // Count of how many boosts are being stacked, for after image spawning
|
||||
fixed_t boostpower; // Base boost value, for offroad
|
||||
fixed_t speedboost; // Boost value smoothing for max speed
|
||||
|
|
|
|||
41
src/k_kart.c
41
src/k_kart.c
|
|
@ -9025,8 +9025,12 @@ static INT32 K_FlameShieldMax(player_t *player)
|
|||
|
||||
boolean K_PlayerEBrake(player_t *player)
|
||||
{
|
||||
if (player->fastfall != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return (K_GetKartButtons(player) & BT_EBRAKEMASK) == BT_EBRAKEMASK
|
||||
&& P_IsObjectOnGround(player->mo) == true
|
||||
&& player->drift == 0
|
||||
&& player->spinouttimer == 0
|
||||
&& player->justbumped == 0
|
||||
|
|
@ -9053,9 +9057,8 @@ void K_KartEbrakeVisuals(player_t *p)
|
|||
mobj_t *spdl;
|
||||
fixed_t sx, sy;
|
||||
|
||||
if (K_PlayerEBrake(p))
|
||||
if (K_PlayerEBrake(p) == true)
|
||||
{
|
||||
|
||||
if (p->ebrakefor % 20 == 0)
|
||||
{
|
||||
wave = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_SOFTLANDING);
|
||||
|
|
@ -9092,7 +9095,6 @@ void K_KartEbrakeVisuals(player_t *p)
|
|||
K_FlipFromObject(p->mo->hprev, p->mo);
|
||||
}
|
||||
|
||||
|
||||
if (!p->spindash)
|
||||
{
|
||||
// Spawn downwards fastline
|
||||
|
|
@ -9233,6 +9235,7 @@ static void K_KartSpindashWind(mobj_t *parent)
|
|||
|
||||
static void K_KartSpindash(player_t *player)
|
||||
{
|
||||
const boolean onGround = P_IsObjectOnGround(player->mo);
|
||||
const INT16 MAXCHARGETIME = K_GetSpindashChargeTime(player);
|
||||
UINT16 buttons = K_GetKartButtons(player);
|
||||
boolean spawnWind = (leveltime % 2 == 0);
|
||||
|
|
@ -9296,6 +9299,36 @@ static void K_KartSpindash(player_t *player)
|
|||
return;
|
||||
}
|
||||
|
||||
// Handle fast falling behaviors first.
|
||||
if (onGround == false)
|
||||
{
|
||||
// Update fastfall.
|
||||
player->fastfall = player->mo->momz;
|
||||
player->spindash = 0;
|
||||
return;
|
||||
}
|
||||
else if (player->fastfall != 0)
|
||||
{
|
||||
// Handle fastfall bounce.
|
||||
const fixed_t maxBounce = player->mo->scale * 10;
|
||||
const fixed_t minBounce = player->mo->scale * 2;
|
||||
fixed_t bounce = abs(player->fastfall) / 4;
|
||||
|
||||
if (bounce > maxBounce)
|
||||
{
|
||||
bounce = maxBounce;
|
||||
}
|
||||
|
||||
if (bounce > minBounce)
|
||||
{
|
||||
S_StartSound(player->mo, sfx_ffbonc);
|
||||
player->mo->momz = bounce * P_MobjFlip(player->mo);
|
||||
}
|
||||
|
||||
player->fastfall = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->speed == 0 && player->steering != 0 && leveltime % 8 == 0)
|
||||
{
|
||||
// Rubber burn turn sfx
|
||||
|
|
|
|||
|
|
@ -274,6 +274,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->spindashspeed);
|
||||
else if (fastcmp(field,"spindashboost"))
|
||||
lua_pushinteger(L, plr->spindashboost);
|
||||
else if (fastcmp(field,"fastfall"))
|
||||
lua_pushfixed(L, plr->fastfall);
|
||||
else if (fastcmp(field,"numboosts"))
|
||||
lua_pushinteger(L, plr->numboosts);
|
||||
else if (fastcmp(field,"boostpower"))
|
||||
|
|
@ -632,6 +634,8 @@ static int player_set(lua_State *L)
|
|||
plr->spindashspeed = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"spindashboost"))
|
||||
plr->spindashboost = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"fastfall"))
|
||||
plr->fastfall = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"numboosts"))
|
||||
plr->numboosts = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"boostpower"))
|
||||
|
|
|
|||
|
|
@ -2463,9 +2463,8 @@ fixed_t P_GetThingStepUp(mobj_t *thing)
|
|||
const fixed_t maxstepmove = P_BaseStepUp();
|
||||
fixed_t maxstep = maxstepmove;
|
||||
|
||||
if (thing->type == MT_SKIM)
|
||||
if (thing->player && thing->player->fastfall != 0)
|
||||
{
|
||||
// Skim special (not needed for kart?)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
43
src/p_mobj.c
43
src/p_mobj.c
|
|
@ -1132,6 +1132,12 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
{
|
||||
gravityadd = FixedMul(TUMBLEGRAVITY, gravityadd);
|
||||
}
|
||||
|
||||
if (mo->player->fastfall != 0)
|
||||
{
|
||||
// Fast falling
|
||||
gravityadd *= 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1761,7 +1767,9 @@ void P_XYMovement(mobj_t *mo)
|
|||
|
||||
if (moved && oldslope && !(mo->flags & MF_NOCLIPHEIGHT)) { // Check to see if we ran off
|
||||
|
||||
if (oldslope != mo->standingslope) { // First, compare different slopes
|
||||
if (oldslope != mo->standingslope)
|
||||
{
|
||||
// First, compare different slopes
|
||||
angle_t oldangle, newangle;
|
||||
angle_t moveangle = K_MomentumAngle(mo);
|
||||
|
||||
|
|
@ -1773,7 +1781,9 @@ void P_XYMovement(mobj_t *mo)
|
|||
newangle = 0;
|
||||
|
||||
// Now compare the Zs of the different quantizations
|
||||
if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later
|
||||
if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180)
|
||||
{
|
||||
// Allow for a bit of sticking - this value can be adjusted later
|
||||
mo->standingslope = oldslope;
|
||||
P_SetPitchRollFromSlope(mo, mo->standingslope);
|
||||
P_SlopeLaunch(mo);
|
||||
|
|
@ -1781,26 +1791,37 @@ void P_XYMovement(mobj_t *mo)
|
|||
//CONS_Printf("launched off of slope - ");
|
||||
}
|
||||
|
||||
/*CONS_Printf("old angle %f - new angle %f = %f\n",
|
||||
/*
|
||||
CONS_Printf("old angle %f - new angle %f = %f\n",
|
||||
FIXED_TO_FLOAT(AngleFixed(oldangle)),
|
||||
FIXED_TO_FLOAT(AngleFixed(newangle)),
|
||||
FIXED_TO_FLOAT(AngleFixed(oldangle-newangle))
|
||||
);*/
|
||||
// Sryder 2018-11-26: Don't launch here if it's a slope without physics, we stick to those like glue anyway
|
||||
} else if (predictedz-mo->z > abs(slopemom.z/2)
|
||||
&& !(mo->standingslope->flags & SL_NOPHYSICS)) { // Now check if we were supposed to stick to this slope
|
||||
);
|
||||
*/
|
||||
|
||||
}
|
||||
else if (predictedz - mo->z > abs(slopemom.z/2)
|
||||
&& P_CanApplySlopePhysics(mo, mo->standingslope) == true) // Sryder 2018-11-26: Don't launch here if it's a slope without physics, we stick to those like glue anyway
|
||||
{
|
||||
// Now check if we were supposed to stick to this slope
|
||||
//CONS_Printf("%d-%d > %d\n", (predictedz), (mo->z), (slopemom.z/2));
|
||||
P_SlopeLaunch(mo);
|
||||
}
|
||||
} else if (moved && mo->standingslope && predictedz) {
|
||||
}
|
||||
else if (moved && mo->standingslope && predictedz)
|
||||
{
|
||||
angle_t moveangle = K_MomentumAngle(mo);
|
||||
angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT));
|
||||
|
||||
/*CONS_Printf("flat to angle %f - predicted z of %f\n",
|
||||
/*
|
||||
CONS_Printf("flat to angle %f - predicted z of %f\n",
|
||||
FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)),
|
||||
FIXED_TO_FLOAT(predictedz)
|
||||
);*/
|
||||
if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) {
|
||||
);
|
||||
*/
|
||||
|
||||
if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180)
|
||||
{
|
||||
mo->momz = P_MobjFlip(mo)*FRACUNIT/2;
|
||||
mo->z = predictedz + P_MobjFlip(mo);
|
||||
mo->standingslope = NULL;
|
||||
|
|
|
|||
|
|
@ -280,6 +280,8 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEFIXED(save_p, players[i].spindashspeed);
|
||||
WRITEUINT8(save_p, players[i].spindashboost);
|
||||
|
||||
WRITEFIXED(save_p, players[i].fastfall);
|
||||
|
||||
WRITEUINT8(save_p, players[i].numboosts);
|
||||
WRITEFIXED(save_p, players[i].boostpower);
|
||||
WRITEFIXED(save_p, players[i].speedboost);
|
||||
|
|
@ -565,6 +567,8 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].spindashspeed = READFIXED(save_p);
|
||||
players[i].spindashboost = READUINT8(save_p);
|
||||
|
||||
players[i].fastfall = READFIXED(save_p);
|
||||
|
||||
players[i].numboosts = READUINT8(save_p);
|
||||
players[i].boostpower = READFIXED(save_p);
|
||||
players[i].speedboost = READFIXED(save_p);
|
||||
|
|
|
|||
104
src/p_slopes.c
104
src/p_slopes.c
|
|
@ -894,6 +894,40 @@ fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y)
|
|||
return light->slope ? P_GetSlopeZAt(light->slope, x, y) : light->height;
|
||||
}
|
||||
|
||||
// Returns true if we should run slope physics code on an object.
|
||||
boolean P_CanApplySlopePhysics(mobj_t *mo, pslope_t *slope)
|
||||
{
|
||||
if (slope == NULL || mo == NULL || P_MobjWasRemoved(mo) == true)
|
||||
{
|
||||
// Invalid input.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (slope->flags & SL_NOPHYSICS)
|
||||
{
|
||||
// Physics are turned off.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (slope->normal.x == 0 && slope->normal.y == 0)
|
||||
{
|
||||
// Flat slope? No such thing, man. No such thing.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mo->player != NULL)
|
||||
{
|
||||
if (K_PlayerEBrake(mo->player) == true)
|
||||
{
|
||||
// Spindash negates slopes.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// We can do slope physics.
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// P_QuantizeMomentumToSlope
|
||||
//
|
||||
|
|
@ -923,19 +957,13 @@ void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
|
|||
slope->zangle = InvAngle(slope->zangle);
|
||||
}
|
||||
|
||||
// SRB2Kart: This fixes all slope-based jumps for different scales in Kart automatically without map tweaking.
|
||||
// However, they will always feel off every single time... see for yourself: https://cdn.discordapp.com/attachments/270211093761097728/484924392128774165/kart0181.gif
|
||||
//#define GROWNEVERMISSES
|
||||
|
||||
//
|
||||
// P_SlopeLaunch
|
||||
//
|
||||
// Handles slope ejection for objects
|
||||
void P_SlopeLaunch(mobj_t *mo)
|
||||
{
|
||||
if (!(mo->standingslope->flags & SL_NOPHYSICS) // If there's physics, time for launching.
|
||||
&& (mo->standingslope->normal.x != 0
|
||||
|| mo->standingslope->normal.y != 0))
|
||||
if (P_CanApplySlopePhysics(mo, mo->standingslope) == true) // If there's physics, time for launching.
|
||||
{
|
||||
// Double the pre-rotation Z, then halve the post-rotation Z. This reduces the
|
||||
// vertical launch given from slopes while increasing the horizontal launch
|
||||
|
|
@ -946,19 +974,9 @@ void P_SlopeLaunch(mobj_t *mo)
|
|||
slopemom.z = mo->momz;
|
||||
P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
|
||||
|
||||
#ifdef GROWNEVERMISSES
|
||||
{
|
||||
const fixed_t xyscale = mapobjectscale + (mapobjectscale - mo->scale);
|
||||
const fixed_t zscale = mapobjectscale + (mapobjectscale - mo->scale);
|
||||
mo->momx = FixedMul(slopemom.x, xyscale);
|
||||
mo->momy = FixedMul(slopemom.y, xyscale);
|
||||
mo->momz = FixedMul(slopemom.z, zscale);
|
||||
}
|
||||
#else
|
||||
mo->momx = slopemom.x;
|
||||
mo->momy = slopemom.y;
|
||||
mo->momz = slopemom.z;
|
||||
#endif
|
||||
|
||||
mo->eflags |= MFE_SLOPELAUNCHED;
|
||||
}
|
||||
|
|
@ -984,14 +1002,19 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope)
|
|||
vector3_t slopemom, axis;
|
||||
angle_t ang;
|
||||
|
||||
if (mo->standingslope->flags & SL_NOPHYSICS)
|
||||
return 0;
|
||||
if (P_CanApplySlopePhysics(mo, mo->standingslope) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If there's physics, time for launching.
|
||||
// Doesn't kill the vertical momentum as much as P_SlopeLaunch does.
|
||||
ang = slope->zangle + ANG15*((slope->zangle > 0) ? 1 : -1);
|
||||
if (ang > ANGLE_90 && ang < ANGLE_180)
|
||||
ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards
|
||||
{
|
||||
// hard cap of directly upwards
|
||||
ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90));
|
||||
}
|
||||
|
||||
slopemom.x = mo->momx;
|
||||
slopemom.y = mo->momy;
|
||||
|
|
@ -1010,13 +1033,16 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope)
|
|||
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
||||
{
|
||||
vector3_t mom; // Ditto.
|
||||
if (slope->flags & SL_NOPHYSICS || (slope->normal.x == 0 && slope->normal.y == 0)) { // No physics, no need to make anything complicated.
|
||||
|
||||
if (P_CanApplySlopePhysics(thing, slope) == false) // No physics, no need to make anything complicated.
|
||||
{
|
||||
if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope
|
||||
{
|
||||
thing->standingslope = slope;
|
||||
P_SetPitchRollFromSlope(thing, slope);
|
||||
thing->momz = -P_MobjFlip(thing);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1026,7 +1052,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
|||
|
||||
P_ReverseQuantizeMomentumToSlope(&mom, slope);
|
||||
|
||||
if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope
|
||||
if (P_MobjFlip(thing)*mom.z < 0)
|
||||
{
|
||||
// falling, land on slope
|
||||
thing->momx = mom.x;
|
||||
thing->momy = mom.y;
|
||||
thing->standingslope = slope;
|
||||
|
|
@ -1041,27 +1069,29 @@ void P_ButteredSlope(mobj_t *mo)
|
|||
{
|
||||
fixed_t thrust;
|
||||
|
||||
if (!mo->standingslope)
|
||||
return;
|
||||
|
||||
if (mo->standingslope->flags & SL_NOPHYSICS)
|
||||
return; // No physics, no butter.
|
||||
|
||||
if (mo->flags & (MF_NOCLIPHEIGHT|MF_NOGRAVITY))
|
||||
return; // don't slide down slopes if you can't touch them or you're not affected by gravity
|
||||
|
||||
if (mo->player) {
|
||||
// SRB2Kart - spindash negates slopes
|
||||
if (K_PlayerEBrake(mo->player))
|
||||
return;
|
||||
if (P_CanApplySlopePhysics(mo, mo->standingslope) == false)
|
||||
return; // No physics, no butter.
|
||||
|
||||
// Changed in kart to only not apply physics on very slight slopes (I think about 4 degree angles)
|
||||
if (mo->player != NULL)
|
||||
{
|
||||
if (abs(mo->standingslope->zdelta) < FRACUNIT/21)
|
||||
return; // Don't slide on non-steep slopes
|
||||
{
|
||||
// Don't slide on non-steep slopes.
|
||||
// Changed in Ring Racers to only not apply physics on very slight slopes.
|
||||
// (I think about 4 degree angles.)
|
||||
return;
|
||||
}
|
||||
|
||||
// This only means you can be stopped on slopes that aren't steeper than 45 degrees
|
||||
if (abs(mo->standingslope->zdelta) < FRACUNIT/2 && !(mo->player->rmomx || mo->player->rmomy))
|
||||
return; // Allow the player to stand still on slopes below a certain steepness
|
||||
if (abs(mo->standingslope->zdelta) < FRACUNIT/2
|
||||
&& !(mo->player->rmomx || mo->player->rmomy))
|
||||
{
|
||||
// Allow the player to stand still on slopes below a certain steepness.
|
||||
// 45 degree angle steep, to be exact.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 5 / 4 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ fixed_t P_GetFFloorBottomZAt(const ffloor_t *ffloor, fixed_t x, fixed_t y);
|
|||
fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y);
|
||||
|
||||
// Lots of physics-based bullshit
|
||||
boolean P_CanApplySlopePhysics(mobj_t *mo, pslope_t *slope);
|
||||
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
|
||||
void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
|
||||
void P_SlopeLaunch(mobj_t *mo);
|
||||
|
|
|
|||
22
src/p_user.c
22
src/p_user.c
|
|
@ -1905,17 +1905,27 @@ static void P_3dMovement(player_t *player)
|
|||
}
|
||||
|
||||
if ((totalthrust.x || totalthrust.y)
|
||||
&& player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
|
||||
&& player->mo->standingslope != NULL
|
||||
&& (!(player->mo->standingslope->flags & SL_NOPHYSICS))
|
||||
&& abs(player->mo->standingslope->zdelta) > FRACUNIT/2)
|
||||
{
|
||||
// Factor thrust to slope, but only for the part pushing up it!
|
||||
// The rest is unaffected.
|
||||
angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection;
|
||||
angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y) - player->mo->standingslope->xydirection;
|
||||
|
||||
if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward
|
||||
if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) {
|
||||
if (player->mo->standingslope->zdelta < 0)
|
||||
{
|
||||
// Direction goes down, so thrustangle needs to face toward
|
||||
if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270)
|
||||
{
|
||||
P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
|
||||
}
|
||||
} else { // Direction goes up, so thrustangle needs to face away
|
||||
if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270) {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Direction goes up, so thrustangle needs to face away
|
||||
if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270)
|
||||
{
|
||||
P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1112,6 +1112,8 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
// SRB2kart - Grow/invinc clash
|
||||
{"parry", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SF_X8AWAYSOUND
|
||||
|
||||
{"ffbonc", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
||||
// SRB2Kart - Engine sounds
|
||||
// Engine class A
|
||||
{"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
|
|
|||
|
|
@ -1176,6 +1176,9 @@ typedef enum
|
|||
// SRB2Kart - Powerup clash SFX
|
||||
sfx_parry,
|
||||
|
||||
// Fast fall bounce
|
||||
sfx_ffbonc,
|
||||
|
||||
// Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy...
|
||||
// Engine class A - Low Speed, Low Weight
|
||||
sfx_krta00,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue