- Fixed: A_Respawn and P_NightmareRespawn() should not check for collision with world geometry.

The initial spawn did not, so this can prevent respawns of things that were initially
  spawned if they happen to intersect a wall.
- Fixed: Don't respawn actors inside the floor.
- Fixed: The final calls to P_FindFloorCeiling() in P_NightmareRespawn() and A_RestoreSpecialPosition
  also need to pass true as the second parameter. (Because this parameter is onlyspawnpos, not
  onlymidtex.)

SVN r3518 (trunk)
This commit is contained in:
Randy Heit 2012-04-06 04:46:45 +00:00
parent 14730a89be
commit 5358fd594b
5 changed files with 39 additions and 12 deletions

View file

@ -384,8 +384,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition)
self->z += FloatBobOffsets[(self->FloatBobPhase + level.maptime) & 63];
}
}
// Redo floor/ceiling check, now with 3D floors
P_FindFloorCeiling(self);
// Redo floor/ceiling check, in case of 3D floors
P_FindFloorCeiling(self, true);
if (self->z < self->floorz)
{ // Do not reappear under the floor, even if that's where we were for the
// initial spawn.
self->z = self->floorz;
}
}
int AInventory::StaticLastMessageTic;

View file

@ -405,8 +405,8 @@ extern TArray<line_t *> spechit;
bool P_TestMobjLocation (AActor *mobj);
bool P_TestMobjZ (AActor *mobj, bool quick=true, AActor **pOnmobj = NULL);
bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm);
bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y);
bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bool actorsonly=false);
bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, bool actorsonly=false);
AActor *P_CheckOnmobj (AActor *thing);
void P_FakeZMovement (AActor *mo);
bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false);
@ -432,7 +432,7 @@ void P_ResetSightCounters (bool full);
bool P_TalkFacing (AActor *player);
void P_UseLines (player_t* player);
bool P_UsePuzzleItem (AActor *actor, int itemType);
void P_FindFloorCeiling (AActor *actor, bool onlymidtex = false);
void P_FindFloorCeiling (AActor *actor, bool onlyspawnpos = false);
bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset);

View file

@ -1256,7 +1256,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
//
//==========================================================================
bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm)
bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bool actorsonly)
{
sector_t *newsec;
AActor *thingblocker;
@ -1399,7 +1399,7 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm)
thing->BlockingMobj = NULL;
thing->height = realheight;
if (thing->flags & MF_NOCLIP)
if (actorsonly || (thing->flags & MF_NOCLIP))
return (thing->BlockingMobj = thingblocker) == NULL;
FBlockLinesIterator it(box);
@ -1435,10 +1435,10 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm)
return (thing->BlockingMobj = thingblocker) == NULL;
}
bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, bool actorsonly)
{
FCheckPosition tm;
return P_CheckPosition(thing, x, y, tm);
return P_CheckPosition(thing, x, y, tm, actorsonly);
}
//----------------------------------------------------------------------------

View file

@ -2467,12 +2467,23 @@ void P_NightmareRespawn (AActor *mobj)
mo = AActor::StaticSpawn(RUNTIME_TYPE(mobj), x, y, z, NO_REPLACE, true);
if (z == ONFLOORZ)
{
mo->z += mobj->SpawnPoint[2];
if (mo->z < mo->floorz)
{ // Do not respawn monsters in the floor, even if that's where they
// started. The initial P_ZMovement() call would have put them on
// the floor right away, but we need them on the floor now so we
// can use P_CheckPosition() properly.
mo->z = mo->floorz;
}
}
else if (z == ONCEILINGZ)
{
mo->z -= mobj->SpawnPoint[2];
}
// something is occupying its position?
if (!P_TestMobjLocation (mo))
if (!P_CheckPosition(mo, mo->x, mo->y, true))
{
//[GrafZahl] MF_COUNTKILL still needs to be checked here.
mo->ClearCounters();
@ -2481,7 +2492,7 @@ void P_NightmareRespawn (AActor *mobj)
}
// If there are 3D floors, we need to find floor/ceiling again.
P_FindFloorCeiling(mo);
P_FindFloorCeiling(mo, true);
z = mo->z;

View file

@ -2649,10 +2649,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn)
{
// [KS] DIE DIE DIE DIE erm *ahem* =)
oktorespawn = P_TeleportMove(self, self->x, self->y, self->z, true);
if (oktorespawn)
{ // Need to do this over again, since P_TeleportMove() will redo
// it with the proper point-on-side calculation.
self->UnlinkFromWorld();
self->LinkToWorld(true);
sector_t *sec = self->Sector;
self->dropoffz =
self->floorz = sec->floorplane.ZatPoint(self->x, self->y);
self->ceilingz = sec->ceilingplane.ZatPoint(self->x, self->y);
P_FindFloorCeiling(self, true);
}
}
else
{
oktorespawn = P_TestMobjLocation(self);
oktorespawn = P_CheckPosition(self, self->x, self->z, true);
}
if (oktorespawn)