mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
Fix segfault when calling P_RemoveMobj from MobjCollide hook
This commit is contained in:
parent
d7a84b967c
commit
ecf0c4b45a
1 changed files with 122 additions and 118 deletions
240
src/p_map.c
240
src/p_map.c
|
@ -4005,131 +4005,135 @@ void P_BounceMove(mobj_t *mo)
|
||||||
slidemo = mo;
|
slidemo = mo;
|
||||||
hitcount = 0;
|
hitcount = 0;
|
||||||
|
|
||||||
retry:
|
do
|
||||||
if (++hitcount == 3)
|
{
|
||||||
goto bounceback; // don't loop forever
|
if (++hitcount == 3)
|
||||||
|
goto bounceback; // don't loop forever
|
||||||
|
|
||||||
if (mo->player)
|
if (mo->player)
|
||||||
{
|
|
||||||
mmomx = mo->player->rmomx;
|
|
||||||
mmomy = mo->player->rmomy;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mmomx = mo->momx;
|
|
||||||
mmomy = mo->momy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trace along the three leading corners
|
|
||||||
if (mo->momx > 0)
|
|
||||||
{
|
|
||||||
leadx = mo->x + mo->radius;
|
|
||||||
trailx = mo->x - mo->radius;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
leadx = mo->x - mo->radius;
|
|
||||||
trailx = mo->x + mo->radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mo->momy > 0)
|
|
||||||
{
|
|
||||||
leady = mo->y + mo->radius;
|
|
||||||
traily = mo->y - mo->radius;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
leady = mo->y - mo->radius;
|
|
||||||
traily = mo->y + mo->radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
bestslidefrac = FRACUNIT + 1;
|
|
||||||
|
|
||||||
P_PathTraverse(leadx, leady, leadx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse);
|
|
||||||
P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse);
|
|
||||||
P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse);
|
|
||||||
|
|
||||||
// move up to the wall
|
|
||||||
if (bestslidefrac == FRACUNIT + 1)
|
|
||||||
{
|
|
||||||
// the move must have hit the middle, so bounce straight back
|
|
||||||
bounceback:
|
|
||||||
if (P_TryMove(mo, mo->x - mmomx, mo->y - mmomy, true))
|
|
||||||
{
|
{
|
||||||
mo->momx *= -1;
|
mmomx = mo->player->rmomx;
|
||||||
mo->momy *= -1;
|
mmomy = mo->player->rmomy;
|
||||||
mo->momx = FixedMul(mo->momx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
}
|
||||||
mo->momy = FixedMul(mo->momy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
else
|
||||||
|
{
|
||||||
|
mmomx = mo->momx;
|
||||||
|
mmomy = mo->momy;
|
||||||
|
}
|
||||||
|
|
||||||
if (mo->player)
|
// trace along the three leading corners
|
||||||
|
if (mo->momx > 0)
|
||||||
|
{
|
||||||
|
leadx = mo->x + mo->radius;
|
||||||
|
trailx = mo->x - mo->radius;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leadx = mo->x - mo->radius;
|
||||||
|
trailx = mo->x + mo->radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mo->momy > 0)
|
||||||
|
{
|
||||||
|
leady = mo->y + mo->radius;
|
||||||
|
traily = mo->y - mo->radius;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leady = mo->y - mo->radius;
|
||||||
|
traily = mo->y + mo->radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
bestslidefrac = FRACUNIT + 1;
|
||||||
|
|
||||||
|
P_PathTraverse(leadx, leady, leadx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse);
|
||||||
|
P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse);
|
||||||
|
P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse);
|
||||||
|
|
||||||
|
// move up to the wall
|
||||||
|
if (bestslidefrac == FRACUNIT + 1)
|
||||||
|
{
|
||||||
|
// the move must have hit the middle, so bounce straight back
|
||||||
|
bounceback:
|
||||||
|
if (P_TryMove(mo, mo->x - mmomx, mo->y - mmomy, true))
|
||||||
{
|
{
|
||||||
mo->player->cmomx *= -1;
|
mo->momx *= -1;
|
||||||
mo->player->cmomy *= -1;
|
mo->momy *= -1;
|
||||||
mo->player->cmomx = FixedMul(mo->player->cmomx,
|
mo->momx = FixedMul(mo->momx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
||||||
(FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
mo->momy = FixedMul(mo->momy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
||||||
mo->player->cmomy = FixedMul(mo->player->cmomy,
|
|
||||||
(FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
if (mo->player)
|
||||||
|
{
|
||||||
|
mo->player->cmomx *= -1;
|
||||||
|
mo->player->cmomy *= -1;
|
||||||
|
mo->player->cmomx = FixedMul(mo->player->cmomx,
|
||||||
|
(FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
||||||
|
mo->player->cmomy = FixedMul(mo->player->cmomy,
|
||||||
|
(FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fudge a bit to make sure it doesn't hit
|
||||||
|
bestslidefrac -= 0x800;
|
||||||
|
if (bestslidefrac > 0)
|
||||||
|
{
|
||||||
|
newx = FixedMul(mmomx, bestslidefrac);
|
||||||
|
newy = FixedMul(mmomy, bestslidefrac);
|
||||||
|
|
||||||
|
if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true))
|
||||||
|
{
|
||||||
|
if (P_MobjWasRemoved(mo))
|
||||||
|
return;
|
||||||
|
goto bounceback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
// Now continue along the wall.
|
||||||
|
// First calculate remainder.
|
||||||
|
bestslidefrac = FRACUNIT - bestslidefrac;
|
||||||
|
|
||||||
|
if (bestslidefrac > FRACUNIT)
|
||||||
|
bestslidefrac = FRACUNIT;
|
||||||
|
|
||||||
|
if (bestslidefrac <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mo->type == MT_SHELL)
|
||||||
|
{
|
||||||
|
tmxmove = mmomx;
|
||||||
|
tmymove = mmomy;
|
||||||
|
}
|
||||||
|
else if (mo->type == MT_THROWNBOUNCE)
|
||||||
|
{
|
||||||
|
tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5)));
|
||||||
|
tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5)));
|
||||||
|
}
|
||||||
|
else if (mo->type == MT_THROWNGRENADE || mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE)
|
||||||
|
{
|
||||||
|
// Quickly decay speed as it bounces
|
||||||
|
tmxmove = FixedDiv(mmomx, 2*FRACUNIT);
|
||||||
|
tmymove = FixedDiv(mmomy, 2*FRACUNIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
||||||
|
tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
||||||
|
}
|
||||||
|
|
||||||
|
P_HitBounceLine(bestslideline); // clip the moves
|
||||||
|
|
||||||
|
mo->momx = tmxmove;
|
||||||
|
mo->momy = tmymove;
|
||||||
|
|
||||||
|
if (mo->player)
|
||||||
|
{
|
||||||
|
mo->player->cmomx = tmxmove;
|
||||||
|
mo->player->cmomy = tmymove;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
while (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true) && !P_MobjWasRemoved(mo));
|
||||||
// fudge a bit to make sure it doesn't hit
|
|
||||||
bestslidefrac -= 0x800;
|
|
||||||
if (bestslidefrac > 0)
|
|
||||||
{
|
|
||||||
newx = FixedMul(mmomx, bestslidefrac);
|
|
||||||
newy = FixedMul(mmomy, bestslidefrac);
|
|
||||||
|
|
||||||
if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true))
|
|
||||||
goto bounceback;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now continue along the wall.
|
|
||||||
// First calculate remainder.
|
|
||||||
bestslidefrac = FRACUNIT - bestslidefrac;
|
|
||||||
|
|
||||||
if (bestslidefrac > FRACUNIT)
|
|
||||||
bestslidefrac = FRACUNIT;
|
|
||||||
|
|
||||||
if (bestslidefrac <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (mo->type == MT_SHELL)
|
|
||||||
{
|
|
||||||
tmxmove = mmomx;
|
|
||||||
tmymove = mmomy;
|
|
||||||
}
|
|
||||||
else if (mo->type == MT_THROWNBOUNCE)
|
|
||||||
{
|
|
||||||
tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5)));
|
|
||||||
tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5)));
|
|
||||||
}
|
|
||||||
else if (mo->type == MT_THROWNGRENADE || mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE)
|
|
||||||
{
|
|
||||||
// Quickly decay speed as it bounces
|
|
||||||
tmxmove = FixedDiv(mmomx, 2*FRACUNIT);
|
|
||||||
tmymove = FixedDiv(mmomy, 2*FRACUNIT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
|
||||||
tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
|
|
||||||
}
|
|
||||||
|
|
||||||
P_HitBounceLine(bestslideline); // clip the moves
|
|
||||||
|
|
||||||
mo->momx = tmxmove;
|
|
||||||
mo->momy = tmymove;
|
|
||||||
|
|
||||||
if (mo->player)
|
|
||||||
{
|
|
||||||
mo->player->cmomx = tmxmove;
|
|
||||||
mo->player->cmomy = tmymove;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true))
|
|
||||||
goto retry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue