Exemplo n.º 1
0
DEFINE_ACTION_FUNCTION(AActor, A_RocketInFlight)
{
	AActor *trail;

	S_Sound (self, CHAN_VOICE, "misc/missileinflight", 1, ATTN_NORM);
	P_SpawnPuff (self, PClass::FindClass("MiniMissilePuff"), self->Pos(), self->angle - ANGLE_180, 2, PF_HITTHING);
	trail = Spawn("RocketTrail", self->Vec3Offset(-self->velx, -self->vely, 0), ALLOW_REPLACE);
	if (trail != NULL)
	{
		trail->velz = FRACUNIT;
	}
}
Exemplo n.º 2
0
DEFINE_ACTION_FUNCTION(AActor, A_RocketInFlight)
{
	PARAM_ACTION_PROLOGUE;

	AActor *trail;

	S_Sound (self, CHAN_VOICE, "misc/missileinflight", 1, ATTN_NORM);
	P_SpawnPuff (self, PClass::FindActor("MiniMissilePuff"), self->Pos(), self->Angles.Yaw - 180, self->Angles.Yaw - 180, 2, PF_HITTHING);
	trail = Spawn("RocketTrail", self->Vec3Offset(-self->Vel.X, -self->Vel.Y, 0.), ALLOW_REPLACE);
	if (trail != NULL)
	{
		trail->Vel.Z = 1;
	}
	return 0;
}
Exemplo n.º 3
0
DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
{
	angle_t exact;
	fixed_t dist;
	fixed_t slope;
	AActor *dest;
	AActor *smoke;
				
	// killough 1/18/98: this is why some missiles do not have smoke
	// and some do. Also, internal demos start at random gametics, thus
	// the bug in which revenants cause internal demos to go out of sync.
	//
	// killough 3/6/98: fix revenant internal demo bug by subtracting
	// levelstarttic from gametic:
	//
	// [RH] level.time is always 0-based, so nothing special to do here.

	if (level.time & 3)
		return;
	
	// spawn a puff of smoke behind the rocket
	P_SpawnPuff (self, PClass::FindClass(NAME_BulletPuff), self->x, self->y, self->z, 0, 3);
		
	smoke = Spawn ("RevenantTracerSmoke", self->x - self->velx,
		self->y - self->vely, self->z, ALLOW_REPLACE);
	
	smoke->velz = FRACUNIT;
	smoke->tics -= pr_tracer()&3;
	if (smoke->tics < 1)
		smoke->tics = 1;
	
	// adjust direction
	dest = self->tracer;
		
	if (!dest || dest->health <= 0 || self->Speed == 0 || !self->CanSeek(dest))
		return;
	
	// change angle 	
	exact = R_PointToAngle2 (self->x, self->y, dest->x,  dest->y);

	if (exact != self->angle)
	{
		if (exact - self->angle > 0x80000000)
		{
			self->angle -= TRACEANGLE;
			if (exact - self->angle < 0x80000000)
				self->angle = exact;
		}
		else
		{
			self->angle += TRACEANGLE;
			if (exact - self->angle > 0x80000000)
				self->angle = exact;
		}
	}
		
	exact = self->angle>>ANGLETOFINESHIFT;
	self->velx = FixedMul (self->Speed, finecosine[exact]);
	self->vely = FixedMul (self->Speed, finesine[exact]);

	if (!(self->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
	{
		// change slope
		dist = P_AproxDistance (dest->x - self->x,
								dest->y - self->y);
		
		dist = dist / self->Speed;

		if (dist < 1)
			dist = 1;

		if (dest->height >= 56*FRACUNIT)
		{
			slope = (dest->z+40*FRACUNIT - self->z) / dist;
		}
		else
		{
			slope = (dest->z + self->height*2/3 - self->z) / dist;
		}

		if (slope < self->velz)
			self->velz -= FRACUNIT/8;
		else
			self->velz += FRACUNIT/8;
	}
}
Exemplo n.º 4
0
//
// A_Tracer
//
// (Accidentally?) randomized homing missile maintenance.
// ioanch 20151230: fixed to be portal-aware
//
void A_Tracer(actionargs_t *actionargs)
{
   angle_t  exact;
   fixed_t  dist;
   fixed_t  slope;
   Mobj    *actor = actionargs->actor;
   Mobj    *dest;
   Mobj    *th;

   // killough 1/18/98: this is why some missiles do not have smoke
   // and some do. Also, internal demos start at random gametics, 
   // thus the bug in which revenants cause internal demos to go out 
   // of sync.
   //
   // killough 3/6/98: fix revenant internal demo bug by subtracting
   // levelstarttic from gametic.
   //
   // killough 9/29/98: use new "basetic" so that demos stay in sync
   // during pauses and menu activations, while retaining old demo 
   // sync.
   //
   // leveltime would have been better to use to start with in Doom, 
   // but since old demos were recorded using gametic, we must stick 
   // with it, and improvise around it (using leveltime causes desync 
   // across levels).

   if((gametic-basetic) & 3)
      return;

   // spawn a puff of smoke behind the rocket
   P_SpawnPuff(actor->x, actor->y, actor->z, 0, 3, false);
   
   th = P_SpawnMobj(actor->x - actor->momx,
                    actor->y - actor->momy,
                    actor->z, E_SafeThingType(MT_SMOKE));
  
   th->momz = FRACUNIT;
   th->tics -= P_Random(pr_tracer) & 3;
   if(th->tics < 1)
      th->tics = 1;
  
   // adjust direction
   dest = actor->tracer;
   
   if(!dest || dest->health <= 0)
      return;

   fixed_t dx = getThingX(actor, dest);
   fixed_t dy = getThingY(actor, dest);
   fixed_t dz = getThingZ(actor, dest);

   // change angle
   exact = P_PointToAngle(actor->x, actor->y, dx, dy);

   if(exact != actor->angle)
   {
      if(exact - actor->angle > 0x80000000)
      {
         actor->angle -= TRACEANGLE;
         if(exact - actor->angle < 0x80000000)
            actor->angle = exact;
      }
      else
      {
         actor->angle += TRACEANGLE;
         if(exact - actor->angle > 0x80000000)
            actor->angle = exact;
      }
   }

   exact = actor->angle>>ANGLETOFINESHIFT;
   actor->momx = FixedMul(actor->info->speed, finecosine[exact]);
   actor->momy = FixedMul(actor->info->speed, finesine[exact]);

   // change slope
   dist = P_AproxDistance(dx - actor->x, dy - actor->y);
   
   dist = dist / actor->info->speed;

   if(dist < 1)
      dist = 1;

   slope = (dz + 40*FRACUNIT - actor->z) / dist;
   
   if(slope < actor->momz)
      actor->momz -= FRACUNIT/8;
   else
      actor->momz += FRACUNIT/8;
}
Exemplo n.º 5
0
void P_XYMovement(mobj_t *mo)
{
    player_t *player;
    fixed_t  xmove, ymove;

    if (!mo->momx && !mo->momy)
    {
        if (mo->flags & MF_SKULLFLY)
        {
            // the skull slammed into something
            mo->flags &= ~MF_SKULLFLY;
            mo->momx = mo->momy = mo->momz = 0;

            P_SetMobjState(mo, (statenum_t)mo->info->spawnstate);
        }
        return;
    }

    player = mo->player;

    if (mo->type == MT_ROCKET)
    {
        if (puffcount++ > 1)
            P_SpawnPuff(mo->x, mo->y, mo->z, mo->angle);
    }

    if (mo->momx > MAXMOVE)
        mo->momx = MAXMOVE;
    else if (mo->momx < -MAXMOVE)
        mo->momx = -MAXMOVE;

    if (mo->momy > MAXMOVE)
        mo->momy = MAXMOVE;
    else if (mo->momy < -MAXMOVE)
        mo->momy = -MAXMOVE;

    xmove = mo->momx;
    ymove = mo->momy;

    do
    {
        fixed_t  ptryx, ptryy;

        if (xmove > MAXMOVE / 2 || ymove > MAXMOVE / 2
            || xmove < -MAXMOVE / 2 || ymove < -MAXMOVE / 2)
        {
            ptryx = mo->x + xmove / 2;
            ptryy = mo->y + ymove / 2;
            xmove >>= 1;
            ymove >>= 1;
        }
        else
        {
            ptryx = mo->x + xmove;
            ptryy = mo->y + ymove;
            xmove = ymove = 0;
        }

        if (!P_TryMove(mo, ptryx, ptryy))
        {
            // blocked move
            if (mo->player)
            {
                // try to slide along it
                P_SlideMove(mo);
            }
            else if (mo->flags & MF_MISSILE)
            {
                // explode a missile
                if (ceilingline
                    && ceilingline->backsector
                    && ceilingline->backsector->ceilingpic == skyflatnum
                    && mo->z > ceilingline->backsector->ceilingheight)
                {
                    // Hack to prevent missiles exploding
                    // against the sky.
                    // Does not handle sky floors.
                    shootingsky = true;
                    P_RemoveMobj(mo);
                    return;
                }
                P_ExplodeMissile(mo);
            }
            else
            {
                mo->momx = mo->momy = 0;
            }
        }
    }