Example #1
0
File: outfit.c Project: pegue/naev
/**
 * @brief Gets the outfit's graphic effect.
 *    @param o Outfit to get information from.
 */
glTexture* outfit_gfx( const Outfit* o )
{
   if (outfit_isBolt(o)) return o->u.blt.gfx_space;
   else if (outfit_isBeam(o)) return o->u.bem.gfx;
   else if (outfit_isAmmo(o)) return o->u.amm.gfx_space;
   return NULL;
}
Example #2
0
File: outfit.c Project: pegue/naev
/**
 * @brief Gets the outfit's energy usage.
 *    @param o Outfit to get information from.
 */
double outfit_energy( const Outfit* o )
{
   if (outfit_isBolt(o)) return o->u.blt.energy;
   else if (outfit_isBeam(o)) return o->u.bem.energy;
   else if (outfit_isAmmo(o)) return o->u.amm.energy;
   return -1.;
}
Example #3
0
File: outfit.c Project: pegue/naev
/**
 * @brief Gets the outfit's range.
 *    @param o Outfit to get information from.
 */
double outfit_range( const Outfit* o )
{
   if (outfit_isBolt(o)) return o->u.blt.range;
   else if (outfit_isBeam(o)) return o->u.bem.range;
   else if (outfit_isAmmo(o)) return 0.8*o->u.amm.speed*o->u.amm.duration;
   return -1.;
}
Example #4
0
File: outfit.c Project: pegue/naev
/**
 * @brief Gets the outfit's damage type.
 *    @param o Outfit to get information from.
 */
DamageType outfit_damageType( const Outfit* o )
{
   if (outfit_isBolt(o)) return o->u.blt.dtype;
   else if (outfit_isBeam(o)) return o->u.bem.dtype;
   else if (outfit_isAmmo(o)) return o->u.amm.dtype;
   return DAMAGE_TYPE_NULL;
}
Example #5
0
File: outfit.c Project: pegue/naev
/**
 * @brief Gets the outfit's damage.
 *    @param o Outfit to get information from.
 */
double outfit_damage( const Outfit* o )
{
   if (outfit_isBolt(o)) return o->u.blt.damage;
   else if (outfit_isBeam(o)) return o->u.bem.damage;
   else if (outfit_isAmmo(o)) return o->u.amm.damage;
   return -1.;
}
Example #6
0
File: outfit.c Project: pegue/naev
/**
 * @brief Gets the outfit's sound effect.
 *    @param o Outfit to get information from.
 */
int outfit_spfxShield( const Outfit* o )
{
   if (outfit_isBolt(o)) return o->u.blt.spfx_shield;
   else if (outfit_isBeam(o)) return o->u.bem.spfx_shield;
   else if (outfit_isAmmo(o)) return o->u.amm.spfx_shield;
   return -1;
}
Example #7
0
File: outfit.c Project: pegue/naev
/**
 * @brief Gets the outfit's sound effect.
 *    @param o Outfit to get information from.
 */
int outfit_spfxArmour( const Outfit* o )
{
   if (outfit_isBolt(o)) return o->u.blt.spfx_armour;
   else if (outfit_isBeam(o)) return o->u.bem.spfx_armour;
   else if (outfit_isAmmo(o)) return o->u.amm.spfx_armour;
   return -1;
}
Example #8
0
File: weapon.c Project: zid/naev
/**
 * @brief Creates a new weapon.
 *
 *    @param outfit Outfit which spawns the weapon.
 *    @param dir Direction of the shooter.
 *    @param pos Position of the shooter.
 *    @param vel Velocity of the shooter.
 *    @param parent Pilot ID of the shooter.
 *    @param target Target ID that is getting shot.
 */
