diff --git a/src/p_map.c b/src/p_map.c index 4bb58790f..6c9706521 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1400,6 +1400,8 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) // Adjusts tmfloorz and tmceilingz as lines are contacted - FOR CAMERA ONLY static BlockItReturn_t PIT_CheckCameraLine(line_t *ld) { + opening_t open = {0}; + if (ld->polyobj && !(ld->polyobj->flags & POF_SOLID)) return BMIT_CONTINUE; @@ -1433,25 +1435,25 @@ static BlockItReturn_t PIT_CheckCameraLine(line_t *ld) } // set openrange, opentop, openbottom - P_CameraLineOpening(ld); + P_CameraLineOpening(ld, &open); // adjust floor / ceiling heights - if (opentop < tmceilingz) + if (open.ceiling < tmceilingz) { - tmceilingz = opentop; + tmceilingz = open.ceiling; ceilingline = ld; } - if (openbottom > tmfloorz) + if (open.floor > tmfloorz) { - tmfloorz = openbottom; + tmfloorz = open.floor; } - if (highceiling > tmdrpoffceilz) - tmdrpoffceilz = highceiling; + if (open.highceiling > tmdrpoffceilz) + tmdrpoffceilz = open.highceiling; - if (lowfloor < tmdropoffz) - tmdropoffz = lowfloor; + if (open.lowfloor < tmdropoffz) + tmdropoffz = open.lowfloor; return BMIT_CONTINUE; } @@ -1502,6 +1504,7 @@ boolean P_IsLineTripWire(const line_t *ld) static BlockItReturn_t PIT_CheckLine(line_t *ld) { const fixed_t thingtop = tmthing->z + tmthing->height; + opening_t open = {0}; if (ld->polyobj && !(ld->polyobj->flags & POF_SOLID)) return BMIT_CONTINUE; @@ -1574,41 +1577,41 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld) return BMIT_ABORT; // set openrange, opentop, openbottom - P_LineOpening(ld, tmthing); + P_LineOpening(ld, tmthing, &open); // adjust floor / ceiling heights - if (opentop < tmceilingz) + if (open.ceiling < tmceilingz) { - tmceilingz = opentop; + tmceilingz = open.ceiling; ceilingline = ld; - tmceilingrover = openceilingrover; - tmceilingslope = opentopslope; - tmceilingpic = opentoppic; - tmceilingstep = openceilingstep; + tmceilingrover = open.ceilingrover; + tmceilingslope = open.ceilingslope; + tmceilingpic = open.ceilingpic; + tmceilingstep = open.ceilingstep; if (thingtop == tmthing->ceilingz) { - tmthing->ceilingdrop = openceilingdrop; + tmthing->ceilingdrop = open.ceilingdrop; } } - if (openbottom > tmfloorz) + if (open.floor > tmfloorz) { - tmfloorz = openbottom; - tmfloorrover = openfloorrover; - tmfloorslope = openbottomslope; - tmfloorpic = openbottompic; - tmfloorstep = openfloorstep; + tmfloorz = open.floor; + tmfloorrover = open.floorrover; + tmfloorslope = open.floorslope; + tmfloorpic = open.floorpic; + tmfloorstep = open.floorstep; if (tmthing->z == tmthing->floorz) { - tmthing->floordrop = openfloordrop; + tmthing->floordrop = open.floordrop; } } - if (highceiling > tmdrpoffceilz) - tmdrpoffceilz = highceiling; + if (open.highceiling > tmdrpoffceilz) + tmdrpoffceilz = open.highceiling; - if (lowfloor < tmdropoffz) - tmdropoffz = lowfloor; + if (open.lowfloor < tmdropoffz) + tmdropoffz = open.lowfloor; // we've crossed the line if (P_SpecialIsLinedefCrossType(ld)) @@ -2629,7 +2632,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { K_UpdateMobjTerrain(thing, tmceilingpic); - + if (!startingonground && tmceilingslope) { P_HandleSlopeLanding(thing, tmceilingslope); @@ -3112,6 +3115,7 @@ static void P_HitBounceLine(line_t *ld) static boolean PTR_SlideCameraTraverse(intercept_t *in) { line_t *li; + opening_t open = {0}; I_Assert(in->isaline); @@ -3126,15 +3130,15 @@ static boolean PTR_SlideCameraTraverse(intercept_t *in) } // set openrange, opentop, openbottom - P_CameraLineOpening(li); + P_CameraLineOpening(li, &open); - if (openrange < mapcampointer->height) + if (open.range < mapcampointer->height) goto isblocking; // doesn't fit - if (opentop - mapcampointer->z < mapcampointer->height) + if (open.ceiling - mapcampointer->z < mapcampointer->height) goto isblocking; // mobj is too high - if (openbottom - mapcampointer->z > 0) // We don't want to make the camera step up. + if (open.floor - mapcampointer->z > 0) // We don't want to make the camera step up. goto isblocking; // too big a step up // this line doesn't block movement @@ -3158,6 +3162,8 @@ isblocking: static boolean PTR_LineIsBlocking(line_t *li) { + opening_t open = {0}; + // one-sided linedefs are always solid to sliding movement. if (!li->backsector) return !P_PointOnLineSide(slidemo->x, slidemo->y, li); @@ -3166,15 +3172,15 @@ static boolean PTR_LineIsBlocking(line_t *li) return true; // set openrange, opentop, openbottom - P_LineOpening(li, slidemo); + P_LineOpening(li, slidemo, &open); - if (openrange < slidemo->height) + if (open.range < slidemo->height) return true; // doesn't fit - if (opentop - slidemo->z < slidemo->height) + if (open.ceiling - slidemo->z < slidemo->height) return true; // mobj is too high - if (openbottom - slidemo->z > P_GetThingStepUp(slidemo, slidemo->x, slidemo->y)) + if (open.floor - slidemo->z > P_GetThingStepUp(slidemo, slidemo->x, slidemo->y)) return true; // too big a step up return false; diff --git a/src/p_maputl.c b/src/p_maputl.c index 1f91154dd..48944373f 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -335,28 +335,24 @@ line_t * P_FindNearestLine // Sets opentop and openbottom to the window through a two sided line. // OPTIMIZE: keep this precalculated // -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 // P_LineOpening, but for camera // Tails 09-29-2002 -void P_CameraLineOpening(line_t *linedef) +void P_CameraLineOpening(line_t *linedef, opening_t *open) { sector_t *front; sector_t *back; fixed_t frontfloor, frontceiling, backfloor, backceiling; + fixed_t thingtop; + + open->ceiling = open->highceiling = INT32_MAX; + open->floor = open->lowfloor = INT32_MIN; + open->range = 0; if (linedef->sidenum[1] == 0xffff) { // single sided line - openrange = 0; return; } @@ -368,14 +364,14 @@ void P_CameraLineOpening(line_t *linedef) if (front->camsec >= 0) { // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) - frontfloor = P_GetSectorFloorZAt (§ors[front->camsec], camera[0].x, camera[0].y); - frontceiling = P_GetSectorCeilingZAt(§ors[front->camsec], camera[0].x, camera[0].y); + frontfloor = P_GetSectorFloorZAt (§ors[front->camsec], mapcampointer->x, mapcampointer->y); + frontceiling = P_GetSectorCeilingZAt(§ors[front->camsec], mapcampointer->x, mapcampointer->y); } else if (front->heightsec >= 0) { // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) - frontfloor = P_GetSectorFloorZAt (§ors[front->heightsec], camera[0].x, camera[0].y); - frontceiling = P_GetSectorCeilingZAt(§ors[front->heightsec], camera[0].x, camera[0].y); + frontfloor = P_GetSectorFloorZAt (§ors[front->heightsec], mapcampointer->x, mapcampointer->x); + frontceiling = P_GetSectorCeilingZAt(§ors[front->heightsec], mapcampointer->x, mapcampointer->y); } else { @@ -386,103 +382,101 @@ void P_CameraLineOpening(line_t *linedef) if (back->camsec >= 0) { // SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope) - backfloor = P_GetSectorFloorZAt (§ors[back->camsec], camera[0].x, camera[0].y); - backceiling = P_GetSectorCeilingZAt(§ors[back->camsec], camera[0].x, camera[0].y); + backfloor = P_GetSectorFloorZAt (§ors[back->camsec], mapcampointer->x, mapcampointer->y); + backceiling = P_GetSectorCeilingZAt(§ors[back->camsec], mapcampointer->x, mapcampointer->y); } else if (back->heightsec >= 0) { // SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope) - backfloor = P_GetSectorFloorZAt (§ors[back->heightsec], camera[0].x, camera[0].y); - backceiling = P_GetSectorCeilingZAt(§ors[back->heightsec], camera[0].x, camera[0].y); + backfloor = P_GetSectorFloorZAt (§ors[back->heightsec], mapcampointer->x, mapcampointer->y); + backceiling = P_GetSectorCeilingZAt(§ors[back->heightsec], mapcampointer->x, mapcampointer->y); } else { - backfloor = P_CameraGetFloorZ(mapcampointer, back, tmx, tmy, linedef); + backfloor = P_CameraGetFloorZ (mapcampointer, back, tmx, tmy, linedef); backceiling = P_CameraGetCeilingZ(mapcampointer, back, tmx, tmy, linedef); } + thingtop = mapcampointer->z + mapcampointer->height; + + if (frontceiling < backceiling) { - fixed_t thingtop = mapcampointer->z + mapcampointer->height; - - if (frontceiling < backceiling) - { - opentop = frontceiling; - highceiling = backceiling; - } - else - { - opentop = backceiling; - highceiling = frontceiling; - } - - if (frontfloor > backfloor) - { - openbottom = frontfloor; - lowfloor = backfloor; - } - else - { - openbottom = backfloor; - lowfloor = frontfloor; - } - - // Check for fake floors in the sector. - if (front->ffloors || back->ffloors) - { - ffloor_t *rover; - fixed_t delta1, delta2; - - // Check for frontsector's fake floors - if (front->ffloors) - for (rover = front->ffloors; rover; rover = rover->next) - { - fixed_t topheight, bottomheight; - if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) - continue; - - topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef); - bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef); - - delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); - delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - if (bottomheight < opentop && delta1 >= delta2) - opentop = bottomheight; - else if (bottomheight < highceiling && delta1 >= delta2) - highceiling = bottomheight; - - if (topheight > openbottom && delta1 < delta2) - openbottom = topheight; - else if (topheight > lowfloor && delta1 < delta2) - lowfloor = topheight; - } - - // Check for backsectors fake floors - if (back->ffloors) - for (rover = back->ffloors; rover; rover = rover->next) - { - fixed_t topheight, bottomheight; - if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) - continue; - - topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef); - bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef); - - delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); - delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - if (bottomheight < opentop && delta1 >= delta2) - opentop = bottomheight; - else if (bottomheight < highceiling && delta1 >= delta2) - highceiling = bottomheight; - - if (topheight > openbottom && delta1 < delta2) - openbottom = topheight; - else if (topheight > lowfloor && delta1 < delta2) - lowfloor = topheight; - } - } - openrange = opentop - openbottom; - return; + open->ceiling = frontceiling; + open->highceiling = backceiling; } + else + { + open->ceiling = backceiling; + open->highceiling = frontceiling; + } + + if (frontfloor > backfloor) + { + open->floor = frontfloor; + open->lowfloor = backfloor; + } + else + { + open->floor = backfloor; + open->lowfloor = frontfloor; + } + + // Check for fake floors in the sector. + if (front->ffloors || back->ffloors) + { + ffloor_t *rover; + fixed_t delta1, delta2; + + // Check for frontsector's fake floors + if (front->ffloors) + for (rover = front->ffloors; rover; rover = rover->next) + { + fixed_t topheight, bottomheight; + if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) ) + continue; + + topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef); + bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef); + + delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + if (bottomheight < open->ceiling && delta1 >= delta2) + open->ceiling = bottomheight; + else if (bottomheight < open->highceiling && delta1 >= delta2) + open->highceiling = bottomheight; + + if (topheight > open->floor && delta1 < delta2) + open->floor = topheight; + else if (topheight > open->lowfloor && delta1 < delta2) + open->lowfloor = topheight; + } + + // Check for backsectors fake floors + if (back->ffloors) + for (rover = back->ffloors; rover; rover = rover->next) + { + fixed_t topheight, bottomheight; + if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) ) + continue; + + topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef); + bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef); + + delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + if (bottomheight < open->ceiling && delta1 >= delta2) + open->ceiling = bottomheight; + else if (bottomheight < open->highceiling && delta1 >= delta2) + open->highceiling = bottomheight; + + if (topheight > open->floor && delta1 < delta2) + open->floor = topheight; + else if (topheight > open->lowfloor && delta1 < delta2) + open->lowfloor = topheight; + } + } + + open->range = (open->ceiling - open->floor); } boolean @@ -592,7 +586,7 @@ static boolean P_MidtextureIsSolid(line_t *linedef, mobj_t *mobj) return ((linedef->flags & ML_MIDSOLID) == ML_MIDSOLID); } -void P_LineOpening(line_t *linedef, mobj_t *mobj) +void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open) { enum { FRONT, BACK }; @@ -607,10 +601,19 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) int hi = 0; int lo = 0; + // set these defaults so that polyobjects don't interfere with collision above or below them + open->ceiling = open->highceiling = INT32_MAX; + open->floor = open->lowfloor = INT32_MIN; + open->range = 0; + open->ceilingslope = open->floorslope = NULL; + open->ceilingrover = open->floorrover = NULL; + open->ceilingpic = open->floorpic = -1; + open->ceilingstep = open->floorstep = 0; + open->ceilingdrop = open->floordrop = 0; + if (linedef->sidenum[1] == 0xffff) { // single sided line - openrange = 0; return; } @@ -636,23 +639,9 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) thingtop = mobj->z + mobj->height; } - openfloorrover = openceilingrover = NULL; - if (linedef->polyobj) + if (!linedef->polyobj) { - // set these defaults so that polyobjects don't interfere with collision above or below them - opentop = INT32_MAX; - openbottom = INT32_MIN; - highceiling = INT32_MIN; - 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 + // Set open and high/low values here fixed_t height[2]; const sector_t * sector[2] = { front, back }; @@ -662,18 +651,18 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) hi = ( height[0] < height[1] ); lo = ! hi; - opentop = height[lo]; - highceiling = height[hi]; - opentopslope = sector[lo]->c_slope; - opentoppic = sector[lo]->ceilingpic; + open->ceiling = height[lo]; + open->highceiling = height[hi]; + open->ceilingslope = sector[lo]->c_slope; + open->ceilingpic = sector[lo]->ceilingpic; if (mobj) { 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] ); + open->ceilingstep = ( thingtop - topedge[lo] ); + open->ceilingdrop = ( topedge[hi] - topedge[lo] ); } height[FRONT] = P_GetFloorZ(mobj, front, tmx, tmy, linedef); @@ -682,18 +671,18 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) hi = ( height[0] < height[1] ); lo = ! hi; - openbottom = height[hi]; - lowfloor = height[lo]; - openbottomslope = sector[hi]->f_slope; - openbottompic = sector[hi]->floorpic; + open->floor = height[hi]; + open->lowfloor = height[lo]; + open->floorslope = sector[hi]->f_slope; + open->floorpic = sector[hi]->floorpic; if (mobj) { 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] ); + open->floorstep = ( botedge[hi] - mobj->z ); + open->floordrop = ( botedge[hi] - botedge[lo] ); } } @@ -711,23 +700,28 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta1 = abs(mobj->z - texmid); delta2 = abs(thingtop - texmid); - if (delta1 > delta2) { // Below - if (opentop > texbottom) + if (delta1 > delta2) + { + // Below + if (open->ceiling > texbottom) { - topedge[lo] -= ( opentop - texbottom ); + topedge[lo] -= ( open->ceiling - texbottom ); - opentop = texbottom; - openceilingstep = ( thingtop - topedge[lo] ); - openceilingdrop = ( topedge[hi] - topedge[lo] ); + open->ceiling = texbottom; + open->ceilingstep = ( thingtop - topedge[lo] ); + open->ceilingdrop = ( topedge[hi] - topedge[lo] ); } - } else { // Above - if (openbottom < textop) + } + else + { + // Above + if (open->floor < textop) { - botedge[hi] += ( textop - openbottom ); + botedge[hi] += ( textop - open->floor ); - openbottom = textop; - openfloorstep = ( botedge[hi] - mobj->z ); - openfloordrop = ( botedge[hi] - botedge[lo] ); + open->floor = textop; + open->floorstep = ( botedge[hi] - mobj->z ); + open->floordrop = ( botedge[hi] - botedge[lo] ); } } } @@ -756,22 +750,33 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta1 = abs(mobj->z - (polybottom + ((polytop - polybottom)/2))); delta2 = abs(thingtop - (polybottom + ((polytop - polybottom)/2))); - if (polybottom < opentop && delta1 >= delta2) + if (delta1 > delta2) { - opentop = polybottom; + if (open->fofType != LO_FOF_FLOORS) + { + if (polybottom < open->ceiling) + { + open->ceiling = polybottom; + } + else if (polybottom < open->highceiling) + { + open->highceiling = polybottom; + } + } } - else if (polybottom < highceiling && delta1 >= delta2) + else { - highceiling = polybottom; - } - - if (polytop > openbottom && delta1 < delta2) - { - openbottom = polytop; - } - else if (polytop > lowfloor && delta1 < delta2) - { - lowfloor = polytop; + if (open->fofType != LO_FOF_CEILINGS) + { + if (polytop > open->floor) + { + open->floor = polytop; + } + else if (polytop > open->lowfloor) + { + open->lowfloor = polytop; + } + } } } // otherwise don't do anything special, pretend there's nothing else there @@ -787,18 +792,15 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) /* yuck */ struct { - fixed_t top; - fixed_t bottom; + fixed_t ceiling; + fixed_t floor; ffloor_t * ceilingrover; ffloor_t * floorrover; - } open[2] = { + } fofopen[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) { @@ -812,34 +814,53 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) || (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player))) continue; - topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef); - bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef); + if (open->fofType != LO_FOF_ANY) + { + topheight = P_VeryTopOfFOF(rover); + bottomheight = P_VeryBottomOfFOF(rover); + } + else + { + topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef); + bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef); + } delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - if (delta1 >= delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) // thing is below FOF + if (delta1 > delta2) { - if (bottomheight < open[FRONT].top) { - open[FRONT].top = bottomheight; - opentopslope = *rover->b_slope; - opentoppic = *rover->bottompic; - open[FRONT].ceilingrover = rover; + if (open->fofType == LO_FOF_FLOORS) + { + continue; } - else if (bottomheight < highceiling) - highceiling = bottomheight; - } - if (delta1 < delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) // thing is above FOF - { - if (topheight > open[FRONT].bottom) { - open[FRONT].bottom = topheight; - openbottomslope = *rover->t_slope; - openbottompic = *rover->toppic; - open[FRONT].floorrover = rover; + // 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 + { + if (open->fofType == LO_FOF_CEILINGS) + { + continue; + } + + // thing is above FOF + if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) + { + if (topheight > fofopen[FRONT].floor) + { + fofopen[FRONT].floor = topheight; + fofopen[FRONT].floorrover = rover; + } } - else if (topheight > lowfloor) - lowfloor = topheight; } } @@ -856,79 +877,118 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) || (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player))) continue; - topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef); - bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef); + if (open->fofType != LO_FOF_ANY) + { + topheight = P_VeryTopOfFOF(rover); + bottomheight = P_VeryBottomOfFOF(rover); + } + else + { + topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef); + bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef); + } delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - if (delta1 >= delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) // thing is below FOF + if (delta1 > delta2) { - if (bottomheight < open[BACK].top) { - open[BACK].top = bottomheight; - opentopslope = *rover->b_slope; - opentoppic = *rover->bottompic; - open[BACK].ceilingrover = rover; + if (open->fofType == LO_FOF_FLOORS) + { + continue; } - else if (bottomheight < highceiling) - highceiling = bottomheight; - } - if (delta1 < delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) // thing is above FOF - { - if (topheight > open[BACK].bottom) { - open[BACK].bottom = topheight; - openbottomslope = *rover->t_slope; - openbottompic = *rover->toppic; - open[BACK].floorrover = rover; + // 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 + { + if (open->fofType == LO_FOF_CEILINGS) + { + continue; + } + + // thing is above FOF + if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) + { + if (topheight > fofopen[BACK].floor) + { + fofopen[BACK].floor = topheight; + fofopen[BACK].floorrover = rover; + } } - else if (topheight > lowfloor) - lowfloor = topheight; } } - lo = ( open[0].top > open[1].top ); + hi = ( fofopen[0].ceiling < fofopen[1].ceiling ); + lo = ! hi; - if (open[lo].top <= oldopentop) + if (fofopen[lo].ceiling <= open->ceiling) { - hi = ! lo; + topedge[lo] = P_GetFFloorBottomZAt(fofopen[lo].ceilingrover, cross.x, cross.y); - topedge[lo] = P_GetFFloorBottomZAt(open[lo].ceilingrover, cross.x, cross.y); - - if (open[hi].top < oldopentop) + if (fofopen[hi].ceiling < open->ceiling) { - topedge[hi] = P_GetFFloorBottomZAt(open[hi].ceilingrover, cross.x, cross.y); + topedge[hi] = P_GetFFloorBottomZAt(fofopen[hi].ceilingrover, cross.x, cross.y); } - opentop = open[lo].top; - openceilingrover = open[lo].ceilingrover; - openceilingstep = ( thingtop - topedge[lo] ); - openceilingdrop = ( topedge[hi] - topedge[lo] ); + open->ceiling = fofopen[lo].ceiling; + open->ceilingrover = fofopen[lo].ceilingrover; + open->ceilingslope = *fofopen[lo].ceilingrover->b_slope; + open->ceilingpic = *fofopen[lo].ceilingrover->bottompic; + open->ceilingstep = ( thingtop - topedge[lo] ); + open->ceilingdrop = ( topedge[hi] - topedge[lo] ); + + if (fofopen[hi].ceiling < open->highceiling) + { + open->highceiling = fofopen[hi].ceiling; + } + } + else if (fofopen[lo].ceiling < open->highceiling) + { + open->highceiling = fofopen[lo].ceiling; } - hi = ( open[0].bottom < open[1].bottom ); + hi = ( fofopen[0].floor < fofopen[1].floor ); + lo = ! hi; - if (open[hi].bottom >= oldopenbottom) + if (fofopen[hi].floor >= open->floor) { - lo = ! hi; + botedge[hi] = P_GetFFloorTopZAt(fofopen[hi].floorrover, cross.x, cross.y); - botedge[hi] = P_GetFFloorTopZAt(open[hi].floorrover, cross.x, cross.y); - - if (open[lo].bottom > oldopenbottom) + if (fofopen[lo].floor > open->floor) { - botedge[lo] = P_GetFFloorTopZAt(open[lo].floorrover, cross.x, cross.y); + botedge[lo] = P_GetFFloorTopZAt(fofopen[lo].floorrover, cross.x, cross.y); } - openbottom = open[hi].bottom; - openfloorrover = open[hi].floorrover; - openfloorstep = ( botedge[hi] - mobj->z ); - openfloordrop = ( botedge[hi] - botedge[lo] ); + open->floor = fofopen[hi].floor; + open->floorrover = fofopen[hi].floorrover; + open->floorslope = *fofopen[hi].floorrover->t_slope; + open->floorpic = *fofopen[hi].floorrover->toppic; + open->floorstep = ( botedge[hi] - mobj->z ); + open->floordrop = ( botedge[hi] - botedge[lo] ); + + if (fofopen[lo].floor > open->lowfloor) + { + open->lowfloor = fofopen[lo].floor; + } + } + else if (fofopen[hi].floor > open->lowfloor) + { + open->lowfloor = fofopen[hi].floor; } } } } - openrange = opentop - openbottom; + open->range = (open->ceiling - open->floor); } diff --git a/src/p_maputl.h b/src/p_maputl.h index 29e7d4de9..3e1d464ac 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -46,7 +46,24 @@ void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *line, vector3_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); void P_MakeDivline(line_t *li, divline_t *dl); -void P_CameraLineOpening(line_t *plinedef); +typedef struct +{ + fixed_t ceiling, floor, range; + fixed_t lowfloor, highceiling; + pslope_t *floorslope, *ceilingslope; + ffloor_t *floorrover, *ceilingrover; + fixed_t ceilingstep, ceilingdrop; + fixed_t floorstep, floordrop; + INT32 ceilingpic, floorpic; + UINT8 fofType; // LO_FOF_ types for forcing FOF collide +} opening_t; + +#define LO_FOF_ANY (0) +#define LO_FOF_FLOORS (1) +#define LO_FOF_CEILINGS (2) + +void P_LineOpening(line_t *plinedef, mobj_t *mobj, opening_t *open); +void P_CameraLineOpening(line_t *plinedef, opening_t *open); fixed_t P_InterceptVector(divline_t *v2, divline_t *v1); INT32 P_BoxOnLineSide(fixed_t *tmbox, line_t *ld); line_t * P_FindNearestLine(const fixed_t x, const fixed_t y, const sector_t *, const INT32 special); @@ -58,17 +75,6 @@ void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_ boolean P_GetMidtextureTopBottom(line_t *linedef, fixed_t x, fixed_t y, fixed_t *return_top, fixed_t *return_bottom); -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); - typedef enum { BMIT_CONTINUE, // Continue blockmap search diff --git a/src/p_sight.c b/src/p_sight.c index 4a8ccab39..806179f55 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -32,10 +32,16 @@ typedef struct { divline_t strace; // from t1 to t2 fixed_t topslope, bottomslope; // slopes to top and bottom of target fixed_t bbox[4]; + + mobj_t *t1, *t2; + boolean alreadyHates; // For bot traversal, for if the bot is already in a sector it doesn't want to be + UINT8 traversed; } los_t; static INT32 sightcounts[2]; +#define TRAVERSE_MAX (2) + // // P_DivlineSide // @@ -423,6 +429,11 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) validcount++; + los.t1 = t1; + los.t2 = t2; + los.alreadyHates = false; + los.traversed = 0; + los.topslope = (los.bottomslope = t2->z - (los.sightzstart = t1->z + t1->height - @@ -681,6 +692,7 @@ static boolean P_CrossBotTraversalSubsector(size_t num, register traceblocking_t { seg_t *seg; INT32 count; + opening_t open = {0}; #ifdef RANGECHECK if (num >= numsubsectors) @@ -751,12 +763,12 @@ static boolean P_CrossBotTraversalSubsector(size_t num, register traceblocking_t // set openrange, opentop, openbottom tmx = tb->compareThing->x; tmy = tb->compareThing->y; - P_LineOpening(line, tb->compareThing); + P_LineOpening(line, tb->compareThing, &open); maxstep = P_GetThingStepUp(tb->compareThing, tmx, tmy); - if ((openrange < tb->compareThing->height) // doesn't fit - || (opentop - tb->compareThing->z < tb->compareThing->height) // mobj is too high - || (openbottom - tb->compareThing->z > maxstep)) // too big a step up + if ((open.range < tb->compareThing->height) // doesn't fit + || (open.ceiling - tb->compareThing->z < tb->compareThing->height) // mobj is too high + || (open.floor - tb->compareThing->z > maxstep)) // too big a step up { // This line situationally blocks us return false;