Exemple #1
0
/**
 * @brief The pseudo-ai of the beam weapons.
 *
 *    @param w Weapon to do the thinking.
 *    @param dt Current delta tick.
 */
static void think_beam( Weapon* w, const double dt )
{
   (void)dt;
   Pilot *p, *t;
   double diff;
   Vector2d v;

   /* Get pilot, if pilot is dead beam is destroyed. */
   p = pilot_get(w->parent);
   if (p==NULL) {
      w->timer = -1.; /* Hack to make it get destroyed next update. */
      return;
   }

   /* Check if pilot has enough energy left to keep beam active. */
   p->energy -= dt*w->outfit->u.bem.energy;
   if (p->energy < 0.) {
      p->energy = 0.;
      w->timer = -1;
      return;
   }

   /* Use mount position. */
   pilot_getMount( p, w->mount, &v );
   w->solid->pos.x = p->solid->pos.x + v.x;
   w->solid->pos.y = p->solid->pos.y + v.y;

   /* Handle aiming. */
   switch (w->outfit->type) {
      case OUTFIT_TYPE_BEAM:
         w->solid->dir = p->solid->dir;
         break;

      case OUTFIT_TYPE_TURRET_BEAM:
         /* Get target, if target is dead beam stops moving. */
         t = pilot_get(w->target);
         if (t==NULL) {
            weapon_setTurn( w, 0. );
            return;
         }

         if (w->target == w->parent) /* Invalid target, tries to follow shooter. */
            diff = angle_diff(w->solid->dir, p->solid->dir);
         else
            diff = angle_diff(w->solid->dir, /* Get angle to target pos */
                  vect_angle(&w->solid->pos, &t->solid->pos));
         weapon_setTurn( w, CLAMP( -w->outfit->u.bem.turn, w->outfit->u.bem.turn,
                  10 * diff *  w->outfit->u.bem.turn ));
         break;

      default:
         return;
   }
}
Exemple #2
0
/**
 * @brief Updates the camera.
 *
 *    @param dt Current delta tick.
 */
void cam_update( double dt )
{
   Pilot *p;
   double dx, dy;

   /* Calculate differential. */
   dx    = old_X;
   dy    = old_Y;

   /* Going to position. */
   p   = NULL;
   if (camera_fly) {
      if (camera_followpilot != 0) {
         p = pilot_get( camera_followpilot );
         if (p == NULL) {
            camera_followpilot = 0;
            camera_fly = 0;
         }
         else {
            cam_updateFly( p->solid->pos.x, p->solid->pos.y, dt );
            cam_updatePilotZoom( p, NULL, dt );
         }
      }
      else
         cam_updateFly( target_X, target_Y, dt );
   }
   else {
      /* Track pilot. */
      if (camera_followpilot != 0) {
         p = pilot_get( camera_followpilot );
         if (p == NULL)
            camera_followpilot = 0;
         else
            cam_updatePilot( p, dt );
      }
   }

   /* Update manual zoom. */
   if (conf.zoom_manual)
      cam_updateManualZoom( dt );

   /* Set the sound. */
   if ((p==NULL) || !conf.snd_pilotrel) {
      dx = dt*(dx-camera_X);
      dy = dt*(dy-camera_Y);
      sound_updateListener( CAMERA_DIR, camera_X, camera_Y, dx, dy );
   }
   else {
      sound_updateListener( p->solid->dir,
            p->solid->pos.x, p->solid->pos.y,
            p->solid->vel.x, p->solid->vel.y );
   }
}
Exemple #3
0
/**
 * @brief Creates an escort.
 *
 *    @param p Parent of the escort (who he's guarding).
 *    @param ship Name of the ship escort should have.
 *    @param pos Position to create escort at.
 *    @param vel Velocity to create escort with.
 *    @param dir Direction to face.
 *    @param type Type of escort.
 *    @param add Whether or not to add it to the escort list.
 *    @return The ID of the escort on success.
 */
unsigned int escort_create( Pilot *p, char *ship,
      Vector2d *pos, Vector2d *vel, double dir,
      EscortType_t type, int add )
{
   Ship *s;
   Pilot *pe;
   unsigned int e;
   PilotFlags f;
   unsigned int parent;

   /* Get important stuff. */
   parent = p->id;
   s = ship_get(ship);

   /* Set flags. */
   pilot_clearFlagsRaw( f );
   pilot_setFlagRaw( f, PILOT_NOJUMP );
   if (type == ESCORT_TYPE_BAY)
      pilot_setFlagRaw( f, PILOT_CARRIED );

   /* Create the pilot. */
   e = pilot_create( s, NULL, p->faction, "escort", dir, pos, vel, f );
   pe = pilot_get(e);
   pe->parent = parent;

   /* Add to escort list. */
   if (add != 0)
      escort_addList( p, ship, type, e, 1 );

   return e;
}
Exemple #4
0
/**
 * @brief Changes the pilot's AI.
 *
 * @usage p:changeAI( "empire" ) -- set the pilot to use the Empire AI
 *
 * @luafunc changeAI( p, newai )
 */
