Skip to content

Commit

Permalink
Fixed|All Games: Latent links to deceased mobjs in the Blockmap
Browse files Browse the repository at this point in the history
Whenever a mobj is moved on the XY plane, regardless of the distance,
it is paramount that the engine is informed of the move. This means
calling P_MobjUnlink() beforehand, then adjusting the origin and then
finalizing the move by calling P_MobjLink().
  • Loading branch information
danij-deng committed Oct 9, 2013
1 parent 00d2eb3 commit 9c2631c
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 17 deletions.
33 changes: 19 additions & 14 deletions doomsday/plugins/doom/src/p_enemy.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,9 +890,9 @@ void C_DECL A_BruisAttack(mobj_t *actor)
P_SpawnMissile(MT_BRUISERSHOT, actor, actor->target);
}

void C_DECL A_SkelMissile(mobj_t* actor)
void C_DECL A_SkelMissile(mobj_t *actor)
{
mobj_t* mo;
mobj_t *mo;

if(!actor->target) return;

Expand All @@ -901,8 +901,10 @@ void C_DECL A_SkelMissile(mobj_t* actor)
mo = P_SpawnMissile(MT_TRACER, actor, actor->target);
if(mo)
{
P_MobjUnlink(mo);
mo->origin[VX] += mo->mom[MX];
mo->origin[VY] += mo->mom[MY];
P_MobjLink(mo);
mo->tracer = actor->target;
}
}
Expand Down Expand Up @@ -1150,9 +1152,10 @@ void C_DECL A_FireCrackle(mobj_t* actor)
/**
* Keep fire in front of player unless out of sight.
*/
void C_DECL A_Fire(mobj_t* actor)
void C_DECL A_Fire(mobj_t *actor)
{
mobj_t* dest;
mobj_t *dest;
vec3d_t offset;
uint an;

dest = actor->tracer;
Expand All @@ -1164,9 +1167,8 @@ void C_DECL A_Fire(mobj_t* actor)
an = dest->angle >> ANGLETOFINESHIFT;

P_MobjUnlink(actor);
memcpy(actor->origin, dest->origin, sizeof(actor->origin));
actor->origin[VX] += 24 * FIX2FLT(finecosine[an]);
actor->origin[VY] += 24 * FIX2FLT(finesine[an]);
V3d_Set(offset, 24 * FIX2FLT(finecosine[an]), 24 * FIX2FLT(finesine[an]), 0);
V3d_Sum(actor->origin, dest->origin, offset);
P_MobjLink(actor);
}

Expand All @@ -1191,31 +1193,34 @@ void C_DECL A_VileTarget(mobj_t* actor)
}
}

void C_DECL A_VileAttack(mobj_t* actor)
void C_DECL A_VileAttack(mobj_t *actor)
{
mobj_t* fire;
mobj_t *fire;
uint an;

if(!actor->target) return;

A_FaceTarget(actor);

if(!P_CheckSight(actor, actor->target)) return;
if(!P_CheckSight(actor, actor->target))
{
return;
}

S_StartSound(SFX_BAREXP, actor);
P_DamageMobj(actor->target, actor, actor, 20, false);
actor->target->mom[MZ] =
FIX2FLT(1000 * FRACUNIT / actor->target->info->mass);

an = actor->angle >> ANGLETOFINESHIFT;
fire = actor->tracer;

if(!fire)
return;
if(!fire) return;

// Move the fire between the Vile and the player.
an = actor->angle >> ANGLETOFINESHIFT;
P_MobjUnlink(actor);
fire->origin[VX] = actor->target->origin[VX] - 24 * FIX2FLT(finecosine[an]);
fire->origin[VY] = actor->target->origin[VY] - 24 * FIX2FLT(finesine[an]);
P_MobjLink(actor);
P_RadiusAttack(fire, actor, 70, 69);
}

Expand Down
3 changes: 3 additions & 0 deletions doomsday/plugins/doom/src/p_mobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -896,9 +896,12 @@ boolean P_CheckMissileSpawn(mobj_t* th)

// Move forward slightly so an angle can be computed if it explodes
// immediately.
/// @todo Optimize: Why not simple spawn at this location? -ds
P_MobjUnlink(th);
th->origin[VX] += th->mom[MX] / 2;
th->origin[VY] += th->mom[MY] / 2;
th->origin[VZ] += th->mom[MZ] / 2;
P_MobjLink(th);

