Exemplo n.º 1
0
//
// ST_updateFaceWidget
//
// This is a not-very-pretty routine which handles
//  the face states and their timing.
// the precedence of expressions is:
//  dead > evil grin > turned head > straight ahead
//
static void ST_updateFaceWidget()
{
   int        i;
   angle_t    badguyangle;
   angle_t    diffang;
   static int lastattackdown = -1;
   static int priority = ST_PRIORITY_NONE;
   bool       doevilgrin;
   
   if(priority < ST_PRIORITY_MAX)
   {
      // dead
      if(!plyr->health)
      {
         priority = ST_PRIORITY_DEAD;
         st_faceindex = ST_DEADFACE;
         st_facecount = 1;
      }
   }

   // haleyjd 06/27/08: ouch face when player screams from falling
   if(priority < ST_PRIORITY_DEAD)
   {
      if(plyr->mo->intflags & MIF_SCREAMED)
      {
         priority = ST_PRIORITY_FALLING;
         st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
         st_facecount = 1;
      }
   }

   if(priority < ST_PRIORITY_FALLING)
   {
      if(plyr->bonuscount)
      {
         // picking up bonus
         doevilgrin = false;

         for(i = 0; i < NUMWEAPONS; i++)
         {
            if(oldweaponsowned[i] != weaponsowned[i])
            {
               doevilgrin = true;
               oldweaponsowned[i] = weaponsowned[i];
            }
         }
         if(doevilgrin)
         {
            // evil grin if just picked up weapon
            priority = ST_PRIORITY_EVILGRIN;
            st_facecount = ST_EVILGRINCOUNT;
            st_faceindex = ST_calcPainOffset() + ST_EVILGRINOFFSET;
         }
      }
   }

   if(priority < ST_PRIORITY_EVILGRIN)
   {
      if(plyr->damagecount && plyr->attacker && plyr->attacker != plyr->mo)
      {
         // being attacked
         priority = ST_PRIORITY_PAIN;

         // haleyjd 10/12/03: classic DOOM problem of missing OUCH face
         // was due to inversion of this test:
         // if(plyr->health - st_oldhealth > ST_MUCHPAIN)
         if(st_oldhealth - plyr->health > ST_MUCHPAIN)
         {
            priority = ST_PRIORITY_MUCHPAIN;
            st_facecount = ST_TURNCOUNT;
            st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
         }
         else
         {
            badguyangle = R_PointToAngle2(plyr->mo->x,
                                          plyr->mo->y,
                                          getThingX(plyr->mo, plyr->attacker),
                                          getThingY(plyr->mo, plyr->attacker));

            if(badguyangle > plyr->mo->angle)
            {
               // whether right or left
               diffang = badguyangle - plyr->mo->angle;
               i = diffang > ANG180;
            }
            else
            {
               // whether left or right
               diffang = plyr->mo->angle - badguyangle;
               i = diffang <= ANG180;
            } // confusing, aint it?

            st_facecount = ST_TURNCOUNT;
            st_faceindex = ST_calcPainOffset();

            if(diffang < ANG45)
            {
               // head-on
               st_faceindex += ST_RAMPAGEOFFSET;
            }
            else if(i)
            {
               // turn face right
               st_faceindex += ST_TURNOFFSET;
            }
            else
            {
               // turn face left
               st_faceindex += ST_TURNOFFSET+1;
            }
         }
      }
   }

   if(priority < ST_PRIORITY_PAIN)
   {
      // getting hurt because of your own damn stupidity
      if(plyr->damagecount)
      {
         // haleyjd 10/12/03: classic DOOM problem of missing OUCH face
         // was due to inversion of this test:
         // if(plyr->health - st_oldhealth > ST_MUCHPAIN)
         if(st_oldhealth - plyr->health > ST_MUCHPAIN)
         {
            priority = ST_PRIORITY_MUCHPAIN_SELF;
            st_facecount = ST_TURNCOUNT;
            st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
         }
         else
         {
            priority = ST_PRIORITY_PAIN_SELF;
            st_facecount = ST_TURNCOUNT;
            st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
         }
      }
   }

   if(priority < ST_PRIORITY_PAIN_SELF)
   {
      // rapid firing
      if(plyr->attackdown)
      {
         if(lastattackdown==-1)
            lastattackdown = ST_RAMPAGEDELAY;
         else if(!--lastattackdown)
         {
            priority = ST_PRIORITY_RAMPAGE;
            st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
            st_facecount = 1;
            lastattackdown = 1;
         }
      }
      else
         lastattackdown = -1;
   }

   if(priority < ST_PRIORITY_RAMPAGE)
   {
      // invulnerability
      if((plyr->cheats & CF_GODMODE) || plyr->powers[pw_invulnerability])
      {
         priority = ST_PRIORITY_GODMODE;
         
         st_faceindex = ST_GODFACE;
         st_facecount = 1;
      }
   }

   // look left or look right if the facecount has timed out
   if(!st_facecount)
   {
      // sf: remove st_randomnumber
      st_faceindex = ST_calcPainOffset() + (M_Random() % 3);
      st_facecount = ST_STRAIGHTFACECOUNT;
      priority = ST_PRIORITY_NONE;
   }
   
   st_facecount--;
}
Exemplo n.º 2
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;
}