static int pilotL_changeAI( lua_State *L )
{
   LuaPilot *lp;
   Pilot *p;
   const char *str;
   int ret;

   /* Get the pilot. */
   lp = luaL_checkpilot(L,1);
   p  = pilot_get(lp->pilot);
   if (p==NULL) {
      NLUA_ERROR(L,"Pilot is invalid.");
      return 0;
   }

   /* Get parameters. */
   str = luaL_checkstring(L,2);

   /* Get rid of current AI. */
   ai_destroy(p);

   /* Create the new AI. */
   ret = ai_pinit( p, str );
   lua_pushboolean(L, ret);
   return 1;
}
Exemple #5
0
/**
 * @brief Hooks the function to a specific pilot.
 *
 * You can hook to different actions.  Curently hook system only supports:<br />
 *    - "death" : triggered when pilot dies.<br />
 *    - "board" : triggered when pilot is boarded.<br />
 *    - "disable" : triggered when pilot is disabled.<br />
 *    - "jump" : triggered when pilot jumps to hyperspace.<br />
 *    - "hail" : triggered when pilot is hailed.<br />
 *    - "attacked" : triggered when the pilot is attacked in manual control <br />
 *    - "idle" : triggered when the pilot becomes idle in manual control <br />
 *
 *    @luaparam pilot Pilot identifier to hook.
 *    @luaparam type One of the supported hook types.
 *    @luaparam funcname Name of function to run when hook is triggered.
 *    @luareturn Hook identifier.
 * @luafunc pilot( pilot, type, funcname )
 */
static int hook_pilot( lua_State *L )
{
   unsigned int h;
   LuaPilot *p;
   int type;
   const char *hook_type;

   /* Parameters. */
   p           = luaL_checkpilot(L,1);
   hook_type   = luaL_checkstring(L,2);

   /* Check to see if hook_type is valid */
   if (strcmp(hook_type,"death")==0)         type = PILOT_HOOK_DEATH;
   else if (strcmp(hook_type,"board")==0)    type = PILOT_HOOK_BOARD;
   else if (strcmp(hook_type,"disable")==0)  type = PILOT_HOOK_DISABLE;
   else if (strcmp(hook_type,"jump")==0)     type = PILOT_HOOK_JUMP;
   else if (strcmp(hook_type,"hail")==0)     type = PILOT_HOOK_HAIL;
   else if (strcmp(hook_type,"attacked")==0) type = PILOT_HOOK_ATTACKED;
   else if (strcmp(hook_type,"idle")==0)     type = PILOT_HOOK_IDLE;
   else { /* hook_type not valid */
      NLUA_DEBUG("Invalid pilot hook type: '%s'", hook_type);
      return 0;
   }

   /* actually add the hook */
   h = hook_generic( L, hook_type, 3 );
   pilot_addHook( pilot_get(p->pilot), type, h );

   return 0;
}
Exemple #6
0
/**
 * @brief Throws cargo out in space graphically.
 *
 *    @param pilot ID of the pilot throwing the stuff out
 *    @param com Commodity to throw out.
 *    @param quantity Quantity thrown out.
 */
void commodity_Jettison( int pilot, Commodity* com, int quantity )
{
   (void)com;
   int i;
   Pilot* p;
   int n, effect;
   double px,py, bvx, bvy, r,a, vx,vy;

   p = pilot_get( pilot );

   n = MAX( 1, RNG(quantity/10, quantity/5) );
   px = p->solid->pos.x;
   py = p->solid->pos.y;
   bvx = p->solid->vel.x;
   bvy = p->solid->vel.y;
   for (i=0; i<n; i++) {
      effect = spfx_get("cargo");

      /* Radial distribution gives much nicer results */
      r  = RNGF()*25 - 12.5;
      a  = 2. * M_PI * RNGF();
      vx = bvx + r*cos(a);
      vy = bvy + r*sin(a);

      /* Add the cargo effect */
      spfx_add( effect, px, py, vx, vy, SPFX_LAYER_BACK );
   }
}
Exemple #7
0
/**
 * @brief Has a pilot attempt to board another pilot.
 * 
 *    @param p Pilot doing the boarding.
 *    @return 1 if target was boarded.
 */
int pilot_board( Pilot *p )
{
   Pilot *target;

   /* Make sure target is sane. */
   target = pilot_get(p->target);
   if (target == NULL) {
      DEBUG("NO TARGET");
      return 0;
   }

   /* Check if can board. */
   if (!pilot_isDisabled(target))
      return 0;
   else if (vect_dist(&p->solid->pos, &target->solid->pos) >
         target->ship->gfx_space->sw * PILOT_SIZE_APROX )
      return 0;
   else if ((pow2(VX(p->solid->vel)-VX(target->solid->vel)) +
            pow2(VY(p->solid->vel)-VY(target->solid->vel))) >
            (double)pow2(MAX_HYPERSPACE_VEL))
      return 0;
   else if (pilot_isFlag(target,PILOT_BOARDED))
      return 0;

   /* Set the boarding flag. */
   pilot_setFlag(target, PILOT_BOARDED);
   pilot_setFlag(p, PILOT_BOARDING);

   /* Set time it takes to board. */
   p->ptimer = 3.;

   return 1;
}
Exemple #8
0
/**
 * @brief Updates the boarding window fields.
 *
 *    @param wdw Window to update.
 */
