예제 #1
0
/**
 * @brief Recalculates the pilot's stats based on his outfits.
 *
 *    @param pilot Pilot to recalculate his stats.
 */
void pilot_calcStats( Pilot* pilot )
{
   int i;
   Outfit* o;
   PilotOutfitSlot *slot;
   double ac, sc, ec, fc; /* temporary health coefficients to set */
   double arel, srel, erel; /* relative health bonuses. */
   ShipStats amount, *s;

   /*
    * set up the basic stuff
    */
   /* mass */
   pilot->solid->mass   = pilot->ship->mass;
   /* movement */
   pilot->thrust        = pilot->ship->thrust;
   pilot->turn_base     = pilot->ship->turn;
   pilot->speed         = pilot->ship->speed;
   /* cpu */
   pilot->cpu_max       = pilot->ship->cpu;
   pilot->cpu           = pilot->cpu_max;
   /* crew */
   pilot->crew          = pilot->ship->crew;
   /* health */
   ac = pilot->armour / pilot->armour_max;
   sc = pilot->shield / pilot->shield_max;
   ec = pilot->energy / pilot->energy_max;
   fc = pilot->fuel   / pilot->fuel_max;
   pilot->armour_max    = pilot->ship->armour;
   pilot->shield_max    = pilot->ship->shield;
   pilot->fuel_max      = pilot->ship->fuel;
   pilot->armour_regen  = pilot->ship->armour_regen;
   pilot->shield_regen  = pilot->ship->shield_regen;
   /* Absorption. */
   pilot->dmg_absorb    = pilot->ship->dmg_absorb;
   /* Energy. */
   pilot->energy_max    = pilot->ship->energy;
   pilot->energy_regen  = pilot->ship->energy_regen;
   /* Stats. */
   memcpy( &pilot->stats, &pilot->ship->stats_array, sizeof(ShipStats) );
   memset( &amount, 0, sizeof(ShipStats) );

   /* cargo has to be reset */
   pilot_cargoCalc(pilot);

   /*
    * now add outfit changes
    */
   pilot->mass_outfit   = 0.;
   pilot->jamming       = 0;
   arel                 = 0.;
   srel                 = 0.;
   erel                 = 0.;
   for (i=0; i<pilot->noutfits; i++) {
      slot = pilot->outfits[i];
      o    = slot->outfit;

      /* Outfit must exist. */
      if (o==NULL)
         continue;

      /* Subtract CPU. */
      pilot->cpu           -= outfit_cpu(o);
      if (outfit_cpu(o) < 0.)
         pilot->cpu_max    -= outfit_cpu(o);

      /* Add mass. */
      pilot->mass_outfit   += o->mass;

      /* Active outfits must be on to affect stuff. */
      if (slot->active && !(slot->state==PILOT_OUTFIT_ON))
         continue;

      if (outfit_isMod(o)) { /* Modification */
         /* movement */
         pilot->thrust        += o->u.mod.thrust * pilot->ship->mass;
         pilot->thrust        += o->u.mod.thrust_rel * pilot->ship->thrust;
         pilot->turn_base     += o->u.mod.turn;
         pilot->turn_base     += o->u.mod.turn_rel * pilot->ship->turn;
         pilot->speed         += o->u.mod.speed;
         pilot->speed         += o->u.mod.speed_rel * pilot->ship->speed;
         /* health */
         pilot->armour_max    += o->u.mod.armour;
         pilot->armour_regen  += o->u.mod.armour_regen;
         arel                 += o->u.mod.armour_rel;
         pilot->shield_max    += o->u.mod.shield;
         pilot->shield_regen  += o->u.mod.shield_regen;
         srel                 += o->u.mod.shield_rel;
         pilot->energy_max    += o->u.mod.energy;
         pilot->energy_regen  += o->u.mod.energy_regen;
         erel                 += o->u.mod.energy_rel;
         /* fuel */
         pilot->fuel_max      += o->u.mod.fuel;
         /* misc */
         pilot->cargo_free    += o->u.mod.cargo;
         pilot->mass_outfit   += o->u.mod.mass_rel * pilot->ship->mass;
         pilot->crew          += o->u.mod.crew_rel * pilot->ship->crew;
         /*
          * Stats.
          */
         ss_statsModFromList( &pilot->stats, o->u.mod.stats, &amount ); /* TODO Handle q or remove it? */
      }
      else if (outfit_isAfterburner(o)) /* Afterburner */
         pilot->afterburner = pilot->outfits[i]; /* Set afterburner */
      else if (outfit_isJammer(o)) { /* Jammer */
         pilot->jamming        = 1;
         pilot->energy_regen  -= o->u.jam.energy;
      }

      /* Add ammo mass. */
      if (outfit_ammo(o) != NULL) {
         if (slot->u.ammo.outfit != NULL)
            pilot->mass_outfit += slot->u.ammo.quantity * slot->u.ammo.outfit->mass;
      }
   }

   /* Set final energy tau. */
   pilot->energy_tau = pilot->energy_max / pilot->energy_regen;

   /* Slot voodoo. */
   s        = &pilot->stats;
   /*
    * Electronic warfare setting base parameters.
    */
   s->ew_hide           = 1. + (s->ew_hide-1.) * exp( -0.2 * (double)(MAX(amount.ew_hide-1,0)) );
   s->ew_detect         = 1. + (s->ew_detect-1.) * exp( -0.2 * (double)(MAX(amount.ew_detect-1,0)) );
   s->ew_jumpDetect     = 1. + (s->ew_jumpDetect-1.) * exp( -0.2 * (double)(MAX(amount.ew_jumpDetect-1,0)) );
   pilot->ew_base_hide  = s->ew_hide;
   pilot->ew_detect     = s->ew_detect;
   pilot->ew_jumpDetect     = s->ew_jumpDetect;
   /* Fire rate:
    *  amount = p * exp( -0.15 * (n-1) )
    *  1x 15% -> 15%
    *  2x 15% -> 25.82%
    *  3x 15% -> 33.33%
    *  6x 15% -> 42.51%
    */
   if (amount.fwd_firerate > 0) {
      s->fwd_firerate = 1. + (s->fwd_firerate-1.) * exp( -0.15 * (double)(MAX(amount.fwd_firerate-1,0)) );
   }
   /* Cruiser. */
   if (amount.tur_firerate > 0) {
      s->tur_firerate = 1. + (s->tur_firerate-1.) * exp( -0.15 * (double)(MAX(amount.tur_firerate-1,0)) );
   }

   /* Increase health by relative bonuses. */
   pilot->armour_max += arel * pilot->ship->armour;
   pilot->armour_max *= pilot->stats.armour_mod;
   pilot->shield_max += srel * pilot->ship->shield;
   pilot->shield_max *= pilot->stats.shield_mod;
   pilot->energy_max += erel * pilot->ship->energy;
   /* pilot->energy_max *= pilot->stats.energy_mod; */

   /* Give the pilot his health proportion back */
   pilot->armour = ac * pilot->armour_max;
   pilot->shield = sc * pilot->shield_max;
   pilot->energy = ec * pilot->energy_max;
   pilot->fuel   = fc * pilot->fuel_max;

   /* Calculate mass. */
   pilot->solid->mass = pilot->ship->mass + pilot->stats.cargo_inertia*pilot->mass_cargo + pilot->mass_outfit;

   /* Calculate the heat. */
   pilot_heatCalc( pilot );

   /* Modulate by mass. */
   pilot_updateMass( pilot );

   /* Update GUI as necessary. */
   gui_setGeneric( pilot );
}
예제 #2
0
/**
 * @brief Recalculates the pilot's stats based on his outfits.
 *
 *    @param pilot Pilot to recalculate his stats.
 */
