Use height difference between front and backside of line when stepping down

This should fix the janky falling off steep slopes and let you cling to them.
Because when falling off a sector the edge of the player must not intersect
the edge of the higher sector, it is trickier than step up. The height
difference at the line must be stored to be useful.
This commit is contained in:
James R 2020-10-14 21:10:02 -07:00
parent dab116a0bd
commit 3a4a687da0
4 changed files with 67 additions and 38 deletions

View file

@ -1707,6 +1707,7 @@ static boolean PIT_CheckLine(line_t *ld)
tmceilingrover = openceilingrover;
tmceilingslope = opentopslope;
tmceilingdiff = openceilingdiff;
tmthing->ceilingdrop = openceilingdrop;
}
if (openbottom > tmfloorz)
@ -1715,6 +1716,7 @@ static boolean PIT_CheckLine(line_t *ld)
tmfloorrover = openfloorrover;
tmfloorslope = openbottomslope;
tmfloordiff = openfloordiff;
tmthing->floordrop = openfloordrop;
}
if (highceiling > tmdrpoffceilz)
@ -2505,10 +2507,25 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thing->eflags & MFE_VERTICALFLIP)
{
if (thing->z < tmfloorz)
{
return false; // mobj must raise itself to fit
}
else if (thing->z > thing->floorz)
{
thing->floordrop = 0;
}
}
else
{
if (tmceilingz < thingtop)
{
return false; // mobj must lower itself to fit
}
else if (thingtop < thing->ceilingz)
{
thing->ceilingdrop = 0;
}
}
else if (tmceilingz < thingtop)
return false; // mobj must lower itself to fit
// Ramp test
if ((maxstep > 0) && !(P_MobjTouchingSectorSpecial(thing, 1, 14, false)))
@ -2518,11 +2535,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thing->eflags & MFE_VERTICALFLIP)
{
if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep)
if (thingtop == thing->ceilingz && tmceilingz > thingtop && thing->ceilingdrop <= maxstep)
{
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->ceilingrover = tmceilingrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
thing->ceilingdrop = 0;
}
else if (tmceilingz < thingtop && tmceilingdiff <= maxstep)
{
@ -2531,11 +2549,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
}
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->floordrop <= maxstep)
{
thing->z = thing->floorz = tmfloorz;
thing->floorrover = tmfloorrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
thing->floordrop = 0;
}
else if (tmfloorz > thing->z && tmfloordiff <= maxstep)
{

View file

@ -281,6 +281,8 @@ pslope_t *opentopslope, *openbottomslope;
ffloor_t *openfloorrover, *openceilingrover;
fixed_t openfloordiff;
fixed_t openceilingdiff;
fixed_t openfloordrop;
fixed_t openceilingdrop;
// P_CameraLineOpening
// P_LineOpening, but for camera
@ -466,46 +468,50 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
}
else
{ // Set open and high/low values here
fixed_t frontheight, backheight;
sector_t * sector;
fixed_t height[2];
const sector_t * sector[2] = { front, back };
frontheight = P_GetCeilingZ(mobj, front, tmx, tmy, linedef);
backheight = P_GetCeilingZ(mobj, back, tmx, tmy, linedef);
int high;
if (frontheight < backheight)
{
opentop = frontheight;
highceiling = backheight;
sector = front;
}
else
{
opentop = backheight;
highceiling = frontheight;
sector = back;
}
#define low ! high
opentopslope = sector->c_slope;
openceilingdiff = ( mobj->z + mobj->height - P_GetSectorCeilingZAt(sector, cross.x, cross.y) );
height[0] = P_GetCeilingZ(mobj, front, tmx, tmy, linedef);
height[1] = P_GetCeilingZ(mobj, back, tmx, tmy, linedef);
frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef);
backheight = P_GetFloorZ(mobj, back, tmx, tmy, linedef);
high = ( height[0] < height[1] );
if (frontheight > backheight)
{
openbottom = frontheight;
lowfloor = backheight;
sector = front;
}
else
{
openbottom = backheight;
lowfloor = frontheight;
sector = back;
}
opentop = height[low];
highceiling = height[high];
opentopslope = sector[low]->c_slope;
openbottomslope = sector->f_slope;
openfloordiff = ( P_GetSectorFloorZAt(sector, cross.x, cross.y) - mobj->z );
openceilingdiff = ( mobj->z + mobj->height -
P_GetSectorCeilingZAt(sector[low], cross.x, cross.y) );
openceilingdrop =
(
P_GetSectorCeilingZAt(sector[high], cross.x, cross.y) -
P_GetSectorCeilingZAt(sector[low], cross.x, cross.y)
);
height[0] = P_GetFloorZ(mobj, front, tmx, tmy, linedef);
height[1] = P_GetFloorZ(mobj, back, tmx, tmy, linedef);
high = ( height[0] < height[1] );
openbottom = height[high];
lowfloor = height[low];
openbottomslope = sector[high]->f_slope;
openfloordiff =
( P_GetSectorFloorZAt(sector[high], cross.x, cross.y) - mobj->z );
openfloordrop =
(
P_GetSectorFloorZAt(sector[high], cross.x, cross.y) -
P_GetSectorFloorZAt(sector[low], cross.x, cross.y)
);
#undef low
}
if (mobj)

View file

@ -60,6 +60,8 @@ extern pslope_t *opentopslope, *openbottomslope;
extern ffloor_t *openfloorrover, *openceilingrover;
extern fixed_t openfloordiff;
extern fixed_t openceilingdiff;
extern fixed_t openfloordrop;
extern fixed_t openceilingdrop;
void P_LineOpening(line_t *plinedef, mobj_t *mobj);

View file

@ -326,6 +326,8 @@ typedef struct mobj_s
fixed_t ceilingz; // Nearest ceiling above.
struct ffloor_s *floorrover; // FOF referred by floorz
struct ffloor_s *ceilingrover; // FOF referred by ceilingz
fixed_t floordrop;
fixed_t ceilingdrop;
// For movement checking.
fixed_t radius;