static void board_update( unsigned int wdw )
{
   int i, j;
   char str[PATH_MAX];
   char cred[10];
   Pilot* p;

   p = pilot_get(player->target);
   j = 0;

   /* Credits. */
   credits2str( cred, p->credits, 2 );
   j += snprintf( &str[j], PATH_MAX-j, "%s\n", cred );

   /* Commodities. */
   if (p->ncommodities==0)
      j += snprintf( &str[j], PATH_MAX-j, "none\n" );
   else {
      for (i=0; i<p->ncommodities; i++)
         j += snprintf( &str[j], PATH_MAX-j,
               "%d %s\n",
               p->commodities[i].quantity, p->commodities[i].commodity->name );
   }

   /* Fuel. */
   if (p->fuel <= 0.)
      j += snprintf( &str[j], PATH_MAX-j, "none\n" );
   else
      j += snprintf( &str[j], PATH_MAX-j, "%.0f Units\n", p->fuel );

   window_modifyText( wdw, "txtData", str ); 
}
Exemple #9
0
/**
 * @brief Checks to see if the pilot can steal from it's target.
 *
 *    @param p Pilot stealing from it's target.
 *    @return 0 if successful, 1 if fails, -1 if fails and kills target.
 */
static int board_trySteal( Pilot *p )
{
   Pilot *target;

   /* Get the target. */
   target = pilot_get(p->target);
   if (target == NULL)
      return 1;

   /* See if was successful. */
   if (RNGF() > (0.5 * 
            (10. + (double)target->ship->crew)/(10. + (double)p->ship->crew)))
      return 0;

   /* Triggered self destruct. */
   if (RNGF() < 0.4) {
      /* Don't actually kill. */
      target->armour = 1.;
      /* This will make the boarding ship take the possible faction hit. */
      pilot_hit( target, NULL, p->id, DAMAGE_TYPE_KINETIC, 100. );
      /* Return ship dead. */
      return -1;
   }

   return 1;
}
Exemple #10
0
/**
 * @brief Sets the target to follow.
 */
void cam_setTargetPilot( unsigned int follow, int soft_over )
{
   Pilot *p;
   double dir, x, y;

   /* Set the target. */
   camera_followpilot   = follow;
   dir                  = CAMERA_DIR;

   /* Set camera if necessary. */
   if (!soft_over) {
      if (follow != 0) {
         p = pilot_get( follow );
         if (p != NULL) {
            dir      = p->solid->dir;
            x        = p->solid->pos.x;
            y        = p->solid->pos.y;
            camera_X = x;
            camera_Y = y;
            old_X    = x;
            old_Y    = y;
         }
      }
      camera_fly = 0;
   }
   else {
      old_X    = camera_X;
      old_Y    = camera_Y;
      camera_fly = 1;
      camera_flyspeed = (double) soft_over;
   }
   sound_updateListener( dir, camera_X, camera_Y, 0., 0. );
}
Exemple #11
0
/**
 * @brief Adds an outfit to a pilot.
 *
 * @usage added = p:addOutfit( "Laser Cannon", 5 ) -- Adds 5 laser cannons to p
 *
 *    @luaparam p Pilot to add outfit to.
 *    @luaparam outfit Name of the outfit to add.
 *    @luaparam q Amount to add.
 *    @luareturn The amount actually added.
 * @luafunc addOutfit( p, outfit, q )
 */
static int pilotL_addOutfit( lua_State *L )
{
   LuaPilot *lp;
   Pilot *p;
   const char *outfit;
   int q, n;
   Outfit *o;

   /* Get the pilot. */
   lp = luaL_checkpilot(L,1);
   p  = pilot_get(lp->pilot);
   if (p==NULL) {
      NLUA_ERROR(L,"Pilot is invalid.");
      return 0;
   }

   /* Get parameters. */
   outfit = luaL_checkstring(L,2);
   q      = luaL_checkint(L,3);

   /* Get the outfit. */
   o = outfit_get( outfit );
   if (o == NULL)
      return 0;
   
   /* Add outfit. */
   n = pilot_addOutfit( p, o, q );
   lua_pushnumber(L,n);
   return 1;
}
Exemple #12
0
/**
 * @brief Attempt to steal the boarded ship's cargo.
 *
 *    @param wdw Window triggering the function.
 *    @param str Unused.
 */
