Revert "Revert the-big-step-up since it has regressions"

This reverts commit 515c531d51.
This commit is contained in:
NepDisk 2024-08-24 15:24:40 -04:00
parent 25a9b5cfa9
commit 1264a4c1bc
3 changed files with 191 additions and 208 deletions

View file

@ -1584,6 +1584,11 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld)
tmceilingrover = openceilingrover;
tmceilingslope = opentopslope;
tmceilingpic = opentoppic;
tmceilingstep = openceilingstep;
if (thingtop == tmthing->ceilingz)
{
tmthing->ceilingdrop = openceilingdrop;
}
}
if (openbottom > tmfloorz)
@ -1592,6 +1597,11 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld)
tmfloorrover = openfloorrover;
tmfloorslope = openbottomslope;
tmfloorpic = openbottompic;
tmfloorstep = openfloorstep;
if (tmthing->z == tmthing->floorz)
{
tmthing->floordrop = openfloordrop;
}
}
if (highceiling > tmdrpoffceilz)
@ -2553,149 +2563,15 @@ boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
//
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
fixed_t tryx = thing->x;
fixed_t tryy = thing->y;
fixed_t oldx = tryx;
fixed_t oldy = tryy;
fixed_t radius = thing->radius;
fixed_t thingtop = thing->z + thing->height;
fixed_t oldx = thing->x;
fixed_t oldy = thing->y;
fixed_t startingonground = P_IsObjectOnGround(thing);
floatok = false;
// reset this to 0 at the start of each trymove call as it's only used here
numspechitint = 0U;
// This makes sure that there are no freezes from computing extremely small movements.
// Originally was MAXRADIUS/2, but that causes some inconsistencies for small players.
if (radius < mapobjectscale)
radius = mapobjectscale;
do {
if (thing->flags & MF_NOCLIP) {
tryx = x;
tryy = y;
} else {
if (x-tryx > radius)
tryx += radius;
else if (x-tryx < -radius)
tryx -= radius;
else
tryx = x;
if (y-tryy > radius)
tryy += radius;
else if (y-tryy < -radius)
tryy -= radius;
else
tryy = y;
}
if (!P_CheckPosition(thing, tryx, tryy))
return false; // solid wall or thing
// copy into the spechitint buffer from spechit
spechitint_copyinto();
if (!(thing->flags & MF_NOCLIP))
{
//All things are affected by their scale.
const fixed_t maxstepmove = FixedMul(MAXSTEPMOVE, mapobjectscale);
fixed_t maxstep = maxstepmove;
if (thing->player && thing->player->waterskip)
maxstep += maxstepmove; // Add some extra stepmove when waterskipping
// If using type Section1:13, double the maxstep.
if (P_MobjTouchingSectorSpecial(thing, 1, 13))
maxstep <<= 1;
// If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin
else if (P_MobjTouchingSectorSpecial(thing, 1, 12))
maxstep = 0;
if (thing->type == MT_SKIM)
maxstep = 0;
if (tmceilingz - tmfloorz < thing->height)
{
if (tmfloorthing)
tmhitthing = tmfloorthing;
return false; // doesn't fit
}
floatok = true;
if (thing->eflags & MFE_VERTICALFLIP)
{
if (thing->z < tmfloorz)
return false; // mobj must raise itself to fit
}
else if (tmceilingz < thingtop)
return false; // mobj must lower itself to fit
// Ramp test
if ((maxstep > 0) && !(P_MobjTouchingSectorSpecial(thing, 1, 14)))
{
// If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS
// step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more.
if (thing->eflags & MFE_VERTICALFLIP)
{
if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep)
{
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->ceilingrover = tmceilingrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
{
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->ceilingrover = tmceilingrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
}
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
{
thing->z = thing->floorz = tmfloorz;
thing->floorrover = tmfloorrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
{
thing->z = thing->floorz = tmfloorz;
thing->floorrover = tmfloorrover;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
}
if (thing->eflags & MFE_VERTICALFLIP)
{
if (thingtop - tmceilingz > maxstep)
{
if (tmfloorthing)
tmhitthing = tmfloorthing;
return false; // too big a step up
}
}
else if (tmfloorz - thing->z > maxstep)
{
if (tmfloorthing)
tmhitthing = tmfloorthing;
return false; // too big a step up
}
if (!allowdropoff && !(thing->flags & MF_FLOAT) && thing->type != MT_SKIM && !tmfloorthing)
{
if (thing->eflags & MFE_VERTICALFLIP)
{
if (tmdrpoffceilz - tmceilingz > maxstep)
return false;
}
else if (tmfloorz - tmdropoffz > maxstep)
return false; // don't stand over a dropoff
}
}
} while (tryx != x || tryy != y);
fixed_t stairjank = 0;
pslope_t *oldslope = thing->standingslope;
// The move is ok!
if (!increment_move(thing, x, y, allowdropoff))
return false;
// If it's a pushable object, check if anything is
// standing on top and move it, too.
@ -2730,12 +2606,14 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (!(thing->flags & MF_NOCLIPHEIGHT))
{
// Assign thing's standingslope if needed
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) {
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP))
{
K_UpdateMobjTerrain(thing, tmfloorpic);
if (!startingonground && tmfloorslope)
{
P_HandleSlopeLanding(thing, tmfloorslope);
}
if (thing->momz <= 0)
{
@ -2743,15 +2621,19 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
P_SetPitchRollFromSlope(thing, thing->standingslope);
if (thing->momz == 0 && thing->player && !startingonground)
{
P_PlayerHitFloor(thing->player, true);
}
}
}
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP))
{
K_UpdateMobjTerrain(thing, tmceilingpic);
if (!startingonground && tmceilingslope)
{
P_HandleSlopeLanding(thing, tmceilingslope);
}
if (thing->momz >= 0)
{
@ -2759,15 +2641,19 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
P_SetPitchRollFromSlope(thing, thing->standingslope);
if (thing->momz == 0 && thing->player && !startingonground)
{
P_PlayerHitFloor(thing->player, true);
}
}
}
}
else // don't set standingslope if you're not going to clip against it
else
{
// don't set standingslope if you're not going to clip against it
thing->standingslope = NULL;
thing->terrain = NULL;
}
thing->x = x;
thing->y = y;

