diff --git a/src/p_map.c b/src/p_map.c index 320760582..5b539ad28 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1671,6 +1671,8 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) // Adjusts tm.floorz and tm.ceilingz 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; @@ -1704,25 +1706,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 < tm.ceilingz) + if (open.ceiling < tm.ceilingz) { - tm.ceilingz = opentop; + tm.ceilingz = open.ceiling; tm.ceilingline = ld; } - if (openbottom > tm.floorz) + if (open.floor > tm.floorz) { - tm.floorz = openbottom; + tm.floorz = open.floor; } - if (highceiling > tm.drpoffceilz) - tm.drpoffceilz = highceiling; + if (open.highceiling > tm.drpoffceilz) + tm.drpoffceilz = open.highceiling; - if (lowfloor < tm.dropoffz) - tm.dropoffz = lowfloor; + if (open.lowfloor < tm.dropoffz) + tm.dropoffz = open.lowfloor; return BMIT_CONTINUE; } @@ -1773,6 +1775,7 @@ boolean P_IsLineTripWire(const line_t *ld) static BlockItReturn_t PIT_CheckLine(line_t *ld) { const fixed_t thingtop = tm.thing->z + tm.thing->height; + opening_t open = {0}; if (ld->polyobj && !(ld->polyobj->flags & POF_SOLID)) return BMIT_CONTINUE; @@ -1845,41 +1848,41 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld) return BMIT_ABORT; // set openrange, opentop, openbottom - P_LineOpening(ld, tm.thing); + P_LineOpening(ld, tm.thing, &open); // adjust floor / ceiling heights - if (opentop < tm.ceilingz) + if (open.ceiling < tm.ceilingz) { - tm.ceilingz = opentop; + tm.ceilingz = open.ceiling; tm.ceilingline = ld; - tm.ceilingrover = openceilingrover; - tm.ceilingslope = opentopslope; - tm.ceilingpic = opentoppic; - tm.ceilingstep = openceilingstep; + tm.ceilingrover = open.ceilingrover; + tm.ceilingslope = open.ceilingslope; + tm.ceilingpic = open.ceilingpic; + tm.ceilingstep = open.ceilingstep; if (thingtop == tm.thing->ceilingz) { - tm.thing->ceilingdrop = openceilingdrop; + tm.thing->ceilingdrop = open.ceilingdrop; } } - if (openbottom > tm.floorz) + if (open.floor > tm.floorz) { - tm.floorz = openbottom; - tm.floorrover = openfloorrover; - tm.floorslope = openbottomslope; - tm.floorpic = openbottompic; - tm.floorstep = openfloorstep; + tm.floorz = open.floor; + tm.floorrover = open.floorrover; + tm.floorslope = open.floorslope; + tm.floorpic = open.floorpic; + tm.floorstep = open.floorstep; if (tm.thing->z == tm.thing->floorz) { - tm.thing->floordrop = openfloordrop; + tm.thing->floordrop = open.floordrop; } } - if (highceiling > tm.drpoffceilz) - tm.drpoffceilz = highceiling; + if (open.highceiling > tm.drpoffceilz) + tm.drpoffceilz = open.highceiling; - if (lowfloor < tm.dropoffz) - tm.dropoffz = lowfloor; + if (open.lowfloor < tm.dropoffz) + tm.dropoffz = open.lowfloor; // we've crossed the line if (P_SpecialIsLinedefCrossType(ld)) @@ -3462,6 +3465,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); @@ -3476,15 +3480,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 @@ -3509,6 +3513,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); @@ -3517,15 +3523,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 0693c20b3..14958c941 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, tm.x, tm.y, linedef); + backfloor = P_CameraGetFloorZ (mapcampointer, back, tm.x, tm.y, linedef); backceiling = P_CameraGetCeilingZ(mapcampointer, back, tm.x, tm.y, 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, tm.x, tm.y, linedef); - bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tm.x, tm.y, 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, tm.x, tm.y, linedef); - bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tm.x, tm.y, 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) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) + continue; + + topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tm.x, tm.y, linedef); + bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tm.x, tm.y, 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) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA)) + continue; + + topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tm.x, tm.y, linedef); + bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tm.x, tm.y, 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 }; @@ -608,15 +602,14 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) int lo = 0; // set these defaults so that polyobjects don't interfere with collision above or below them - opentop = highceiling = INT32_MAX; - openbottom = lowfloor = INT32_MIN; - openrange = 0; - opentopslope = openbottomslope = NULL; - opentoppic = openbottompic = -1; - openceilingstep = 0; - openceilingdrop = 0; - openfloorstep = 0; - openfloordrop = 0; + 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) { @@ -646,7 +639,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) thingtop = mobj->z + mobj->height; } - openfloorrover = openceilingrover = NULL; if (!linedef->polyobj) { // Set open and high/low values here @@ -659,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, tm.x, tm.y, linedef); @@ -679,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] ); } } @@ -712,25 +704,25 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (delta1 > delta2) { // Below - if (opentop > texbottom) + 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) + 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] ); } } } @@ -760,26 +752,26 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta1 = abs(mobj->z - polymid); delta2 = abs(thingtop - polymid); - if (delta1 >= delta2) + if (delta1 > delta2) { - if (polybottom < opentop) + if (polybottom < open->ceiling) { - opentop = polybottom; + open->ceiling = polybottom; } - else if (polybottom < highceiling) + else if (polybottom < open->highceiling) { - highceiling = polybottom; + open->highceiling = polybottom; } } else { - if (polytop > openbottom) + if (polytop > open->floor) { - openbottom = polytop; + open->floor = polytop; } - else if (polytop > lowfloor) + else if (polytop > open->lowfloor) { - lowfloor = polytop; + open->lowfloor = polytop; } } } @@ -796,11 +788,11 @@ 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 }, }; @@ -831,10 +823,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) // thing is below FOF if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) { - if (bottomheight < open[FRONT].top) + if (bottomheight < fofopen[FRONT].ceiling) { - open[FRONT].top = bottomheight; - open[FRONT].ceilingrover = rover; + fofopen[FRONT].ceiling = bottomheight; + fofopen[FRONT].ceilingrover = rover; } } } @@ -843,10 +835,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) // thing is above FOF if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) { - if (topheight > open[FRONT].bottom) + if (topheight > fofopen[FRONT].floor) { - open[FRONT].bottom = topheight; - open[FRONT].floorrover = rover; + fofopen[FRONT].floor = topheight; + fofopen[FRONT].floorrover = rover; } } } @@ -878,10 +870,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) // thing is below FOF if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) { - if (bottomheight < open[BACK].top) + if (bottomheight < fofopen[BACK].ceiling) { - open[BACK].top = bottomheight; - open[BACK].ceilingrover = rover; + fofopen[BACK].ceiling = bottomheight; + fofopen[BACK].ceilingrover = rover; } } } @@ -890,77 +882,77 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) // thing is above FOF if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) { - if (topheight > open[BACK].bottom) + if (topheight > fofopen[BACK].floor) { - open[BACK].bottom = topheight; - open[BACK].floorrover = rover; + fofopen[BACK].floor = topheight; + fofopen[BACK].floorrover = rover; } } } } - hi = ( open[0].top < open[1].top ); + hi = ( fofopen[0].ceiling < fofopen[1].ceiling ); lo = ! hi; - if (open[lo].top <= opentop) + if (fofopen[lo].ceiling <= open->ceiling) { - topedge[lo] = P_GetFFloorBottomZAt(open[lo].ceilingrover, cross.x, cross.y); + topedge[lo] = P_GetFFloorBottomZAt(fofopen[lo].ceilingrover, cross.x, cross.y); - if (open[hi].top < opentop) + 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; - opentopslope = *open[lo].ceilingrover->b_slope; - opentoppic = *open[lo].ceilingrover->bottompic; - 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 (open[hi].top < highceiling) + if (fofopen[hi].ceiling < open->highceiling) { - highceiling = open[hi].top; + open->highceiling = fofopen[hi].ceiling; } } - else if (open[lo].top < highceiling) + else if (fofopen[lo].ceiling < open->highceiling) { - highceiling = open[lo].top; + 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 >= openbottom) + if (fofopen[hi].floor >= open->floor) { - botedge[hi] = P_GetFFloorTopZAt(open[hi].floorrover, cross.x, cross.y); + botedge[hi] = P_GetFFloorTopZAt(fofopen[hi].floorrover, cross.x, cross.y); - if (open[lo].bottom > openbottom) + 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; - openbottomslope = *open[hi].floorrover->t_slope; - openbottompic = *open[hi].floorrover->toppic; - 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 (open[lo].bottom > lowfloor) + if (fofopen[lo].floor > open->lowfloor) { - lowfloor = open[lo].bottom; + open->lowfloor = fofopen[lo].floor; } } - else if (open[hi].bottom > lowfloor) + else if (fofopen[hi].floor > open->lowfloor) { - lowfloor = open[hi].bottom; + 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 5718afd04..4656ffdd4 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -50,7 +50,7 @@ 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); +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); @@ -61,16 +61,18 @@ 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; +struct opening_t +{ + 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; +}; -void P_LineOpening(line_t *plinedef, mobj_t *mobj); +void P_LineOpening(line_t *plinedef, mobj_t *mobj, opening_t *open); typedef enum { diff --git a/src/p_sight.c b/src/p_sight.c index 901e1003f..761b4b47b 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -36,6 +36,7 @@ typedef struct 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; typedef boolean (*los_init_t)(mobj_t *, mobj_t *, register los_t *); @@ -51,6 +52,8 @@ typedef struct static INT32 sightcounts[2]; +#define TRAVERSE_MAX (2) + // // P_DivlineSide // @@ -365,6 +368,7 @@ static boolean P_CanBotTraverse(seg_t *seg, divline_t *divl, register los_t *los fixed_t frac = 0; boolean canStepUp, canDropOff; fixed_t maxstep = 0; + opening_t open = {0}; if (P_CanTraceBlockingLine(seg, divl, los) == false) { @@ -380,32 +384,32 @@ static boolean P_CanBotTraverse(seg_t *seg, divline_t *divl, register los_t *los tm.y = los->strace.y + FixedMul(los->strace.dy, frac); // set openrange, opentop, openbottom - P_LineOpening(line, los->t1); + P_LineOpening(line, los->t1, &open); maxstep = P_GetThingStepUp(los->t1, tm.x, tm.y); - if (openrange < los->t1->height) + if (open.range < los->t1->height) { // Can't fit return false; } - canStepUp = ((flip ? (highceiling - opentop) : (openbottom - lowfloor)) <= maxstep); - canDropOff = (flip ? (los->t1->z + los->t1->height <= opentop) : (los->t1->z >= openbottom)); + // If we can step up... + canStepUp = ((flip ? (open.highceiling - open.ceiling) : (open.floor - open.lowfloor)) <= maxstep); + + // Or if we're on the higher side... + canDropOff = (flip ? (los->t1->z + los->t1->height <= open.ceiling) : (los->t1->z >= open.floor)); if (canStepUp || canDropOff) { if (los->t1->player != NULL && los->alreadyHates == false) { - // Treat damage sectors like walls, if you're not already in a bad sector. - sector_t *front, *back; + // Treat damage / offroad sectors like walls. + UINT8 side = P_DivlineSide(los->t2x, los->t2y, divl) & 1; + sector_t *sector = (side == 1) ? seg->backsector : seg->frontsector; - front = seg->frontsector; - back = seg->backsector; - - if (K_BotHatesThisSector(los->t1->player, front, tm.x, tm.y) - || K_BotHatesThisSector(los->t1->player, back, tm.x, tm.y)) + if (K_BotHatesThisSector(los->t1->player, sector, tm.x, tm.y)) { - // This line does not block us, but we don't want to be in it. + // This line does not block us, but we don't want to cross it regardless. return false; } } @@ -413,7 +417,8 @@ static boolean P_CanBotTraverse(seg_t *seg, divline_t *divl, register los_t *los return true; } - return false; + los->traversed++; + return (los->traversed < TRAVERSE_MAX); } static boolean P_CanWaypointTraverse(seg_t *seg, divline_t *divl, register los_t *los) @@ -423,6 +428,7 @@ static boolean P_CanWaypointTraverse(seg_t *seg, divline_t *divl, register los_t fixed_t frac = 0; boolean canStepUp, canDropOff; fixed_t maxstep = 0; + opening_t open = {0}; if (P_CanTraceBlockingLine(seg, divl, los) == false) { @@ -445,10 +451,10 @@ static boolean P_CanWaypointTraverse(seg_t *seg, divline_t *divl, register los_t tm.y = los->strace.y + FixedMul(los->strace.dy, frac); // set openrange, opentop, openbottom - P_LineOpening(line, los->t1); + P_LineOpening(line, los->t1, &open); maxstep = P_GetThingStepUp(los->t1, tm.x, tm.y); -#if 0 +#if 1 if (los->t2->type == MT_WAYPOINT) { waypoint_t *wp = K_SearchWaypointHeapForMobj(los->t2); @@ -456,19 +462,19 @@ static boolean P_CanWaypointTraverse(seg_t *seg, divline_t *divl, register los_t if (wp != NULL) { CONS_Printf( - "========\nID: %d\nopenrange: %.2f >= %.2f\n", + "========\nID: %d\nrange: %.2f >= %.2f\n", K_GetWaypointID(wp), - FIXED_TO_FLOAT(openrange), + FIXED_TO_FLOAT(open.range), FIXED_TO_FLOAT(los->t1->height) ); - if (openrange >= los->t1->height) + if (open.range >= los->t1->height) { CONS_Printf( - "openbottom: %.2f\nlowfloor: %.2f\nstep: %.2f <= %.2f\n", - FIXED_TO_FLOAT(openbottom), - FIXED_TO_FLOAT(lowfloor), - FIXED_TO_FLOAT(openbottom - lowfloor), + "floor: %.2f\nlowfloor: %.2f\nstep: %.2f <= %.2f\n", + FIXED_TO_FLOAT(open.floor), + FIXED_TO_FLOAT(open.lowfloor), + FIXED_TO_FLOAT(open.floor - open.lowfloor), FIXED_TO_FLOAT(maxstep) ); } @@ -476,24 +482,25 @@ static boolean P_CanWaypointTraverse(seg_t *seg, divline_t *divl, register los_t } #endif - if (openrange < los->t1->height) + if (open.range < los->t1->height) { // Can't fit return false; } // If we can step up... - canStepUp = ((flip ? (highceiling - opentop) : (openbottom - lowfloor)) <= maxstep); + canStepUp = ((flip ? (open.highceiling - open.ceiling) : (open.floor - open.lowfloor)) <= maxstep); // Or if we're on the higher side... - canDropOff = (flip ? (los->t1->z + los->t1->height <= opentop) : (los->t1->z >= openbottom)); + canDropOff = (flip ? (los->t1->z + los->t1->height <= open.ceiling) : (los->t1->z >= open.floor)); if (canStepUp || canDropOff) { return true; } - return false; + los->traversed++; + return (los->traversed < TRAVERSE_MAX); } // @@ -748,6 +755,7 @@ static boolean P_CompareMobjsAcrossLines(mobj_t *t1, mobj_t *t2, register los_fu los.t1 = t1; los.t2 = t2; los.alreadyHates = false; + los.traversed = 0; los.topslope = (los.bottomslope = t2->z - (los.sightzstart = diff --git a/src/typedef.h b/src/typedef.h index ebe816913..16d9fa8c1 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -265,6 +265,7 @@ TYPEDEF (BasicFF_t); // p_maputl.h TYPEDEF (divline_t); TYPEDEF (intercept_t); +TYPEDEF (opening_t); // p_mobj.h TYPEDEF (mobj_t);