예제 #1
0
파일: physics.c 프로젝트: Anatolis/naev
/**
 * @brief Initializes a new Solid.
 *
 *    @param dest Solid to initialize.
 *    @param mass Mass to set solid to.
 *    @param dir Solid initial direction.
 *    @param pos Initial solid position.
 *    @param vel Initial solid velocity.
 */
void solid_init( Solid* dest, const double mass, const double dir,
      const Vector2d* pos, const Vector2d* vel, int update )
{
   memset(dest, 0, sizeof(Solid));

   dest->mass = mass;

   /* Set direction velocity. */
   dest->dir_vel = 0.;

   /* Set force. */
   dest->thrust  = 0.;

   /* Set direction. */
   dest->dir = dir;
   if ((dest->dir > 2.*M_PI) || (dest->dir < 0.))
      dest->dir = fmod(dest->dir, 2.*M_PI);

   /* Set velocity. */
   if (vel == NULL)
      vectnull( &dest->vel );
   else
      vectcpy( &dest->vel, vel );

   /* Set position. */
   if (pos == NULL)
      vectnull( &dest->pos );
   else
      vectcpy( &dest->pos, pos);

   /* Misc. */
   dest->speed_max = -1.; /* Negative is invalid. */

   /* Handle update. */
   switch (update) {
      case SOLID_UPDATE_RK4:
         dest->update = solid_update_rk4;
         break;

      case SOLID_UPDATE_EULER:
         dest->update = solid_update_euler;
         break;

      default:
         WARN("Solid initialization did not specify correct update function!");
         dest->update = solid_update_rk4;
         break;
   }
}
예제 #2
0
파일: nlua_player.c 프로젝트: s0be/naev
/**
 * @brief Gets the player's position.
 *
 * @usage v = player.pos()
 *
 *    @luareturn The position of the player (Vec2).
 * @luafunc pos()
 */
static int playerL_getPosition( lua_State *L )
{
   LuaVector v;

   vectcpy( &v.vec, &player.p->solid->pos );
   lua_pushvector(L, v);
   return 1;
}
예제 #3
0
파일: nlua_jump.c 프로젝트: BariumBlue/naev
/**
 * @brief Gets the position of the jump in the system.
 *
 * @usage v = j:pos()
 *    @luaparam j Jump to get the position of.
 *    @luareturn The position of the jump in the system as a vec2.
 * @luafunc pos( j )
 */
static int jumpL_position( lua_State *L )
{
   JumpPoint *jp;
   LuaVector v;
   jp = luaL_validjump(L,1);
   vectcpy(&v.vec, &jp->pos);
   lua_pushvector(L, v);
   return 1;
}
예제 #4
0
파일: nlua_planet.c 프로젝트: ekrumme/naev
/**
 * @brief Gets the position of the planet in the system.
 *
 * @usage v = p:pos()
 *    @luaparam p Planet to get the position of.
 *    @luareturn The position of the planet in the system as a vec2.
 * @luafunc pos( p )
 */
static int planetL_position( lua_State *L )
{
   LuaPlanet *p;
   LuaVector v;
   p = luaL_checkplanet(L,1);
   vectcpy(&v.vec, &p->p->pos);
   lua_pushvector(L, v);
   return 1;
}
예제 #5
0
파일: nlua_pilot.c 프로젝트: pegue/naev
/**
 * @brief Gets the pilot's velocity.
 *
 * @usage vel = p:vel()
 *
 *    @luaparam p Pilot to get the velocity of.
 *    @luareturn The pilot's current velocity as a vec2.
 * @luafunc vel( p )
 */
static int pilotL_velocity( lua_State *L )
{
   LuaPilot *p1;
   Pilot *p;
   LuaVector v;

   /* Parse parameters */
   p1 = luaL_checkpilot(L,1);
   p  = pilot_get( p1->pilot );

   /* Pilot must exist. */
   if (p == NULL) {
      NLUA_ERROR(L,"Pilot is invalid.");
      return 0;
   }

   /* Push velocity. */
   vectcpy( &v.vec, &p->solid->vel );
   lua_pushvector(L, v);
   return 1;
}
예제 #6
0
파일: nlua_pilot.c 프로젝트: pegue/naev
/**
 * @brief Sets the pilot's position.
 *
 * @usage p:warp( vec2.new( 300, 200 ) )
 *
 *    @luaparam p Pilot to set the position of.
 *    @luaparam pos Position to set.
 * @luafunc warp( p, pos )
 */