void pilot_calcStats( Pilot* pilot )
{
   int i;
   Outfit* o;
   PilotOutfitSlot *slot;
   double ac, sc, ec, fc; /* temporary health coefficients to set */
   ShipStats amount, *s;

   /*
    * set up the basic stuff
    */
   /* mass */
   pilot->solid->mass   = pilot->ship->mass;
   pilot->base_mass     = pilot->solid->mass;
   /* cpu */
   pilot->cpu           = 0.;
   /* movement */
   pilot->thrust_base   = pilot->ship->thrust;
   pilot->turn_base     = pilot->ship->turn;
   pilot->speed_base    = pilot->ship->speed;
   /* crew */
   pilot->crew          = pilot->ship->crew;
   /* cargo */
   pilot->cap_cargo     = pilot->ship->cap_cargo;
   /* fuel_consumption. */
   pilot->fuel_consumption = pilot->ship->fuel_consumption;
   /* health */
   ac = (pilot->armour_max > 0.) ? pilot->armour / pilot->armour_max : 0.;
   sc = (pilot->shield_max > 0.) ? pilot->shield / pilot->shield_max : 0.;
   ec = (pilot->energy_max > 0.) ? pilot->energy / pilot->energy_max : 0.;
   fc = (pilot->fuel_max   > 0.) ? pilot->fuel   / pilot->fuel_max   : 0.;
   pilot->armour_max    = pilot->ship->armour;
   pilot->shield_max    = pilot->ship->shield;
   pilot->fuel_max      = pilot->ship->fuel;
   pilot->armour_regen  = pilot->ship->armour_regen;
   pilot->shield_regen  = pilot->ship->shield_regen;
   /* Absorption. */
   pilot->dmg_absorb    = pilot->ship->dmg_absorb;
   /* Energy. */
   pilot->energy_max    = pilot->ship->energy;
   pilot->energy_regen  = pilot->ship->energy_regen;
   pilot->energy_loss   = 0.; /* Initially no net loss. */
   /* Stats. */ 
   s = &pilot->stats;
   memcpy( s, &pilot->ship->stats_array, sizeof(ShipStats) );
   memset( &amount, 0, sizeof(ShipStats) );

   /*
    * Now add outfit changes
    */
   pilot->mass_outfit   = 0.;
   pilot->jamming       = 0;
   for (i=0; i<pilot->noutfits; i++) {
      slot = pilot->outfits[i];
      o    = slot->outfit;

      /* Outfit must exist. */
      if (o==NULL)
         continue;

      /* Modify CPU. */
      pilot->cpu           += outfit_cpu(o);

      /* Add mass. */
      pilot->mass_outfit   += o->mass;

      /* Keep a separate counter for required (core) outfits. */
      if (sp_required( o->slot.spid ))
         pilot->base_mass += o->mass;

      /* Add ammo mass. */
      if (outfit_ammo(o) != NULL)
         if (slot->u.ammo.outfit != NULL)
            pilot->mass_outfit += slot->u.ammo.quantity * slot->u.ammo.outfit->mass;

      if (outfit_isAfterburner(o)) /* Afterburner */
         pilot->afterburner = pilot->outfits[i]; /* Set afterburner */

      /* Active outfits must be on to affect stuff. */
      if (slot->active && !(slot->state==PILOT_OUTFIT_ON))
         continue;

      if (outfit_isMod(o)) { /* Modification */
         /* Movement. */
         pilot->thrust_base   += o->u.mod.thrust;
         pilot->turn_base     += o->u.mod.turn;
         pilot->speed_base    += o->u.mod.speed;
         /* Health. */
         pilot->dmg_absorb    += o->u.mod.absorb;
         pilot->armour_max    += o->u.mod.armour;
         pilot->armour_regen  += o->u.mod.armour_regen;
         pilot->shield_max    += o->u.mod.shield;
         pilot->shield_regen  += o->u.mod.shield_regen;
         pilot->energy_max    += o->u.mod.energy;
         pilot->energy_regen  += o->u.mod.energy_regen;
         pilot->energy_loss   += o->u.mod.energy_loss;
         /* Fuel. */
         pilot->fuel_max      += o->u.mod.fuel;
         /* Misc. */
         pilot->cap_cargo     += o->u.mod.cargo;
         pilot->mass_outfit   += o->u.mod.mass_rel * pilot->ship->mass;
         pilot->crew          += o->u.mod.crew_rel * pilot->ship->crew;
         /*
          * Stats.
          */
         ss_statsModFromList( s, o->u.mod.stats, &amount );
     
      }
      else if (outfit_isAfterburner(o)) { /* Afterburner */
         pilot_setFlag( pilot, PILOT_AFTERBURNER ); /* We use old school flags for this still... */
         pilot->energy_loss += pilot->afterburner->outfit->u.afb.energy; /* energy loss */
      }
      else if (outfit_isJammer(o)) { /* Jammer */
         pilot->jamming        = 1;
         pilot->energy_loss   += o->u.jam.energy;
      }
   }

   if (!pilot_isFlag( pilot, PILOT_AFTERBURNER ))
      pilot->solid->speed_max = pilot->speed;

   /* Slot voodoo. */
   s = &pilot->stats;

   /* Fire rate:
    *  amount = p * exp( -0.15 * (n-1) )
    *  1x 15% -> 15%
    *  2x 15% -> 25.82%
    *  3x 15% -> 33.33%
    *  6x 15% -> 42.51%
    */
   if (amount.fwd_firerate > 0) {
      s->fwd_firerate = 1. + (s->fwd_firerate-1.) * exp( -0.15 * (double)(MAX(amount.fwd_firerate-1.,0)) );
   }
   /* Cruiser. */
   if (amount.tur_firerate > 0) {
      s->tur_firerate = 1. + (s->tur_firerate-1.) * exp( -0.15 * (double)(MAX(amount.tur_firerate-1.,0)) );
   }
   /*
    * Electronic warfare setting base parameters.
    */
   s->ew_hide           = 1. + (s->ew_hide-1.)        * exp( -0.2 * (double)(MAX(amount.ew_hide-1.,0)) );
   s->ew_detect         = 1. + (s->ew_detect-1.)      * exp( -0.2 * (double)(MAX(amount.ew_detect-1.,0)) );
   s->ew_jump_detect    = 1. + (s->ew_jump_detect-1.) * exp( -0.2 * (double)(MAX(amount.ew_jump_detect-1.,0)) );

   /* Square the internal values to speed up comparisons. */
   pilot->ew_base_hide   = pow2( s->ew_hide );
   pilot->ew_detect      = pow2( s->ew_detect );
   pilot->ew_jump_detect = pow2( s->ew_jump_detect );

   /*
    * Relative increases.
    */
   /* Movement. */
   pilot->thrust_base  *= s->thrust_mod;
   pilot->turn_base    *= s->turn_mod;
   pilot->speed_base   *= s->speed_mod;
   /* Health. */
   pilot->armour_max   *= s->armour_mod;
   pilot->armour_regen *= s->armour_regen_mod;
   pilot->shield_max   *= s->shield_mod;
   pilot->shield_regen *= s->shield_regen_mod;
   pilot->energy_max   *= s->energy_mod;
   pilot->energy_regen *= s->energy_regen_mod;
   /* cpu */
   pilot->cpu_max       = (int)floor((float)(pilot->ship->cpu + s->cpu_max)*s->cpu_mod);
   pilot->cpu          += pilot->cpu_max; /* CPU is negative, this just sets it so it's based off of cpu_max. */
   /* Misc. */
   pilot->dmg_absorb    = MAX( 0., pilot->dmg_absorb );
   pilot->crew         *= s->crew_mod;
   pilot->cap_cargo    *= s->cargo_mod;

   /*
    * Flat increases.
    */
   pilot->energy_max   += s->energy_flat;
   pilot->energy       += s->energy_flat;
   pilot->energy_regen -= s->energy_usage;

   /* Give the pilot his health proportion back */
   pilot->armour = ac * pilot->armour_max;
   pilot->shield = sc * pilot->shield_max;
   pilot->energy = ec * pilot->energy_max;
   pilot->fuel   = fc * pilot->fuel_max;

   /* Set final energy tau. */
   pilot->energy_tau = pilot->energy_max / pilot->energy_regen;

   /* Cargo has to be reset. */
   pilot_cargoCalc(pilot);

   /* Calculate mass. */
   pilot->solid->mass = s->mass_mod*pilot->ship->mass + pilot->stats.cargo_inertia*pilot->mass_cargo + pilot->mass_outfit;

   /* Calculate the heat. */
   pilot_heatCalc( pilot );

   /* Modulate by mass. */
   pilot_updateMass( pilot );

   /* Update GUI as necessary. */
   gui_setGeneric( pilot );
}
예제 #3
0
/**
 * @brief Dumps the modification data to csv.
 *
 * Note that this function is primarily intended for balancing core outfits.
 *
 * To that end, it omits a number of seldom-used properties, and is primarily
 * concerned with those that are common to most types of modifications, or at
 * least one category of core outfit.
 */
