Ensure BlockingMobj checks don't fail on destroyed Actors when handling physics
This commit is contained in:
parent
12fac42bab
commit
9a4c2dc111
3 changed files with 19 additions and 16 deletions
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue