- fixed: P_LineOpening could miss a 3D floor if an actor was centered right against its side.

- restored the original 3D floor code to retrieve the current floor in P_CheckPosition. The portal aware version was a bit too strict and could place the actor on the wrong side when moving at high speeds.
This commit is contained in:
Christoph Oelckers 2016-04-27 02:13:35 +02:00
parent 172290224b
commit fab38d092b
2 changed files with 40 additions and 2 deletions

View File

@ -790,7 +790,7 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li
lowestceilingsec = j == 0 ? linedef->frontsector : linedef->backsector; lowestceilingsec = j == 0 ? linedef->frontsector : linedef->backsector;
} }
if(ff_top > highestfloor && delta1 < delta2 && (!restrict || thing->Z() >= ff_top)) if(ff_top > highestfloor && delta1 <= delta2 && (!restrict || thing->Z() >= ff_top))
{ {
highestfloor = ff_top; highestfloor = ff_top;
highestfloorpic = *rover->top.texture; highestfloorpic = *rover->top.texture;

View File

@ -1514,9 +1514,47 @@ bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, boo
// Any contacted lines the step closer together will adjust them. // Any contacted lines the step closer together will adjust them.
if (!thing->IsNoClip2()) if (!thing->IsNoClip2())
{ {
if (!newsec->PortalBlocksMovement(sector_t::ceiling) || !newsec->PortalBlocksMovement(sector_t::floor))
{
// Use P_GetFloorCeilingZ only if there's portals to consider. Its logic is subtly different than what is needed here for 3D floors.
P_GetFloorCeilingZ(tm, FFCF_SAMESECTOR); P_GetFloorCeilingZ(tm, FFCF_SAMESECTOR);
} }
else else
{
tm.floorz = tm.dropoffz = newsec->floorplane.ZatPoint(pos);
tm.floorpic = newsec->GetTexture(sector_t::floor);
tm.ceilingz = newsec->ceilingplane.ZatPoint(pos);
tm.ceilingpic = newsec->GetTexture(sector_t::ceiling);
tm.floorsector = tm.ceilingsector = newsec;
}
F3DFloor* rover;
double thingtop = thing->Height > 0 ? thing->Top() : thing->Z() + 1;
for (unsigned i = 0; i<newsec->e->XFloor.ffloors.Size(); i++)
{
rover = newsec->e->XFloor.ffloors[i];
if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;
double ff_bottom = rover->bottom.plane->ZatPoint(pos);
double ff_top = rover->top.plane->ZatPoint(pos);
double delta1 = thing->Z() - (ff_bottom + ((ff_top - ff_bottom) / 2));
double delta2 = thingtop - (ff_bottom + ((ff_top - ff_bottom) / 2));
if (ff_top > tm.floorz && fabs(delta1) < fabs(delta2))
{
tm.floorz = tm.dropoffz = ff_top;
tm.floorpic = *rover->top.texture;
}
if (ff_bottom < tm.ceilingz && abs(delta1) >= abs(delta2))
{
tm.ceilingz = ff_bottom;
tm.ceilingpic = *rover->bottom.texture;
}
}
}
else
{ {
// With noclip2, we must ignore 3D floors and go right to the uppermost ceiling and lowermost floor. // With noclip2, we must ignore 3D floors and go right to the uppermost ceiling and lowermost floor.
tm.floorz = tm.dropoffz = newsec->LowestFloorAt(pos, &tm.floorsector); tm.floorz = tm.dropoffz = newsec->LowestFloorAt(pos, &tm.floorsector);