void dout_csvMod( const char *path )
{
   Outfit *o, *o_all;
   int i, n, l;
   SDL_RWops *rw;
   char buf[ 1024 ];
   ShipStats base, stats;

   /* 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,size,"
         "license,mass,price,cpu,cpu_max,"
         "thrust,turn,speed,fuel,energy_usage,"
         "armour,armour_regen,"
         "shield,shield_regen,"
         "energy,energy_regen,"
         "absorb,cargo,ew_hide\n"
         );
   SDL_RWwrite( rw, buf, l, 1 );

   ss_statsInit( &base );

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

      /* Only handle modifications. */
      if (!outfit_isMod(o))
         continue;

      stats = base;
      ss_statsModFromList( &stats, o->u.mod.stats, NULL );

      l = nsnprintf( buf, sizeof(buf),
            "%s,%s,%s,%s,"
            "%s,%f,%"CREDITS_PRI",%f,%f,"
            "%f,%f,%f,%f,%f,"
            "%f,%f,"
            "%f,%f,"
            "%f,%f,"
            "%f,%f,%f\n",
            o->name, outfit_getType(o), outfit_slotName(o), outfit_slotSize(o),
            o->license, o->mass, o->price, o->cpu, stats.cpu_max,
            o->u.mod.thrust, o->u.mod.turn * 180. / M_PI, o->u.mod.speed, o->u.mod.fuel, stats.energy_usage,
            o->u.mod.armour, o->u.mod.armour_regen,
            o->u.mod.shield, o->u.mod.shield_regen,
            o->u.mod.energy, o->u.mod.energy_regen,
            o->u.mod.absorb * 100, o->u.mod.cargo, (stats.ew_hide - 1.) * 100
            );
      SDL_RWwrite( rw, buf, l, 1 );
   }

   /* Close file. */
   SDL_RWclose( rw );
}