static void board_stealCargo( unsigned int wdw, char* str )
{
   (void)str;
   int q;
   Pilot* p;

   p = pilot_get(player->target);

   if (p->ncommodities==0) { /* no cargo */
      player_message("The ship has no cargo.");
      return;
   }
   else if (pilot_cargoFree(player) <= 0) {
      player_message("You have no room for cargo.");
      return;
   }

   if (board_fail(wdw)) return;

   /** steal as much as possible until full - @todo let player choose */
   q = 1;
   while ((p->ncommodities > 0) && (q!=0)) {
      q = pilot_addCargo( player, p->commodities[0].commodity,
            p->commodities[0].quantity );
      pilot_rmCargo( p, p->commodities[0].commodity, q );
   }

   board_update( wdw );
   player_message("You manage to steal the ship's cargo.");
}
Exemple #13
0
/**
 * @brief Attempt to steal the boarded ship's fuel.
 *
 *    @param wdw Window triggering the function.
 *    @param str Unused.
 */
static void board_stealFuel( unsigned int wdw, char* str )
{
   (void)str;
   Pilot* p;

   p = pilot_get(player->target);

   if (p->fuel <= 0.) { /* no fuel. */
      player_message("The ship has no fuel.");
      return;
   }
   else if (player->fuel == player->fuel_max) {
      player_message("Your ship is at maximum fuel capacity.");
      return;
   }

   if (board_fail(wdw)) return;

   /* Steal fuel. */
   player->fuel += p->fuel;
   p->fuel = 0.;

   /* Make sure doesn't overflow. */
   if (player->fuel > player->fuel_max) {
      p->fuel = player->fuel_max - player->fuel;
      player->fuel = player->fuel_max;
   }

   board_update( wdw );
   player_message("You manage to steal the ship's fuel.");
}
Exemple #14
0
/**
 * @brief Sets the pilot's faction.
 *
 * @usage p:setFaction( "Empire" )
 * @usage p:setFaction( faction.get( "Dvaered" ) )
 *
 *    @luaparam p Pilot to change faction of.
 *    @luaparam faction Faction to set by name or faction.
 * @luafunc setFaction( faction )
 */
static int pilotL_setFaction( lua_State *L )
{
   Pilot *p;
   LuaPilot *lp;
   LuaFaction *f;
   int fid;
   const char *faction;

   /* Parse parameters. */
   lp = luaL_checkpilot(L,1);
   if (lua_isstring(L,2)) {
      faction = lua_tostring(L,2);
      fid = faction_get(faction);
   }
   else if (lua_isfaction(L,2)) {
      f = lua_tofaction(L,2);
      fid = f->f;
   }
   else NLUA_INVALID_PARAMETER();

   /* Get pilot/faction. */
   p = pilot_get(lp->pilot);
   if (p==NULL) {
      NLUA_ERROR(L,"Pilot is invalid.");
      return 0;
   }

   /* Set the new faction. */
   p->faction = fid;

   return 0;
}
Exemple #15
0
/**
 * @brief Runs an escort command on all of a pilot's escorts.
 *
 *    @param parent Pilot who is giving orders.
 *    @param cmd Order to give.
 *    @param param Parameter for order.
 *    @return 0 on success, 1 if no orders given.
 */
static int escort_command( Pilot *parent, int cmd, int param )
{
   int i, n;
   lua_State *L;
   Pilot *e;
   char *buf;

   if (parent->nescorts == 0)
      return 1;

   n = 0;
   for (i=0; i<parent->nescorts; i++) {
      e = pilot_get( parent->escorts[i] );
      if (e == NULL) /* Most likely died. */
         continue;

      /* Check if command makes sense. */
      if ((cmd == ESCORT_RETURN) && !pilot_isFlag(e, PILOT_CARRIED))
         continue;

      n++; /* Amount of escorts left. */

      /* Prepare ai. */
      ai_setPilot( e );

      /* Set up stack. */
      L = e->ai->L;
      switch (cmd) {
         case ESCORT_ATTACK:
            buf = "e_attack";
            break;
         case ESCORT_HOLD:
            buf = "e_hold";
            break;
         case ESCORT_RETURN:
            buf = "e_return";
            break;
         case ESCORT_CLEAR:
            buf = "e_clear";
            break;
      }
      lua_getglobal(L, buf);
      if (param >= 0)
         lua_pushnumber(L, param);

      /* Run command. */
      if (lua_pcall(L, (param >= 0) ? 1 : 0, 0, 0))
         WARN("Pilot '%s' ai -> '%s': %s", e->name,
               buf, lua_tostring(L,-1));
   }

   return !n;
}
Exemple #16
0
/**
 * @brief Sends a message to the target or player if no target is passed.
 *
 * @usage p:comm( "How are you doing?" ) -- Messages the player
 * @usage p:comm( "You got this?", true ) -- Messages the player ignoring interference
 * @usage p:comm( target, "Heya!" ) -- Messages target
 * @usage p:comm( target, "Got this?", true ) -- Messages target ignoring interference
 *
 *    @luaparam p Pilot to message the player.
 *    @ulaparam target Target to send message to.
 *    @luaparam msg Message to send.
 * @luafunc comm( p, target, msg )
 */
