diff --git a/src/p_local.h b/src/p_local.h index f91e1490b..89c9197c4 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -356,7 +356,7 @@ void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab); mobj_t *P_GetClosestAxis(mobj_t *source); boolean P_CanRunOnWater(player_t *player, ffloor_t *rover); -boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover); +boolean P_CheckSolidFFloorSurface(mobj_t *mobj, ffloor_t *rover); void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot); diff --git a/src/p_map.c b/src/p_map.c index 52a1e3971..caa54063f 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1724,6 +1724,10 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld) // tm.ceilingz // the nearest ceiling or thing's bottom over tm.thing // + +static const fixed_t hoopblockdist = 16*FRACUNIT + 8*FRACUNIT; +static const fixed_t hoophalfheight = (56*FRACUNIT)/2; + boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y, TryMoveResult_t *result) { INT32 thingtop = thing->z + thing->height; @@ -1837,11 +1841,11 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y, TryMoveResult_t *re continue; } - if (thing->player && P_CheckSolidFFloorSurface(thing->player, rover)) + if (P_CheckSolidFFloorSurface(thing, rover)) ; else if (thing->type == MT_SKIM && (rover->fofflags & FOF_SWIMMABLE)) ; - else if (!((rover->fofflags & FOF_BLOCKPLAYER && thing->player) + else if (!((rover->fofflags & FOF_BLOCKPLAYER && thing->player) || (rover->fofflags & FOF_BLOCKOTHERS && !thing->player) || rover->fofflags & FOF_QUICKSAND)) continue; @@ -1988,13 +1992,11 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y, TryMoveResult_t *re // reset special lines numspechit = 0U; - if (tm.flags & MF_NOCLIP) - return true; - // Check things first, possibly picking things up. // MF_NOCLIPTHING: used by camera to not be blocked by things - if (!(thing->flags & MF_NOCLIPTHING)) + // Respawning things should also be intangible to other things + if (!(thing->flags & MF_NOCLIPTHING) /*&& !P_MobjIsReappearing(thing)*/) { for (bx = xl; bx <= xh; bx++) { @@ -2017,6 +2019,16 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y, TryMoveResult_t *re } } + if (tm.flags & MF_NOCLIP) + { + // Sal 12/19/2022 -- PIT_CheckThing code will still run + // with MF_NOCLIP enabled, but they won't be blocked + // regardless of the result. This allows for SPBs and + // the UFO to collide. + // ...but be careful about removed obj! ~toast 140423 + return !P_MobjWasRemoved(thing); + } + validcount++; // check lines @@ -2048,9 +2060,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y, TryMoveResult_t *re return blockval; } -static const fixed_t hoopblockdist = 16*FRACUNIT + 8*FRACUNIT; -static const fixed_t hoophalfheight = (56*FRACUNIT)/2; - // P_CheckPosition optimized for the MT_HOOPCOLLIDE object. This needs to be as fast as possible! void P_CheckHoopPosition(mobj_t *hoopthing, fixed_t x, fixed_t y, fixed_t z, fixed_t radius) { diff --git a/src/p_maputl.c b/src/p_maputl.c index 1f23cfb38..f67ed5994 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -611,7 +611,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open) if (mobj) { // Check for collision with front side's midtexture if Effect 4 is set - if (P_MidtextureIsSolid(linedef, mobj) == true) { + if (P_MidtextureIsSolid(linedef, mobj) == true) + { fixed_t textop, texbottom; fixed_t texmid, delta1, delta2; @@ -655,7 +656,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open) if (linedef->polyobj->flags & POF_TESTHEIGHT) { const sector_t *polysec = linedef->backsector; - fixed_t polytop, polybottom; + fixed_t polytop, polybottom, polymid; fixed_t delta1, delta2; if (linedef->polyobj->flags & POF_CLIPPLANES) @@ -669,35 +670,67 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open) polybottom = INT32_MIN; } - delta1 = abs(mobj->z - (polybottom + ((polytop - polybottom)/2))); - delta2 = abs(thingtop - (polybottom + ((polytop - polybottom)/2))); - - if (delta1 > delta2) + switch (open->fofType) { - if (open->fofType != LO_FOF_FLOORS) + case LO_FOF_FLOORS: { - if (polybottom < open->ceiling) + if (mobj->z >= polytop) { - open->ceiling = polybottom; - } - else if (polybottom < open->highceiling) - { - open->highceiling = polybottom; + if (polytop > open->floor) + { + open->floor = polytop; + } + else if (polytop > open->lowfloor) + { + open->lowfloor = polytop; + } } + break; } - } - else - { - if (open->fofType != LO_FOF_CEILINGS) + case LO_FOF_CEILINGS: { - if (polytop > open->floor) + if (thingtop <= polybottom) { - open->floor = polytop; + if (polybottom < open->ceiling) + { + open->ceiling = polybottom; + } + else if (polybottom < open->highceiling) + { + open->highceiling = polybottom; + } } - else if (polytop > open->lowfloor) + break; + } + default: + { + polymid = polybottom + (polytop - polybottom) / 2; + delta1 = abs(mobj->z - polymid); + delta2 = abs(thingtop - polymid); + + if (delta1 > delta2) { - open->lowfloor = polytop; + if (polybottom < open->ceiling) + { + open->ceiling = polybottom; + } + else if (polybottom < open->highceiling) + { + open->highceiling = polybottom; + } } + else + { + if (polytop > open->floor) + { + open->floor = polytop; + } + else if (polytop > open->lowfloor) + { + open->lowfloor = polytop; + } + } + break; } } } @@ -726,11 +759,12 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open) // Check for frontsector's fake floors for (rover = front->ffloors; rover; rover = rover->next) { - fixed_t topheight, bottomheight; + fixed_t topheight, bottomheight, midheight; + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (mobj->player && P_CheckSolidFFloorSurface(mobj->player, rover)) + if (P_CheckSolidFFloorSurface(mobj, rover)) ; else if (!((rover->fofflags & FOF_BLOCKPLAYER && mobj->player) || (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player))) @@ -747,41 +781,69 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open) bottomheight = P_GetFOFBottomZ(mobj, front, rover, tm.x, tm.y, linedef); } - delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); - delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - - if (delta1 > delta2) + switch (open->fofType) { - if (open->fofType == LO_FOF_FLOORS) + case LO_FOF_FLOORS: { - continue; - } - - // thing is below FOF - if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) - { - if (bottomheight < fofopen[FRONT].ceiling) + if (mobj->z >= topheight) { - fofopen[FRONT].ceiling = bottomheight; - fofopen[FRONT].ceilingrover = rover; + if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) + { + if (topheight > fofopen[FRONT].floor) + { + fofopen[FRONT].floor = topheight; + fofopen[FRONT].floorrover = rover; + } + } } + break; } - } - else - { - if (open->fofType == LO_FOF_CEILINGS) + case LO_FOF_CEILINGS: { - continue; - } - - // thing is above FOF - if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) - { - if (topheight > fofopen[FRONT].floor) + if (thingtop <= bottomheight) { - fofopen[FRONT].floor = topheight; - fofopen[FRONT].floorrover = rover; + if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) + { + if (bottomheight < fofopen[FRONT].ceiling) + { + fofopen[FRONT].ceiling = bottomheight; + fofopen[FRONT].ceilingrover = rover; + } + } } + break; + } + default: + { + midheight = bottomheight + (topheight - bottomheight) / 2; + delta1 = abs(mobj->z - midheight); + delta2 = abs(thingtop - midheight); + + if (delta1 > delta2) + { + // thing is below FOF + if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) + { + if (bottomheight < fofopen[FRONT].ceiling) + { + fofopen[FRONT].ceiling = bottomheight; + fofopen[FRONT].ceilingrover = rover; + } + } + } + else + { + // thing is above FOF + if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) + { + if (topheight > fofopen[FRONT].floor) + { + fofopen[FRONT].floor = topheight; + fofopen[FRONT].floorrover = rover; + } + } + } + break; } } } @@ -789,11 +851,12 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open) // Check for backsectors fake floors for (rover = back->ffloors; rover; rover = rover->next) { - fixed_t topheight, bottomheight; + fixed_t topheight, bottomheight, midheight; + if (!(rover->fofflags & FOF_EXISTS)) continue; - if (mobj->player && P_CheckSolidFFloorSurface(mobj->player, rover)) + if (P_CheckSolidFFloorSurface(mobj, rover)) ; else if (!((rover->fofflags & FOF_BLOCKPLAYER && mobj->player) || (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player))) @@ -810,41 +873,69 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open) bottomheight = P_GetFOFBottomZ(mobj, back, rover, tm.x, tm.y, linedef); } - delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); - delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - - if (delta1 > delta2) + switch (open->fofType) { - if (open->fofType == LO_FOF_FLOORS) + case LO_FOF_FLOORS: { - continue; - } - - // thing is below FOF - if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) - { - if (bottomheight < fofopen[BACK].ceiling) + if (mobj->z >= topheight) { - fofopen[BACK].ceiling = bottomheight; - fofopen[BACK].ceilingrover = rover; + if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) + { + if (topheight > fofopen[BACK].floor) + { + fofopen[BACK].floor = topheight; + fofopen[BACK].floorrover = rover; + } + } } + break; } - } - else - { - if (open->fofType == LO_FOF_CEILINGS) + case LO_FOF_CEILINGS: { - continue; - } - - // thing is above FOF - if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) - { - if (topheight > fofopen[BACK].floor) + if (thingtop <= bottomheight) { - fofopen[BACK].floor = topheight; - fofopen[BACK].floorrover = rover; + if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) + { + if (bottomheight < fofopen[BACK].ceiling) + { + fofopen[BACK].ceiling = bottomheight; + fofopen[BACK].ceilingrover = rover; + } + } } + break; + } + default: + { + midheight = bottomheight + (topheight - bottomheight) / 2; + delta1 = abs(mobj->z - midheight); + delta2 = abs(thingtop - midheight); + + if (delta1 > delta2) + { + // thing is below FOF + if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) + { + if (bottomheight < fofopen[BACK].ceiling) + { + fofopen[BACK].ceiling = bottomheight; + fofopen[BACK].ceilingrover = rover; + } + } + } + else + { + // thing is above FOF + if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) + { + if (topheight > fofopen[BACK].floor) + { + fofopen[BACK].floor = topheight; + fofopen[BACK].floorrover = rover; + } + } + } + break; } } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 4fa1d3d92..e9fa2cd3b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1997,7 +1997,7 @@ void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype) topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL); bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL); - if (mo->player && P_CheckSolidFFloorSurface(mo->player, rover)) // only the player should stand on lava or run on water + if (P_CheckSolidFFloorSurface(mo, rover)) // only the player should stand on lava or run on water ; else if (motype != 0 && rover->fofflags & FOF_SWIMMABLE) // "scenery" only continue; @@ -3082,10 +3082,17 @@ boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) return false; } -boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover) +boolean P_CheckSolidFFloorSurface(mobj_t *mobj, ffloor_t *rover) { + if (!mobj->player) + { + // future proff if we ever decide to allow mobjs + // to interact with P_CheckSolidFFloorSurface + return false; + } + return P_CheckSolidLava(rover) || - P_CanRunOnWater(player, rover); + P_CanRunOnWater(mobj->player, rover); } //