Fix various segfaults caused by missing P_MobjWasRemoved checks

This commit is contained in:
Gustaf Alhäll 2023-07-15 23:12:01 +02:00 committed by Hanicef
parent 0c59a46d5a
commit 1a53971c39
8 changed files with 152 additions and 42 deletions

View file

@ -541,7 +541,7 @@ boolean P_Move(mobj_t *actor, fixed_t speed)
if (!P_TryMove(actor, tryx, tryy, false)) if (!P_TryMove(actor, tryx, tryy, false))
{ {
if (actor->flags & MF_FLOAT && floatok) if (!P_MobjWasRemoved(actor) && actor->flags & MF_FLOAT && floatok)
{ {
// must adjust height // must adjust height
if (actor->z < tmfloorz) if (actor->z < tmfloorz)
@ -585,6 +585,7 @@ void P_NewChaseDir(mobj_t *actor)
dirtype_t d[3]; dirtype_t d[3];
dirtype_t tdir = DI_NODIR, olddir, turnaround; dirtype_t tdir = DI_NODIR, olddir, turnaround;
I_Assert(!P_MobjWasRemoved(actor));
I_Assert(actor->target != NULL); I_Assert(actor->target != NULL);
I_Assert(!P_MobjWasRemoved(actor->target)); I_Assert(!P_MobjWasRemoved(actor->target));
@ -623,7 +624,7 @@ void P_NewChaseDir(mobj_t *actor)
dirtype_t newdir = diags[((deltay < 0)<<1) + (deltax > 0)]; dirtype_t newdir = diags[((deltay < 0)<<1) + (deltax > 0)];
actor->movedir = newdir; actor->movedir = newdir;
if ((newdir != turnaround) && P_TryWalk(actor)) if ((newdir != turnaround) && (P_TryWalk(actor) || P_MobjWasRemoved(actor)))
return; return;
} }
@ -644,7 +645,7 @@ void P_NewChaseDir(mobj_t *actor)
{ {
actor->movedir = d[1]; actor->movedir = d[1];
if (P_TryWalk(actor)) if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
return; // either moved forward or attacked return; // either moved forward or attacked
} }
@ -652,7 +653,7 @@ void P_NewChaseDir(mobj_t *actor)
{ {
actor->movedir = d[2]; actor->movedir = d[2];
if (P_TryWalk(actor)) if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
return; return;
} }
@ -661,7 +662,7 @@ void P_NewChaseDir(mobj_t *actor)
{ {
actor->movedir =olddir; actor->movedir =olddir;
if (P_TryWalk(actor)) if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
return; return;
} }
@ -674,7 +675,7 @@ void P_NewChaseDir(mobj_t *actor)
{ {
actor->movedir = tdir; actor->movedir = tdir;
if (P_TryWalk(actor)) if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
return; return;
} }
} }
@ -687,7 +688,7 @@ void P_NewChaseDir(mobj_t *actor)
{ {
actor->movedir = tdir; actor->movedir = tdir;
if (P_TryWalk(actor)) if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
return; return;
} }
} }
@ -697,7 +698,7 @@ void P_NewChaseDir(mobj_t *actor)
{ {
actor->movedir = turnaround; actor->movedir = turnaround;
if (P_TryWalk(actor)) if (P_TryWalk(actor) || P_MobjWasRemoved(actor))
return; return;
} }
@ -1100,7 +1101,7 @@ nomissile:
return; // got a new target return; // got a new target
// chase towards player // chase towards player
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
P_NewChaseDir(actor); P_NewChaseDir(actor);
} }
@ -1188,7 +1189,7 @@ nomissile:
return; // got a new target return; // got a new target
// chase towards player // chase towards player
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
P_NewChaseDir(actor); P_NewChaseDir(actor);
} }
@ -1267,7 +1268,8 @@ void A_FaceStabRev(mobj_t *actor)
else else
{ {
P_TryMove(actor, actor->x - P_ReturnThrustX(actor, actor->angle, 2<<FRACBITS), actor->y - P_ReturnThrustY(actor, actor->angle, 2<<FRACBITS), false); P_TryMove(actor, actor->x - P_ReturnThrustX(actor, actor->angle, 2<<FRACBITS), actor->y - P_ReturnThrustY(actor, actor->angle, 2<<FRACBITS), false);
P_FaceStabFlume(actor); if (!P_MobjWasRemoved(actor))
P_FaceStabFlume(actor);
} }
} }
} }
@ -1333,8 +1335,9 @@ void A_FaceStabHurl(mobj_t *actor)
while (step > 0) while (step > 0)
{ {
if (!hwork->hnext) if (P_MobjWasRemoved(hwork->hnext))
P_SetTarget(&hwork->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_FACESTABBERSPEAR)); P_SetTarget(&hwork->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_FACESTABBERSPEAR));
if (!P_MobjWasRemoved(hwork->hnext)) if (!P_MobjWasRemoved(hwork->hnext))
{ {
hwork = hwork->hnext; hwork = hwork->hnext;
@ -1343,6 +1346,20 @@ void A_FaceStabHurl(mobj_t *actor)
P_SetScale(hwork, hwork->destscale); P_SetScale(hwork, hwork->destscale);
hwork->fuse = 2; hwork->fuse = 2;
P_MoveOrigin(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS))); P_MoveOrigin(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS)));
if (P_MobjWasRemoved(hwork))
{
// if one of the sections are removed, erase the entire damn thing.
mobj_t *hnext = actor->hnext;
hwork = actor;
do
{
hnext = hwork->hnext;
P_RemoveMobj(hwork);
hwork = hnext;
}
while (!P_MobjWasRemoved(hwork));
return;
}
} }
step -= NUMGRADS; step -= NUMGRADS;
} }
@ -1359,11 +1376,14 @@ void A_FaceStabHurl(mobj_t *actor)
#undef NUMGRADS #undef NUMGRADS
#undef NUMSTEPS #undef NUMSTEPS
} }
if (P_MobjWasRemoved(actor))
return;
} }
} }
P_SetMobjState(actor, locvar2); P_SetMobjState(actor, locvar2);
actor->reactiontime = actor->info->reactiontime; if (!P_MobjWasRemoved(actor))
actor->reactiontime = actor->info->reactiontime;
} }
// Function: A_FaceStabMiss // Function: A_FaceStabMiss
@ -1393,6 +1413,8 @@ void A_FaceStabMiss(mobj_t *actor)
actor->y + P_ReturnThrustY(actor, actor->angle, actor->extravalue2<<FRACBITS), actor->y + P_ReturnThrustY(actor, actor->angle, actor->extravalue2<<FRACBITS),
false)) false))
{ {
if (P_MobjWasRemoved(actor))
return;
actor->extravalue2 = 0; actor->extravalue2 = 0;
P_SetMobjState(actor, locvar2); P_SetMobjState(actor, locvar2);
} }
@ -1425,6 +1447,8 @@ void A_StatueBurst(mobj_t *actor)
P_SetTarget(&new->target, actor->target); P_SetTarget(&new->target, actor->target);
if (locvar2) if (locvar2)
P_SetMobjState(new, (statenum_t)locvar2); P_SetMobjState(new, (statenum_t)locvar2);
if (P_MobjWasRemoved(new))
return;
S_StartSound(new, new->info->attacksound); S_StartSound(new, new->info->attacksound);
S_StopSound(actor); S_StopSound(actor);
S_StartSound(actor, sfx_s3k96); S_StartSound(actor, sfx_s3k96);
@ -1520,7 +1544,7 @@ void A_JetJawChomp(mobj_t *actor)
} }
// chase towards player // chase towards player
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
P_NewChaseDir(actor); P_NewChaseDir(actor);
} }
@ -1941,14 +1965,15 @@ void A_SharpChase(mobj_t *actor)
} }
// chase towards player // chase towards player
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
P_NewChaseDir(actor); P_NewChaseDir(actor);
} }
else else
{ {
actor->threshold = actor->info->painchance; actor->threshold = actor->info->painchance;
P_SetMobjState(actor, actor->info->missilestate); P_SetMobjState(actor, actor->info->missilestate);
S_StartSound(actor, actor->info->attacksound); if (!P_MobjWasRemoved(actor))
S_StartSound(actor, actor->info->attacksound);
} }
} }
@ -2034,6 +2059,8 @@ void A_CrushstaceanWalk(mobj_t *actor)
false) false)
|| (actor->reactiontime-- <= 0)) || (actor->reactiontime-- <= 0))
{ {
if (P_MobjWasRemoved(actor))
return;
actor->flags2 ^= MF2_AMBUSH; actor->flags2 ^= MF2_AMBUSH;
P_SetTarget(&actor->target, NULL); P_SetTarget(&actor->target, NULL);
P_SetMobjState(actor, locvar2); P_SetMobjState(actor, locvar2);
@ -2215,6 +2242,8 @@ void A_CrushclawLaunch(mobj_t *actor)
true) true)
&& !locvar1) && !locvar1)
{ {
if (P_MobjWasRemoved(actor))
return;
actor->extravalue1 = 0; actor->extravalue1 = 0;
actor->extravalue2 = FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y)>>FRACBITS; actor->extravalue2 = FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y)>>FRACBITS;
P_SetMobjState(actor, locvar2); P_SetMobjState(actor, locvar2);
@ -2223,6 +2252,8 @@ void A_CrushclawLaunch(mobj_t *actor)
} }
else else
{ {
if (P_MobjWasRemoved(actor))
return;
actor->z = actor->target->z; actor->z = actor->target->z;
if ((!locvar1 && (actor->extravalue2 > 256)) || (locvar1 && (actor->extravalue2 < 16))) if ((!locvar1 && (actor->extravalue2 > 256)) || (locvar1 && (actor->extravalue2 < 16)))
{ {
@ -2648,7 +2679,7 @@ nomissile:
return; // got a new target return; // got a new target
// chase towards player // chase towards player
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
P_NewChaseDir(actor); P_NewChaseDir(actor);
} }
@ -5788,7 +5819,11 @@ void A_MinusDigging(mobj_t *actor)
if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2) if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2)
{ {
P_SetMobjState(actor, actor->info->meleestate); P_SetMobjState(actor, actor->info->meleestate);
if (P_MobjWasRemoved(actor))
return;
P_TryMove(actor, actor->target->x, actor->target->y, false); P_TryMove(actor, actor->target->x, actor->target->y, false);
if (P_MobjWasRemoved(actor))
return;
S_StartSound(actor, actor->info->attacksound); S_StartSound(actor, actor->info->attacksound);
// Spawn growing dirt pile. // Spawn growing dirt pile.
@ -5796,6 +5831,8 @@ void A_MinusDigging(mobj_t *actor)
if (P_MobjWasRemoved(par)) if (P_MobjWasRemoved(par))
return; return;
P_SetMobjState(par, actor->info->raisestate); P_SetMobjState(par, actor->info->raisestate);
if (P_MobjWasRemoved(par))
return;
P_SetScale(par, actor->scale*2); P_SetScale(par, actor->scale*2);
if (actor->eflags & MFE_VERTICALFLIP) if (actor->eflags & MFE_VERTICALFLIP)
par->eflags |= MFE_VERTICALFLIP; par->eflags |= MFE_VERTICALFLIP;
@ -5809,6 +5846,8 @@ void A_MinusDigging(mobj_t *actor)
// Move // Move
var1 = 3; var1 = 3;
A_Chase(actor); A_Chase(actor);
if (P_MobjWasRemoved(actor))
return;
// Carry over shit, maybe // Carry over shit, maybe
if (P_MobjWasRemoved(actor->tracer) || !actor->tracer->health) if (P_MobjWasRemoved(actor->tracer) || !actor->tracer->health)
@ -5832,7 +5871,7 @@ void A_MinusDigging(mobj_t *actor)
{ {
if (P_TryMove(actor->tracer, actor->x, actor->y, false)) if (P_TryMove(actor->tracer, actor->x, actor->y, false))
actor->tracer->z = mz; actor->tracer->z = mz;
else else if (!P_MobjWasRemoved(actor))
P_SetTarget(&actor->tracer, NULL); P_SetTarget(&actor->tracer, NULL);
} }
} }
@ -7304,7 +7343,7 @@ nomissile:
// chase towards player // chase towards player
if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) > actor->radius+actor->target->radius) if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) > actor->radius+actor->target->radius)
{ {
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
P_NewChaseDir(actor); P_NewChaseDir(actor);
} }
// too close, don't want to chase. // too close, don't want to chase.
@ -7661,7 +7700,7 @@ void A_Boss7Chase(mobj_t *actor)
if (leveltime & 1) if (leveltime & 1)
{ {
// chase towards player // chase towards player
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) if (--actor->movecount < 0 || (!P_Move(actor, actor->info->speed) && !P_MobjWasRemoved(actor)))
P_NewChaseDir(actor); P_NewChaseDir(actor);
} }
} }
@ -8119,6 +8158,8 @@ void A_GuardChase(mobj_t *actor)
false) false)
&& speed > 0) // can't be the same check as previous so that P_TryMove gets to happen. && speed > 0) // can't be the same check as previous so that P_TryMove gets to happen.
{ {
if (P_MobjWasRemoved(actor))
return;
INT32 direction = actor->spawnpoint ? actor->spawnpoint->args[0] : TMGD_BACK; INT32 direction = actor->spawnpoint ? actor->spawnpoint->args[0] : TMGD_BACK;
switch (direction) switch (direction)
@ -8135,6 +8176,8 @@ void A_GuardChase(mobj_t *actor)
break; break;
} }
} }
if (P_MobjWasRemoved(actor))
return;
if (actor->extravalue1 < actor->info->speed) if (actor->extravalue1 < actor->info->speed)
actor->extravalue1++; actor->extravalue1++;
@ -8171,7 +8214,11 @@ void A_GuardChase(mobj_t *actor)
// chase towards player // chase towards player
if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed)) if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed))
{ {
if (P_MobjWasRemoved(actor))
return;
P_NewChaseDir(actor); P_NewChaseDir(actor);
if (P_MobjWasRemoved(actor))
return;
actor->movecount += 5; // Increase tics before change in direction allowed. actor->movecount += 5; // Increase tics before change in direction allowed.
} }
} }
@ -8641,6 +8688,9 @@ void A_PlaySeeSound(mobj_t *actor)
if (LUA_CallAction(A_PLAYSEESOUND, actor)) if (LUA_CallAction(A_PLAYSEESOUND, actor))
return; return;
if (P_MobjWasRemoved(actor))
return;
if (actor->info->seesound) if (actor->info->seesound)
S_StartScreamSound(actor, actor->info->seesound); S_StartScreamSound(actor, actor->info->seesound);
} }
@ -11735,7 +11785,13 @@ void A_BrakChase(mobj_t *actor)
// chase towards player // chase towards player
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed))
{
if (P_MobjWasRemoved(actor))
return;
P_NewChaseDir(actor); P_NewChaseDir(actor);
if (P_MobjWasRemoved(actor))
return;
}
// Optionally play a sound effect // Optionally play a sound effect
if (locvar2 > 0 && locvar2 < NUMSFX) if (locvar2 > 0 && locvar2 < NUMSFX)
@ -13314,6 +13370,8 @@ void A_DoNPCSkid(mobj_t *actor)
if ((FixedHypot(actor->momx, actor->momy) < locvar2) if ((FixedHypot(actor->momx, actor->momy) < locvar2)
|| !P_TryMove(actor, actor->x + actor->momx, actor->y + actor->momy, false)) || !P_TryMove(actor, actor->x + actor->momx, actor->y + actor->momy, false))
{ {
if (P_MobjWasRemoved(actor))
return;
actor->momx = actor->momy = 0; actor->momx = actor->momy = 0;
P_SetMobjState(actor, locvar1); P_SetMobjState(actor, locvar1);
return; return;
@ -13856,6 +13914,8 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing)
y = dustdevil->y; y = dustdevil->y;
} }
P_TryMove(thing, x - thing->momx, y - thing->momy, true); P_TryMove(thing, x - thing->momx, y - thing->momy, true);
if (P_MobjWasRemoved(thing))
return false;
} }
else else
{ //Player on the top of the tornado. { //Player on the top of the tornado.
@ -14260,6 +14320,8 @@ static void P_SnapperLegPlace(mobj_t *mo)
seg->z = mo->z + ((mo->eflags & MFE_VERTICALFLIP) ? (((mo->height<<1)/3) - seg->height) : mo->height/3); seg->z = mo->z + ((mo->eflags & MFE_VERTICALFLIP) ? (((mo->height<<1)/3) - seg->height) : mo->height/3);
P_TryMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, true); P_TryMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, true);
if (P_MobjWasRemoved(seg))
return;
seg->angle = a; seg->angle = a;
// Move as many legs as available. // Move as many legs as available.
@ -14281,6 +14343,8 @@ static void P_SnapperLegPlace(mobj_t *mo)
y = s*o2 - c*o1; y = s*o2 - c*o1;
seg->z = mo->z + (((mo->eflags & MFE_VERTICALFLIP) ? (mo->height - seg->height) : 0)); seg->z = mo->z + (((mo->eflags & MFE_VERTICALFLIP) ? (mo->height - seg->height) : 0));
P_TryMove(seg, mo->x + x, mo->y + y, true); P_TryMove(seg, mo->x + x, mo->y + y, true);
if (P_MobjWasRemoved(seg))
return;
P_SetMobjState(seg, seg->info->raisestate); P_SetMobjState(seg, seg->info->raisestate);
} }
else else
@ -14424,6 +14488,8 @@ void A_SnapperThinker(mobj_t *actor)
s = FINESINE(fa); s = FINESINE(fa);
P_TryMove(actor, actor->x + c*speed, actor->y + s*speed, false); P_TryMove(actor, actor->x + c*speed, actor->y + s*speed, false);
if (P_MobjWasRemoved(actor))
return;
// The snapper spawns dust if going fast! // The snapper spawns dust if going fast!
if (actor->reactiontime < 4) if (actor->reactiontime < 4)