void weapon_add( const Outfit* outfit, const double dir,
      const Vector2d* pos, const Vector2d* vel,
      unsigned int parent, unsigned int target )
{
   WeaponLayer layer;
   Weapon *w;
   Weapon **curLayer;
   int *mLayer, *nLayer;
   GLsizei size;

   if (!outfit_isBolt(outfit) &&
         !outfit_isAmmo(outfit)) {
      ERR("Trying to create a Weapon from a non-Weapon type Outfit");
      return;
   }

   layer = (parent==PLAYER_ID) ? WEAPON_LAYER_FG : WEAPON_LAYER_BG;
   w = weapon_create( outfit, dir, pos, vel, parent, target );

   /* set the proper layer */
   switch (layer) {
      case WEAPON_LAYER_BG:
         curLayer = wbackLayer;
         nLayer = &nwbackLayer;
         mLayer = &mwbacklayer;
         break;
      case WEAPON_LAYER_FG:
         curLayer = wfrontLayer;
         nLayer = &nwfrontLayer;
         mLayer = &mwfrontLayer;
         break;

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

   if (*mLayer > *nLayer) /* more memory alloced than needed */
      curLayer[(*nLayer)++] = w;
   else { /* need to allocate more memory */
      switch (layer) {
         case WEAPON_LAYER_BG:
            (*mLayer) += WEAPON_CHUNK;
            curLayer = wbackLayer = realloc(curLayer, (*mLayer)*sizeof(Weapon*));
            break;
         case WEAPON_LAYER_FG:
            (*mLayer) += WEAPON_CHUNK;
            curLayer = wfrontLayer = realloc(curLayer, (*mLayer)*sizeof(Weapon*));
            break;
      }
      curLayer[(*nLayer)++] = w;

      /* Grow the vertex stuff. */
      weapon_vboSize = mwfrontLayer + mwbacklayer;
      size = sizeof(GLfloat) * (2+4) * weapon_vboSize;
      weapon_vboData = realloc( weapon_vboData, size );
      if (weapon_vbo == NULL)
         weapon_vbo = gl_vboCreateStream( size, NULL );
   }
}
Example #9
0
File: outfit.c Project: pegue/naev
/**
 * @brief Gets the outfit's delay.
 *    @param o Outfit to get information from.
 */
int outfit_delay( const Outfit* o )
{
   if (outfit_isBolt(o)) return o->u.blt.delay;
   else if (outfit_isBeam(o)) return o->u.bem.delay;
   else if (outfit_isLauncher(o)) return o->u.lau.delay;
   else if (outfit_isFighterBay(o)) return o->u.bay.delay;
   return -1;
}
Example #10
0
/**
 * @brief Dumps the bolt weapon data to csv.
 */
void dout_csvBolt( const char *path )
{
   Outfit *o, *o_all;
   int i, n, l;
   SDL_RWops *rw;
   char buf[ 1024 ];
   Damage *dmg;

   /* File to output to. */
   rw = SDL_RWFromFile( path, "w" );
   if (rw == NULL) {
      WARN("Unable to open '%s' for writing: %s", path, SDL_GetError());
      return;
   }

   /* Write "header" */
   l = nsnprintf( buf, sizeof(buf),
         "name,type,slot,license,"
         "mass,price,"
         "delay,speed,range,falloff,"
         "lockon,energy,heatup,cpu,"
         "track,swivel,"
         "penetrate,dtype,damage,disable\n"
         );
   SDL_RWwrite( rw, buf, l, 1 );

   o_all = outfit_getAll( &n );
   for (i=0; i<n; i++) {
      o = &o_all[i];

      /* Only handle bolt weapons. */
      if (!outfit_isBolt(o))
         continue;

      dmg = &o->u.blt.dmg;
      l = nsnprintf( buf, sizeof(buf),
            "%s,%s,%s,%s,"
            "%f,%"CREDITS_PRI","
            "%f,%f,%f,%f,"
            "%f,%f,%f,%f,"
            "%f,%f,"
            "%f,%s,%f,%f\n",
            o->name, outfit_getType(o), outfit_slotName(o), o->license,
            o->mass, o->price,
            o->u.blt.delay*1000., o->u.blt.speed, o->u.blt.range, o->u.blt.falloff,
            o->u.blt.ew_lockon, o->u.blt.energy, o->u.blt.heatup, o->u.blt.cpu,
            o->u.blt.track, o->u.blt.swivel * 180. / M_PI,
            dmg->penetration*100, dtype_damageTypeToStr(dmg->type), dmg->damage, dmg->disable
            );
      SDL_RWwrite( rw, buf, l, 1 );
   }

   /* Close file. */
   SDL_RWclose( rw );
}
Example #11
0
/**
 * @brief Dumps the bolt weapon data to csv.
 */
void dout_csvBolt( const char *path )
{
   Outfit *o, *o_all;
   int i, n, l;
   SDL_RWops *rw;
   char buf[ 1024 ];

   /* File to output to. */
   rw = SDL_RWFromFile( path, "w" );

   /* Write "header" */
   l = snprintf( buf, sizeof(buf),
         "name,type,slot,license,"
         "mass,price,"
         "delay,speed,range,falloff,"
         "lockon,energy,heatup,cpu,"
         "track,swivel,"
         "dtype,damage\n"
         );
   SDL_RWwrite( rw, buf, l, 1 );

   o_all = outfit_getAll( &n );
   for (i=0; i<n; i++) {
      o = &o_all[i];

      /* Only handle bolt weapons. */
      if (!outfit_isBolt(o))
         continue;

      l = snprintf( buf, sizeof(buf),
            "%s,%s,%s,%s,"
            "%f,%"CREDITS_PRI","
            "%f,%f,%f,%f,"
            "%f,%f,%f,%f,"
            "%f,%f,"
            "%s,%f\n",
            o->name, outfit_getType(o), outfit_slotName(o), o->license,
            o->mass, o->price,
            o->u.blt.delay*1000., o->u.blt.speed, o->u.blt.range, o->u.blt.falloff,
            o->u.blt.ew_lockon, o->u.blt.energy, o->u.blt.heatup, o->u.blt.cpu,
            o->u.blt.track, o->u.blt.swivel * 180. / M_PI,
            outfit_damageTypeToStr(o->u.blt.dtype), o->u.blt.damage
            );
      SDL_RWwrite( rw, buf, l, 1 );
   }

   /* Close file. */
   SDL_RWclose( rw );
}
Example #12
0
File: outfit.c Project: pegue/naev
/**
 * @brief Gets the outfit's broad type.
 *
 *    @param o Outfit to get the type of.
 *    @return The outfit's broad type in human readable form.
 */
const char* outfit_getTypeBroad( const Outfit* o )
{
   if (outfit_isBolt(o)) return "Bolt Weapon";
   else if (outfit_isBeam(o)) return "Beam Weapon";
   else if (outfit_isLauncher(o)) return "Launcher";
   else if (outfit_isAmmo(o)) return "Ammo";
   else if (outfit_isTurret(o)) return "Turret";
   else if (outfit_isMod(o)) return "Modification";
   else if (outfit_isAfterburner(o)) return "Afterburner";
   else if (outfit_isJammer(o)) return "Jammer";
   else if (outfit_isFighterBay(o)) return "Fighter Bay";
   else if (outfit_isFighter(o)) return "Fighter";
   else if (outfit_isMap(o)) return "Map";
   else if (outfit_isLicense(o)) return "License";
   else return "Unknown";
}
Example #13
0
/**
 * @brief Adds an outfit to a weapon set.
 *
 *    @param p Pilot to manipulate.
 *    @param id ID of the weapon set.
 *    @param o Outfit to add.
 *    @param level Level of the trigger.
 */
void pilot_weapSetAdd( Pilot* p, int id, PilotOutfitSlot *o, int level )
{
   PilotWeaponSet *ws;
   PilotWeaponSetOutfit *slot;
   Outfit *oo;
   int i;

   ws = pilot_weapSet(p,id);

   /* Make sure outfit is valid. */
   oo = o->outfit;
   if (oo == NULL)
      return;

   /* Make sure outfit type is weapon (or usable). */
   if (!(outfit_isBeam(oo) || outfit_isBolt(oo) ||
            outfit_isLauncher(oo) || outfit_isFighterBay(oo)))
      return;

   /* Create if needed. */
   if (ws->slots == NULL)
      ws->slots = array_create( PilotWeaponSetOutfit );

   /* Check if already there. */
   for (i=0; i<array_size(ws->slots); i++) {
      if (ws->slots[i].slot == o) {
         ws->slots[i].level = level;

         /* Update if needed. */
         if (id == p->active_set)
            pilot_weapSetUpdateOutfits( p, ws );
         return;
      }
   }

   /* Add it. */
   slot        = &array_grow( &ws->slots );
   slot->level = level;
   slot->slot  = o;

   /* Update range. */
   pilot_weapSetUpdateRange( ws );

   /* Update if needed. */
   if (id == p->active_set)
      pilot_weapSetUpdateOutfits( p, ws );
}
Example #14
0
/**
 * @brief Adds an outfit to the pilot, ignoring CPU or other limits.
 *
 * @note Does not call pilot_calcStats().
 *
 *    @param pilot Pilot to add the outfit to.
 *    @param outfit Outfit to add to the pilot.
 *    @param s Slot to add ammo to.
 *    @return 0 on success.
 */
int pilot_addOutfitRaw( Pilot* pilot, Outfit* outfit, PilotOutfitSlot *s )
{
   Outfit *o;

   /* Set the outfit. */
   s->outfit   = outfit;

   /* Set some default parameters. */
   s->timer    = 0.;

   /* Some per-case scenarios. */
   if (outfit_isFighterBay(outfit)) {
      s->u.ammo.outfit   = NULL;
      s->u.ammo.quantity = 0;
      s->u.ammo.deployed = 0;
   }
   if (outfit_isTurret(outfit)) /* used to speed up AI */
      pilot->nturrets++;
   else if (outfit_isBolt(outfit))
      pilot->ncannons++;
   else if (outfit_isJammer(outfit))
      pilot->njammers++;
   else if (outfit_isAfterburner(outfit))
      pilot->nafterburners++;

   if (outfit_isBeam(outfit)) { /* Used to speed up some calculations. */
      s->u.beamid = 0;
      pilot->nbeams++;
   }
   if (outfit_isLauncher(outfit)) {
      s->u.ammo.outfit   = NULL;
      s->u.ammo.quantity = 0;
      s->u.ammo.deployed = 0; /* Just in case. */
   }

   /* Check if active. */
   o = s->outfit;
   s->active = outfit_isActive(o);

   /* Update heat. */
   pilot_heatCalcSlot( s );

   return 0;
}
Example #15
0
File: weapon.c Project: zid/naev
static void weapon_explodeLayer( WeaponLayer layer,
      double x, double y, double radius,
      unsigned int parent, int mode )
{
   (void)parent;
   int i;
   Weapon **curLayer;
   int *nLayer;
   double dist, rad2;

   /* set the proper layer */
   switch (layer) {
      case WEAPON_LAYER_BG:
         curLayer = wbackLayer;
         nLayer = &nwbackLayer;
         break;
      case WEAPON_LAYER_FG:
         curLayer = wfrontLayer;
         nLayer = &nwfrontLayer;
         break;

      default:
         ERR("Invalid WEAPON_LAYER specified");
         return;
   }

   rad2 = radius*radius;

   /* Now try to destroy the weapons affected. */
   for (i=0; i<*nLayer; i++) {
      if (((mode & EXPL_MODE_MISSILE) && outfit_isAmmo(curLayer[i]->outfit)) ||
            ((mode & EXPL_MODE_BOLT) && outfit_isBolt(curLayer[i]->outfit))) {

         dist = pow2(curLayer[i]->solid->pos.x - x) +
               pow2(curLayer[i]->solid->pos.y - y);

         if (dist < rad2) {
            weapon_destroy(curLayer[i], layer);
            i--;
         }
      }
   }
}
Example #16
0
/**
 * @brief Removes an outfit from the pilot without doing any checks.
 *
 * @note Does not run pilot_calcStats().
 *
 *    @param pilot Pilot to remove the outfit from.
 *    @param s Slot to remove.
 *    @return 0 on success.
 */
int pilot_rmOutfitRaw( Pilot* pilot, PilotOutfitSlot *s )
{
   int ret;

   /* Decrement counters if necessary. */
   if (s->outfit != NULL) {
      if (outfit_isTurret(s->outfit))
         pilot->nturrets--;
      else if (outfit_isBolt(s->outfit))
         pilot->ncannons--;
      if (outfit_isBeam(s->outfit))
         pilot->nbeams--;
   }

   /* Remove the outfit. */
   ret         = (s->outfit==NULL);
   s->outfit   = NULL;

   /* Remove secondary and such if necessary. */
   if (pilot->afterburner == s)
      pilot->afterburner = NULL;

   return ret;
}
Example #17
0
File: weapon.c Project: zid/naev
/**
 * @brief Renders an individual weapon.
 *
 *    @param w Weapon to render.
 *    @param dt Current delta tick.
 */
static void weapon_render( Weapon* w, const double dt )
{
   double x,y, cx,cy, gx,gy;
   glTexture *gfx;
   double z;
   glColour c = { .r=1., .g=1., .b=1. };

   switch (w->outfit->type) {
      /* Weapons that use sprites. */
      case OUTFIT_TYPE_AMMO:
      case OUTFIT_TYPE_TURRET_AMMO:
      case OUTFIT_TYPE_BOLT:
      case OUTFIT_TYPE_TURRET_BOLT:
         gfx = outfit_gfx(w->outfit);

         /* Alpha based on strength. */
         c.a = w->strength;

         /* Outfit spins around. */
         if (outfit_isProp(w->outfit, OUTFIT_PROP_WEAP_SPIN)) {
            /* Check timer. */
            w->anim -= dt;
            if (w->anim < 0.) {
               w->anim = outfit_spin(w->outfit);

               /* Increment sprite. */
               w->sprite++;
               if (w->sprite >= gfx->sx*gfx->sy)
                  w->sprite = 0;
            }

            /* Render. */
            if (outfit_isBolt(w->outfit) && w->outfit->u.blt.gfx_end)
               gl_blitSpriteInterpolate( gfx, w->outfit->u.blt.gfx_end,
                     w->timer / w->life,
                     w->solid->pos.x, w->solid->pos.y,
                     w->sprite % (int)gfx->sx, w->sprite / (int)gfx->sx, &c );
            else
               gl_blitSprite( gfx, w->solid->pos.x, w->solid->pos.y,
                     w->sprite % (int)gfx->sx, w->sprite / (int)gfx->sx, &c );
         }
         /* Outfit faces direction. */
         else {
            if (outfit_isBolt(w->outfit) && w->outfit->u.blt.gfx_end)
               gl_blitSpriteInterpolate( gfx, w->outfit->u.blt.gfx_end,
                     w->timer / w->life,
                     w->solid->pos.x, w->solid->pos.y, w->sx, w->sy, &c );
            else
               gl_blitSprite( gfx, w->solid->pos.x, w->solid->pos.y, w->sx, w->sy, &c );
         }
         break;

      /* Beam weapons. */
      case OUTFIT_TYPE_BEAM:
      case OUTFIT_TYPE_TURRET_BEAM:
         gfx = outfit_gfx(w->outfit);

         /* Zoom. */
         gl_cameraZoomGet( &z );

         /* Position. */
         gl_cameraGet( &cx, &cy );
         gui_getOffset( &gx, &gy );
         x = (w->solid->pos.x - cx)*z + gx;
         y = (w->solid->pos.y - cy)*z + gy;

         /* Set up the matrix. */
         glMatrixMode(GL_PROJECTION);
         glPushMatrix();
            glTranslated( x, y, 0. );
            glRotated( 270. + w->solid->dir / M_PI * 180., 0., 0., 1. );

         /* Preparatives. */
         glEnable(GL_TEXTURE_2D);
         glBindTexture( GL_TEXTURE_2D, gfx->texture);
         glShadeModel(GL_SMOOTH);

         /* Actual rendering. */
         glBegin(GL_QUAD_STRIP);

            /* Start faded. */
            ACOLOUR(cWhite, 0.);

            glTexCoord2d( w->anim, 0. );
            glVertex2d( -gfx->sh/2.*z, 0. );

            glTexCoord2d( w->anim, 1. );
            glVertex2d( +gfx->sh/2.*z, 0. );

            /* Full strength. */
            COLOUR(cWhite);

            glTexCoord2d( w->anim + 10. / gfx->sw, 0. );
            glVertex2d( -gfx->sh/2.*z, 10.*z );

            glTexCoord2d( w->anim + 10. / gfx->sw, 1. );
            glVertex2d( +gfx->sh/2.*z, 10.*z );

            glTexCoord2d( w->anim + 0.8*w->outfit->u.bem.range / gfx->sw, 0. );
            glVertex2d( -gfx->sh/2.*z, 0.8*w->outfit->u.bem.range*z );

            glTexCoord2d( w->anim + 0.8*w->outfit->u.bem.range / gfx->sw, 1. );
            glVertex2d( +gfx->sh/2.*z, 0.8*w->outfit->u.bem.range*z );

            /* Fades out. */
            ACOLOUR(cWhite, 0.);

            glTexCoord2d( w->anim + w->outfit->u.bem.range / gfx->sw, 0. );
            glVertex2d( -gfx->sh/2.*z, w->outfit->u.bem.range*z );

            glTexCoord2d( w->anim + w->outfit->u.bem.range / gfx->sw, 1. );
            glVertex2d( +gfx->sh/2.*z, w->outfit->u.bem.range*z );
         glEnd(); /* GL_QUAD_STRIP */

         /* Do the beam movement. */
         w->anim -= 5. * dt;
         if (w->anim <= -gfx->sw)
            w->anim += gfx->sw;

         /* Clean up. */
         glDisable(GL_TEXTURE_2D);
         glShadeModel(GL_FLAT);
         glPopMatrix(); /* GL_PROJECTION */
         gl_checkErr();
         break;

      default:
         WARN("Weapon of type '%s' has no render implemented yet!",
               w->outfit->name);
         break;
   }
}


/**
 * @brief Checks to see if the weapon can hit the pilot.
 *
 *    @param w Weapon to check if hits pilot.
 *    @param p Pilot to check if is hit by weapon.
 *    @return 1 if can be hit, 0 if can't.
 */
static int weapon_checkCanHit( Weapon* w, Pilot *p )
{
   Pilot *parent;

   /* Can't hit invincible stuff. */
   if (pilot_isFlag(p, PILOT_INVINCIBLE))
      return 0;

   /* Can never hit same faction. */
   if (p->faction == w->faction)
      return 0;

   /* Go "through" dead pilots. */
   if (pilot_isFlag(p, PILOT_DEAD))
      return 0;

   /* Player behaves differently. */
   if (w->faction == FACTION_PLAYER) {

      /* Always hit without safety. */
      if (!weapon_safety)
         return 1;

      /* Always hit target. */
      else if (w->target == p->id)
         return 1;

      /* Always hit hostiles. */
      else if (pilot_isFlag(p, PILOT_HOSTILE))
         return 1;

      /* Always hit unbribed enemies. */
      else if (!pilot_isFlag(p, PILOT_BRIBED) &&
            areEnemies(w->faction, p->faction))
        return 1;

      /* Miss rest - can be neutral/ally. */
      else
         return 0;
   }

   /* Let hostiles hit player. */
   if (p->faction == FACTION_PLAYER) {
      parent = pilot_get(w->parent);
      if (parent != NULL) {
         if (pilot_isFlag(parent, PILOT_BRIBED))
            return 0;
         if (pilot_isFlag(parent, PILOT_HOSTILE))
            return 1;
      }
   }

   /* Hit non-allies. */
   if (areEnemies(w->faction, p->faction))
      return 1;

   return 0;
}
Example #18
0
File: outfit.c Project: pegue/naev
/**
 * @brief Gets the outfit's animation spin.
 *    @param o Outfit to get information from.
 */
double outfit_spin( const Outfit* o )
{
   if (outfit_isBolt(o)) return o->u.blt.spin;
   else if (outfit_isAmmo(o)) return o->u.amm.spin;
   return -1.;
}
Example #19
0
/**
 * @brief Actually handles the shooting, how often the player.p can shoot and such.
 *
 *    @param p Pilot that is shooting.
 *    @param w Pilot's outfit to shoot.
 *    @return 0 if nothing was shot and 1 if something was shot.
 */
static int pilot_shootWeapon( Pilot* p, PilotOutfitSlot* w )
{
   Vector2d vp, vv;
   double rate_mod, energy_mod;
   double energy;

   /* Make sure weapon has outfit. */
   if (w->outfit == NULL)
      return 0;

   /* check to see if weapon is ready */
   if (w->timer > 0.)
      return 0;

   /* Calculate rate modifier. */
   pilot_getRateMod( &rate_mod, &energy_mod, p, w->outfit );

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

   /* Modify velocity to take into account the rotation. */
   vect_cset( &vv, p->solid->vel.x + vp.x*p->solid->dir_vel,
         p->solid->vel.y + vp.y*p->solid->dir_vel );

   /*
    * regular bolt weapons
    */
   if (outfit_isBolt(w->outfit)) {

      /* enough energy? */
      if (outfit_energy(w->outfit)*energy_mod > p->energy)
         return 0;

      energy      = outfit_energy(w->outfit)*energy_mod;
      p->energy  -= energy;
      pilot_heatAddSlot( p, w );
      weapon_add( w->outfit, w->heat_T, p->solid->dir,
            &vp, &p->solid->vel, p, p->target );
   }

   /*
    * Beam weapons.
    */
   else if (outfit_isBeam(w->outfit)) {

      /* Check if enough energy to last a second. */
      if (outfit_energy(w->outfit)*energy_mod > p->energy)
         return 0;

      /** @todo Handle warmup stage. */
      w->state = PILOT_OUTFIT_ON;
      w->u.beamid = beam_start( w->outfit, p->solid->dir,
            &vp, &p->solid->vel, p, p->target, w );
   }

   /*
    * missile launchers
    *
    * must be a secondary weapon
    */
   else if (outfit_isLauncher(w->outfit)) {

      /* Shooter can't be the target - sanity check for the player.p */
      if ((w->outfit->u.lau.ammo->u.amm.ai > 0) && (p->id==p->target))
         return 0;

      /* Must have ammo left. */
      if ((w->u.ammo.outfit == NULL) || (w->u.ammo.quantity <= 0))
         return 0;

      /* enough energy? */
      if (outfit_energy(w->u.ammo.outfit)*energy_mod > p->energy)
         return 0;

      energy      = outfit_energy(w->u.ammo.outfit)*energy_mod;
      p->energy  -= energy;
      pilot_heatAddSlot( p, w );
      weapon_add( w->outfit, w->heat_T, p->solid->dir,
            &vp, &p->solid->vel, p, p->target );

      w->u.ammo.quantity -= 1; /* we just shot it */
      p->mass_outfit     -= w->u.ammo.outfit->mass;
      pilot_updateMass( p );
   }

   /*
    * Fighter bays.
    */
   else if (outfit_isFighterBay(w->outfit)) {

      /* Must have ammo left. */
      if ((w->u.ammo.outfit == NULL) || (w->u.ammo.quantity <= 0))
         return 0;

      /* Create the escort. */
      escort_create( p, w->u.ammo.outfit->u.fig.ship,
            &vp, &p->solid->vel, p->solid->dir, ESCORT_TYPE_BAY, 1 );

      w->u.ammo.quantity -= 1; /* we just shot it */
      p->mass_outfit     -= w->u.ammo.outfit->mass;
      w->u.ammo.deployed += 1; /* Mark as deployed. */
      pilot_updateMass( p );
   }
   else
      WARN("Shooting unknown weapon type: %s", w->outfit->name);


   /* Reset timer. */
   w->timer += rate_mod * outfit_delay( w->outfit );

   return 1;
}
Example #20
0
/**
 * @brief Actually handles the shooting, how often the player.p can shoot and such.
 *
 *    @param p Pilot that is shooting.
 *    @param w Pilot's outfit to shoot.
 *    @param time Expected flight time.
 *    @return 0 if nothing was shot and 1 if something was shot.
 */
static int pilot_shootWeapon( Pilot* p, PilotOutfitSlot* w, double time )
{
   Vector2d vp, vv;
   double rate_mod, energy_mod;
   double energy;
   int j;

   /* Make sure weapon has outfit. */
   if (w->outfit == NULL)
      return 0;

   /* Reset beam shut-off if needed. */
   if (outfit_isBeam(w->outfit) && w->outfit->u.bem.min_duration)
      w->stimer = INFINITY;

   /* check to see if weapon is ready */
   if (w->timer > 0.)
      return 0;

   /* Calculate rate modifier. */
   pilot_getRateMod( &rate_mod, &energy_mod, p, w->outfit );

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

   /* Modify velocity to take into account the rotation. */
   vect_cset( &vv, p->solid->vel.x + vp.x*p->solid->dir_vel,
         p->solid->vel.y + vp.y*p->solid->dir_vel );

   /*
    * regular bolt weapons
    */
   if (outfit_isBolt(w->outfit)) {

      /* enough energy? */
      if (outfit_energy(w->outfit)*energy_mod > p->energy)
         return 0;

      energy      = outfit_energy(w->outfit)*energy_mod;
      p->energy  -= energy;
      pilot_heatAddSlot( p, w );
      weapon_add( w->outfit, w->heat_T, p->solid->dir,
            &vp, &p->solid->vel, p, p->target, time );
   }

   /*
    * Beam weapons.
    */
   else if (outfit_isBeam(w->outfit)) {
      /* Don't fire if the existing beam hasn't been destroyed yet. */
      if (w->u.beamid > 0)
         return 0;

      /* Check if enough energy to last a second. */
      if (outfit_energy(w->outfit)*energy_mod > p->energy)
         return 0;

      /** @todo Handle warmup stage. */
      w->state = PILOT_OUTFIT_ON;
      w->u.beamid = beam_start( w->outfit, p->solid->dir,
            &vp, &p->solid->vel, p, p->target, w );

      w->timer = w->outfit->u.bem.duration;

      return 1; /* Return early due to custom timer logic. */
   }

   /*
    * missile launchers
    *
    * must be a secondary weapon
    */
   else if (outfit_isLauncher(w->outfit)) {

      /* Shooter can't be the target - sanity check for the player.p */
      if ((w->outfit->u.lau.ammo->u.amm.ai != AMMO_AI_DUMB) && (p->id==p->target))
         return 0;

      /* Must have ammo left. */
      if ((w->u.ammo.outfit == NULL) || (w->u.ammo.quantity <= 0))
         return 0;

      /* enough energy? */
      if (outfit_energy(w->u.ammo.outfit)*energy_mod > p->energy)
         return 0;

      energy      = outfit_energy(w->u.ammo.outfit)*energy_mod;
      p->energy  -= energy;
      pilot_heatAddSlot( p, w );
      weapon_add( w->outfit, w->heat_T, p->solid->dir,
            &vp, &p->solid->vel, p, p->target, time );

      w->u.ammo.quantity -= 1; /* we just shot it */
      p->mass_outfit     -= w->u.ammo.outfit->mass;
      p->solid->mass     -= w->u.ammo.outfit->mass;

      pilot_updateMass( p );

      /* If last ammo was shot, update the range */
      if (w->u.ammo.quantity <= 0) {
         for (j=0; j<PILOT_WEAPON_SETS; j++)
            pilot_weapSetUpdateRange( &p->weapon_sets[j] );
      }
   }

   /*
    * Fighter bays.
    */
   else if (outfit_isFighterBay(w->outfit)) {

      /* Must have ammo left. */
      if ((w->u.ammo.outfit == NULL) || (w->u.ammo.quantity <= 0))
         return 0;

      /* Create the escort. */
      escort_create( p, w->u.ammo.outfit->u.fig.ship,
            &vp, &p->solid->vel, p->solid->dir, ESCORT_TYPE_BAY, 1 );

      w->u.ammo.quantity -= 1; /* we just shot it */
      p->mass_outfit     -= w->u.ammo.outfit->mass;
      w->u.ammo.deployed += 1; /* Mark as deployed. */
      pilot_updateMass( p );
   }
   else
      WARN(_("Shooting unknown weapon type: %s"), w->outfit->name);


   /* Reset timer. */
   w->timer += rate_mod * outfit_delay( w->outfit );

   return 1;
}
Example #21
0
/**
 * @brief Tries to automatically set and create the pilot's weapon set.
 *
 * Weapon set 0 is for all weapons. <br />
 * Weapon set 1 is for forward weapons. Ammo using weapons are secondaries. <br />
 * Weapon set 2 is for turret weapons. Ammo using weapons are secondaries. <br />
 * Weapon set 3 is for all weapons. Forwards are primaries and turrets are secondaries. <br />
 * Weapon set 4 is for seeking weapons. High payload variants are secondaries. <br />
 * Weapon set 5 is for fighter bays. <br />
 *
 *    @param p Pilot to automagically generate weapon lists.
 */
void pilot_weaponAuto( Pilot *p )
{
   PilotOutfitSlot *slot;
   Outfit *o;
   int i, level, id;

   /* Clear weapons. */
   pilot_weaponClear( p );

   /* Set modes. */
   pilot_weapSetMode( p, 0, 0 );
   pilot_weapSetMode( p, 1, 0 );
   pilot_weapSetMode( p, 2, 0 );
   pilot_weapSetMode( p, 3, 0 );
   pilot_weapSetMode( p, 4, 1 );
   pilot_weapSetMode( p, 5, 1 );
   pilot_weapSetMode( p, 6, 0 );
   pilot_weapSetMode( p, 7, 0 );
   pilot_weapSetMode( p, 8, 0 );
   pilot_weapSetMode( p, 9, 0 );

   /* Set names. */
   pilot_weapSetNameSet( p, 0, "All" );
   pilot_weapSetNameSet( p, 1, "Forward" );
   pilot_weapSetNameSet( p, 2, "Turret" );
   pilot_weapSetNameSet( p, 3, "Fwd/Tur" );
   pilot_weapSetNameSet( p, 4, "Seekers" );
   pilot_weapSetNameSet( p, 5, "Fighter Bays" );
   pilot_weapSetNameSet( p, 6, "Weaponset 7" );
   pilot_weapSetNameSet( p, 7, "Weaponset 8" );
   pilot_weapSetNameSet( p, 8, "Weaponset 9" );
   pilot_weapSetNameSet( p, 9, "Weaponset 0" );

   /* Iterate through all the outfits. */
   for (i=0; i<p->outfit_nweapon; i++) {
      slot = &p->outfit_weapon[i];
      o    = slot->outfit;

      /* Must have outfit. */
      if (o == NULL) {
         slot->level = -1; /* Clear level. */
         continue;
      }

      /* Bolts and beams. */
      if (outfit_isBolt(o) || outfit_isBeam(o) ||
            (outfit_isLauncher(o) && !outfit_isSeeker(o->u.lau.ammo))) {
         id    = outfit_isTurret(o) ? 2 : 1;
         level = (outfit_ammo(o) != NULL) ? 1 : 0;
      }
      /* Seekers. */
      else if (outfit_isLauncher(o) && outfit_isSeeker(o->u.lau.ammo)) {
         id    = 4;
         level = 1;
      }
      /* Fighter bays. */
      else if (outfit_isFighterBay(o)) {
         id    = 5;
         level = 0;
      }
      /* Ignore rest. */
      else
         continue;
   
      /* Add to it's base group. */
      pilot_weapSetAdd( p, id, slot, level );
   
      /* Also add another copy to another group. */
      if (id == 1) { /* Forward. */
         pilot_weapSetAdd( p, 0, slot, level ); /* Also get added to 'All'. */
         pilot_weapSetAdd( p, 3, slot, 0 );     /* Also get added to 'Fwd/Tur'. */
      }
      else if (id == 2) { /* Turrets. */
         pilot_weapSetAdd( p, 0, slot, level ); /* Also get added to 'All'. */
         pilot_weapSetAdd( p, 3, slot, 1 );     /* Also get added to 'Fwd/Tur'. */
      }
      else if (id == 4) { /* Seekers */
         pilot_weapSetAdd( p, 0, slot, level ); /* Also get added to 'All'. */
      }
   }
}
Example #22
0
/**
 * @brief Tries to automatically set and create the pilot's weapon set.
 *
 * Weapon set 0 is for all weapons. <br />
 * Weapon set 1 is for forward weapons. Ammo using weapons are secondaries. <br />
 * Weapon set 2 is for turret weapons. Ammo using weapons are secondaries. <br />
 * Weapon set 3 is for all weapons. Forwards are primaries and turrets are secondaries. <br />
 * Weapon set 4 is for seeking weapons. High payload variants are secondaries. <br />
 * Weapon set 5 is for fighter bays. <br />
 *
 *    @param p Pilot to automagically generate weapon lists.
 */
void pilot_weaponAuto( Pilot *p )
{
   PilotOutfitSlot *slot;
   Outfit *o;
   int i, level, id;

   /* Clear weapons. */
   pilot_weaponClear( p );

   /* Set modes. */
   pilot_weapSetType( p, 0, WEAPSET_TYPE_CHANGE );
   pilot_weapSetType( p, 1, WEAPSET_TYPE_CHANGE );
   pilot_weapSetType( p, 2, WEAPSET_TYPE_CHANGE );
   pilot_weapSetType( p, 3, WEAPSET_TYPE_CHANGE );
   pilot_weapSetType( p, 4, WEAPSET_TYPE_WEAPON );
   pilot_weapSetType( p, 5, WEAPSET_TYPE_WEAPON );
   pilot_weapSetType( p, 6, WEAPSET_TYPE_ACTIVE );
   pilot_weapSetType( p, 7, WEAPSET_TYPE_ACTIVE );
   pilot_weapSetType( p, 8, WEAPSET_TYPE_ACTIVE );
   pilot_weapSetType( p, 9, WEAPSET_TYPE_ACTIVE );

   /* All should be inrange. */
   if (!pilot_isPlayer(p))
      for (i=0; i<PILOT_WEAPON_SETS; i++){
         pilot_weapSetInrange( p, i, 1 );
         /* Update range and speed (at 0)*/
         pilot_weapSetUpdateRange( &p->weapon_sets[i] );
      }

   /* Iterate through all the outfits. */
   for (i=0; i<p->noutfits; i++) {
      slot = p->outfits[i];
      o    = slot->outfit;

      /* Must be non-empty, and a weapon or active outfit. */
      if ((o == NULL) || !outfit_isActive(o)) {
         slot->level   = -1; /* Clear level. */
         slot->weapset = -1;
         continue;
      }

      /* Manually defined group preempts others. */
      if (o->group) {
         id    = o->group;
      }
      /* Bolts and beams. */
      else if (outfit_isBolt(o) || outfit_isBeam(o) ||
            (outfit_isLauncher(o) && !outfit_isSeeker(o->u.lau.ammo))) {
         id    = outfit_isTurret(o) ? 2 : 1;
      }
      /* Seekers. */
      else if (outfit_isLauncher(o) && outfit_isSeeker(o->u.lau.ammo)) {
         id    = 4;
      }
      /* Fighter bays. */
      else if (outfit_isFighterBay(o)) {
         id    = 5;
      }
      /* Ignore rest. */
      else {
         slot->level = -1;
         continue;
      }

      /* Set level based on secondary flag. */
      level = outfit_isSecondary(o);

      /* Add to its base group. */
      pilot_weapSetAdd( p, id, slot, level );

      /* Also add another copy to another group. */
      if (id == 1) { /* Forward. */
         pilot_weapSetAdd( p, 0, slot, level ); /* Also get added to 'All'. */
         pilot_weapSetAdd( p, 3, slot, 0 );     /* Also get added to 'Fwd/Tur'. */
      }
      else if (id == 2) { /* Turrets. */
         pilot_weapSetAdd( p, 0, slot, level ); /* Also get added to 'All'. */
         pilot_weapSetAdd( p, 3, slot, 1 );     /* Also get added to 'Fwd/Tur'. */
      }
      else if (id == 4) /* Seekers */
         pilot_weapSetAdd( p, 0, slot, level ); /* Also get added to 'All'. */
   }

   /* Update active weapon set. */
   pilot_weapSetUpdateOutfits( p, &p->weapon_sets[ p->active_set ] );
}
Example #23
0
File: outfit.c Project: pegue/naev
/**
 * @brief Parses and returns Outfit from parent node.
 *
 *    @param temp Outfit to load into.
 *    @param parent Parent node to parse outfit from.
 *    @return 0 on success.
 */
static int outfit_parse( Outfit* temp, const xmlNodePtr parent )
{
   xmlNodePtr cur, node;
   char *prop;

   /* Clear data. */
   memset( temp, 0, sizeof(Outfit) );

   temp->name = xml_nodeProp(parent,"name"); /* already mallocs */
   if (temp->name == NULL) WARN("Outfit in "OUTFIT_DATA" has invalid or no name");

   node = parent->xmlChildrenNode;

   do { /* load all the data */
      if (xml_isNode(node,"general")) {
         cur = node->children;
         do {
            xmlr_int(cur,"max",temp->max);
            xmlr_int(cur,"tech",temp->tech);
            xmlr_strd(cur,"license",temp->license);
            xmlr_int(cur,"mass",temp->mass);
            xmlr_int(cur,"price",temp->price);
            xmlr_strd(cur,"description",temp->description);
            if (xml_isNode(cur,"gfx_store")) {
               temp->gfx_store = xml_parseTexture( cur,
                     OUTFIT_GFX"store/%s.png", 1, 1, 0 );
            }

         } while (xml_nextNode(cur));
      }
      else if (xml_isNode(node,"specific")) { /* has to be processed seperately */

         /* get the type */
         prop = xml_nodeProp(node,"type");
         if (prop == NULL)
            ERR("Outfit '%s' element 'specific' missing property 'type'",temp->name);
         temp->type = outfit_strToOutfitType(prop);
         free(prop);

         /* is secondary weapon? */
         prop = xml_nodeProp(node,"secondary");
         if (prop != NULL) {
            if ((int)atoi(prop)) outfit_setProp(temp, OUTFIT_PROP_WEAP_SECONDARY);
            free(prop);
         }

         if (temp->type==OUTFIT_TYPE_NULL)
            WARN("Outfit '%s' is of type NONE", temp->name);
         else if (outfit_isBolt(temp))
            outfit_parseSBolt( temp, node );
         else if (outfit_isBeam(temp))
            outfit_parseSBeam( temp, node );
         else if (outfit_isLauncher(temp))
            outfit_parseSLauncher( temp, node );
         else if (outfit_isAmmo(temp))
            outfit_parseSAmmo( temp, node );
         else if (outfit_isMod(temp))
            outfit_parseSMod( temp, node );
         else if (outfit_isAfterburner(temp))
            outfit_parseSAfterburner( temp, node );
         else if (outfit_isJammer(temp))
            outfit_parseSJammer( temp, node );
         else if (outfit_isFighterBay(temp))
            outfit_parseSFighterBay( temp, node );
         else if (outfit_isFighter(temp))
            outfit_parseSFighter( temp, node );
         else if (outfit_isMap(temp))
            outfit_parseSMap( temp, node );
         else if (outfit_isLicense(temp))
            outfit_parseSLicense( temp, node );
      }
   } while (xml_nextNode(node));

#define MELEMENT(o,s) \
if (o) WARN("Outfit '%s' missing/invalid '"s"' element", temp->name) /**< Define to help check for data errors. */
   MELEMENT(temp->name==NULL,"name");
   MELEMENT(temp->max==0,"max");
   MELEMENT(temp->tech==0,"tech");
   MELEMENT(temp->gfx_store==NULL,"gfx_store");
   /*MELEMENT(temp->mass==0,"mass"); Not really needed */
   MELEMENT(temp->type==0,"type");
   MELEMENT(temp->price==0,"price");
   MELEMENT(temp->description==NULL,"description");
#undef MELEMENT

   return 0;
}