static int pilotL_comm( lua_State *L )
{
   Pilot *p, *t;
   LuaPilot *lp, *target;
   const char *msg;
   int ignore_int;

   /* Parse parameters. */
   lp    = luaL_checkpilot(L,1);
   if (lua_isstring(L,2)) {
      target = NULL;
      msg   = luaL_checkstring(L,2);
      ignore_int = lua_toboolean(L,3);
   }
   else {
      target = luaL_checkpilot(L,2);
      msg   = luaL_checkstring(L,3);
      ignore_int = lua_toboolean(L,4);
   }

   /* Check to see if pilot is valid. */
   p = pilot_get(lp->pilot);
   if (p == NULL) {
      NLUA_ERROR(L,"Pilot param 1 not found in pilot stack!");
      return 0;
   }
   if (target == NULL)
      t = player;
   else {
      t = pilot_get(target->pilot);
      if (t == NULL) {
         NLUA_ERROR(L,"Pilot param 2 not found in pilot stack!");
         return 0;
      }
   }

   /* Broadcast message. */
   pilot_message( p, t->id, msg, ignore_int );
   return 0;
}
Exemple #17
0
/**
 * @brief Checks to see if pilot is still alive.
 *
 * @usage if p:alive() then -- Pilot is still alive
 *
 *    @luaparam p Pilot to check to see if is still alive.
 *    @luareturn true if pilot is still alive.
 * @luafunc alive( p )
 */
static int pilotL_alive( lua_State *L )
{
   LuaPilot *lp;
   Pilot *p;

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

   /* Check if is alive. */
   lua_pushboolean(L, p!=NULL);
   return 1;
}
Exemple #18
0
Fichier : comm.c Projet : zid/naev
/**
 * @brief Opens the communication dialogue with a pilot.
 *
 *    @param pilot Pilot to communicate with.
 *    @return 0 on success.
 */
int comm_openPilot( unsigned int pilot )
{
   const char *msg;
   unsigned int wid;

   /* Get the pilot. */
   comm_pilot = pilot_get( pilot );
   if (comm_pilot == NULL)
      return -1;
  
   /* Must not be disabled. */
   if (pilot_isFlag(comm_pilot, PILOT_DISABLED)) {
      player_message("%s does not respond.", comm_pilot->name);
      return 0;
   }

   /* Check to see if pilot wants to communicate. */
   msg = comm_getString( "comm_no" );   
   if (msg != NULL) {
      player_message( msg );
      return 0;
   }

   /* Set up for the comm_get* functions. */
   ai_setPilot( comm_pilot );

   /* Create the generic comm window. */
   wid = comm_open( ship_loadCommGFX( comm_pilot->ship ),
         comm_pilot->faction,
         pilot_isHostile(comm_pilot) ? -1 : pilot_isFriendly(comm_pilot) ? 1 : 0,
         pilot_isFlag(comm_pilot, PILOT_BRIBED),
         comm_pilot->name );

   /* Add special buttons. */
   window_addButton( wid, -20, 20 + BUTTON_HEIGHT + 20,
         BUTTON_WIDTH, BUTTON_HEIGHT, "btnGreet", "Greet", NULL );
   if (!pilot_isFlag(comm_pilot, PILOT_BRIBED) && /* Not already bribed. */
         ((faction_getPlayer( comm_pilot->faction ) < 0) || /* Hostile. */
            pilot_isHostile(comm_pilot)))
      window_addButton( wid, -20, 20 + 2*BUTTON_HEIGHT + 40,
            BUTTON_WIDTH, BUTTON_HEIGHT, "btnBribe", "Bribe", comm_bribePilot );
   else
      window_addButton( wid, -20, 20 + 2*BUTTON_HEIGHT + 40,
            BUTTON_WIDTH, BUTTON_HEIGHT, "btnRequest",
            "Refuel", comm_requestFuel );

   /* Run hooks if needed. */
   pilot_runHook( comm_pilot, PILOT_HOOK_HAIL );

   return 0;
}
Exemple #19
0
/**
 * @brief Destroys a weapon.
 *
 *    @param w Weapon to destroy.
 *    @param layer Layer to which the weapon belongs.
 */
static void weapon_destroy( Weapon* w, WeaponLayer layer )
{
   int i;
   Weapon** wlayer;
   int *nlayer;
   Pilot *pilot_target;

   /* Decrement target lockons if needed */
   if (outfit_isSeeker(w->outfit)) {
      pilot_target = pilot_get( w->target );
      if (pilot_target != NULL)
         pilot_target->lockons--;
   }

   /* Stop playing sound if beam weapon. */
   if (outfit_isBeam(w->outfit)) {
      sound_stop( w->voice );
      sound_playPos(w->outfit->u.bem.sound_off,
            w->solid->pos.x,
            w->solid->pos.y,
            w->solid->vel.x,
            w->solid->vel.y);
   }

   switch (layer) {
      case WEAPON_LAYER_BG:
         wlayer = wbackLayer;
         nlayer = &nwbackLayer;
         break;
      case WEAPON_LAYER_FG:
         wlayer = wfrontLayer;
         nlayer = &nwfrontLayer;
         break;

      default:
         WARN("Unknown weapon layer!");
   }

   for (i=0; (wlayer[i] != w) && (i < *nlayer); i++); /* get to the curent position */
   if (i >= *nlayer) {
      WARN("Trying to destroy weapon not found in stack!");
      return;
   }

   weapon_free(wlayer[i]);
   wlayer[i] = NULL;
   (*nlayer)--;

   for ( ; i < (*nlayer); i++)
      wlayer[i] = wlayer[i+1];
}
Exemple #20
0
/**
 * @brief Creates an escort.
 *
 *    @param parent Parent of the escort (who he's guarding).
 *    @param ship Name of the ship escort should have.
 *    @param pos Position to create escort at.
 *    @param vel Velocity to create escort with.
 *    @param carried Does escort come out of the parent?
 */
int escort_create( unsigned int parent, char *ship,
      Vector2d *pos, Vector2d *vel, int carried )
{
   Ship *s;
   Pilot *p, *pe;
   char buf[16];
   unsigned int e, f;
   double dir;

   /* Get important stuff. */
   p = pilot_get(parent);
   s = ship_get(ship);
   snprintf(buf, 16, "escort*%u", parent);

   /* Set flags. */
   f = PILOT_ESCORT;
   if (carried) f |= PILOT_CARRIED;

   /* Get the direction. */
   if (carried) dir = p->solid->dir;
   else dir = 0.;

   /* Create the pilot. */
   e = pilot_create( s, NULL, p->faction, buf, dir, pos, vel, f );
   pe = pilot_get(e);
   pe->parent = parent;

   /* Add to escort list. */
   p->nescorts++;
   if (p->nescorts == 1)
      p->escorts = malloc(sizeof(unsigned int) * ESCORT_PREALLOC);
   else if (p->nescorts > ESCORT_PREALLOC)
      p->escorts = realloc( p->escorts, sizeof(unsigned int) * p->nescorts );
   p->escorts[p->nescorts-1] = e;

   return 0;
}
Exemple #21
0
/**
 * @brief Have a pilot order it's escorts to attack it's target.
 *
 *    @param parent Pilot giving the order.
 */
int escorts_attack( Pilot *parent )
{
   int ret;
   Pilot *t;

   ret = 1;
   if (parent->target != parent->id)
      ret = escort_command( parent, ESCORT_ATTACK, parent->target );
   if ((ret == 0) && (parent == player)) {
      t = pilot_get(parent->target);
      if (t != NULL)
         player_message("Escorts: Attacking %s.", t->name);
   }
   return ret;
}
Exemple #22
0
/**
 * @brief Plays a sound based on position.
 *
 *    @param sound Sound to play.
 *    @param px X position of the sound.
 *    @param py Y position of the sound.
 *    @param vx X velocity of the sound.
 *    @param vy Y velocity of the sound.
 *    @return Voice identifier on success.
 */
int sound_playPos( int sound, double px, double py, double vx, double vy )
{
   alVoice *v;
   alSound *s;
   Pilot *p;
   double cx, cy, dist;
   int target;

   if (sound_disabled)
      return 0;

   if ((sound < 0) || (sound >= sound_nlist))
      return -1;

   target = cam_getTarget();

   /* Following a pilot. */
   p = pilot_get(target);
   if (target && (p != NULL)) {
      if (!pilot_inRange( p, px, py ))
         return 0;
   }
   /* Set to a position. */
   else {
      cam_getPos(&cx, &cy);
      dist = pow2(px - cx) + pow2(py - cy);
      if (dist > pilot_sensorRange())
         return 0;
   }

   /* Gets a new voice. */
   v = voice_new();

   /* Get the sound. */
   s = &sound_list[sound];

   /* Try to play the sound. */
   if (sound_sys_playPos( v, s, px, py, vx, vy ))
      return -1;

   /* Actually add the voice to the list. */
   v->state = VOICE_PLAYING;
   v->id = ++voice_genid;
   voice_add(v);

   return v->id;
}
Exemple #23
0
/**
 * @brief Hooks the function to a specific pilot.
 *
 * You can hook to different actions.  Curently hook system only supports:<br />
 * <ul>
 *    <li> "death" : triggered when pilot dies (before marked as dead). <br />
 *    <li> "exploded" : triggered when pilot has died and the final explosion has begun. <br />
 *    <li> "board" : triggered when pilot is boarded.<br />
 *    <li> "disable" : triggered when pilot is disabled (with disable set).<br />
 *    <li> "jump" : triggered when pilot jumps to hyperspace (before he actually jumps out).<br />
 *    <li> "hail" : triggered when pilot is hailed.<br />
 *    <li> "land" : triggered when pilot is landing (right when starting land descent).<br />
 *    <li> "attacked" : triggered when the pilot is attacked. <br />
 *    <li> "idle" : triggered when the pilot becomes idle in manual control.<br />
 * </ul>
 * <br />
 * If you pass nil as pilot, it will set it as a global hook that will jump for all pilots.<br />
 * <br />
 * DO NOT DO UNSAFE THINGS IN PILOT HOOKS. THIS MEANS STUFF LIKE player.teleport(). IF YOU HAVE DOUBTS USE A "safe" HOOK.<br />
 * <br />
 * These hooks all pass the pilot triggering the hook as a parameter, so they should have the structure of:<br />
 * <br />
 * function my_hook( pilot, arg )<br />
 * end<br />
 * <br />
 * The combat hooks also pass the pilot acting on it, so for example the pilot
 *  that disabled, attacked or killed the selected pilot. They have the
 *  following format:<br />
 * <br />
 * function combat_hook( pilot, attacker, arg )<br />
 * end<br />
 * <br />
 * Please note that in the case of disable or death hook the attacker may be nil
 *  indicating that it was killed by other means like for example the shockwave
 *  of a dying ship or nebula volatility.
 *
 *    @luaparam pilot Pilot identifier to hook (or nil for all).
 *    @luaparam type One of the supported hook types.
 *    @luaparam funcname Name of function to run when hook is triggered.
 *    @luaparam arg Argument to pass to hook.
 *    @luareturn Hook identifier.
 * @luafunc pilot( pilot, type, funcname, arg )
 */
