From d0bba7c3c3f5a39913be70c37e6b230d202273c8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 8 Apr 2012 05:39:46 +0000 Subject: [PATCH] - Added another flag to P_FindFloorCeiling() to get it to do its standard processing but without resetting the actor's sector. The 3D floor checks in P_NightmareRespawn() and A_RestoreSpecialPosition now use this. - Fixed: P_NightmareRespawn() did its Z clamping before checking for 3D floors. - Fixed: Respawning actors were not clamped to the ceiling. SVN r3542 (trunk) --- src/g_shared/a_pickups.cpp | 8 ++++++-- src/p_local.h | 8 +++++++- src/p_map.cpp | 23 +++++++++++++---------- src/p_maputl.cpp | 2 +- src/p_mobj.cpp | 29 ++++++++++++++++++++++++----- src/p_user.cpp | 2 +- src/thingdef/thingdef_codeptr.cpp | 2 +- 7 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index acf183502..bef479d58 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -357,7 +357,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) self->dropoffz = self->floorz = sec->floorplane.ZatPoint(_x, _y); self->ceilingz = sec->ceilingplane.ZatPoint(_x, _y); - P_FindFloorCeiling(self, true); + P_FindFloorCeiling(self, FFCF_ONLYSPAWNPOS); if (self->flags & MF_SPAWNCEILING) { @@ -385,12 +385,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) } } // Redo floor/ceiling check, in case of 3D floors - P_FindFloorCeiling(self, true); + P_FindFloorCeiling(self, FFCF_SAMESECTOR); 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; } + if (self->z + self->height > self->ceilingz) + { // Do the same for the ceiling. + self->z = self->ceilingz - self->height; + } } int AInventory::StaticLastMessageTic; diff --git a/src/p_local.h b/src/p_local.h index 7575371e4..9586651cc 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -432,7 +432,13 @@ 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 onlyspawnpos = false); + +enum +{ + FFCF_ONLYSPAWNPOS = 1, + FFCF_SAMESECTOR = 2 +}; +void P_FindFloorCeiling (AActor *actor, int flags=0); bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset); diff --git a/src/p_map.cpp b/src/p_map.cpp index 3b66abedf..068f01688 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -170,12 +170,12 @@ static bool PIT_FindFloorCeiling (line_t *ld, const FBoundingBox &box, FCheckPos // //========================================================================== -void P_GetFloorCeilingZ(FCheckPosition &tmf, bool get) +void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags) { sector_t *sec; - if (get) + if (!(flags & FFCF_ONLYSPAWNPOS)) { - sec = P_PointInSector (tmf.x, tmf.y); + sec = !(flags & FFCF_SAMESECTOR) ? P_PointInSector (tmf.x, tmf.y) : sec = tmf.thing->Sector; tmf.floorsector = sec; tmf.ceilingsector = sec; @@ -184,7 +184,10 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, bool get) tmf.floorpic = sec->GetTexture(sector_t::floor); tmf.ceilingpic = sec->GetTexture(sector_t::ceiling); } - else sec = tmf.thing->Sector; + else + { + sec = tmf.thing->Sector; + } #ifdef _3DFLOORS for(unsigned int i=0;ie->XFloor.ffloors.Size();i++) @@ -219,7 +222,7 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, bool get) // //========================================================================== -void P_FindFloorCeiling (AActor *actor, bool onlyspawnpos) +void P_FindFloorCeiling (AActor *actor, int flags) { FCheckPosition tmf; @@ -228,9 +231,9 @@ void P_FindFloorCeiling (AActor *actor, bool onlyspawnpos) tmf.y = actor->y; tmf.z = actor->z; - if (!onlyspawnpos) + if (!(flags & FFCF_ONLYSPAWNPOS)) { - P_GetFloorCeilingZ(tmf, true); + P_GetFloorCeilingZ(tmf, flags); } else { @@ -240,7 +243,7 @@ void P_FindFloorCeiling (AActor *actor, bool onlyspawnpos) tmf.ceilingz = actor->ceilingz; tmf.floorpic = actor->floorpic; tmf.ceilingpic = actor->ceilingpic; - P_GetFloorCeilingZ(tmf, false); + P_GetFloorCeilingZ(tmf, flags); } actor->floorz = tmf.floorz; actor->dropoffz = tmf.dropoffz; @@ -266,7 +269,7 @@ void P_FindFloorCeiling (AActor *actor, bool onlyspawnpos) if (tmf.touchmidtex) tmf.dropoffz = tmf.floorz; - if (!onlyspawnpos || (tmf.abovemidtex && (tmf.floorz <= actor->z))) + if (!(flags & FFCF_ONLYSPAWNPOS) || (tmf.abovemidtex && (tmf.floorz <= actor->z))) { actor->floorz = tmf.floorz; actor->dropoffz = tmf.dropoffz; @@ -321,7 +324,7 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr tmf.z = z; tmf.touchmidtex = false; tmf.abovemidtex = false; - P_GetFloorCeilingZ(tmf, true); + P_GetFloorCeilingZ(tmf, FFCF_ONLYSPAWNPOS); spechit.Clear (); diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 05c248695..477ed3504 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -578,7 +578,7 @@ void AActor::SetOrigin (fixed_t ix, fixed_t iy, fixed_t iz) LinkToWorld (); floorz = Sector->floorplane.ZatPoint (ix, iy); ceilingz = Sector->ceilingplane.ZatPoint (ix, iy); - P_FindFloorCeiling(this, true); + P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS); } FBlockNode *FBlockNode::FreeBlocks = NULL; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 1829fe4c0..494218285 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2476,12 +2476,34 @@ void P_NightmareRespawn (AActor *mobj) // can use P_CheckPosition() properly. mo->z = mo->floorz; } + if (mo->z + mo->height > mo->ceilingz) + { + mo->z = mo->ceilingz - mo->height; + } } else if (z == ONCEILINGZ) { mo->z -= mobj->SpawnPoint[2]; } + // If there are 3D floors, we need to find floor/ceiling again. + P_FindFloorCeiling(mo, FFCF_SAMESECTOR); + + if (z == ONFLOORZ) + { + 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; + } + if (mo->z + mo->height > mo->ceilingz) + { // Do the same for the ceiling. + mo->z = mo->ceilingz - mo->height; + } + } + // something is occupying its position? if (!P_CheckPosition(mo, mo->x, mo->y, true)) { @@ -2491,9 +2513,6 @@ void P_NightmareRespawn (AActor *mobj) return; // no respawn } - // If there are 3D floors, we need to find floor/ceiling again. - P_FindFloorCeiling(mo, true); - z = mo->z; // inherit attributes from deceased one @@ -3629,7 +3648,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t // z-coordinate. if (!SpawningMapThing) { - P_FindFloorCeiling(actor, true); + P_FindFloorCeiling(actor, FFCF_ONLYSPAWNPOS); } else { @@ -4495,7 +4514,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->SpawnPoint[2] = mthing->z; mobj->SpawnAngle = mthing->angle; mobj->SpawnFlags = mthing->flags; - P_FindFloorCeiling(mobj, true); + P_FindFloorCeiling(mobj, FFCF_ONLYSPAWNPOS); if (!(mobj->flags2 & MF2_ARGSDEFINED)) { diff --git a/src/p_user.cpp b/src/p_user.cpp index bd1e04340..797017d48 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -542,7 +542,7 @@ void APlayerPawn::PostBeginPlay() { dropoffz = floorz = Sector->floorplane.ZatPoint(x, y); ceilingz = Sector->ceilingplane.ZatPoint(x, y); - P_FindFloorCeiling(this, true); + P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS); z = floorz; } else diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 451f36505..5b070c003 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2697,7 +2697,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn) self->dropoffz = self->floorz = sec->floorplane.ZatPoint(self->x, self->y); self->ceilingz = sec->ceilingplane.ZatPoint(self->x, self->y); - P_FindFloorCeiling(self, true); + P_FindFloorCeiling(self, FFCF_ONLYSPAWNPOS); } } else