23#include "damagetype.h"
30#include "gatherable.h"
34#include "land_outfits.h"
35#include "land_shipyard.h"
39#include "nlua_pilotoutfit.h"
47#include "player_autonav.h"
51#define PILOT_SIZE_MIN 128
68 const double dir,
const vec2* pos,
const vec2* vel,
69 const PilotFlags flags,
unsigned int dockpilot,
int dockslot );
91static int pilot_cmp(
const void *ptr1,
const void *ptr2 )
94 p1 = *((
const Pilot**) ptr1);
95 p2 = *((
const Pilot**) ptr2);
96 return p1->
id - p2->
id;
107 const Pilot pid = { .
id =
id };
108 const Pilot *pidptr = &pid;
202 else if (mode == 1) {
246 if (pilot_isFlag( p, PILOT_DELETE ) ||
247 pilot_isFlag( p, PILOT_DEAD ))
251 if (pilot_isFlag( p, PILOT_HIDE ) ||
252 pilot_isFlag( p, PILOT_INVISIBLE))
277 if (pilot_isDisabled(target))
281 if (pilot_isFlag( target, PILOT_INVINCIBLE ))
285 if (pilot_isFlag( target, PILOT_LANDING) ||
286 pilot_isFlag( target, PILOT_TAKEOFF ) ||
287 pilot_isFlag( target, PILOT_NONTARGETABLE))
324 td = vec2_dist2(&
pilot_stack[i]->solid->pos, &p->solid->pos);
325 if (!tp || (td <
d)) {
356 td = vec2_dist2(&
pilot_stack[i]->solid->pos, &p->solid->pos);
357 if (!tp || (td <
d)) {
377 double mass_factor,
double health_factor,
378 double damage_factor,
double range_factor )
381 double current_heuristic_value = 10e3;
391 temp = range_factor *
392 vec2_dist2( &target->
solid->
pos, &p->solid->pos )
397 if ((tp == 0) || (temp < current_heuristic_value)) {
398 current_heuristic_value = temp;
428 double relpower, ppower;
438 double dx, dy, td, curpower;
454 p->solid->pos.x - 2*p->solid->vel.x;
456 p->solid->pos.y - 2*p->solid->vel.y;
471 if (ppower >= curpower )
474 if (relpower < curpower ) {
505 if (!disabled && pilot_isPlayer(p) &&
519 if (((*tp==PLAYER_ID) || (td <
d))) {
538 double a = ang + M_PI;
549 if (!disabled && pilot_isPlayer(p) &&
571 if (
ABS(angle_diff(ang, ta)) <
ABS(angle_diff(ang, a))) {
598 if ((m==-1) || (pilot_isFlag(
pilot_stack[m], PILOT_DELETE)))
612 if (p->target==p->id)
618 if (pilot_isFlag( t, PILOT_DELETE )) {
634 p->solid->thrust = p->thrust * thrust;
642 p->solid->dir_vel = p->turn * turn;
654 && !pilot_isFlag( p, PILOT_BRIBED )
655 && (pilot_isFlag( p, PILOT_HOSTILE ) ||
683 if (pilot_isFlag( p, PILOT_FRIENDLY) ||
684 (
areAllies( FACTION_PLAYER,p->faction) &&
685 !pilot_isFlag( p, PILOT_HOSTILE ) ) )
696 if (pilot_isWithPlayer(p)) {
699 else if (pilot_isFlag( target, PILOT_HOSTILE ))
702 else if (pilot_isWithPlayer(target)) {
705 else if (pilot_isFlag( p, PILOT_HOSTILE ))
720 if (pilot_isWithPlayer(p)) {
723 else if (pilot_isFlag( target, PILOT_FRIENDLY ))
725 else if (pilot_isFlag(target, PILOT_BRIBED))
728 if (pilot_isWithPlayer(target)) {
731 else if (pilot_isFlag( p, PILOT_FRIENDLY ))
733 else if (pilot_isFlag(p, PILOT_BRIBED))
753 if ((p->dockpilot != 0) && (p->dockslot != -1)) {
755 if (dockpilot != NULL)
756 return dockpilot->
outfits[p->dockslot];
775 double diff = angle_diff( p->solid->dir, dir );
776 double turn =
CLAMP( -1., 1., -10.*diff );
790 double dir, thrust, diff;
791 int isstopped = pilot_isStopped(p);
797 dir = VANGLE(p->solid->vel) + M_PI;
800 if (p->stats.misc_reverse_thrust) {
803 diff = angle_diff(p->solid->dir, VANGLE(p->solid->vel) + M_PI);
804 btime =
ABS(diff) / p->turn +
MIN( VMOD(p->solid->vel), p->speed ) /
805 (p->thrust / p->solid->mass);
808 diff = angle_diff(p->solid->dir, VANGLE(p->solid->vel));
809 ftime =
ABS(diff) / p->turn +
MIN( VMOD(p->solid->vel), p->speed ) /
810 (p->thrust / p->solid->mass * PILOT_REVERSE_THRUST);
813 dir = VANGLE(p->solid->vel);
814 thrust = -PILOT_REVERSE_THRUST;
819 if (
ABS(diff) < MAX_DIR_ERR && !isstopped)
839 double fdiff, bdiff, ftime, btime;
840 double vang, speed, dist;
842 if (pilot_isStopped(p)) {
844 *pos = p->solid->pos;
849 vang = VANGLE(p->solid->vel);
850 speed =
MIN( VMOD(p->solid->vel), p->speed );
853 bdiff = angle_diff(p->solid->dir, vang + M_PI);
854 btime =
ABS(bdiff) / p->turn + speed / (p->thrust / p->solid->mass);
855 dist = (
ABS(bdiff) / p->turn) * speed +
856 (speed / (p->thrust / p->solid->mass)) * (speed / 2.);
858 if (p->stats.misc_reverse_thrust) {
860 fdiff = angle_diff(p->solid->dir, vang);
861 ftime =
ABS(fdiff) / p->turn + speed /
862 (p->thrust / p->solid->mass * PILOT_REVERSE_THRUST);
866 dist = (
ABS(fdiff) / p->turn) * speed + (speed /
867 (p->thrust / p->solid->mass * PILOT_REVERSE_THRUST)) * (speed / 2.);
872 p->solid->pos.x + cos(vang) * dist,
873 p->solid->pos.y + sin(vang) * dist);
890 double px, py, target, face, diff, fdiff;
892 px = p->solid->pos.x;
893 py = p->solid->pos.y;
896 target = atan2( y - py, x - px );
899 diff = angle_diff( VANGLE(p->solid->vel), target );
901 if (
ABS(diff) < MIN_DIR_ERR) {
905 else if (
ABS(diff) > M_PI / 1.5) {
910 if (
FABS(fdiff) < M_PI)
917 else if (diff > M_PI_4)
918 face = target + M_PI_4;
919 else if (diff < -M_PI_4)
920 face = target - M_PI_4;
922 face = target + diff;
943 double heat_capacity, heat_mean;
946 if (dochecks && !pilot_isStopped(p)) {
947 pilot_setFlag(p, PILOT_BRAKING);
948 pilot_setFlag(p, PILOT_COOLDOWN_BRAKE);
952 pilot_rmFlag(p, PILOT_BRAKING);
953 pilot_rmFlag(p, PILOT_COOLDOWN_BRAKE);
956 if (p->id == PLAYER_ID)
964 heat_capacity = p->heat_C;
965 heat_mean = p->heat_T * p->heat_C;
966 for (
int i=0; i<
array_size(p->outfits); i++) {
969 heat_capacity += p->outfits[i]->heat_C;
974 heat_mean =
MAX( heat_mean, CONST_SPACE_STAR_TEMP );
976 heat_mean /= heat_capacity;
988 p->cdelay = (5. + sqrt(p->base_mass) / 2.) *
989 (1. + pow(
MAX(heat_mean / CONST_SPACE_STAR_TEMP - 1.,0.), 1.25));
990 p->ctimer = p->cdelay * p->stats.cooldown_time;
991 p->heat_start = p->heat_T;
992 pilot_setFlag(p, PILOT_COOLDOWN);
1006 if (pilot_isFlag(p, PILOT_COOLDOWN_BRAKE)) {
1007 pilot_rmFlag(p, PILOT_COOLDOWN_BRAKE);
1012 if (p->id == PLAYER_ID) {
1024 pilot_rmFlag(p, PILOT_COOLDOWN);
1027 if (p->ctimer < 0.) {
1048 vec2 tv, approach_vector, relative_location, orthoradial_vector;
1051 double radial_speed;
1052 double orthoradial_speed;
1055 dist = vec2_dist( &p->solid->pos, pos );
1070 vec2_cset(&approach_vector, VX(p->solid->vel) - VX(*vel), VY(p->solid->vel) - VY(*vel) );
1071 vec2_cset(&relative_location, VX(*pos) - VX(p->solid->pos), VY(*pos) - VY(p->solid->pos) );
1072 vec2_cset(&orthoradial_vector, VY(p->solid->pos) - VY(*pos), VX(*pos) - VX(p->solid->pos) );
1074 radial_speed = vec2_dot(&approach_vector, &relative_location);
1075 radial_speed = radial_speed / VMOD(relative_location);
1077 orthoradial_speed = vec2_dot(&approach_vector, &orthoradial_vector);
1078 orthoradial_speed = orthoradial_speed / VMOD(relative_location);
1083 if ( ((speed*speed - VMOD(approach_vector)*VMOD(approach_vector)) != 0) && (speed*speed - orthoradial_speed*orthoradial_speed) > 0)
1084 t = dist * (sqrt( speed*speed - orthoradial_speed*orthoradial_speed ) - radial_speed) /
1085 (speed*speed - VMOD(approach_vector)*VMOD(approach_vector));
1091 t = - dist * (sqrt( speed*speed - orthoradial_speed*orthoradial_speed ) + radial_speed) /
1092 (speed*speed - VMOD(approach_vector)*VMOD(approach_vector));
1099 x = pos->
x + vel->
x*t - (p->solid->pos.x + p->solid->vel.x*t);
1100 y = pos->
y + vel->
y*t - (p->solid->pos.y + p->solid->vel.y*t);
1101 vec2_cset( &tv, x, y );
1114 || !pilot_isFlag( p, PILOT_HOSTILE ))
1115 pilot_setFlag( p, PILOT_HOSTILE );
1117 pilot_rmFlag( p, PILOT_BRIBED );
1127 if (pilot_isDisabled(p))
1141 free( p->comm_msg );
1142 p->comm_msg = strdup( s );
1192 if (attacker == NULL)
1201 if (!pilot_isFlag(p, PILOT_DISTRESSED)) {
1204 if (spob_hasService(
cur_system->spobs[i], SPOB_SERVICE_INHABITED) &&
1218 if ((pi->
ai == NULL) || (pi->
id == p->id) ||
1219 (pilot_isFlag(pi, PILOT_DEAD)) ||
1220 (pilot_isFlag(pi, PILOT_DELETE)))
1228 d = vec2_dist2( &p->solid->pos, &pi->
solid->
pos );
1237 if (!pilot_isFlag(p, PILOT_DISTRESSED) &&
1243 if (!pilot_isFlag(p, PILOT_DISTRESSED)) {
1246 if (r && (attacker != NULL) && (pilot_isWithPlayer(attacker))) {
1248 WARN(_(
"Pilot '%s' does not have an AI!"), p->name);
1251 lua_rawgeti( naevL, LUA_REGISTRYINDEX, p->lua_mem );
1252 lua_getfield( naevL, -1,
"distress_hit" );
1253 if (lua_isnil(naevL,-1))
1254 hit = (pow(p->base_mass, 0.2) - 1.);
1255 else if (lua_isnumber(naevL,-1))
1256 hit = lua_tonumber(naevL,-1);
1258 WARN(_(
"Pilot '%s' has non-number mem.distress_hit!"),p->name);
1267 pilot_setFlag(p, PILOT_DISTRESSED);
1281 if (pilot_isFlag(p, PILOT_HOSTILE))
1282 pilot_rmFlag(p, PILOT_HOSTILE);
1285 if (
areEnemies( FACTION_PLAYER, p->faction ))
1286 pilot_setFlag(p, PILOT_BRIBED);
1297 pilot_setFlag(p, PILOT_FRIENDLY);
1307 pilot_rmFlag(p, PILOT_FRIENDLY);
1318 return p->fuel / p->fuel_consumption;
1329 const glColour *col;
1333 else if (pilot_isDisabled(p) || pilot_isFlag(p,PILOT_DEAD))
1354 if (p->target ==
id)
1366 p->nav_asteroid = -1;
1382 const Damage *dmg,
const Outfit *outfit,
int lua_mem,
int reset )
1385 double damage_shield, damage_armour, disable, knockback, dam_mod, ddmg, ddis, absorb, dmod, start;
1386 double tdshield, tdarmour;
1389 if (pilot_isFlag( p, PILOT_INVINCIBLE ) ||
1390 pilot_isFlag( p, PILOT_HIDE ) ||
1391 ((pshooter!=NULL) && pilot_isWithPlayer(pshooter) && pilot_isFlag( p, PILOT_INVINC_PLAYER )))
1398 shooter = (pshooter==NULL) ? 0 : pshooter->
id;
1403 dtype_calcDamage( &damage_shield, &damage_armour, absorb, &knockback, dmg, &p->stats );
1409 if (!pilot_isFlag(p, PILOT_DEAD) && (p->dtimer_accum > 0.))
1410 p->dtimer_accum -=
MIN( pow(disable, 0.8), p->dtimer_accum );
1413 if (pilot_isFlag( p, PILOT_NODISABLE )) {
1414 damage_armour += disable * absorb;
1425 if (p->shield - damage_shield > 0.) {
1427 ddmg = damage_shield;
1428 p->shield -= damage_shield;
1429 dam_mod = damage_shield/p->shield_max;
1442 ddis = disable * (0.5 + (0.5 - ((start+p->shield) / p->shield_max) / 4.));
1446 tdshield = damage_shield;
1451 else if (p->shield > 0.) {
1453 dmod = (1. - p->shield/damage_shield);
1454 ddmg = p->shield + dmod * damage_armour;
1455 tdshield = p->shield;
1459 ddis = disable * (1. - dmod) * (0.5 + (0.5 - (start / p->shield_max / 4.)));
1464 tdarmour = dmod * damage_armour;
1465 p->armour -= tdarmour;
1466 p->stress += dmod * disable;
1467 dam_mod = (damage_shield + damage_armour) /
1468 ((p->shield_max + p->armour_max) / 2.);
1479 else if (p->armour > 0.) {
1480 ddmg = damage_armour;
1483 p->armour -= damage_armour;
1498 if (p->stress > p->armour)
1499 p->stress = p->armour;
1502 if ((p->armour <= 0.) && pilot_isFlag( p, PILOT_NODEATH )) {
1508 if (pilot_isFlag( p, PILOT_DISABLED_PERM ))
1509 p->stress = p->armour;
1512 if (p->shield <= 0.) {
1513 if (p->id == PLAYER_ID) {
1514 double spfx_mod = tdarmour/p->armour_max;
1521 if (p->id == PLAYER_ID) {
1529 else if (shooter == PLAYER_ID) {
1539 vec2_cadd( &p->solid->vel,
1540 knockback * (w->vel.x * (dam_mod/9. + w->mass/p->solid->mass/6.)),
1541 knockback * (w->vel.y * (dam_mod/9. + w->mass/p->solid->mass/6.)) );
1544 if ((outfit!=NULL) && (outfit->
lua_onimpact != LUA_NOREF)) {
1545 lua_rawgeti(naevL, LUA_REGISTRYINDEX, lua_mem);
1546 nlua_setenv(naevL, outfit->
lua_env,
"mem");
1549 lua_rawgeti(naevL, LUA_REGISTRYINDEX, outfit->
lua_onimpact);
1554 if (nlua_pcall( outfit->
lua_env, 4, 0 )) {
1555 WARN( _(
"Pilot '%s''s outfit '%s' -> '%s':\n%s"), p->name, outfit->
name,
"onimpact", lua_tostring(naevL,-1) );
1567 if (p->armour <= 0.) {
1570 if (!pilot_isFlag(p, PILOT_DEAD)) {
1574 if ((pshooter != NULL) && pilot_isWithPlayer(pshooter)) {
1577 mod = 2. * (pow(p->base_mass, 0.4) - 1.);
1600 if ((!pilot_isFlag(p, PILOT_DISABLED)) &&
1601 (!pilot_isFlag(p, PILOT_NODISABLE) || (p->armour <= 0.)) &&
1602 (p->armour <= p->stress)) {
1606 if (pilot_isFlag(p, PILOT_COOLDOWN))
1610 pilot_rmFlag(p, PILOT_COOLDOWN_BRAKE);
1611 pilot_rmFlag(p, PILOT_BRAKING);
1612 pilot_rmFlag(p, PILOT_STEALTH);
1615 pilot_rmFlag(p, PILOT_HYP_PREP);
1616 pilot_rmFlag(p, PILOT_HYP_BEGIN);
1617 pilot_rmFlag(p, PILOT_HYP_BRAKE);
1618 pilot_rmFlag(p, PILOT_HYPERSPACE);
1621 if (p->presence > 0) {
1630 p->dtimer = 8. * pow( p->solid->mass, 1./3. );
1631 p->dtimer_accum = 0.;
1637 pilot_setFlag( p, PILOT_DISABLED );
1638 if (pilot_isPlayer( p ))
1643 hparam.
type = HOOK_PARAM_PILOT;
1644 hparam.
u.
lp = shooter;
1647 hparam.
type = HOOK_PARAM_NIL;
1651 else if (pilot_isFlag(p, PILOT_DISABLED) && (p->armour > p->stress)) {
1652 pilot_rmFlag( p, PILOT_DISABLED );
1653 pilot_rmFlag( p, PILOT_DISABLED_PERM );
1654 pilot_rmFlag( p, PILOT_BOARDING );
1657 p->dtimer_accum = 0.;
1663 if (pilot_isPlayer(p)) {
1665 player_message(
"#g%s",_(
"You have recovered control of your ship!"));
1680 if (pilot_isFlag(p,PILOT_DEAD))
1684 if (p->id==PLAYER_ID) {
1685 pilot_setFlag(p, PILOT_DISABLED );
1689 p->ptimer =
MIN( 1. + sqrt(p->armour_max * p->shield_max) / 650.,
1690 3 + pow(p->armour_max * p->shield_max, 0.4) / 500);
1694 pilot_rmFlag(p,PILOT_HYP_PREP);
1695 pilot_rmFlag(p,PILOT_HYP_BEGIN);
1696 pilot_rmFlag(p,PILOT_HYP_BRAKE);
1697 pilot_rmFlag(p,PILOT_HYPERSPACE);
1704 hparam.
type = HOOK_PARAM_PILOT;
1705 hparam.
u.
lp = killer;
1708 hparam.
type = HOOK_PARAM_NIL;
1712 if (p->armour <= 0.) {
1713 if (p->parent == PLAYER_ID)
1714 player_message( _(
"#rShip under command '%s' was destroyed!#0"), p->name );
1716 pilot_setFlag( p, PILOT_DEAD );
1734 rad2 = radius*radius;
1742 rx = p->solid->pos.x - x;
1743 ry = p->solid->pos.y - y;
1746 dist -=
pow2(p->ship->gfx_space->sw);
1762 pilot_hit( p, &s, parent, &ddmg, NULL, LUA_NOREF, 1 );
1765 if (p->id == PILOT_PLAYER)
1780 glColour
c = { 1., 1., 1., 1. };
1783 if (pilot_isFlag(p, PILOT_STEALTH))
1786 glBindFramebuffer( GL_FRAMEBUFFER, fbo );
1787 glClearColor( 0., 0., 0., 0. );
1789 if (p->ship->gfx_3d != NULL) {
1790 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1798 glClear( GL_COLOR_BUFFER_BIT );
1800 sa = p->ship->gfx_space;
1801 sb = p->ship->gfx_engine;
1804 tx = sa->
sw*(double)(p->tsx)/sa->
w;
1805 ty = sa->
sh*(sa->
sy-(double)p->tsy-1)/sa->
h;
1807 tmpm = gl_view_matrix;
1808 gl_view_matrix =
mat4_ortho( 0., fw, 0, fh, -1., 1. );
1811 1.-p->engine_glow, 0., 0., sa->
sw, sa->
sh,
1812 tx, ty, sa->
srw, sa->
srh, &
c );
1814 gl_view_matrix = tmpm;
1818 glClearColor( 0., 0., 0., 1. );
1828 double scale, x,y, w,h, z;
1831 glColour
c = {.r=1., .g=1., .b=1., .a=1.};
1834 if (pilot_isFlag( p, PILOT_NORENDER ))
1839 w = p->ship->gfx_space->sw;
1840 h = p->ship->gfx_space->sh;
1844 if ((x < -w) || (x > SCREEN_W+w) ||
1845 (y < -h) || (y > SCREEN_H+h))
1850 for (
int i=0; i<
array_size(p->effects); i++) {
1852 Effect *eiter = &p->effects[i];
1853 if (eiter->
data->program==0)
1862 if (pilot_isFlag( p, PILOT_LANDING ))
1863 scale =
CLAMP( 0., 1., p->ptimer / p->landing_delay );
1864 else if (pilot_isFlag( p, PILOT_TAKEOFF ))
1865 scale =
CLAMP( 0., 1., 1. - p->ptimer / p->landing_delay );
1870 if (pilot_isFlag(p, PILOT_STEALTH))
1875 if (p->ship->gfx_3d != NULL) {
1877 object_renderSolidPart(p->ship->gfx_3d, p->solid,
"body",
c.a, p->ship->gfx_3d_scale * scale);
1878 object_renderSolidPart(p->ship->gfx_3d, p->solid,
"engine",
c.a * p->engine_glow, p->ship->gfx_3d_scale * scale);
1882 1.-p->engine_glow, p->solid->pos.x, p->solid->pos.y,
1883 scale, scale, p->tsx, p->tsy, &
c );
1888 mat4 projection, tex_mat;
1894 glUseProgram( ed->program );
1896 glActiveTexture( GL_TEXTURE0 );
1898 glUniform1i( ed->u_tex, 0 );
1900 glEnableVertexAttribArray( ed->vertex );
1903 projection = gl_view_matrix;
1904 mat4_translate( &projection, x + (1.-scale)*z*w/2., y + (1.-scale)*z*h/2., 0. );
1905 mat4_scale( &projection, scale*z*w, scale*z*h, 1. );
1906 gl_uniformMat4(ed->projection, &projection);
1910 gl_uniformMat4(ed->tex_mat, &tex_mat);
1912 glUniform3f( ed->dimensions, SCREEN_W, SCREEN_H,
cam_getZoom() );
1913 glUniform1f( ed->u_timer, e->
timer );
1914 glUniform1f( ed->u_elapsed, e->
elapsed );
1915 glUniform1f( ed->u_r, e->
r );
1918 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
1921 glDisableVertexAttribArray( ed->vertex );
1926 double dircos, dirsin;
1927 int debug_mark_emitter = debug_isFlag(DEBUG_MARK_EMITTER);
1929 if (debug_mark_emitter) {
1930 dircos = cos(p->solid->dir);
1931 dirsin = sin(p->solid->dir);
1936 for (
int i=0,g=0; g<
array_size(p->ship->trail_emitters); g++) {
1938 if (debug_mark_emitter) {
1940 v.x = p->ship->trail_emitters[g].x_engine * dircos -
1941 p->ship->trail_emitters[g].y_engine * dirsin;
1942 v.y = p->ship->trail_emitters[g].x_engine * dirsin +
1943 p->ship->trail_emitters[g].y_engine * dircos +
1944 p->ship->trail_emitters[g].h_engine;
1947 p->solid->pos.y + v.y*M_SQRT1_2 );
1948 if (p->ship->trail_emitters[i].trail_spec->nebula)
1956 if (p->trail[i]->ontop)
1973 if (pilot_isFlag( p, PILOT_NORENDER ))
1976 playerdead = (player_isFlag(PLAYER_DESTROYED) || (
player.
p==NULL));
1979 if (!playerdead && pilot_isFlag( p, PILOT_HAILING )) {
1981 if (ico_hail != NULL) {
1982 int sx = (int)ico_hail->
sx;
1986 p->solid->pos.x + PILOT_SIZE_APPROX*p->ship->gfx_space->sw/2. + ico_hail->
sw/4.,
1987 p->solid->pos.y + PILOT_SIZE_APPROX*p->ship->gfx_space->sh/2. + ico_hail->
sh/4.,
1988 p->hail_pos % sx, p->hail_pos / sx, NULL );
1993 if (p->comm_msg != NULL) {
1994 double x, y, dx, dy;
2000 glColour
c = {1., 1., 1., 1.};
2007 dx = x - p->comm_msgWidth/2.;
2008 dy = y + PILOT_SIZE_APPROX*p->ship->gfx_space->sh/2.;
2018 if (conf.
healthbars && !playerdead && !pilot_isPlayer(p) && !pilot_isFlag(p, PILOT_DEAD) &&
2019 (pilot_isFlag(p, PILOT_COMBAT) || (p->shield < p->shield_max))) {
2025 w = p->ship->gfx_space->sw + 4.;
2026 h = p->ship->gfx_space->sh + 4.;
2029 if ((x < -w) || (x > SCREEN_W+w) ||
2030 (y < -h) || (y > SCREEN_H+h))
2033 w = PILOT_SIZE_APPROX * p->ship->gfx_space->sw;
2034 h = PILOT_SIZE_APPROX * p->ship->gfx_space->sh / 3.;
2036 glUseProgram( shaders.healthbar.program );
2037 glUniform2f( shaders.healthbar.dimensions, 5., h );
2038 glUniform1f( shaders.healthbar.paramf, (p->armour + p->shield) / (p->armour_max + p->shield_max) );
2039 gl_uniformColor( shaders.healthbar.paramv, (p->shield > 0.) ? &cShield : &cArmour );
2054 double a, px,py, vx,vy;
2063 cooling = pilot_isFlag(pilot, PILOT_COOLDOWN);
2072 if (pilot->
ctimer < 0.) {
2080 for (
int i=0; i<MAX_AI_TIMERS; i++)
2081 if (pilot->
timer[i] > 0.)
2082 pilot->
timer[i] -= dt;
2090 if (pilot_isFlag( pilot, PILOT_HAILING )) {
2092 if (ico_hail != NULL) {
2095 sx = (int)ico_hail->
sx;
2096 sy = (
int)ico_hail->
sy;
2097 if (pilot->
htimer < 0.) {
2126 double ammo_threshold, reload_time;
2143 if (o->
rtimer < reload_time)
2150 while ((o->
rtimer >= reload_time) &&
2152 o->
rtimer -= reload_time;
2163 if (o->
state == PILOT_OUTFIT_ON) {
2167 else if (o->
state == PILOT_OUTFIT_COOLDOWN) {
2168 o->
state = PILOT_OUTFIT_OFF;
2192 if (!pilot_isFlag(pilot, PILOT_DISABLED)) {
2193 double stress_falloff = 0.3*sqrt(pilot->
solid->
mass);
2197 else if (!pilot_isFlag(pilot, PILOT_DISABLED_PERM)) {
2213 pilot_hit( pilot, NULL, NULL, &dmg, NULL, LUA_NOREF, 0 );
2217 if (pilot_isFlag(pilot,PILOT_TAKEOFF)) {
2218 if (pilot->
ptimer < 0.) {
2219 pilot_rmFlag(pilot,PILOT_TAKEOFF);
2220 if (pilot_isFlag(pilot, PILOT_PLAYER)) {
2221 pilot_setFlag(pilot, PILOT_NONTARGETABLE);
2222 pilot->
itimer = PILOT_PLAYER_NONTARGETABLE_TAKEOFF_DELAY;
2227 else if (pilot_isFlag(pilot,PILOT_LANDING)) {
2228 if (pilot->
ptimer < 0.) {
2229 if (pilot_isPlayer(pilot)) {
2230 player_setFlag( PLAYER_HOOK_LAND );
2239 else if (pilot_isFlag(pilot,PILOT_DEAD)) {
2242 if (!pilot_isFlag(pilot,PILOT_DEATH_SOUND) &&
2243 (pilot->
ptimer < 0.050)) {
2247 snprintf(buf,
sizeof(buf),
"explosion%d", RNG(0,2));
2251 pilot_setFlag(pilot,PILOT_DEATH_SOUND);
2254 else if (!pilot_isFlag(pilot,PILOT_EXPLODED) &&
2255 (pilot->
ptimer < 0.200)) {
2261 dmg.
damage =
MAX(0., 2. * (a * (1. + sqrt(pilot->
fuel + 1.) / 28.)));
2266 pilot->
ship->
gfx_space->
sw/2./PILOT_SIZE_APPROX + a, &dmg, NULL, EXPL_MODE_SHIP );
2270 pilot_setFlag(pilot,PILOT_EXPLODED);
2274 if (pilot_isFlag(pilot, PILOT_EXPLODED)) {
2282 else if (pilot->
timer[1] <= 0.) {
2296 l = (pilot->
id==PLAYER_ID) ? SPFX_LAYER_FRONT : SPFX_LAYER_MIDDLE;
2304 if (pilot_isFlag(pilot,PILOT_DEAD) && (pilot->
ptimer < 0.)) {
2305 if (pilot->
id==PLAYER_ID)
2311 else if (pilot_isFlag(pilot, PILOT_NONTARGETABLE)) {
2314 pilot_rmFlag(pilot, PILOT_NONTARGETABLE);
2316 else if (pilot->
armour <= 0.) {
2317 if (pilot_isFlag( pilot, PILOT_NODEATH ))
2324 if (pilot_isFlag(pilot, PILOT_BRAKING )) {
2326 if (pilot_isFlag(pilot, PILOT_COOLDOWN_BRAKE))
2335 if (VMOD(pilot->
solid->
vel) < 1e-1) {
2337 pilot_rmFlag(pilot, PILOT_BRAKING);
2344 if (!pilot_isDisabled(pilot)) {
2353 if (pilot->
stimer <= 0.) {
2381 else if (pilot->
energy < 0.) {
2392 if (pilot_isFlag( pilot, PILOT_DELETE ))
2400 if (pilot_isDisabled(pilot) || pilot_isFlag(pilot, PILOT_COOLDOWN)) {
2432 if (pilot_isFlag(pilot, PILOT_REFUELBOARDING))
2436 if (pilot_isFlag(pilot, PILOT_BOARDING)) {
2438 pilot_rmFlag(pilot, PILOT_BOARDING);
2452 if (!pilot_isFlag(pilot, PILOT_HYPERSPACE)) {
2455 if (pilot_isFlag(pilot, PILOT_AFTERBURNER)) {
2465 double efficiency, thrust;
2467 if (pilot->
id == PLAYER_ID)
2507 if (!pilot_isDisabled(pilot))
2515 while (pilot->
otimer >= PILOT_OUTFIT_LUA_UPDATE_DT) {
2517 if (pilot_isFlag( pilot, PILOT_DELETE ))
2519 pilot->
otimer -= PILOT_OUTFIT_LUA_UPDATE_DT;
2531 double d2, cx, cy, dircos, dirsin;
2539 if (p->trail == NULL)
2544 d2 =
pow2(cx-p->solid->pos.x) +
pow2(cy-p->solid->pos.y);
2548 dircos = cos(p->solid->dir);
2549 dirsin = sin(p->solid->dir);
2555 if (pilot_isFlag(p, PILOT_HYPERSPACE) || pilot_isFlag(p, PILOT_HYP_END))
2556 mode = MODE_JUMPING;
2557 else if (pilot_isFlag(p, PILOT_AFTERBURNER))
2558 mode = MODE_AFTERBURN;
2559 else if (p->engine_glow > 0.)
2566 for (
int i=0, g=0; g<
array_size(p->ship->trail_emitters); g++) {
2567 double dx, dy, prod;
2572 p->trail[i]->ontop = 0;
2573 if (!(p->ship->trail_emitters[g].always_under) && (dirsin > 0)) {
2575 prod = (trail_front( p->trail[i] ).x - p->solid->pos.x) * dircos +
2576 (trail_front( p->trail[i] ).y - p->solid->pos.y) * dirsin;
2578 p->trail[i]->ontop = (prod < 0);
2581 dx = p->ship->trail_emitters[g].x_engine * dircos -
2582 p->ship->trail_emitters[g].y_engine * dirsin;
2583 dy = p->ship->trail_emitters[g].x_engine * dirsin +
2584 p->ship->trail_emitters[g].y_engine * dircos +
2585 p->ship->trail_emitters[g].h_engine;
2586 spfx_trail_sample( p->trail[i++], p->solid->pos.x + dx, p->solid->pos.y + dy*M_SQRT1_2, mode, mode==MODE_NONE );
2595 return !p->ship->trail_emitters[generator].trail_spec->nebula ||
cur_system->nebu_density>0;
2608 if (pilot_isFlag( p, PILOT_DELETE ))
2618 if (p->parent != 0) {
2625 if (p->presence > 0) {
2632 if (dockslot != NULL) {
2639 pilot_setFlag(p, PILOT_DELETE);
2656 if (pilot_isFlag(p, PILOT_HYPERSPACE)) {
2659 if ((p->id == PLAYER_ID) &&
2661 (p->timer[0] == -1.)) {
2667 if (p->ptimer < 0.) {
2668 pilot_setFlag( p, PILOT_HYP_END );
2670 if (p->id == PLAYER_ID)
2671 player_setFlag( PLAYER_HOOK_HYPER );
2673 hparam.
type = HOOK_PARAM_JUMP;
2689 else if (pilot_isFlag(p, PILOT_HYP_BEGIN)) {
2696 if (pilot_isPlayer(p))
2697 if (!player_isFlag(PLAYER_AUTONAV))
2698 player_message(
"#r%s", _(
"Strayed too far from jump point: jump aborted.") );
2700 else if (pilot_isFlag(p,PILOT_AFTERBURNER)) {
2703 if (pilot_isPlayer(p))
2704 if (!player_isFlag(PLAYER_AUTONAV))
2705 player_message(
"#r%s", _(
"Afterburner active: jump aborted.") );
2708 if (p->ptimer < 0.) {
2709 p->ptimer = HYPERSPACE_FLY_DELAY * p->stats.jump_delay;
2710 pilot_setFlag(p, PILOT_HYPERSPACE);
2711 if (p->id == PLAYER_ID)
2723 if (pilot_isPlayer(p))
2724 if (!player_isFlag(PLAYER_AUTONAV))
2725 player_message(
"#r%s", _(
"Strayed too far from jump point: jump aborted.") );
2729 if (!p->stats.misc_instant_jump &&
2730 !pilot_isFlag(p, PILOT_HYP_BRAKE) && !pilot_isStopped(p))
2735 pilot_setFlag( p, PILOT_HYP_BRAKE );
2739 sys =
cur_system->jumps[p->nav_hyperspace].target;
2743 if (
ABS(diff) < MAX_DIR_ERR) {
2744 if (jp_isFlag( &
cur_system->jumps[p->nav_hyperspace], JP_EXITONLY )) {
2745 WARN( _(
"Pilot '%s' trying to jump through exit-only jump from '%s' to '%s'"),
2750 p->ptimer = HYPERSPACE_ENGINE_DELAY * p->stats.jump_warmup * !p->stats.misc_instant_jump;
2751 pilot_setFlag(p, PILOT_HYP_BEGIN);
2753 if ((p->id == PLAYER_ID) && !p->stats.misc_instant_jump)
2761 if (pilot_isPlayer(p))
2774 if (pilot_isFlag(p, PILOT_HYPERSPACE))
2777 if (pilot_isFlag(p, PILOT_HYP_BEGIN)) {
2779 if (p->id == PLAYER_ID) {
2784 pilot_rmFlag(p, PILOT_HYP_BEGIN);
2785 pilot_rmFlag(p, PILOT_HYP_BRAKE);
2786 pilot_rmFlag(p, PILOT_HYP_PREP);
2798 if (target == NULL) {
2799 pilot_rmFlag(p, PILOT_REFUELING);
2804 if (vec2_dist(&p->solid->pos, &target->
solid->
pos) >
2807 else if (vec2_dist2( &p->solid->vel, &target->
solid->
vel ) >
pow2(MAX_HYPERSPACE_VEL))
2811 pilot_setFlag(p, PILOT_REFUELBOARDING);
2812 p->ptimer = PILOT_REFUEL_TIME;
2827 if (target == NULL) {
2828 pilot_rmFlag(p, PILOT_REFUELBOARDING);
2829 pilot_rmFlag(p, PILOT_REFUELING);
2834 p->solid->vel = target->
solid->
vel;
2837 if (p->ptimer < 0.) {
2839 double amount =
MIN( p->fuel, p->refuel_amount );
2842 target->
fuel += amount;
2844 pilot_rmFlag(p, PILOT_REFUELBOARDING);
2845 pilot_rmFlag(p, PILOT_REFUELING);
2857 int stu = (int)(NT_PERIOD_SECONDS * p->stats.jump_delay);
2883 for (
int i=0; i<
array_size(p->outfits); i++) {
2884 if (p->outfits[i]->outfit == o)
2901 return (amount <= p->credits);
2914 if (CREDITS_MAX - p->credits <= amount)
2915 p->credits = CREDITS_MAX;
2917 p->credits += amount;
2919 else if (amount < 0) {
2930 if ( (amount <= CREDITS_MIN) || (
ABS(amount) >= p->credits) )
2933 p->credits += amount;
2953 const double dir,
const vec2* pos,
const vec2* vel,
2954 const PilotFlags flags,
unsigned int dockpilot,
int dockslot )
2961 memset(pilot, 0,
sizeof(
Pilot));
2968 pilot->
parent = dockpilot;
2974 pilot->
name = strdup( (name==NULL) ? _(ship->
name) : name );
2980 pilot->
solid = solid_create(ship->
mass, dir, pos, vel, SOLID_UPDATE_RK4);
2993 for (
int i=0; i<3; i++) {
2995 for (
int j=0; j<
array_size(ship_list[i]); j++) {
2999 slot->
sslot = &ship_list[i][j];
3011 if (!pilot_isFlagRaw(flags, PILOT_PLAYER))
3039 char message[STRMAX_SHORT];
3042 DEBUG( _(
"Pilot '%s' failed safety check: %s"), pilot->
name, message );
3051 pilot_copyFlagsRaw(pilot->
flags, flags);
3071 if (pilot_isFlagRaw( flags, PILOT_TAKEOFF )) {
3077 lua_newtable(naevL);
3078 pilot->
messages = luaL_ref(naevL, LUA_REGISTRYINDEX);
3091 for (
int i=PILOT_NOCLEAR+1; i<PILOT_FLAGS_MAX; i++)
3092 pilot->
flags[i] = 0;
3133 if (p->trail == NULL)
3136 for (
int g=0; g<n; g++)
3152 const double dir,
const vec2* pos,
const vec2* vel,
3153 const PilotFlags flags,
unsigned int dockpilot,
int dockslot )
3158 p = malloc(
sizeof(
Pilot));
3160 WARN(_(
"Unable to allocate memory"));
3168 pilot_init( p, ship, name, faction, dir, pos, vel, flags, dockpilot, dockslot );
3171 if (pilot_isFlagRaw(flags, PILOT_PLAYER)) {
3206 int faction, PilotFlags flags )
3210 WARN(_(
"Unable to allocate memory"));
3213 pilot_init( dyn, ship, name, faction, 0., NULL, NULL, flags, 0, 0 );
3228 pilot_clearFlagsRaw( &pf );
3229 pilot_setFlagRaw( pf, PILOT_NO_OUTFITS );
3232 dyn = malloc(
sizeof(
Pilot));
3234 WARN(_(
"Unable to allocate memory"));
3244 ref->solid->dir, &ref->solid->pos, &ref->solid->vel, pf, 0, 0 );
3247 for (
int i=0; i<
array_size(ref->outfits); i++)
3248 if (ref->outfits[i]->outfit != NULL)
3250 for (
int i=0; i<
array_size(ref->outfit_intrinsic); i++)
3265 pilot_setFlag( p, PILOT_NOFREE );
3278 WARN(_(
"Duplicate pilots on stack!"));
3315 after->
id = PLAYER_ID;
3326 pilot_setFlag( after, PILOT_PLAYER );
3327 pilot_setFlag( after, PILOT_NOFREE );
3348 JumpPoint **validJumpPoints;
3359 if (spob_hasService( pnt, SPOB_SERVICE_INHABITED ) &&
3373 JumpPoint *target =
cur_system->jumps[i].returnJump;
3381 if (!jp_isFlag( target, JP_EXITONLY ) && (ignore_rules ||
3382 ((!jp_isFlag( &
cur_system->jumps[i], JP_HIDDEN ) || guerilla) &&
3391 vec2_pset ( vp, 1.5*
cur_system->radius, RNGF()*2*M_PI );
3395 if (!jp_isFlag( jp->returnJump, JP_EXITONLY ))
3400 WARN(_(
"Creating pilot in system with no jumps nor spobs to take off from!"));
3408 chance = chance / (chance +
array_size(ind));
3411 if ((RNGF() <= chance) && (validJumpPoints != NULL))
3412 *jump = validJumpPoints[ RNG_BASE(0,
array_size(validJumpPoints)-1) ];
3442 p->trail[i]->ontop = 0;
3449 if (pilot_isFlag( p, PILOT_NOFREE )) {
3474 solid_free(p->solid);
3482 luaL_unref(naevL, p->messages, LUA_REGISTRYINDEX);
3485 memset( p, 0,
sizeof(
Pilot) );
3511 WARN(_(
"Trying to remove non-existent pilot '%s' from stack!"), p->name);
3557 int persist_count = 0;
3564 (persist && pilot_isFlag(p, PILOT_PERSIST)))
3575 if (!pilot_isFlag(
pilot_stack[i], PILOT_DELETE) &&
3577 (persist && pilot_isFlag(
pilot_stack[i], PILOT_PERSIST)))) {
3639 pilot_rmFlag(
player.
p, PILOT_NOFREE );
3663 if (pilot_isFlag(p, PILOT_DELETE))
3672 if (pilot_isFlag(p, PILOT_HIDE))
3676 if (pilot_isDisabled(p))
3678 if (pilot_isFlag(p,PILOT_DEAD))
3686 if (pilot_isFlag(p, PILOT_HYP_PREP))
3689 else if (pilot_isFlag(p, PILOT_HYP_END)) {
3690 if ((VMOD(p->solid->vel) < 2*solid_maxspeed( p->solid, p->speed, p->thrust) ) && (p->ptimer < 0.))
3691 pilot_rmFlag(p, PILOT_HYP_END);
3694 else if (!pilot_isFlag(p, PILOT_BOARDING) &&
3695 !pilot_isFlag(p, PILOT_REFUELBOARDING) &&
3697 !pilot_isFlag(p, PILOT_LANDING) &&
3698 !pilot_isFlag(p, PILOT_TAKEOFF) &&
3700 !pilot_isFlag(p, PILOT_HYP_END)) {
3701 if (pilot_isFlag(p, PILOT_PLAYER))
3713 if (pilot_isFlag(p, PILOT_DELETE))
3717 if (pilot_isFlag(p, PILOT_HIDE))
3721 if (pilot_isFlag( p, PILOT_PLAYER ))
3737 if (pilot_isFlag(p, PILOT_HIDE) || pilot_isFlag(p, PILOT_DELETE))
3740 if (!pilot_isFlag( p, PILOT_PLAYER ))
3754 if (pilot_isFlag(p, PILOT_HIDE) || pilot_isFlag(p, PILOT_DELETE))
3757 if (!pilot_isFlag( p, PILOT_PLAYER ))
3779 for (
int i=0; i<MAX_AI_TIMERS; i++)
3780 pilot->
timer[i] = 0.;
3786 if (o->
state != PILOT_OUTFIT_OFF) {
3787 o->
state = PILOT_OUTFIT_OFF;
3818 double shots, dps=0., eps=0.;
3819 for (
int i=0; i<
array_size(p->outfits); i++) {
3821 double mod_energy, mod_damage, mod_shots;
3822 const Outfit *o = p->outfits[i]->outfit;
3826 case OUTFIT_TYPE_BOLT:
3827 mod_energy = p->stats.fwd_energy;
3828 mod_damage = p->stats.fwd_damage;
3829 mod_shots = 1. / p->stats.fwd_firerate * (double)o->
u.
blt.
shots;
3831 case OUTFIT_TYPE_TURRET_BOLT:
3832 mod_energy = p->stats.tur_energy;
3833 mod_damage = p->stats.tur_damage;
3834 mod_shots = 1. / p->stats.tur_firerate * (
double)o->
u.
blt.
shots;
3836 case OUTFIT_TYPE_LAUNCHER:
3837 case OUTFIT_TYPE_TURRET_LAUNCHER:
3839 mod_damage = p->stats.launch_damage;
3840 mod_shots = 1. / p->stats.launch_rate * (double)o->
u.
lau.
shots;
3842 case OUTFIT_TYPE_BEAM:
3843 case OUTFIT_TYPE_TURRET_BEAM:
3845 if (o->
type == OUTFIT_TYPE_BEAM) {
3846 mod_energy = p->stats.fwd_energy;
3847 mod_damage = p->stats.fwd_damage;
3848 mod_shots = 1. / p->stats.fwd_firerate;
3851 mod_energy = p->stats.tur_energy;
3852 mod_damage = p->stats.tur_damage;
3853 mod_shots = 1. / p->stats.tur_firerate;
3856 mod_shots = shots / (shots + mod_shots *
outfit_delay(o));
3867 dps += shots * mod_damage * dmg->
damage;
3885 double DPSaccum_target, DPSaccum_pilot;
3890 if ((DPSaccum_target > 1e-6) && (DPSaccum_pilot > 1e-6))
3891 return DPSaccum_pilot / (DPSaccum_target + DPSaccum_pilot);
3892 else if (DPSaccum_pilot > 0.)
3907 double p_hp = p -> armour_max + p -> shield_max;
3908 return c_hp / (p_hp + c_hp);
3921 for (
int i=0; i<
array_size(p->outfits); i++) {
3922 if (p->outfits[i]->outfit == NULL)
3925 if (outfit_isProp(p->outfits[i]->outfit, OUTFIT_PROP_UNIQUE))
3927 price += p->outfits[i]->outfit->price;
3944 lua_pushvalue(naevL, idx);
3948 lua_newtable(naevL);
3952 lua_rawseti(naevL, -2, 1);
3955 lua_pushstring(naevL, type);
3956 lua_rawseti(naevL, -2, 2);
3958 lua_pushvalue(naevL, -2);
3959 lua_rawseti(naevL, -2, 3);
3961 lua_rawgeti(naevL, LUA_REGISTRYINDEX, receiver->
messages);
3962 lua_pushvalue(naevL, -2);
3963 lua_rawseti(naevL, -2, lua_objlen(naevL, -2)+1);
3977 for (
int i=0; i<
array_size(p->commodities); i++) {
3978 const Commodity *
c = p->commodities[i].commodity;
3979 if (commodity_checkIllegal(
c, faction ))
3983 for (
int i=0; i<
array_size(p->outfits); i++) {
3984 const Outfit *o = p->outfits[i]->outfit;
void ai_getDistress(Pilot *p, const Pilot *distressed, const Pilot *attacker)
Sends a distress signal to a pilot.
void ai_cleartasks(Pilot *p)
Clears the pilot's tasks.
void ai_destroy(Pilot *p)
Destroys the ai part of the pilot.
void ai_think(Pilot *pilot, const double dt)
Heart of the AI, brains 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.
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.
void gatherable_gather(Pilot *p)
See if the pilot can gather anything.
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.
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.
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.
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.
credits_t pilot_worth(const Pilot *p)
Gets the price or worth of a pilot in credits.
void pilot_choosePoint(vec2 *vp, Spob **spob, JumpPoint **jump, int lf, int ignore_rules, int guerilla)
Finds a spawn point for a pilot.
void pilot_setThrust(Pilot *p, double thrust)
Sets the pilot's thrust.
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.
unsigned int 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.
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 pilot_msg(Pilot *p, Pilot *receiver, const char *type, unsigned int idx)
Sends a message.
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_getNearestPos(const Pilot *p, unsigned int *tp, double x, double y, int disabled)
Get the nearest pilot to a pilot from a certain position.
ntime_t pilot_hyperspaceDelay(Pilot *p)
Calculates the hyperspace delay for a pilot.
double pilot_face(Pilot *p, const double dir)
Tries to turn the pilot to face dir.
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.
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.
static void pilot_erase(Pilot *p)
Destroys pilot from stack.
void pilot_cooldownEnd(Pilot *p, const char *reason)
Terminates active cooldown.
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.
void pilot_broadcast(Pilot *p, const char *msg, int ignore_int)
Has the pilot broadcast a message.
double pilot_brakeDist(Pilot *p, vec2 *pos)
Gets the braking distance for a pilot.
void pilot_setHostile(Pilot *p)
Marks pilot as hostile to player.
void pilot_dpseps(const Pilot *p, double *pdps, double *peps)
Calculates the dps and eps of a pilot.
int pilot_hasCredits(Pilot *p, credits_t amount)
Checks to see if the pilot has at least a certain amount of credits.
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.
int pilot_interceptPos(Pilot *p, double x, double y)
Attempts to make the pilot pass through a given point.
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.
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.
int pilot_brake(Pilot *p)
Causes the pilot to turn around and brake.
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.
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.
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.
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.
int pilot_runHookParam(Pilot *p, int hook_type, const HookParam *param, int nparam)
Tries to run a pilot hook if he has it.
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.
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.
void pilot_afterburnOver(Pilot *p)
Deactivates the afterburner.
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).
int ss_statsInit(ShipStats *stats)
Initializes a stat structure.
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.
int space_isSimulationEffects(void)
returns whether or not we're simulating with effects.
double system_getPresence(const StarSystem *sys, int faction)
Get the presence of a faction in a system.
int space_isSimulation(void)
returns whether we're just simulating.
int spfx_get(char *name)
Gets the id of an spfx based on name.
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.
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
ShipStats intrinsic_stats
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
ShipOutfitSlot * outfit_utility
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.