mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 07:12:02 +00:00
- 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:
parent
14730a89be
commit
5358fd594b
5 changed files with 39 additions and 12 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue