15#include "SDL_thread.h"
25#include "damagetype.h"
32#include "nlua_pilotoutfit.h"
33#include "nlua_outfit.h"
34#include "nlua_camera.h"
40#include "pilot_heat.h"
46#define outfit_setProp(o,p) ((o)->properties |= p)
48#define XML_OUTFIT_TAG "outfit"
50#define OUTFIT_SHORTDESC_MAX STRMAX_SHORT
61#define SDESC_ADD( l, temp, txt, args... ) \
62(l) += scnprintf( &(temp)->summary_raw[l], OUTFIT_SHORTDESC_MAX-(l), (txt), ## args )
63#define SDESC_COLOUR( l, temp, txt, val, args... ) \
64SDESC_ADD( l, temp, "#%c", ((val)>0)?'g':(((val)<0)?'r':'0') ); \
65SDESC_ADD( l, temp, txt, (val), ## args ); \
66SDESC_ADD( l, temp, "#0" )
68#define SDESC_COLOURT( l, temp, txt, threshold, val, args... ) \
69SDESC_ADD( l, temp, "#%c", ((val)>threshold)?'g':(((val)<threshold)?'r':'0') ); \
70SDESC_ADD( l, temp, txt, (val), ## args ); \
71SDESC_ADD( l, temp, "#0" )
73#define SDESC_COND( l, temp, txt, val, args... ) \
74if (fabs(val) > 1e-5) { \
75 SDESC_ADD( l, temp, txt, (val), ## args ); \
77#define SDESC_COND_COLOUR( l, temp, txt, val, args... ) \
78if (fabs(val) > 1e-5) { \
79 SDESC_COLOUR( l, temp, txt, (val), ## args ); \
104static int outfit_cmp(
const void *p1,
const void *p2 )
109 return strcmp( o1->
name, o2->
name );
122 WARN(_(
"Outfit '%s' not found in stack."), name);
167 names = malloc(
sizeof(
char*) * nstack );
171 for (
int i=0; i<nstack; i++) {
201 o1 = * (
const Outfit**) outfit1;
202 o2 = * (
const Outfit**) outfit2;
252 return strcmp( o1->
name, o2->
name );
255int outfit_filterWeapon(
const Outfit *o )
258int outfit_filterUtility(
const Outfit *o )
261int outfit_filterStructure(
const Outfit *o )
264int outfit_filterCore(
const Outfit *o )
267int outfit_filterOther(
const Outfit *o )
270 || (o->
slot.
type == OUTFIT_SLOT_NA)));
290 case OUTFIT_SLOT_NULL:
293 return gettext_noop(
"N/A");
294 case OUTFIT_SLOT_STRUCTURE:
295 return gettext_noop(
"Structure");
296 case OUTFIT_SLOT_UTILITY:
297 return gettext_noop(
"Utility");
298 case OUTFIT_SLOT_WEAPON:
299 return gettext_noop(
"Weapon");
301 return gettext_noop(
"Unknown");
311 case OUTFIT_SLOT_SIZE_NA:
312 return gettext_noop(
"N/A");
313 case OUTFIT_SLOT_SIZE_LIGHT:
314 return gettext_noop(
"Small");
315 case OUTFIT_SLOT_SIZE_MEDIUM:
316 return gettext_noop(
"Medium");
317 case OUTFIT_SLOT_SIZE_HEAVY:
318 return gettext_noop(
"Large");
320 return gettext_noop(
"Unknown");
343 if (os->
size == OUTFIT_SLOT_SIZE_HEAVY)
344 return &cOutfitHeavy;
345 else if (os->
size == OUTFIT_SLOT_SIZE_MEDIUM)
346 return &cOutfitMedium;
347 else if (os->
size == OUTFIT_SLOT_SIZE_LIGHT)
348 return &cOutfitLight;
360 if (os->
size == OUTFIT_SLOT_SIZE_HEAVY)
362 else if (os->
size == OUTFIT_SLOT_SIZE_MEDIUM)
364 else if (os->
size == OUTFIT_SLOT_SIZE_LIGHT)
377 if (os->
type == OUTFIT_SLOT_WEAPON)
379 else if (os->
type == OUTFIT_SLOT_UTILITY)
381 else if (os->
type == OUTFIT_SLOT_STRUCTURE)
396 size_t p =
scnprintf( &buf[0], size,
"%s", _(outfit->
name) );
397 if (outfit->
slot.
type != OUTFIT_SLOT_NA) {
398 p +=
scnprintf( &buf[p], size-p, _(
"\n#%c%s #%c%s #0slot"),
415 return OUTFIT_SLOT_SIZE_NA;
418 if (strcasecmp(s,
"Large")==0)
419 return OUTFIT_SLOT_SIZE_HEAVY;
420 else if (strcasecmp(s,
"Medium")==0)
421 return OUTFIT_SLOT_SIZE_MEDIUM;
422 else if (strcasecmp(s,
"Small")==0)
423 return OUTFIT_SLOT_SIZE_LIGHT;
425 WARN(_(
"'%s' does not match any outfit slot sizes."), s);
426 return OUTFIT_SLOT_SIZE_NA;
470 return ( (o->
type==OUTFIT_TYPE_BOLT) ||
471 (o->
type==OUTFIT_TYPE_BEAM) );
480 return ( (o->
type==OUTFIT_TYPE_BOLT) ||
481 (o->
type==OUTFIT_TYPE_TURRET_BOLT) );
490 return ( (o->
type==OUTFIT_TYPE_BEAM) ||
491 (o->
type==OUTFIT_TYPE_TURRET_BEAM) );
500 return ( (o->
type==OUTFIT_TYPE_LAUNCHER) ||
501 (o->
type==OUTFIT_TYPE_TURRET_LAUNCHER) );
510 if (((o->
type==OUTFIT_TYPE_TURRET_LAUNCHER) ||
511 (o->
type==OUTFIT_TYPE_LAUNCHER)) &&
523 return ((o->
type==OUTFIT_TYPE_TURRET_BOLT) ||
524 (o->
type==OUTFIT_TYPE_TURRET_BEAM) ||
525 (o->
type==OUTFIT_TYPE_TURRET_LAUNCHER));
534 return (o->
type==OUTFIT_TYPE_MODIFICATION);
543 return (o->
type==OUTFIT_TYPE_AFTERBURNER);
552 return (o->
type==OUTFIT_TYPE_FIGHTER_BAY);
561 return (o->
type==OUTFIT_TYPE_MAP);
570 return (o->
type==OUTFIT_TYPE_LOCALMAP);
579 return (o->
type==OUTFIT_TYPE_LICENSE);
588 return (o->
type==OUTFIT_TYPE_GUI);
598 return (o->
properties & OUTFIT_PROP_WEAP_SECONDARY) != 0;
725 if (at < o->u.lau.duration)
757 if (t < o->u.lau.duration)
881 const char* outfit_typename[] = {
888 N_(
"Turret Launcher"),
889 N_(
"Ship Modification"),
901 return outfit_typename[o->
type];
923 else return N_(
"Unknown");
933 const char *ai_type[] = {
940 WARN(_(
"Outfit '%s' is not a launcher outfit"), o->
name);
944 return ai_type[o->
u.
lau.
ai];
986 if ((os->
type == OUTFIT_SLOT_NULL) ||
987 (os->
type == OUTFIT_SLOT_NA))
1030 if ((os->
type == OUTFIT_SLOT_NULL) ||
1031 (os->
type == OUTFIT_SLOT_NA))
1053if (strcasecmp(buf,(s))==0) return t
1062 O_CMP(
"bolt", OUTFIT_TYPE_BOLT);
1063 O_CMP(
"beam", OUTFIT_TYPE_BEAM);
1064 O_CMP(
"turret bolt", OUTFIT_TYPE_TURRET_BOLT);
1065 O_CMP(
"turret beam", OUTFIT_TYPE_TURRET_BEAM);
1066 O_CMP(
"launcher", OUTFIT_TYPE_LAUNCHER);
1067 O_CMP(
"turret launcher",OUTFIT_TYPE_TURRET_LAUNCHER);
1068 O_CMP(
"modification", OUTFIT_TYPE_MODIFICATION);
1069 O_CMP(
"afterburner", OUTFIT_TYPE_AFTERBURNER);
1070 O_CMP(
"fighter bay", OUTFIT_TYPE_FIGHTER_BAY);
1071 O_CMP(
"map", OUTFIT_TYPE_MAP);
1072 O_CMP(
"localmap", OUTFIT_TYPE_LOCALMAP);
1073 O_CMP(
"license", OUTFIT_TYPE_LICENSE);
1074 O_CMP(
"gui", OUTFIT_TYPE_GUI);
1076 WARN(_(
"Invalid outfit type: '%s'"),buf);
1077 return OUTFIT_TYPE_NULL;
1089 SDESC_ADD( *l, temp,
"\n#g%s#0", _(
"Can mine uncommon and rare minerals") );
1091 SDESC_ADD( *l, temp,
"\n#g%s#0", _(
"Can mine uncommon minerals") );
1116 cur = node->xmlChildrenNode;
1118 xml_onlyNodes( cur );
1122 xmlr_float( cur,
"physical", dmg->
damage );
1123 xmlr_float( cur,
"disable", dmg->
disable );
1126 if (xml_isNode(cur,
"type")) {
1127 char *buf = xml_get( cur );
1129 if (dmg->
type < 0) {
1131 WARN(_(
"Unknown damage type '%s'"), buf);
1134 else WARN(_(
"Damage has unknown node '%s'"), cur->name);
1136 }
while (xml_nextNode(cur));
1156 xmlNodePtr node, cur;
1158 asprintf( &file,
"%s%s.xml", OUTFIT_POLYGON_PATH, buf );
1161 if (!PHYSFS_exists(file)) {
1162 WARN(_(
"%s xml collision polygon does not exist!\n \
1163 Please use the script 'polygon_from_sprite.py' \
1164that can be found in Naev's artwork repo."), file);
1177 node = doc->xmlChildrenNode;
1180 WARN(_(
"Malformed %s file: does not contain elements"), file);
1189 if (xml_isNode(node,
"polygons")) {
1190 cur = node->children;
1193 if (xml_isNode(cur,
"polygon")) {
1197 }
while (xml_nextNode(cur));
1199 }
while (xml_nextNode(node));
1203 if (xml_isNode(node,
"polygons")) {
1204 cur = node->children;
1207 if (xml_isNode(cur,
"polygon")) {
1211 }
while (xml_nextNode(cur));
1213 }
while (xml_nextNode(node));
1232 double dshield, darmour, dknockback;
1245 node = parent->xmlChildrenNode;
1247 xml_onlyNodes(node);
1248 xmlr_float(node,
"speed",temp->
u.
blt.
speed);
1249 xmlr_float(node,
"delay",temp->
u.
blt.
delay);
1250 xmlr_float(node,
"energy",temp->
u.
blt.
energy);
1251 xmlr_float(node,
"heatup",temp->
u.
blt.
heatup);
1254 xmlr_float(node,
"swivel",temp->
u.
blt.
swivel);
1257 xmlr_int(node,
"shots",temp->
u.
blt.
shots);
1259 xmlr_strd(node,
"lua",temp->
lua_file);
1260 if (xml_isNode(node,
"range")) {
1261 xmlr_attr_strd(node,
"blowup",buf);
1263 if (strcmp(buf,
"armour")==0)
1265 else if (strcmp(buf,
"shield")==0)
1268 WARN(_(
"Outfit '%s' has invalid blowup property: '%s'"),
1278 if (xml_isNode(node,
"gfx")) {
1280 OUTFIT_GFX_PATH
"space/%s", 6, 6,
1281 OPENGL_TEX_MAPTRANS | OPENGL_TEX_MIPMAPS );
1282 xmlr_attr_strd(node,
"spin", buf);
1289 buf = xml_get(node);
1294 WARN(_(
"Outfit '%s': the number of collision polygons is wrong.\n \
1295 npolygon = %i and sx*sy = %i"),
1300 if (xml_isNode(node,
"gfx_end")) {
1302 OUTFIT_GFX_PATH
"space/%s", 6, 6,
1303 OPENGL_TEX_MAPTRANS | OPENGL_TEX_MIPMAPS );
1308 if (xml_isNode(node,
"spfx_shield")) {
1312 if (xml_isNode(node,
"spfx_armour")) {
1318 if (xml_isNode(node,
"sound")) {
1322 if (xml_isNode(node,
"sound_hit")) {
1326 if (xml_isNode(node,
"damage")) {
1338 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, node->name);
1339 }
while (xml_nextNode(node));
1357 temp->
u.
blt.
heat = ((800.-CONST_SPACE_STAR_TEMP)*
C +
1358 STEEL_HEAT_CONDUCTIVITY * ((800-CONST_SPACE_STAR_TEMP) * area)) /
1367 SDESC_COLOURT( l, temp, _(
"\n %.0f%% vs armour"), 100., darmour*100. );
1368 SDESC_COLOURT( l, temp, _(
"\n %.0f%% vs shield"), 100., dshield*100. );
1369 SDESC_COND( l, temp, _(
"\n %.0f%% knockback"), dknockback*100. );
1370 SDESC_COND_COLOUR( l, temp, _(
"\n%.0f CPU"), temp->
cpu );
1371 SDESC_COND( l, temp, _(
"\n%.0f Mass"), temp->
mass );
1373 SDESC_COND( l, temp, _(
"\n%.2f DPS [%.0f Damage]"),
1375 SDESC_COND( l, temp, _(
"\n%.2f Disable/s [%.0f Disable]"),
1377 SDESC_ADD( l, temp, _(
"\n%.1f Shots Per Second"), 1./temp->
u.
blt.
delay );
1378 SDESC_COND( l, temp, _(
"\n%.1f EPS [%.0f Energy]"),
1381 SDESC_ADD( l, temp, _(
"\n%.0f Speed"), temp->
u.
blt.
speed );
1382 SDESC_COND( l, temp, _(
"\n%.1f second heat up"), temp->
u.
blt.
heatup);
1383 SDESC_COND( l, temp, _(
"\n%.1f Degree Dispersion"), temp->
u.
blt.
dispersion*180./M_PI );
1385 SDESC_ADD( l, temp, _(
"\n%.1f Degree Swivel"), temp->
u.
blt.
swivel*180./M_PI );
1390#define MELEMENT(o,s) \
1391if (o) WARN(_("Outfit '%s' missing/invalid '%s' element"), temp->name, s)
1396 MELEMENT(temp->
mass==0.,
"mass");
1422 double dshield, darmour, dknockback;
1432 node = parent->xmlChildrenNode;
1434 xml_onlyNodes(node);
1435 xmlr_float(node,
"range",temp->
u.
bem.
range);
1436 xmlr_float(node,
"turn",temp->
u.
bem.
turn);
1437 xmlr_float(node,
"energy",temp->
u.
bem.
energy);
1438 xmlr_float(node,
"delay",temp->
u.
bem.
delay);
1439 xmlr_float(node,
"warmup",temp->
u.
bem.
warmup);
1440 xmlr_float(node,
"heatup",temp->
u.
bem.
heatup);
1441 xmlr_float(node,
"swivel",temp->
u.
bem.
swivel);
1443 xmlr_strd(node,
"lua",temp->
lua_file);
1445 if (xml_isNode(node,
"duration")) {
1451 if (xml_isNode(node,
"damage")) {
1457 if (xml_isNode(node,
"shader")) {
1458 xmlr_attr_float(node,
"r", temp->
u.
bem.
colour.r);
1459 xmlr_attr_float(node,
"g", temp->
u.
bem.
colour.g);
1460 xmlr_attr_float(node,
"b", temp->
u.
bem.
colour.b);
1461 xmlr_attr_float(node,
"a", temp->
u.
bem.
colour.a);
1462 xmlr_attr_float(node,
"width", temp->
u.
bem.
width);
1464 shader = xml_get(node);
1465 if (gl_has( OPENGL_SUBROUTINES )) {
1466 temp->
u.
bem.
shader = glGetSubroutineIndex( shaders.beam.program, GL_FRAGMENT_SHADER, shader );
1468 WARN(
"Beam outfit '%s' has unknown shader function '%s'", temp->
name, shader);
1472 if (xml_isNode(node,
"spfx_armour")) {
1476 if (xml_isNode(node,
"spfx_shield")) {
1482 if (xml_isNode(node,
"sound_warmup")) {
1486 if (xml_isNode(node,
"sound")) {
1490 if (xml_isNode(node,
"sound_off")) {
1502 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, node->name);
1503 }
while (xml_nextNode(node));
1510 temp->
u.
bem.
heat = ((800.-CONST_SPACE_STAR_TEMP)*
C +
1511 STEEL_HEAT_CONDUCTIVITY * ((800-CONST_SPACE_STAR_TEMP) * area)) /
1520 SDESC_COLOURT( l, temp, _(
"\n %.0f%% vs armour"), 100., darmour*100. );
1521 SDESC_COLOURT( l, temp, _(
"\n %.0f%% vs shield"), 100., dshield*100. );
1522 SDESC_COND( l, temp, _(
"\n %.0f%% knockback"), dknockback*100. );
1523 SDESC_COND_COLOUR( l, temp, _(
"\n%.0f CPU"), temp->
cpu );
1524 SDESC_COND( l, temp, _(
"\n%.0f Mass"), temp->
mass );
1526 SDESC_ADD( l, temp, _(
"\n%.2f DPS [%s]"),
1529 SDESC_COND( l, temp, _(
"\n%.0f Disable/s"), temp->
u.
bem.
dmg.
disable );
1530 SDESC_COND( l, temp, _(
"\n%.1f EPS"), temp->
u.
bem.
energy );
1531 SDESC_ADD( l, temp, _(
"\n%.1f Duration"), temp->
u.
bem.
duration );
1533 SDESC_ADD( l, temp, _(
"\n%.1f Cooldown"), temp->
u.
bem.
duration );
1535 SDESC_COND( l, temp, _(
"\n%.1f second heat up"),temp->
u.
bem.
heatup );
1537 SDESC_ADD( l, temp, _(
"\n%.1f Degree Swivel"), temp->
u.
bem.
swivel*180./M_PI );
1540#define MELEMENT(o,s) \
1541if (o) WARN( _("Outfit '%s' missing/invalid '%s' element"), temp->name, s)
1542 MELEMENT(temp->
u.
bem.
width==0.,
"shader width");
1552 MELEMENT((temp->
type!=OUTFIT_TYPE_BEAM) && (temp->
u.
bem.
turn==0),
"turn");
1554 MELEMENT(temp->
cpu==0.,
"cpu");
1570 double dshield, darmour, dknockback;
1584 node = parent->xmlChildrenNode;
1586 xml_onlyNodes(node);
1587 xmlr_float(node,
"delay",temp->
u.
lau.
delay);
1592 xmlr_float(node,
"lockon",temp->
u.
lau.
lockon);
1594 xmlr_float(node,
"swivel",temp->
u.
lau.
swivel);
1597 xmlr_int(node,
"shots",temp->
u.
blt.
shots);
1599 xmlr_strd(node,
"lua",temp->
lua_file);
1602 xmlr_float(node,
"arc",temp->
u.
lau.
arc);
1606 if (xml_isNode(node,
"duration")) {
1608 xmlr_attr_strd(node,
"blowup",buf);
1610 if (strcmp(buf,
"armour")==0)
1612 else if (strcmp(buf,
"shield")==0)
1615 WARN(_(
"Outfit '%s' has invalid blowup property: '%s'"),
1622 xmlr_float(node,
"resist",temp->
u.
lau.
resist);
1624 xmlr_float(node,
"thrust",temp->
u.
lau.
thrust);
1625 xmlr_float(node,
"turn",temp->
u.
lau.
turn);
1626 xmlr_float(node,
"speed",temp->
u.
lau.
speed);
1628 xmlr_float(node,
"energy",temp->
u.
lau.
energy);
1630 if (xml_isNode(node,
"gfx")) {
1632 OUTFIT_GFX_PATH
"space/%s", 6, 6,
1633 OPENGL_TEX_MAPTRANS | OPENGL_TEX_MIPMAPS );
1634 xmlr_attr_float(node,
"spin", temp->
u.
lau.
spin);
1638 char *buf = xml_get(node);
1643 WARN(_(
"Outfit '%s': the number of collision polygons is wrong.\n \
1644 npolygon = %i and sx*sy = %i"),
1649 if (xml_isNode(node,
"spfx_armour")) {
1653 if (xml_isNode(node,
"spfx_shield")) {
1657 if (xml_isNode(node,
"sound")) {
1661 if (xml_isNode(node,
"sound_hit")) {
1665 if (xml_isNode(node,
"damage")) {
1669 if (xml_isNode(node,
"trail_generator")) {
1671 char *buf = xml_get(node);
1677 if (xml_isNode(node,
"ai")) {
1678 char *buf = xml_get(node);
1680 if (strcmp(buf,
"unguided")==0)
1681 temp->
u.
lau.
ai = AMMO_AI_UNGUIDED;
1682 else if (strcmp(buf,
"seek")==0)
1683 temp->
u.
lau.
ai = AMMO_AI_SEEK;
1684 else if (strcmp(buf,
"smart")==0)
1685 temp->
u.
lau.
ai = AMMO_AI_SMART;
1687 WARN(_(
"Ammo '%s' has unknown ai type '%s'."), temp->
name, buf);
1699 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, node->name);
1700 }
while (xml_nextNode(node));
1711 WARN(_(
"Max speed of ammo '%s' will be ignored."), temp->
name);
1720 SDESC_COLOURT( l, temp, _(
"\n %.0f%% vs armour"), 100., darmour*100. );
1721 SDESC_COLOURT( l, temp, _(
"\n %.0f%% vs shield"), 100., dshield*100. );
1722 SDESC_COND( l, temp, _(
"\n %.0f%% knockback"), dknockback*100. );
1723 SDESC_COND_COLOUR( l, temp, _(
"\n%.0f CPU"), temp->
cpu );
1724 SDESC_COND( l, temp, _(
"\n%.0f Mass"), temp->
mass );
1727 SDESC_ADD( l, temp, _(
"\n%.1f Second Lock-on"), temp->
u.
lau.
lockon );
1728 SDESC_ADD( l, temp, _(
"\n%.1f Second In-Flight Calibration"), temp->
u.
lau.
iflockon );
1733 SDESC_ADD( l, temp, _(
"\nNo Seeking") );
1737 SDESC_COND( l, temp, _(
"\n%.1f Degree Swivel"), temp->
u.
lau.
swivel*180./M_PI );
1741 SDESC_ADD( l, temp, _(
"\nHolds %d ammo"), temp->
u.
lau.
amount );
1743 SDESC_COND( l, temp, _(
"\n%.2f DPS [%.0f Damage]"),
1745 SDESC_COND( l, temp, _(
"\n%.1f Disable/s [%.0f Disable]"),
1747 SDESC_ADD( l, temp, _(
"\n%.1f Shots Per Second"), 1. / temp->
u.
lau.
delay );
1751 SDESC_ADD( l, temp, _(
"\n%.0f Initial Speed (%.0f Thrust)"), temp->
u.
lau.
speed, temp->
u.
lau.
thrust );
1753 SDESC_ADD( l, temp, _(
"\n%.0f Thrust"), temp->
u.
lau.
thrust );
1756 SDESC_COND( l, temp, _(
"\n%.0f Speed"), temp->
u.
lau.
speed );
1758 SDESC_ADD( l, temp, _(
"\n%.0f Maximum Speed"), temp->
u.
lau.
speed_max );
1759 SDESC_ADD( l, temp, _(
"\n%.1f Seconds to Reload"), temp->
u.
lau.
reload_time );
1761 SDESC_COND( l, temp, _(
"\n%.0f%% Jam Resistance"), temp->
u.
lau.
resist * 100. );
1764#define MELEMENT(o,s) \
1765if (o) WARN(_("Outfit '%s' missing '%s' element"), temp->name, s)
1766 MELEMENT(temp->
u.
lau.
delay==0.,
"delay");
1767 MELEMENT(temp->
cpu==0.,
"cpu");
1771 MELEMENT(!outfit_isProp(temp,OUTFIT_PROP_SHOOT_DRY)&&temp->
u.
lau.
gfx_space==NULL,
"gfx");
1772 MELEMENT(!outfit_isProp(temp,OUTFIT_PROP_SHOOT_DRY)&&temp->
u.
lau.
spfx_shield==-1,
"spfx_shield");
1773 MELEMENT(!outfit_isProp(temp,OUTFIT_PROP_SHOOT_DRY)&&temp->
u.
lau.
spfx_armour==-1,
"spfx_armour");
1778 MELEMENT(temp->
u.
lau.
turn==0,
"turn");
1784 MELEMENT(!outfit_isProp(temp,OUTFIT_PROP_SHOOT_DRY)&&temp->
u.
lau.
speed_max==0,
"speed_max");
1785 MELEMENT(!outfit_isProp(temp,OUTFIT_PROP_SHOOT_DRY)&&temp->
u.
lau.
duration==0,
"duration");
1789 if (!outfit_isProp(temp,OUTFIT_PROP_SHOOT_DRY)&&temp->
u.
lau.
speed==0. && temp->
u.
lau.
thrust==0.)
1790 WARN(_(
"Outfit '%s' has no speed nor thrust set!"), temp->
name);
1792 WARN(_(
"Outfit '%s' has longer 'iflockon' than ammo 'duration'"), temp->
name);
1804 xmlNodePtr node = parent->children;
1809 xml_onlyNodes(node);
1810 xmlr_strd(node,
"lua",temp->
lua_file);
1812 if (xml_isNode(node,
"active")) {
1813 xmlr_attr_float(node,
"cooldown", temp->
u.
mod.
cooldown);
1832 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, node->name);
1833 }
while (xml_nextNode(node));
1840 SDESC_ADD( l, temp,
"%s", _(
"\n#rActivated Outfit#0") );
1842 SDESC_ADD( l, temp, _(
" #r(%.1f s Cooldown)#0"), temp->
u.
mod.
cooldown );
1843 SDESC_COND_COLOUR( l, temp, _(
"\n%+.0f CPU"), temp->
cpu );
1844 SDESC_COND( l, temp, _(
"\n%.0f Mass"), temp->
mass );
1857 xmlNodePtr node = parent->children;
1871 xml_onlyNodes(node);
1872 xmlr_float(node,
"rumble",temp->
u.
afb.
rumble);
1873 xmlr_strd(node,
"lua",temp->
lua_file);
1874 if (xml_isNode(node,
"sound_on")) {
1878 if (xml_isNode(node,
"sound")) {
1882 if (xml_isNode(node,
"sound_off")) {
1886 xmlr_float(node,
"thrust",temp->
u.
afb.
thrust);
1887 xmlr_float(node,
"speed",temp->
u.
afb.
speed);
1888 xmlr_float(node,
"energy",temp->
u.
afb.
energy);
1890 xmlr_float(node,
"heatup",temp->
u.
afb.
heatup);
1901 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, node->name);
1902 }
while (xml_nextNode(node));
1908 SDESC_ADD( l, temp, _(
"\n#rActivated Outfit#0") );
1909 SDESC_COND_COLOUR( l, temp, _(
"\n%.0f CPU"), temp->
cpu );
1910 SDESC_COND( l, temp, _(
"\n%.0f Mass"), temp->
mass );
1911 SDESC_ADD( l, temp, _(
"\nOnly one can be equipped") );
1912 SDESC_ADD( l, temp, _(
"\n%.0f Maximum Effective Mass"), temp->
u.
afb.
mass_limit );
1913 SDESC_ADD( l, temp, _(
"\n%.0f%% Thrust"), temp->
u.
afb.
thrust + 100. );
1914 SDESC_ADD( l, temp, _(
"\n%.0f%% Maximum Speed"), temp->
u.
afb.
speed + 100. );
1915 SDESC_COND( l, temp, _(
"\n%.1f EPS"), temp->
u.
afb.
energy );
1916 SDESC_COND( l, temp, _(
"\n%.1f Rumble"), temp->
u.
afb.
rumble );
1923 temp->
u.
afb.
heat = ((800.-CONST_SPACE_STAR_TEMP)*
C +
1924 STEEL_HEAT_CONDUCTIVITY * ((800-CONST_SPACE_STAR_TEMP) * area)) /
1927#define MELEMENT(o,s) \
1928if (o) WARN(_("Outfit '%s' missing/invalid '%s' element"), temp->name, s)
1930 MELEMENT(temp->
u.
afb.
speed==0.,
"speed");
1947 xmlNodePtr node = parent->children;
1952 xml_onlyNodes(node);
1953 xmlr_float(node,
"delay",temp->
u.
bay.
delay);
1955 xmlr_strd(node,
"ship",temp->
u.
bay.
ship);
1958 xmlr_strd(node,
"lua",temp->
lua_file);
1967 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, node->name);
1968 }
while (xml_nextNode(node));
1974 SDESC_COND_COLOUR( l, temp, _(
"\n%.0f CPU"), temp->
cpu );
1975 SDESC_COND( l, temp, _(
"\n%.0f Mass"), temp->
mass );
1976 SDESC_COND( l, temp, _(
"\n%.1f Seconds Per Launch"), temp->
u.
bay.
delay );
1977 SDESC_ADD( l, temp, _(
"\nHolds %d ships"), temp->
u.
bay.
amount );
1978 SDESC_COND( l, temp, _(
"\n%.1f Seconds to Reload"), temp->
u.
bay.
reload_time );
1980#define MELEMENT(o,s) \
1981if (o) WARN(_("Outfit '%s' missing/invalid '%s' element"), temp->name, s)
1982 MELEMENT(temp->
u.
bay.
ship==NULL,
"ship");
1986 MELEMENT(temp->
cpu==0.,
"cpu");
2001 StarSystem *system_stack;
2005 node = parent->children;
2008 temp->
slot.
size = OUTFIT_SLOT_SIZE_NA;
2015 xml_onlyNodes(node);
2017 if (xml_isNode(node,
"sys")) {
2018 xmlr_attr_strd(node,
"name",buf);
2021 WARN(_(
"Map '%s' has invalid system '%s'"), temp->
name, buf);
2029 xmlNodePtr cur = node->children;
2033 if (xml_isNode(cur,
"spob")) {
2035 if ((buf != NULL) && ((spob =
spob_get(buf)) != NULL))
2038 WARN(_(
"Map '%s' has invalid spob '%s'"), temp->
name, buf);
2040 else if (xml_isNode(cur,
"jump")) {
2042 if ((buf != NULL) && ((jump =
jump_get(xml_get(cur),
2046 WARN(_(
"Map '%s' has invalid jump point '%s'"), temp->
name, buf);
2049 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, cur->name);
2050 }
while (xml_nextNode(cur));
2052 else if (xml_isNode(node,
"short_desc")) {
2056 else if (xml_isNode(node,
"all")) {
2058 for (
int i=0;i<
array_size(system_stack);i++) {
2060 for (
int j=0;j<
array_size(system_stack[i].spobs);j++)
2062 for (
int j=0;j<
array_size(system_stack[i].jumps);j++)
2067 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, node->name);
2068 }
while (xml_nextNode(node));
2081#define MELEMENT(o,s) \
2082if (o) WARN(_("Outfit '%s' missing/invalid '%s' element"), temp->name, s)
2084 MELEMENT(temp->
mass!=0.,
"cpu");
2085 MELEMENT(temp->
cpu!=0.,
"cpu");
2097 xmlNodePtr node = parent->children;
2100 temp->
slot.
size = OUTFIT_SLOT_SIZE_NA;
2103 xml_onlyNodes(node);
2106 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, node->name);
2107 }
while (xml_nextNode(node));
2118#define MELEMENT(o,s) \
2119if (o) WARN(_("Outfit '%s' missing/invalid '%s' element"), temp->name, s)
2121 MELEMENT(temp->
mass!=0.,
"cpu");
2122 MELEMENT(temp->
cpu!=0.,
"cpu");
2134 xmlNodePtr node = parent->children;
2137 temp->
slot.
size = OUTFIT_SLOT_SIZE_NA;
2140 xml_onlyNodes(node);
2141 xmlr_strd(node,
"gui",temp->
u.
gui.
gui);
2142 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, node->name);
2143 }
while (xml_nextNode(node));
2148 _(
"GUI (Graphical User Interface)") );
2150#define MELEMENT(o,s) \
2151if (o) WARN(_("Outfit '%s' missing/invalid '%s' element"), temp->name, s)
2153 MELEMENT(temp->
u.
gui.
gui==NULL,
"gui");
2154 MELEMENT(temp->
mass!=0.,
"cpu");
2155 MELEMENT(temp->
cpu!=0.,
"cpu");
2167 xmlNodePtr node = parent->children;
2170 temp->
slot.
size = OUTFIT_SLOT_SIZE_NA;
2173 xml_onlyNodes(node);
2175 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, node->name);
2176 }
while (xml_nextNode(node));
2191#define MELEMENT(o,s) \
2192if (o) WARN(_("Outfit '%s' missing/invalid '%s' element"), temp->name, s)
2194 MELEMENT(temp->
mass!=0.,
"cpu");
2195 MELEMENT(temp->
cpu!=0.,
"cpu");
2208 xmlNodePtr node, parent;
2209 char *prop, *desc_extra;
2217 parent = doc->xmlChildrenNode;
2218 if (parent == NULL) {
2219 ERR( _(
"Malformed '%s' file: does not contain elements"), file);
2224 memset( temp, 0,
sizeof(
Outfit) );
2253 xmlr_attr_strd(parent,
"name",temp->
name);
2254 if (temp->
name == NULL)
2255 WARN(_(
"Outfit '%s' has invalid or no name"), file);
2257 node = parent->xmlChildrenNode;
2262 xml_onlyNodes(node);
2264 if (xml_isNode(node,
"general")) {
2265 xmlNodePtr cur = node->children;
2268 xmlr_int(cur,
"rarity",temp->
rarity);
2269 xmlr_strd(cur,
"license",temp->
license);
2270 xmlr_strd(cur,
"cond",temp->
cond);
2271 xmlr_strd(cur,
"condstr",temp->
condstr);
2272 xmlr_float(cur,
"mass",temp->
mass);
2273 xmlr_float(cur,
"cpu",temp->
cpu);
2274 xmlr_long(cur,
"price",temp->
price);
2275 xmlr_strd(cur,
"limit",temp->
limit);
2276 xmlr_strd(cur,
"description",temp->
desc_raw);
2277 xmlr_strd(cur,
"desc_extra",desc_extra);
2278 xmlr_strd(cur,
"typename",temp->
typename);
2279 xmlr_int(cur,
"priority",temp->
priority);
2280 if (xml_isNode(cur,
"unique")) {
2284 if (xml_isNode(cur,
"shoot_dry")) {
2288 else if (xml_isNode(cur,
"gfx_store")) {
2290 OUTFIT_GFX_PATH
"store/%s", 1, 1, OPENGL_TEX_MIPMAPS );
2293 else if (xml_isNode(cur,
"gfx_overlays")) {
2294 xmlNodePtr ccur = cur->children;
2297 xml_onlyNodes(ccur);
2298 if (xml_isNode(ccur,
"gfx_overlay"))
2300 xml_parseTexture( ccur, OVERLAY_GFX_PATH
"%s", 1, 1, OPENGL_TEX_MIPMAPS ) );
2301 }
while (xml_nextNode(ccur));
2304 else if (xml_isNode(cur,
"slot")) {
2305 cprop = xml_get(cur);
2307 WARN(_(
"Outfit '%s' has an slot type invalid."), temp->
name);
2308 else if (strcmp(cprop,
"structure") == 0)
2309 temp->
slot.
type = OUTFIT_SLOT_STRUCTURE;
2310 else if (strcmp(cprop,
"utility") == 0)
2311 temp->
slot.
type = OUTFIT_SLOT_UTILITY;
2312 else if (strcmp(cprop,
"weapon") == 0)
2313 temp->
slot.
type = OUTFIT_SLOT_WEAPON;
2314 else if (strcmp(cprop,
"intrinsic") == 0)
2317 WARN(_(
"Outfit '%s' has unknown slot type '%s'."), temp->
name, cprop);
2320 xmlr_attr_strd( cur,
"prop", prop );
2326 else if (xml_isNode(cur,
"size")) {
2330 else if (xml_isNode(cur,
"illegalto")) {
2331 xmlNodePtr ccur = cur->xmlChildrenNode;
2334 xml_onlyNodes(ccur);
2335 if (xml_isNode(ccur,
"faction")) {
2336 const char *s = xml_get(ccur);
2338 WARN(_(
"Empty faction string for outfit '%s' legality!"), temp->
name);
2342 }
while (xml_nextNode(ccur));
2344 WARN(_(
"Outfit '%s' has no factions defined in <illegalto> block!"), temp->
name);
2347 WARN(_(
"Outfit '%s' has unknown general node '%s'"),temp->
name, cur->name);
2348 }
while (xml_nextNode(cur));
2352 if (xml_isNode(node,
"stats")) {
2353 xmlNodePtr cur = node->children;
2364 WARN(_(
"Outfit '%s' has unknown node '%s'"), temp->
name, cur->name);
2365 }
while (xml_nextNode(cur));
2370 if (xml_isNode(node,
"tags")) {
2371 xmlNodePtr cur = node->children;
2375 if (xml_isNode(cur,
"tag")) {
2376 char *tmp = xml_get(cur);
2381 WARN(_(
"Outfit '%s' has unknown node in tags '%s'."), temp->
name, cur->name );
2382 }
while (xml_nextNode(cur));
2386 if (xml_isNode(node,
"specific")) {
2388 xmlr_attr_strd(node,
"type", prop);
2390 ERR(_(
"Outfit '%s' element 'specific' missing property 'type'"),temp->
name);
2395 xmlr_attr_strd(node,
"secondary", prop);
2397 if ((
int)atoi(prop))
2403 xmlr_attr_int_def(node,
"group", group, -1);
2405 if (group > PILOT_WEAPON_SETS || group < 1) {
2406 WARN(_(
"Outfit '%s' has group '%d', should be in the 1-%d range"),
2407 temp->
name, group, PILOT_WEAPON_SETS);
2416 if (temp->
type==OUTFIT_TYPE_NULL)
2417 WARN(_(
"Outfit '%s' is of type NONE"), temp->
name);
2431 temp->
u.
map = malloc(
sizeof(OutfitMapData_t) );
2433 temp->
slot.
size = OUTFIT_SLOT_SIZE_NA;
2447 if (desc_extra != NULL) {
2457 WARN(_(
"Outfit '%s' has unknown node '%s'"),temp->
name, node->name);
2458 }
while (xml_nextNode(node));
2460#define MELEMENT(o,s) \
2461if (o) WARN( _("Outfit '%s' missing/invalid '%s' element"), temp->name, s)
2462 MELEMENT(temp->
name==NULL,
"name");
2463 MELEMENT(temp->
slot.
type==OUTFIT_SLOT_NULL,
"slot");
2464 MELEMENT((temp->
slot.
type!=OUTFIT_SLOT_NA) && (temp->
slot.
size==OUTFIT_SLOT_SIZE_NA),
"size");
2465 MELEMENT(temp->
gfx_store==NULL,
"gfx_store");
2467 MELEMENT(temp->
type==0,
"type");
2469 MELEMENT(temp->
desc_raw==NULL,
"description");
2470 MELEMENT((temp->
cond!=NULL) && (temp->
condstr==NULL),
"condstr");
2471 MELEMENT((temp->
cond==NULL) && (temp->
condstr!=NULL),
"cond");
2488 for (
int i=0; i <
array_size( outfit_files ); i++) {
2498 free( outfit_files[i] );
2513 Uint32 time = SDL_GetTicks();
2526 for (
int i=0; i<noutfits; i++) {
2535 WARN(_(
"Outfit '%s' failed to read Lua '%s'!"), o->
name, o->
lua_file );
2539 env = nlua_newEnv();
2549 if (nlua_dobufenv( env, dat, sz, o->
lua_file ) != 0) {
2550 WARN(_(
"Outfit '%s' Lua error:\n%s"), o->
name, lua_tostring(naevL,-1));
2584 nlua_getenv( naevL, env,
"notactive" );
2586 if (lua_toboolean(naevL,-1)) {
2589 WARN(_(
"Outfit '%s' has 'ontoggle' Lua function defined, but is set as 'notactive'!"),o->
name);
2596 char **outfit_names = malloc( noutfits *
sizeof(
char*) );
2599 for (
int i=0; i<noutfits; i++)
2602 qsort( outfit_names, noutfits,
sizeof(
char*),
strsort );
2603 for (
int i=0; i<(noutfits - 1); i++) {
2605 while (strcmp(outfit_names[i], outfit_names[i+1]) == 0)
2611 WARN( n_(
"Name collision! %d outfit is named '%s'",
"Name collision! %d outfits are named '%s'",
2613 i + 1 - start, outfit_names[ start ] );
2619 time = SDL_GetTicks() - time;
2620 DEBUG( n_(
"Loaded %d Outfit in %.3f s",
"Loaded %d Outfits in %.3f s", noutfits ), noutfits, time/1000. );
2623 DEBUG( n_(
"Loaded %d Outfit",
"Loaded %d Outfits", noutfits ), noutfits );
2639 WARN(_(
"Fighter Bay Outfit '%s' has not found ship '%s'!"),o->
name,o->
u.
bay.
ship);
2653 SDESC_ADD( l, o, _(
"\n#rIllegal to:#0") );
2659 if (o->
lua_env != LUA_NOREF) {
2660 nlua_getenv( naevL, o->
lua_env,
"onload" );
2661 if (lua_isnil(naevL,-1))
2665 if (nlua_pcall( o->
lua_env, 1, 0 )) {
2666 WARN(_(
"Outfit '%s' lua load error -> 'load':\n%s"), o->
name, lua_tostring(naevL,-1));
2674 WARN(_(
"Outfit '%s' has inexistent license requirement '%s'!"), o->
name, o->
license);
2688 xmlNodePtr node, cur;
2698 node = doc->xmlChildrenNode;
2700 WARN( _(
"Malformed '%s' file: does not contain elements"), o->
filename );
2705 cur = node->xmlChildrenNode;
2710 if (xml_isNode(cur,
"specific"))
2713 }
while (xml_nextNode(cur));
2728 snprintf( s,
sizeof(s), OVERLAY_GFX_PATH
"rarity_%d.webp", rarity );
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
#define array_create_size(basic_type, capacity)
Creates a new dynamic array of ‘basic_type’ with an initial capacity.
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_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
void LoadPolygon(CollPoly *polygon, xmlNodePtr node)
Loads a polygon from an xml node.
int dtype_raw(int type, double *shield, double *armour, double *knockback)
Gets the raw modulation stats of a damage type.
int dtype_get(const char *name)
Gets the id of a dtype based on name.
const char * dtype_damageTypeToStr(int type)
Gets the human readable string from damage type.
const char * faction_name(int f)
Gets a factions "real" (internal) name.
int faction_get(const char *name)
Gets a faction ID by name.
void naev_renderLoadscreen(void)
Renders the loadscreen if necessary.
Header file with generic functions and naev-specifics.
void * ndata_read(const char *path, size_t *filesize)
Reads a file from the ndata (will be NUL terminated).
int ndata_matchExt(const char *path, const char *ext)
Sees if a file matches an extension.
char ** ndata_listRecursive(const char *path)
Lists all the visible files in a directory, at any depth.
static char buf[NEWS_MAX_LENGTH]
int nlua_loadStandard(nlua_env env)
Loads the standard Naev Lua API.
int nlua_refenvtype(nlua_env env, const char *name, int type)
Gets the reference of a global in a lua environment if it matches a type.
int nlua_loadCamera(nlua_env env)
Loads the camera library.
int nlua_loadGFX(nlua_env env)
Loads the graphics library.
int nlua_loadHook(nlua_env env)
Loads the hook Lua library.
const Outfit ** lua_pushoutfit(lua_State *L, const Outfit *outfit)
Pushes a outfit on the stack.
int nlua_loadPilotOutfit(nlua_env env)
Loads the pilot outfit library.
int asprintf(char **strp, const char *fmt,...)
Like sprintf(), but it allocates a large-enough string and returns the pointer in the first argument....
int strsort(const void *p1, const void *p2)
Sort function for sorting strings with qsort().
char * strcasestr(const char *haystack, const char *needle)
Finds a string inside another string case insensitively.
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
const char * num2strU(double n, int decimals)
Unsafe version of num2str that uses an internal buffer. Every call overwrites the return value.
glTexture * xml_parseTexture(xmlNodePtr node, const char *path, int defsx, int defsy, const unsigned int flags)
Parses a texture handling the sx and sy elements.
xmlDocPtr xml_parsePhysFS(const char *filename)
Analogous to xmlParseMemory/xmlParseFile.
glTexture * gl_newImage(const char *path, const unsigned int flags)
Loads an image as a texture.
void gl_freeTexture(glTexture *texture)
Frees a texture.
int outfit_isSecondary(const Outfit *o)
Checks if outfit has the secondary flag set.
const char * outfit_description(const Outfit *o)
Gets the description of an outfit.
static void outfit_parseSMap(Outfit *temp, const xmlNodePtr parent)
Parses the map tidbits of the outfit.
static int outfit_loadPLG(Outfit *temp, const char *buf, unsigned int bolt)
Loads the collision polygon for a bolt outfit.
double outfit_speed(const Outfit *o)
Gets the outfit's speed.
static Outfit * outfit_stack
double outfit_trackmin(const Outfit *o)
Gets the outfit's minimal tracking.
static void outfit_parseSLauncher(Outfit *temp, const xmlNodePtr parent)
Parses the specific area for a launcher and loads it into Outfit.
static int outfit_parseDamage(Damage *dmg, xmlNodePtr node)
Parses a damage node.
int outfit_isBeam(const Outfit *o)
Checks if outfit is a beam type weapon.
const char * outfit_summary(const Outfit *o, int withname)
Gets the summary of an outfit.
const Outfit * outfit_getAll(void)
Gets the array (array.h) of all outfits.
double outfit_cpu(const Outfit *o)
Gets the outfit's cpu usage.
static void outfit_parseSAfterburner(Outfit *temp, const xmlNodePtr parent)
Parses the afterburner tidbits of the outfit.
int outfit_isActive(const Outfit *o)
Checks if outfit is an active outfit.
int outfit_soundHit(const Outfit *o)
Gets the outfit's hit sound.
static int outfit_parse(Outfit *temp, const char *file)
Parses and returns Outfit from parent node.
const Outfit * outfit_get(const char *name)
Gets an outfit by name.
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.
static OutfitType outfit_strToOutfitType(char *buf)
Gets the outfit type from a human readable string.
OutfitSlotSize outfit_toSlotSize(const char *s)
Gets the outfit slot size from a human readable string.
int outfit_miningRarity(const Outfit *o)
Gets the maximum rarity the outfit can mine up to.
static void outfit_parseSLicense(Outfit *temp, const xmlNodePtr parent)
Parses the license tidbits of the outfit.
int outfit_isLocalMap(const Outfit *o)
Checks if outfit is a local space map.
static void outfit_parseSFighterBay(Outfit *temp, const xmlNodePtr parent)
Parses the fighter bay tidbits of the outfit.
char outfit_slotTypeColourFont(const OutfitSlot *os)
Gets a font colour character that roughly matches an outfit slot type colour.
int outfit_isToggleable(const Outfit *o)
Checks if outfit can be toggled.
static void outfit_parseSBolt(Outfit *temp, const xmlNodePtr parent)
Parses the specific area for a bolt weapon and loads it into Outfit.
int outfit_compareTech(const void *outfit1, const void *outfit2)
Function meant for use with C89, C99 algorithm qsort().
size_t outfit_getNameWithClass(const Outfit *outfit, char *buf, size_t size)
Gets a brief name/class description suitable for the title section of an outfitter screen.
const Outfit * outfit_getW(const char *name)
Gets an outfit by name without warning on no-find.
const char * outfit_getTypeBroad(const Outfit *o)
Gets the outfit's broad type.
static void outfit_parseSMod(Outfit *temp, const xmlNodePtr parent)
Parses the modification tidbits of the outfit.
int outfit_fitsSlot(const Outfit *o, const OutfitSlot *s)
Checks to see if an outfit fits a slot.
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.
int outfit_isAfterburner(const Outfit *o)
Checks if outfit is an afterburner.
double outfit_range(const Outfit *o)
Gets the outfit's range.
int outfit_isMap(const Outfit *o)
Checks if outfit is a space map.
int outfit_spfxShield(const Outfit *o)
Gets the outfit's sound effect.
int outfit_isTurret(const Outfit *o)
Checks if outfit is a turret class weapon.
double outfit_ammoMass(const Outfit *o)
Gets the outfit's ammunition mass.
int outfit_isForward(const Outfit *o)
Checks if outfit is a fixed mounted weapon.
const CollPoly * outfit_plg(const Outfit *o)
Gets the outfit's collision polygon.
static void sdesc_miningRarity(int *l, Outfit *temp, int rarity)
Adds a small blurb about rarity mining.
int outfit_isLicense(const Outfit *o)
Checks if outfit is a license.
static void outfit_parseSGUI(Outfit *temp, const xmlNodePtr parent)
Parses the GUI tidbits of the outfit.
char outfit_slotSizeColourFont(const OutfitSlot *os)
Gets a font colour character that roughly matches an outfit slot size colour.
int outfit_amount(const Outfit *o)
Gets the amount an outfit can hold.
const glTexture * outfit_gfx(const Outfit *o)
Gets the outfit's graphic effect.
int outfit_load(void)
Loads all the outfits.
const char * slotName(const OutfitSlotType type)
double outfit_spin(const Outfit *o)
Gets the outfit's animation spin.
int outfit_mapParse(void)
Parses all the maps.
const char * outfit_getType(const Outfit *o)
Gets the outfit's specific type.
double outfit_heat(const Outfit *o)
Gets the outfit's heat generation.
double outfit_trackmax(const Outfit *o)
Gets the outfit's minimal tracking.
static void outfit_parseSBeam(Outfit *temp, const xmlNodePtr parent)
Parses the beam weapon specifics of an outfit.
static char ** license_stack
int outfit_isMod(const Outfit *o)
Checks if outfit is a ship modification.
int outfit_isGUI(const Outfit *o)
Checks if outfit is a GUI.
int outfit_sound(const Outfit *o)
Gets the outfit's sound.
int outfit_spfxArmour(const Outfit *o)
Gets the outfit's sound effect.
#define OUTFIT_SHORTDESC_MAX
const char * slotSize(const OutfitSlotSize o)
Gets the slot size as a string.
const Damage * outfit_damage(const Outfit *o)
Gets the outfit's damage.
char ** outfit_searchFuzzyCase(const char *name, int *n)
Does a fuzzy search of all the outfits. Searches translated names but returns internal names.
static void outfit_parseSLocalMap(Outfit *temp, const xmlNodePtr parent)
Parses the map tidbits of the outfit.
double outfit_duration(const Outfit *o)
Gets the outfit's duration.
double outfit_cooldown(const Outfit *o)
Gets the outfit's cooldown.
const char * outfit_slotName(const Outfit *o)
Gets the name of the slot type of an outfit.
int outfit_isBolt(const Outfit *o)
Checks if outfit is bolt type weapon.
const char * outfit_slotSize(const Outfit *o)
Gets the name of the slot size of an outfit.
void outfit_free(void)
Frees the outfit stack.
#define outfit_setProp(o, p)
const char * outfit_existsCase(const char *name)
Checks to see if an outfit exists matching name (case insensitive).
static int outfit_loadDir(char *dir)
Loads all the files in a directory.
double outfit_energy(const Outfit *o)
Gets the outfit's energy usage.
int outfit_licenseExists(const char *name)
Checks to see if a license exists.
void outfit_freeSlot(OutfitSlot *s)
Frees an outfit slot.
const char * outfit_getAmmoAI(const Outfit *o)
Gets a human-readable string describing an ammo outfit's AI.
glTexture * rarity_texture(int rarity)
const glColour * outfit_slotSizeColour(const OutfitSlot *os)
Gets the slot size colour for an outfit slot.
double outfit_delay(const Outfit *o)
Gets the outfit's delay.
int outfit_fitsSlotType(const Outfit *o, const OutfitSlot *s)
Checks to see if an outfit fits a slot type (ignoring size).
int outfit_loadPost(void)
Loads all the outfits legality.
double pilot_heatCalcOutfitC(const Outfit *o)
Calculates the thermal mass of an outfit.
double pilot_heatCalcOutfitArea(const Outfit *o)
Calculates the effective transfer area of an outfit.
const char * pilot_outfitDescription(const Pilot *p, const Outfit *o)
Gets the description of an outfit for a given pilot.
const char * pilot_outfitSummary(const Pilot *p, const Outfit *o, int withname)
Gets the summary of an outfit for a give pilot.
const Ship * ship_get(const char *name)
Gets a ship based on its name.
int ss_statsListDesc(const ShipStatList *ll, char *buf, int len, int newline)
Writes the ship statistics description.
void ss_free(ShipStatList *ll)
Frees a list of ship stats.
ShipStatList * ss_listFromXML(xmlNodePtr node)
Creates a shipstat list element from an xml node.
unsigned int sp_get(const char *name)
Gets the id of a slot property.
int sp_required(unsigned int spid)
Gets whether or not a slot property is required.
int sound_get(const char *name)
Gets the buffer to sound of name.
Spob * spob_get(const char *spobname)
Gets a spob based on its name.
StarSystem * system_getAll(void)
Gets an array (array.h) of all star systems.
StarSystem * system_get(const char *sysname)
Get the system from its name.
JumpPoint * jump_get(const char *jumpname, const StarSystem *sys)
Gets a jump point based on its target and system.
const TrailSpec * trailSpec_get(const char *name)
Gets a trail spec by name.
int spfx_get(char *name)
Gets the id of an spfx based on name.
Represents a polygon used for collision detection.
Core damage that an outfit does.
const TrailSpec * trail_spec
Pilot slot that can contain outfits.
A ship outfit, depends radically on the type.
OutfitModificationData mod
OutfitAfterburnerData afb
glTexture ** gfx_overlays
Represents relative ship statistics as a linked list.
struct ShipStatList_ * next
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Abstraction for rendering sprite sheets.