- Fixed: Do not interpolate from an actor's despawned position to its spawned position when it

respawns.
- Use doubles instead of floats, as appropriate, in PIT_FindFloorCeiling().
- Fixed: The second call to P_FindFloorCeiling() in A_RestoreSpecialPosition and P_NightmareRespawn()
  must only consider 3D floors and midtexes.

SVN r3545 (trunk)
This commit is contained in:
Randy Heit 2012-04-08 21:12:14 +00:00
parent 9451b7c1d3
commit 837126ae57
5 changed files with 87 additions and 65 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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)