Improvements related to slope collision, and quantize momentum properly for landing

This commit is contained in:
RedEnchilada 2015-05-13 16:15:32 -05:00
parent 371e23d55d
commit a3358479f0
4 changed files with 46 additions and 6 deletions

View file

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

View file

@ -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),

View file

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

View file

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