- Random spawners no longer move the missile forward when spawning them, because presumably

whatever spawned the random spawner already took care of this.
- Added a maxdist parameter to P_CheckMissileSpawn() to help ensure that it doesn't completely 
  move the spawned missile outside of its shooter (and potentially beyond a wall the shooter
  might happen to be standing next to).

SVN r4194 (trunk)
This commit is contained in:
Randy Heit 2013-03-21 03:06:04 +00:00
parent 34b2d0b21a
commit 2874d927b1
15 changed files with 79 additions and 91 deletions

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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);
}
//----------------------------------------------------------------------------

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}
//---------------------------------------------------------------------------

View file

@ -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;

View file

@ -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);
}
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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<double> 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<double>(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; i<count; i++)
// 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)))
{
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;
}

View file

@ -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;
}

View file

@ -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);
}