From e9fa53c54dc007948d066da4ff47d3656c23e9f2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 28 Feb 2016 13:59:15 +0100 Subject: [PATCH] - fixed dropoff calculation over portals. It can easily happen that the lower sector has no lines below the checked area, in which case it would not set the dropoffz correctly. To prevent this, P_LineOpening must, when it checks the opening over a sector portal, actually calculate the dropoff to the lower portal itself by calling sector_t::NextLowestPointAt. It also means that FindRefPoint must calculate a proper reference point when one side of the line to be checked is part of a floor portal. --- src/p_map.cpp | 23 ++++++++++++++++----- src/p_maputl.cpp | 52 +++++++++++++++++++++++++----------------------- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 578375358..d1878162f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -162,11 +162,22 @@ static inline fixed_t GetCoefficientClosestPointInLine24(line_t *ld, fixedvec2 p static inline fixedvec2 FindRefPoint(line_t *ld, fixedvec2 pos) { - if (!((((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) | - (ld->backsector->floorplane.a | ld->backsector->floorplane.b) | - (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | - (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) - && ld->backsector->e->XFloor.ffloors.Size() == 0 && ld->frontsector->e->XFloor.ffloors.Size() == 0)) + // If there's any chance of slopes getting in the way we need to get a proper refpoint, otherwise we can save the work. + // Slopes can get in here when: + // - the actual sector planes are sloped + // - there's 3D floors in this sector + // - there's a crossable floor portal (for which the dropoff needs to be calculated within P_LineOpening, and the lower sector can easily have slopes) + if ( + (((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) | + (ld->backsector->floorplane.a | ld->backsector->floorplane.b) | + (ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | + (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) != 0) + || + ld->backsector->e->XFloor.ffloors.Size() == 0 + || + ld->frontsector->e->XFloor.ffloors.Size() == 0 + || + !ld->frontsector->PortalBlocksMovement(sector_t::floor)) { fixed_t r = GetCoefficientClosestPointInLine24(ld, pos); if (r <= 0) @@ -972,7 +983,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec } if (open.lowfloor < tm.dropoffz) + { tm.dropoffz = open.lowfloor; + } } // if contacted a special line, add it to the list diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 057c4329c..9d98f4bf5 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -150,7 +150,7 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, if (!(flags & FFCF_ONLY3DFLOORS)) { sector_t *front, *back; - fixed_t fc, ff, bc, bf; + fixed_t fc = 0, ff = 0, bc = 0, bf = 0; if (linedef->backsector == NULL) { @@ -162,29 +162,20 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, front = linedef->frontsector; back = linedef->backsector; - if (!(flags & FFCF_NOPORTALS) && !linedef->frontsector->PortalBlocksMovement(sector_t::ceiling) && - linedef->backsector->SkyBoxes[sector_t::ceiling] && - linedef->frontsector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup == linedef->backsector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup) + if (!(flags & FFCF_NOPORTALS)) { - fc = bc = FIXED_MAX; - } - else - { - fc = front->ceilingplane.ZatPoint(x, y); - bc = back->ceilingplane.ZatPoint(x, y); - } - if (!(flags & FFCF_NOPORTALS) && !linedef->frontsector->PortalBlocksMovement(sector_t::floor) && - linedef->backsector->SkyBoxes[sector_t::floor] && - linedef->frontsector->SkyBoxes[sector_t::floor]->Sector->PortalGroup == linedef->backsector->SkyBoxes[sector_t::floor]->Sector->PortalGroup) - { - ff = bf = FIXED_MIN; - } - else - { - ff = front->floorplane.ZatPoint(x, y); - bf = back->floorplane.ZatPoint(x, y); + if (!linedef->frontsector->PortalBlocksMovement(sector_t::ceiling)) fc = FIXED_MAX; + if (!linedef->backsector->PortalBlocksMovement(sector_t::ceiling)) bc = FIXED_MAX; + if (!linedef->frontsector->PortalBlocksMovement(sector_t::floor)) ff = FIXED_MIN; + if (!linedef->backsector->PortalBlocksMovement(sector_t::floor)) bf = FIXED_MIN; } + if (fc == 0) fc = front->ceilingplane.ZatPoint(x, y); + if (bc == 0) bc = back->ceilingplane.ZatPoint(x, y); + if (ff == 0) ff = front->floorplane.ZatPoint(x, y); + if (bf == 0) bf = back->floorplane.ZatPoint(x, y); + + /*Printf ("]]]]]] %d %d\n", ff, bf);*/ open.topsec = fc < bc? front : back; @@ -198,8 +189,7 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, // that imprecisions in the plane equation mean there is a // good chance that even if a slope and non-slope look like // they line up, they won't be perfectly aligned. - if (refx == FIXED_MIN || - abs (ff-bf) > 256) + if (ff == FIXED_MIN || bf == FIXED_MIN || (refx == FIXED_MIN || abs (ff-bf) > 256)) { usefront = (ff > bf); } @@ -219,7 +209,13 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, open.bottomsec = front; open.floorpic = front->GetTexture(sector_t::floor); open.floorterrain = front->GetTerrain(sector_t::floor); - open.lowfloor = bf; + if (bf != FIXED_MIN) open.lowfloor = bf; + else + { + // We must check through the portal for the actual dropoff. + // If there's no lines in the lower sections we'd never get a usable value otherwise. + open.lowfloor = back->NextLowestFloorAt(refx, refy, back->SkyBoxes[sector_t::floor]->threshold-1); + } } else { @@ -227,7 +223,13 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, open.bottomsec = back; open.floorpic = back->GetTexture(sector_t::floor); open.floorterrain = back->GetTerrain(sector_t::floor); - open.lowfloor = ff; + if (ff != FIXED_MIN) open.lowfloor = ff; + else + { + // We must check through the portal for the actual dropoff. + // If there's no lines in the lower sections we'd never get a usable value otherwise. + open.lowfloor = front->NextLowestFloorAt(refx, refy, front->SkyBoxes[sector_t::floor]->threshold - 1); + } } open.frontfloorplane = front->floorplane; open.backfloorplane = back->floorplane;