diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index bef479d58..8303aea39 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -385,7 +385,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) } } // Redo floor/ceiling check, in case of 3D floors - P_FindFloorCeiling(self, FFCF_SAMESECTOR); + P_FindFloorCeiling(self, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS); if (self->z < self->floorz) { // Do not reappear under the floor, even if that's where we were for the // initial spawn. @@ -395,6 +395,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) { // Do the same for the ceiling. self->z = self->ceilingz - self->height; } + // Do not interpolate from the position the actor was at when it was + // picked up, in case that is different from where it is now. + self->PrevX = self->x; + self->PrevY = self->y; + self->PrevZ = self->z; } int AInventory::StaticLastMessageTic; diff --git a/src/p_local.h b/src/p_local.h index 9586651cc..c0d7179f2 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -259,7 +259,7 @@ struct FLineOpening bool abovemidtex; }; -void P_LineOpening (FLineOpening &open, AActor *thing, const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx=FIXED_MIN, fixed_t refy=0); +void P_LineOpening (FLineOpening &open, AActor *thing, const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx=FIXED_MIN, fixed_t refy=0, bool only3d=false); class FBoundingBox; struct polyblock_t; @@ -436,7 +436,8 @@ bool P_UsePuzzleItem (AActor *actor, int itemType); enum { FFCF_ONLYSPAWNPOS = 1, - FFCF_SAMESECTOR = 2 + FFCF_SAMESECTOR = 2, + FFCF_ONLY3DFLOORS = 4, // includes 3D midtexes }; void P_FindFloorCeiling (AActor *actor, int flags=0); diff --git a/src/p_map.cpp b/src/p_map.cpp index ae6590a48..9f8cc6271 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -83,9 +83,11 @@ msecnode_t* sector_list = NULL; // phares 3/16/98 // // PIT_FindFloorCeiling // +// only3d set means to only check against 3D floors and midtexes. +// //========================================================================== -static bool PIT_FindFloorCeiling (line_t *ld, const FBoundingBox &box, FCheckPosition &tmf) +static bool PIT_FindFloorCeiling (line_t *ld, const FBoundingBox &box, FCheckPosition &tmf, bool only3d) { if (box.Right() <= ld->bbox[BOXLEFT] || box.Left() >= ld->bbox[BOXRIGHT] @@ -113,28 +115,28 @@ static bool PIT_FindFloorCeiling (line_t *ld, const FBoundingBox &box, FCheckPos (ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0) && ld->backsector->e->XFloor.ffloors.Size()==0 && ld->frontsector->e->XFloor.ffloors.Size()==0) { - P_LineOpening (open, tmf.thing, ld, sx=tmf.x, sy=tmf.y, tmf.x, tmf.y); + P_LineOpening (open, tmf.thing, ld, sx=tmf.x, sy=tmf.y, tmf.x, tmf.y, only3d); } else { // Find the point on the line closest to the actor's center, and use // that to calculate openings - float dx = (float)ld->dx; - float dy = (float)ld->dy; - fixed_t r = (fixed_t)(((float)(tmf.x - ld->v1->x) * dx + - (float)(tmf.y - ld->v1->y) * dy) / + double dx = ld->dx; + double dy = ld->dy; + fixed_t r = xs_CRoundToInt(((double)(tmf.x - ld->v1->x) * dx + + (double)(tmf.y - ld->v1->y) * dy) / (dx*dx + dy*dy) * 16777216.f); if (r <= 0) { - P_LineOpening (open, tmf.thing, ld, sx=ld->v1->x, sy=ld->v1->y, tmf.x, tmf.y); + P_LineOpening (open, tmf.thing, ld, sx=ld->v1->x, sy=ld->v1->y, tmf.x, tmf.y, only3d); } else if (r >= (1<<24)) { - P_LineOpening (open, tmf.thing, ld, sx=ld->v2->x, sy=ld->v2->y, tmf.thing->x, tmf.thing->y); + P_LineOpening (open, tmf.thing, ld, sx=ld->v2->x, sy=ld->v2->y, tmf.thing->x, tmf.thing->y, only3d); } else { P_LineOpening (open, tmf.thing, ld, sx=ld->v1->x + MulScale24 (r, ld->dx), - sy=ld->v1->y + MulScale24 (r, ld->dy), tmf.x, tmf.y); + sy=ld->v1->y + MulScale24 (r, ld->dy), tmf.x, tmf.y, only3d); } } @@ -264,7 +266,7 @@ void P_FindFloorCeiling (AActor *actor, int flags) while ((ld = it.Next())) { - PIT_FindFloorCeiling(ld, box, tmf); + PIT_FindFloorCeiling(ld, box, tmf, !!(flags & FFCF_ONLY3DFLOORS)); } if (tmf.touchmidtex) tmf.dropoffz = tmf.floorz; @@ -340,7 +342,7 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr thing->z = z; while ((ld = it.Next())) { - PIT_FindFloorCeiling(ld, box, tmf); + PIT_FindFloorCeiling(ld, box, tmf, false); } thing->z = savedz; diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 477ed3504..61adff876 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -135,72 +135,84 @@ fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1) // // Sets opentop and openbottom to the window // through a two sided line. -// OPTIMIZE: keep this precalculated // //========================================================================== void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, - fixed_t x, fixed_t y, fixed_t refx, fixed_t refy) + fixed_t x, fixed_t y, fixed_t refx, fixed_t refy, bool only3d) { - sector_t *front, *back; - fixed_t fc, ff, bc, bf; - - if (linedef->sidedef[1] == NULL) + if (!only3d) { - // single sided line - open.range = 0; - return; - } + sector_t *front, *back; + fixed_t fc, ff, bc, bf; - front = linedef->frontsector; - back = linedef->backsector; + if (linedef->sidedef[1] == NULL) + { + // single sided line + open.range = 0; + return; + } - fc = front->ceilingplane.ZatPoint (x, y); - ff = front->floorplane.ZatPoint (x, y); - bc = back->ceilingplane.ZatPoint (x, y); - bf = back->floorplane.ZatPoint (x, y); + front = linedef->frontsector; + back = linedef->backsector; - /*Printf ("]]]]]] %d %d\n", ff, bf);*/ + fc = front->ceilingplane.ZatPoint (x, y); + ff = front->floorplane.ZatPoint (x, y); + bc = back->ceilingplane.ZatPoint (x, y); + bf = back->floorplane.ZatPoint (x, y); - open.topsec = fc < bc? front : back; - open.ceilingpic = open.topsec->GetTexture(sector_t::ceiling); - open.top = fc < bc ? fc : bc; + /*Printf ("]]]]]] %d %d\n", ff, bf);*/ - bool usefront; + open.topsec = fc < bc? front : back; + open.ceilingpic = open.topsec->GetTexture(sector_t::ceiling); + open.top = fc < bc ? fc : bc; - // [RH] fudge a bit for actors that are moving across lines - // bordering a slope/non-slope that meet on the floor. Note - // 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) - { - usefront = (ff > bf); - } - else - { - if ((front->floorplane.a | front->floorplane.b) == 0) - usefront = true; - else if ((back->floorplane.a | front->floorplane.b) == 0) - usefront = false; + bool usefront; + + // [RH] fudge a bit for actors that are moving across lines + // bordering a slope/non-slope that meet on the floor. Note + // 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) + { + usefront = (ff > bf); + } else - usefront = !P_PointOnLineSide (refx, refy, linedef); - } + { + if ((front->floorplane.a | front->floorplane.b) == 0) + usefront = true; + else if ((back->floorplane.a | front->floorplane.b) == 0) + usefront = false; + else + usefront = !P_PointOnLineSide (refx, refy, linedef); + } - if (usefront) - { - open.bottom = ff; - open.bottomsec = front; - open.floorpic = front->GetTexture(sector_t::floor); - open.lowfloor = bf; + if (usefront) + { + open.bottom = ff; + open.bottomsec = front; + open.floorpic = front->GetTexture(sector_t::floor); + open.lowfloor = bf; + } + else + { + open.bottom = bf; + open.bottomsec = back; + open.floorpic = back->GetTexture(sector_t::floor); + open.lowfloor = ff; + } } else - { - open.bottom = bf; - open.bottomsec = back; - open.floorpic = back->GetTexture(sector_t::floor); - open.lowfloor = ff; + { // Dummy stuff to have some sort of opening for the 3D checks to modify + open.topsec = NULL; + open.ceilingpic.SetInvalid(); + open.top = FIXED_MAX; + open.bottomsec = NULL; + open.floorpic.SetInvalid(); + open.bottom = FIXED_MIN; + open.lowfloor = FIXED_MAX; } // Check 3D floors diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 494218285..636399503 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2487,7 +2487,7 @@ void P_NightmareRespawn (AActor *mobj) } // If there are 3D floors, we need to find floor/ceiling again. - P_FindFloorCeiling(mo, FFCF_SAMESECTOR); + P_FindFloorCeiling(mo, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS); if (z == ONFLOORZ) { @@ -2530,6 +2530,8 @@ void P_NightmareRespawn (AActor *mobj) mo->skillrespawncount = mobj->skillrespawncount; + mo->PrevZ = z; // Do not interpolate Z position if we changed it since spawning. + // spawn a teleport fog at old spot because of removal of the body? mo = Spawn ("TeleportFog", mobj->x, mobj->y, mobj->z, ALLOW_REPLACE); if (mo != NULL)