static int hook_pilot( lua_State *L )
{
   unsigned int h;
   LuaPilot *p;
   int type;
   const char *hook_type;
   char buf[ PATH_MAX ];

   /* Parameters. */
   if (lua_ispilot(L,1))
      p           = luaL_checkpilot(L,1);
   else if (lua_isnil(L,1))
      p           = NULL;
   else {
      NLUA_ERROR(L, "Invalid parameter #1 for hook.pilot, expecting pilot or nil.");
      return 0;
   }
   hook_type   = luaL_checkstring(L,2);

   /* Check to see if hook_type is valid */
   if (strcmp(hook_type,"death")==0)         type = PILOT_HOOK_DEATH;
   else if (strcmp(hook_type,"exploded")==0)    type = PILOT_HOOK_EXPLODED;
   else if (strcmp(hook_type,"board")==0)    type = PILOT_HOOK_BOARD;
   else if (strcmp(hook_type,"disable")==0)  type = PILOT_HOOK_DISABLE;
   else if (strcmp(hook_type,"jump")==0)     type = PILOT_HOOK_JUMP;
   else if (strcmp(hook_type,"hail")==0)     type = PILOT_HOOK_HAIL;
   else if (strcmp(hook_type,"land")==0)     type = PILOT_HOOK_LAND;
   else if (strcmp(hook_type,"attacked")==0) type = PILOT_HOOK_ATTACKED;
   else if (strcmp(hook_type,"idle")==0)     type = PILOT_HOOK_IDLE;
   else { /* hook_type not valid */
      NLUA_ERROR(L, "Invalid pilot hook type: '%s'", hook_type);
      return 0;
   }

   /* actually add the hook */
   snprintf( buf, sizeof(buf), "p_%s", hook_type );
   h = hook_generic( L, buf, 0., 3, 0 );
   if (p==NULL)
      pilots_addGlobalHook( type, h );
   else
      pilot_addHook( pilot_get(p->pilot), type, h );

   lua_pushnumber( L, h );
   return 1;
}
Exemple #24
0
/**
 * @brief Removes an outfit from a pilot.
 *
 * "all" will remove all outfits.
 *
 * @usage p:rmOutfit( "all" ) -- Leaves the pilot naked.
 * @usage p:rmOutfit( "Neutron Disruptor", 1 ) -- Removes a neutron disruptor.
 *
 *    @luparam p Pilot to remove outfit from.
 *    @luaparam outfit Name of the outfit to remove.
 *    @luaparam q Amount to remove.
 *    @luareturn The amount actually removed.
 * @luafunc rmOutfit( p, outfit, q )
 */
static int pilotL_rmOutfit( lua_State *L )
{
   LuaPilot *lp;
   Pilot *p;
   const char *outfit;
   int q, n;
   Outfit *o;

   /* Get the pilot. */
   lp = luaL_checkpilot(L,1);
   p  = pilot_get(lp->pilot);
   if (p==NULL) {
      NLUA_ERROR(L,"Pilot is invalid.");
      return 0;
   }

   /* Get parameters. */
   outfit = luaL_checkstring(L,2);

   /* If outfit is "all", we remove everything. */
   if (strcmp(outfit,"all")==0) {
      n = 0;
      while (p->outfits != NULL) {
         pilot_rmOutfit( p, p->outfits[0].outfit, p->outfits[0].quantity );
         n++;
      }
      lua_pushnumber(L,n);
      return 1;
   }

   /* We'll need a quantity now. */
   q      = luaL_checkint(L,3);

   /* Get the outfit. */
   o = outfit_get( outfit );
   if (o == NULL) {
      NLUA_ERROR(L,"Outfit isn't found in outfit stack.");
      return 0;
   }
   
   /* Add outfit. */
   n = pilot_rmOutfit( p, o, q );
   lua_pushnumber(L,n);
   return 1;
}
Exemple #25
0
/**
 * @brief Runs an escort command on all of a pilot's escorts.
 *
 *    @param parent Pilot who is giving orders.
 *    @param cmd Order to give.
 *    @param idx Lua index of argument or 0.
 *    @return 0 on success, 1 if no orders given.
 */
