diff --git a/src/p_local.h b/src/p_local.h index 0dd0dca68..82f4580b9 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -221,7 +221,7 @@ void P_FakeZMovement (AActor *mo); bool P_TryMove(AActor* thing, const DVector2 &pos, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false); bool P_TryMove(AActor* thing, const DVector2 &pos, int dropoff, const secplane_t * onfloor = NULL); -bool P_CheckMove(AActor *thing, const DVector2 &pos); +bool P_CheckMove(AActor *thing, const DVector2 &pos, bool dropoff = false); void P_ApplyTorque(AActor *mo); bool P_TeleportMove(AActor* thing, const DVector3 &pos, bool telefrag, bool modifyactor = true); // [RH] Added z and telefrag parameters diff --git a/src/p_map.cpp b/src/p_map.cpp index 61e651ce6..15cd5eb5b 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2410,7 +2410,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, // //========================================================================== -bool P_CheckMove(AActor *thing, const DVector2 &pos) +bool P_CheckMove(AActor *thing, const DVector2 &pos, bool dropoff) { FCheckPosition tm; double newz = thing->Z(); @@ -2469,6 +2469,17 @@ bool P_CheckMove(AActor *thing, const DVector2 &pos) return false; } } + else if (dropoff) + { + const DVector3 oldpos = thing->Pos(); + thing->SetOrigin(pos.X, pos.Y, newz, true); + bool hcheck = (newz - thing->MaxDropOffHeight > thing->floorz); + thing->SetOrigin(oldpos, true); + if (hcheck && !(thing->flags & MF_FLOAT) && !(i_compatflags & COMPATF_DROPOFF)) + { + return false; + } + } } if (thing->flags2 & MF2_CANTLEAVEFLOORPIC diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index d0a157932..cc4ffd33b 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -6707,7 +6707,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) if (flags & CBF_DROPOFF) { mobj->SetZ(pos.Z); - checker = P_CheckMove(mobj, pos); + checker = P_CheckMove(mobj, pos, true); mobj->SetZ(oldpos.Z); } else @@ -6742,8 +6742,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) } //[MC] I don't know why I let myself be persuaded not to include a flag. //If an actor is loaded with pointers, they don't really have any options to spare. + //Also, fail if a dropoff or a step is too great to pass over when checking for dropoffs. - if ((!(flags & CBF_NOACTORS) && (mobj->BlockingMobj)) || (!(flags & CBF_NOLINES) && mobj->BlockingLine != NULL)) + if ((!(flags & CBF_NOACTORS) && (mobj->BlockingMobj)) || (!(flags & CBF_NOLINES) && mobj->BlockingLine != NULL) || + ((flags & CBF_DROPOFF) && !checker)) { ACTION_RETURN_STATE(block); }