if(!P_TryMoveXY(th, th->origin[VX], th->origin[VY], false, false))
{
Expand Down
2 changes: 2 additions & 0 deletions doomsday/plugins/heretic/src/p_enemy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1483,9 +1483,11 @@ void C_DECL A_MinotaurAtk3(mobj_t* actor)
{
if(fixFloorFire)
{
P_MobjUnlink(mo);
mo->origin[VX] += mo->mom[MX] / 2;
mo->origin[VY] += mo->mom[MY] / 2;
mo->origin[VZ] += mo->mom[MZ] / 2;
P_MobjLink(mo);

P_ExplodeMissile(mo);
}
Expand Down
4 changes: 3 additions & 1 deletion doomsday/plugins/heretic/src/p_mobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -1246,10 +1246,11 @@ boolean P_HitFloor(mobj_t* thing)
* @return @c true, if the missile is at a valid spawn point,
* otherwise; explode it and return @false.
*/
boolean P_CheckMissileSpawn(mobj_t* mo)
boolean P_CheckMissileSpawn(mobj_t *mo)
{
// Move a little forward so an angle can be computed if it immediately
// explodes
P_MobjUnlink(mo);
if(mo->type == MT_BLASTERFX1)
{
// Ultra-fast ripper spawning missile.
Expand All @@ -1263,6 +1264,7 @@ boolean P_CheckMissileSpawn(mobj_t* mo)
mo->origin[VY] += mo->mom[MY] / 2;
mo->origin[VZ] += mo->mom[MZ] / 2;
}
P_MobjLink(mo);

if(!P_TryMoveXY(mo, mo->origin[VX], mo->origin[VY], false, false))
{
Expand Down
4 changes: 3 additions & 1 deletion doomsday/plugins/heretic/src/p_pspr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1391,14 +1391,16 @@ void C_DECL A_BoltSpark(mobj_t* bolt)
{
mobj_t* spark;

if(IS_NETWORK_SERVER) return; // Would not be visible to anynoe.
if(IS_NETWORK_SERVER) return; // Would not be visible to anyone.

if(P_Random() > 50)
{
if((spark = P_SpawnMobj(MT_CRBOWFX4, bolt->origin, P_Random() << 24, 0)))
{
P_MobjUnlink(spark);
spark->origin[VX] += FIX2FLT((P_Random() - P_Random()) << 10);
spark->origin[VY] += FIX2FLT((P_Random() - P_Random()) << 10);
P_MobjLink(spark);
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion doomsday/plugins/hexen/src/p_mobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -1742,13 +1742,15 @@ boolean P_HealRadius(player_t* player)
* @return @c true, if the missile is at a valid spawn point,
* otherwise explodes it and return @c false.
*/
boolean P_CheckMissileSpawn(mobj_t* mo)
boolean P_CheckMissileSpawn(mobj_t *mo)
{
// Move a little forward so an angle can be computed if it
// immediately explodes
P_MobjUnlink(mo);
mo->origin[VX] += mo->mom[MX] / 2;
mo->origin[VY] += mo->mom[MY] / 2;
mo->origin[VZ] += mo->mom[MZ] / 2;
P_MobjLink(mo);

if(!P_TryMoveXY(mo, mo->origin[VX], mo->origin[VY]))
{
Expand Down Expand Up @@ -2032,6 +2034,7 @@ mobj_t* P_SpawnPlayerMissile(mobjtype_t type, mobj_t* source)
movfac * MissileMobj->info->speed * FIX2FLT(finesine[an]);
MissileMobj->mom[MZ] = MissileMobj->info->speed * slope;

P_MobjUnlink(MissileMobj);
if(MissileMobj->type == MT_MWAND_MISSILE ||
MissileMobj->type == MT_CFLAME_MISSILE)
{
Expand All @@ -2047,6 +2050,7 @@ mobj_t* P_SpawnPlayerMissile(mobjtype_t type, mobj_t* source)
MissileMobj->origin[VY] += MissileMobj->mom[MY] / 2;
MissileMobj->origin[VZ] += MissileMobj->mom[MZ] / 2;
}
P_MobjLink(MissileMobj);

if(!P_TryMoveXY(MissileMobj, MissileMobj->origin[VX], MissileMobj->origin[VY]))
{
Expand Down

0 comments on commit 9c2631c

Please sign in to comment.