diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 211f459f4..575e16d2b 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -4757,14 +4757,15 @@ DEFINE_ACTION_FUNCTION(AActor, CheckBlock) ACTION_RETURN_BOOL(false); } - if (mobj->BlockingMobj) + auto blocking = mobj->BlockingMobj.ForceGet(); + if (blocking != nullptr && !(blocking->ObjectFlags & OF_EuthanizeMe)) { AActor *setter = (flags & CBF_SETONPTR) ? mobj : self; if (setter) { - if (flags & CBF_SETTARGET) setter->target = mobj->BlockingMobj; - if (flags & CBF_SETMASTER) setter->master = mobj->BlockingMobj; - if (flags & CBF_SETTRACER) setter->tracer = mobj->BlockingMobj; + if (flags & CBF_SETTARGET) setter->target = blocking; + if (flags & CBF_SETMASTER) setter->master = blocking; + if (flags & CBF_SETTRACER) setter->tracer = blocking; } } @@ -4772,7 +4773,7 @@ DEFINE_ACTION_FUNCTION(AActor, CheckBlock) //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. - ACTION_RETURN_BOOL((!(flags & CBF_NOACTORS) && (mobj->BlockingMobj)) || (!(flags & CBF_NOLINES) && mobj->BlockingLine != NULL) || + ACTION_RETURN_BOOL((!(flags & CBF_NOACTORS) && blocking != nullptr) || (!(flags & CBF_NOLINES) && mobj->BlockingLine != NULL) || ((flags & CBF_DROPOFF) && !checker)); } diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index d397f8938..c33d74310 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -1549,7 +1549,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch // Check for skulls slamming into things if (tm.thing->flags & MF_SKULLFLY) { - bool res = tm.thing->CallSlam(tm.thing->BlockingMobj); + bool res = tm.thing->CallSlam(tm.thing->BlockingMobj.ForceGet()); tm.thing->BlockingMobj = NULL; return res; } @@ -1896,7 +1896,7 @@ bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, boo // other things in the blocks and see if we hit something that is // definitely blocking. Otherwise, we need to check the lines, or we // could end up stuck inside a wall. - AActor* BlockingMobj = thing->BlockingMobj; + AActor* BlockingMobj = thing->BlockingMobj.ForceGet(); // If this blocks through a restricted line portal, it will always completely block. if (BlockingMobj == NULL || (thing->Level->i_compatflags & COMPATF_NO_PASSMOBJ) || (tcres.portalflags & FFCF_RESTRICTEDPORTAL)) @@ -2060,7 +2060,7 @@ AActor *P_CheckOnmobj(AActor *thing) good = P_TestMobjZ(thing, false, &onmobj); // Make sure we don't double call a collision with it. - if (!good && onmobj != nullptr && onmobj != thing->BlockingMobj + if (!good && onmobj != nullptr && onmobj != thing->BlockingMobj.ForceGet() && (thing->player == nullptr || !(thing->player->cheats & CF_PREDICTING))) { P_CollidedWith(thing, onmobj); @@ -2360,7 +2360,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, thing->flags6 |= MF6_INTRYMOVE; if (!P_CheckPosition(thing, pos, tm)) { - AActor *BlockingMobj = thing->BlockingMobj; + AActor *BlockingMobj = thing->BlockingMobj.ForceGet(); // This gets called regardless of whether or not the following checks allow the thing to pass. This is because a player // could step on top of an enemy but we still want it to register as a collision. if (BlockingMobj != nullptr && (thing->player == nullptr || !(thing->player->cheats & CF_PREDICTING))) @@ -2646,8 +2646,9 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, thing->SetXYZ(thingpos.X, thingpos.Y, pos.Z); if (!P_CheckPosition(thing, pos.XY(), true)) // check if some actor blocks us on the other side. (No line checks, because of the mess that'd create.) { - if (thing->BlockingMobj != nullptr && (thing->player == nullptr || !(thing->player->cheats && CF_PREDICTING))) - P_CollidedWith(thing, thing->BlockingMobj); + auto blocking = thing->BlockingMobj.ForceGet(); + if (blocking != nullptr && (thing->player == nullptr || !(thing->player->cheats && CF_PREDICTING))) + P_CollidedWith(thing, blocking); thing->SetXYZ(oldthingpos); thing->flags6 &= ~MF6_INTRYMOVE; @@ -2887,7 +2888,7 @@ bool P_CheckMove(AActor *thing, const DVector2 &pos, FCheckPosition& tm, int fla { return false; } - if (!(flags & PCM_NOACTORS) && thing->BlockingMobj) + if (!(flags & PCM_NOACTORS) && thing->BlockingMobj.ForceGet()) { return false; } diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 33c44facc..260ecf623 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -2597,7 +2597,7 @@ static double P_XYMovement (AActor *mo, DVector2 scroll) if (!P_TryMove (mo, ptry, true, walkplane, tm)) { // blocked move - AActor *BlockingMobj = mo->BlockingMobj; + AActor *BlockingMobj = mo->BlockingMobj.ForceGet(); line_t *BlockingLine = mo->MovementBlockingLine = mo->BlockingLine; // [ZZ] @@ -4944,7 +4944,7 @@ void AActor::Tick () } } - if (Vel.Z != 0 || BlockingMobj || Z() != floorz) + if (Vel.Z != 0 || BlockingMobj.ForceGet() || Z() != floorz) { // Handle Z velocity and gravity if (((flags2 & MF2_PASSMOBJ) || (flags & MF_SPECIAL)) && !(Level->i_compatflags & COMPATF_NO_PASSMOBJ)) { @@ -7611,7 +7611,8 @@ bool P_CheckMissileSpawn (AActor* th, double maxdist) if (!(P_TryMove (th, newpos.XY(), false, NULL, tm, true))) { // [RH] Don't explode ripping missiles that spawn inside something - if (th->BlockingMobj == NULL || !(th->flags2 & MF2_RIP) || (th->BlockingMobj->flags5 & MF5_DONTRIP)) + auto blocking = th->BlockingMobj.ForceGet(); + if (blocking == NULL || !(th->flags2 & MF2_RIP) || (blocking->flags5 & MF5_DONTRIP)) { // If this is a monster spawned by A_SpawnProjectile subtract it from the counter. th->ClearCounters(); @@ -7626,7 +7627,7 @@ bool P_CheckMissileSpawn (AActor* th, double maxdist) } else { - P_ExplodeMissile (th, th->BlockingLine, th->BlockingMobj); + P_ExplodeMissile (th, th->BlockingLine, blocking); } return false; }