20#include "background.h"
23#include "damagetype.h"
24#include "dev_uniedit.h"
26#include "gatherable.h"
32#include "map_overlay.h"
39#include "nlua_camera.h"
41#include "nlua_pilot.h"
59#define XML_SPOB_TAG "spob"
60#define XML_SYSTEM_TAG "ssys"
62#define SPOB_GFX_EXTERIOR_PATH_W 400
63#define SPOB_GFX_EXTERIOR_PATH_H 400
66#define FLAG_POSSET ( 1 << 0 )
67#define FLAG_INTERFERENCESET ( 1 << 1 )
68#define FLAG_SERVICESSET ( 1 << 2 )
69#define FLAG_FACTIONSET ( 1 << 3 )
71#define DEBRIS_BUFFER 1000
73static const double spob_aa_scale = 2.;
75typedef struct spob_lua_file_s {
117static Spob *space_landQueueSpob = NULL;
135static int system_parse( StarSystem *system,
const char *filename );
142static int spob_cmp(
const void *p1,
const void *p2 );
144static SystemPresence *system_getFactionPresenceGrow( StarSystem *sys,
147static int space_addMarkerSystem(
int sysid, MissionMarkerType type );
148static int space_addMarkerSpob(
int pntid, MissionMarkerType type );
149static int space_rmMarkerSystem(
int sysid, MissionMarkerType type );
150static int space_rmMarkerSpob(
int pntid, MissionMarkerType type );
158static int spob_lua_cmp(
const void *a,
const void *b );
159static nlua_env spob_lua_get(
int *mem,
const char *filename );
172 case SPOB_SERVICE_LAND:
174 case SPOB_SERVICE_INHABITED:
175 return N_(
"Inhabited" );
176 case SPOB_SERVICE_REFUEL:
177 return N_(
"Refuel" );
178 case SPOB_SERVICE_BAR:
180 case SPOB_SERVICE_MISSIONS:
181 return N_(
"Missions" );
182 case SPOB_SERVICE_COMMODITY:
183 return N_(
"Commodity" );
184 case SPOB_SERVICE_OUTFITS:
185 return N_(
"Outfits" );
186 case SPOB_SERVICE_SHIPYARD:
187 return N_(
"Shipyard" );
188 case SPOB_SERVICE_BLACKMARKET:
189 return N_(
"Blackmarket" );
199 if ( strcasecmp( name,
"Land" ) == 0 )
200 return SPOB_SERVICE_LAND;
201 else if ( strcasecmp( name,
"Inhabited" ) == 0 )
202 return SPOB_SERVICE_INHABITED;
203 else if ( strcasecmp( name,
"Refuel" ) == 0 )
204 return SPOB_SERVICE_REFUEL;
205 else if ( strcasecmp( name,
"Bar" ) == 0 )
206 return SPOB_SERVICE_BAR;
207 else if ( strcasecmp( name,
"Missions" ) == 0 )
208 return SPOB_SERVICE_MISSIONS;
209 else if ( strcasecmp( name,
"Commodity" ) == 0 )
210 return SPOB_SERVICE_COMMODITY;
211 else if ( strcasecmp( name,
"Outfits" ) == 0 )
212 return SPOB_SERVICE_OUTFITS;
213 else if ( strcasecmp( name,
"Shipyard" ) == 0 )
214 return SPOB_SERVICE_SHIPYARD;
215 else if ( strcasecmp( name,
"Blackmarket" ) == 0 )
216 return SPOB_SERVICE_BLACKMARKET;
229 if ( strcmp(
class,
"0" ) == 0 )
230 return _(
"Civilian Station" );
231 else if ( strcmp(
class,
"1" ) == 0 )
232 return _(
"Military Station" );
233 else if ( strcmp(
class,
"2" ) == 0 )
234 return _(
"Pirate Station" );
235 else if ( strcmp(
class,
"3" ) == 0 )
236 return _(
"Robotic Station" );
237 else if ( strcmp(
class,
"4" ) == 0 )
238 return _(
"Artificial Ecosystem" );
240 else if ( strcmp(
class,
"A" ) == 0 )
241 return _(
"Geothermal" );
242 else if ( strcmp(
class,
"B" ) == 0 )
243 return _(
"Geomorteus" );
244 else if ( strcmp(
class,
"C" ) == 0 )
245 return _(
"Geoinactive" );
246 else if ( strcmp(
class,
"D" ) == 0 )
247 return _(
"Asteroid/Moon" );
248 else if ( strcmp(
class,
"E" ) == 0 )
249 return _(
"Geoplastic" );
250 else if ( strcmp(
class,
"F" ) == 0 )
251 return _(
"Geometallic" );
252 else if ( strcmp(
class,
"G" ) == 0 )
253 return _(
"Geocrystaline" );
254 else if ( strcmp(
class,
"H" ) == 0 )
255 return _(
"Desert" );
256 else if ( strcmp(
class,
"I" ) == 0 )
257 return _(
"Gas Supergiant" );
258 else if ( strcmp(
class,
"J" ) == 0 )
259 return _(
"Gas Giant" );
260 else if ( strcmp(
class,
"K" ) == 0 )
261 return _(
"Adaptable" );
262 else if ( strcmp(
class,
"L" ) == 0 )
263 return _(
"Marginal" );
264 else if ( strcmp(
class,
"M" ) == 0 )
265 return _(
"Terrestrial" );
266 else if ( strcmp(
class,
"N" ) == 0 )
267 return _(
"Reducing" );
268 else if ( strcmp(
class,
"O" ) == 0 )
269 return _(
"Pelagic" );
270 else if ( strcmp(
class,
"P" ) == 0 )
271 return _(
"Glaciated" );
272 else if ( strcmp(
class,
"Q" ) == 0 )
273 return _(
"Variable" );
274 else if ( strcmp(
class,
"R" ) == 0 )
276 else if ( strcmp(
class,
"S" ) == 0 || strcmp(
class,
"T" ) == 0 )
277 return _(
"Ultragiants" );
278 else if ( strcmp(
class,
"X" ) == 0 )
280 else if ( strcmp(
class,
"Y" ) == 0 )
282 else if ( strcmp(
class,
"Z" ) == 0 )
283 return _(
"Shattered" );
296 const StarSystem *sys =
system_get( sysname );
311 const StarSystem *sys =
system_get( sysname );
323 economy_averageSeenPricesAtTime( p, tupdate );
350 for (
int i = 0; i <
array_size( sys->asteroids ); i++ ) {
352 density += ast->
area * ast->
density / ASTEROID_REF_AREA;
355 for (
int j = 0; j <
array_size( sys->astexclude ); j++ ) {
359 ast->
density / ASTEROID_REF_AREA;
362 sys->asteroid_density = density;
374 p->presence.faction = faction;
401 p->services |= service;
403 if ( service & SPOB_SERVICE_COMMODITY ) {
408 if ( p->commodities != NULL )
413 for (
int i = 0; i <
array_size( stdList ); i++ )
423 if ( sysname == NULL ) {
424 DEBUG( _(
"Spob '%s' not in system. Not initializing economy." ),
429 economy_initialiseSingleSystem( sys, p );
444 p->services &= ~service;
466 WARN( _(
"Renaming spob '%s', but not found in name stack!" ), p->name );
481 double r = jp->radius * p->stats.jump_distance;
500 if ( pilot_isFlag( p, PILOT_NOJUMP ) )
504 if ( p->fuel < p->fuel_consumption )
508 if ( 0 > p->nav_hyperspace ||
517 d = vec2_dist2( &p->solid.pos, &jp->pos );
531 if ( pilot_isFlag( p, PILOT_NOJUMP ) )
533 if ( p->fuel < p->fuel_consumption )
541 pilot_setFlag( p, PILOT_HYP_PREP );
565 for (
int i = 0; i <
array_size( in->jumps ); i++ )
566 if ( in->jumps[i].target == out )
571 WARN( _(
"Unable to find jump in point for '%s' in '%s': not connected" ),
572 out->name, in->name );
581 a = 2. * M_PI - jp->angle;
582 d = RNGF() * ( HYPERSPACE_ENTER_MAX - HYPERSPACE_ENTER_MIN ) +
583 HYPERSPACE_ENTER_MIN;
584 if ( ( p != NULL ) && pilot_isFlag( p, PILOT_STEALTH ) )
592 ea = 2. * M_PI * RNGF();
593 ed = jp->radius / 2.;
595 ed *= p->stats.jump_distance;
596 if ( pilot_isFlag( p, PILOT_STEALTH ) )
603 vec2_cset( pos, x, y );
607 vec2_cset( vel, HYPERSPACE_VEL * cos( a ), HYPERSPACE_VEL * sin( a ) );
610 *dir = angle_clean( a );
630 for (
int k = 0; k <
array_size( factions ); k++ ) {
667 int ( *filter )(
Spob *p ) )
676 if ( services && ( spob_hasService( pnt, services ) != services ) )
679 if ( ( filter != NULL ) && !filter( pnt ) )
688 for (
int i = 0; i <
array_size( tmp ); i++ ) {
724 int *fie,
double x,
double y )
735 for (
int i = 0; i <
array_size( sys->spobs ); i++ ) {
737 Spob *p = sys->spobs[i];
738 if ( !spob_isKnown( p ) )
740 td =
pow2( x - p->pos.x ) +
pow2( y - p->pos.y );
748 for (
int i = 0; i <
array_size( sys->asteroids ); i++ ) {
750 for (
int k = 0; k <
array_size( f->asteroids ); k++ ) {
755 if ( as->
state != ASTEROID_FG )
773 for (
int i = 0; i <
array_size( sys->jumps ); i++ ) {
775 JumpPoint *j = &sys->jumps[i];
776 if ( !jp_isUsable( j ) )
778 td =
pow2( x - j->pos.x ) +
pow2( y - j->pos.y );
809 int *fie,
double x,
double y,
double ang )
819 for (
int i = 0; i <
array_size( sys->spobs ); i++ ) {
820 Spob *p = sys->spobs[i];
821 double ta = atan2( y - p->pos.y, x - p->pos.x );
822 if (
ABS( angle_diff( ang, ta ) ) <
ABS( angle_diff( ang, a ) ) ) {
829 for (
int i = 0; i <
array_size( sys->asteroids ); i++ ) {
831 for (
int k = 0; k <
array_size( f->asteroids ); k++ ) {
836 if ( as->
state != ASTEROID_FG )
840 if (
ABS( angle_diff( ang, ta ) ) <
ABS( angle_diff( ang, a ) ) ) {
850 for (
int i = 0; i <
array_size( sys->jumps ); i++ ) {
851 JumpPoint *j = &sys->jumps[i];
852 double ta = atan2( y - j->pos.y, x - j->pos.x );
853 if (
ABS( angle_diff( ang, ta ) ) <
ABS( angle_diff( ang, a ) ) ) {
871 if ( sys_isKnown( sys ) )
875 for (
int i = 0; i <
array_size( sys->jumps ); i++ ) {
876 const JumpPoint *jp = sys->jumps[i].returnJump;
877 if ( jp && jp_isUsable( jp ) )
891 StarSystem **path, *goal;
893 if ( strcmp( sysname,
cur_system->name ) == 0 )
898 path = map_getJumpPath(
cur_system, NULL, goal, 1, 1, NULL, NULL );
899 if ( path != NULL ) {
917 else if ( jp_isUsable( jp ) )
960 if ( SDL_strcasestr( system_name( sys ), sysname ) != NULL ) {
961 names[len] = sys->name;
963 }
else if ( ( sys->features != NULL ) &&
964 SDL_strcasestr( _( sys->features ), sysname ) != NULL ) {
965 names[len] = sys->name;
968 for (
int j = 0; j <
array_size( sys->spobs ); j++ ) {
969 const Spob *spob = sys->spobs[j];
970 if ( ( spob->
feature != NULL ) &&
971 SDL_strcasestr( _( spob->
feature ), sysname ) != NULL ) {
972 names[len] = sys->name;
995 const StarSystem *s1, *s2;
996 s1 = (
const StarSystem *)p1;
997 s2 = (
const StarSystem *)p2;
998 return strcmp( s1->name, s2->name );
1009 if ( sysname == NULL )
1018 WARN( _(
"System '%s' not found in stack" ), sysname );
1022 const StarSystem s = { .name = (
char *)sysname };
1025 if ( found != NULL )
1028 WARN( _(
"System '%s' not found in stack" ), sysname );
1087 DEBUG( _(
"Spob '%s' is not placed in a system" ), spobname );
1096 const Spob *spb1 = p1;
1097 const Spob *spb2 = p2;
1098 return strcmp( spb1->
name, spb2->
name );
1109 if ( spobname == NULL ) {
1110 WARN( _(
"Trying to find NULL spob…" ) );
1118 if ( strcmp(
spob_stack[i].name, spobname ) == 0 )
1120 WARN( _(
"Spob '%s' not found in the universe" ), spobname );
1124 const Spob p = { .name = (
char *)spobname };
1127 if ( found != NULL )
1130 WARN( _(
"Spob '%s' not found in the universe" ), spobname );
1144 WARN( _(
"Spob index '%d' out of range (max %d)" ), ind,
1176 spob_setFlag( p, SPOB_KNOWN );
1188 if ( strcmp(
spob_stack[i].name, spobname ) == 0 )
1202 if ( strcasecmp(
spob_stack[i].name, spobname ) == 0 )
1220 if ( SDL_strcasestr(
spob_name( spob ), spobname ) != NULL ) {
1221 names[len] = spob->
name;
1223 }
else if ( ( spob->
feature != NULL ) &&
1224 SDL_strcasestr( _( spob->
feature ), spobname ) != NULL ) {
1225 names[len] = spob->
name;
1255 return strcmp( v1->name, v2->name );
1266 if ( found != NULL )
1268 WARN( _(
"Virtual Spob '%s' not found in the universe" ), name );
1279JumpPoint *
jump_get(
const char *jumpname,
const StarSystem *sys )
1281 if ( jumpname == NULL ) {
1282 WARN( _(
"Trying to find NULL jump point..." ) );
1286 for (
int i = 0; i <
array_size( sys->jumps ); i++ ) {
1287 JumpPoint *jp = &sys->jumps[i];
1288 if ( strcmp( jp->target->name, jumpname ) == 0 )
1292 WARN( _(
"Jump point '%s' not found in %s" ), jumpname, sys->name );
1305 for (
int i = 0; i <
array_size( sys->jumps ); i++ ) {
1306 JumpPoint *jp = &sys->jumps[i];
1307 if ( jp->target->id == target->id )
1310 WARN( _(
"Jump point to '%s' not found in %s" ), target->name, sys->name );
1319 if ( jp_isFlag( jp, JP_HIDDEN ) )
1332 NTracingZone( _ctx, 1 );
1339 if ( p->value <= 0. )
1345 if ( env == LUA_NOREF )
1354 nlua_getenv(
naevL, env,
"create" );
1355 if ( lua_isnil(
naevL, -1 ) ) {
1356 WARN( _(
"Lua Spawn script for faction '%s' missing obligatory "
1357 "entry point 'create'." ),
1359 lua_pop(
naevL, 1 );
1366 if ( p->timer >= 0. )
1369 nlua_getenv(
naevL, env,
"spawn" );
1370 if ( lua_isnil(
naevL, -1 ) ) {
1371 WARN( _(
"Lua Spawn script for faction '%s' missing obligatory "
1372 "entry point 'spawn'." ),
1374 lua_pop(
naevL, 1 );
1377 lua_pushnumber(
naevL, p->curUsed );
1380 lua_pushnumber(
naevL, p->value );
1383 if ( nlua_pcall( env, n + 1, 2 ) ) {
1384 WARN( _(
"Lua Spawn script for faction '%s' : %s" ),
1386 lua_pop(
naevL, 1 );
1391 if ( !lua_isnumber(
naevL, -2 ) ) {
1392 WARN( _(
"Lua spawn script for faction '%s' failed to return timer "
1395 lua_pop(
naevL, 2 );
1398 p->timer += lua_tonumber(
naevL, -2 );
1400 if ( lua_istable(
naevL, -1 ) ) {
1401 lua_pushnil(
naevL );
1402 while ( lua_next(
naevL, -2 ) != 0 ) {
1406 if ( !lua_istable(
naevL, -1 ) ) {
1407 WARN( _(
"Lua spawn script for faction '%s' returns invalid "
1408 "data (not a table)." ),
1410 lua_pop(
naevL, 2 );
1414 lua_getfield(
naevL, -1,
"pilot" );
1416 WARN( _(
"Lua spawn script for faction '%s' returns invalid "
1417 "data (not a pilot)." ),
1419 lua_pop(
naevL, 2 );
1423 if ( pilot == NULL ) {
1424 lua_pop(
naevL, 2 );
1427 lua_pop(
naevL, 1 );
1428 lua_getfield(
naevL, -1,
"presence" );
1429 if ( !lua_isnumber(
naevL, -1 ) ) {
1430 WARN( _(
"Lua spawn script for faction '%s' returns invalid "
1431 "data (not a number)." ),
1433 lua_pop(
naevL, 2 );
1439 if ( pilot->
faction != p->faction ) {
1440 WARN( _(
"Lua spawn script for faction '%s' actually spawned a "
1448 lua_pop(
naevL, 2 );
1451 lua_pop(
naevL, 2 );
1454 NTracingZoneEnd( _ctx );
1470 if ( space_landQueueSpob != NULL ) {
1471 land( space_landQueueSpob, 0 );
1472 space_landQueueSpob = NULL;
1488 NTracingZone( _ctx, 1 );
1517 if ( (
player.p != NULL ) && (
player.p->nav_spob >= 0 ) &&
1518 player_isFlag( PLAYER_LANDACK ) )
1526 int found_something = 0;
1536 if (
player.discover_off )
1546 hparam[0].
type = HOOK_PARAM_STRING;
1547 hparam[0].
u.
str =
"spob";
1548 hparam[1].
type = HOOK_PARAM_SPOB;
1549 hparam[1].
u.
la = pnt->
id;
1550 hparam[2].
type = HOOK_PARAM_SENTINEL;
1552 found_something = 1;
1562 if (
player.discover_off )
1565 if ( jp_isKnown( jp ) )
1567 if ( jp_isFlag( jp, JP_EXITONLY ) )
1572 jp_setFlag( jp, JP_KNOWN );
1574 hparam[0].
type = HOOK_PARAM_STRING;
1575 hparam[0].
u.
str =
"jump";
1576 hparam[1].
type = HOOK_PARAM_JUMP;
1579 hparam[2].
type = HOOK_PARAM_SENTINEL;
1581 found_something = 1;
1585 if ( found_something )
1595 NTracingZoneEnd( _ctx );
1622 const double fps_min_simulation =
fps_min;
1625 NTracingFrameMarkStart(
"space_init" );
1626 NTracingZone( _ctx, 1 );
1628 char buf[STRMAX_SHORT];
1629 size_t l = snprintf( buf,
sizeof( buf ),
"Entering system '%s'", sysname );
1630 NTracingMessage( buf, l );
1645 if (
player.p != NULL ) {
1654 if ( ( sysname == NULL ) && (
cur_system == NULL ) ) {
1656 _(
"Cannot reinit system if there is no system previously loaded" ) );
1659 }
else if ( sysname != NULL ) {
1664 WARN( _(
"System '%s' not found, trying random system!" ), sysname );
1669 if ( sys_isFlag(
cur_system, SYSTEM_HIDENEBULADAMAGE ) )
1670 snprintf( dmgstr,
sizeof( dmgstr ),
1671 p_(
"nebula_volatility",
"??? %s" ), UNIT_POWER );
1673 snprintf( dmgstr,
sizeof( dmgstr ),
1674 p_(
"nebula_volatility",
"%.1f %s" ),
1676 player_message( _(
"#oEntering System %s on %s." ), _( sysname ), nt );
1678 player_message( _(
"#rWARNING - Volatile nebula detected in %s! "
1679 "Taking %s damage!" ),
1680 _( sysname ), dmgstr );
1685 if ( ( oldsys != NULL && oldsys->stats != NULL ) ||
1691 if ( pilot_isWithPlayer( p ) )
1692 pilot_setFlag( p, PILOT_HIDE );
1704 if ( (
player.p != NULL ) && do_simulate )
1727 NTracingZoneName( _ctx_simulating,
"space_init[simulation]", 1 );
1732 if (
player.p != NULL ) {
1734 pilot_setFlag(
player.p, PILOT_HIDE );
1737 if ( pilot_isWithPlayer( p ) )
1738 pilot_setFlag( p, PILOT_HIDE );
1742 if ( do_simulate ) {
1748 n = SYSTEM_SIMULATE_TIME_PRE / fps_min_simulation;
1749 for (
int i = 0; i < n; i++ )
1752 n = SYSTEM_SIMULATE_TIME_POST / fps_min_simulation;
1753 for (
int i = 0; i < n; i++ )
1759 if (
player.p != NULL ) {
1761 pilot_rmFlag(
player.p, PILOT_HIDE );
1764 if ( pilot_isWithPlayer( p ) )
1765 pilot_rmFlag( p, PILOT_HIDE );
1770 NTracingZoneEnd( _ctx_simulating );
1780 sys_isFlag(
cur_system, SYSTEM_NEBULATRAIL ) ) {
1797 NTracingZoneEnd( _ctx );
1798 NTracingFrameMarkEnd(
"space_init" );
1806 Spob *p, *old_stack;
1837 return _( p->display );
1838 return _( p->name );
1860 for (
int i = 0; i <
array_size( spob_files ); i++ ) {
1863 int ret =
spob_parse( &s, spob_files[i], stdList );
1874 free( spob_files[i] );
1902 for (
int i = 0; i <
array_size( spob_files ); i++ ) {
1907 free( spob_files[i] );
1912 if ( doc == NULL ) {
1913 free( spob_files[i] );
1917 node = doc->xmlChildrenNode;
1918 if ( node == NULL ) {
1919 WARN( _(
"Malformed %s file: does not contain elements" ),
1921 free( spob_files[i] );
1929 memset( &va, 0,
sizeof( va ) );
1930 xmlr_attr_strd( node,
"name", va.
name );
1933 cur = node->children;
1935 xml_onlyNodes( cur );
1936 if ( xml_isNode( cur,
"presence" ) ) {
1943 WARN( _(
"Unknown node '%s' in virtual spob '%s'" ), cur->name,
1945 }
while ( xml_nextNode( cur ) );
1951 free( spob_files[i] );
1968 if ( !spob_hasService( p, SPOB_SERVICE_INHABITED ) )
1971 if ( p->can_land ) {
1972 if (
areAllies( FACTION_PLAYER, p->presence.faction ) )
1977 if ( spob_isFlag( p, SPOB_HOSTILE ) ||
1978 areEnemies( FACTION_PLAYER, p->presence.faction ) )
1988 if ( !spob_hasService( p, SPOB_SERVICE_INHABITED ) ) {
1989 if ( spob_hasService( p, SPOB_SERVICE_LAND ) )
1994 if ( p->can_land ) {
1995 if (
areAllies( FACTION_PLAYER, p->presence.faction ) )
2000 if ( spob_isFlag( p, SPOB_HOSTILE ) ||
2001 areEnemies( FACTION_PLAYER, p->presence.faction ) )
2011 if ( !spob_hasService( p, SPOB_SERVICE_INHABITED ) )
2014 if ( p->can_land ) {
2015 if (
areAllies( FACTION_PLAYER, p->presence.faction ) )
2020 if ( spob_isFlag( p, SPOB_HOSTILE ) ||
2021 areEnemies( FACTION_PLAYER, p->presence.faction ) )
2023 return &cRestricted;
2033 if ( p->land_override && ( p->land_msg != NULL ) ) {
2034 p->can_land = ( p->land_override > 0 );
2038 NTracingZone( _ctx, 1 );
2041 free( p->land_msg );
2046 if ( p->lua_can_land != LUA_NOREF ) {
2048 lua_rawgeti(
naevL, LUA_REGISTRYINDEX, p->lua_can_land );
2049 if ( nlua_pcall( p->lua_env, 0, 2 ) ) {
2050 WARN( _(
"Spob '%s' failed to run '%s':\n%s" ), p->name,
"can_land",
2051 lua_tostring(
naevL, -1 ) );
2052 lua_pop(
naevL, 1 );
2053 NTracingZoneEnd( _ctx );
2057 p->can_land = lua_toboolean(
naevL, -2 );
2058 if ( lua_isstring(
naevL, -1 ) )
2059 p->land_msg = strdup( lua_tostring(
naevL, -1 ) );
2060 lua_pop(
naevL, 2 );
2062 NTracingZoneEnd( _ctx );
2067 if ( p->land_override < 0 ) {
2068 p->land_msg = strdup( _(
"Landing permission denied." ) );
2069 }
else if ( spob_hasService( p, SPOB_SERVICE_LAND ) ||
2070 ( p->land_override > 0 ) ) {
2072 p->land_msg = strdup( _(
"Landing permission granted." ) );
2075 NTracingZoneEnd( _ctx );
2083 if ( attacker == NULL )
2095 if ( nlua_pcall( spb->
lua_env, 2, 0 ) ) {
2096 WARN( _(
"Spob '%s' failed to run '%s':\n%s" ), spb->
name,
"distress",
2097 lua_tostring(
naevL, -1 ) );
2098 lua_pop(
naevL, 1 );
2111 lua_rawgeti(
naevL, LUA_REGISTRYINDEX, spob->
lua_mem );
2127 if ( ( x ) != LUA_NOREF ) { \
2128 luaL_unref( naevL, LUA_REGISTRYINDEX, ( x ) ); \
2129 ( x ) = LUA_NOREF; \
2152 nlua_env env = spob_lua_get( &mem, spob->
lua_file );
2153 if ( env == LUA_NOREF )
2172 lua_newtable(
naevL );
2173 lua_pushvalue(
naevL, -1 );
2177 lua_rawgeti(
naevL, LUA_REGISTRYINDEX, mem );
2178 lua_pushnil(
naevL );
2179 while ( lua_next(
naevL, -2 ) != 0 ) {
2180 lua_pushvalue(
naevL, -2 );
2181 lua_pushvalue(
naevL, -2 );
2182 lua_remove(
naevL, -3 );
2183 lua_settable(
naevL, -5 );
2185 lua_pop(
naevL, 2 );
2188 if ( spob->
lua_init != LUA_NOREF ) {
2192 if ( nlua_pcall( spob->
lua_env, 1, 0 ) ) {
2193 WARN( _(
"Spob '%s' failed to run '%s':\n%s" ), spob->
name,
"init",
2194 lua_tostring(
naevL, -1 ) );
2195 lua_pop(
naevL, 1 );
2208 if ( spob->
lua_load != LUA_NOREF ) {
2211 if ( nlua_pcall( spob->
lua_env, 0, 2 ) ) {
2212 WARN( _(
"Spob '%s' failed to run '%s':\n%s" ), spob->
name,
"load",
2213 lua_tostring(
naevL, -1 ) );
2214 lua_pop(
naevL, 1 );
2221 }
else if ( lua_isnil(
naevL, -2 ) ) {
2225 _(
"Spob '%s' ran '%s' but got non-texture or nil return value!" ),
2226 spob->
name,
"load" );
2228 lua_pop(
naevL, 2 );
2231 if ( ( spob->gfx_space3d == NULL ) && ( spob->
gfx_space == NULL ) ) {
2232 if ( spob->gfx_space3dName != NULL ) {
2234 double s = spob->gfx_space3d_size;
2235 spob->gfx_space3d = gltf_loadFromFile( spob->gfx_space3dName );
2238 s * spob_aa_scale );
2239 gl_fboAddDepth( spob->gfx_fbo, &spob->gfx_dtex, s * spob_aa_scale,
2240 s * spob_aa_scale );
2243 glBindFramebuffer( GL_FRAMEBUFFER, spob->gfx_fbo );
2244 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
2246 gltf_renderScene( spob->gfx_fbo, spob->gfx_space3d, 0, NULL,
2249 glBindFramebuffer( GL_FRAMEBUFFER,
gl_screen.current_fbo );
2255 if ( ( spob->gfx_space3d != NULL ) && ( spob->
radius < 0. ) )
2256 spob->
radius = spob->gfx_space3d_size * 0.5;
2268 NTracingZone( _ctx, 1 );
2270 for (
int i = 0; i <
array_size( sys->spobs ); i++ )
2273 NTracingZoneEnd( _ctx );
2283 for (
int i = 0; i <
array_size( sys->spobs ); i++ ) {
2284 Spob *spob = sys->spobs[i];
2289 if ( nlua_pcall( spob->
lua_env, 0, 0 ) ) {
2290 WARN( _(
"Spob '%s' failed to run '%s':\n%s" ), spob->
name,
2291 "unload", lua_tostring(
naevL, -1 ) );
2292 lua_pop(
naevL, 1 );
2296 if ( spob->gfx_space3d != NULL ) {
2297 glDeleteFramebuffers( 1, &spob->gfx_fbo );
2298 glDeleteTextures( 1, &spob->gfx_dtex );
2300 gltf_free( spob->gfx_space3d );
2301 spob->gfx_space3d = NULL;
2315 xmlNodePtr cur = node->children;
2319 xml_onlyNodes( cur );
2320 xmlr_float( cur,
"base", ap->
base );
2321 xmlr_float( cur,
"bonus", ap->
bonus );
2322 xmlr_int( cur,
"range", ap->
range );
2323 if ( xml_isNode( cur,
"faction" ) ) {
2327 }
while ( xml_nextNode( cur ) );
2337 memset( spob, 0,
sizeof(
Spob ) );
2368 xmlNodePtr node, parent;
2376 parent = doc->xmlChildrenNode;
2377 if ( parent == NULL ) {
2378 WARN( _(
"Malformed %s file: does not contain elements" ), filename );
2389 xmlr_attr_strd( parent,
"name", spob->
name );
2391 node = parent->xmlChildrenNode;
2394 xml_onlyNodes( node );
2396 xmlr_strd( node,
"display", spob->
display );
2397 xmlr_strd( node,
"feature", spob->
feature );
2398 xmlr_float( node,
"radius", spob->
radius );
2399 if ( xml_isNode( node,
"lua" ) ) {
2400 const char *nstr = xml_get( node );
2401 if ( nstr == NULL ) {
2402 WARN( _(
"Spob '%s' has invalid '%s' node." ), spob->
name,
"lua" );
2405 if ( nstr[0] ==
'/' )
2408 SDL_asprintf( &spob->
lua_file, SPOB_DATA_LUA_PATH
"%s", nstr );
2412 if ( xml_isNode( node,
"marker" ) ) {
2413 const char *s = xml_get( node );
2414 spob->
marker = shaders_getSimple( s );
2415 xmlr_attr_float_def( node,
"scale", spob->
marker_scale, 1. );
2416 if ( spob->
marker == NULL )
2417 WARN( _(
"Spob '%s' has unknown marker shader '%s'!" ), spob->
name,
2422 if ( xml_isNode( node,
"GFX" ) ) {
2423 xmlNodePtr cur = node->children;
2425 xml_onlyNodes( cur );
2426 if ( xml_isNode( cur,
"space3d" ) ) {
2428 snprintf( str,
sizeof( str ), SPOB_GFX_SPACE3D_PATH
"%s",
2430 spob->gfx_space3dName = strdup( str );
2431 spob->gfx_space3dPath = xml_getStrd( cur );
2432 xmlr_attr_float( cur,
"size", spob->gfx_space3d_size );
2435 if ( xml_isNode( cur,
"space" ) ) {
2437 snprintf( str,
sizeof( str ), SPOB_GFX_SPACE_PATH
"%s",
2443 if ( xml_isNode( cur,
"exterior" ) ) {
2445 snprintf( str,
sizeof( str ), SPOB_GFX_EXTERIOR_PATH
"%s",
2451 if ( xml_isNode( cur,
"comm" ) ) {
2453 snprintf( str,
sizeof( str ), SPOB_GFX_COMM_PATH
"%s",
2459 WARN( _(
"Unknown node '%s' in spob '%s'" ), node->name,
2461 }
while ( xml_nextNode( cur ) );
2463 }
else if ( xml_isNode( node,
"pos" ) ) {
2464 xmlr_attr_float( node,
"x", spob->
pos.
x );
2465 xmlr_attr_float( node,
"y", spob->
pos.
y );
2468 }
else if ( xml_isNode( node,
"presence" ) ) {
2473 }
else if ( xml_isNode( node,
"general" ) ) {
2474 xmlNodePtr cur = node->children;
2476 xml_onlyNodes( cur );
2478 xmlr_strd( cur,
"class", spob->
class );
2480 xmlr_strd( cur,
"description", spob->
description );
2481 xmlr_float( cur,
"population", spob->
population );
2482 xmlr_float( cur,
"hide", spob->
hide );
2484 if ( xml_isNode( cur,
"services" ) ) {
2485 xmlNodePtr ccur = cur->children;
2489 xml_onlyNodes( ccur );
2491 if ( xml_isNode( ccur,
"land" ) )
2492 spob->
services |= SPOB_SERVICE_LAND;
2493 else if ( xml_isNode( ccur,
"refuel" ) )
2495 SPOB_SERVICE_REFUEL | SPOB_SERVICE_INHABITED;
2496 else if ( xml_isNode( ccur,
"bar" ) )
2498 SPOB_SERVICE_BAR | SPOB_SERVICE_INHABITED;
2499 else if ( xml_isNode( ccur,
"missions" ) )
2501 SPOB_SERVICE_MISSIONS | SPOB_SERVICE_INHABITED;
2502 else if ( xml_isNode( ccur,
"commodity" ) )
2504 SPOB_SERVICE_COMMODITY | SPOB_SERVICE_INHABITED;
2505 else if ( xml_isNode( ccur,
"outfits" ) )
2507 SPOB_SERVICE_OUTFITS | SPOB_SERVICE_INHABITED;
2508 else if ( xml_isNode( ccur,
"shipyard" ) )
2510 SPOB_SERVICE_SHIPYARD | SPOB_SERVICE_INHABITED;
2511 else if ( xml_isNode( ccur,
"nomissionspawn" ) )
2512 spob->
flags |= SPOB_NOMISNSPAWN;
2513 else if ( xml_isNode( ccur,
"uninhabited" ) )
2514 spob->
flags |= SPOB_UNINHABITED;
2515 else if ( xml_isNode( ccur,
"blackmarket" ) )
2516 spob->
services |= SPOB_SERVICE_BLACKMARKET;
2517 else if ( xml_isNode( ccur,
"nolanes" ) )
2518 spob->
flags |= SPOB_NOLANES;
2520 WARN( _(
"Spob '%s' has unknown services tag '%s'" ),
2521 spob->
name, ccur->name );
2522 }
while ( xml_nextNode( ccur ) );
2525 else if ( xml_isNode( cur,
"commodities" ) ) {
2526 xmlNodePtr ccur = cur->children;
2528 if ( xml_isNode( ccur,
"commodity" ) ) {
2531 if ( commodity_isFlag( com, COMMODITY_FLAG_STANDARD ) )
2536 }
while ( xml_nextNode( ccur ) );
2537 }
else if ( xml_isNode( cur,
"blackmarket" ) ) {
2541 }
while ( xml_nextNode( cur ) );
2543 }
else if ( xml_isNode( node,
"tech" ) ) {
2546 }
else if ( xml_isNode( node,
"tags" ) ) {
2547 xmlNodePtr cur = node->children;
2548 if ( spob->
tags != NULL )
2549 WARN( _(
"Spob '%s' has duplicate '%s' node!" ), spob->
name,
2554 xml_onlyNodes( cur );
2555 if ( xml_isNode( cur,
"tag" ) ) {
2556 const char *tmp = xml_get( cur );
2561 WARN( _(
"Spob '%s' has unknown node in tags '%s'." ), spob->
name,
2563 }
while ( xml_nextNode( cur ) );
2567 WARN( _(
"Unknown node '%s' in spob '%s'" ), node->name, spob->
name );
2568 }
while ( xml_nextNode( node ) );
2571 if ( spob_isFlag( spob, SPOB_UNINHABITED ) )
2572 spob->
services &= ~SPOB_SERVICE_INHABITED;
2575 spob_setFlag( spob, SPOB_RADIUS );
2585 spob->
filename = strdup( filename );
2590 WARN( _(
"Can not find exterior graphic '%s' for spob '%s'!" ),
2593 WARN( _(
"Can not find comm graphic '%s' for spob '%s'!" ),
2600#define MELEMENT( o, s ) \
2602 WARN( _( "Spob '%s' missing '%s' element" ), spob->name, s )
2604 MELEMENT( spob_hasService( spob, SPOB_SERVICE_LAND ) &&
2607 MELEMENT( spob_hasService( spob, SPOB_SERVICE_INHABITED ) &&
2611 MELEMENT( spob->
class == NULL,
"class" );
2612 MELEMENT( spob_hasService( spob, SPOB_SERVICE_LAND ) &&
2615 MELEMENT( spob_hasService( spob, SPOB_SERVICE_BAR ) &&
2618 MELEMENT( spob_hasService( spob, SPOB_SERVICE_INHABITED ) &&
2622 MELEMENT( spob_hasService( spob, SPOB_SERVICE_INHABITED ) &&
2623 ( spob_hasService( spob, SPOB_SERVICE_OUTFITS ) ||
2624 spob_hasService( spob, SPOB_SERVICE_SHIPYARD ) ) &&
2625 ( spob->
tech == NULL ),
2634 if ( spob_hasService( spob, SPOB_SERVICE_COMMODITY ) ) {
2640 for (
int i = 0; i <
array_size( stdList ); i++ )
2645 for (
int i = 0; i <
array_size( comms ); i++ )
2694 if ( spob_hasService( spob, SPOB_SERVICE_COMMODITY ) )
2695 economy_initialiseSingleSystem( sys, spob );
2714 if ( sys == NULL ) {
2715 WARN( _(
"Unable to remove spob '%s' from NULL system." ), spobname );
2721 for ( i = 0; i <
array_size( sys->spobs ); i++ )
2722 if ( sys->spobs[i] == spob )
2727 WARN( _(
"Spob '%s' not found in system '%s' for removal." ), spobname,
2733 array_erase( &sys->spobs, &sys->spobs[i], &sys->spobs[i + 1] );
2734 array_erase( &sys->spobsid, &sys->spobsid[i], &sys->spobsid[i + 1] );
2748 WARN( _(
"Unable to find spob '%s' and system '%s' in spob<->system "
2750 spobname, sys->name );
2793 if ( sys == NULL ) {
2794 WARN( _(
"Unable to remove virtual spob '%s' from NULL system." ),
2800 for ( i = 0; i <
array_size( sys->spobs_virtual ); i++ )
2801 if ( strcmp( sys->spobs_virtual[i]->name, spobname ) == 0 )
2805 if ( i >=
array_size( sys->spobs_virtual ) ) {
2806 WARN( _(
"Virtual spob '%s' not found in system '%s' for removal." ),
2807 spobname, sys->name );
2812 array_erase( &sys->spobs_virtual, &sys->spobs_virtual[i],
2813 &sys->spobs_virtual[i + 1] );
2834 for (
int i = 0; i <
array_size( sys->jumps ); i++ ) {
2835 JumpPoint *jp = &sys->jumps[i];
2836 if ( jp->targetid != target->id )
2839 WARN( _(
"Star System '%s' has duplicate jump point to '%s'." ),
2840 sys->name, target->name );
2847 memset( j, 0,
sizeof( JumpPoint ) );
2851 j->targetid = j->target->id;
2853 j->hide = HIDE_DEFAULT_JUMP;
2854 jp_setFlag( j, JP_AUTOPOS );
2873 for ( i = 0; i <
array_size( sys->jumps ); i++ )
2874 if ( sys->jumps[i].target == target )
2879 WARN( _(
"Jump for system '%s' not found in system '%s' for removal." ),
2880 target->name, sys->name );
2885 array_erase( &sys->jumps, &sys->jumps[i], &sys->jumps[i + 1] );
2894 memset( sys, 0,
sizeof( StarSystem ) );
2941const char *system_name(
const StarSystem *sys )
2943 if ( sys->display != NULL )
2944 return _( sys->display );
2945 return _( sys->name );
2948const char *system_nameKnown(
const StarSystem *sys )
2950 if ( !sys_isKnown( sys ) )
2951 return _(
"Unknown" );
2952 return system_name( sys );
2960 for (
int j = 0; j <
array_size( sys->jumps ); j++ ) {
2962 JumpPoint *jp = &sys->jumps[j];
2968 dx = jp->target->pos.x - sys->pos.x;
2969 dy = jp->target->pos.y - sys->pos.y;
2970 a = atan2( dy, dx );
2975 if ( jp->flags & JP_AUTOPOS )
2976 vec2_pset( &jp->pos, sys->radius, a );
2981 jp->angle = 2. * M_PI - a;
2982 jp->cosa = cos( jp->angle );
2983 jp->sina = sin( jp->angle );
2992 NTracingZone( _ctx, 1 );
2999 for (
int j = 0; j <
array_size( sys->jumps ); j++ )
3000 sys->jumps[j].targetid = sys->jumps[j].target->id;
3003 NTracingZoneEnd( _ctx );
3011 NTracingZone( _ctx, 1 );
3015 for (
int j = 0; j <
array_size( sys->spobsid ); j++ )
3016 sys->spobs[j] = &
spob_stack[sys->spobsid[j]];
3019 NTracingZoneEnd( _ctx );
3043 xmlr_attr_strd( node,
"label", a->label );
3046 cur = node->xmlChildrenNode;
3048 xml_onlyNodes( cur );
3050 xmlr_float( cur,
"density", a->density );
3051 xmlr_float( cur,
"radius", a->radius );
3052 xmlr_float( cur,
"maxspeed", a->maxspeed );
3053 xmlr_float( cur,
"accel", a->accel );
3056 if ( xml_isNode( cur,
"group" ) ) {
3058 const char *name = xml_get( cur );
3059 xmlr_attr_float_def( cur,
"weight", w, 1. );
3066 if ( xml_isNode( cur,
"pos" ) ) {
3069 xmlr_attr_float( cur,
"x", x );
3070 xmlr_attr_float( cur,
"y", y );
3073 vec2_cset( &a->pos, x, y );
3077 WARN( _(
"Asteroid Field in Star System '%s' has unknown node '%s'" ),
3078 sys->name, node->name );
3079 }
while ( xml_nextNode( cur ) );
3084#define MELEMENT( o, s ) \
3086 WARN( _( "Asteroid Field in Star System '%s' has missing/invalid '%s' " \
3089 MELEMENT( !pos,
"pos" );
3090 MELEMENT( a->radius <= 0.,
"radius" );
3091 MELEMENT(
array_size( a->groups ) == 0,
"groups" );
3114 memset( a, 0,
sizeof( *a ) );
3117 xmlr_attr_strd( node,
"label", a->label );
3123 cur = node->xmlChildrenNode;
3125 xml_onlyNodes( cur );
3127 xmlr_float( cur,
"radius", a->radius );
3130 if ( xml_isNode( cur,
"pos" ) ) {
3132 xmlr_attr_float( cur,
"x", x );
3133 xmlr_attr_float( cur,
"y", y );
3136 vec2_cset( &a->pos, x, y );
3139 WARN( _(
"Asteroid Exclusion Zone in Star System '%s' has unknown node "
3141 sys->name, node->name );
3142 }
while ( xml_nextNode( cur ) );
3144#define MELEMENT( o, s ) \
3146 WARN( _( "Asteroid Exclusion Zone in Star System '%s' has missing/invalid " \
3149 MELEMENT( !pos,
"pos" );
3150 MELEMENT( a->radius <= 0.,
"radius" );
3165 xmlNodePtr node, parent;
3174 parent = doc->xmlChildrenNode;
3175 if ( parent == NULL ) {
3176 WARN( _(
"Malformed %s file: does not contain elements" ), filename );
3184 sys->ownerpresence = 0.;
3185 sys->nebu_hue = NEBULA_DEFAULT_HUE;
3186 sys->spacedust = -1;
3188 xmlr_attr_strd( parent,
"name", sys->name );
3190 node = parent->xmlChildrenNode;
3193 xml_onlyNodes( node );
3195 xmlr_strd( node,
"display", sys->display );
3196 if ( xml_isNode( node,
"pos" ) ) {
3198 xmlr_attr_float( node,
"x", sys->pos.x );
3199 xmlr_attr_float( node,
"y", sys->pos.y );
3201 }
else if ( xml_isNode( node,
"general" ) ) {
3202 xmlNodePtr cur = node->children;
3204 xml_onlyNodes( cur );
3205 xmlr_strd( cur,
"background", sys->background );
3206 xmlr_strd( cur,
"map_shader", sys->map_shader );
3207 xmlr_strd( cur,
"features", sys->features );
3208 xmlr_int( cur,
"spacedust", sys->spacedust );
3212 sys->spacedust = xml_getInt( cur );
3213 WARN( _(
"System '%s' is using deprecated field 'stars'. Use "
3214 "'spacedust' instead!" ),
3217 xmlr_float( cur,
"radius", sys->radius );
3218 if ( xml_isNode( cur,
"interference" ) ) {
3220 sys->interference = xml_getFloat( cur );
3223 if ( xml_isNode( cur,
"nebula" ) ) {
3226 xmlr_attr_float( cur,
"volatility", sys->nebu_volatility );
3227 xmlr_attr_float_def( cur,
"hue", sys->nebu_hue,
3228 NEBULA_DEFAULT_HUE );
3229 xmlr_attr_int( cur,
"trails", trails );
3230 xmlr_attr_int( cur,
"hidenebuladamage", hidedmg );
3231 sys->nebu_density = xml_getFloat( cur );
3232 if ( trails || ( sys->nebu_density > 0. ) )
3233 sys_setFlag( sys, SYSTEM_NEBULATRAIL );
3235 sys_setFlag( sys, SYSTEM_HIDENEBULADAMAGE );
3238 if ( xml_isNode( cur,
"nolanes" ) ) {
3239 sys_setFlag( sys, SYSTEM_NOLANES );
3242 DEBUG( _(
"Unknown node '%s' in star system '%s'" ), node->name,
3244 }
while ( xml_nextNode( cur ) );
3248 else if ( xml_isNode( node,
"spobs" ) ) {
3249 xmlNodePtr cur = node->children;
3251 xml_onlyNodes( cur );
3252 if ( xml_isNode( cur,
"spob" ) ) {
3256 if ( xml_isNode( cur,
"spob_virtual" ) ) {
3260 DEBUG( _(
"Unknown node '%s' in star system '%s'" ), node->name,
3262 }
while ( xml_nextNode( cur ) );
3266 if ( xml_isNode( node,
"asteroids" ) ) {
3267 xmlNodePtr cur = node->children;
3269 xml_onlyNodes( cur );
3270 if ( xml_isNode( cur,
"asteroid" ) )
3272 else if ( xml_isNode( cur,
"exclusion" ) )
3274 }
while ( xml_nextNode( cur ) );
3277 if ( xml_isNode( node,
"stats" ) ) {
3278 xmlNodePtr cur = node->children;
3280 xml_onlyNodes( cur );
3283 ll->
next = sys->stats;
3287 WARN( _(
"System '%s' has unknown stat '%s'." ), sys->name,
3289 }
while ( xml_nextNode( cur ) );
3293 if ( xml_isNode( node,
"tags" ) ) {
3294 xmlNodePtr cur = node->children;
3297 xml_onlyNodes( cur );
3298 if ( xml_isNode( cur,
"tag" ) ) {
3299 const char *tmp = xml_get( cur );
3304 WARN( _(
"System '%s' has unknown node in tags '%s'." ), sys->name,
3306 }
while ( xml_nextNode( cur ) );
3311 if ( xml_isNode( node,
"jumps" ) || xml_isNode( node,
"asteroids" ) )
3314 DEBUG( _(
"Unknown node '%s' in star system '%s'" ), node->name,
3316 }
while ( xml_nextNode( node ) );
3325 sys->nebu_hue /= 360.;
3328 if ( sys->map_shader != NULL )
3331#define MELEMENT( o, s ) \
3333 WARN( _( "Star System '%s' missing '%s' element" ), sys->name, s )
3334 if ( sys->name == NULL )
3335 WARN( _(
"Star System '%s' missing 'name' tag" ), sys->name );
3337 MELEMENT( sys->spacedust < 0,
"spacedust" );
3338 MELEMENT( sys->radius == 0.,
"radius" );
3381 qsort( sys->presence,
array_size( sys->presence ),
3385 for (
int i = 0; i <
array_size( sys->presence ); i++ ) {
3386 for (
int j = 0; j <
array_size( sys->spobs );
3388 Spob *pnt = sys->spobs[j];
3416 xmlr_attr_strd( node,
"target", buf );
3417 if ( buf == NULL ) {
3418 WARN( _(
"JumpPoint node for system '%s' has no target attribute." ),
3423 if ( target == NULL ) {
3424 WARN( _(
"JumpPoint node for system '%s' has invalid target '%s'." ),
3432 for (
int i = 0; i <
array_size( sys->jumps ); i++ ) {
3433 JumpPoint *jp = &sys->jumps[i];
3434 if ( jp->targetid != target->id )
3437 WARN( _(
"Star System '%s' has duplicate jump point to '%s'." ),
3438 sys->name, target->name );
3445 memset( j, 0,
sizeof( JumpPoint ) );
3450 j->targetid = j->target->id;
3456 cur = node->xmlChildrenNode;
3458 xmlr_float( cur,
"radius", j->radius );
3461 if ( xml_isNode( cur,
"pos" ) ) {
3463 xmlr_attr_float( cur,
"x", x );
3464 xmlr_attr_float( cur,
"y", y );
3467 vec2_cset( &j->pos, x, y );
3468 }
else if ( xml_isNode( cur,
"autopos" ) )
3469 jp_setFlag( j, JP_AUTOPOS );
3470 else if ( xml_isNode( cur,
"hidden" ) )
3471 jp_setFlag( j, JP_HIDDEN );
3472 else if ( xml_isNode( cur,
"exitonly" ) )
3473 jp_setFlag( j, JP_EXITONLY );
3474 else if ( xml_isNode( cur,
"nolanes" ) )
3475 jp_setFlag( j, JP_NOLANES );
3476 else if ( xml_isNode( cur,
"hide" ) ) {
3477 xmlr_float( cur,
"hide", j->hide );
3479 }
while ( xml_nextNode( cur ) );
3481 if ( !jp_isFlag( j, JP_AUTOPOS ) && !pos )
3482 WARN( _(
"JumpPoint in system '%s' is missing pos element but does not "
3483 "have autopos flag." ),
3497 xmlNodePtr parent, node;
3504 parent = doc->xmlChildrenNode;
3505 if ( parent == NULL ) {
3510 node = parent->xmlChildrenNode;
3512 if ( xml_isNode( node,
"jumps" ) ) {
3513 xmlNodePtr cur = node->children;
3515 if ( xml_isNode( cur,
"jump" ) )
3517 }
while ( xml_nextNode( cur ) );
3519 }
while ( xml_nextNode( node ) );
3543 OPENGL_TEX_MIPMAPS );
3590 Uint32 time = SDL_GetTicks();
3592 char **system_files;
3603 for (
int i = 0; i <
array_size( system_files ); i++ ) {
3611 sys.filename = system_files[i];
3640 if ( conf.devmode ) {
3641 DEBUG( n_(
"Loaded %d Star System",
"Loaded %d Star Systems",
3644 DEBUG( n_(
" with %d Space Object in %.3f s",
3645 " with %d Space Objects in %.3f s",
3649 DEBUG( n_(
"Loaded %d Star System",
"Loaded %d Star Systems",
3652 DEBUG( n_(
" with %d Space Object",
" with %d Space Objects",
3671 NTracingZone( _ctx, 1 );
3678 NTracingZoneEnd( _ctx );
3691 NTracingZone( _ctx, 1 );
3703 NTracingZoneEnd( _ctx );
3715 NTracingZone( _ctx, 1 );
3731 NTracingZoneEnd( _ctx );
3741 if ( !jp_isUsable( jp ) )
3744 if ( (
player.p != NULL ) && ( i ==
player.p->nav_hyperspace ) &&
3745 ( pilot_isFlag(
player.p, PILOT_HYPERSPACE ) ||
3748 else if ( jp_isFlag( jp, JP_HIDDEN ) )
3756 if ( jp->hide == 0. ) {
3758 jp->pos.y + 200 * jp->cosa, 0, 0, NULL );
3760 jp->pos.y + -200 * jp->cosa, 0, 0, NULL );
3769 if ( p->lua_render != LUA_NOREF ) {
3772 lua_rawgeti(
naevL, LUA_REGISTRYINDEX, p->lua_render );
3773 if ( nlua_pcall( p->lua_env, 0, 0 ) ) {
3774 WARN( _(
"Spob '%s' failed to run '%s':\n%s" ), p->name,
"render",
3775 lua_tostring(
naevL, -1 ) );
3776 lua_pop(
naevL, 1 );
3778 }
else if ( p->gfx_space3d ) {
3779 double s = p->gfx_space3d_size;
3785 if ( ( x < -sz ) || ( x > SCREEN_W + sz ) || ( y < -sz ) ||
3786 ( y > SCREEN_H + sz ) )
3789 glBindFramebuffer( GL_FRAMEBUFFER, p->gfx_fbo );
3790 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
3793 s * spob_aa_scale, NULL );
3795 glBindFramebuffer( GL_FRAMEBUFFER,
gl_screen.current_fbo );
3798 }
else if ( p->gfx_space )
3807 if ( p->lua_update == LUA_NOREF )
3811 lua_rawgeti(
naevL, LUA_REGISTRYINDEX, p->lua_update );
3812 lua_pushnumber(
naevL, dt );
3814 if ( nlua_pcall( p->lua_env, 2, 0 ) ) {
3815 WARN( _(
"Spob '%s' failed to run '%s':\n%s" ), p->name,
"update",
3816 lua_tostring(
naevL, -1 ) );
3817 lua_pop(
naevL, 1 );
3850 free( spb->
tags[j] );
3854 gltf_free( spb->gfx_space3d );
3855 free( spb->gfx_space3dName );
3856 free( spb->gfx_space3dPath );
3869 if ( spb->
tech != NULL )
3896 free( sys->filename );
3898 free( sys->display );
3899 free( sys->background );
3900 free( sys->map_shader );
3901 free( sys->features );
3909 for (
int j = 0; j <
array_size( sys->tags ); j++ )
3910 free( sys->tags[j] );
3914 for (
int j = 0; j <
array_size( sys->asteroids ); j++ )
3916 for (
int j = 0; j <
array_size( sys->astexclude ); j++ )
3936 glDeleteProgram( ms->
program );
3949 sys_rmFlag( sys, SYSTEM_KNOWN );
3950 sys_rmFlag( sys, SYSTEM_HIDDEN );
3951 sys_rmFlag( sys, SYSTEM_PMARKED );
3952 for (
int j = 0; j <
array_size( sys->jumps ); j++ )
3953 jp_rmFlag( &sys->jumps[j], JP_KNOWN );
3968 sys_rmFlag( sys, SYSTEM_MARKED );
3969 sys->markers_computer = 0;
3970 sys->markers_plot = 0;
3971 sys->markers_high = 0;
3972 sys->markers_low = 0;
3976 spob_rmFlag( pnt, SPOB_MARKED );
3990static int space_addMarkerSystem(
int sysid, MissionMarkerType type )
4002 case SYSMARKER_COMPUTER:
4003 markers = &ssys->markers_computer;
4006 markers = &ssys->markers_low;
4008 case SYSMARKER_HIGH:
4009 markers = &ssys->markers_high;
4011 case SYSMARKER_PLOT:
4012 markers = &ssys->markers_plot;
4015 WARN( _(
"Unknown marker type." ) );
4021 sys_setFlag( ssys, SYSTEM_MARKED );
4026static int space_addMarkerSpob(
int pntid, MissionMarkerType type )
4029 MissionMarkerType stype;
4036 spob_setFlag( pnt, SPOB_MARKED );
4040 if ( sys == NULL ) {
4041 WARN( _(
"Marking spob '%s' that is not in any system!" ), pnt->
name );
4044 stype = mission_markerTypeSpobToSystem( type );
4058 case SYSMARKER_COMPUTER:
4060 case SYSMARKER_HIGH:
4061 case SYSMARKER_PLOT:
4062 return space_addMarkerSystem( objid, type );
4063 case SPOBMARKER_COMPUTER:
4064 case SPOBMARKER_LOW:
4065 case SPOBMARKER_HIGH:
4066 case SPOBMARKER_PLOT:
4067 return space_addMarkerSpob( objid, type );
4069 WARN( _(
"Unknown marker type." ) );
4075static int space_rmMarkerSystem(
int sys, MissionMarkerType type )
4087 case SYSMARKER_COMPUTER:
4088 markers = &ssys->markers_computer;
4091 markers = &ssys->markers_low;
4093 case SYSMARKER_HIGH:
4094 markers = &ssys->markers_high;
4096 case SYSMARKER_PLOT:
4097 markers = &ssys->markers_plot;
4100 WARN( _(
"Unknown marker type." ) );
4106 if ( *markers <= 0 ) {
4107 sys_rmFlag( ssys, SYSTEM_MARKED );
4114static int space_rmMarkerSpob(
int pntid, MissionMarkerType type )
4118 MissionMarkerType stype;
4124 spob_rmFlag( pnt, SPOB_MARKED );
4130 stype = mission_markerTypeSpobToSystem( type );
4144 case SYSMARKER_COMPUTER:
4146 case SYSMARKER_HIGH:
4147 case SYSMARKER_PLOT:
4148 return space_rmMarkerSystem( objid, type );
4149 case SPOBMARKER_COMPUTER:
4150 case SPOBMARKER_LOW:
4151 case SPOBMARKER_HIGH:
4152 case SPOBMARKER_PLOT:
4153 return space_rmMarkerSpob( objid, type );
4155 WARN( _(
"Unknown marker type." ) );
4168 xmlw_startElem( writer,
"space" );
4172 xmlw_startElem( writer,
"known" );
4173 xmlw_attr( writer,
"sys",
"%s", sys->name );
4174 if ( sys_isKnown( sys ) )
4175 xmlw_attr( writer,
"known",
"1" );
4176 if ( sys_isFlag( sys, SYSTEM_PMARKED ) )
4177 xmlw_attr( writer,
"pmarked",
"1" );
4178 if ( sys->note != NULL )
4179 xmlw_attr( writer,
"note",
"%s", sys->note );
4182 for (
int j = 0; j <
array_size( sys->spobs ); j++ ) {
4183 if ( !spob_isKnown( sys->spobs[j] ) )
4185 xmlw_elem( writer,
"spob",
"%s", sys->spobs[j]->name );
4189 for (
int j = 0; j <
array_size( sys->jumps ); j++ ) {
4190 if ( !jp_isKnown( &sys->jumps[j] ) )
4192 xmlw_elem( writer,
"jump",
"%s", ( &sys->jumps[j] )->target->name );
4196 for (
int j = 0; j <
array_size( sys->presence ); j++ ) {
4201 xmlw_startElem( writer,
"faction" );
4203 xmlw_str( writer,
"%f", sp->
local );
4204 xmlw_endElem( writer );
4207 xmlw_endElem( writer );
4209 xmlw_endElem( writer );
4231 node = parent->xmlChildrenNode;
4235 xml_onlyNodes( node );
4236 if ( !xml_isNode( node,
"space" ) )
4239 cur = node->xmlChildrenNode;
4244 xml_onlyNodes( cur );
4245 if ( !xml_isNode( cur,
"known" ) )
4249 xmlr_attr_strd( cur,
"sys", str );
4251 if ( sys == NULL ) {
4252 WARN( _(
"Save trying to load information about system '%s', which "
4253 "is not found in the universe!" ),
4260 sys_setFlag( sys, SYSTEM_KNOWN );
4262 xmlr_attr_strd( cur,
"known", str );
4263 if ( str != NULL ) {
4264 sys_setFlag( sys, SYSTEM_KNOWN );
4269 xmlr_attr_strd( cur,
"pmarked", str );
4270 if ( str != NULL ) {
4271 sys_setFlag( sys, SYSTEM_PMARKED );
4275 xmlr_attr_strd( cur,
"note", str );
4276 if ( str != NULL ) {
4277 xmlr_attr_strd( cur,
"note", sys->note );
4282 }
while ( xml_nextNode( cur ) );
4283 }
while ( xml_nextNode( node ) );
4300 xmlNodePtr node = parent->xmlChildrenNode;
4302 if ( xml_isNode( node,
"spob" ) ) {
4306 }
else if ( xml_isNode( node,
"jump" ) ) {
4307 JumpPoint *jp =
jump_get( xml_get( node ), sys );
4309 jp_setFlag( jp, JP_KNOWN );
4310 }
else if ( xml_isNode( node,
"faction" ) ) {
4313 xmlr_attr_strd( node,
"name", buf );
4320 for (
int i = 0; i <
array_size( sys->presence ); i++ ) {
4324 sp->
local = xml_getFloat( node );
4328 }
while ( xml_nextNode( node ) );
4345 double base = ap->
base;
4346 double bonus = ap->
bonus;
4347 double range = ap->
range;
4352 if ( sys == NULL ) {
4353 WARN(
"sys == NULL" );
4362 if ( ( base == 0. ) && ( bonus == 0. ) )
4369 SystemPresence *sp = system_getFactionPresenceGrow( sys, faction );
4373 for (
int i = 0; i <
array_size( fgens ); i++ ) {
4374 SystemPresence *spf = system_getFactionPresenceGrow( sys, fgens[i].
id );
4376 spf->
bonus +=
MAX( 0., bonus * fgens[i].weight );
4391 for (
int i = 0; i <
array_size( sys->jumps ); i++ ) {
4392 if ( sys->jumps[i].target->spilled == 0 &&
4393 ( usehidden || !jp_isFlag( &sys->jumps[i], JP_HIDDEN ) ) &&
4394 !jp_isFlag( &sys->jumps[i], JP_EXITONLY ) ) {
4396 sys->jumps[i].target->spilled = 1;
4409 while ( curSpill < range ) {
4418 for (
int i = 0; i <
array_size( cur->jumps ); i++ ) {
4419 if ( cur->jumps[i].target->spilled == 0 &&
4420 ( usehidden || !jp_isFlag( &cur->jumps[i], JP_HIDDEN ) ) &&
4421 !jp_isFlag( &cur->jumps[i], JP_EXITONLY ) ) {
4423 cur->jumps[i].target->spilled = 1;
4428 sp = system_getFactionPresenceGrow( cur, faction );
4429 spillfactor = 1. / ( 2. + (double)curSpill );
4431 sp->
bonus += bonus * spillfactor;
4434 for (
int i = 0; i <
array_size( fgens ); i++ ) {
4436 system_getFactionPresenceGrow( cur, fgens[i].
id );
4438 MAX( spf->
base,
MAX( 0., base * spillfactor * fgens[i].weight ) );
4439 spf->
bonus +=
MAX( 0., bonus * spillfactor * fgens[i].weight );
4463static SystemPresence *system_getFactionPresenceGrow( StarSystem *sys,
4467 for (
int i = 0; i <
array_size( sys->presence ); i++ ) {
4468 if ( sys->presence[i].faction == faction )
4469 return &sys->presence[i];
4479SystemPresence *system_getFactionPresence( StarSystem *sys,
int faction )
4482 for (
int i = 0; i <
array_size( sys->presence ); i++ ) {
4483 if ( sys->presence[i].faction == faction )
4484 return &sys->presence[i];
4488const SystemPresence *system_getFactionPresenceConst(
const StarSystem *sys,
4492 for (
int i = 0; i <
array_size( sys->presence ); i++ ) {
4493 if ( sys->presence[i].faction == faction )
4494 return &sys->presence[i];
4505 double val = faction_reputationOverride( faction, &set );
4508 const SystemPresence *sp = system_getFactionPresenceConst( sys, faction );
4521 double val = faction_reputationOverride( faction, &set );
4524 const SystemPresence *sp = system_getFactionPresenceConst( sys, faction );
4541 if ( sys == NULL ) {
4542 WARN(
"sys == NULL" );
4548 for (
int i = 0; i <
array_size( sys->presence ); i++ ) {
4549 if ( sys->presence[i].faction == faction )
4550 return MAX( sys->presence[i].value, 0. );
4571 if ( sys == NULL ) {
4572 WARN(
"sys == NULL" );
4578 for (
int i = 0; i <
array_size( sys->presence ); i++ ) {
4579 if ( sys->presence[i].faction == faction ) {
4580 *base = sys->presence[i].base;
4581 *bonus = sys->presence[i].bonus;
4582 return MAX( sys->presence[i].value, 0 );
4601 if ( sys == NULL ) {
4602 WARN(
"sys == NULL" );
4608 for (
int i = 0; i <
array_size( sys->spobs ); i++ )
4612 for (
int i = 0; i <
array_size( sys->spobs_virtual ); i++ )
4613 for (
int j = 0; j <
array_size( sys->spobs_virtual[i]->presences ); j++ )
4627 for (
int j = 0; j <
array_size( sys->presence ); j++ ) {
4663 if ( sys == NULL ) {
4664 WARN(
"sys == NULL" );
4669 for (
int i = 0; i <
array_size( sys->spobs ); i++ )
4687 SystemPresence *presence = system_getFactionPresence( sys, faction );
4688 if ( presence == NULL )
4696 nlua_getenv(
naevL, env,
"decrease" );
4697 if ( lua_isnil(
naevL, -1 ) ) {
4698 lua_pop(
naevL, 1 );
4706 if ( nlua_pcall( env, 3, 1 ) ) {
4707 WARN( _(
"Lua decrease script for faction '%s' : %s" ),
4709 lua_pop(
naevL, 1 );
4714 if ( !lua_isnumber(
naevL, -1 ) ) {
4716 _(
"Lua spawn script for faction '%s' failed to return timer value." ),
4718 lua_pop(
naevL, 1 );
4722 lua_pop(
naevL, 1 );
4733 space_landQueueSpob = pnt;
4745 static char pop[STRMAX_SHORT];
4751 if ( nlua_pcall( spb->
lua_env, 0, 1 ) ) {
4752 WARN( _(
"Spob '%s' failed to run '%s':\n%s" ), spb->
name,
4753 "population", lua_tostring(
naevL, -1 ) );
4754 lua_pop(
naevL, 1 );
4758 scnprintf( pop,
sizeof( pop ),
"%s", luaL_checkstring(
naevL, -1 ) );
4759 lua_pop(
naevL, 1 );
4770 snprintf( pop,
sizeof( pop ),
"%.0f", p );
4772 char scratch[STRMAX_SHORT];
4773 const char *digits[] = {
"\xe2\x81\xb0",
"\xc2\xb9",
"\xc2\xb2",
4774 "\xc2\xb3",
"\xe2\x81\xb4",
"\xe2\x81\xb5",
4775 "\xe2\x81\xb6",
"\xe2\x81\xb7",
"\xe2\x81\xb8",
4777 int state = 0, COEF = 0, E = 1, EXP = 4;
4778 size_t l =
scnprintf( pop,
sizeof( pop ), _(
"roughly " ) );
4779 snprintf( scratch,
sizeof( scratch ),
"%.1e", p );
4780 for (
const char *
c = scratch; *
c;
c++ ) {
4781 if ( state == COEF && *
c !=
'e' )
4782 l +=
scnprintf( &pop[l],
sizeof( pop ) - l,
"%c", *
c );
4783 else if ( state == COEF ) {
4784 l +=
scnprintf( &pop[l],
sizeof( pop ) - l,
"%s",
4788 }
else if ( state == E && ( *
c ==
'+' || *
c ==
'0' ) )
4793 scnprintf( &pop[l],
sizeof( pop ) - l,
"%s", digits[*
c -
'0'] );
4816 if ( strcmp( t->
name, name ) == 0 )
4824 ms->
name = strdup( name );
4825 ms->
program = gl_program_vert_frag(
"system_map.vert", name );
4828 ms->
time = glGetUniformLocation( ms->
program,
"time" );
4830 ms->
alpha = glGetUniformLocation( ms->
program,
"alpha" );
4835static int spob_lua_cmp(
const void *a,
const void *b )
4842static nlua_env spob_lua_get(
int *mem,
const char *filename )
4860 if ( dat == NULL ) {
4861 WARN( _(
"Failed to read spob Lua '%s'!" ), filename );
4865 nlua_env env = nlua_newEnv( filename );
4876 lua_newtable(
naevL );
4877 lua_pushvalue(
naevL, -1 );
4879 nlua_setenv(
naevL, env,
"mem" );
4882 if ( nlua_dobufenv( env, dat, sz, filename ) != 0 ) {
4884 WARN( _(
"Lua Spob '%s' error:\n%s" ), filename,
4885 lua_tostring(
naevL, -1 ) );
4886 lua_pop(
naevL, 1 );
4887 spob_lua_free( lf );
4904 nlua_freeEnv( lf->
env );
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.
#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_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
void asteroids_render(void)
Renders the current systems' spobs.
void asteroids_computeInternals(AsteroidAnchor *a)
Updates internal alues of an asteroid field.
void asteroids_free(void)
Cleans up the system.
int asteroids_load(void)
Loads the asteroids.
void asteroid_freeAnchor(AsteroidAnchor *ast)
Frees an asteroid anchor.
AsteroidTypeGroup * astgroup_getName(const char *name)
Gets an asteroid type group by name.
void asteroids_init(void)
Initializes the system.
void asteroids_renderOverlay(void)
Renders the system overlay.
void asteroid_initAnchor(AsteroidAnchor *ast)
Initializes an asteroid anchor.
void asteroid_freeExclude(AsteroidExclusion *exc)
Frees an asteroid exclusion.
void asteroids_update(double dt)
Controls fleet spawning.
void background_clear(void)
Cleans up the background stuff.
void background_initDust(int n)
Initializes background dust.
void background_renderOverlay(double dt)
Renders the background overlay.
void background_render(double dt)
Render the background.
int background_load(const char *name)
Loads a background script by name.
double cam_getZoom(void)
Gets the camera zoom.
double CollideCircleIntersection(const vec2 *p1, double r1, const vec2 *p2, double r2)
Calculates the area of intersection between two circles.
Commodity * commodity_get(const char *name)
Gets a commodity by name.
Commodity ** standard_commodities(void)
Return an array (array.h) of standard commodities. Free with array_free. (Don't free contents....
int dtype_get(const char *name)
Gets the id of a dtype based on name.
StarSystem * systems_stack
void economy_addQueuedUpdate(void)
Increments the queued update counter.
credits_t economy_getPriceAtTime(const Commodity *com, const StarSystem *sys, const Spob *p, ntime_t tme)
Gets the price of a good on a spob in a system.
void economy_initialiseCommodityPrices(void)
Initialises commodity prices for the sinusoidal economy model.
void economy_clearSingleSpob(Spob *p)
Clears all economy knowledge of a given spob. Used by the unidiff system.
credits_t economy_getPrice(const Commodity *com, const StarSystem *sys, const Spob *p)
Gets the price of a good on a spob in a system.
int economy_getAverageSpobPrice(const Commodity *com, const Spob *p, credits_t *mean, double *std)
Gets the average price of a good on a spob in a system, using a rolling average over the times the pl...
int faction_isFaction(int f)
Checks whether or not a faction is valid.
void faction_updateGlobal(void)
Computes the global faction standing for each of the factions.
int areEnemies(int a, int b)
Checks whether two factions are enemies.
void factions_clearDynamic(void)
Clears dynamic factions.
const char * faction_name(int f)
Gets a factions "real" (internal) name.
int faction_isDynamic(int id)
Is faction dynamic.
void factions_resetLocal(void)
Reset local standing.
const FactionGenerator * faction_generators(int f)
Gets the faction's generators.
int faction_usesHiddenJumps(int f)
Checks to see if a faction uses hidden jumps.
nlua_env faction_getScheduler(int f)
Gets the state associated to the faction scheduler.
double faction_reputation(int f)
Gets the player's standing with a faction.
int faction_isStatic(int id)
Is the faction static?
int faction_get(const char *name)
Gets a faction ID by name.
int areAllies(int a, int b)
Checks whether two factions are allies or not.
void gatherable_free(void)
Frees all the gatherables.
void gatherable_update(double dt)
Updates all gatherable objects.
void gatherable_render(void)
Renders all the gatherables.
void gui_setSystem(void)
Player just changed their system.
void gui_updateFaction(void)
Player's relationship with a faction was modified.
void player_message(const char *fmt,...)
Adds a mesg to the queue to be displayed on screen.
void player_messageToggle(int enable)
Toggles if player should receive messages.
int hooks_runParam(const char *stack, const HookParam *param)
Runs all the hooks of stack.
void land(Spob *p, int load)
Opens up all the land dialogue stuff.
int music_choose(const char *situation)
Actually runs the music stuff, based on situation.
void naev_renderLoadscreen(void)
Renders the loadscreen if necessary.
void update_routine(double dt, int dohooks)
Actually runs the updates.
int naev_versionCompareTarget(const char *version, const char *target)
Does a comparison with a specific target.
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.
void nebu_update(double dt)
Updates visibility and stuff.
void nebu_renderOverlay(const double dt)
Renders the nebula overlay (hides what player can't see).
void nebu_render(const double dt)
Renders the nebula.
void nebu_prep(double density, double volatility, double hue)
Prepares the nebualae to be rendered.
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.
LuaPilot lua_topilot(lua_State *L, int ind)
Lua bindings to interact with pilots.
LuaPilot * lua_pushpilot(lua_State *L, LuaPilot pilot)
Pushes a pilot on the stack.
int lua_ispilot(lua_State *L, int ind)
Checks to see if ind is a pilot.
LuaSpob * lua_pushspob(lua_State *L, LuaSpob spob)
Pushes a spob on the stack.
glTexture * lua_totex(lua_State *L, int ind)
Lua bindings to interact with OpenGL textures.
int lua_istex(lua_State *L, int ind)
Checks to see if ind is a texture.
void arrayShuffle(void **array)
Randomly sorts an array (array.h) of pointers in place with the Fisher-Yates shuffle.
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
char * ntime_pretty(ntime_t t, int d)
Gets the time in a pretty human readable format.
void ntime_allowUpdate(int enable)
Allows the time to update when the game is updating.
xmlDocPtr xml_parsePhysFS(const char *filename)
Analogous to xmlParseMemory/xmlParseFile.
void gl_gameToScreenCoords(double *nx, double *ny, double bx, double by)
Converts in-game coordinates to screen coordinates.
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.
glTexture * gl_dupTexture(const glTexture *texture)
Duplicates a texture.
glTexture * gl_newSprite(const char *path, const int sx, const int sy, const unsigned int flags)
Loads the texture immediately, but also sets it as a sprite.
USE_RESULT glTexture * gl_rawTexture(const char *name, GLuint texid, double w, double h)
Creates a texture from a raw opengl index.
int gl_fboCreate(GLuint *fbo, GLuint *tex, GLsizei width, GLsizei height)
Creates a framebuffer and its associated texture.
glTexture * gl_newImage(const char *path, const unsigned int flags)
Loads an image as a texture.
int gl_fboAddDepth(GLuint fbo, GLuint *tex, GLsizei width, GLsizei height)
Adds a depth attachment to an FBO.
void gl_getSpriteFromDir(int *x, int *y, int sx, int sy, double dir)
Sets x and y to be the appropriate sprite for glTexture using dir.
void gl_freeTexture(glTexture *texture)
Frees a texture.
void pilots_clean(int persist)
Cleans up the pilot stack - leaves the player.
void pilot_clearTimers(Pilot *pilot)
Clears the pilot's timers.
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
static Pilot ** pilot_stack
Pilot *const * pilot_getAll(void)
Gets the pilot stack.
void pilots_newSystem(void)
Updates pilot state which depends on the system (sensor range, nebula trails...)
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.
int pilot_inRangeSpob(const Pilot *p, int target)
Check to see if a spob is in sensor range of the pilot.
int pilot_inRangeJump(const Pilot *p, int i)
Check to see if a jump point is in sensor range of the pilot.
int pilot_inRangeAsteroid(const Pilot *p, int ast, int fie)
Check to see if an asteroid is in sensor range of the pilot.
void pilot_calcStats(Pilot *pilot)
Recalculates the pilot's stats based on his outfits.
void pilot_lockClear(Pilot *p)
Clears pilot's missile lockon timers.
int pilot_outfitOffAll(Pilot *p)
Disables all active outfits for a pilot.
void player_checkLandAck(void)
Revokes landing authorization if the player's reputation is too low.
void player_clear(void)
Clears the targets.
void * q_dequeue(Queue q)
Dequeues an item.
int q_isEmpty(Queue q)
Checks if the queue is empty.
void q_destroy(Queue q)
Destroys a queue.
Queue q_create(void)
Creates a queue.
void q_enqueue(Queue q, void *data)
Enqueues an item.
void safelanes_recalculate(void)
Update the safe lane locations in response to the universe changing (e.g., diff applied).
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.
int ss_sort(ShipStatList **ll)
Sorts the ship stats, useful if doing saving stuff.
int sound_env(SoundEnv_t env_type, double param)
Sets up the sound environment.
static int spob_cmp(const void *p1, const void *p2)
Comparison function for qsort'ing Spob by name.
void space_reconstructPresences(void)
Reset the presence of all systems.
void space_init(const char *sysname, int do_simulate)
Initializes the system.
double system_getClosestAng(const StarSystem *sys, int *pnt, int *jp, int *ast, int *fie, double x, double y, double ang)
Gets the feature nearest to directly ahead of a position in the system.
void spob_distress(Spob *spb, const Pilot *p, const Pilot *attacker)
Spob is receiving distress from a pilot about an attacker.
static int spobs_load(void)
Loads all the spobs in the game.
void spob_averageSeenPricesAtTime(const Spob *p, const ntime_t tupdate)
Adds cost of commodities on spob p to known statistics at time t.
static int system_cmp(const void *p1, const void *p2)
Comparison function for qsort'ing StarSystem by name.
double system_getClosest(const StarSystem *sys, int *pnt, int *jp, int *ast, int *fie, double x, double y)
Gets the closest feature to a position in the system.
int spob_exists(const char *spobname)
Check to see if a spob exists.
void system_rmCurrentPresence(StarSystem *sys, int faction, double amount)
Removes active presence.
void space_gfxUnload(StarSystem *sys)
Unloads all the graphics for a star system.
int space_canHyperspace(const Pilot *p)
Checks to make sure if pilot is far enough away to hyperspace.
void space_render(const double dt)
Renders the system.
static void space_renderSpob(const Spob *p)
Renders a spob.
static int sys_cmpSysFaction(const void *a, const void *b)
Compares two system presences.
int spob_luaInit(Spob *spob)
Updatse the spob's internal Lua stuff.
static void system_init(StarSystem *sys)
Initializes a new star system with null memory.
void systems_reconstructJumps(void)
Reconstructs the jumps.
int space_jumpDistance(const Pilot *p, const JumpPoint *jp)
Distance at which a pilot can jump.
const glColour * spob_getColour(const Spob *p)
Gets the spob colour.
int space_rmMarker(int objid, MissionMarkerType type)
Removes a marker from a system.
static int space_parseSaveNodes(xmlNodePtr parent, StarSystem *sys)
Parses spobs in a system.
int system_addJump(StarSystem *sys, StarSystem *target)
Adds a jump point between two star systems.
int spob_averageSpobPrice(const Spob *p, const Commodity *c, credits_t *mean, double *std)
Gets the average price of a commodity at a spob that has been seen so far.
static char ** systemname_stack
double system_getPresenceFull(const StarSystem *sys, int faction, double *base, double *bonus)
Get the presence of a faction in a system.
double system_getReputation(const StarSystem *sys, int faction)
Gets the local reputation of the player in a system or returns 0.
static int spob_parse(Spob *spob, const char *filename, Commodity **stdList)
Parses a spob from an xml node.
Spob * spob_getAll(void)
Gets an array (array.h) of all spobs.
int spob_rename(Spob *p, char *newname)
Renames a spob.
int spob_getService(const char *name)
Converts name to spob service flag.
void system_setFaction(StarSystem *sys)
Sets the system faction based on the spobs it has.
Spob * spob_get(const char *spobname)
Gets a spob based on its name.
void space_factionChange(void)
Mark when a faction changes.
static char ** spobname_stack
int system_addVirtualSpob(StarSystem *sys, const char *spobname)
Adds a virtual spob to a system.
const char * space_getRndSpob(int landable, unsigned int services, int(*filter)(Spob *p))
Gets the name of a random spob.
static spob_lua_file * spob_lua_stack
void space_update(double dt, double real_dt)
Controls fleet spawning.
static int systems_load(void)
Loads the entire systems, needs to be called after spobs_load.
StarSystem * system_getIndex(int id)
Get the system by its index.
static void spob_initDefaults(Spob *spob)
Initializes a new spob to safe defaults.
int spob_index(const Spob *p)
Gets the ID of a spob.
double system_getReputationOrGlobal(const StarSystem *sys, int faction)
Gets the local reputation of the player in a system or returns the global standing.
int spob_hasSystem(const Spob *spb)
Get whether or not a spob has a system (i.e. is on the map).
static int space_simulating
#define FLAG_INTERFERENCESET
static VirtualSpob * vspob_stack
const char * jump_getSymbol(const JumpPoint *jp)
Gets the jump point symbol.
static int systemstack_changed
const char * spob_getSymbol(const Spob *p)
Gets the spob symbol.
void space_renderOverlay(const double dt)
Renders the system overlay.
int spob_setFaction(Spob *p, int faction)
Changes the spobs faction.
char spob_getColourChar(const Spob *p)
Gets the spob colour char.
StarSystem * system_new(void)
Creates a new star system.
static glTexture * jumpbuoy_gfx
int space_sysReachable(const StarSystem *sys)
Sees if a system is reachable.
JumpPoint * jump_getTarget(const StarSystem *target, const StarSystem *sys)
Less safe version of jump_get that works with pointers.
const char * system_existsCase(const char *sysname)
Checks to see if a system exists case insensitively.
StarSystem * system_getAll(void)
Gets an array (array.h) of all star systems.
char ** spob_searchFuzzyCase(const char *spobname, int *n)
Does a fuzzy case matching. Searches spob_name() but returns internal names.
int space_sysReachableFromSys(const StarSystem *target, const StarSystem *sys)
Sees if a system is reachable from another system.
char ** system_searchFuzzyCase(const char *sysname, int *n)
Does a fuzzy case matching. Searches translated names but returns internal names.
int space_playerLoad(xmlNodePtr parent, const char *version)
Loads player's space properties from an XML node.
StarSystem * system_get(const char *sysname)
Get the system from its name.
int space_calcJumpInPos(const StarSystem *in, const StarSystem *out, vec2 *pos, vec2 *vel, double *dir, const Pilot *p)
Calculates the jump in pos for a pilot.
int spob_rmService(Spob *p, int service)
Removes a service from a spob.
static MapShader ** mapshaders
void system_updateAsteroids(StarSystem *sys)
Updates some internal calculations about asteroids in a system.
void spob_setKnown(Spob *p)
Sets a spob's known status, if it's real.
static void system_scheduler(double dt, int init)
Controls fleet spawning.
void spobs_render(void)
Renders the current systems' spobs.
const char * spob_existsCase(const char *spobname)
Check to see if a spob exists (case insensitive).
int system_addSpob(StarSystem *sys, const char *spobname)
Adds a spob to a star system.
void space_exit(void)
Cleans up the system.
int space_addMarker(int objid, MissionMarkerType type)
Adds a marker to a system.
static int spob_parsePresence(xmlNodePtr node, SpobPresence *ap)
Parsess an spob presence from xml.
double system_getPresence(const StarSystem *sys, int faction)
Get the presence of a faction in a system.
void spob_updateLand(Spob *p)
Updates the land possibilities of a spob.
int space_sysReallyReachable(const char *sysname)
Sees if a system can be reached via jumping.
static int space_simulating_effects
static void space_renderJumpPoint(const JumpPoint *jp, int i)
Renders a jump point.
void spob_gfxLoad(Spob *spob)
Loads a spob's graphics (and radius).
int system_rmVirtualSpob(StarSystem *sys, const char *spobname)
Removes a virtual spob from a system.
void space_clearMarkers(void)
Clears all system markers.
int space_playerSave(xmlTextWriterPtr writer)
Saves what is needed to be saved for space.
static int virtualspobs_load(void)
Loads all the virtual spobs.
VirtualSpob * virtualspob_getAll(void)
Gets all the virtual spobs.
Spob * spob_getIndex(int ind)
Gets spob by index.
void system_presenceAddSpob(StarSystem *sys, const SpobPresence *ap)
Adds (or removes) some presence to a system.
VirtualSpob * virtualspob_get(const char *name)
Gets a virtual spob by matching name.
void space_clearKnown(void)
Clears all system knowledge.
void system_addAllSpobsPresence(StarSystem *sys)
Go through all the spobs and call system_addPresence().
int spob_addCommodity(Spob *p, Commodity *c)
Adds a commodity to a spob.
static int system_parseJumps(StarSystem *sys)
Loads the jumps into a system.
const char * spob_getSystemName(const char *spobname)
Get the name of a system from a spobname.
static const MapShader * mapshader_get(const char *name)
Gets the map shader by name.
int system_hasSpob(const StarSystem *sys)
See if the system has a spob.
int spob_addService(Spob *p, int service)
Removes a service from a spob.
static int systems_loading
const char * spob_name(const Spob *p)
Gets the translated name of a spob.
static int spobstack_changed
static int virtualspob_cmp(const void *p1, const void *p2)
Comparison function for qsort'ing VirtuaSpob by name.
const char * spob_getClassName(const char *class)
Gets the long class name for a spob.
static int system_parseAsteroidExclusion(const xmlNodePtr node, StarSystem *sys)
Parses a single asteroid exclusion zone for a system.
const char * space_populationStr(const Spob *spb)
Gets the population in an approximated string. Note this function changes the string value each call,...
void space_clearComputerMarkers(void)
Clears all the system computer markers.
void space_queueLand(Spob *pnt)
Cues a spob to be landed on. This is not done immediately, but when the engine thinks it is ok to do.
static void space_updateSpob(const Spob *p, double dt, double real_dt)
Renders a spob.
int system_rmJump(StarSystem *sys, StarSystem *target)
Removes a jump point from a star system.
static int system_parseAsteroidField(const xmlNodePtr node, StarSystem *sys)
Parses a single asteroid field for a system.
credits_t spob_commodityPrice(const Spob *p, const Commodity *c)
Gets the price of a commodity at a spob.
const char * spob_getServiceName(int service)
Gets the (English) name for a service code.
void systems_reconstructSpobs(void)
Updates the system spob pointers.
Spob * spob_new(void)
Creates a new spob.
StarSystem * spob_getSystem(const Spob *spob)
Gets the system a spob is in.
int space_needsEffects(void)
returns whether or not we're simulating with effects.
char ** space_getFactionSpob(const int *factions, int landable)
Gets the name of all the spobs that belong to factions.
void spob_luaInitMem(const Spob *spob)
Initializes the memory fo a spob.
JumpPoint * jump_get(const char *jumpname, const StarSystem *sys)
Gets a jump point based on its target and system.
void space_checkLand(void)
Handles landing if necessary.
glTexture * jumppoint_gfx
void space_gfxLoad(StarSystem *sys)
Loads all the graphics for a star system.
int space_hyperspace(Pilot *p)
Tries to get the pilot into hyperspace.
int space_load(void)
Loads the entire universe into ram - pretty big feat eh?
int space_isSimulation(void)
returns whether we're just simulating.
credits_t spob_commodityPriceAtTime(const Spob *p, const Commodity *c, ntime_t t)
Gets the price of a commodity at a spob at given time.
int system_index(const StarSystem *sys)
Gets the index of a star system.
int system_rmSpob(StarSystem *sys, const char *spobname)
Removes a spob from a star system.
int space_loadLua(void)
initializes the Lua for all the spobs.
static int system_parseJumpPoint(const xmlNodePtr node, StarSystem *sys)
Parses a single jump point for a system.
static int system_parse(StarSystem *system, const char *filename)
Creates a system from an XML node.
void system_reconstructJumps(StarSystem *sys)
Reconstructs the jumps for a single system.
void spfx_clear(void)
Clears all the currently running effects.
const char * start_spob_lua_default(void)
Gets the default spob Lua file.
Represents an asteroid field anchor.
Represents an asteroid exclusion zone.
Represents a single asteroid.
Core damage that an outfit does.
The actual hook parameter.
union HookParam::@114305201244257020071001257133270030317263020235 u
The representation of an in-game pilot.
Represents relative ship statistics as a linked list.
struct ShipStatList_ * next
Represents the presence of a spob.
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
const SimpleShader * marker
CommodityPrice * commodityPrice
Represents presence in a system.
Basically modifies system parameters without creating any real objects.
Abstraction for rendering sprite sheets.
tech_group_t * tech_groupCreateXML(xmlNodePtr node)
Creates a tech group from an XML node.
void tech_groupDestroy(tech_group_t *grp)
Frees a tech group.
void weapon_clear(void)
Clears all the weapons, does NOT free the layers.
void weapon_newSystem(void)
Sets up collision stuff for a new system.