29#include "nlua_pilot.h"
37#define weapon_isSmart(w) (w->think != NULL)
40typedef enum WeaponStatus_ {
49#define WEAPON_FLAG_DESTROYED 1
50#define weapon_isFlag(w,f) ((w)->flags & (f))
51#define weapon_setFlag(w,f) ((w)->flags |= (f))
52#define weapon_rmFlag(w,f) ((w)->flags &= ~(f))
59typedef struct Weapon_ {
89 void (*update)(
struct Weapon_*,
const double, WeaponLayer);
90 void (*think)(
struct Weapon_*,
const double);
112 const Pilot *pilot_target,
const vec2 *pos,
const vec2 *vel,
double dir,
113 double swivel,
double time );
115 const double dir,
const vec2* pos,
const vec2* vel,
const Pilot* parent,
double time,
int aim );
117 const double dir,
const vec2* pos,
const vec2* vel,
const Pilot* parent,
double time,
int aim );
119 const double dir,
const vec2* pos,
const vec2* vel,
120 const Pilot *parent,
const unsigned int target,
double time,
int aim );
121static double weapon_computeTimes(
double rdir,
double rx,
double ry,
double dvx,
double dvy,
double pxv,
122 double vmin,
double acc,
double *tt );
132 double x,
double y,
double radius,
133 const Pilot *parent,
int mode );
141 vec2 pos[2],
const double dt );
143 vec2 pos[2],
const double dt );
149 const double h,
const RadarShape shape,
double alpha );
173 const double h,
const RadarShape shape,
double alpha )
184 if (shape==RADAR_CIRCLE)
203 if (shape==RADAR_RECT && (
ABS(x)>w/2. ||
ABS(y)>h/2.))
205 if (shape==RADAR_CIRCLE && (((x)*(x)+(y)*(y)) > rc))
210 (wp->
faction == FACTION_PLAYER))
213 if (wp->
target == PLAYER_ID)
250 if (shape==RADAR_RECT && (
ABS(x)>w/2. ||
ABS(y)>h/2.))
252 if (shape==RADAR_CIRCLE && (((x)*(x)+(y)*(y)) > rc))
285 glUseProgram(shaders.points.program);
286 glEnableVertexAttribArray(shaders.points.vertex);
287 glEnableVertexAttribArray(shaders.points.vertex_color);
288 gl_uniformMat4(shaders.points.projection, &gl_view_matrix);
291 glDrawArrays( GL_POINTS, 0, p );
292 glDisableVertexAttribArray(shaders.points.vertex);
293 glDisableVertexAttribArray(shaders.points.vertex_color);
304 w->solid->thrust = thrust;
312 w->solid->dir_vel = turn;
326 double t, turn_max,
d, jc, speed_mod;
328 if (w->target == w->parent)
352 jc = p->stats.jam_chance - w->outfit->u.lau.resist;
355 d = vec2_dist( &p->solid->pos, &w->solid->pos );
356 if (d < w->r * p->ew_evasion) {
365 weapon_setTurn( w, w->outfit->u.lau.turn * ((RNGF()>0.5)?-1.0:1.0) );
374 w->falloff = RNGF()*0.5;
387 if (w->outfit->u.lau.ai == AMMO_AI_SMART) {
390 vec2_cset( &v, p->solid->pos.x - w->solid->pos.x,
391 p->solid->pos.y - w->solid->pos.y );
392 t = vec2_odist( &v ) / w->outfit->u.lau.speed_max;
395 vec2_cset( &v, v.x + t*(p->solid->vel.x - w->solid->vel.x),
396 v.y + t*(p->solid->vel.y - w->solid->vel.y) );
399 diff = angle_diff(w->solid->dir, VANGLE(v) );
403 diff = angle_diff(w->solid->dir,
404 vec2_angle(&w->solid->pos, &p->solid->pos));
408 turn_max = w->outfit->u.lau.turn;
410 10 * diff * w->outfit->u.lau.turn ));
418 WARN(_(
"Unknown weapon status for '%s'"), w->outfit->name);
426 w->real_vel =
MIN( speed_mod * w->outfit->u.lau.speed_max, w->real_vel + w->outfit->u.lau.thrust*dt );
427 vec2_pset( &w->solid->vel, w->real_vel, w->solid->dir );
447 unsigned int turn_off;
459 mod = (w->outfit->type == OUTFIT_TYPE_BEAM) ? p->stats.fwd_energy : p->stats.tur_energy;
460 p->energy -= mod * dt*w->outfit->u.bem.energy;
462 if (p->energy < 0.) {
469 if (p->nav_asteroid != -1) {
470 field = &
cur_system->asteroids[p->nav_anchor];
471 ast = &field->
asteroids[p->nav_asteroid];
475 t = (w->target != w->parent) ?
pilot_get(w->target) : NULL;
505 w->solid->pos.x = p->solid->pos.x + v.x;
506 w->solid->pos.y = p->solid->pos.y + v.y;
509 switch (w->outfit->type) {
510 case OUTFIT_TYPE_BEAM:
511 if (w->outfit->u.bem.swivel > 0.)
512 w->solid->dir =
weapon_aimTurret( w->outfit, p, t, &w->
solid->
pos, &p->solid->vel, p->solid->dir, w->outfit->u.bem.swivel, 0. );
514 w->solid->dir = p->solid->dir;
517 case OUTFIT_TYPE_TURRET_BEAM:
521 t = (w->target != w->parent) ?
pilot_get(w->target) : NULL;
524 diff = angle_diff(w->solid->dir,
525 vec2_angle(&w->solid->pos, &ast->
pos));
528 diff = angle_diff(w->solid->dir, p->solid->dir);
531 diff = angle_diff(w->solid->dir,
532 vec2_angle(&w->solid->pos, &t->
solid->
pos));
535 10 * diff * w->outfit->u.bem.turn ));
571 case WEAPON_LAYER_BG:
574 case WEAPON_LAYER_FG:
579 WARN(_(
"Unknown weapon layer!"));
587 if (weapon_isFlag(w, WEAPON_FLAG_DESTROYED))
591 switch (w->outfit->type) {
594 case OUTFIT_TYPE_LAUNCHER:
595 case OUTFIT_TYPE_TURRET_LAUNCHER:
600 if (outfit_isProp(w->outfit, OUTFIT_PROP_WEAP_BLOWUP_ARMOUR))
603 else if (outfit_isProp(w->outfit, OUTFIT_PROP_WEAP_BLOWUP_SHIELD))
608 spfx_add( spfx, w->solid->pos.x, w->solid->pos.y,
609 w->solid->vel.x, w->solid->vel.y,
625 case OUTFIT_TYPE_BOLT:
626 case OUTFIT_TYPE_TURRET_BOLT:
631 if (outfit_isProp(w->outfit, OUTFIT_PROP_WEAP_BLOWUP_ARMOUR))
634 else if (outfit_isProp(w->outfit, OUTFIT_PROP_WEAP_BLOWUP_SHIELD))
639 spfx_add( spfx, w->solid->pos.x, w->solid->pos.y,
640 w->solid->vel.x, w->solid->vel.y,
654 else if (w->timer < w->falloff)
655 w->strength = w->timer / w->falloff;
659 case OUTFIT_TYPE_BEAM:
660 case OUTFIT_TYPE_TURRET_BEAM:
664 if (w->timer < 0. || (w->outfit->u.bem.min_duration > 0. &&
665 w->mount->stimer < 0.)) {
674 if (w->timer2 < 0.) {
682 WARN(_(
"Weapon of type '%s' has no update implemented yet!"),
688 if (!weapon_isFlag(w, WEAPON_FLAG_DESTROYED))
701 if (weapon_isFlag(layer[i],WEAPON_FLAG_DESTROYED)) {
720 case WEAPON_LAYER_BG:
723 case WEAPON_LAYER_FG:
728 WARN(_(
"Unknown weapon layer!"));
736static void weapon_renderBeam(
Weapon* w,
const double dt )
745 glUseProgram(shaders.beam.program);
753 projection = gl_view_matrix;
756 mat4_scale( &projection, w->outfit->u.bem.range*z,w->outfit->u.bem.width * z, 1. );
760 glEnableVertexAttribArray( shaders.beam.vertex );
765 gl_uniformMat4(shaders.beam.projection, &projection);
766 gl_uniformColor(shaders.beam.color, &w->outfit->u.bem.colour);
767 glUniform2f(shaders.beam.dimensions, w->outfit->u.bem.range, w->outfit->u.bem.width);
768 glUniform1f(shaders.beam.dt, w->anim);
769 glUniform1f(shaders.beam.r, w->r);
772 if (gl_has( OPENGL_SUBROUTINES ))
773 glUniformSubroutinesuiv( GL_FRAGMENT_SHADER, 1, &w->outfit->u.bem.shader );
776 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
779 glDisableVertexAttribArray( shaders.beam.vertex );
795 double x, y, z, r,
st;
796 glColour col,
c = { .r=1., .g=1., .b=1. };
799 if (weapon_isFlag(w,WEAPON_FLAG_DESTROYED))
802 switch (w->outfit->type) {
804 case OUTFIT_TYPE_LAUNCHER:
805 case OUTFIT_TYPE_TURRET_LAUNCHER:
810 r = gfx->
sw * z * 0.75;
812 st = 1. - w->timer2 / w->paramf;
816 glUseProgram( shaders.iflockon.program );
817 glUniform1f( shaders.iflockon.paramf,
st );
821 case OUTFIT_TYPE_BOLT:
822 case OUTFIT_TYPE_TURRET_BOLT:
829 if (outfit_isProp(w->outfit, OUTFIT_PROP_WEAP_SPIN)) {
837 if (w->sprite >= gfx->
sx*gfx->
sy)
845 w->solid->pos.x, w->solid->pos.y,
846 w->sprite % (
int)gfx->
sx, w->sprite / (
int)gfx->
sx, &
c );
849 w->sprite % (
int)gfx->
sx, w->sprite / (
int)gfx->
sx, &
c );
856 w->solid->pos.x, w->solid->pos.y, w->
sx, w->sy, &
c );
863 case OUTFIT_TYPE_BEAM:
864 case OUTFIT_TYPE_TURRET_BEAM:
865 weapon_renderBeam(w, dt);
869 WARN(_(
"Weapon of type '%s' has no render implemented yet!"),
887 if (pilot_isFlag(p, PILOT_INVINCIBLE))
891 if (pilot_isFlag(p, PILOT_HIDE))
895 if (pilot_isFlag(p, PILOT_LANDING) ||
896 pilot_isFlag(p, PILOT_TAKEOFF))
900 if (pilot_isFlag(p, PILOT_DEAD))
904 if ((w->faction == FACTION_PLAYER) &&
905 pilot_isFlag(p, PILOT_INVINC_PLAYER))
909 if (w->target == p->id)
913 if (p->faction == w->faction)
917 if (w->faction == FACTION_PLAYER) {
929 if (p->faction == FACTION_PLAYER) {
931 if (parent != NULL) {
954 unsigned int coll, usePoly, usePolyW = 1;
970 n = gfx->
sx * w->sy + w->sx;
976 if (
array_size(w->outfit->u.blt.polygon) == 0)
980 if (
array_size(w->outfit->u.lau.polygon) == 0)
988 if (w->outfit->type == OUTFIT_TYPE_BEAM) {
989 w->dam_mod = p->stats.fwd_damage;
990 w->dam_as_dis_mod = p->stats.fwd_dam_as_dis-1.;
993 w->dam_mod = p->stats.tur_damage;
994 w->dam_as_dis_mod = p->stats.tur_dam_as_dis-1.;
996 w->dam_as_dis_mod =
CLAMP( 0., 1., w->dam_as_dis_mod );
1004 if (pilot_isFlag(p, PILOT_DELETE))
1023 int k = p->ship->gfx_space->sx * psy + psx;
1025 w->outfit->u.bem.range, &p->ship->polygon[k],
1026 &p->solid->pos, crash);
1030 w->outfit->u.bem.range, p->ship->gfx_space, psx, psy,
1031 &p->solid->pos, crash);
1045 int k = p->ship->gfx_space->sx * psy + psx;
1047 polygon, &w->solid->pos, &crash[0] );
1051 p->ship->gfx_space, psx, psy,
1052 &p->solid->pos, &crash[0] );
1064 int k = p->ship->gfx_space->sx * psy + psx;
1066 polygon, &w->solid->pos, &crash[0] );
1070 p->ship->gfx_space, psx, psy,
1071 &p->solid->pos, &crash[0] );
1088 if ( vec2_dist2( &w->solid->pos, &ast->
pos ) >
1092 for (
int j=0; j<ast->
nb; j++) {
1094 if (a->state != ASTEROID_FG)
1099 if ( vec2_dist2( &w->solid->pos, &a->pos ) >
pow2( gfx->
sw/2. + a->gfx->sw/2. ) )
1104 if (a->polygon->npt == 0)
1111 polygon, &w->solid->pos, &crash[0] );
1117 a->gfx, 0, 0, &a->pos, &crash[0] );
1133 if (vec2_dist2( &w->solid->pos, &ast->
pos ) >
1137 for (
int j=0; j<ast->
nb; j++) {
1139 if (a->state != ASTEROID_FG)
1143 if ( vec2_dist2( &w->solid->pos, &a->pos ) >
pow2( w->outfit->u.bem.range + a->gfx->sw/2. ) )
1148 if (a->polygon->npt == 0)
1155 w->outfit->u.bem.range,
1156 &rpoly, &a->pos, crash );
1162 w->outfit->u.bem.range,
1163 a->gfx, 0, 0, &a->pos, crash );
1180 (*w->solid->update)(w->solid, dt);
1184 w->solid->vel.x, w->solid->vel.y);
1187 if (w->trail != NULL)
1204 dx = w->outfit->u.lau.trail_x_offset * cos(a);
1205 dy = w->outfit->u.lau.trail_x_offset * sin(a);
1208 if ((w->outfit->u.lau.ai == AMMO_AI_UNGUIDED) ||
1209 w->solid->vel.x*w->solid->vel.x + w->solid->vel.y*w->solid->vel.y + 1.
1210 < w->solid->speed_max*w->solid->speed_max)
1211 mode = MODE_AFTERBURN;
1212 else if (w->solid->dir_vel != 0.)
1217 spfx_trail_sample( w->trail, w->solid->pos.x + dx, w->solid->pos.y + dy*M_SQRT1_2, mode, 0 );
1230 if (shooter == NULL)
1238 if (pilot_isDisabled(p))
1242 if (pilot_isFlag(p, PILOT_DELETE) || pilot_isFlag(p, PILOT_DEAD) || pilot_isFlag( p, PILOT_HIDE ))
1246 if (shooter->
faction == FACTION_PLAYER) {
1248 p->player_damage += dmg / (p->shield_max + p->armour_max);
1251 if ((p->player_damage > PILOT_HOSTILE_THRESHOLD) ||
1252 (shooter->
target==p->id)) {
1275 WeaponLayer spfx_layer;
1282 damage = w->dam_mod * w->strength * odmg->
damage;
1283 dmg.
damage =
MAX( 0., damage * (1.-w->dam_as_dis_mod) );
1286 dmg.
disable =
MAX( 0., w->dam_mod * w->strength * odmg->
disable + damage * w->dam_as_dis_mod );
1298 damage =
pilot_hit( p, w->solid, parent, &dmg, w->outfit, w->lua_mem, 1 );
1301 spfx_layer = (p==
player.
p) ? SPFX_LAYER_FRONT : SPFX_LAYER_MIDDLE;
1309 VX(p->solid->vel), VY(p->solid->vel), spfx_layer );
1326 if (w->outfit->lua_onmiss != LUA_NOREF) {
1329 lua_rawgeti(naevL, LUA_REGISTRYINDEX, w->lua_mem);
1330 nlua_setenv(naevL, w->outfit->lua_env,
"mem");
1333 lua_rawgeti(naevL, LUA_REGISTRYINDEX, w->outfit->lua_onmiss);
1337 if (nlua_pcall( w->outfit->lua_env, 3, 0 )) {
1338 WARN( _(
"Outfit '%s' -> '%s':\n%s"), w->outfit->name,
"onmiss", lua_tostring(naevL,-1) );
1360 double mining_bonus;
1380 spfx_add( spfx, pos->
x, pos->
y,VX(a->vel), VY(a->vel), layer );
1399 vec2 pos[2],
const double dt )
1405 WeaponLayer spfx_layer;
1412 damage = w->dam_mod * w->strength * odmg->
damage * dt ;
1413 dmg.
damage =
MAX( 0., damage * (1.-w->dam_as_dis_mod) );
1416 dmg.
disable =
MAX( 0., w->dam_mod * w->strength * odmg->
disable * dt + damage * w->dam_as_dis_mod );
1419 damage =
pilot_hit( p, w->solid, parent, &dmg, w->outfit, w->lua_mem, 1 );
1422 if (w->timer2 == -1.) {
1424 spfx_layer = (p==
player.
p) ? SPFX_LAYER_FRONT : SPFX_LAYER_MIDDLE;
1433 spfx_add( spfx, pos[0].x, pos[0].y,
1434 VX(p->solid->vel), VY(p->solid->vel), spfx_layer );
1435 spfx_add( spfx, pos[1].x, pos[1].y,
1436 VX(p->solid->vel), VY(p->solid->vel), spfx_layer );
1454 vec2 pos[2],
const double dt )
1460 double mining_bonus;
1474 if (w->timer2 == -1.) {
1478 spfx_add( spfx, pos[0].x, pos[0].y,
1479 VX(a->vel), VY(a->vel), SPFX_LAYER_MIDDLE );
1480 spfx_add( spfx, pos[1].x, pos[1].y,
1481 VX(a->vel), VY(a->vel), SPFX_LAYER_MIDDLE );
1499 const Pilot *pilot_target,
const vec2 *pos,
const vec2 *vel,
double dir,
1500 double swivel,
double time )
1502 vec2 *target_pos, *target_vel;
1503 double rx, ry, x, y, t, lead, rdir, off;
1505 if (pilot_target != NULL) {
1506 target_pos = &pilot_target->
solid->
pos;
1507 target_vel = &pilot_target->
solid->
vel;
1515 target_pos = &ast->
pos;
1516 target_vel = &ast->
vel;
1520 rx = target_pos->
x - pos->
x;
1521 ry = target_pos->
y - pos->
y;
1529 x = (target_pos->
x + target_vel->
x*t) - (pos->
x + vel->
x*t);
1530 y = (target_pos->
y + target_vel->
y*t) - (pos->
y + vel->
y*t);
1533 if (pilot_target != NULL) {
1538 x = lead * x + (1.-lead) * rx;
1539 y = lead * y + (1.-lead) * ry;
1551 double tt, ddir, dtdd, acc, pxv, ang, dvx, dvy;
1556 dvx = lead * (target_vel->
x - vel->
x);
1557 dvy = lead * (target_vel->
y - vel->
y);
1561 pxv = rx*dvy - ry*dvx;
1562 ang = atan2( pxv, rx*dvx+ry*dvy );
1563 if (fabs(ang + M_PI) < fabs(ang))
1565 else if (fabs(ang - M_PI) < fabs(ang))
1573 if (fabs(ang) > 1e-7) {
1574 for (
int i=0; i<niter; i++) {
1581 if (tt < 0. || fabs(
d) < 5.)
1585 rdir = rdir -
d/dtdd;
1592 off = angle_diff( rdir, dir );
1593 if (
FABS(off) > swivel) {
1595 rdir = dir - swivel;
1597 rdir = dir + swivel;
1617 double vmin,
double acc,
double *tt )
1619 double l, dxv, dxp, ct,
st,
d;
1622 ct = cos(rdir);
st = sin(rdir);
1625 dxv = ct*dvy -
st*dvx;
1626 dxp = ct*ry -
st*rx;
1631 d = .5*acc*(*tt)*(*tt) + vmin*(*tt);
1650 const double dir,
const vec2* pos,
const vec2* vel,
const Pilot* parent,
double time,
int aim )
1653 double mass, rdir, acc, m;
1654 Pilot *pilot_target;
1658 if ((w->parent!=w->target) && (w->target != 0))
1661 pilot_target = NULL;
1676 if (outfit->
type == OUTFIT_TYPE_TURRET_BOLT) {
1687 w->dam_as_dis_mod =
CLAMP( 0., 1., w->dam_as_dis_mod );
1690 rdir += RNG_2SIGMA() * acc;
1693 else if (rdir >= 2.*M_PI)
1701 vec2_cadd( &v, m*cos(rdir), m*sin(rdir));
1704 w->solid = solid_create( mass, rdir, pos, &v, SOLID_UPDATE_EULER );
1730 const double dir,
const vec2* pos,
const vec2* vel,
const Pilot* parent,
double time,
int aim )
1734 double mass, rdir, m;
1735 Pilot *pilot_target;
1739 if ((w->parent!=w->target) && (w->target != 0))
1742 pilot_target = NULL;
1745 if (outfit->
type == OUTFIT_TYPE_TURRET_LAUNCHER)
1746 rdir =
weapon_aimTurret( outfit, parent, pilot_target, pos, vel, dir, M_PI, time );
1762 while (rdir >= 2.*M_PI)
1773 vec2_cadd( &v, m * cos(rdir), m * sin(rdir) );
1774 w->real_vel = VMOD(v);
1777 mass = w->outfit->mass;
1779 w->solid = solid_create( mass, rdir, pos, &v, SOLID_UPDATE_EULER );
1780 if (w->outfit->u.lau.thrust > 0.) {
1783 w->solid->speed_max = w->outfit->u.lau.speed_max;
1784 if (w->outfit->u.lau.speed > 0.)
1785 w->solid->speed_max = -1;
1789 if (w->outfit->u.lau.ai != AMMO_AI_UNGUIDED) {
1798 if (pilot_target == NULL)
1800 if (pilot_target != NULL)
1818 if (w->outfit->u.lau.trail_spec != NULL)
1837 const double dir,
const vec2* pos,
const vec2* vel,
1838 const Pilot* parent,
const unsigned int target,
double time,
int aim )
1841 Pilot *pilot_target;
1848 w = calloc( 1,
sizeof(
Weapon) );
1850 w->dam_as_dis_mod = 0.;
1852 w->parent = parent->
id;
1854 w->lua_mem = LUA_NOREF;
1855 if (po != NULL && po->
lua_mem != LUA_NOREF) {
1856 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->
lua_mem);
1857 w->lua_mem = luaL_ref( naevL, LUA_REGISTRYINDEX );
1866 if (pilot_target != NULL)
1870 switch (outfit->
type) {
1873 case OUTFIT_TYPE_BOLT:
1874 case OUTFIT_TYPE_TURRET_BOLT:
1879 case OUTFIT_TYPE_BEAM:
1880 case OUTFIT_TYPE_TURRET_BEAM:
1882 if (aim && (outfit->
type == OUTFIT_TYPE_TURRET_BEAM)) {
1884 if ((w->parent != w->target) && (pilot_target != NULL))
1885 rdir = vec2_angle(pos, &pilot_target->
solid->
pos);
1889 rdir = vec2_angle(pos, &ast->
pos);
1895 else if (rdir >= 2.*M_PI)
1899 w->solid = solid_create( mass, rdir, pos, vel, SOLID_UPDATE_EULER );
1908 if (outfit->
type == OUTFIT_TYPE_BEAM) {
1916 w->dam_as_dis_mod =
CLAMP( 0., 1., w->dam_as_dis_mod );
1921 case OUTFIT_TYPE_LAUNCHER:
1922 case OUTFIT_TYPE_TURRET_LAUNCHER:
1928 WARN(_(
"Weapon of type '%s' has no create implemented yet!"),
1930 w->solid = solid_create( 1., dir, pos, vel, SOLID_UPDATE_EULER );
1955 const Pilot *parent,
unsigned int target,
double time,
int aim )
1963 ERR(_(
"Trying to create a Weapon from a non-Weapon type Outfit"));
1967 layer = (parent->
id==PLAYER_ID) ? WEAPON_LAYER_FG : WEAPON_LAYER_BG;
1968 w =
weapon_create( po, T, dir, pos, vel, parent, target, time, aim );
1972 case WEAPON_LAYER_BG:
1975 case WEAPON_LAYER_FG:
1980 WARN(_(
"Unknown weapon layer!"));
2013 const double dir,
const vec2* pos,
const vec2* vel,
2014 const Pilot *parent,
const unsigned int target,
int aim )
2022 ERR(_(
"Trying to create a Beam Weapon from a non-beam outfit."));
2026 layer = (parent->
id==PLAYER_ID) ? WEAPON_LAYER_FG : WEAPON_LAYER_BG;
2027 w =
weapon_create( po, 0., dir, pos, vel, parent, target, 0., aim );
2034 case WEAPON_LAYER_BG:
2037 case WEAPON_LAYER_FG:
2042 ERR(_(
"Invalid WEAPON_LAYER specified"));
2067void beam_end(
const unsigned int parent,
unsigned int beam )
2072 layer = (parent==PLAYER_ID) ? WEAPON_LAYER_FG : WEAPON_LAYER_BG;
2076 case WEAPON_LAYER_BG:
2079 case WEAPON_LAYER_FG:
2084 ERR(_(
"Invalid WEAPON_LAYER specified"));
2090 WARN(_(
"Trying to remove beam with ID 0!"));
2097 if (curLayer[i]->ID == beam) {
2112 weapon_setFlag( w, WEAPON_FLAG_DESTROYED );
2135 if (pilot_target != NULL) {
2143 solid_free(w->solid);
2149 luaL_unref( naevL, LUA_REGISTRYINDEX, w->lua_mem );
2152 memset(w, 0,
sizeof(
Weapon));
2200 int dtype,
double damage,
2201 const Pilot *parent,
int mode )
2213 double x,
double y,
double radius,
2214 const Pilot *parent,
int mode )
2222 case WEAPON_LAYER_BG:
2225 case WEAPON_LAYER_FG:
2230 ERR(_(
"Invalid WEAPON_LAYER specified"));
2234 rad2 = radius*radius;
2239 ((mode & EXPL_MODE_BOLT) &&
outfit_isBolt(curLayer[i]->outfit))) {
2241 double dist =
pow2(curLayer[i]->solid->pos.x - x) +
2242 pow2(curLayer[i]->solid->pos.y - y);
void ai_attacked(Pilot *attacked, const unsigned int attacker, double dmg)
Triggers the attacked() function in the pilot's 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_erase(ptr_array, first, last)
Erases elements in interval [first, last).
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
#define array_begin(array)
Returns a pointer to the beginning of the reserved memory space.
#define array_reserved(array)
Returns number of elements reserved.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
void asteroid_hit(Asteroid *a, const Damage *dmg, int max_rarity, double mining_bonus)
Hits an asteroid.
double cam_getZoom(void)
Gets the camera zoom.
void RotatePolygon(CollPoly *rpolygon, CollPoly *ipolygon, float theta)
Rotates a polygon.
int CollideLinePolygon(const vec2 *ap, double ad, double al, const CollPoly *bt, const vec2 *bp, vec2 crash[2])
Checks to see if a line collides with a polygon.
int CollideLineSprite(const vec2 *ap, double ad, double al, const glTexture *bt, const int bsx, const int bsy, const vec2 *bp, vec2 crash[2])
Checks to see if a line collides with a sprite.
int CollideSprite(const glTexture *at, const int asx, const int asy, const vec2 *ap, const glTexture *bt, const int bsx, const int bsy, const vec2 *bp, vec2 *crash)
Checks whether or not two sprites collide.
int CollidePolygon(const CollPoly *at, const vec2 *ap, const CollPoly *bt, const vec2 *bp, vec2 *crash)
Checks whether or not two polygons collide. /!\ The function is not symmetric: the points of polygon ...
void col_blend(glColour *blend, const glColour *fg, const glColour *bg, float alpha)
Blends two colours.
int areEnemies(int a, int b)
Checks whether two factions are enemies.
void mat4_translate(mat4 *m, double x, double y, double z)
Translates a homogenous transformation matrix.
void mat4_scale(mat4 *m, double x, double y, double z)
Scales a homogeneous transformation matrix.
void mat4_rotate2d(mat4 *m, double angle)
Rotates an angle, in radians, around the z axis.
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.
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_gameToScreenCoords(double *nx, double *ny, double bx, double by)
Converts in-game coordinates to screen coordinates.
void gl_renderSpriteInterpolate(const glTexture *sa, const glTexture *sb, double inter, double bx, double by, int sx, int sy, const glColour *c)
Blits a sprite interpolating, position is relative to the player.
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_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_vboDestroy(gl_vbo *vbo)
Destroys a VBO.
gl_vbo * gl_vboCreateStream(GLsizei size, const void *data)
Creates a stream vbo.
void gl_vboActivateAttribOffset(gl_vbo *vbo, GLuint index, GLuint offset, GLint size, GLenum type, GLsizei stride)
Activates a VBO's offset.
void gl_vboData(gl_vbo *vbo, GLsizei size, const void *data)
Reloads new data or grows the size of the vbo.
void gl_vboSubData(gl_vbo *vbo, GLint offset, GLsizei size, const void *data)
Loads some data into the VBO.
double outfit_trackmin(const Outfit *o)
Gets the outfit's minimal tracking.
int outfit_isBeam(const Outfit *o)
Checks if outfit is a beam type weapon.
int outfit_soundHit(const Outfit *o)
Gets the outfit's hit sound.
int outfit_isLauncher(const Outfit *o)
Checks if outfit is a weapon launcher.
int outfit_isSeeker(const Outfit *o)
Checks if outfit is a seeking weapon.
int outfit_miningRarity(const Outfit *o)
Gets the maximum rarity the outfit can mine up to.
int outfit_spfxShield(const Outfit *o)
Gets the outfit's sound effect.
const CollPoly * outfit_plg(const Outfit *o)
Gets the outfit's collision polygon.
const glTexture * outfit_gfx(const Outfit *o)
Gets the outfit's graphic effect.
double outfit_spin(const Outfit *o)
Gets the outfit's animation spin.
double outfit_trackmax(const Outfit *o)
Gets the outfit's minimal tracking.
int outfit_spfxArmour(const Outfit *o)
Gets the outfit's sound effect.
const Damage * outfit_damage(const Outfit *o)
Gets the outfit's damage.
int outfit_isBolt(const Outfit *o)
Checks if outfit is bolt type weapon.
int pilot_isHostile(const Pilot *p)
Checks to see if pilot is hostile to the player.
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
void pilot_setHostile(Pilot *p)
Marks pilot as hostile to player.
static Pilot ** pilot_stack
Pilot *const * pilot_getAll(void)
Gets 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.
double pilot_ewWeaponTrack(const Pilot *p, const Pilot *t, double trackmin, double trackmax)
Calculates the weapon lead (1. is 100%, 0. is 0%)..
int pilot_inRange(const Pilot *p, double x, double y)
Check to see if a position is in range of the pilot.
double pilot_heatAccuracyMod(double T)
Returns a 0:1 modifier representing accuracy (0. being normal).
void pilot_heatAddSlotTime(const Pilot *p, PilotOutfitSlot *o, double dt)
Adds heat to an outfit slot over a period of time.
int pilot_getMount(const Pilot *p, const PilotOutfitSlot *w, vec2 *v)
Gets the mount position of a pilot.
void pilot_stopBeam(Pilot *p, PilotOutfitSlot *w)
Stops a beam outfit and sets delay as appropriate.
int sound_playPos(int sound, double px, double py, double vx, double vy)
Plays a sound based on position.
void sound_stop(int voice)
Stops a voice from playing.
int sound_updatePos(int voice, double px, double py, double vx, double vy)
Updates the position of a voice.
int space_isSimulationEffects(void)
returns whether or not we're simulating with effects.
void spfx_trail_sample(Trail_spfx *trail, double x, double y, TrailMode mode, int force)
Makes a trail grow.
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.
Trail_spfx * spfx_trail_create(const TrailSpec *spec)
Initalizes a trail.
Represents an asteroid field anchor.
Represents a single asteroid.
Represents a polygon used for collision detection.
Core damage that an outfit does.
A ship outfit, depends radically on the type.
Stores an outfit the pilot has.
The representation of an in-game pilot.
double launch_calibration
Represents a solid in the game.
A trail generated by a ship or an ammo.
In-game representation of a weapon.
Abstraction for rendering sprite sheets.
void weapon_add(PilotOutfitSlot *po, const double T, const double dir, const vec2 *pos, const vec2 *vel, const Pilot *parent, unsigned int target, double time, int aim)
Creates a new weapon.
static void weapon_render(Weapon *w, const double dt)
Renders an individual weapon.
void beam_end(const unsigned int parent, unsigned int beam)
Ends a beam weapon.
static void weapon_sample_trail(Weapon *w)
Updates the animated trail for a weapon.
static int weapon_checkCanHit(const Weapon *w, const Pilot *p)
Checks to see if the weapon can hit the pilot.
void weapons_render(const WeaponLayer layer, const double dt)
Renders all the weapons in a layer.
static void weapon_destroy(Weapon *w)
Destroys a weapon.
static gl_vbo * weapon_vbo
static double weapon_computeTimes(double rdir, double rx, double ry, double dvx, double dvy, double pxv, double vmin, double acc, double *tt)
Computes precisely interception times for propelled weapons (rockets).
static Weapon * weapon_create(PilotOutfitSlot *po, double T, const double dir, const vec2 *pos, const vec2 *vel, const Pilot *parent, const unsigned int target, double time, int aim)
Creates a new weapon.
static void weapon_hitAstBeam(Weapon *w, Asteroid *a, WeaponLayer layer, vec2 pos[2], const double dt)
Weapon hit an asteroid.
static void weapon_update(Weapon *w, const double dt, WeaponLayer layer)
Updates an individual weapon.
static void weapons_updateLayer(const double dt, const WeaponLayer layer)
Updates all the weapons in the layer.
static void weapon_setTurn(Weapon *w, double turn)
Sets the weapon's turn.
void weapon_clear(void)
Clears all the weapons, does NOT free the layers.
void weapons_update(const double dt)
Updates all the weapon layers.
void weapon_minimap(const double res, const double w, const double h, const RadarShape shape, double alpha)
Draws the minimap weapons (used in player.c).
void weapon_explode(double x, double y, double radius, int dtype, double damage, const Pilot *parent, int mode)
Clears possible exploded weapons.
#define weapon_isSmart(w)
static void weapon_setThrust(Weapon *w, double thrust)
Sets the weapon's thrust.
void weapon_hitAI(Pilot *p, const Pilot *shooter, double dmg)
Informs the AI if needed that it's been hit.
static GLfloat * weapon_vboData
static void weapon_hit(Weapon *w, Pilot *p, vec2 *pos)
Weapon hit the pilot.
unsigned int beam_start(PilotOutfitSlot *po, const double dir, const vec2 *pos, const vec2 *vel, const Pilot *parent, const unsigned int target, int aim)
Starts a beam weapon.
static void weapon_hitBeam(Weapon *w, Pilot *p, WeaponLayer layer, vec2 pos[2], const double dt)
Weapon hit the pilot.
static void think_seeker(Weapon *w, const double dt)
The AI of seeker missiles.
static void weapon_hitAst(Weapon *w, Asteroid *a, WeaponLayer layer, vec2 *pos)
Weapon hit an asteroid.
static double weapon_aimTurret(const Outfit *outfit, const Pilot *parent, const Pilot *pilot_target, const vec2 *pos, const vec2 *vel, double dir, double swivel, double time)
Gets the aim position of a turret weapon.
static void weapon_free(Weapon *w)
Frees the weapon.
static void weapon_miss(Weapon *w)
Weapon missed and is due to be destroyed.
void weapon_exit(void)
Destroys all the weapons and frees it all.
static unsigned int beam_idgen
static void weapons_purgeLayer(Weapon **layer)
Purges weapons marked for deletion.
void weapon_init(void)
Initializes the weapon stuff.
static size_t weapon_vboSize
static void weapon_createAmmo(Weapon *w, const Outfit *outfit, double T, const double dir, const vec2 *pos, const vec2 *vel, const Pilot *parent, double time, int aim)
Creates the ammo specific properties of a weapon.
static void weapon_createBolt(Weapon *w, const Outfit *outfit, double T, const double dir, const vec2 *pos, const vec2 *vel, const Pilot *parent, double time, int aim)
Creates the bolt specific properties of a weapon.
static void weapon_explodeLayer(WeaponLayer layer, double x, double y, double radius, const Pilot *parent, int mode)
Explodes all the things on a layer.
static void think_beam(Weapon *w, const double dt)
The pseudo-ai of the beam weapons.
static Weapon ** wbackLayer
@ WEAPON_STATUS_JAMMED_SLOWED
static Weapon ** wfrontLayer