mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 07:12:02 +00:00
- 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:
parent
9451b7c1d3
commit
837126ae57
5 changed files with 87 additions and 65 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
112
src/p_maputl.cpp
112
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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue