mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
- 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:
parent
34b2d0b21a
commit
2874d927b1
15 changed files with 79 additions and 91 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
120
src/p_mobj.cpp
120
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<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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue