예제 #1
0
파일: spfx.c 프로젝트: Crockadavin/naev
/**
 * @brief Updates the shake position.
 */
static void spfx_updateShake( double dt )
{
   double mod, vmod, angle;
   double force_x, force_y;
   int forced;

   /* Must still be on. */
   if (shake_off)
      return;

   /* The shake decays over time */
   forced = 0;
   if (shake_force_mod > 0.) {
      shake_force_mod -= SHAKE_DECAY*dt;
      if (shake_force_mod < 0.)
         shake_force_mod   = 0.;
      else
         forced            = 1;
   }

   /* See if it's settled down. */
   mod      = VMOD( shake_pos );
   vmod     = VMOD( shake_vel );
   if (!forced && (mod < 0.01) && (vmod < 0.01)) {
      shake_off      = 1;
      if (shake_force_ang > 1e3)
         shake_force_ang = RNGF();
      return;
   }

   /* Calculate force. */
   force_x  = -SHAKE_K*shake_pos.x + -SHAKE_B*shake_vel.x;
   force_y  = -SHAKE_K*shake_pos.y + -SHAKE_B*shake_vel.y;

   /* Apply force if necessary. */
   if (forced) {
      shake_force_ang  += dt;
      angle             = noise_simplex1( shake_noise, &shake_force_ang ) * 5.*M_PI;
      force_x          += shake_force_mod * cos(angle);
      force_y          += shake_force_mod * sin(angle);
   }


   /* Update velocity. */
   vect_cadd( &shake_vel, (1./SHAKE_MASS) * force_x * dt, (1./SHAKE_MASS) * force_y * dt );

   /* Update position. */
   vect_cadd( &shake_pos, shake_vel.x * dt, shake_vel.y * dt );
}
예제 #2
0
파일: nlua_vec2.c 프로젝트: pegue/naev
/**
 * @ingroup META_VECTOR
 *
 * @brief Subtracts two vectors or a vector and some cartesian coordinates.
 *
 * If x is a vector it subtracts both vectors, otherwise it subtracts cartesian
 * coordinates to the vector.
 *
 * @usage my_vec = my_vec - your_vec
 * @usage my_vec:sub( your_vec )
 * @usage my_vec:sub( 5, 3 )
 *
 *    @luaparam v Vector getting stuff subtracted from.
 *    @luaparam x X coordinate or vector to subtract.
 *    @luaparam y Y coordinate or nil to subtract.
 *    @luareturn The result of the vector operation.
 * @luafunc sub v, x, y )
 */
static int vectorL_sub( lua_State *L )
{
   LuaVector *v1, *v2;
   double x, y;

   /* Get self. */
   v1    = luaL_checkvector(L,1);

   /* Get rest of parameters. */
   v2 = NULL;
   if (lua_isvector(L,2)) {
      v2 = lua_tovector(L,2);
      x = v2->vec.x;
      y = v2->vec.y;
   }
   else if ((lua_gettop(L) > 2) && lua_isnumber(L,2) && lua_isnumber(L,3)) {
      x = lua_tonumber(L,2);
      y = lua_tonumber(L,3);
   }
   else NLUA_INVALID_PARAMETER();

   /* Actually add it */
   vect_cadd( &v1->vec, -x, -y );
   lua_pushvalue(L,1);
   return 1;
}
예제 #3
0
파일: spfx.c 프로젝트: zid/naev
/**
 * @brief Prepares the rendering for the special effects.
 *
 * Should be called at the beginning of the rendering loop.
 *
 *    @param dt Current delta tick.
 */
void spfx_begin( const double dt )
{
   GLdouble bx, by, x, y;
   double inc;

   /* Save cycles. */
   if (shake_off == 1)
      return;

#if SDL_VERSION_ATLEAST(1,3,0)
   /* Decrement the haptic timer. */
   if (haptic_lastUpdate > 0.)
      haptic_lastUpdate -= dt;
#endif /* SDL_VERSION_ATLEAST(1,3,0) */

   /* set defaults */
   bx = SCREEN_W/2;
   by = SCREEN_H/2;

   if (!paused) {
      inc = dt*100000.;

      /* calculate new position */
      if (shake_rad > 0.01) {
         vect_cadd( &shake_pos, shake_vel.x * inc, shake_vel.y * inc );

         if (VMOD(shake_pos) > shake_rad) { /* change direction */
            vect_pset( &shake_pos, shake_rad, VANGLE(shake_pos) );
            vect_pset( &shake_vel, SHAKE_VEL_MOD*shake_rad, 
                  -VANGLE(shake_pos) + (RNGF()-0.5) * M_PI );
         }

         /* the shake decays over time */
         shake_rad -= SHAKE_DECAY*dt;
         if (shake_rad < 0.)
            shake_rad = 0.;

         x = shake_pos.x;
         y = shake_pos.y;  
      }
      else {
         shake_rad = 0.;
         shake_off = 1;
         x = 0.;
         y = 0.;
      }
   }
   else {
      x = 0.;
      y = 0.;
   }

   /* set the new viewport */
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho( -bx+x, bx+x, -by+y, by+y, -1., 1. );
}
예제 #4
0
파일: nlua_vec2.c 프로젝트: pegue/naev
/**
 * @ingroup META_VECTOR
 *
 * @brief Divides a vector by a number.
 *
 * @usage my_vec = my_vec / 3
 * @usage my_vec:div(3)
 *
 *    @luaparam v Vector to divide.
 *    @luaparam mod Amount to divide by.
 *    @luareturn The result of the vector operation.
 * @luafunc div( v, mod )
 */
static int vectorL_div( lua_State *L )
{
   LuaVector *v1;
   double mod;

   /* Get parameters. */
   v1    = luaL_checkvector(L,1);
   mod   = luaL_checknumber(L,2);

   /* Actually add it */
   vect_cadd( &v1->vec, v1->vec.x / mod, v1->vec.x / mod );
   lua_pushvalue(L,1);
   return 1;
}
예제 #5
0
파일: spfx.c 프로젝트: zid/naev
/**
 * @brief Updates an individual spfx.
 *
 *    @param layer Layer the spfx is on.
 *    @param nlayer Pointer to the assosciated nlayer.
 *    @param dt Current delta tick.
 */
static void spfx_update_layer( SPFX *layer, int *nlayer, const double dt )
{
   int i;

   for (i=0; i<*nlayer; i++) {
      layer[i].timer -= dt; /* less time to live */

      /* time to die! */
      if (layer[i].timer < 0.) {
         spfx_destroy( layer, nlayer, i );
         i--;
         continue;
      }

      /* actually update it */
      vect_cadd( &layer[i].pos, dt*VX(layer[i].vel), dt*VY(layer[i].vel) );
   }
}
예제 #6
0
파일: nlua_pilot.c 프로젝트: pegue/naev
/**
 * @brief Adds a fleet to the system.
 *
 * You can then iterate over the pilots to change parameters like so:
 * @code
 * p = pilot.add( "Sml Trader Convoy" )
 * for k,v in pairs(p) do
 *    v:setHostile()
 * end
 * @endcode
 *
 * @usage p = pilot.add( "Pirate Hyena" ) -- Just adds the pilot (will jump in).
 * @usage p = pilot.add( "Trader Llama", "dummy" ) -- Overrides AI with dummy ai.
 * @usage p = pilot.add( "Sml Trader Convoy", "def", vec2.new( 1000, 200 ) ) -- Pilot won't jump in, will just appear.
 * @usage p = pilot.add( "Empire Pacifier", "def", vec2.new( 1000, 1000 ), true ) -- Have the pilot jump in.
 *
 *    @luaparam fleetname Name of the fleet to add.
 *    @luaparam ai If set will override the standard fleet AI.  "def" means use default.
 *    @luaparam pos Position to create pilots around instead of choosing randomly.
 *    @luaparam jump true if pilots should jump in, false by default if pos is defined.
 *    @luareturn Table populated with all the pilots created.  The keys are ordered numbers.
 * @luafunc add( fleetname, ai, pos, jump )
 */
static int pilot_addFleet( lua_State *L )
{
   NLUA_MIN_ARGS(1);
   Fleet *flt;
   const char *fltname, *fltai;
   int i, j;
   unsigned int p;
   double a;
   double d;
   Vector2d vv,vp, vn;
   FleetPilot *plt;
   LuaPilot lp;
   LuaVector *lv;
   int jump;

   /* Parse first argument - Fleet Name */
   fltname = luaL_checkstring(L,1);
   
   /* Parse second argument - Fleet AI Override */
   if (lua_gettop(L) > 1) {
      fltai = luaL_checkstring(L,2);
      if (strcmp(fltai, "def")==0) /* Check if set to default */
         fltai = NULL;
   }
   else fltai = NULL;

   /* Parse third argument - Position */
   if (lua_gettop(L) > 2) {
      lv = luaL_checkvector(L,3);
   }
   else lv = NULL;

   if (lua_gettop(L) > 3) {
      jump = lua_toboolean(L,4);
   }
   else {
      /* Only jump by default if not position was passed. */
      if (lv==NULL)
         jump = 1;
      else
         jump = 0;
   }

   /* Needed to determine angle. */
   vectnull(&vn);

   /* pull the fleet */
   flt = fleet_get( fltname );
   if (flt == NULL) {
      NLUA_ERROR(L,"Fleet '%s' doesn't exist.", fltname);
      return 0;
   }

   /* Use position passed if possible. */
   if (lv != NULL) {
      if (!jump)
         vectcpy( &vp, &lv->vec );
      else {
         /* Pilot is jumping in, we'll only use the vector angle. */
         d = RNGF()*(HYPERSPACE_ENTER_MAX-HYPERSPACE_ENTER_MIN) + HYPERSPACE_ENTER_MIN;
         vect_pset( &vp, d, VANGLE(lv->vec) );
      }
   }
   else {
      d = RNGF()*(HYPERSPACE_ENTER_MAX-HYPERSPACE_ENTER_MIN) + HYPERSPACE_ENTER_MIN;
      vect_pset( &vp, d, RNGF() * 2.*M_PI);
   }

   /* now we start adding pilots and toss ids into the table we return */
   j = 0;
   lua_newtable(L);
   for (i=0; i<flt->npilots; i++) {

      plt = &flt->pilots[i];

      if (RNG(0,100) <= plt->chance) {

         /* fleet displacement */
         vect_cadd(&vp, RNG(75,150) * (RNG(0,1) ? 1 : -1),
               RNG(75,150) * (RNG(0,1) ? 1 : -1));

         /* Set velocity only if no position is set.. */
         if (lv != NULL) {
            if (jump) {
               a = vect_angle(&vp,&vn);
               vect_pset( &vv, HYPERSPACE_VEL, a );
            }
            else {
               a = RNGF() * 2.*M_PI;
               vectnull( &vv );
            }
         }
         else { /* Entering via hyperspace. */
            a = vect_angle(&vp,&vn);
            vect_pset( &vv, HYPERSPACE_VEL, a );
         }

         /* Make sure angle is sane. */
         if (a < 0.)
            a += 2.*M_PI;

         /* Create the pilot. */
         p = fleet_createPilot( flt, plt, a, &vp, &vv, fltai, 0 );

         /* we push each pilot created into a table and return it */
         lua_pushnumber(L,++j); /* index, starts with 1 */
         lp.pilot = p;
         lua_pushpilot(L,lp); /* value = LuaPilot */
         lua_rawset(L,-3); /* store the value in the table */
      }
   }
   return 1;
}
예제 #7
0
파일: weapon.c 프로젝트: zid/naev
/**
 * @brief Creates a new weapon.
 *
 *    @param outfit Outfit which spawned the weapon.
 *    @param dir Direction the shooter is facing.
 *    @param pos Position of the shooter.
 *    @param vel Velocity of the shooter.
 *    @param parent Shooter ID.
 *    @param target Target ID of the shooter.
 *    @return A pointer to the newly created weapon.
 */
static Weapon* weapon_create( const Outfit* outfit,
      const double dir, const Vector2d* pos, const Vector2d* vel,
      const unsigned int parent, const unsigned int target )
{
   Vector2d v;
   double mass, rdir;
   Pilot *pilot_target;
   double x,y, t, dist;
   Weapon* w;

   /* Create basic features */
   w = malloc(sizeof(Weapon));
   memset(w, 0, sizeof(Weapon));
   w->faction = pilot_get(parent)->faction; /* non-changeable */
   w->parent = parent; /* non-changeable */
   w->target = target; /* non-changeable */
   w->outfit = outfit; /* non-changeable */
   w->update = weapon_update;
   w->status = WEAPON_STATUS_OK;
   w->strength = 1.;

   switch (outfit->type) {

      /* Bolts treated together */
      case OUTFIT_TYPE_BOLT:
      case OUTFIT_TYPE_TURRET_BOLT:
         /* Only difference is the direction of fire */
         if ((outfit->type == OUTFIT_TYPE_TURRET_BOLT) && (w->parent!=w->target) &&
               (w->target != 0)) { /* Must have valid target */

            pilot_target = pilot_get(w->target);
            if (pilot_target == NULL)
               rdir = dir;

            else {
               /* Get the distance */
               dist = vect_dist( pos, &pilot_target->solid->pos );

               /* Aim. */
               if (dist > outfit->u.blt.range*1.2) {
                  x = pilot_target->solid->pos.x - pos->x;
                  y = pilot_target->solid->pos.y - pos->y;
               }
               else {
                  /* Try to predict where the enemy will be. */
                  /* Time for shots to reach that distance */
                  t = dist / (w->outfit->u.blt.speed + VMOD(*vel));

                  /* Position is calculated on where it should be */
                  x = (pilot_target->solid->pos.x + pilot_target->solid->vel.x*t)
                     - (pos->x + vel->x*t);
                  y = (pilot_target->solid->pos.y + pilot_target->solid->vel.y*t)
                     - (pos->y + vel->y*t);
               }

               /* Set angle to face. */
               rdir = ANGLE(x, y);
            }
         }
         else /* fire straight */
            rdir = dir;

         rdir += RNG_2SIGMA() * outfit->u.blt.accuracy/2. * 1./180.*M_PI;
         if (rdir < 0.)
            rdir += 2.*M_PI;
         else if (rdir >= 2.*M_PI)
            rdir -= 2.*M_PI;

         mass = 1; /* Lasers are presumed to have unitary mass */
         vectcpy( &v, vel );
         vect_cadd( &v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
         w->timer = outfit->u.blt.range / outfit->u.blt.speed;
         w->falloff = w->timer - outfit->u.blt.falloff / outfit->u.blt.speed;
         w->solid = solid_create( mass, rdir, pos, &v );
         w->voice = sound_playPos( w->outfit->u.blt.sound,
               w->solid->pos.x,
               w->solid->pos.y,
               w->solid->vel.x,
               w->solid->vel.y);
         break;

      /* Beam weapons are treated together. */
      case OUTFIT_TYPE_BEAM:
      case OUTFIT_TYPE_TURRET_BEAM:
         if ((outfit->type == OUTFIT_TYPE_TURRET_BEAM) && (w->parent!=w->target)) {
            pilot_target = pilot_get(target);
            rdir = (pilot_target == NULL) ? dir :
                  vect_angle(pos, &pilot_target->solid->pos);
         }
         else
            rdir = dir;
         if (rdir < 0.)
            rdir += 2.*M_PI;
         else if (rdir >= 2.*M_PI)
            rdir -= 2.*M_PI;
         mass = 1.; /**< Needs a mass. */
         w->solid = solid_create( mass, rdir, pos, NULL );
         w->think = think_beam;
         w->timer = outfit->u.bem.duration;
         w->voice = sound_playPos( w->outfit->u.bem.sound,
               w->solid->pos.x,
               w->solid->pos.y,
               w->solid->vel.x,
               w->solid->vel.y);
         break;

      /* Treat seekers together. */
      case OUTFIT_TYPE_AMMO:
      case OUTFIT_TYPE_TURRET_AMMO:
         if (w->outfit->type == OUTFIT_TYPE_TURRET_AMMO) {
            pilot_target = pilot_get(w->target);
            if (pilot_target == NULL)
               rdir = dir;

            else {
               /* Get the distance */
               dist = vect_dist( pos, &pilot_target->solid->pos );

               /* Aim. */
               /* Try to predict where the enemy will be. */
               /* Time for shots to reach that distance */
               if (outfit->u.amm.thrust == 0.)
                  t = dist / (w->outfit->u.amm.speed + VMOD(*vel));
               else
                  t = dist / w->outfit->u.amm.speed;

               /* Position is calculated on where it should be */
               x = (pilot_target->solid->pos.x + pilot_target->solid->vel.x*t)
                  - (pos->x + vel->x*t);
               y = (pilot_target->solid->pos.y + pilot_target->solid->vel.y*t)
                  - (pos->y + vel->y*t);

               /* Set angle to face. */
               rdir = ANGLE(x, y);
            }
         }
         else {
            rdir = dir;
         }
         if (outfit->u.amm.accuracy != 0.) {
            rdir += RNG_2SIGMA() * outfit->u.amm.accuracy/2. * 1./180.*M_PI;
            if ((rdir > 2.*M_PI) || (rdir < 0.))
               rdir = fmod(rdir, 2.*M_PI);
         }
         if (rdir < 0.)
            rdir += 2.*M_PI;
         else if (rdir >= 2.*M_PI)
            rdir -= 2.*M_PI;

         /* If thrust is 0. we assume it starts out at speed. */
         vectcpy( &v, vel );
         if (outfit->u.amm.thrust == 0.)
            vect_cadd( &v, cos(rdir) * w->outfit->u.amm.speed,
                  sin(rdir) * w->outfit->u.amm.speed );

         /* Set up ammo details. */
         mass        = w->outfit->mass;
         w->lockon   = outfit->u.amm.lockon;
         w->timer    = outfit->u.amm.duration;
         w->solid    = solid_create( mass, rdir, pos, &v );
         if (w->outfit->u.amm.thrust != 0.)
            weapon_setThrust( w, w->outfit->u.amm.thrust * mass );

         /* Handle seekers. */
         if (w->outfit->u.amm.ai > 0) {
            w->think = think_seeker; /* AI is the same atm. */

            /* If they are seeking a pilot, increment lockon counter. */
            pilot_target = pilot_get(target);
            if (pilot_target != NULL)
               pilot_target->lockons++;
         }

         /* Play sound. */
         w->voice    = sound_playPos(w->outfit->u.amm.sound,
               w->solid->pos.x,
               w->solid->pos.y,
               w->solid->vel.x,
               w->solid->vel.y);
         break;

      /* just dump it where the player is */
      default:
         WARN("Weapon of type '%s' has no create implemented yet!",
               w->outfit->name);
         w->solid = solid_create( 1., dir, pos, vel );
         break;
   }

   /* Set life to timer. */
   w->life = w->timer;

   return w;
}