23#include "damagetype.h"
30#include "gatherable.h"
34#include "land_outfits.h"
35#include "land_shipyard.h"
39#include "nlua_pilotoutfit.h"
41#include "nlua_outfit.h"
48#include "player_autonav.h"
49#include "pilot_ship.h"
55#define PILOT_SIZE_MIN 128
64static int qt_init = 0;
66static int qt_max_elem = 2;
67static int qt_depth = 5;
78 const double dir,
const vec2* pos,
const vec2* vel,
79 const PilotFlags flags,
unsigned int dockpilot,
int dockslot );
102static int pilot_cmp(
const void *ptr1,
const void *ptr2 )
104 const Pilot *p1, *p2;
105 p1 = *((
const Pilot**) ptr1);
106 p2 = *((
const Pilot**) ptr2);
107 return p1->
id - p2->
id;
118 const Pilot pid = { .id =
id };
119 const Pilot *pidptr = &pid;
213 else if (mode == 1) {
257 if (pilot_isFlag( p, PILOT_DELETE ) ||
258 pilot_isFlag( p, PILOT_DEAD ))
262 if (pilot_isFlag( p, PILOT_HIDE ) ||
263 pilot_isFlag( p, PILOT_INVISIBLE))
288 if (pilot_isDisabled(target))
292 if (pilot_isFlag( target, PILOT_INVINCIBLE ))
296 if (pilot_isFlag( target, PILOT_LANDING) ||
297 pilot_isFlag( target, PILOT_TAKEOFF ) ||
298 pilot_isFlag( target, PILOT_NONTARGETABLE))
335 td = vec2_dist2(&
pilot_stack[i]->solid.pos, &p->solid.pos);
336 if (!tp || (td <
d)) {
367 td = vec2_dist2(&
pilot_stack[i]->solid.pos, &p->solid.pos);
368 if (!tp || (td <
d)) {
388 double mass_factor,
double health_factor,
389 double damage_factor,
double range_factor )
392 double current_heuristic_value = 10e3;
402 temp = range_factor *
403 vec2_dist2( &target->
solid.
pos, &p->solid.pos )
408 if ((tp == 0) || (temp < current_heuristic_value)) {
409 current_heuristic_value = temp;
439 double relpower, ppower;
449 double dx, dy, td, curpower;
465 p->solid.pos.x - 2*p->solid.vel.x;
467 p->solid.pos.y - 2*p->solid.vel.y;
482 if (ppower >= curpower )
485 if (relpower < curpower ) {
515 if (!disabled && pilot_isPlayer(p) &&
529 if (((*tp==NULL) || (td <
d))) {
569 double a = ang + M_PI;
580 if (!disabled && pilot_isPlayer(p) &&
602 if (
ABS(angle_diff(ang, ta)) <
ABS(angle_diff(ang, a))) {
622 const Pilot pid = { .id =
id };
623 const Pilot *pidptr = &pid;
626 if ((pp==NULL) || (pilot_isFlag(*pp, PILOT_DELETE)))
639 if (p->target==p->id)
645 if (pilot_isFlag( t, PILOT_DELETE )) {
661 p->solid.accel = p->accel * accel;
669 p->solid.dir_vel = p->turn * turn;
681 && !pilot_isFlag( p, PILOT_BRIBED )
682 && (pilot_isFlag( p, PILOT_HOSTILE ) ||
710 if (pilot_isFlag( p, PILOT_FRIENDLY) ||
711 (
areAllies( FACTION_PLAYER,p->faction) &&
712 !pilot_isFlag( p, PILOT_HOSTILE ) ) )
723 if (pilot_isWithPlayer(p)) {
726 else if (pilot_isFlag( target, PILOT_HOSTILE ))
729 else if (pilot_isWithPlayer(target)) {
732 else if (pilot_isFlag( p, PILOT_HOSTILE ))
747 if (pilot_isWithPlayer(p)) {
750 else if (pilot_isFlag( target, PILOT_FRIENDLY ))
752 else if (pilot_isFlag(target, PILOT_BRIBED))
755 if (pilot_isWithPlayer(target)) {
758 else if (pilot_isFlag( p, PILOT_FRIENDLY ))
760 else if (pilot_isFlag(p, PILOT_BRIBED))
778 if ((p->dockpilot != 0) && (p->dockslot != -1)) {
780 if (dockpilot != NULL)
781 return dockpilot->
outfits[p->dockslot];
788const IntList *pilot_collideQuery(
int x1,
int y1,
int x2,
int y2 )
794void pilot_collideQueryIL(
IntList *il,
int x1,
int y1,
int x2,
int y2 )
812 double diff = angle_diff( p->solid.dir, dir );
813 double turn =
CLAMP( -1., 1., diff/dt );
823 if (p->stats.misc_reverse_thrust) {
824 double diff, btime, ftime, vel, t;
825 vel =
MIN( VMOD(p->solid.vel), p->speed );
829 diff = angle_diff(p->solid.dir, VANGLE(p->solid.vel) + M_PI);
830 btime =
ABS(diff) / p->turn + t;
833 diff = angle_diff(p->solid.dir, VANGLE(p->solid.vel));
834 ftime =
ABS(diff) / p->turn + t / PILOT_REVERSE_THRUST;
847 double vel =
MIN(
MIN( VMOD(p->solid.vel), p->speed ), solid_maxspeed( &p->solid, p->speed, p->accel ) );
848 double accel = p->accel;
849 double t = vel / accel + dt;
851 return vel * t - 0.5 * PILOT_REVERSE_THRUST * accel * t * t;
852 return vel*(t+M_PI/p->turn) - 0.5 * accel * t * t;
864 double dir, accel, diff;
865 int isstopped = pilot_isStopped(p);
871 dir = VANGLE(p->solid.vel);
872 accel = -PILOT_REVERSE_THRUST;
875 dir = VANGLE(p->solid.vel) + M_PI;
880 if (
ABS(diff) < MIN_DIR_ERR)
895 double heat_capacity, heat_mean;
898 if (dochecks && !pilot_isStopped(p)) {
899 pilot_setFlag(p, PILOT_BRAKING);
900 pilot_setFlag(p, PILOT_COOLDOWN_BRAKE);
904 pilot_rmFlag(p, PILOT_BRAKING);
905 pilot_rmFlag(p, PILOT_COOLDOWN_BRAKE);
908 if (p->id == PLAYER_ID)
919 heat_capacity = p->heat_C;
920 heat_mean = p->heat_T * p->heat_C;
921 for (
int i=0; i<
array_size(p->outfits); i++) {
924 heat_capacity += p->outfits[i]->heat_C;
929 heat_mean =
MAX( heat_mean, CONST_SPACE_STAR_TEMP );
931 heat_mean /= heat_capacity;
943 p->cdelay = (5. + sqrt(p->base_mass) / 2.) *
944 (1. + pow(
MAX(heat_mean / CONST_SPACE_STAR_TEMP - 1.,0.), 1.25));
945 p->ctimer = p->cdelay * p->stats.cooldown_time;
946 p->heat_start = p->heat_T;
947 pilot_setFlag(p, PILOT_COOLDOWN);
961 if (pilot_isFlag(p, PILOT_COOLDOWN_BRAKE)) {
962 pilot_rmFlag(p, PILOT_COOLDOWN_BRAKE);
967 if (p->id == PLAYER_ID) {
979 pilot_rmFlag(p, PILOT_COOLDOWN);
982 if (p->ctimer < 0.) {
1003 vec2 tv, approach_vector, relative_location, orthoradial_vector;
1006 double radial_speed;
1007 double orthoradial_speed;
1010 dist = vec2_dist( &p->solid.pos, pos );
1025 vec2_cset(&approach_vector, VX(p->solid.vel) - VX(*vel), VY(p->solid.vel) - VY(*vel) );
1026 vec2_cset(&relative_location, VX(*pos) - VX(p->solid.pos), VY(*pos) - VY(p->solid.pos) );
1027 vec2_cset(&orthoradial_vector, VY(p->solid.pos) - VY(*pos), VX(*pos) - VX(p->solid.pos) );
1029 radial_speed = vec2_dot(&approach_vector, &relative_location);
1030 radial_speed = radial_speed / VMOD(relative_location);
1032 orthoradial_speed = vec2_dot(&approach_vector, &orthoradial_vector);
1033 orthoradial_speed = orthoradial_speed / VMOD(relative_location);
1038 if ( ((speed*speed - VMOD(approach_vector)*VMOD(approach_vector)) != 0) && (speed*speed - orthoradial_speed*orthoradial_speed) > 0)
1039 t = dist * (sqrt( speed*speed - orthoradial_speed*orthoradial_speed ) - radial_speed) /
1040 (speed*speed - VMOD(approach_vector)*VMOD(approach_vector));
1046 t = - dist * (sqrt( speed*speed - orthoradial_speed*orthoradial_speed ) + radial_speed) /
1047 (speed*speed - VMOD(approach_vector)*VMOD(approach_vector));
1054 x = pos->
x + vel->
x*t - (p->solid.pos.x + p->solid.vel.x*t);
1055 y = pos->
y + vel->
y*t - (p->solid.pos.y + p->solid.vel.y*t);
1056 vec2_cset( &tv, x, y );
1069 || !pilot_isFlag( p, PILOT_HOSTILE ))
1070 pilot_setFlag( p, PILOT_HOSTILE );
1072 pilot_rmFlag( p, PILOT_BRIBED );
1082 if (pilot_isDisabled(p))
1088 else if (pilot_isFlag(p, PILOT_BRIBED))
1098 free( p->comm_msg );
1099 p->comm_msg = strdup( s );
1149 if (attacker == NULL)
1158 if (!pilot_isFlag(p, PILOT_DISTRESSED)) {
1161 if (spob_hasService(
cur_system->spobs[i], SPOB_SERVICE_INHABITED) &&
1175 if ((pi->
ai == NULL) || (pi->
id == p->id) ||
1176 (pilot_isFlag(pi, PILOT_DEAD)) ||
1177 (pilot_isFlag(pi, PILOT_DELETE)))
1185 d = vec2_dist2( &p->solid.pos, &pi->
solid.
pos );
1194 if (!pilot_isFlag(p, PILOT_DISTRESSED) &&
1200 if (!pilot_isFlag(p, PILOT_DISTRESSED)) {
1203 if (r && (attacker != NULL) && (pilot_isWithPlayer(attacker))) {
1205 WARN(_(
"Pilot '%s' does not have an AI!"), p->name);
1208 lua_rawgeti( naevL, LUA_REGISTRYINDEX, p->lua_mem );
1209 lua_getfield( naevL, -1,
"distress_hit" );
1210 if (lua_isnil(naevL,-1))
1211 hit = (pow(p->base_mass, 0.2) - 1.);
1212 else if (lua_isnumber(naevL,-1))
1213 hit = lua_tonumber(naevL,-1);
1215 WARN(_(
"Pilot '%s' has non-number mem.distress_hit!"),p->name);
1224 pilot_setFlag(p, PILOT_DISTRESSED);
1238 if (pilot_isFlag(p, PILOT_HOSTILE))
1239 pilot_rmFlag(p, PILOT_HOSTILE);
1242 if (
areEnemies( FACTION_PLAYER, p->faction ))
1243 pilot_setFlag(p, PILOT_BRIBED);
1254 pilot_setFlag(p, PILOT_FRIENDLY);
1264 pilot_rmFlag(p, PILOT_FRIENDLY);
1275 return p->fuel / p->fuel_consumption;
1286 const glColour *col;
1290 else if (pilot_isDisabled(p) || pilot_isFlag(p,PILOT_DEAD))
1311 if (p->target ==
id)
1323 p->nav_asteroid = -1;
1339 const Damage *dmg,
const Outfit *outfit,
int lua_mem,
int reset )
1342 double damage_shield, damage_armour, disable, knockback, dam_mod, ddmg, ddis, absorb, dmod, start;
1343 double tdshield, tdarmour;
1346 if (pilot_isFlag( p, PILOT_INVINCIBLE ) ||
1347 pilot_isFlag( p, PILOT_HIDE ) ||
1348 ((pshooter!=NULL) && pilot_isWithPlayer(pshooter) && pilot_isFlag( p, PILOT_INVINC_PLAYER )))
1355 shooter = (pshooter==NULL) ? 0 : pshooter->
id;
1360 dtype_calcDamage( &damage_shield, &damage_armour, absorb, &knockback, dmg, &p->stats );
1366 if (!pilot_isFlag(p, PILOT_DEAD) && (p->dtimer_accum > 0.))
1367 p->dtimer_accum -=
MIN( pow(disable, 0.8), p->dtimer_accum );
1370 if (pilot_isFlag( p, PILOT_NODISABLE )) {
1371 damage_armour += disable * absorb;
1382 if (p->shield - damage_shield > 0.) {
1384 ddmg = damage_shield;
1385 p->shield -= damage_shield;
1386 dam_mod = damage_shield/p->shield_max;
1399 ddis = disable * (0.5 + (0.5 - ((start+p->shield) / p->shield_max) / 4.));
1403 tdshield = damage_shield;
1408 else if (p->shield > 0.) {
1410 dmod = (1. - p->shield/damage_shield);
1411 ddmg = p->shield + dmod * damage_armour;
1412 tdshield = p->shield;
1416 ddis = disable * (1. - dmod) * (0.5 + (0.5 - (start / p->shield_max / 4.)));
1421 tdarmour = dmod * damage_armour;
1422 p->armour -= tdarmour;
1423 p->stress += dmod * disable;
1424 dam_mod = (damage_shield + damage_armour) /
1425 ((p->shield_max + p->armour_max) / 2.);
1436 else if (p->armour > 0.) {
1437 ddmg = damage_armour;
1440 p->armour -= damage_armour;
1455 if ((p->armour <= 0.) && pilot_isFlag( p, PILOT_NODEATH )) {
1461 if (pilot_isFlag( p, PILOT_DISABLED_PERM ))
1462 p->stress = p->armour;
1465 if (p->shield <= 0.) {
1466 if (p->id == PLAYER_ID) {
1467 double spfx_mod = tdarmour/p->armour_max;
1474 if (p->id == PLAYER_ID) {
1481 else if ((pshooter!=NULL) && pilot_isWithPlayer(pshooter)) {
1491 vec2_cadd( &p->solid.vel,
1492 knockback * (w->vel.x * (dam_mod/9. + w->mass/p->solid.mass/6.)),
1493 knockback * (w->vel.y * (dam_mod/9. + w->mass/p->solid.mass/6.)) );
1496 if ((outfit!=NULL) && (outfit->
lua_onimpact != LUA_NOREF)) {
1497 lua_rawgeti(naevL, LUA_REGISTRYINDEX, lua_mem);
1498 nlua_setenv(naevL, outfit->
lua_env,
"mem");
1501 lua_rawgeti(naevL, LUA_REGISTRYINDEX, outfit->
lua_onimpact);
1507 if (nlua_pcall( outfit->
lua_env, 5, 0 )) {
1508 WARN( _(
"Pilot '%s''s outfit '%s' -> '%s':\n%s"), p->name, outfit->
name,
"onimpact", lua_tostring(naevL,-1) );
1520 if (p->armour <= 0.) {
1523 if (!pilot_isFlag(p, PILOT_DEAD)) {
1527 if ((pshooter != NULL) && pilot_isWithPlayer(pshooter)) {
1529 int mod = 2. * (pow(p->base_mass, 0.4) - 1.);
1552 if ((!pilot_isFlag(p, PILOT_DISABLED)) &&
1553 (!pilot_isFlag(p, PILOT_NODISABLE) || (p->armour <= 0.)) &&
1554 (p->armour <= p->stress)) {
1558 if (pilot_isFlag(p, PILOT_COOLDOWN))
1562 pilot_rmFlag(p, PILOT_COOLDOWN_BRAKE);
1563 pilot_rmFlag(p, PILOT_BRAKING);
1564 pilot_rmFlag(p, PILOT_STEALTH);
1567 pilot_rmFlag(p, PILOT_HYP_PREP);
1568 pilot_rmFlag(p, PILOT_HYP_BEGIN);
1569 pilot_rmFlag(p, PILOT_HYP_BRAKE);
1570 pilot_rmFlag(p, PILOT_HYPERSPACE);
1573 if (p->presence > 0) {
1582 p->dtimer = 8. * pow( p->solid.mass, 1./3. );
1583 p->dtimer_accum = 0.;
1589 pilot_setFlag( p, PILOT_DISABLED );
1590 if (pilot_isPlayer( p ))
1595 hparam.
type = HOOK_PARAM_PILOT;
1596 hparam.
u.
lp = shooter;
1599 hparam.
type = HOOK_PARAM_NIL;
1601 pilot_runHookParam( p, PILOT_HOOK_DISABLE, &hparam, 1 );
1603 else if (pilot_isFlag(p, PILOT_DISABLED) && (p->armour > p->stress)) {
1604 pilot_rmFlag( p, PILOT_DISABLED );
1605 pilot_rmFlag( p, PILOT_DISABLED_PERM );
1606 pilot_rmFlag( p, PILOT_BOARDING );
1609 p->dtimer_accum = 0.;
1615 if (pilot_isPlayer(p)) {
1617 player_message(
"#g%s",_(
"You have recovered control of your ship!"));
1632 if (pilot_isFlag(p,PILOT_DEAD))
1636 if (p->id==PLAYER_ID) {
1637 pilot_setFlag(p, PILOT_DISABLED );
1641 p->ptimer =
MIN( 1. + sqrt(p->armour_max * p->shield_max) / 650.,
1642 3 + pow(p->armour_max * p->shield_max, 0.4) / 500);
1646 pilot_rmFlag(p,PILOT_HYP_PREP);
1647 pilot_rmFlag(p,PILOT_HYP_BEGIN);
1648 pilot_rmFlag(p,PILOT_HYP_BRAKE);
1649 pilot_rmFlag(p,PILOT_HYPERSPACE);
1656 hparam.
type = HOOK_PARAM_PILOT;
1657 hparam.
u.
lp = killer;
1660 hparam.
type = HOOK_PARAM_NIL;
1661 pilot_runHookParam( p, PILOT_HOOK_DEATH, &hparam, 1 );
1664 if (p->armour <= 0.) {
1665 if (p->parent == PLAYER_ID)
1666 player_message( _(
"#rShip under command '%s' was destroyed!#0"), p->name );
1668 pilot_setFlag( p, PILOT_DEAD );
1691 rad2 = radius*radius;
1697 qt = pilot_collideQuery( qx-qr, qy-qr, qx+qr, qy+qr );
1698 for (
int i=0; i<il_size(qt); i++) {
1700 double rx, ry, dist;
1703 rx = p->solid.pos.x - x;
1704 ry = p->solid.pos.y - y;
1707 dist -=
pow2(p->ship->gfx_space->sw);
1723 pilot_hit( p, &s, parent, &ddmg, NULL, LUA_NOREF, 1 );
1726 if (p->id == PILOT_PLAYER)
1741 glColour
c = { 1., 1., 1., 1. };
1744 if (!pilot_isPlayer(p) && pilot_isFlag(p, PILOT_STEALTH))
1747 glBindFramebuffer( GL_FRAMEBUFFER, fbo );
1748 glClearColor( 0., 0., 0., 0. );
1750 if (p->ship->gfx_3d != NULL) {
1751 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1759 glClear( GL_COLOR_BUFFER_BIT );
1761 sa = p->ship->gfx_space;
1762 sb = p->ship->gfx_engine;
1765 tx = sa->
sw*(double)(p->tsx)/sa->
w;
1766 ty = sa->
sh*(sa->
sy-(double)p->tsy-1)/sa->
h;
1768 tmpm = gl_view_matrix;
1769 gl_view_matrix =
mat4_ortho( 0., fw, 0, fh, -1., 1. );
1772 1.-p->engine_glow, 0., 0., sa->
sw, sa->
sh,
1773 tx, ty, sa->
srw, sa->
srh, &
c );
1775 gl_view_matrix = tmpm;
1779 glClearColor( 0., 0., 0., 1. );
1795 double timeleft, elapsed;
1799 w = p->ship->gfx_space->sw;
1800 h = p->ship->gfx_space->sh;
1804 for (
int i=0; i<
array_size(p->effects); i++) {
1806 Effect *eiter = &p->effects[i];
1807 if (eiter->
data->program==0)
1812 timeleft = e->
timer;
1826 mat4 projection, tex_mat;
1832 glBindFramebuffer( GL_FRAMEBUFFER, fbo );
1834 glClearColor( 0., 0., 0., 0. );
1835 glClear( GL_COLOR_BUFFER_BIT );
1837 glUseProgram( ed->program );
1839 glActiveTexture( GL_TEXTURE0 );
1841 glUniform1i( ed->u_tex, 0 );
1843 glEnableVertexAttribArray( ed->vertex );
1846 projection =
mat4_ortho( 0., fw, 0, fh, -1., 1. );
1848 gl_uniformMat4(ed->projection, &projection);
1852 gl_uniformMat4(ed->tex_mat, &tex_mat);
1854 glUniform3f( ed->dimensions, SCREEN_W, SCREEN_H, 1. );
1855 glUniform1f( ed->u_timer, timeleft );
1856 glUniform1f( ed->u_elapsed, elapsed );
1857 glUniform1f( ed->u_r, e->
r );
1858 glUniform1f( ed->u_dir, p->solid.dir );
1861 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
1864 glDisableVertexAttribArray( ed->vertex );
1867 glClearColor( 0., 0., 0., 1. );
1878 double scale, x,y, w,h, z;
1879 double timeleft, elapsed;
1882 glColour
c = {.r=1., .g=1., .b=1., .a=1.};
1885 if (pilot_isFlag( p, PILOT_NORENDER ))
1890 w = p->ship->gfx_space->sw;
1891 h = p->ship->gfx_space->sh;
1895 if ((x < -w) || (x > SCREEN_W+w) ||
1896 (y < -h) || (y > SCREEN_H+h))
1901 for (
int i=0; i<
array_size(p->effects); i++) {
1903 Effect *eiter = &p->effects[i];
1904 if (eiter->
data->program==0)
1909 timeleft = e->
timer;
1919 if (pilot_isFlag( p, PILOT_LANDING ))
1920 scale =
CLAMP( 0., 1., p->ptimer / p->landing_delay );
1921 else if (pilot_isFlag( p, PILOT_TAKEOFF ))
1922 scale =
CLAMP( 0., 1., 1. - p->ptimer / p->landing_delay );
1927 if (!pilot_isPlayer(p) && pilot_isFlag(p, PILOT_STEALTH))
1932 if (p->ship->gfx_3d != NULL) {
1934 object_renderSolidPart(p->ship->gfx_3d, &p->solid,
"body",
c.a, p->ship->gfx_3d_scale * scale);
1935 object_renderSolidPart(p->ship->gfx_3d, &p->solid,
"engine",
c.a * p->engine_glow, p->ship->gfx_3d_scale * scale);
1939 1.-p->engine_glow, p->solid.pos.x, p->solid.pos.y,
1940 scale, scale, p->tsx, p->tsy, &
c );
1945 mat4 projection, tex_mat;
1951 glUseProgram( ed->program );
1953 glActiveTexture( GL_TEXTURE0 );
1955 glUniform1i( ed->u_tex, 0 );
1957 glEnableVertexAttribArray( ed->vertex );
1960 projection = gl_view_matrix;
1961 mat4_translate( &projection, x + (1.-scale)*z*w/2., y + (1.-scale)*z*h/2., 0. );
1962 mat4_scale( &projection, scale*z*w, scale*z*h, 1. );
1963 gl_uniformMat4(ed->projection, &projection);
1967 gl_uniformMat4(ed->tex_mat, &tex_mat);
1969 glUniform3f( ed->dimensions, SCREEN_W, SCREEN_H,
cam_getZoom() );
1970 glUniform1f( ed->u_timer, timeleft );
1971 glUniform1f( ed->u_elapsed, elapsed );
1972 glUniform1f( ed->u_r, e->
r );
1973 glUniform1f( ed->u_dir, p->solid.dir );
1976 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
1979 glDisableVertexAttribArray( ed->vertex );
1984 double dircos, dirsin;
1985 int debug_mark_emitter = debug_isFlag(DEBUG_MARK_EMITTER);
1987 if (debug_mark_emitter) {
1988 dircos = cos(p->solid.dir);
1989 dirsin = sin(p->solid.dir);
1994 for (
int i=0,g=0; g<
array_size(p->ship->trail_emitters); g++) {
1996 if (debug_mark_emitter) {
1998 v.x = p->ship->trail_emitters[g].x_engine * dircos -
1999 p->ship->trail_emitters[g].y_engine * dirsin;
2000 v.y = p->ship->trail_emitters[g].x_engine * dirsin +
2001 p->ship->trail_emitters[g].y_engine * dircos +
2002 p->ship->trail_emitters[g].h_engine;
2005 p->solid.pos.y + v.y*M_SQRT1_2 );
2006 if (p->ship->trail_emitters[i].trail_spec->nebula)
2014 if (p->trail[i]->ontop)
2031 if (pilot_isFlag( p, PILOT_NORENDER ))
2034 playerdead = (player_isFlag(PLAYER_DESTROYED) || (
player.
p==NULL));
2037 if (!playerdead && pilot_isFlag( p, PILOT_HAILING )) {
2039 if (ico_hail != NULL) {
2040 int sx = (int)ico_hail->
sx;
2044 p->solid.pos.x + PILOT_SIZE_APPROX*p->ship->gfx_space->sw/2. + ico_hail->
sw/4.,
2045 p->solid.pos.y + PILOT_SIZE_APPROX*p->ship->gfx_space->sh/2. + ico_hail->
sh/4.,
2046 p->hail_pos % sx, p->hail_pos / sx, NULL );
2051 if (p->comm_msg != NULL) {
2052 double x, y, dx, dy;
2058 glColour
c = {1., 1., 1., 1.};
2065 dx = x - p->comm_msgWidth/2.;
2066 dy = y + PILOT_SIZE_APPROX*p->ship->gfx_space->sh/2.;
2076 if (conf.
healthbars && !playerdead && !pilot_isPlayer(p) && !pilot_isFlag(p, PILOT_DEAD) && !pilot_isDisabled(p) &&
2077 (pilot_isFlag(p, PILOT_COMBAT) || (p->shield < p->shield_max))) {
2083 w = p->ship->gfx_space->sw + 4.;
2084 h = p->ship->gfx_space->sh + 4.;
2087 if ((x < -w) || (x > SCREEN_W+w) ||
2088 (y < -h) || (y > SCREEN_H+h))
2091 w = PILOT_SIZE_APPROX * p->ship->gfx_space->sw;
2092 h = PILOT_SIZE_APPROX * p->ship->gfx_space->sh / 3.;
2094 glUseProgram( shaders.healthbar.program );
2095 glUniform2f( shaders.healthbar.dimensions, 5., h );
2096 glUniform1f( shaders.healthbar.paramf, (p->armour + p->shield) / (p->armour_max + p->shield_max) );
2097 gl_uniformColour( shaders.healthbar.paramv, (p->shield > 0.) ? &cShield : &cArmour );
2112 double a, px,py, vx,vy;
2120 cooling = pilot_isFlag(pilot, PILOT_COOLDOWN);
2129 if (pilot->
ctimer < 0.) {
2137 for (
int i=0; i<MAX_AI_TIMERS; i++)
2138 if (pilot->
timer[i] > 0.)
2139 pilot->
timer[i] -= dt;
2147 if (pilot_isFlag( pilot, PILOT_HAILING )) {
2149 if (ico_hail != NULL) {
2152 sx = (int)ico_hail->
sx;
2153 sy = (int)ico_hail->
sy;
2154 if (pilot->
htimer < 0.) {
2183 double ammo_threshold, reload_time;
2200 if (o->
rtimer < reload_time)
2207 while ((o->
rtimer >= reload_time) &&
2209 o->
rtimer -= reload_time;
2220 if (o->
state == PILOT_OUTFIT_ON) {
2224 else if (o->
state == PILOT_OUTFIT_COOLDOWN) {
2225 o->
state = PILOT_OUTFIT_OFF;
2249 if (!pilot_isFlag(pilot, PILOT_DISABLED)) {
2250 double stress_falloff = 0.3*sqrt(pilot->
solid.
mass);
2254 else if (!pilot_isFlag(pilot, PILOT_DISABLED_PERM)) {
2270 pilot_hit( pilot, NULL, NULL, &dmg, NULL, LUA_NOREF, 0 );
2274 if (pilot_isFlag(pilot,PILOT_TAKEOFF)) {
2275 if (pilot->
ptimer < 0.) {
2276 pilot_rmFlag(pilot,PILOT_TAKEOFF);
2277 if (pilot_isFlag(pilot, PILOT_PLAYER)) {
2278 pilot_setFlag(pilot, PILOT_NONTARGETABLE);
2279 pilot->
itimer = PILOT_PLAYER_NONTARGETABLE_TAKEOFF_DELAY;
2284 else if (pilot_isFlag(pilot,PILOT_LANDING)) {
2285 if (pilot->
ptimer < 0.) {
2286 if (pilot_isPlayer(pilot)) {
2287 player_setFlag( PLAYER_HOOK_LAND );
2296 else if (pilot_isFlag(pilot,PILOT_DEAD)) {
2304 if (!pilot_isFlag(pilot,PILOT_DEATH_SOUND) &&
2305 (pilot->
ptimer < 0.050)) {
2309 snprintf( buf,
sizeof(buf),
"explosion%d", RNG(0,2) );
2313 pilot_setFlag(pilot,PILOT_DEATH_SOUND);
2316 else if (!pilot_isFlag(pilot,PILOT_EXPLODED) &&
2317 (pilot->
ptimer < 0.200)) {
2323 dmg.
damage =
MAX(0., 2. * (a * (1. + sqrt(pilot->
fuel + 1.) / 28.)));
2328 pilot->
ship->
gfx_space->
sw/2./PILOT_SIZE_APPROX + a, &dmg, NULL, EXPL_MODE_SHIP );
2332 pilot_setFlag(pilot,PILOT_EXPLODED);
2336 if (pilot_isFlag(pilot, PILOT_EXPLODED)) {
2344 else if (pilot->
timer[1] <= 0.) {
2358 l = (pilot->
id==PLAYER_ID) ? SPFX_LAYER_FRONT : SPFX_LAYER_MIDDLE;
2366 if (pilot_isFlag(pilot,PILOT_DEAD) && (pilot->
ptimer < 0.)) {
2367 if (pilot->
id==PLAYER_ID)
2374 else if (pilot_isFlag(pilot, PILOT_NONTARGETABLE)) {
2377 pilot_rmFlag(pilot, PILOT_NONTARGETABLE);
2379 else if (pilot->
armour <= 0.) {
2380 if (pilot_isFlag( pilot, PILOT_NODEATH ))
2387 if (pilot_isFlag(pilot, PILOT_BRAKING )) {
2389 if (pilot_isFlag(pilot, PILOT_COOLDOWN_BRAKE))
2397 if (VMOD(pilot->
solid.
vel) < 1e-1) {
2399 pilot_rmFlag(pilot, PILOT_BRAKING);
2406 if (!pilot_isDisabled(pilot)) {
2415 if (pilot->
stimer <= 0.) {
2443 else if (pilot->
energy < 0.) {
2454 if (pilot_isFlag( pilot, PILOT_DELETE ))
2462 if (pilot_isDisabled(pilot) || cooling) {
2489 while (pilot->
otimer >= PILOT_OUTFIT_LUA_UPDATE_DT) {
2491 if (pilot_isFlag( pilot, PILOT_DELETE ))
2493 pilot->
otimer -= PILOT_OUTFIT_LUA_UPDATE_DT;
2505 if (pilot_isFlag(pilot, PILOT_REFUELBOARDING))
2509 if (pilot_isFlag(pilot, PILOT_BOARDING)) {
2511 pilot_rmFlag(pilot, PILOT_BOARDING);
2525 if (!pilot_isFlag(pilot, PILOT_HYPERSPACE)) {
2528 if (pilot_isFlag(pilot, PILOT_AFTERBURNER)) {
2538 double efficiency, accel;
2540 if (pilot->
id == PLAYER_ID)
2587 while (pilot->
otimer >= PILOT_OUTFIT_LUA_UPDATE_DT) {
2589 if (pilot_isFlag( pilot, PILOT_DELETE ))
2591 pilot->
otimer -= PILOT_OUTFIT_LUA_UPDATE_DT;
2603 double d2, cx, cy, dircos, dirsin;
2611 if (p->trail == NULL)
2616 d2 =
pow2(cx-p->solid.pos.x) +
pow2(cy-p->solid.pos.y);
2620 dircos = cos(p->solid.dir);
2621 dirsin = sin(p->solid.dir);
2627 if (pilot_isFlag(p, PILOT_HYPERSPACE) || pilot_isFlag(p, PILOT_HYP_END))
2628 mode = MODE_JUMPING;
2629 else if (pilot_isFlag(p, PILOT_AFTERBURNER))
2630 mode = MODE_AFTERBURN;
2631 else if (p->engine_glow > 0.)
2638 for (
int i=0, g=0; g<
array_size(p->ship->trail_emitters); g++) {
2640 double dx, dy, scale;
2645 p->trail[i]->ontop = 0;
2648 double prod = (trail_front( p->trail[i] ).x - p->solid.pos.x) * dircos +
2649 (trail_front( p->trail[i] ).y - p->solid.pos.y) * dirsin;
2651 p->trail[i]->ontop = (prod < 0);
2660 if (pilot_isFlag( p, PILOT_LANDING ))
2661 scale =
CLAMP( 0., 1., p->ptimer / p->landing_delay );
2662 else if (pilot_isFlag( p, PILOT_TAKEOFF ))
2663 scale =
CLAMP( 0., 1., 1. - p->ptimer / p->landing_delay );
2670 spfx_trail_sample( p->trail[i++], p->solid.pos.x + dx, p->solid.pos.y + dy*M_SQRT1_2, mode, mode==MODE_NONE );
2679 return !p->ship->trail_emitters[generator].trail_spec->nebula ||
cur_system->nebu_density>0;
2692 if (pilot_isFlag( p, PILOT_DELETE ))
2703 if (p->parent != 0) {
2710 if (p->presence > 0) {
2717 if (dockslot != NULL) {
2724 pilot_setFlag(p, PILOT_DELETE);
2741 if (pilot_isFlag(p, PILOT_HYPERSPACE)) {
2744 if ((p->id == PLAYER_ID) &&
2746 (p->timer[0] == -1.)) {
2752 if (p->ptimer < 0.) {
2753 pilot_setFlag( p, PILOT_HYP_END );
2755 if (p->id == PLAYER_ID)
2756 player_setFlag( PLAYER_HOOK_HYPER );
2758 hparam.
type = HOOK_PARAM_JUMP;
2763 pilot_runHookParam( p, PILOT_HOOK_JUMP, &hparam, 1 );
2774 else if (pilot_isFlag(p, PILOT_HYP_BEGIN)) {
2781 if (pilot_isPlayer(p))
2782 if (!player_isFlag(PLAYER_AUTONAV))
2783 player_message(
"#r%s", _(
"Strayed too far from jump point: jump aborted.") );
2785 else if (pilot_isFlag(p,PILOT_AFTERBURNER)) {
2788 if (pilot_isPlayer(p))
2789 if (!player_isFlag(PLAYER_AUTONAV))
2790 player_message(
"#r%s", _(
"Afterburner active: jump aborted.") );
2793 if (p->ptimer < 0.) {
2794 p->ptimer = HYPERSPACE_FLY_DELAY * p->stats.jump_delay;
2795 pilot_setFlag(p, PILOT_HYPERSPACE);
2796 if (p->id == PLAYER_ID)
2808 if (pilot_isPlayer(p))
2809 if (!player_isFlag(PLAYER_AUTONAV))
2810 player_message(
"#r%s", _(
"Strayed too far from jump point: jump aborted.") );
2814 if (!p->stats.misc_instant_jump &&
2815 !pilot_isFlag(p, PILOT_HYP_BRAKE) && !pilot_isStopped(p))
2820 pilot_setFlag( p, PILOT_HYP_BRAKE );
2824 sys =
cur_system->jumps[p->nav_hyperspace].target;
2828 if (
ABS(diff) < MIN_DIR_ERR) {
2829 if (jp_isFlag( &
cur_system->jumps[p->nav_hyperspace], JP_EXITONLY )) {
2830 WARN( _(
"Pilot '%s' trying to jump through exit-only jump from '%s' to '%s'"),
2835 p->ptimer = HYPERSPACE_ENGINE_DELAY * p->stats.jump_warmup * !p->stats.misc_instant_jump;
2836 pilot_setFlag(p, PILOT_HYP_BEGIN);
2838 if ((p->id == PLAYER_ID) && !p->stats.misc_instant_jump)
2846 if (pilot_isPlayer(p))
2859 if (pilot_isFlag(p, PILOT_HYPERSPACE))
2862 if (pilot_isFlag(p, PILOT_HYP_BEGIN)) {
2864 if (p->id == PLAYER_ID) {
2869 pilot_rmFlag(p, PILOT_HYP_BEGIN);
2870 pilot_rmFlag(p, PILOT_HYP_BRAKE);
2871 pilot_rmFlag(p, PILOT_HYP_PREP);
2874 for (
int i=0; i<
array_size(p->escorts); i++) {
2878 pilot_msg( p, e,
"hyperspace_abort", 0 );
2891 if (target == NULL) {
2892 pilot_rmFlag(p, PILOT_REFUELING);
2897 if (vec2_dist(&p->solid.pos, &target->
solid.
pos) >
2900 else if (vec2_dist2( &p->solid.vel, &target->
solid.
vel ) >
pow2(MAX_HYPERSPACE_VEL))
2904 pilot_setFlag(p, PILOT_REFUELBOARDING);
2905 p->ptimer = PILOT_REFUEL_TIME;
2920 if (target == NULL) {
2921 pilot_rmFlag(p, PILOT_REFUELBOARDING);
2922 pilot_rmFlag(p, PILOT_REFUELING);
2930 if (p->ptimer < 0.) {
2932 double amount =
MIN( p->fuel, p->refuel_amount );
2935 target->
fuel += amount;
2937 pilot_rmFlag(p, PILOT_REFUELBOARDING);
2938 pilot_rmFlag(p, PILOT_REFUELING);
2950 int stu = (int)(NT_PERIOD_SECONDS * p->stats.jump_delay);
2976 for (
int i=0; i<
array_size(p->outfits); i++) {
2977 if (p->outfits[i]->outfit == o)
2994 return (amount <= p->credits);
3007 if (CREDITS_MAX - p->credits <= amount)
3008 p->credits = CREDITS_MAX;
3010 p->credits += amount;
3012 else if (amount < 0) {
3023 if ( (amount <= CREDITS_MIN) || (
ABS(amount) >= p->credits) )
3026 p->credits += amount;
3046 double dir,
const vec2* pos,
const vec2* vel,
3047 const PilotFlags flags,
unsigned int dockpilot,
int dockslot )
3054 memset( pilot, 0,
sizeof(
Pilot) );
3062 pilot->
parent = dockpilot;
3067 pilot->
name = strdup( (name==NULL) ? _(ship->
name) : name );
3073 solid_init( &pilot->
solid, ship->
mass, dir, pos, vel, SOLID_UPDATE_RK4 );
3086 for (
int i=0; i<3; i++) {
3088 for (
int j=0; j<
array_size(ship_list[i]); j++) {
3092 slot->
sslot = &ship_list[i][j];
3104 if (!pilot_isFlagRaw(flags, PILOT_NO_OUTFITS)) {
3138 if (!pilot_isFlagRaw(flags, PILOT_NO_OUTFITS)) {
3139 char message[STRMAX_SHORT];
3142 DEBUG( _(
"Pilot '%s' failed safety check: %s"), pilot->
name, message );
3152 pilot_copyFlagsRaw(pilot->
flags, flags);
3170 if (pilot_isFlagRaw( flags, PILOT_TAKEOFF )) {
3176 lua_newtable(naevL);
3177 pilot->
messages = luaL_ref(naevL, LUA_REGISTRYINDEX);
3188 for (
int i=PILOT_NOCLEAR+1; i<PILOT_FLAGS_MAX; i++)
3189 pilot->
flags[i] = 0;
3231 if (p->trail == NULL)
3234 for (
int g=0; g<n; g++)
3249 const double dir,
const vec2* pos,
const vec2* vel,
3250 const PilotFlags flags,
unsigned int dockpilot,
int dockslot )
3255 WARN(_(
"Unable to allocate memory"));
3263 pilot_init( p, ship, name, faction, dir, pos, vel, flags, dockpilot, dockslot );
3266 if (pilot_isFlagRaw(flags, PILOT_PLAYER)) {
3302 int faction, PilotFlags flags )
3306 WARN(_(
"Unable to allocate memory"));
3309 pilot_init( dyn, ship, name, faction, 0., NULL, NULL, flags, 0, 0 );
3324 pilot_clearFlagsRaw( &pf );
3325 pilot_setFlagRaw( pf, PILOT_NO_OUTFITS );
3328 dyn = malloc(
sizeof(
Pilot));
3330 WARN(_(
"Unable to allocate memory"));
3340 ref->solid.dir, &ref->solid.pos, &ref->solid.vel, pf, 0, 0 );
3343 for (
int i=0; i<
array_size(ref->outfits); i++)
3344 if (ref->outfits[i]->outfit != NULL)
3346 for (
int i=0; i<
array_size(ref->outfit_intrinsic); i++)
3361 pilot_setFlag( p, PILOT_NOFREE );
3374 WARN(_(
"Duplicate pilots on stack!"));
3411 after->
id = PLAYER_ID;
3422 pilot_setFlag( after, PILOT_PLAYER );
3423 pilot_setFlag( after, PILOT_NOFREE );
3445 JumpPoint **validJumpPoints;
3456 if (spob_hasService( pnt, SPOB_SERVICE_INHABITED ) &&
3469 const JumpPoint *jmp = &
cur_system->jumps[i];
3470 JumpPoint *target = jmp->returnJump;
3475 if (jp_isFlag( target, JP_EXITONLY ))
3484 if (jp_isFlag( jmp, JP_HIDDEN ) && !guerilla)
3505 vec2_pset ( vp, 1.5*
cur_system->radius, RNGF()*2*M_PI );
3509 if (jp_isFlag( jp->returnJump, JP_EXITONLY ))
3512 if (jp_isFlag( jp, JP_HIDDEN ))
3517 if (!guerilla &&
array_size(validJumpPoints)<=0) {
3520 if (jp_isFlag( jp->returnJump, JP_EXITONLY ))
3527 WARN(_(
"Creating pilot in system with no jumps nor spobs to take off from!"));
3535 chance = chance / (chance +
array_size(ind));
3538 if ((RNGF() <= chance) && (validJumpPoints != NULL))
3539 *jump = validJumpPoints[ RNG_BASE(0,
array_size(validJumpPoints)-1) ];
3573 if (pilot_isFlag( p, PILOT_NOFREE )) {
3583 ss_free( p->intrinsic_stats );
3590 for (
int i=0; i<
array_size(p->outfits); i++) {
3591 ss_free( p->outfits[i]->lua_stats );
3616 luaL_unref(naevL, p->messages, LUA_REGISTRYINDEX);
3619 memset( p, 0,
sizeof(
Pilot) );
3645 WARN(_(
"Trying to remove non-existent pilot '%s' from stack!"), p->name);
3698 int persist_count = 0;
3705 (persist && pilot_isFlag(p, PILOT_PERSIST)))
3716 if (!pilot_isFlag(
pilot_stack[i], PILOT_DELETE) &&
3718 (persist && pilot_isFlag(
pilot_stack[i], PILOT_PERSIST)))) {
3765 qt_create( &
pilot_quadtree, -r, -r, r, r, qt_max_elem, qt_depth );
3807 if (pilot_isFlag(p, PILOT_DELETE))
3815 int x, y, w2, h2, px, py;
3818 if (pilot_isFlag(p, PILOT_DELETE))
3822 if (pilot_isFlag(p, PILOT_HIDE))
3825 x = round(p->solid.pos.x);
3826 y = round(p->solid.pos.y);
3827 px = round(p->solid.pre.x);
3828 py = round(p->solid.pre.y);
3829 w2 = ceil(p->ship->gfx_space->sw * 0.5);
3830 h2 = ceil(p->ship->gfx_space->sh * 0.5);
3847 if (pilot_isFlag(p, PILOT_HIDE))
3851 if (pilot_isDisabled(p))
3853 if (pilot_isFlag(p,PILOT_DEAD))
3861 if (pilot_isFlag(p, PILOT_HYP_PREP)) {
3862 if (!pilot_isFlag(p, PILOT_HYPERSPACE))
3867 else if (pilot_isFlag(p, PILOT_HYP_END)) {
3868 if ((VMOD(p->solid.vel) < 2*solid_maxspeed( &p->solid, p->speed, p->accel) ) && (p->ptimer < 0.))
3869 pilot_rmFlag(p, PILOT_HYP_END);
3872 else if (!pilot_isFlag(p, PILOT_BOARDING) &&
3873 !pilot_isFlag(p, PILOT_REFUELBOARDING) &&
3875 !pilot_isFlag(p, PILOT_LANDING) &&
3876 !pilot_isFlag(p, PILOT_TAKEOFF) &&
3878 !pilot_isFlag(p, PILOT_HYP_END)) {
3879 if (pilot_isFlag(p, PILOT_PLAYER))
3891 if (pilot_isFlag(p, PILOT_DELETE))
3895 if (pilot_isFlag(p, PILOT_HIDE))
3899 if (pilot_isFlag( p, PILOT_PLAYER ))
3915 if (pilot_isFlag(p, PILOT_HIDE) || pilot_isFlag(p, PILOT_DELETE))
3918 if (!pilot_isFlag( p, PILOT_PLAYER ))
3932 if (pilot_isFlag(p, PILOT_HIDE) || pilot_isFlag(p, PILOT_DELETE))
3935 if (!pilot_isFlag( p, PILOT_PLAYER ))
3957 for (
int i=0; i<MAX_AI_TIMERS; i++)
3958 pilot->
timer[i] = 0.;
3964 if (o->
state != PILOT_OUTFIT_OFF) {
3965 o->
state = PILOT_OUTFIT_OFF;
3996 double shots, dps=0., eps=0.;
3997 for (
int i=0; i<
array_size(p->outfits); i++) {
3999 double mod_energy, mod_damage, mod_shots;
4000 const Outfit *o = p->outfits[i]->outfit;
4004 case OUTFIT_TYPE_BOLT:
4005 mod_energy = p->stats.fwd_energy;
4006 mod_damage = p->stats.fwd_damage;
4007 mod_shots = 1. / p->stats.fwd_firerate * (double)o->
u.
blt.
shots;
4009 case OUTFIT_TYPE_TURRET_BOLT:
4010 mod_energy = p->stats.tur_energy;
4011 mod_damage = p->stats.tur_damage;
4012 mod_shots = 1. / p->stats.tur_firerate * (double)o->
u.
blt.
shots;
4014 case OUTFIT_TYPE_LAUNCHER:
4015 case OUTFIT_TYPE_TURRET_LAUNCHER:
4017 mod_damage = p->stats.launch_damage;
4018 mod_shots = 1. / p->stats.launch_rate * (double)o->
u.
lau.
shots;
4020 case OUTFIT_TYPE_BEAM:
4021 case OUTFIT_TYPE_TURRET_BEAM:
4023 if (o->
type == OUTFIT_TYPE_BEAM) {
4024 mod_energy = p->stats.fwd_energy;
4025 mod_damage = p->stats.fwd_damage;
4026 mod_shots = 1. / p->stats.fwd_firerate;
4029 mod_energy = p->stats.tur_energy;
4030 mod_damage = p->stats.tur_damage;
4031 mod_shots = 1. / p->stats.tur_firerate;
4034 mod_shots = shots / (shots + mod_shots *
outfit_delay(o));
4045 dps += shots * mod_damage * dmg->
damage;
4063 double DPSaccum_target, DPSaccum_pilot;
4068 if ((DPSaccum_target > 1e-6) && (DPSaccum_pilot > 1e-6))
4069 return DPSaccum_pilot / (DPSaccum_target + DPSaccum_pilot);
4070 else if (DPSaccum_pilot > 0.)
4085 double p_hp = p -> armour_max + p -> shield_max;
4086 return c_hp / (p_hp + c_hp);
4100 for (
int i=0; i<
array_size(p->outfits); i++) {
4101 if (p->outfits[i]->outfit == NULL)
4104 if (!count_unique && outfit_isProp(p->outfits[i]->outfit, OUTFIT_PROP_UNIQUE))
4106 price += p->outfits[i]->outfit->price;
4123 lua_pushvalue(naevL, idx);
4127 lua_newtable(naevL);
4131 lua_rawseti(naevL, -2, 1);
4134 lua_pushstring(naevL, type);
4135 lua_rawseti(naevL, -2, 2);
4137 lua_pushvalue(naevL, -2);
4138 lua_rawseti(naevL, -2, 3);
4140 lua_rawgeti(naevL, LUA_REGISTRYINDEX, receiver->
messages);
4141 lua_pushvalue(naevL, -2);
4142 lua_rawseti(naevL, -2, lua_objlen(naevL, -2)+1);
4156 for (
int i=0; i<
array_size(p->commodities); i++) {
4157 const Commodity *
c = p->commodities[i].commodity;
4162 for (
int i=0; i<
array_size(p->outfits); i++) {
4163 const Outfit *o = p->outfits[i]->outfit;
4179 qt_max_elem = max_elem;
void ai_cleartasks(Pilot *p)
Clears the pilot's tasks.
void ai_think(Pilot *pilot, double dt, int dotask)
Heart of the AI, brains of the pilot.
void ai_getDistress(const Pilot *p, const Pilot *distressed, const Pilot *attacker)
Sends a distress signal to a pilot.
void ai_destroy(Pilot *p)
Destroys the ai part of the pilot.
void ai_init(Pilot *p)
Initializes the AI.
int ai_pinit(Pilot *p, const char *ai)
Initializes the pilot in the ai.
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
#define array_end(array)
Returns a pointer to the end of the reserved memory space.
#define array_create_size(basic_type, capacity)
Creates a new dynamic array of ‘basic_type’ with an initial capacity.
#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_shrink(ptr_array)
Shrinks memory to fit only ‘size’ elements.
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
#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’.
void pilot_boardComplete(Pilot *p)
Finishes the boarding.
void cam_getPos(double *x, double *y)
Gets the camera position.
double cam_getZoom(void)
Gets the camera zoom.
int commodity_checkIllegal(const Commodity *com, int faction)
Checks to see if a commodity is illegal to a faction.
void dtype_calcDamage(double *dshield, double *darmour, double absorb, double *knockback, const Damage *dmg, const ShipStats *s)
Gives the real shield damage, armour damage and knockback modifier.
int dtype_get(const char *name)
Gets the id of a dtype based on name.
void debris_add(double mass, double r, double px, double py, double vx, double vy)
Creates a cloud of debris.
void effect_cleanup(Effect *efxlist)
Cleans up an effect list freeing it.
int effect_update(Effect **efxlist, double dt)
Updates an effect list.
void escort_rmList(Pilot *p, unsigned int id)
Remove from escorts list.
void escort_freeList(Pilot *p)
Remove all escorts from a pilot.
void expl_explode(double x, double y, double vx, double vy, double radius, const Damage *dmg, const Pilot *parent, int mode)
Does explosion in a radius (damage and graphics).
const char * faction_default_ai(int f)
Gets the name of the default AI profile for the faction's pilots.
const int * faction_getEnemies(int f)
Gets the list of enemies of a faction.
char faction_getColourChar(int f)
Gets the faction character associated to its standing with the player.
int areEnemies(int a, int b)
Checks whether two factions are enemies.
void faction_modPlayer(int f, double mod, const char *source)
Modifies the player's standing with a faction.
int areAllies(int a, int b)
Checks whether two factions are allies or not.
void gl_printRaw(const glFont *ft_font, double x, double y, const glColour *c, double outlineR, const char *text)
Prints text on screen.
int gl_printWidthRaw(const glFont *ft_font, const char *text)
Gets the width that it would take to print some text.
glTexture * gui_hailIcon(void)
Gets the hail icon texture.
int gui_onScreenPilot(double *rx, double *ry, const Pilot *pilot)
Takes a pilot and returns whether it's on screen, plus its relative position.
void gui_cooldownEnd(void)
Notifies GUI scripts that the player broke out of cooldown.
void player_message(const char *fmt,...)
Adds a mesg to the queue to be displayed on screen.
void lvar_freeArray(lvar *arr)
Frees a variable array.
void mat4_translate(mat4 *m, double x, double y, double z)
Translates a homogenous transformation matrix.
mat4 mat4_identity(void)
Creates an identity matrix.
void mat4_scale(mat4 *m, double x, double y, double z)
Scales a homogeneous transformation matrix.
mat4 mat4_ortho(double left, double right, double bottom, double top, double nearVal, double farVal)
Creates an orthographic projection matrix.
Header file with generic functions and naev-specifics.
const Outfit ** lua_pushoutfit(lua_State *L, const Outfit *outfit)
Pushes a outfit on the stack.
LuaPilot * lua_pushpilot(lua_State *L, LuaPilot pilot)
Pushes a pilot on the stack.
vec2 * lua_pushvector(lua_State *L, vec2 vec)
Pushes a vector on the stack.
ntime_t ntime_create(int scu, int stp, int stu)
Creates a time structure.
void gl_renderShader(double x, double y, double w, double h, double r, const SimpleShader *shd, const glColour *c, int center)
Renders a simple shader.
void gl_renderRect(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
void gl_gameToScreenCoords(double *nx, double *ny, double bx, double by)
Converts in-game coordinates to screen coordinates.
void gl_renderTextureInterpolate(const glTexture *ta, const glTexture *tb, double inter, double x, double y, double w, double h, double tx, double ty, double tw, double th, const glColour *c)
Texture blitting backend for interpolated texture.
void gl_renderSprite(const glTexture *sprite, double bx, double by, int sx, int sy, const glColour *c)
Blits a sprite, position is relative to the player.
void gl_renderCross(double x, double y, double r, const glColour *c)
Renders a cross at a given position.
void gl_renderSpriteInterpolateScale(const glTexture *sa, const glTexture *sb, double inter, double bx, double by, double scalew, double scaleh, int sx, int sy, const glColour *c)
Blits a sprite interpolating, position is relative to the player.
void gl_getSpriteFromDir(int *x, int *y, const glTexture *t, const double dir)
Sets x and y to be the appropriate sprite for glTexture using dir.
void gl_vboActivateAttribOffset(gl_vbo *vbo, GLuint index, GLuint offset, GLint size, GLenum type, GLsizei stride)
Activates a VBO's offset.
int outfit_isLauncher(const Outfit *o)
Checks if outfit is a weapon launcher.
int outfit_checkIllegal(const Outfit *o, int fct)
Checks illegality of an outfit to a faction.
int outfit_isFighterBay(const Outfit *o)
Checks if outfit is a fighter bay.
const Damage * outfit_damage(const Outfit *o)
Gets the outfit's damage.
double outfit_duration(const Outfit *o)
Gets the outfit's duration.
double outfit_energy(const Outfit *o)
Gets the outfit's energy usage.
double outfit_delay(const Outfit *o)
Gets the outfit's delay.
char pilot_getFactionColourChar(const Pilot *p)
Gets the faction colour char, works like faction_getColourChar but for a pilot.
void pilot_free(Pilot *p)
Frees and cleans up a pilot.
void pilot_stackRemove(Pilot *p)
Tries to remove a pilot from the stack.
static void pilot_hyperspace(Pilot *pilot, double dt)
Handles pilot's hyperspace states.
unsigned int pilot_getNearestEnemy_size(const Pilot *p, double target_mass_LB, double target_mass_UB)
Gets the nearest enemy to the pilot closest to the pilot whose mass is between LB and UB.
static int pilot_trail_generated(Pilot *p, int generator)
Return true if the given trail_emitters index has a corresponding generated trail.
void pilot_choosePoint(vec2 *vp, Spob **spob, JumpPoint **jump, int lf, int ignore_rules, int guerilla)
Finds a spawn point for a pilot.
int pilot_isHostile(const Pilot *p)
Checks to see if pilot is hostile to the player.
void pilot_updateDisable(Pilot *p, unsigned int shooter)
Handles pilot disabling. Set or unset the disable status depending on health and stress values.
void pilot_cooldown(Pilot *p, int dochecks)
Begins active cooldown, reducing hull and outfit temperatures.
static IntList pilot_qtquery
int pilot_brakeCheckReverseThrusters(const Pilot *p)
See if the pilot wants to use their reverse thrusters to brake.
void pilot_rmHostile(Pilot *p)
Unmarks a pilot as hostile to player.
unsigned int pilot_addStack(Pilot *p)
Adds a pilot to the stack.
void pilots_updatePurge(void)
Purges pilots set for deletion.
void pilot_quadtreeParams(int max_elem, int depth)
Sets the quad tree parameters. Can have significant impact on performance.
double pilot_relhp(const Pilot *cur_pilot, const Pilot *p)
Gets the relative hp(combined shields and armour) between the current pilot and the specified target.
int pilot_validEnemy(const Pilot *p, const Pilot *target)
Checks to see if a pilot is a valid enemy for another pilot.
double pilot_relsize(const Pilot *cur_pilot, const Pilot *p)
Gets the relative size(shipmass) between the current pilot and the specified target.
int pilot_areEnemies(const Pilot *p, const Pilot *target)
Like areEnemies but for pilots.
void pilots_clear(void)
Clears all the pilots except the player and clear-exempt pilots.
static const double pilot_commFade
unsigned int pilot_getNearestPilot(const Pilot *p)
Get the nearest pilot to a pilot.
void pilots_clean(int persist)
Cleans up the pilot stack - leaves the player.
Pilot * pilot_getTarget(Pilot *p)
Gets the target of a pilot using a fancy caching system.
Pilot * pilot_createEmpty(const Ship *ship, const char *name, int faction, PilotFlags flags)
Creates a pilot without adding it to the stack.
double pilot_face(Pilot *p, double dir, double dt)
Tries to turn the pilot to face dir.
double pilot_getNearestPos(const Pilot *p, unsigned int *tp, double x, double y, int disabled)
Get the nearest pilot to a pilot from a certain position.
void pilot_clearTimers(Pilot *pilot)
Clears the pilot's timers.
double pilot_reldps(const Pilot *cur_pilot, const Pilot *p)
Gets the relative damage output(total DPS) between the current pilot and the specified target.
static void pilot_renderFramebufferBase(Pilot *p, GLuint fbo, double fw, double fh)
Renders a pilot to a framebuffer without effects.
void pilot_msg(const Pilot *p, const Pilot *receiver, const char *type, unsigned int idx)
Sends a message.
void pilot_dead(Pilot *p, unsigned int killer)
Pilot is dead, now will slowly explode.
static int pilot_cmp(const void *ptr1, const void *ptr2)
Compare id (for use with bsearch)
Pilot * pilot_setPlayer(Pilot *after)
Replaces the player's pilot with an alternate ship with the same ID.
int pilot_validEnemyDist(const Pilot *p, const Pilot *target, double *dist)
Same as pilot_validEnemy, but able to store the distance too.
static void pilot_refuel(Pilot *p, double dt)
Has the pilot refuel its target.
void pilot_renderOverlay(Pilot *p)
Renders the pilot overlay.
void pilot_setAccel(Pilot *p, double accel)
Sets the pilot's accel.
static void pilot_erase(Pilot *p)
Destroys pilot from stack.
void pilot_cooldownEnd(Pilot *p, const char *reason)
Terminates active cooldown.
static void pilot_init(Pilot *dest, const Ship *ship, const char *name, int faction, const double dir, const vec2 *pos, const vec2 *vel, const PilotFlags flags, unsigned int dockpilot, int dockslot)
Initialize pilot.
static const double pilot_commTimeout
credits_t pilot_modCredits(Pilot *p, credits_t amount)
Modifies the amount of credits the pilot has.
unsigned int pilot_getNearestEnemy(const Pilot *p)
Gets the nearest enemy to the pilot.
void pilot_setFriendly(Pilot *p)
Marks pilot as friendly to player.
void pilot_hyperspaceAbort(Pilot *p)
Stops the pilot from hyperspacing.
void pilot_setTurn(Pilot *p, double turn)
Sets the pilot's turn.
int pilot_validTarget(const Pilot *p, const Pilot *target)
Checks to see if a pilot is a valid target for another pilot.
void pilot_explode(double x, double y, double radius, const Damage *dmg, const Pilot *parent)
Makes the pilot explosion.
void pilot_reset(Pilot *pilot)
Resets a pilot.
int pilot_isFriendly(const Pilot *p)
Checks to see if pilot is friendly to the player.
int pilot_refuelStart(Pilot *p)
Attempts to start refueling the pilot's target.
void pilots_renderOverlay(void)
Renders all the pilots overlays.
int pilot_isNeutral(const Pilot *p)
Checks to see if pilot is neutral to the player.
PilotOutfitSlot * pilot_getDockSlot(Pilot *p)
Gets the dock slot of the pilot.
void pilots_init(void)
Initializes pilot stuff.
int pilot_hasIllegal(const Pilot *p, int faction)
Checks to see if the pilot has illegal stuf to a faction.
void pilot_setCommMsg(Pilot *p, const char *s)
Sets the overhead communication message of the pilot.
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
ntime_t pilot_hyperspaceDelay(const Pilot *p)
Calculates the hyperspace delay for a pilot.
void pilot_broadcast(Pilot *p, const char *msg, int ignore_int)
Has the pilot broadcast a message.
void pilot_setHostile(Pilot *p)
Marks pilot as hostile to player.
double pilot_getNearestPosPilot(const Pilot *p, Pilot **tp, double x, double y, int disabled)
Get the nearest pilot to a pilot from a certain position.
void pilot_dpseps(const Pilot *p, double *pdps, double *peps)
Calculates the dps and eps of a pilot.
const glColour * pilot_getColour(const Pilot *p)
Gets a pilot's colour.
static Pilot ** pilot_stack
void pilot_distress(Pilot *p, Pilot *attacker, const char *msg)
Has the pilot broadcast a distress signal.
void pilot_render(Pilot *p)
Renders the pilot.
Pilot *const * pilot_getAll(void)
Gets the pilot stack.
int pilot_canTarget(const Pilot *p)
Same as pilot_validTarget but without the range check.
credits_t pilot_worth(const Pilot *p, int count_unique)
Gets the price or worth of a pilot in credits.
unsigned int pilot_getNearestEnemy_heuristic(const Pilot *p, double mass_factor, double health_factor, double damage_factor, double range_factor)
Gets the nearest enemy to the pilot closest to the pilot whose mass is between LB and UB.
static unsigned int pilot_id
double pilot_aimAngle(Pilot *p, const vec2 *pos, const vec2 *vel)
Returns the angle for a pilot to aim at another pilot.
void pilots_newSystem(void)
Updates pilot state which depends on the system (sensor range, nebula trails...)
unsigned int pilot_getNextID(unsigned int id, int mode)
Gets the next pilot based on id.
double pilot_minbrakedist(const Pilot *p, double dt)
Gets the minimum braking distance for the pilot.
void pilot_rmFriendly(Pilot *p)
Unmarks a pilot as friendly to player.
void pilots_render(void)
Renders all the pilots.
int pilot_areAllies(const Pilot *p, const Pilot *target)
Like areAllies but for pilots.
double pilot_getNearestAng(const Pilot *p, unsigned int *tp, double ang, int disabled)
Get the pilot closest to an angle extending from another pilot.
void pilot_untargetAsteroid(int anchor, int asteroid)
Loops over pilot stack to remove an asteroid as target.
int pilot_getJumps(const Pilot *p)
Gets the amount of jumps the pilot has left.
void pilot_delete(Pilot *p)
Deletes a pilot.
void pilots_update(double dt)
Updates all the pilots.
void pilots_cleanAll(void)
Even cleans up the player.
void pilot_clearTrails(Pilot *p)
Resets the trails for a pilot.
unsigned int pilot_getBoss(const Pilot *p)
Get the strongest ally in a given range.
static void pilot_init_trails(Pilot *p)
Initialize pilot's trails according to the ship type and current system characteristics.
void pilots_free(void)
Frees the pilot stack.
static Quadtree pilot_quadtree
double pilot_hit(Pilot *p, const Solid *w, const Pilot *pshooter, const Damage *dmg, const Outfit *outfit, int lua_mem, int reset)
Damages the pilot.
static int pilot_getStackPos(unsigned int id)
Gets the pilot's position in the stack.
void pilot_renderFramebuffer(Pilot *p, GLuint fbo, double fw, double fh)
Renders a pilot to a framebuffer.
void pilot_update(Pilot *pilot, double dt)
Updates the pilot.
Pilot * pilot_create(const Ship *ship, const char *name, int faction, const char *ai, const double dir, const vec2 *pos, const vec2 *vel, const PilotFlags flags, unsigned int dockpilot, int dockslot)
Creates a new pilot.
unsigned int pilot_getPrevID(unsigned int id, int mode)
Gets the previous pilot based on ID.
int pilot_numOutfit(const Pilot *p, const Outfit *o)
Checks to see how many of an outfit a pilot has.
void pilot_sample_trails(Pilot *p, int none)
Updates the given pilot's trail emissions.
int pilot_hasCredits(const Pilot *p, credits_t amount)
Checks to see if the pilot has at least a certain amount of credits.
int pilot_brake(Pilot *p, double dt)
Causes the pilot to turn around and brake.
void pilot_setTarget(Pilot *p, unsigned int id)
Sets the target of the pilot.
unsigned int pilot_clone(const Pilot *ref)
Clones an existing pilot.
int pilot_cargoRmAll(Pilot *pilot, int cleanup)
Gets rid of all cargo from pilot. Can remove mission cargo.
int pilot_cargoJet(Pilot *p, const Commodity *cargo, int quantity, int simulate)
Tries to get rid of quantity cargo from pilot, jetting it into space.
void pilot_ewUpdateStealth(Pilot *p, double dt)
Updates the stealth mode and checks to see if it is getting broken.
int pilot_inRangePilot(const Pilot *p, const Pilot *target, double *dist2)
Check to see if a pilot is in sensor range of another.
void pilot_ewUpdateDynamic(Pilot *p, double dt)
Updates the pilot's dynamic electronic warfare properties.
int pilot_inRangeSpob(const Pilot *p, int target)
Check to see if a spob is in sensor range of the pilot.
void pilot_updateSensorRange(void)
Updates the system's base sensor range.
void pilot_ewScanStart(Pilot *p)
Initializes the scan timer for a pilot.
double pilot_sensorRange(void)
Returns the default sensor range for the current system.
double pilot_heatEfficiencyMod(double T, double Tb, double Tc)
Returns a 0:1 modifier representing efficiency (1. being normal).
void pilot_heatUpdateCooldown(Pilot *p)
Overrides the usual heat model during active cooldown.
double pilot_heatFireRateMod(double T)
Returns a 0:1 modifier representing fire rate (1. being normal).
void pilot_heatReset(Pilot *p)
Resets a pilot's heat.
void pilot_heatUpdateShip(Pilot *p, double Q_cond, double dt)
Heats the pilot's ship.
double pilot_heatUpdateSlot(const Pilot *p, PilotOutfitSlot *o, double dt)
Heats the pilot's slot.
void pilot_heatAddSlotTime(const Pilot *p, PilotOutfitSlot *o, double dt)
Adds heat to an outfit slot over a period of time.
void pilots_clearGlobalHooks(void)
Removes all the pilot global hooks.
void pilot_clearHooks(Pilot *p)
Clears the pilots hooks.
void pilot_freeGlobalHooks(void)
Clears global pilot hooks.
int pilot_runHook(Pilot *p, int hook_type)
Tries to run a pilot hook if he has it.
int pilot_addOutfitIntrinsicRaw(Pilot *pilot, const Outfit *outfit)
Adds an outfit as an intrinsic slot.
void pilot_outfitLCooldown(Pilot *pilot, int done, int success, double timer)
Handle cooldown hooks for outfits.
void pilot_outfitLOutfofenergy(Pilot *pilot)
Handles when the pilot runs out of energy.
void pilot_healLanded(Pilot *pilot)
Cures the pilot as if he was landed.
void pilot_calcStats(Pilot *pilot)
Recalculates the pilot's stats based on his outfits.
void pilot_fillAmmo(Pilot *pilot)
Fills pilot's ammo completely.
int pilot_addAmmo(Pilot *pilot, PilotOutfitSlot *s, int quantity)
Adds some ammo to the pilot stock.
void pilot_lockClear(Pilot *p)
Clears pilot's missile lockon timers.
void pilot_outfitLCleanup(Pilot *pilot)
Handle cleanup hooks for outfits.
int pilot_reportSpaceworthy(const Pilot *p, char *buf, int bufSize)
Pilot safety report - makes sure stats are safe.
void pilot_lockUpdateSlot(Pilot *p, PilotOutfitSlot *o, Pilot *t, double *a, double dt)
Updates the lockons on the pilot's launchers.
void pilot_outfitLUpdate(Pilot *pilot, double dt)
Runs the pilot's Lua outfits update script.
int pilot_addOutfitRaw(Pilot *pilot, const Outfit *outfit, PilotOutfitSlot *s)
Adds an outfit to the pilot, ignoring CPU or other limits.
int pilot_addOutfitIntrinsic(Pilot *pilot, const Outfit *outfit)
Adds an outfit as an intrinsic slot.
void pilot_outfitLOnhit(Pilot *pilot, double armour, double shield, unsigned int attacker)
Runs the pilot's Lua outfits onhit script.
void pilot_outfitLInitAll(Pilot *pilot)
Runs the pilot's Lua outfits init script.
int pilot_shipLInit(Pilot *p)
Initializes the pilot ship Lua.
int pilot_shipLExplodeUpdate(Pilot *p, double dt)
Updates the pilot explosion Lua stuff.
int pilot_shipLUpdate(Pilot *p, double dt)
Updates the pilot Lua stuff.
int pilot_shipLCleanup(Pilot *p)
Cleans up the pilot ship Lua.
int pilot_shipLExplodeInit(Pilot *p)
Initializes the pilot explosion stuff.
void pilot_afterburnOver(Pilot *p)
Deactivates the afterburner.
void pilot_weapSetAIClear(Pilot *p)
Useful function for AI, clears activeness of all weapon sets.
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_weaponAuto(Pilot *p)
Tries to automatically set and create the pilot's weapon set.
void pilot_weapSetFree(Pilot *p)
Frees a pilot's weapon sets.
double pilot_weapSetSpeed(Pilot *p, int id, int level)
Gets the speed of the current pilot weapon set.
int pilot_outfitOff(Pilot *p, PilotOutfitSlot *o)
Disables a given active outfit.
void player_updateSpecific(Pilot *pplayer, const double dt)
Does a player specific update.
void player_dead(void)
Player got pwned.
void player_soundPlay(int sound, int once)
Plays a sound at the player.
void player_update(Pilot *pplayer, const double dt)
Player update function.
void player_soundStop(void)
Stops playing player sounds.
void player_think(Pilot *pplayer, const double dt)
Basically uses keyboard input instead of AI input. Used in pilot.c.
void player_destroyed(void)
Player blew up in a fireball.
void player_autonavResetSpeed(void)
Resets the game speed.
credits_t ship_basePrice(const Ship *s)
Gets the ship's base price (no outfits).
void ss_free(ShipStatList *ll)
Frees a list of ship stats.
double sound_getLength(int sound)
Gets the length of the sound buffer.
int sound_playPos(int sound, double px, double py, double vx, double vy)
Plays a sound based on position.
int sound_get(const char *name)
Gets the buffer to sound of name.
void system_rmCurrentPresence(StarSystem *sys, int faction, double amount)
Removes active presence.
int space_canHyperspace(const Pilot *p)
Checks to make sure if pilot is far enough away to hyperspace.
double system_getPresence(const StarSystem *sys, int faction)
Get the presence of a faction in a system.
int space_needsEffects(void)
returns whether or not we're simulating with effects.
int space_isSimulation(void)
returns whether we're just simulating.
void spfx_trail_sample(Trail_spfx *trail, double x, double y, TrailMode mode, int force)
Makes a trail grow.
void spfx_shake(double mod)
Increases the current rumble level.
int spfx_get(const char *name)
Gets the id of an spfx based on name.
void spfx_trail_remove(Trail_spfx *trail)
Removes a trail.
void spfx_add(int effect, const double px, const double py, const double vx, const double vy, int layer)
Creates a new special effect.
void spfx_damage(double mod)
Increases the current damage level.
Trail_spfx * spfx_trail_create(const TrailSpec *spec)
Initalizes a trail.
void spfx_trail_draw(const Trail_spfx *trail)
Draws a trail on screen.
Core damage that an outfit does.
The actual hook parameter.
A ship outfit, depends radically on the type.
OutfitAfterburnerData afb
const Commodity * commodity
Stores an outfit the pilot has.
The representation of an in-game pilot.
PilotCommodity * commodities
PilotOutfitSlot * outfit_structure
PilotOutfitSlot ** outfits
PilotOutfitSlot * outfit_utility
PilotOutfitSlot * outfit_intrinsic
double timer[MAX_AI_TIMERS]
unsigned int shoot_indicator
PilotOutfitSlot * afterburner
PilotOutfitSlot * outfit_weapon
unsigned int ships_destroyed[SHIP_CLASS_TOTAL]
unsigned int ships_destroyed[SHIP_CLASS_TOTAL]
double stress_dissipation
unsigned int always_under
ShipOutfitSlot * outfit_utility
Outfit const ** outfit_intrinsic
ShipOutfitSlot * outfit_weapon
ShipOutfitSlot * outfit_structure
Represents a solid in the game.
void(* update)(struct Solid_ *, double)
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
A trail generated by a ship or an ammo.
GLuint fbo_tex[OPENGL_NUM_FBOS]
GLuint fbo[OPENGL_NUM_FBOS]
Abstraction for rendering sprite sheets.