From 5ac7ac324198351603d07f8895a53ec906653ff7 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 14 Sep 2007 22:20:08 +0000 Subject: Add P_SubstNullMobj, substitute NULL mobjs for a dummy mobj where mo->target is not checked for NULL. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 971 --- src/p_enemy.c | 37 ++++++++++++++++++++++++++----------- src/p_local.h | 1 + src/p_mobj.c | 55 ++++++++++++++++++++++++++----------------------------- 3 files changed, 53 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/p_enemy.c b/src/p_enemy.c index 0ed7f60f..16d2ff06 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1258,14 +1258,17 @@ void A_FireCrackle (mobj_t* actor) void A_Fire (mobj_t* actor) { mobj_t* dest; + mobj_t* target; unsigned an; dest = actor->tracer; if (!dest) return; + + target = P_SubstNullMobj(actor->target); // don't move it if the vile lost sight - if (!P_CheckSight (actor->target, dest) ) + if (!P_CheckSight (target, dest) ) return; an = dest->angle >> ANGLETOFINESHIFT; @@ -1359,14 +1362,17 @@ void A_FatRaise (mobj_t *actor) void A_FatAttack1 (mobj_t* actor) { mobj_t* mo; + mobj_t* target; int an; - + A_FaceTarget (actor); + // Change direction to ... actor->angle += FATSPREAD; - P_SpawnMissile (actor, actor->target, MT_FATSHOT); + target = P_SubstNullMobj(actor->target); + P_SpawnMissile (actor, target, MT_FATSHOT); - mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT); + mo = P_SpawnMissile (actor, target, MT_FATSHOT); mo->angle += FATSPREAD; an = mo->angle >> ANGLETOFINESHIFT; mo->momx = FixedMul (mo->info->speed, finecosine[an]); @@ -1376,14 +1382,16 @@ void A_FatAttack1 (mobj_t* actor) void A_FatAttack2 (mobj_t* actor) { mobj_t* mo; + mobj_t* target; int an; A_FaceTarget (actor); // Now here choose opposite deviation. actor->angle -= FATSPREAD; - P_SpawnMissile (actor, actor->target, MT_FATSHOT); + target = P_SubstNullMobj(actor->target); + P_SpawnMissile (actor, target, MT_FATSHOT); - mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT); + mo = P_SpawnMissile (actor, target, MT_FATSHOT); mo->angle -= FATSPREAD*2; an = mo->angle >> ANGLETOFINESHIFT; mo->momx = FixedMul (mo->info->speed, finecosine[an]); @@ -1393,17 +1401,20 @@ void A_FatAttack2 (mobj_t* actor) void A_FatAttack3 (mobj_t* actor) { mobj_t* mo; + mobj_t* target; int an; A_FaceTarget (actor); + + target = P_SubstNullMobj(actor->target); - mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT); + mo = P_SpawnMissile (actor, target, MT_FATSHOT); mo->angle -= FATSPREAD/2; an = mo->angle >> ANGLETOFINESHIFT; mo->momx = FixedMul (mo->info->speed, finecosine[an]); mo->momy = FixedMul (mo->info->speed, finesine[an]); - mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT); + mo = P_SpawnMissile (actor, target, MT_FATSHOT); mo->angle += FATSPREAD/2; an = mo->angle >> ANGLETOFINESHIFT; mo->momx = FixedMul (mo->info->speed, finecosine[an]); @@ -1598,7 +1609,11 @@ void A_Fall (mobj_t *actor) // void A_Explode (mobj_t* thingy) { - P_RadiusAttack ( thingy, thingy->target, 128 ); + mobj_t *target; + + target = P_SubstNullMobj(thingy->target); + + P_RadiusAttack(thingy, target, 128); } @@ -1823,7 +1838,7 @@ A_CloseShotgun2 mobj_t* braintargets[32]; int numbraintargets; -int braintargeton; +int braintargeton = 0; void A_BrainAwake (mobj_t* mo) { @@ -1959,7 +1974,7 @@ void A_SpawnFly (mobj_t* mo) if (--mo->reactiontime) return; // still flying - targ = mo->target; + targ = P_SubstNullMobj(mo->target); // First spawn teleport fog. fog = P_SpawnMobj (targ->x, targ->y, targ->z, MT_SPAWNFIRE); diff --git a/src/p_local.h b/src/p_local.h index d58a7708..2e602ad5 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -119,6 +119,7 @@ P_SpawnMobj mobjtype_t type ); void P_RemoveMobj (mobj_t* th); +mobj_t* P_SubstNullMobj (mobj_t* th); boolean P_SetMobjState (mobj_t* mobj, statenum_t state); void P_MobjThinker (mobj_t* mobj); diff --git a/src/p_mobj.c b/src/p_mobj.c index 29dafdec..bb72166d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -922,6 +922,28 @@ void P_CheckMissileSpawn (mobj_t* th) P_ExplodeMissile (th); } +// Certain functions assume that a mobj_t pointer is non-NULL, +// causing a crash in some situations where it is NULL. Vanilla +// Doom did not crash because of the lack of proper memory +// protection. This function substitutes NULL pointers for +// pointers to a dummy mobj, to avoid a crash. + +mobj_t *P_SubstNullMobj(mobj_t *mobj) +{ + if (mobj == NULL) + { + static mobj_t dummy_mobj; + + dummy_mobj.x = 0; + dummy_mobj.y = 0; + dummy_mobj.z = 0; + dummy_mobj.flags = 0; + + mobj = &dummy_mobj; + } + + return mobj; +} // // P_SpawnMissile @@ -935,31 +957,6 @@ P_SpawnMissile mobj_t* th; angle_t an; int dist; - fixed_t dest_x, dest_y, dest_z, dest_flags; - - // fraggle: This prevents against *crashes* when dest == NULL. - // For example, when loading a game saved when a mancubus was - // in the middle of firing, mancubus->target == NULL. SpawnMissile - // then gets called with dest == NULL. - // - // However, this is not the *correct* behavior. At the moment, - // the missile is aimed at 0,0,0. In reality, monsters seem to aim - // somewhere else. - - if (dest) - { - dest_x = dest->x; - dest_y = dest->y; - dest_z = dest->z; - dest_flags = dest->flags; - } - else - { - dest_x = 0; - dest_y = 0; - dest_z = 0; - dest_flags = 0; - } th = P_SpawnMobj (source->x, source->y, @@ -969,10 +966,10 @@ P_SpawnMissile S_StartSound (th, th->info->seesound); th->target = source; // where it came from - an = R_PointToAngle2 (source->x, source->y, dest_x, dest_y); + an = R_PointToAngle2 (source->x, source->y, dest->x, dest->y); // fuzzy player - if (dest_flags & MF_SHADOW) + if (dest->flags & MF_SHADOW) an += (P_Random()-P_Random())<<20; th->angle = an; @@ -980,13 +977,13 @@ P_SpawnMissile th->momx = FixedMul (th->info->speed, finecosine[an]); th->momy = FixedMul (th->info->speed, finesine[an]); - dist = P_AproxDistance (dest_x - source->x, dest_y - source->y); + dist = P_AproxDistance (dest->x - source->x, dest->y - source->y); dist = dist / th->info->speed; if (dist < 1) dist = 1; - th->momz = (dest_z - source->z) / dist; + th->momz = (dest->z - source->z) / dist; P_CheckMissileSpawn (th); return th; -- cgit v1.2.3