From 3a4a687da06275d59b29b1a0e9ad8dc61652556b Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 14 Oct 2020 21:10:02 -0700 Subject: [PATCH] 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. --- src/p_map.c | 27 +++++++++++++++--- src/p_maputl.c | 74 +++++++++++++++++++++++++++----------------------- src/p_maputl.h | 2 ++ src/p_mobj.h | 2 ++ 4 files changed, 67 insertions(+), 38 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index c6044c6f9..4d4a7ea67 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -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) { diff --git a/src/p_maputl.c b/src/p_maputl.c index 12365067a..cbb06dfe3 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -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) diff --git a/src/p_maputl.h b/src/p_maputl.h index 1a885c586..237170bac 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -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); diff --git a/src/p_mobj.h b/src/p_mobj.h index eaf97c441..cd0cc3bc7 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -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;