static int escort_command( Pilot *parent, const char *cmd, unsigned int idx )
{
   int i;
   Pilot *e;

   if (parent->nescorts == 0)
      return 1;

   for (i=0; i<parent->nescorts; i++) {
      e = pilot_get( parent->escorts[i].id );
      if (e == NULL) /* Most likely died. */
         continue;

      pilot_msg(parent, e, cmd, idx);
   }

   return 0;
}
Exemple #26
0
/**
 * @brief Sets the pilot as friendly to player.
 *
 * @usage p:setFriendly()
 *
 *    @luaparam p Pilot to set as friendly.
 * @luafunc setFriendly( p )
 */
static int pilotL_setFriendly( lua_State *L )
{
   LuaPilot *lp;
   Pilot *p;

   /* Get the pilot. */
   lp = luaL_checkpilot(L,1);
   p = pilot_get(lp->pilot);
   if (p==NULL) {
      NLUA_ERROR(L,"Pilot is invalid.");
      return 0;
   }

   /* Remove hostile and mark as friendly. */
   pilot_setFriendly(p);

   return 0;
}
Exemple #27
0
/**
 * @brief Sets the pilot as hostile to player.
 *
 * @usage p:setHostile()
 *
 *    @luaparam p Pilot to set as hostile.
 * @luafunc setHostile( p )
 */
static int pilotL_setHostile( lua_State *L )
{
   LuaPilot *lp;
   Pilot *p;

   /* Get the pilot. */
   lp = luaL_checkpilot(L,1);
   p  = pilot_get(lp->pilot);
   if (p==NULL) {
      NLUA_ERROR(L,"Pilot is invalid.");
      return 0;
   }

   /* Set as hostile. */
   pilot_setHostile(p);

   return 0;
}
Exemple #28
0
/**
 * @fn void player_board (void)
 *
 * @brief Attempt to board the player's target.
 *
 * Creates the window on success.
 */
void player_board (void)
{
   Pilot *p;
   unsigned int wdw;
   char c;
   HookParam hparam[2];

   if (player.p->target==PLAYER_ID) {
      /* We don't try to find far away targets, only nearest and see if it matches.
       * However, perhaps looking for first boardable target within a certain range
       * could be more interesting. */
      player_targetNearest();
      p = pilot_get(player.p->target);
      if ((!pilot_isDisabled(p) && !pilot_isFlag(p,PILOT_BOARDABLE)) ||
            pilot_isFlag(p,PILOT_NOBOARD)) {
         player_targetClear();
         player_message("\erYou need a target to board first!");
         return;
      }
Exemple #29
0
/**
 * @brief Weapon hit the pilot.
 *
 *    @param w Weapon involved in the collision.
 *    @param p Pilot that got hit.
 *    @param layer Layer to which the weapon belongs.
 *    @param pos Position of the hit.
 */
static void weapon_hit( Weapon* w, Pilot* p, WeaponLayer layer, Vector2d* pos )
{
   Pilot *parent;
   int spfx;
   double damage;
   DamageType dtype;
   WeaponLayer spfx_layer;
   int s;

   /* Get general details. */
   parent = pilot_get(w->parent);
   damage = w->strength * outfit_damage(w->outfit);
   dtype  = outfit_damageType(w->outfit);

   /* Play sound if they have it. */
   s = outfit_soundHit(w->outfit);
   if (s != -1)
      w->voice = sound_playPos( s,
            w->solid->pos.x,
            w->solid->pos.y,
            w->solid->vel.x,
            w->solid->vel.y);

   /* Have pilot take damage and get real damage done. */
   damage = pilot_hit( p, w->solid, w->parent, dtype, damage );

   /* Get the layer. */
   spfx_layer = (p==player) ? SPFX_LAYER_FRONT : SPFX_LAYER_BACK;
   /* Choose spfx. */
   if (p->shield > 0.)
      spfx = outfit_spfxShield(w->outfit);
   else
      spfx = outfit_spfxArmour(w->outfit);
   /* Add sprite, layer depends on whether player shot or not. */
   spfx_add( spfx, pos->x, pos->y,
         VX(p->solid->vel), VY(p->solid->vel), spfx_layer );

   /* Inform AI that it's been hit. */
   weapon_hitAI( p, parent, damage );

   /* no need for the weapon particle anymore */
   weapon_destroy(w,layer);
}
Exemple #30
0
/**
 * @brief Gets the pilot's current name.
 *
 * @usage name = p:name()
 *
 *    @luaparam p Pilot to get the name of.
 *    @luareturn The current name of the pilot.
 * @luafunc name( p )
 */
static int pilotL_name( lua_State *L )
{
   LuaPilot *p1;
   Pilot *p;

   /* 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;
   }

   /* Get name. */
   lua_pushstring(L, p->name);
   return 1;
}