diff --git a/src/p_map.c b/src/p_map.c index 468e2530a..4b74b0f02 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1912,6 +1912,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t tryy = thing->y; fixed_t radius = thing->radius; fixed_t thingtop = thing->z + thing->height; +#ifdef ESLOPE + fixed_t startingonground = P_IsObjectOnGround(thing); +#endif floatok = false; if (radius < MAXRADIUS/2) @@ -2003,7 +2006,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } - else if (thingtop == thing->ceilingz && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) + else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) { thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->eflags |= MFE_JUSTSTEPPEDDOWN; @@ -2014,7 +2017,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->z = thing->floorz = tmfloorz; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } - else if (thing->z == thing->floorz && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) + else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) { thing->z = thing->floorz = tmfloorz; thing->eflags |= MFE_JUSTSTEPPEDDOWN; @@ -2090,10 +2093,20 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) #ifdef ESLOPE // Assign thing's standingslope if needed - if (thing->z <= tmfloorz && thing->momz <= 0 && !(thing->eflags & MFE_VERTICALFLIP)) - thing->standingslope = tmfloorslope; - else if (thing->z+thing->height >= tmceilingz && thing->momz >= 0 && (thing->eflags & MFE_VERTICALFLIP)) - thing->standingslope = tmceilingslope; + if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) { + if (!startingonground && tmfloorslope) + P_HandleSlopeLanding(thing, tmfloorslope); + + if (thing->momz <= 0) + thing->standingslope = tmfloorslope; + } + else if (thing->z+thing->height >= tmceilingz /*&& thing->momz >= 0*/ && (thing->eflags & MFE_VERTICALFLIP)) { + if (!startingonground && tmceilingslope) + P_HandleSlopeLanding(thing, tmceilingslope); + + if (thing->momz >= 0) + thing->standingslope = tmceilingslope; + } #endif thing->x = x; diff --git a/src/p_mobj.c b/src/p_mobj.c index 5af7b99a6..ac193b73e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2344,6 +2344,12 @@ static void P_PlayerZMovement(mobj_t *mo) if (mo->state == &states[mo->info->painstate] || mo->state == &states[S_PLAY_SUPERHIT]) P_SetPlayerMobjState(mo, S_PLAY_STND); +#ifdef ESLOPE + if (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope) + // Handle landing on slope during Z movement + P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)); +#endif + if (P_MobjFlip(mo)*mo->momz < 0) // falling { // Squat down. Decrease viewheight for a moment after hitting the ground (hard), diff --git a/src/p_slopes.c b/src/p_slopes.c index 5891756e8..cf786f1bb 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -805,6 +805,26 @@ void P_SlopeLaunch(mobj_t *mo) mo->standingslope = NULL; } +// Function to help handle landing on slopes +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) +{ + v3fixed_t mom; + mom.x = thing->momx; + mom.y = thing->momy; + mom.z = thing->momz*2; + + // Reverse quantizing might could use its own function later + slope->zangle = ANGLE_MAX-slope->zangle; + P_QuantizeMomentumToSlope(&mom, slope); + slope->zangle = ANGLE_MAX-slope->zangle; + + if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope + thing->momx = mom.x; + thing->momy = mom.y; + thing->momz = -P_MobjFlip(thing); + } +} + // https://yourlogicalfallacyis.com/slippery-slope // Handles sliding down slopes, like if they were made of butter :) void P_ButteredSlope(mobj_t *mo) diff --git a/src/p_slopes.h b/src/p_slopes.h index f82d8a83d..4281d5796 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -79,6 +79,7 @@ float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori, // Lots of physics-based bullshit void P_QuantizeMomentumToSlope(v3fixed_t *momentum, pslope_t *slope); void P_SlopeLaunch(mobj_t *mo); +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); void P_ButteredSlope(mobj_t *mo); #endif