34#include "nlua_pilot.h"
35#include "nlua_pilotoutfit.h"
60 return &p->weapon_sets[ id ];
80 isstealth = pilot_isFlag( p, PILOT_STEALTH );
92 if ((level != -1) && (ws->
slots[i].
level != level))
97 for (
int j=0; j<i; j++) {
99 if ((level != -1) && (ws->
slots[j].
level != level))
102 if (p->outfits[ ws->
slots[j].
slotid ]->outfit == o) {
122 else if (p->nav_asteroid != -1) {
123 field = &
cur_system->asteroids[p->nav_anchor];
124 ast = &field->
asteroids[p->nav_asteroid];
137 if (isstealth && (ret>0))
152 for (
int i=0; i<PILOT_WEAPON_SETS; i++) {
168 int isstealth = pilot_isFlag( p, PILOT_STEALTH );
171 if (ws->
slots == NULL)
176 case WEAPSET_TYPE_CHANGE:
179 if (
id != p->active_set)
185 case WEAPSET_TYPE_WEAPON:
197 case WEAPSET_TYPE_ACTIVE:
207 if ((pilot_isDisabled(p)) || (pilot_isFlag(p, PILOT_COOLDOWN)))
213 for (
int i=0; i<l; i++) {
215 if (pos->
state == PILOT_OUTFIT_OFF) {
224 for (
int i=0; i<l; i++) {
226 if (pos->
state != PILOT_OUTFIT_ON)
234 pilotoutfit_modified = 0;
235 for (
int i=0; i<l; i++) {
237 if (pos->
state != PILOT_OUTFIT_OFF)
243 if (pilotoutfit_modified)
266 if (pilot_isFlag( p, PILOT_HYP_BEGIN))
269 for (
int i=0; i<PILOT_WEAPON_SETS; i++) {
271 if (ws->
slots == NULL)
275 if (ws->
type == WEAPSET_TYPE_WEAPON) {
288 p->outfits[i]->level = -1;
320 if ((ws->
type == WEAPSET_TYPE_WEAPON) ||
321 (ws->
type == WEAPSET_TYPE_ACTIVE))
387 case WEAPSET_TYPE_CHANGE:
return _(
"Weapons - Switched");
break;
388 case WEAPSET_TYPE_WEAPON:
return _(
"Weapons - Instant");
break;
389 case WEAPSET_TYPE_ACTIVE:
return _(
"Abilities - Toggled");
break;
405 if (ws->
slots == NULL)
408 for (
int i=0; i<l; i++) {
448 if (ws->
slots == NULL)
457 if (
id == p->active_set)
473 for (
int j=0; j<PILOT_WEAPON_SETS; j++) {
484 if (
id == p->active_set)
508 if (
id == p->active_set)
513 for (
int j=0; j<PILOT_WEAPON_SETS; j++) {
550 for (
int i=0; i<PILOT_WEAPON_SETS; i++)
564 double range_accum[PILOT_WEAPSET_MAX_LEVELS];
565 int range_num[PILOT_WEAPSET_MAX_LEVELS];
566 double speed_accum[PILOT_WEAPSET_MAX_LEVELS];
567 int speed_num[PILOT_WEAPSET_MAX_LEVELS];
570 for (
int i=0; i<PILOT_WEAPSET_MAX_LEVELS; i++) {
583 if (lev >= PILOT_WEAPSET_MAX_LEVELS)
593 range *= p->stats.launch_range;
596 range_accum[ lev ] += range;
604 speed_accum[ lev ] += speed;
610 for (
int i=0; i<PILOT_WEAPSET_MAX_LEVELS; i++) {
612 if (range_num[i] == 0)
615 ws->
range[i] = range_accum[i] / (double) range_num[i];
618 if (speed_num[i] == 0)
621 ws->
speed[i] = speed_accum[i] / (double) speed_num[i];
638 for (
int i=0; i<PILOT_WEAPSET_MAX_LEVELS; i++)
639 range += ws->
range[i];
642 range = ws->
range[ level ];
660 for (
int i=0; i<PILOT_WEAPSET_MAX_LEVELS; i++)
661 speed += ws->
speed[i];
664 speed = ws->
speed[ level ];
687 if ((level >= 0) && (ws->
slots[i].
level != level))
695 return (nammo==0) ? 0. : ammo / (double)nammo;
720 for (
int i=0; i<PILOT_WEAPON_SETS; i++)
748 if (ws->
type == WEAPSET_TYPE_CHANGE) {
752 if (pilot_isFlag(p, PILOT_COOLDOWN) && ret)
800 if ((level != -1) && (ws->
slots[i].
level != level))
807 pos->
state = PILOT_OUTFIT_OFF;
841 double rate_mod, energy_mod, used;
844 if (w->u.beamid == 0)
848 if (w->outfit == NULL) {
854 if ((w->outfit->lua_ontoggle != LUA_NOREF) &&
865 w->timer = rate_mod * (used / w->outfit->u.bem.duration) *
outfit_delay( w->outfit );
879 vec2 approach_vector, relative_location, orthoradial_vector;
880 double speed, radial_speed, orthoradial_speed, dist, t;
882 dist = vec2_dist( &parent->
solid->
pos, pos );
897 vec2_cset( &approach_vector, - vel->
x, - vel->
y );
899 vec2_cset( &approach_vector, VX(parent->
solid->
vel) - vel->
x,
905 vec2_cset( &relative_location, pos->
x - VX(parent->
solid->
pos),
909 vec2_cset(&orthoradial_vector, VY(parent->
solid->
pos) - pos->
y,
912 radial_speed = vec2_dot( &approach_vector, &relative_location );
913 radial_speed = radial_speed / VMOD(relative_location);
915 orthoradial_speed = vec2_dot(&approach_vector, &orthoradial_vector);
916 orthoradial_speed = orthoradial_speed / VMOD(relative_location);
918 if ( ((speed*speed - VMOD(approach_vector)*VMOD(approach_vector)) != 0) && (speed*speed - orthoradial_speed*orthoradial_speed) > 0)
919 t = dist * (sqrt( speed*speed - orthoradial_speed*orthoradial_speed ) - radial_speed) /
920 (speed*speed - VMOD(approach_vector)*VMOD(approach_vector));
926 t = - dist * (sqrt( speed*speed - orthoradial_speed*orthoradial_speed ) + radial_speed) /
927 (speed*speed - VMOD(approach_vector)*VMOD(approach_vector));
942 int is_launcher, is_bay;
943 double rate_mod, energy_mod;
983 if ((level != -1) && (ws->
slots[i].
level != level))
987 if ((is_launcher || is_bay) && (pos->u.
ammo.
quantity <= 0))
991 if (pos->
timer <= 0.) {
1003 if ((maxp < 0) || (pos->
timer > maxt)) {
1036 double rate_mod, energy_mod;
1041 if (w->outfit == NULL)
1045 if (
outfit_isBeam(w->outfit) && w->outfit->u.bem.min_duration)
1046 w->stimer = INFINITY;
1059 vec2_cset( &vv, p->solid->vel.x - vp.
y*p->solid->dir_vel,
1060 p->solid->vel.y + vp.
x*p->solid->dir_vel );
1063 vp.
x += p->solid->pos.x;
1064 vp.
y += p->solid->pos.y;
1075 if ((w->outfit->lua_ontoggle != LUA_NOREF) &&
1080 p->energy -= energy;
1082 if (!outfit_isProp( w->outfit, OUTFIT_PROP_SHOOT_DRY )) {
1083 for (
int i=0; i<w->outfit->u.blt.shots; i++)
1085 &vp, &vv, p, p->target, time, aim );
1094 if (w->u.beamid > 0)
1102 if ((w->outfit->lua_ontoggle != LUA_NOREF) &&
1107 w->state = PILOT_OUTFIT_ON;
1108 if (!outfit_isProp( w->outfit, OUTFIT_PROP_SHOOT_DRY )) {
1110 &vp, &p->solid->vel, p, p->target, aim );
1113 w->timer = w->outfit->u.bem.duration;
1126 if ((w->outfit->u.lau.ai != AMMO_AI_UNGUIDED) && (p->id==p->target))
1130 if (w->u.ammo.quantity <= 0)
1138 if ((w->outfit->lua_ontoggle != LUA_NOREF) &&
1143 p->energy -= energy;
1145 if (!outfit_isProp( w->outfit, OUTFIT_PROP_SHOOT_DRY )) {
1146 for (
int i=0; i<w->outfit->u.lau.shots; i++)
1148 &vp, &vv, p, p->target, time, aim );
1155 p->shoot_indicator = 1;
1158 if (w->u.ammo.quantity <= 0) {
1159 for (
int j=0; j<PILOT_WEAPON_SETS; j++)
1170 if (w->u.ammo.quantity <= 0)
1174 if ((w->outfit->lua_ontoggle != LUA_NOREF) &&
1179 for (
int j=0; j<
array_size(p->outfits); j++) {
1180 if (p->outfits[j] == w)
1185 if (!outfit_isProp( w->outfit, OUTFIT_PROP_SHOOT_DRY ))
1187 &vp, &p->solid->vel, p->solid->dir, ESCORT_TYPE_BAY, 1, dockslot );
1189 w->u.ammo.quantity -= 1;
1190 p->mass_outfit -= w->outfit->u.bay.ship_mass;
1194 WARN(_(
"Shooting unknown weapon type: %s"), w->outfit->name);
1214 case OUTFIT_TYPE_BOLT:
1215 case OUTFIT_TYPE_BEAM:
1216 *rate_mod = 1. / p->stats.fwd_firerate;
1217 *energy_mod = p->stats.fwd_energy;
1219 case OUTFIT_TYPE_TURRET_BOLT:
1220 case OUTFIT_TYPE_TURRET_BEAM:
1221 *rate_mod = 1. / p->stats.tur_firerate;
1222 *energy_mod = p->stats.tur_energy;
1225 case OUTFIT_TYPE_LAUNCHER:
1226 case OUTFIT_TYPE_TURRET_LAUNCHER:
1227 *rate_mod = 1. / p->stats.launch_rate;
1231 case OUTFIT_TYPE_FIGHTER_BAY:
1232 *rate_mod = 1. / p->stats.fbay_rate;
1250 for (
int i=0; i<PILOT_WEAPON_SETS; i++) {
1288 if (!pilot_isPlayer(p))
1289 for (
int i=0; i<PILOT_WEAPON_SETS; i++) {
1296 for (
int i=0; i<
array_size(p->outfits); i++) {
1364 if (p->weapon_sets[ p->active_set ].type == WEAPSET_TYPE_CHANGE) {
1371 for (i=0; i<PILOT_WEAPON_SETS; i++)
1372 if (p->weapon_sets[i].type == WEAPSET_TYPE_CHANGE)
1376 if (i >= PILOT_WEAPON_SETS)
1392 for (
int j=0; j<PILOT_WEAPON_SETS; j++) {
1396 for (
int i=0; i<l; i++) {
1410 if ((ws->
type == WEAPSET_TYPE_WEAPON) ||
1411 (ws->
type == WEAPSET_TYPE_ACTIVE))
1430 if (o->
outfit == NULL || (pilot_isDisabled(p)) || (pilot_isFlag(p, PILOT_COOLDOWN)))
1457 o->
state = PILOT_OUTFIT_COOLDOWN;
1480 o->
state = PILOT_OUTFIT_ON;
1498 for (
int i=0; i<
array_size(p->outfits); i++) {
1503 if (o->
state == PILOT_OUTFIT_ON)
1519 if (pilot_isFlag(p, PILOT_HYP_PREP) || pilot_isFlag(p, PILOT_HYPERSPACE) ||
1520 pilot_isFlag(p, PILOT_LANDING) || pilot_isFlag(p, PILOT_TAKEOFF) ||
1521 pilot_isDisabled(p) || pilot_isFlag(p, PILOT_COOLDOWN))
1525 if (pilot_isFlag( p, PILOT_MANUAL_CONTROL ) && pilot_isFlag( p, PILOT_PLAYER ))
1529 if (p->afterburner == NULL)
1534 p->afterburner->outfit->u.afb.heat_base,
1535 p->afterburner->outfit->u.afb.heat_cap ) < 0.3)
1538 if (p->afterburner->state == PILOT_OUTFIT_OFF) {
1539 p->afterburner->state = PILOT_OUTFIT_ON;
1541 pilot_setFlag(p,PILOT_AFTERBURNER);
1547 p->solid->pos.x, p->solid->pos.y, p->solid->vel.x, p->solid->vel.y);
1550 if (pilot_isPlayer(p)) {
1563 if (p->afterburner == NULL)
1566 if (p->afterburner->state == PILOT_OUTFIT_ON) {
1567 p->afterburner->state = PILOT_OUTFIT_OFF;
1568 pilot_rmFlag(p,PILOT_AFTERBURNER);
1573 p->solid->pos.x, p->solid->pos.y, p->solid->vel.x, p->solid->vel.y);
1584 for (
int i=0; i<PILOT_WEAPON_SETS; i++)
1593 for (
int i=0; i<PILOT_WEAPON_SETS; i++) {
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
#define array_copy(basic_type, ptr_array)
Returns a shallow copy of the input array.
#define array_end(array)
Returns a pointer to the end of the reserved memory space.
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
#define array_begin(array)
Returns a pointer to the beginning of the reserved memory space.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
unsigned int escort_create(Pilot *p, const char *ship, const vec2 *pos, const vec2 *vel, double dir, EscortType_t type, int add, int dockslot)
Creates an escort.
Header file with generic functions and naev-specifics.
int outfit_isSecondary(const Outfit *o)
Checks if outfit has the secondary flag set.
double outfit_speed(const Outfit *o)
Gets the outfit's speed.
int outfit_isBeam(const Outfit *o)
Checks if outfit is a beam type weapon.
int outfit_isActive(const Outfit *o)
Checks if outfit is an active outfit.
int outfit_isLauncher(const Outfit *o)
Checks if outfit is a weapon launcher.
int outfit_isSeeker(const Outfit *o)
Checks if outfit is a seeking weapon.
int outfit_isFighterBay(const Outfit *o)
Checks if outfit is a fighter bay.
int outfit_isAfterburner(const Outfit *o)
Checks if outfit is an afterburner.
double outfit_range(const Outfit *o)
Gets the outfit's range.
int outfit_isTurret(const Outfit *o)
Checks if outfit is a turret class weapon.
int outfit_isMod(const Outfit *o)
Checks if outfit is a ship modification.
double outfit_duration(const Outfit *o)
Gets the outfit's duration.
double outfit_cooldown(const Outfit *o)
Gets the outfit's cooldown.
int outfit_isBolt(const Outfit *o)
Checks if outfit is bolt type weapon.
double outfit_energy(const Outfit *o)
Gets the outfit's energy usage.
double outfit_delay(const Outfit *o)
Gets the outfit's delay.
Pilot * pilot_getTarget(Pilot *p)
Gets the target of a pilot using a fancy caching system.
void pilot_cooldownEnd(Pilot *p, const char *reason)
Terminates active cooldown.
void pilot_destealth(Pilot *p)
Destealths a pilot.
void pilot_heatAddSlot(const Pilot *p, PilotOutfitSlot *o)
Adds heat to an outfit slot.
double pilot_heatEfficiencyMod(double T, double Tb, double Tc)
Returns a 0:1 modifier representing efficiency (1. being normal).
double pilot_heatAccuracyMod(double T)
Returns a 0:1 modifier representing accuracy (0. being normal).
int pilot_getMount(const Pilot *p, const PilotOutfitSlot *w, vec2 *v)
Gets the mount position of a pilot.
void pilot_updateMass(Pilot *pilot)
Updates the pilot stats after mass change.
void pilot_outfitLOnshoot(Pilot *pilot)
Runs the pilot's Lua outfits onshoot script.
int pilot_maxAmmoO(const Pilot *p, const Outfit *o)
Gets the maximum available ammo for a pilot for a specific outfit.
int pilot_slotIsToggleable(const PilotOutfitSlot *o)
Checks to see if a slot has an active outfit that can be toggleable.
void pilot_calcStats(Pilot *pilot)
Recalculates the pilot's stats based on his outfits.
int pilot_outfitLOntoggle(Pilot *pilot, PilotOutfitSlot *po, int on)
Handle the manual toggle of an outfit.
int pilot_rmAmmo(Pilot *pilot, PilotOutfitSlot *s, int quantity)
Removes some ammo from the pilot stock.
static int pilot_shootWeapon(Pilot *p, PilotOutfitSlot *w, double time, int aim)
Actually handles the shooting, how often the player.p can shoot and such.
void pilot_stopBeam(Pilot *p, PilotOutfitSlot *w)
Stops a beam outfit and sets delay as appropriate.
int pilot_weapSetTypeCheck(Pilot *p, int id)
Checks the current weapon set type.
void pilot_getRateMod(double *rate_mod, double *energy_mod, const Pilot *p, const Outfit *o)
Gets applicable fire rate and energy modifications for a pilot's weapon.
void pilot_weapSetInrange(Pilot *p, int id, int inrange)
Changes the weapon set inrange property.
void pilot_weaponSafe(Pilot *p)
Sets the weapon set as safe.
int pilot_shoot(Pilot *p, int level)
Makes the pilot shoot.
void pilot_weapSetManual(Pilot *p, int id, int manual)
Changes the weapon set manual property.
void pilot_afterburnOver(Pilot *p)
Deactivates the afterburner.
void pilot_weapSetCleanup(Pilot *p, int id)
Cleans up a weapon set.
int pilot_weapSetManualCheck(Pilot *p, int id)
Checks the current weapon set manual property.
static int pilot_weapSetFire(Pilot *p, PilotWeaponSet *ws, int level)
Fires a weapon set.
static int pilot_shootWeaponSetOutfit(Pilot *p, PilotWeaponSet *ws, const Outfit *o, int level, double time, int aim)
Calculates and shoots the appropriate weapons in a weapon set matching an outfit.
static void pilot_weapSetUpdateOutfits(Pilot *p, PilotWeaponSet *ws)
Updates the outfits with their current weapon set level.
void pilot_shootStop(Pilot *p, int level)
Have pilot stop shooting their weapon.
void pilot_afterburn(Pilot *p)
Activate the afterburner.
void pilot_weaponClear(Pilot *p)
Clears the pilots weapon settings.
void ws_copy(PilotWeaponSet dest[PILOT_WEAPON_SETS], const PilotWeaponSet src[PILOT_WEAPON_SETS])
Copies a weapon set over.
void ws_free(PilotWeaponSet ws[PILOT_WEAPON_SETS])
Frees a weapon set.
static void pilot_weapSetUpdateRange(const Pilot *p, PilotWeaponSet *ws)
Updates the weapon range for a pilot weapon set.
void pilot_weapSetAdd(Pilot *p, int id, PilotOutfitSlot *o, int level)
Adds an outfit to a weapon set.
double pilot_weapFlyTime(const Outfit *o, const Pilot *parent, const vec2 *pos, const vec2 *vel)
Computes an estimation of ammo flying time.
int pilot_weapSetCheck(Pilot *p, int id, PilotOutfitSlot *o)
Checks to see if a slot is in a weapon set.
void pilot_weapSetAIClear(Pilot *p)
Useful function for AI, clears activeness of all weapon sets.
void pilot_weapSetRmSlot(Pilot *p, int id, OutfitSlotType type)
Removes slots by type from the weapon set.
void pilot_weapSetType(Pilot *p, int id, int type)
Changes the weapon sets mode.
PilotWeaponSet * pilot_weapSet(Pilot *p, int id)
Gets a weapon set from id.
void pilot_weapSetUpdate(Pilot *p)
Updates the pilot's weapon sets.
int pilot_outfitOffAll(Pilot *p)
Disables all active outfits for a pilot.
void pilot_weaponSetDefault(Pilot *p)
Gives the pilot a default weapon set.
PilotWeaponSetOutfit * pilot_weapSetList(Pilot *p, int id)
Lists the items in a pilot weapon set.
unsigned int pilot_weaponSetShootStop(Pilot *p, PilotWeaponSet *ws, int level)
Have pilot stop shooting a given weaponset.
int pilot_outfitOn(Pilot *p, PilotOutfitSlot *o)
Enable a given active outfit.
double pilot_weapSetAmmo(Pilot *p, int id, int level)
Gets the ammo of the current pilot weapon set.
void pilot_weaponAuto(Pilot *p)
Tries to automatically set and create the pilot's weapon set.
int pilot_weapSetInrangeCheck(Pilot *p, int id)
Checks the current weapon set inrange property.
void pilot_weapSetPress(Pilot *p, int id, int type)
Handles a weapon set press.
void pilot_weapSetFree(Pilot *p)
Frees a pilot's weapon sets.
const char * pilot_weapSetName(Pilot *p, int id)
Gets the name of a weapon set.
double pilot_weapSetSpeed(Pilot *p, int id, int level)
Gets the speed of the current pilot weapon set.
void pilot_weapSetRm(Pilot *p, int id, PilotOutfitSlot *o)
Removes a slot from a weapon set.
int pilot_outfitOff(Pilot *p, PilotOutfitSlot *o)
Disables a given active outfit.
double pilot_weapSetRange(Pilot *p, int id, int level)
Gets the range of the current pilot weapon set.
void pilot_weapSetUpdateStats(Pilot *p)
Update the weapon sets given pilot stat changes.
int sound_playPos(int sound, double px, double py, double vx, double vy)
Plays a sound based on position.
void spfx_shake(double mod)
Increases the current rumble level.
Represents an asteroid field anchor.
Represents a single asteroid.
A ship outfit, depends radically on the type.
OutfitAfterburnerData afb
Stores an outfit the pilot has.
A pilot Weapon Set Outfit.
A weapon set represents a set of weapons that have an action.
PilotWeaponSetOutfit * slots
double range[PILOT_WEAPSET_MAX_LEVELS]
double speed[PILOT_WEAPSET_MAX_LEVELS]
The representation of an in-game pilot.
PilotOutfitSlot * afterburner
void weapon_add(PilotOutfitSlot *po, const double T, const double dir, const vec2 *pos, const vec2 *vel, const Pilot *parent, unsigned int target, double time, int aim)
Creates a new weapon.
void beam_end(const unsigned int parent, unsigned int beam)
Ends a beam weapon.
unsigned int beam_start(PilotOutfitSlot *po, const double dir, const vec2 *pos, const vec2 *vel, const Pilot *parent, const unsigned int target, int aim)
Starts a beam weapon.