diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 9461145209..ec083631a0 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -4256,7 +4256,7 @@ void FParser::SF_SpawnShot2(void) S_Sound (mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_NORM); mo->target = source; P_ThrustMobj(mo, mo->angle = source->angle, mo->Speed); - if (!P_CheckMissileSpawn(mo)) mo = NULL; + if (!P_CheckMissileSpawn(mo, source->radius)) mo = NULL; } t_return.value.mobj = mo; } diff --git a/src/g_heretic/a_hereticmisc.cpp b/src/g_heretic/a_hereticmisc.cpp index a8d4fcb8f9..83200068b8 100644 --- a/src/g_heretic/a_hereticmisc.cpp +++ b/src/g_heretic/a_hereticmisc.cpp @@ -175,7 +175,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast) blast->vely = FixedMul (1*FRACUNIT, finesine[angle]); blast->velz = (FRACUNIT*5/2) + (pr_blast() << 10); S_Sound (blast, CHAN_BODY, "world/volcano/shoot", 1, ATTN_NORM); - P_CheckMissileSpawn (blast); + P_CheckMissileSpawn (blast, self->radius); } } @@ -209,7 +209,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact) tiny->velx = FixedMul (FRACUNIT*7/10, finecosine[angle]); tiny->vely = FixedMul (FRACUNIT*7/10, finesine[angle]); tiny->velz = FRACUNIT + (pr_volcimpact() << 9); - P_CheckMissileSpawn (tiny); + P_CheckMissileSpawn (tiny, self->radius); } } diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index e8f287f698..5e1f0647c4 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -395,7 +395,7 @@ void FireMacePL1B (AActor *actor) ball->velx = (actor->velx>>1) + FixedMul(ball->Speed, finecosine[angle]); ball->vely = (actor->vely>>1) + FixedMul(ball->Speed, finesine[angle]); S_Sound (ball, CHAN_BODY, "weapons/maceshoot", 1, ATTN_NORM); - P_CheckMissileSpawn (ball); + P_CheckMissileSpawn (ball, actor->radius); } //---------------------------------------------------------------------------- @@ -538,7 +538,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2) tiny->velx = (self->velx>>1) + FixedMul(self->velz-FRACUNIT, finecosine[angle]); tiny->vely = (self->vely>>1) + FixedMul(self->velz-FRACUNIT, finesine[angle]); tiny->velz = self->velz; - P_CheckMissileSpawn (tiny); + P_CheckMissileSpawn (tiny, self->radius); tiny = Spawn("MaceFX3", self->x, self->y, self->z, ALLOW_REPLACE); angle = self->angle-ANG90; @@ -548,7 +548,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2) tiny->velx = (self->velx>>1) + FixedMul(self->velz-FRACUNIT, finecosine[angle]); tiny->vely = (self->vely>>1) + FixedMul(self->velz-FRACUNIT, finesine[angle]); tiny->velz = self->velz; - P_CheckMissileSpawn (tiny); + P_CheckMissileSpawn (tiny, self->radius); } else { // Explode @@ -809,7 +809,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnRippers) angle >>= ANGLETOFINESHIFT; ripper->velx = FixedMul (ripper->Speed, finecosine[angle]); ripper->vely = FixedMul (ripper->Speed, finesine[angle]); - P_CheckMissileSpawn (ripper); + P_CheckMissileSpawn (ripper, self->radius); } } @@ -1064,7 +1064,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm) mo->velx = 1; // Force collision detection mo->velz = -mo->Speed; mo->special2 = self->special2; // Transfer player number - P_CheckMissileSpawn (mo); + P_CheckMissileSpawn (mo, self->radius); if (self->special1 != -1 && !S_IsActorPlayingSomething (self, CHAN_BODY, -1)) { S_Sound (self, CHAN_BODY|CHAN_LOOP, self->special1, 1, ATTN_NORM); @@ -1314,7 +1314,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) { S_Sound (self, CHAN_WEAPON|CHAN_LOOP, soundid, 1, ATTN_NORM); } - P_CheckMissileSpawn (mo); + P_CheckMissileSpawn (mo, self->radius); } //---------------------------------------------------------------------------- diff --git a/src/g_heretic/a_ironlich.cpp b/src/g_heretic/a_ironlich.cpp index 8efaa8d82d..5801e6cac7 100644 --- a/src/g_heretic/a_ironlich.cpp +++ b/src/g_heretic/a_ironlich.cpp @@ -116,7 +116,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack) fire->velz = baseFire->velz; fire->Damage = 0; fire->health = (i+1) * 2; - P_CheckMissileSpawn (fire); + P_CheckMissileSpawn (fire, self->radius); } } } @@ -185,7 +185,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact) shard->velx = FixedMul (shard->Speed, finecosine[angle]); shard->vely = FixedMul (shard->Speed, finesine[angle]); shard->velz = -FRACUNIT*6/10; - P_CheckMissileSpawn (shard); + P_CheckMissileSpawn (shard, self->radius); } } diff --git a/src/g_hexen/a_flechette.cpp b/src/g_hexen/a_flechette.cpp index 5c28b83586..1a9461ae8a 100644 --- a/src/g_hexen/a_flechette.cpp +++ b/src/g_hexen/a_flechette.cpp @@ -137,7 +137,7 @@ bool AArtiPoisonBag3::Use (bool pickup) mo->target = Owner; mo->tics -= pr_poisonbag()&3; - P_CheckMissileSpawn(mo); + P_CheckMissileSpawn(mo, Owner->radius); return true; } return false; diff --git a/src/g_hexen/a_korax.cpp b/src/g_hexen/a_korax.cpp index a7d8908b2f..5323fb8515 100644 --- a/src/g_hexen/a_korax.cpp +++ b/src/g_hexen/a_korax.cpp @@ -502,5 +502,5 @@ AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z, dist = 1; } th->velz = (dest->z-z+(30*FRACUNIT))/dist; - return (P_CheckMissileSpawn(th) ? th : NULL); + return (P_CheckMissileSpawn(th, source->radius) ? th : NULL); } diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index 949e38d01c..ff39bf67ca 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -375,7 +375,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MntrFloorFire) mo = Spawn("MinotaurFX3", x, y, self->floorz, ALLOW_REPLACE); mo->target = self->target; mo->velx = 1; // Force block checking - P_CheckMissileSpawn (mo); + P_CheckMissileSpawn (mo, self->radius); } //--------------------------------------------------------------------------- diff --git a/src/g_shared/a_randomspawner.cpp b/src/g_shared/a_randomspawner.cpp index fc7ca8cf93..293b17d3b6 100644 --- a/src/g_shared/a_randomspawner.cpp +++ b/src/g_shared/a_randomspawner.cpp @@ -173,7 +173,7 @@ class ARandomSpawner : public AActor newmobj->z += SpawnPoint[2]; } if (newmobj->flags & MF_MISSILE) - P_CheckMissileSpawn(newmobj); + P_CheckMissileSpawn(newmobj, 0); // Bouncecount is used to count how many recursions we're in. if (newmobj->IsKindOf(PClass::FindClass("RandomSpawner"))) newmobj->bouncecount = ++bouncecount; diff --git a/src/g_strife/a_entityboss.cpp b/src/g_strife/a_entityboss.cpp index 3dfeb3b5a7..58a88121e7 100644 --- a/src/g_strife/a_entityboss.cpp +++ b/src/g_strife/a_entityboss.cpp @@ -29,7 +29,7 @@ void A_SpectralMissile (AActor *self, const char *missilename) if (missile != NULL) { missile->tracer = self->target; - P_CheckMissileSpawn(missile); + P_CheckMissileSpawn(missile, self->radius); } } } diff --git a/src/g_strife/a_sentinel.cpp b/src/g_strife/a_sentinel.cpp index 696858f81f..74f0e917f0 100644 --- a/src/g_strife/a_sentinel.cpp +++ b/src/g_strife/a_sentinel.cpp @@ -64,7 +64,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelAttack) trail->velx = missile->velx; trail->vely = missile->vely; trail->velz = missile->velz; - P_CheckMissileSpawn (trail); + P_CheckMissileSpawn (trail, self->radius); } } missile->z += missile->velz >> 2; diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 5ac40b82ec..82560e6f79 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -538,7 +538,7 @@ AActor *P_SpawnSubMissile (AActor *source, const PClass *type, AActor *target) } } - if (P_CheckMissileSpawn (other)) + if (P_CheckMissileSpawn (other, source->radius)) { angle_t pitch = P_AimLineAttack (source, source->angle, 1024*FRACUNIT); other->velz = FixedMul (-finesine[pitch>>ANGLETOFINESHIFT], other->Speed); diff --git a/src/p_local.h b/src/p_local.h index fe149d4315..f5e1f44a0f 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -481,7 +481,7 @@ enum // P_RailAttack / A_RailAttack / A_CustomRailgun / P_DrawRailTrail flags }; -bool P_CheckMissileSpawn (AActor *missile); +bool P_CheckMissileSpawn (AActor *missile, fixed_t maxdist); void P_PlaySpawnSound(AActor *missile, AActor *spawner); // [RH] Position the chasecam diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index d36c27463a..bf84d33400 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5258,10 +5258,8 @@ void P_CheckSplash(AActor *self, fixed_t distance) // //--------------------------------------------------------------------------- -bool P_CheckMissileSpawn (AActor* th) +bool P_CheckMissileSpawn (AActor* th, fixed_t maxdist) { - int shift, count = 1; - // [RH] Don't decrement tics if they are already less than 1 if ((th->flags4 & MF4_RANDOMIZE) && th->tics > 0) { @@ -5270,76 +5268,66 @@ bool P_CheckMissileSpawn (AActor* th) th->tics = 1; } - // move a little forward so an angle can be computed if it immediately explodes - if (th->Speed >= 100*FRACUNIT) - { // Ultra-fast ripper spawning missile - shift = 3; - } - else - { // Normal missile - shift = 1; - } - - if (th->radius > 0) + if (maxdist > 0) { - while ( ((th->velx >> shift) > th->radius) || ((th->vely >> shift) > th->radius)) + // move a little forward so an angle can be computed if it immediately explodes + TVector3 advance(FIXED2DBL(th->velx), FIXED2DBL(th->vely), FIXED2DBL(th->velz)); + double maxsquared = FIXED2DBL(maxdist); + maxsquared *= maxsquared; + + // Keep halving the advance vector until we get something less than maxdist + // units away, since we still want to spawn the missile inside the shooter. + while (TVector2(advance).LengthSquared() >= maxsquared) { - // we need to take smaller steps but to produce the same end result - // we have to do more of them. - shift++; - count<<=1; + advance *= 0.5f; } + th->x += FLOAT2FIXED(advance.X); + th->y += FLOAT2FIXED(advance.Y); + th->z += FLOAT2FIXED(advance.Z); } FCheckPosition tm(!!(th->flags2 & MF2_RIP)); - for(int i=0; iflags & MF_MISSILE) || (th->BounceFlags & BOUNCE_MBF)); + + // killough 3/15/98: no dropoff (really = don't care for missiles) + if (!(P_TryMove (th, th->x, th->y, false, NULL, tm, true))) { - th->x += th->velx >> shift; - th->y += th->vely >> shift; - th->z += th->velz >> shift; - - // killough 8/12/98: for non-missile objects (e.g. grenades) - // - // [GZ] MBF excludes non-missile objects from the P_TryMove test - // and subsequent potential P_ExplodeMissile call. That is because - // in MBF, a projectile is not an actor with the MF_MISSILE flag - // but an actor with either or both the MF_MISSILE and MF_BOUNCES - // flags, and a grenade is identified by not having MF_MISSILE. - // Killough wanted grenades not to explode directly when spawned, - // therefore they can be fired safely even when humping a wall as - // they will then just drop on the floor at their shooter's feet. - // - // However, ZDoom does allow non-missiles to be shot as well, so - // Killough's check for non-missiles is inadequate here. So let's - // replace it by a check for non-missile and MBF bounce type. - // This should allow MBF behavior where relevant without altering - // established ZDoom behavior for crazy stuff like a cacodemon cannon. - bool MBFGrenade = (!(th->flags & MF_MISSILE) || (th->BounceFlags & BOUNCE_MBF)); - - // killough 3/15/98: no dropoff (really = don't care for missiles) - if (!(P_TryMove (th, th->x, th->y, 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)) { - // [RH] Don't explode ripping missiles that spawn inside something - if (th->BlockingMobj == NULL || !(th->flags2 & MF2_RIP) || (th->BlockingMobj->flags5 & MF5_DONTRIP)) + // If this is a monster spawned by A_CustomMissile subtract it from the counter. + th->ClearCounters(); + // [RH] Don't explode missiles that spawn on top of horizon lines + if (th->BlockingLine != NULL && th->BlockingLine->special == Line_Horizon) { - // If this is a monster spawned by A_CustomMissile subtract it from the counter. - th->ClearCounters(); - // [RH] Don't explode missiles that spawn on top of horizon lines - if (th->BlockingLine != NULL && th->BlockingLine->special == Line_Horizon) - { - th->Destroy (); - } - else if (MBFGrenade && th->BlockingLine != NULL ) - { - P_BounceWall(th); - } - else - { - P_ExplodeMissile (th, NULL, th->BlockingMobj); - } - return false; + th->Destroy (); } + else if (MBFGrenade && th->BlockingLine != NULL) + { + P_BounceWall(th); + } + else + { + P_ExplodeMissile (th, NULL, th->BlockingMobj); + } + return false; } } return true; @@ -5473,7 +5461,7 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, th->SetFriendPlayer(owner->player); } - return (!checkspawn || P_CheckMissileSpawn (th)) ? th : NULL; + return (!checkspawn || P_CheckMissileSpawn (th, source->radius)) ? th : NULL; } AActor * P_OldSpawnMissile(AActor * source, AActor * owner, AActor * dest, const PClass *type) @@ -5503,7 +5491,7 @@ AActor * P_OldSpawnMissile(AActor * source, AActor * owner, AActor * dest, const th->SetFriendPlayer(owner->player); } - P_CheckMissileSpawn(th); + P_CheckMissileSpawn(th, source->radius); return th; } @@ -5592,7 +5580,7 @@ AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, mo->SetFriendPlayer(owner->player); } - return (!checkspawn || P_CheckMissileSpawn(mo)) ? mo : NULL; + return (!checkspawn || P_CheckMissileSpawn(mo, source->radius)) ? mo : NULL; } /* @@ -5711,7 +5699,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, { MissileActor->SetFriendPlayer(source->player); } - if (P_CheckMissileSpawn (MissileActor)) + if (P_CheckMissileSpawn (MissileActor, source->radius)) { return MissileActor; } diff --git a/src/p_things.cpp b/src/p_things.cpp index 289e8835af..d2d8a963e8 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -336,7 +336,7 @@ nolead: mobj->angle = R_PointToAngle2 (mobj->x, mobj->y, targ->x, targ->y); } if (mobj->flags & MF_MISSILE) { - if (P_CheckMissileSpawn (mobj)) + if (P_CheckMissileSpawn (mobj, source->radius)) { rtn = true; } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index ccb7f59610..d201f41a6c 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -333,7 +333,7 @@ static void DoAttack (AActor *self, bool domelee, bool domissile, { missile->tracer=self->target; } - P_CheckMissileSpawn(missile); + P_CheckMissileSpawn(missile, self->radius); } } } @@ -1019,7 +1019,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) missile->FriendPlayer = 0; } } - P_CheckMissileSpawn(missile); + P_CheckMissileSpawn(missile, self->radius); } } } @@ -1170,7 +1170,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack) { missile->tracer=self->target; } - P_CheckMissileSpawn(missile); + P_CheckMissileSpawn(missile, self->radius); } } } @@ -2045,8 +2045,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade) bo->vely = xy_vely + z_vely + (self->vely >> 1); bo->velz = xy_velz + z_velz; - bo->target= self; - P_CheckMissileSpawn (bo); + bo->target = self; + P_CheckMissileSpawn (bo, self->radius); } else ACTION_SET_RESULT(false); }