static int pilotL_warp( lua_State *L )
{
   LuaPilot *p1;
   Pilot *p;
   LuaVector *v;

   /* Parse parameters */
   p1 = luaL_checkpilot(L,1);
   p  = pilot_get( p1->pilot );
   v  = luaL_checkvector(L,2);

   /* Pilot must exist. */
   if (p == NULL) {
      NLUA_ERROR(L,"Pilot is invalid.");
      return 0;
   }

   /* Warp pilot to new position. */
   vectcpy( &p->solid->pos, &v->vec );
   vectnull( &p->solid->vel ); /* Clear velocity otherwise it's a bit weird. */
   return 0;
}
예제 #7
0
파일: nlua_system.c 프로젝트: reynir/naev
/**
 * @brief Gets the position of a jump point from one system to another.
 *
 * @usage v = system.cur():jumpPos( neighbour_system ) -- Gets the position of the jump point to neighbour_system
 *
 *    @luaparam from System jumping from.
 *    @luaparam to System jumping to.
 *    @luareturn A Vector2D containing the jump position or nil if not connected.
 * @luafunc jumpPos( from, to )
 */
static int systemL_jumpPos( lua_State *L )
{
    LuaVector lv;
    StarSystem *from, *to;
    int i;

    from  = luaL_validsystem(L,1);
    to    = luaL_validsystem(L,2);

    for (i=0; i<from->njumps; i++) {
        /* Wait until found. */
        if (from->jumps[i].target != to)
            continue;

        vectcpy( &lv.vec, &from->jumps[i].pos );
        lua_pushvector(L,lv);
        return 1;
    }

    lua_pushnil(L);
    return 1;
}
예제 #8
0
/**
 * @brief Teleports the player to a new planet or system (only if not landed).
 *
 * If the destination is a system, the coordinates of the player will not change.
 * If the destination is a planet, the player will be placed over that planet.
 *
 * @usage player.teleport( system.get("Arcanis") ) -- Teleports the player to Arcanis.
 * @usage player.teleport( "Arcanis" ) -- Teleports the player to Arcanis.
 * @usage player.teleport( "Dvaer Prime" ) -- Teleports the player to Dvaer, and relocates him to Dvaer Prime.
 *
 *    @luaparam dest System or name of a system or planet or name of a planet to teleport the player to.
 * @luafunc teleport( dest )
 */
static int playerL_teleport( lua_State *L )
{
    Planet *pnt;
    StarSystem *sys;
    const char *name, *pntname;

    /* Must not be landed. */
    if (landed)
        NLUA_ERROR(L,"Can not teleport the player while landed!");
    if (comm_isOpen())
        NLUA_ERROR(L,"Can not teleport the player while the comm is open!");
    if (player_isBoarded())
        NLUA_ERROR(L,"Can not teleport the player while he is boarded!");

    pnt = NULL;

    /* Get a system. */
    if (lua_issystem(L,1)) {
        sys   = luaL_validsystem(L,1);
        name  = system_getIndex(sys->id)->name;
    }
    /* Get a planet. */
    else if (lua_isplanet(L,1)) {
        pnt   = luaL_validplanet(L,1);
        name  = planet_getSystem( pnt->name );
        if (name == NULL) {
            NLUA_ERROR( L, "Planet '%s' does not belong to a system..", pnt->name );
            return 0;
        }
    }
    /* Get destination from string. */
    else if (lua_isstring(L,1)) {
        name = lua_tostring(L,1);
        if (!system_exists( name )) {
            if (!planet_exists( name )) {
                NLUA_ERROR( L, "'%s' is not a valid teleportation target.", name );
                return 0;
            }

            /* No system found, assume destination string is the name of a planet. */
            pntname = name;
            name = planet_getSystem( name );
            pnt  = planet_get( pntname );
            if (name == NULL) {
                NLUA_ERROR( L, "Planet '%s' does not belong to a system..", pntname );
                return 0;
            }
        }
    }
    else
        NLUA_INVALID_PARAMETER(L);

    /* Check if system exists. */
    if (!system_exists( name )) {
        NLUA_ERROR( L, "System '%s' does not exist.", name );
        return 0;
    }

    /* Jump out hook is run first. */
    hooks_run( "jumpout" );

    /* Just in case remove hyperspace flags. */
    pilot_rmFlag( player.p, PILOT_HYPERSPACE );
    pilot_rmFlag( player.p, PILOT_HYP_BEGIN );
    pilot_rmFlag( player.p, PILOT_HYP_BRAKE );
    pilot_rmFlag( player.p, PILOT_HYP_PREP );

    /* Free graphics. */
    space_gfxUnload( cur_system );

    /* Go to the new system. */
    space_init( name );

    /* Map gets deformed when jumping this way. */
    map_clear();

    /* Add the escorts. */
    player_addEscorts();

    /* Run hooks - order is important. */
    hooks_run( "jumpin" );
    hooks_run( "enter" );
    events_trigger( EVENT_TRIGGER_ENTER );
    missions_run( MIS_AVAIL_SPACE, -1, NULL, NULL );

    /* Reset targets when teleporting */
    player_targetPlanetSet( -1 );
    player_targetHyperspaceSet( -1 );
    gui_setNav();

    /* Move to planet. */
    if (pnt != NULL)
        vectcpy( &player.p->solid->pos, &pnt->pos );

    return 0;
}
예제 #9
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;
}
예제 #10
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;
}