- 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.
This commit is contained in:
Christoph Oelckers 2016-02-28 13:59:15 +01:00
parent b0f1e9b8f3
commit e9fa53c54d
2 changed files with 45 additions and 30 deletions

View File

@ -162,11 +162,22 @@ static inline fixed_t GetCoefficientClosestPointInLine24(line_t *ld, fixedvec2 p
static inline fixedvec2 FindRefPoint(line_t *ld, fixedvec2 pos) static inline fixedvec2 FindRefPoint(line_t *ld, fixedvec2 pos)
{ {
if (!((((ld->frontsector->floorplane.a | ld->frontsector->floorplane.b) | // If there's any chance of slopes getting in the way we need to get a proper refpoint, otherwise we can save the work.
(ld->backsector->floorplane.a | ld->backsector->floorplane.b) | // Slopes can get in here when:
(ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) | // - the actual sector planes are sloped
(ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) // - there's 3D floors in this sector
&& ld->backsector->e->XFloor.ffloors.Size() == 0 && ld->frontsector->e->XFloor.ffloors.Size() == 0)) // - 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); fixed_t r = GetCoefficientClosestPointInLine24(ld, pos);
if (r <= 0) if (r <= 0)
@ -972,7 +983,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
} }
if (open.lowfloor < tm.dropoffz) if (open.lowfloor < tm.dropoffz)
{
tm.dropoffz = open.lowfloor; tm.dropoffz = open.lowfloor;
}
} }
// if contacted a special line, add it to the list // if contacted a special line, add it to the list

View File

@ -150,7 +150,7 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef,
if (!(flags & FFCF_ONLY3DFLOORS)) if (!(flags & FFCF_ONLY3DFLOORS))
{ {
sector_t *front, *back; sector_t *front, *back;
fixed_t fc, ff, bc, bf; fixed_t fc = 0, ff = 0, bc = 0, bf = 0;
if (linedef->backsector == NULL) if (linedef->backsector == NULL)
{ {
@ -162,29 +162,20 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef,
front = linedef->frontsector; front = linedef->frontsector;
back = linedef->backsector; back = linedef->backsector;
if (!(flags & FFCF_NOPORTALS) && !linedef->frontsector->PortalBlocksMovement(sector_t::ceiling) && if (!(flags & FFCF_NOPORTALS))
linedef->backsector->SkyBoxes[sector_t::ceiling] &&
linedef->frontsector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup == linedef->backsector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup)
{ {
fc = bc = FIXED_MAX; if (!linedef->frontsector->PortalBlocksMovement(sector_t::ceiling)) fc = FIXED_MAX;
} if (!linedef->backsector->PortalBlocksMovement(sector_t::ceiling)) bc = FIXED_MAX;
else if (!linedef->frontsector->PortalBlocksMovement(sector_t::floor)) ff = FIXED_MIN;
{ if (!linedef->backsector->PortalBlocksMovement(sector_t::floor)) bf = FIXED_MIN;
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 (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);*/ /*Printf ("]]]]]] %d %d\n", ff, bf);*/
open.topsec = fc < bc? front : back; 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 // that imprecisions in the plane equation mean there is a
// good chance that even if a slope and non-slope look like // good chance that even if a slope and non-slope look like
// they line up, they won't be perfectly aligned. // they line up, they won't be perfectly aligned.
if (refx == FIXED_MIN || if (ff == FIXED_MIN || bf == FIXED_MIN || (refx == FIXED_MIN || abs (ff-bf) > 256))
abs (ff-bf) > 256)
{ {
usefront = (ff > bf); usefront = (ff > bf);
} }
@ -219,7 +209,13 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef,
open.bottomsec = front; open.bottomsec = front;
open.floorpic = front->GetTexture(sector_t::floor); open.floorpic = front->GetTexture(sector_t::floor);
open.floorterrain = front->GetTerrain(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 else
{ {
@ -227,7 +223,13 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef,
open.bottomsec = back; open.bottomsec = back;
open.floorpic = back->GetTexture(sector_t::floor); open.floorpic = back->GetTexture(sector_t::floor);
open.floorterrain = back->GetTerrain(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.frontfloorplane = front->floorplane;
open.backfloorplane = back->floorplane; open.backfloorplane = back->floorplane;