View file

@ -1397,11 +1397,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
i = 0; i = 0;
for (; special->type == MT_HOOP; special = special->hnext) for (; special->type == MT_HOOP; special = special->hnext)
{ {
special->fuse = 11; if (!P_MobjWasRemoved(special->target))
special->movedir = i; {
special->extravalue1 = special->target->extravalue1; special->fuse = 11;
special->extravalue2 = special->target->extravalue2; special->movedir = i;
special->target->threshold = 4242; special->extravalue1 = special->target->extravalue1;
special->extravalue2 = special->target->extravalue2;
special->target->threshold = 4242;
}
i++; i++;
} }
// Make the collision detectors disappear. // Make the collision detectors disappear.

View file

@ -2734,7 +2734,7 @@ increment_move
tryy = y; tryy = y;
} }
if (!P_CheckPosition(thing, tryx, tryy)) if (!P_CheckPosition(thing, tryx, tryy) || P_MobjWasRemoved(thing))
return false; // solid wall or thing return false; // solid wall or thing
if (!(thing->flags & MF_NOCLIP)) if (!(thing->flags & MF_NOCLIP))
@ -2958,6 +2958,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
{ {
fixed_t tryx, tryy; fixed_t tryx, tryy;
I_Assert(!P_MobjWasRemoved(thing));
tryx = thing->x; tryx = thing->x;
tryy = thing->y; tryy = thing->y;
@ -2975,7 +2976,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
else else
tryy = y; tryy = y;
if (!P_CheckPosition(thing, tryx, tryy)) if (!P_CheckPosition(thing, tryx, tryy) || P_MobjWasRemoved(thing))
return false; // solid wall or thing return false; // solid wall or thing
if (!(thing->flags & MF_NOCLIP)) if (!(thing->flags & MF_NOCLIP))
@ -3714,6 +3715,12 @@ static void P_CheckLavaWall(mobj_t *mo, sector_t *sec)
} }
} }
static inline void P_StairStepSlideMove(mobj_t *mo)
{
if (!P_TryMove(mo, mo->x, mo->y + mo->momy, true) && !P_MobjWasRemoved(mo)) //Allow things to drop off.
P_TryMove(mo, mo->x + mo->momx, mo->y, true);
}
// //
// P_SlideMove // P_SlideMove
// The momx / momy move is bad, so try to slide // The momx / momy move is bad, so try to slide
@ -3735,6 +3742,8 @@ void P_SlideMove(mobj_t *mo)
memset(&junk, 0x00, sizeof(junk)); memset(&junk, 0x00, sizeof(junk));
I_Assert(!P_MobjWasRemoved(mo));
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height) if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
{ {
// Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already. // Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already.
@ -3869,7 +3878,10 @@ void P_SlideMove(mobj_t *mo)
retry: retry:
if ((++hitcount == 3) || papercol) if ((++hitcount == 3) || papercol)
goto stairstep; // don't loop forever {
P_StairStepSlideMove(mo);
return;
}
// trace along the three leading corners // trace along the three leading corners
if (mo->momx > 0) if (mo->momx > 0)
@ -3921,9 +3933,7 @@ papercollision:
if (bestslidefrac == FRACUNIT+1) if (bestslidefrac == FRACUNIT+1)
{ {
// the move must have hit the middle, so stairstep // the move must have hit the middle, so stairstep
stairstep: P_StairStepSlideMove(mo);
if (!P_TryMove(mo, mo->x, mo->y + mo->momy, true)) //Allow things to drop off.
P_TryMove(mo, mo->x + mo->momx, mo->y, true);
return; return;
} }
@ -3935,7 +3945,13 @@ stairstep:
newy = FixedMul(mo->momy, bestslidefrac); newy = FixedMul(mo->momy, bestslidefrac);
if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true)) if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true))
goto stairstep; {
if (!P_MobjWasRemoved(mo))
P_StairStepSlideMove(mo);
return;
}
if (P_MobjWasRemoved(mo))
return;
} }
// Now continue along the wall. // Now continue along the wall.
@ -3986,11 +4002,13 @@ stairstep:
tmymove = 0; tmymove = 0;
} }
if (!P_TryMove(mo, newx, newy, true)) { if (!P_TryMove(mo, newx, newy, true)) {
if (success) if (success || P_MobjWasRemoved(mo))
return; // Good enough!! return; // Good enough!!
else else
goto retry; goto retry;
} }
if (P_MobjWasRemoved(mo))
return;
success = true; success = true;
} while(tmxmove || tmymove); } while(tmxmove || tmymove);
} }