View file

@ -338,6 +338,10 @@ line_t * P_FindNearestLine
fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
pslope_t *opentopslope, *openbottomslope;
ffloor_t *openfloorrover, *openceilingrover;
fixed_t openceilingstep;
fixed_t openceilingdrop;
fixed_t openfloorstep;
fixed_t openfloordrop;
INT32 opentoppic, openbottompic;
// P_CameraLineOpening
@ -590,7 +594,18 @@ static boolean P_MidtextureIsSolid(line_t *linedef, mobj_t *mobj)
void P_LineOpening(line_t *linedef, mobj_t *mobj)
{
enum { 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)
{
@ -599,6 +614,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
return;
}
P_ClosestPointOnLine(tmx, tmy, linedef, &cross);
// Treat polyobjects kind of like 3D Floors
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT))
{
@ -614,6 +631,11 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
I_Assert(front != NULL);
I_Assert(back != NULL);
if (mobj)
{
thingtop = mobj->z + mobj->height;
}
openfloorrover = openceilingrover = NULL;
if (linedef->polyobj)
{
@ -624,78 +646,88 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
lowfloor = INT32_MAX;
opentopslope = openbottomslope = NULL;
opentoppic = openbottompic = -1;
openceilingstep = 0;
openceilingdrop = 0;
openfloorstep = 0;
openfloordrop = 0;
}
else
{ // 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);
backheight = P_GetCeilingZ(mobj, back, tmx, tmy, linedef);
height[FRONT] = P_GetCeilingZ(mobj, front, 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;
opentoppic = sector[lo]->ceilingpic;
if (mobj)
{
opentop = frontheight;
highceiling = backheight;
opentopslope = front->c_slope;
}
else
{
opentop = backheight;
highceiling = frontheight;
opentopslope = back->c_slope;
topedge[FRONT] = P_GetSectorCeilingZAt(front, cross.x, cross.y);
topedge[BACK] = P_GetSectorCeilingZAt(back, cross.x, cross.y);
openceilingstep = ( thingtop - topedge[lo] );
openceilingdrop = ( topedge[hi] - topedge[lo] );
}
frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef);
backheight = P_GetFloorZ(mobj, back, tmx, tmy, linedef);
height[FRONT] = P_GetFloorZ(mobj, front, 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;
openbottompic = sector[hi]->floorpic;
if (mobj)
{
openbottom = frontheight;
lowfloor = backheight;
openbottomslope = front->f_slope;
botedge[FRONT] = P_GetSectorFloorZAt(front, cross.x, cross.y);
botedge[BACK] = P_GetSectorFloorZAt(back, cross.x, cross.y);
openfloorstep = ( botedge[hi] - mobj->z );
openfloordrop = ( botedge[hi] - botedge[lo] );
}
else
{
openbottom = backheight;
lowfloor = frontheight;
openbottomslope = back->f_slope;
}
opentoppic = sector[!(frontheight < backheight)]->ceilingpic;
openbottompic = sector[frontheight < backheight]->floorpic;
}
if (mobj)
{
fixed_t thingtop = mobj->z + mobj->height;
// Check for collision with front side's midtexture if Effect 4 is set
if (P_MidtextureIsSolid(linedef, mobj) == true) {
side_t *side = &sides[linedef->sidenum[0]];
fixed_t textop, texbottom, texheight;
fixed_t textop, texbottom;
fixed_t texmid, delta1, delta2;
INT32 texnum = R_GetTextureNum(side->midtexture); // make sure the texture is actually valid
vertex_t cross;
if (texnum) {
// Get the midtexture's height
texheight = textures[texnum]->height << FRACBITS;
P_ClosestPointOnLine(tmx, tmy, linedef, &cross);
if (P_GetMidtextureTopBottom(linedef, cross.x, cross.y, &textop, &texbottom))
{
texmid = texbottom+(textop-texbottom)/2;
if (P_GetMidtextureTopBottom(linedef, cross.x, cross.y, &textop, &texbottom))
{
texmid = texbottom+(textop-texbottom)/2;
delta1 = abs(mobj->z - texmid);
delta2 = abs(thingtop - texmid);
delta1 = abs(mobj->z - texmid);
delta2 = abs(thingtop - texmid);
if (delta1 > delta2) { // Below
if (opentop > texbottom)
opentop = texbottom;
} else { // Above
if (openbottom < textop)
openbottom = textop;
if (delta1 > delta2) { // Below
if (opentop > texbottom)
{
topedge[lo] -= ( opentop - texbottom );
opentop = texbottom;
openceilingstep = ( thingtop - topedge[lo] );
openceilingdrop = ( topedge[hi] - topedge[lo] );
}
} else { // Above
if (openbottom < textop)
{
botedge[hi] += ( textop - openbottom );
openbottom = textop;
openfloorstep = ( botedge[hi] - mobj->z );
openfloordrop = ( botedge[hi] - botedge[lo] );
}
}
}
@ -725,14 +757,22 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
delta2 = abs(thingtop - (polybottom + ((polytop - polybottom)/2)));
if (polybottom < opentop && delta1 >= delta2)
{
opentop = polybottom;
}
else if (polybottom < highceiling && delta1 >= delta2)
{
highceiling = polybottom;
}
if (polytop > openbottom && delta1 < delta2)
{
openbottom = polytop;
}
else if (polytop > lowfloor && delta1 < delta2)
{
lowfloor = polytop;
}
}
// otherwise don't do anything special, pretend there's nothing else there
}
@ -744,6 +784,21 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
ffloor_t *rover;
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
for (rover = front->ffloors; rover; rover = rover->next)
{
@ -765,11 +820,11 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 >= delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
if (bottomheight < open[FRONT].top) {
open[FRONT].top = bottomheight;
opentopslope = *rover->b_slope;
opentoppic = *rover->bottompic;
openceilingrover = rover;
open[FRONT].ceilingrover = rover;
}
else if (bottomheight < highceiling)
highceiling = bottomheight;
@ -777,11 +832,11 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 < delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;
if (topheight > open[FRONT].bottom) {
open[FRONT].bottom = topheight;
openbottomslope = *rover->t_slope;
openbottompic = *rover->toppic;
openfloorrover = rover;
open[FRONT].floorrover = rover;
}
else if (topheight > lowfloor)
lowfloor = topheight;
@ -809,11 +864,11 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 >= delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
if (bottomheight < open[BACK].top) {
open[BACK].top = bottomheight;
opentopslope = *rover->b_slope;
opentoppic = *rover->bottompic;
openceilingrover = rover;
open[BACK].ceilingrover = rover;
}
else if (bottomheight < highceiling)
highceiling = bottomheight;
@ -821,16 +876,54 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (delta1 < delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;
if (topheight > open[BACK].bottom) {
open[BACK].bottom = topheight;
openbottomslope = *rover->t_slope;
openbottompic = *rover->toppic;
openfloorrover = rover;
open[BACK].floorrover = rover;
}
else if (topheight > lowfloor)
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

@ -61,6 +61,10 @@ boolean P_GetMidtextureTopBottom(line_t *linedef, fixed_t x, fixed_t y, fixed_t
extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
extern pslope_t *opentopslope, *openbottomslope;
extern ffloor_t *openfloorrover, *openceilingrover;
extern fixed_t openceilingstep;
extern fixed_t openceilingdrop;
extern fixed_t openfloorstep;
extern fixed_t openfloordrop;
extern INT32 opentoppic, openbottompic;
void P_LineOpening(line_t *plinedef, mobj_t *mobj);