Merge branch 'the-big-step-up' into 'the-scary-22-merge'

Fix steep slope jank

See merge request KartKrew/Kart!318
This commit is contained in:
Sal 2020-10-18 01:20:19 -04:00
commit 08dc784c17
4 changed files with 184 additions and 46 deletions

View file

@ -58,6 +58,8 @@ mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz
mobj_t *tmhitthing; // the solid thing you bumped into (for collisions) mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
ffloor_t *tmfloorrover, *tmceilingrover; ffloor_t *tmfloorrover, *tmceilingrover;
pslope_t *tmfloorslope, *tmceilingslope; pslope_t *tmfloorslope, *tmceilingslope;
static fixed_t tmfloorstep;
static fixed_t tmceilingstep;
// keep track of the line that lowers the ceiling, // keep track of the line that lowers the ceiling,
// so missiles don't explode against sky hack walls // so missiles don't explode against sky hack walls
@ -1618,6 +1620,8 @@ static boolean PIT_CheckCameraLine(line_t *ld)
// //
static boolean PIT_CheckLine(line_t *ld) static boolean PIT_CheckLine(line_t *ld)
{ {
const fixed_t thingtop = tmthing->z + tmthing->height;
if (ld->polyobj && !(ld->polyobj->flags & POF_SOLID)) if (ld->polyobj && !(ld->polyobj->flags & POF_SOLID))
return true; return true;
@ -1704,6 +1708,11 @@ static boolean PIT_CheckLine(line_t *ld)
ceilingline = ld; ceilingline = ld;
tmceilingrover = openceilingrover; tmceilingrover = openceilingrover;
tmceilingslope = opentopslope; tmceilingslope = opentopslope;
tmceilingstep = openceilingstep;
if (thingtop == tmthing->ceilingz)
{
tmthing->ceilingdrop = openceilingdrop;
}
} }
if (openbottom > tmfloorz) if (openbottom > tmfloorz)
@ -1711,6 +1720,11 @@ static boolean PIT_CheckLine(line_t *ld)
tmfloorz = openbottom; tmfloorz = openbottom;
tmfloorrover = openfloorrover; tmfloorrover = openfloorrover;
tmfloorslope = openbottomslope; tmfloorslope = openbottomslope;
tmfloorstep = openfloorstep;
if (tmthing->z == tmthing->floorz)
{
tmthing->floordrop = openfloordrop;
}
} }
if (highceiling > tmdrpoffceilz) if (highceiling > tmdrpoffceilz)
@ -1765,6 +1779,7 @@ static boolean PIT_CheckLine(line_t *ld)
// //
boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
{ {
INT32 thingtop = thing->z + thing->height;
INT32 xl, xh, yl, yh, bx, by; INT32 xl, xh, yl, yh, bx, by;
subsector_t *newsubsec; subsector_t *newsubsec;
boolean blockval = true; boolean blockval = true;
@ -1800,12 +1815,24 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmfloorslope = newsubsec->sector->f_slope; tmfloorslope = newsubsec->sector->f_slope;
tmceilingslope = newsubsec->sector->c_slope; tmceilingslope = newsubsec->sector->c_slope;
tmfloorstep = 0;
tmceilingstep = 0;
if (thingtop < thing->ceilingz)
{
thing->ceilingdrop = 0;
}
if (thing->z > thing->floorz)
{
thing->floordrop = 0;
}
// Check list of fake floors and see if tmfloorz/tmceilingz need to be altered. // Check list of fake floors and see if tmfloorz/tmceilingz need to be altered.
if (newsubsec->sector->ffloors) if (newsubsec->sector->ffloors)
{ {
ffloor_t *rover; ffloor_t *rover;
fixed_t delta1, delta2; fixed_t delta1, delta2;
INT32 thingtop = thing->z + thing->height;
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next) for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{ {
@ -1937,7 +1964,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (po->validcount != validcount) // if polyobj hasn't been checked if (po->validcount != validcount) // if polyobj hasn't been checked
{ {
sector_t *polysec; sector_t *polysec;
fixed_t delta1, delta2, thingtop; fixed_t delta1, delta2;
fixed_t polytop, polybottom; fixed_t polytop, polybottom;
po->validcount = validcount; po->validcount = validcount;
@ -1963,7 +1990,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
polybottom = INT32_MIN; polybottom = INT32_MIN;
} }
thingtop = thing->z + thing->height;
delta1 = thing->z - (polybottom + ((polytop - polybottom)/2)); delta1 = thing->z - (polybottom + ((polytop - polybottom)/2));
delta2 = thingtop - (polybottom + ((polytop - polybottom)/2)); delta2 = thingtop - (polybottom + ((polytop - polybottom)/2));
@ -2511,26 +2537,28 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thing->eflags & MFE_VERTICALFLIP) 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->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->ceilingrover = tmceilingrover; thing->ceilingrover = tmceilingrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
thing->ceilingdrop = 0;
} }
else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) else if (tmceilingz < thingtop && tmceilingstep <= maxstep)
{ {
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->ceilingrover = tmceilingrover; thing->ceilingrover = tmceilingrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; 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->z = thing->floorz = tmfloorz;
thing->floorrover = tmfloorrover; thing->floorrover = tmfloorrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
thing->floordrop = 0;
} }
else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) else if (tmfloorz > thing->z && tmfloorstep <= maxstep)
{ {
thing->z = thing->floorz = tmfloorz; thing->z = thing->floorz = tmfloorz;
thing->floorrover = tmfloorrover; thing->floorrover = tmfloorrover;

View file

@ -279,6 +279,10 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1)
fixed_t opentop, openbottom, openrange, lowfloor, highceiling; fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
pslope_t *opentopslope, *openbottomslope; pslope_t *opentopslope, *openbottomslope;
ffloor_t *openfloorrover, *openceilingrover; ffloor_t *openfloorrover, *openceilingrover;
fixed_t openceilingstep;
fixed_t openceilingdrop;
fixed_t openfloorstep;
fixed_t openfloordrop;
// P_CameraLineOpening // P_CameraLineOpening
// P_LineOpening, but for camera // P_LineOpening, but for camera
@ -423,7 +427,18 @@ void P_CameraLineOpening(line_t *linedef)
void P_LineOpening(line_t *linedef, mobj_t *mobj) void P_LineOpening(line_t *linedef, mobj_t *mobj)
{ {
enum { FRONT, BACK };
sector_t *front, *back; sector_t *front, *back;
fixed_t thingtop = 0;
vertex_t cross;
/* these init to shut compiler up */
fixed_t topedge[2] = {0};
fixed_t botedge[2] = {0};
int hi = 0;
int lo = 0;
if (linedef->sidenum[1] == 0xffff) if (linedef->sidenum[1] == 0xffff)
{ {
@ -432,6 +447,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
return; return;
} }
P_ClosestPointOnLine(tmx, tmy, linedef, &cross);
// Treat polyobjects kind of like 3D Floors // Treat polyobjects kind of like 3D Floors
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT))
{ {
@ -447,6 +464,11 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
I_Assert(front != NULL); I_Assert(front != NULL);
I_Assert(back != NULL); I_Assert(back != NULL);
if (mobj)
{
thingtop = mobj->z + mobj->height;
}
openfloorrover = openceilingrover = NULL; openfloorrover = openceilingrover = NULL;
if (linedef->polyobj) if (linedef->polyobj)
{ {
@ -456,48 +478,57 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
highceiling = INT32_MIN; highceiling = INT32_MIN;
lowfloor = INT32_MAX; lowfloor = INT32_MAX;
opentopslope = openbottomslope = NULL; opentopslope = openbottomslope = NULL;
openceilingstep = 0;
openceilingdrop = 0;
openfloorstep = 0;
openfloordrop = 0;
} }
else else
{ // Set open and high/low values here { // Set open and high/low values here
fixed_t frontheight, backheight; fixed_t height[2];
const sector_t * sector[2] = { front, back };
frontheight = P_GetCeilingZ(mobj, front, tmx, tmy, linedef); height[FRONT] = P_GetCeilingZ(mobj, front, tmx, tmy, linedef);
backheight = P_GetCeilingZ(mobj, back, tmx, tmy, linedef); height[BACK] = P_GetCeilingZ(mobj, back, tmx, tmy, linedef);
if (frontheight < backheight) hi = ( height[0] < height[1] );
lo = ! hi;
opentop = height[lo];
highceiling = height[hi];
opentopslope = sector[lo]->c_slope;
if (mobj)
{ {
opentop = frontheight; topedge[FRONT] = P_GetSectorCeilingZAt(front, cross.x, cross.y);
highceiling = backheight; topedge[BACK] = P_GetSectorCeilingZAt(back, cross.x, cross.y);
opentopslope = front->c_slope;
} openceilingstep = ( thingtop - topedge[lo] );
else openceilingdrop = ( topedge[hi] - topedge[lo] );
{
opentop = backheight;
highceiling = frontheight;
opentopslope = back->c_slope;
} }
frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef); height[FRONT] = P_GetFloorZ(mobj, front, tmx, tmy, linedef);
backheight = P_GetFloorZ(mobj, back, tmx, tmy, linedef); height[BACK] = P_GetFloorZ(mobj, back, tmx, tmy, linedef);
if (frontheight > backheight) hi = ( height[0] < height[1] );
lo = ! hi;
openbottom = height[hi];
lowfloor = height[lo];
openbottomslope = sector[hi]->f_slope;
if (mobj)
{ {
openbottom = frontheight; botedge[FRONT] = P_GetSectorFloorZAt(front, cross.x, cross.y);
lowfloor = backheight; botedge[BACK] = P_GetSectorFloorZAt(back, cross.x, cross.y);
openbottomslope = front->f_slope;
} openfloorstep = ( botedge[hi] - mobj->z );
else openfloordrop = ( botedge[hi] - botedge[lo] );
{
openbottom = backheight;
lowfloor = frontheight;
openbottomslope = back->f_slope;
} }
} }
if (mobj) if (mobj)
{ {
fixed_t thingtop = mobj->z + mobj->height;
// Check for collision with front side's midtexture if Effect 4 is set // Check for collision with front side's midtexture if Effect 4 is set
if (linedef->flags & ML_EFFECT4 if (linedef->flags & ML_EFFECT4
&& !linedef->polyobj // don't do anything for polyobjects! ...for now && !linedef->polyobj // don't do anything for polyobjects! ...for now
@ -548,10 +579,22 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 > delta2) { // Below if (delta1 > delta2) { // Below
if (opentop > texbottom) if (opentop > texbottom)
{
topedge[lo] -= ( opentop - texbottom );
opentop = texbottom; opentop = texbottom;
openceilingstep = ( thingtop - topedge[lo] );
openceilingdrop = ( topedge[hi] - topedge[lo] );
}
} else { // Above } else { // Above
if (openbottom < textop) if (openbottom < textop)
{
botedge[hi] += ( textop - openbottom );
openbottom = textop; openbottom = textop;
openfloorstep = ( botedge[hi] - mobj->z );
openfloordrop = ( botedge[hi] - botedge[lo] );
}
} }
} }
} }
@ -579,14 +622,22 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
delta2 = abs(thingtop - (polybottom + ((polytop - polybottom)/2))); delta2 = abs(thingtop - (polybottom + ((polytop - polybottom)/2)));
if (polybottom < opentop && delta1 >= delta2) if (polybottom < opentop && delta1 >= delta2)
{
opentop = polybottom; opentop = polybottom;
}
else if (polybottom < highceiling && delta1 >= delta2) else if (polybottom < highceiling && delta1 >= delta2)
{
highceiling = polybottom; highceiling = polybottom;
}
if (polytop > openbottom && delta1 < delta2) if (polytop > openbottom && delta1 < delta2)
{
openbottom = polytop; openbottom = polytop;
}
else if (polytop > lowfloor && delta1 < delta2) else if (polytop > lowfloor && delta1 < delta2)
{
lowfloor = polytop; lowfloor = polytop;
}
} }
// otherwise don't do anything special, pretend there's nothing else there // otherwise don't do anything special, pretend there's nothing else there
} }
@ -598,6 +649,21 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
ffloor_t *rover; ffloor_t *rover;
fixed_t delta1, delta2; fixed_t delta1, delta2;
/* yuck */
struct
{
fixed_t top;
fixed_t bottom;
ffloor_t * ceilingrover;
ffloor_t * floorrover;
} open[2] = {
{ INT32_MAX, INT32_MIN, NULL, NULL },
{ INT32_MAX, INT32_MIN, NULL, NULL },
};
const fixed_t oldopentop = opentop;
const fixed_t oldopenbottom = openbottom;
// Check for frontsector's fake floors // Check for frontsector's fake floors
for (rover = front->ffloors; rover; rover = rover->next) for (rover = front->ffloors; rover; rover = rover->next)
{ {
@ -619,10 +685,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{ {
if (bottomheight < opentop) { if (bottomheight < open[FRONT].top) {
opentop = bottomheight; open[FRONT].top = bottomheight;
opentopslope = *rover->b_slope; opentopslope = *rover->b_slope;
openceilingrover = rover; open[FRONT].ceilingrover = rover;
} }
else if (bottomheight < highceiling) else if (bottomheight < highceiling)
highceiling = bottomheight; highceiling = bottomheight;
@ -630,10 +696,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
{ {
if (topheight > openbottom) { if (topheight > open[FRONT].bottom) {
openbottom = topheight; open[FRONT].bottom = topheight;
openbottomslope = *rover->t_slope; openbottomslope = *rover->t_slope;
openfloorrover = rover; open[FRONT].floorrover = rover;
} }
else if (topheight > lowfloor) else if (topheight > lowfloor)
lowfloor = topheight; lowfloor = topheight;
@ -661,10 +727,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{ {
if (bottomheight < opentop) { if (bottomheight < open[BACK].top) {
opentop = bottomheight; open[BACK].top = bottomheight;
opentopslope = *rover->b_slope; opentopslope = *rover->b_slope;
openceilingrover = rover; open[BACK].ceilingrover = rover;
} }
else if (bottomheight < highceiling) else if (bottomheight < highceiling)
highceiling = bottomheight; highceiling = bottomheight;
@ -672,15 +738,53 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
{ {
if (topheight > openbottom) { if (topheight > open[BACK].bottom) {
openbottom = topheight; open[BACK].bottom = topheight;
openbottomslope = *rover->t_slope; openbottomslope = *rover->t_slope;
openfloorrover = rover; open[BACK].floorrover = rover;
} }
else if (topheight > lowfloor) else if (topheight > lowfloor)
lowfloor = topheight; lowfloor = topheight;
} }
} }
lo = ( open[0].top > open[1].top );
if (open[lo].top <= oldopentop)
{
hi = ! lo;
topedge[lo] = P_GetFFloorBottomZAt(open[lo].ceilingrover, cross.x, cross.y);
if (open[hi].top < oldopentop)
{
topedge[hi] = P_GetFFloorBottomZAt(open[hi].ceilingrover, cross.x, cross.y);
}
opentop = open[lo].top;
openceilingrover = open[lo].ceilingrover;
openceilingstep = ( thingtop - topedge[lo] );
openceilingdrop = ( topedge[hi] - topedge[lo] );
}
hi = ( open[0].bottom < open[1].bottom );
if (open[hi].bottom >= oldopenbottom)
{
lo = ! hi;
botedge[hi] = P_GetFFloorTopZAt(open[hi].floorrover, cross.x, cross.y);
if (open[lo].bottom > oldopenbottom)
{
botedge[lo] = P_GetFFloorTopZAt(open[lo].floorrover, cross.x, cross.y);
}
openbottom = open[hi].bottom;
openfloorrover = open[hi].floorrover;
openfloorstep = ( botedge[hi] - mobj->z );
openfloordrop = ( botedge[hi] - botedge[lo] );
}
} }
} }
} }

View file

@ -58,6 +58,10 @@ void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_
extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
extern pslope_t *opentopslope, *openbottomslope; extern pslope_t *opentopslope, *openbottomslope;
extern ffloor_t *openfloorrover, *openceilingrover; extern ffloor_t *openfloorrover, *openceilingrover;
extern fixed_t openceilingstep;
extern fixed_t openceilingdrop;
extern fixed_t openfloorstep;
extern fixed_t openfloordrop;
void P_LineOpening(line_t *plinedef, mobj_t *mobj); 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. fixed_t ceilingz; // Nearest ceiling above.
struct ffloor_s *floorrover; // FOF referred by floorz struct ffloor_s *floorrover; // FOF referred by floorz
struct ffloor_s *ceilingrover; // FOF referred by ceilingz struct ffloor_s *ceilingrover; // FOF referred by ceilingz
fixed_t floordrop;
fixed_t ceilingdrop;
// For movement checking. // For movement checking.
fixed_t radius; fixed_t radius;