View file

@ -2118,7 +2118,7 @@ void P_RingXYMovement(mobj_t *mo)
I_Assert(mo != NULL); I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo)); I_Assert(!P_MobjWasRemoved(mo));
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy)) if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy) && !P_MobjWasRemoved(mo))
P_SlideMove(mo); P_SlideMove(mo);
} }
@ -2132,8 +2132,10 @@ void P_SceneryXYMovement(mobj_t *mo)
oldx = mo->x; oldx = mo->x;
oldy = mo->y; oldy = mo->y;
if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy)) if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy) && !P_MobjWasRemoved(mo))
P_SlideMove(mo); P_SlideMove(mo);
if (P_MobjWasRemoved(mo))
return;
if ((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz)) if ((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz))
return; // no friction when airborne return; // no friction when airborne
@ -3914,6 +3916,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
} }
else else
P_TryMove(mobj, mobj->x, mobj->y, true); P_TryMove(mobj, mobj->x, mobj->y, true);
if (P_MobjWasRemoved(mobj))
return;
P_CheckCrumblingPlatforms(mobj); P_CheckCrumblingPlatforms(mobj);
@ -4708,6 +4712,8 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t dz)
{ {
seg->z = bz + (dz*(9-s)); seg->z = bz + (dz*(9-s));
P_TryMove(seg, workx + (dx*s), worky + (dy*s), true); P_TryMove(seg, workx + (dx*s), worky + (dy*s), true);
if (P_MobjWasRemoved(seg))
return;
} }
angle += ANGLE_MAX/3; angle += ANGLE_MAX/3;
} }
@ -4945,6 +4951,8 @@ static void P_Boss4Thinker(mobj_t *mobj)
(mobj->spawnpoint->x<<FRACBITS) - P_ReturnThrustX(mobj, mobj->angle, mobj->movefactor), (mobj->spawnpoint->x<<FRACBITS) - P_ReturnThrustX(mobj, mobj->angle, mobj->movefactor),
(mobj->spawnpoint->y<<FRACBITS) - P_ReturnThrustY(mobj, mobj->angle, mobj->movefactor), (mobj->spawnpoint->y<<FRACBITS) - P_ReturnThrustY(mobj, mobj->angle, mobj->movefactor),
true); true);
if (P_MobjWasRemoved(mobj))
return;
P_Boss4PinchSpikeballs(mobj, FixedAngle(mobj->movecount), mobj->z - mobj->watertop - mobjinfo[MT_EGGMOBILE4_MACE].height - mobj->height/2); P_Boss4PinchSpikeballs(mobj, FixedAngle(mobj->movecount), mobj->z - mobj->watertop - mobjinfo[MT_EGGMOBILE4_MACE].height - mobj->height/2);
@ -5514,6 +5522,8 @@ static void P_Boss9Thinker(mobj_t *mobj)
{ {
P_InstaThrust(mobj, mobj->angle, -4*FRACUNIT); P_InstaThrust(mobj, mobj->angle, -4*FRACUNIT);
P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true); P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true);
if (P_MobjWasRemoved(mobj))
return;
mobj->momz -= gravity; mobj->momz -= gravity;
if (mobj->z < mobj->watertop || mobj->z < (mobj->floorz + 16*FRACUNIT)) if (mobj->z < mobj->watertop || mobj->z < (mobj->floorz + 16*FRACUNIT))
{ {
@ -5862,6 +5872,8 @@ static void P_Boss9Thinker(mobj_t *mobj)
P_InstaThrust(mobj, mobj->angle, 30*FRACUNIT); P_InstaThrust(mobj, mobj->angle, 30*FRACUNIT);
if (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true)) if (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true))
{ // Hit a wall? Find a direction to bounce { // Hit a wall? Find a direction to bounce
if (P_MobjWasRemoved(mobj))
return;
mobj->threshold--; mobj->threshold--;
if (!mobj->threshold) { // failed bounce! if (!mobj->threshold) { // failed bounce!
S_StartSound(mobj, sfx_mspogo); S_StartSound(mobj, sfx_mspogo);
@ -5902,6 +5914,8 @@ static void P_Boss9Thinker(mobj_t *mobj)
P_InstaThrust(mobj, mobj->angle, -speed); P_InstaThrust(mobj, mobj->angle, -speed);
while (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true) && tries++ < 16) while (!P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true) && tries++ < 16)
{ {
if (P_MobjWasRemoved(mobj))
return;
S_StartSound(mobj, sfx_mspogo); S_StartSound(mobj, sfx_mspogo);
P_BounceMove(mobj); P_BounceMove(mobj);
mobj->angle = R_PointToAngle2(mobj->momx, mobj->momy,0,0); mobj->angle = R_PointToAngle2(mobj->momx, mobj->momy,0,0);
@ -7501,6 +7515,8 @@ static void P_RosySceneryThink(mobj_t *mobj)
fixed_t x = mobj->x, y = mobj->y, z = mobj->z; fixed_t x = mobj->x, y = mobj->y, z = mobj->z;
angle_t angletoplayer = R_PointToAngle2(x, y, mobj->target->x, mobj->target->y); angle_t angletoplayer = R_PointToAngle2(x, y, mobj->target->x, mobj->target->y);
boolean allowed = P_TryMove(mobj, mobj->target->x, mobj->target->y, false); boolean allowed = P_TryMove(mobj, mobj->target->x, mobj->target->y, false);
if (P_MobjWasRemoved(mobj))
return;
P_UnsetThingPosition(mobj); P_UnsetThingPosition(mobj);
mobj->x = x; mobj->x = x;
@ -8064,7 +8080,8 @@ static void P_MobjSceneryThink(mobj_t *mobj)
break; break;
} }
P_SceneryThinker(mobj); if (!P_MobjWasRemoved(mobj))
P_SceneryThinker(mobj);
} }
static boolean P_MobjPushableThink(mobj_t *mobj) static boolean P_MobjPushableThink(mobj_t *mobj)
@ -10423,6 +10440,8 @@ void P_MobjThinker(mobj_t *mobj)
|| mobj->type == MT_CANNONBALLDECOR || mobj->type == MT_CANNONBALLDECOR
|| mobj->type == MT_FALLINGROCK) { || mobj->type == MT_FALLINGROCK) {
P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly
if (P_MobjWasRemoved(mobj))
return;
//if (mobj->standingslope) CONS_Printf("slope physics on mobj\n"); //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n");
P_ButteredSlope(mobj); P_ButteredSlope(mobj);
} }
@ -10524,6 +10543,8 @@ void P_PushableThinker(mobj_t *mobj)
// it has to be pushable RIGHT NOW for this part to happen // it has to be pushable RIGHT NOW for this part to happen
if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy)) if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy))
P_TryMove(mobj, mobj->x, mobj->y, true); P_TryMove(mobj, mobj->x, mobj->y, true);
if (P_MobjWasRemoved(mobj))
return;
if (mobj->type == MT_MINECART && mobj->health) if (mobj->type == MT_MINECART && mobj->health)
{ {
@ -14017,7 +14038,8 @@ boolean P_CheckMissileSpawn(mobj_t *th)
if (!P_TryMove(th, th->x, th->y, true)) if (!P_TryMove(th, th->x, th->y, true))
{ {
P_ExplodeMissile(th); if (!P_MobjWasRemoved(th))
P_ExplodeMissile(th);
return false; return false;
} }
return true; return true;

View file

@ -844,7 +844,7 @@ void P_Ticker(boolean run)
if (quake.time) if (quake.time)
--quake.time; --quake.time;
if (metalplayback) if (!P_MobjWasRemoved(metalplayback))
G_ReadMetalTic(metalplayback); G_ReadMetalTic(metalplayback);
if (metalrecording) if (metalrecording)
G_WriteMetalTic(players[consoleplayer].mo); G_WriteMetalTic(players[consoleplayer].mo);

View file

@ -11101,7 +11101,8 @@ static void P_MinecartThink(player_t *player)
fa = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; fa = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK;
if (!P_TryMove(minecart, minecart->x + FINECOSINE(fa), minecart->y + FINESINE(fa), true)) if (!P_TryMove(minecart, minecart->x + FINECOSINE(fa), minecart->y + FINESINE(fa), true))
{ {
P_KillMobj(minecart, NULL, NULL, 0); if (!P_MobjWasRemoved(minecart))
P_KillMobj(minecart, NULL, NULL, 0);
return; return;
} }
@ -12455,7 +12456,7 @@ void P_PlayerThink(player_t *player)
player->texttimer = 4*TICRATE; player->texttimer = 4*TICRATE;
player->textvar = 2; // GET n RINGS! player->textvar = 2; // GET n RINGS!
if (player->capsule && player->capsule->health != player->capsule->spawnpoint->angle) if (!P_MobjWasRemoved(player->capsule) && player->capsule->health != player->capsule->spawnpoint->angle)
player->textvar++; // GET n MORE RINGS! player->textvar++; // GET n MORE RINGS!
} }
} }

View file

@ -1363,7 +1363,7 @@ void R_SkyboxFrame(player_t *player)
newview->z += campos.z * -mh->skybox_scalez; newview->z += campos.z * -mh->skybox_scalez;
} }
if (r_viewmobj->subsector) if (!P_MobjWasRemoved(r_viewmobj) && r_viewmobj->subsector)
newview->sector = r_viewmobj->subsector->sector; newview->sector = r_viewmobj->subsector->sector;
else else
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector; newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;

View file

@ -1926,7 +1926,7 @@ static void ST_drawNiGHTSHUD(void)
total_ringcount = stplyr->spheres; total_ringcount = stplyr->spheres;
} }
if (stplyr->capsule) if (!P_MobjWasRemoved(stplyr->capsule))
{ {
INT32 amount; INT32 amount;
const INT32 length = 88; const INT32 length = 88;