20#include "background.h"
22#include "damagetype.h"
23#include "dev_uniedit.h"
25#include "gatherable.h"
31#include "map_overlay.h"
39#include "nlua_pilot.h"
42#include "nlua_camera.h"
61#define XML_SPOB_TAG "spob"
62#define XML_SYSTEM_TAG "ssys"
64#define SPOB_GFX_EXTERIOR_PATH_W 400
65#define SPOB_GFX_EXTERIOR_PATH_H 400
68#define FLAG_POSSET (1<<0)
69#define FLAG_INTERFERENCESET (1<<1)
70#define FLAG_SERVICESSET (1<<2)
71#define FLAG_FACTIONSET (1<<3)
73#define DEBRIS_BUFFER 1000
75typedef struct spob_lua_file_s {
96static int systemstack_changed = 0;
97static int spobstack_changed = 0;
111static Spob *space_landQueueSpob = NULL;
128static int system_parse( StarSystem *system,
const char *filename );
138static int space_addMarkerSystem(
int sysid, MissionMarkerType type );
139static int space_addMarkerSpob(
int pntid, MissionMarkerType type );
140static int space_rmMarkerSystem(
int sysid, MissionMarkerType type );
141static int space_rmMarkerSpob(
int pntid, MissionMarkerType type );
149static int spob_lua_cmp(
const void *a,
const void *b );
150static nlua_env spob_lua_get(
int *mem,
const char *filename );
168 case SPOB_SERVICE_LAND:
return N_(
"Land");
169 case SPOB_SERVICE_INHABITED:
return N_(
"Inhabited");
170 case SPOB_SERVICE_REFUEL:
return N_(
"Refuel");
171 case SPOB_SERVICE_BAR:
return N_(
"Bar");
172 case SPOB_SERVICE_MISSIONS:
return N_(
"Missions");
173 case SPOB_SERVICE_COMMODITY:
return N_(
"Commodity");
174 case SPOB_SERVICE_OUTFITS:
return N_(
"Outfits");
175 case SPOB_SERVICE_SHIPYARD:
return N_(
"Shipyard");
176 case SPOB_SERVICE_BLACKMARKET:
return N_(
"Blackmarket");
186 if (strcasecmp(name,
"Land")==0)
187 return SPOB_SERVICE_LAND;
188 else if (strcasecmp(name,
"Inhabited")==0)
189 return SPOB_SERVICE_INHABITED;
190 else if (strcasecmp(name,
"Refuel")==0)
191 return SPOB_SERVICE_REFUEL;
192 else if (strcasecmp(name,
"Bar")==0)
193 return SPOB_SERVICE_BAR;
194 else if (strcasecmp(name,
"Missions")==0)
195 return SPOB_SERVICE_MISSIONS;
196 else if (strcasecmp(name,
"Commodity")==0)
197 return SPOB_SERVICE_COMMODITY;
198 else if (strcasecmp(name,
"Outfits")==0)
199 return SPOB_SERVICE_OUTFITS;
200 else if (strcasecmp(name,
"Shipyard")==0)
201 return SPOB_SERVICE_SHIPYARD;
202 else if (strcasecmp(name,
"Blackmarket")==0)
203 return SPOB_SERVICE_BLACKMARKET;
215 if (strcmp(
class,
"0")==0)
216 return _(
"Civilian Station");
217 else if (strcmp(
class,
"1")==0)
218 return _(
"Military Station");
219 else if (strcmp(
class,
"2")==0)
220 return _(
"Pirate Station");
221 else if (strcmp(
class,
"3")==0)
222 return _(
"Robotic Station");
223 else if (strcmp(
class,
"A")==0)
224 return _(
"Geothermal");
225 else if (strcmp(
class,
"B")==0)
226 return _(
"Geomorteus");
227 else if (strcmp(
class,
"C")==0)
228 return _(
"Geoinactive");
229 else if (strcmp(
class,
"D")==0)
230 return _(
"Asteroid/Moon");
231 else if (strcmp(
class,
"E")==0)
232 return _(
"Geoplastic");
233 else if (strcmp(
class,
"F")==0)
234 return _(
"Geometallic");
235 else if (strcmp(
class,
"G")==0)
236 return _(
"Geocrystaline");
237 else if (strcmp(
class,
"H")==0)
239 else if (strcmp(
class,
"I")==0)
240 return _(
"Gas Supergiant");
241 else if (strcmp(
class,
"J")==0)
242 return _(
"Gas Giant");
243 else if (strcmp(
class,
"K")==0)
244 return _(
"Adaptable");
245 else if (strcmp(
class,
"L")==0)
246 return _(
"Marginal");
247 else if (strcmp(
class,
"M")==0)
248 return _(
"Terrestrial");
249 else if (strcmp(
class,
"N")==0)
250 return _(
"Reducing");
251 else if (strcmp(
class,
"O")==0)
253 else if (strcmp(
class,
"P")==0)
254 return _(
"Glaciated");
255 else if (strcmp(
class,
"Q")==0)
256 return _(
"Variable");
257 else if (strcmp(
class,
"R")==0)
259 else if (strcmp(
class,
"S")==0 || strcmp(
class,
"T")==0)
260 return _(
"Ultragiants");
261 else if (strcmp(
class,
"X")==0 || strcmp(
class,
"Y")==0 || strcmp(
class,
"Z")==0)
301 economy_averageSeenPricesAtTime( p, tupdate );
325 for (
int i=0; i<
array_size(sys->asteroids); i++) {
327 density += ast->
area * ast->
density / ASTEROID_REF_AREA;
330 for (
int j=0; j<
array_size(sys->astexclude); j++) {
332 density -= CollideCircleIntersection( &ast->
pos, ast->
radius, &exc->
pos, exc->
radius ) * ast->
density / ASTEROID_REF_AREA;
335 sys->asteroid_density = density;
347 p->presence.faction = faction;
374 p->services |= service;
376 if (service & SPOB_SERVICE_COMMODITY) {
381 if (p->commodities!=NULL)
383 Commodity **stdList = standard_commodities();
397 DEBUG(_(
"Spob '%s' not in system. Not initializing economy."), p->name);
401 economy_initialiseSingleSystem( sys, p );
416 p->services &= ~service;
425 double r = jp->radius * p->stats.jump_distance;
426 if (pilot_isFlag( p, PILOT_STEALTH ))
443 if (pilot_isFlag(p, PILOT_NOJUMP))
447 if (p->fuel < p->fuel_consumption)
459 d = vec2_dist2( &p->solid->pos, &jp->pos );
473 if (pilot_isFlag(p, PILOT_NOJUMP))
475 if (p->fuel < p->fuel_consumption)
481 pilot_setFlag(p, PILOT_HYP_PREP);
504 if (in->jumps[i].target == out)
509 WARN(_(
"Unable to find jump in point for '%s' in '%s': not connected"), out->name, in->name);
518 a = 2.*M_PI - jp->angle;
519 d = RNGF()*(HYPERSPACE_ENTER_MAX-HYPERSPACE_ENTER_MIN) + HYPERSPACE_ENTER_MIN;
520 if ((p!=NULL) && pilot_isFlag(p, PILOT_STEALTH))
531 ed *= p->stats.jump_distance;
532 if (pilot_isFlag(p, PILOT_STEALTH))
539 vec2_cset( pos, x, y );
543 vec2_cset( vel, HYPERSPACE_VEL*cos(a), HYPERSPACE_VEL*sin(a) );
602 int (*filter)(
Spob *p))
611 if (services && spob_hasService(pnt, services) != services)
614 if (filter != NULL && !filter(pnt))
655double system_getClosest(
const StarSystem *sys,
int *pnt,
int *jp,
int *ast,
int *fie,
double x,
double y )
666 for (
int i=0; i<
array_size(sys->spobs); i++) {
668 Spob *p = sys->spobs[i];
669 if (!spob_isKnown(p))
671 td =
pow2(x-p->pos.x) +
pow2(y-p->pos.y);
679 for (
int i=0; i<
array_size(sys->asteroids); i++) {
681 for (
int k=0; k<f->nb; k++) {
686 if (as->
state != ASTEROID_FG)
704 for (
int i=0; i<
array_size(sys->jumps); i++) {
706 JumpPoint *j = &sys->jumps[i];
709 td =
pow2(x-j->pos.x) +
pow2(y-j->pos.y);
734double system_getClosestAng(
const StarSystem *sys,
int *pnt,
int *jp,
int *ast,
int *fie,
double x,
double y,
double ang )
744 for (
int i=0; i<
array_size(sys->spobs); i++) {
745 Spob *p = sys->spobs[i];
746 double ta = atan2( y - p->pos.y, x - p->pos.x);
747 if (
ABS(angle_diff(ang, ta)) <
ABS(angle_diff(ang, a))) {
754 for (
int i=0; i<
array_size(sys->asteroids); i++) {
756 for (
int k=0; k<f->nb; k++) {
761 if (as->
state != ASTEROID_FG)
764 ta = atan2( y - as->
pos.
y, x - as->
pos.
x);
765 if (
ABS(angle_diff(ang, ta)) <
ABS(angle_diff(ang, a))) {
775 for (
int i=0; i<
array_size(sys->jumps); i++) {
776 JumpPoint *j = &sys->jumps[i];
777 double ta = atan2( y - j->pos.y, x - j->pos.x);
778 if (
ABS(angle_diff(ang, ta)) <
ABS(angle_diff(ang, a))) {
796 if (sys_isKnown(sys))
800 for (
int i=0; i<
array_size(sys->jumps); i++) {
801 JumpPoint *jp = sys->jumps[i].returnJump;
802 if (jp && jp_isUsable( jp ))
820 path = map_getJumpPath(
cur_system->name, sysname, 1, 1, NULL );
839 else if (jp_isUsable( jp ))
881 if (
strcasestr( _(sys->name), sysname ) != NULL) {
882 names[len] = sys->name;
902 const StarSystem *s1, *s2;
903 s1 = (
const StarSystem*) p1;
904 s2 = (
const StarSystem*) p2;
905 return strcmp(s1->name,s2->name);
920 if (systemstack_changed) {
924 WARN(_(
"System '%s' not found in stack"), sysname);
929 const StarSystem s = {.name = (
char*)sysname};
934 WARN(_(
"System '%s' not found in stack"), sysname);
985 LOG(_(
"Spob '%s' is not placed in a system"), spobname);
992static int spob_cmp(
const void *p1,
const void *p2 )
994 const Spob *pnt1, *pnt2;
995 pnt1 = (
const Spob*) p1;
996 pnt2 = (
const Spob*) p2;
997 return strcmp(pnt1->
name,pnt2->
name);
1008 if (spobname==NULL) {
1009 WARN(_(
"Trying to find NULL spob…"));
1014 if (spobstack_changed) {
1018 WARN(_(
"Spob '%s' not found in the universe"), spobname);
1023 const Spob p = {.name = (
char*)spobname};
1028 WARN(_(
"Spob '%s' not found in the universe"), spobname);
1073 spob_setFlag(p, SPOB_KNOWN);
1099 if (strcasecmp(
spob_stack[i].name,spobname)==0)
1120 names[len] = spob->
name;
1151 return strcmp(v1->name,v2->name);
1163 WARN(_(
"Virtual Spob '%s' not found in the universe"), name);
1174JumpPoint*
jump_get(
const char* jumpname,
const StarSystem* sys )
1176 if (jumpname==NULL) {
1177 WARN(_(
"Trying to find NULL jump point..."));
1181 for (
int i=0; i<
array_size(sys->jumps); i++) {
1182 JumpPoint *jp = &sys->jumps[i];
1183 if (strcmp(jp->target->name,jumpname)==0)
1187 WARN(_(
"Jump point '%s' not found in %s"), jumpname, sys->name);
1200 for (
int i=0; i<
array_size(sys->jumps); i++) {
1201 JumpPoint *jp = &sys->jumps[i];
1202 if (jp->target == target)
1205 WARN(_(
"Jump point to '%s' not found in %s"), target->name, sys->name);
1214 if (jp_isFlag(jp, JP_HIDDEN))
1247 nlua_getenv( naevL, env,
"create" );
1248 if (lua_isnil(naevL,-1)) {
1249 WARN(_(
"Lua Spawn script for faction '%s' missing obligatory entry point 'create'."),
1262 nlua_getenv( naevL, env,
"spawn" );
1263 if (lua_isnil(naevL,-1)) {
1264 WARN(_(
"Lua Spawn script for faction '%s' missing obligatory entry point 'spawn'."),
1269 lua_pushnumber( naevL, p->curUsed );
1272 lua_pushnumber( naevL, p->value );
1275 if (nlua_pcall(env, n+1, 2)) {
1276 WARN(_(
"Lua Spawn script for faction '%s' : %s"),
1283 if (!lua_isnumber(naevL,-2)) {
1284 WARN(_(
"Lua spawn script for faction '%s' failed to return timer value."),
1289 p->timer += lua_tonumber(naevL,-2);
1291 if (lua_istable(naevL,-1)) {
1293 while (lua_next(naevL,-2) != 0) {
1297 if (!lua_istable(naevL,-1)) {
1298 WARN(_(
"Lua spawn script for faction '%s' returns invalid data (not a table)."),
1304 lua_getfield( naevL, -1,
"pilot" );
1306 WARN(_(
"Lua spawn script for faction '%s' returns invalid data (not a pilot)."),
1312 if (pilot == NULL) {
1317 lua_getfield( naevL, -1,
"presence" );
1318 if (!lua_isnumber(naevL,-1)) {
1319 WARN(_(
"Lua spawn script for faction '%s' returns invalid data (not a number)."),
1324 pilot->
presence = lua_tonumber(naevL,-1);
1325 if (pilot->
faction != p->faction) {
1327 WARN( _(
"Lua spawn script for faction '%s' actually spawned a '%s' pilot."),
1354 if (space_landQueueSpob != NULL) {
1355 land( space_landQueueSpob, 0 );
1356 space_landQueueSpob = NULL;
1408 int found_something = 0;
1429 hparam[0].
type = HOOK_PARAM_STRING;
1430 hparam[0].
u.
str =
"spob";
1431 hparam[1].
type = HOOK_PARAM_SPOB;
1432 hparam[1].
u.
la = pnt->
id;
1433 hparam[2].
type = HOOK_PARAM_SENTINEL;
1435 found_something = 1;
1450 if (jp_isFlag(jp,JP_EXITONLY))
1455 jp_setFlag( jp, JP_KNOWN );
1457 hparam[0].
type = HOOK_PARAM_STRING;
1458 hparam[0].
u.
str =
"jump";
1459 hparam[1].
type = HOOK_PARAM_JUMP;
1462 hparam[2].
type = HOOK_PARAM_SENTINEL;
1464 found_something = 1;
1468 if (found_something)
1504 const double fps_min_simulation =
fps_min * 2.;
1529 ERR(_(
"Cannot reinit system if there is no system previously loaded"));
1530 else if (sysname!=NULL) {
1533 WARN(_(
"System '%s' not found, trying random system!"),sysname);
1538 player_message(_(
"#oEntering System %s on %s."), _(sysname), nt);
1540 player_message(_(
"#rWARNING - Volatile nebula detected in %s! Taking %.1f MW damage!"), _(sysname),
cur_system->nebu_volatility);
1561 if ((oldsys != NULL && oldsys->stats != NULL) ||
cur_system->stats != NULL) {
1566 if (pilot_isWithPlayer(p))
1567 pilot_setFlag( p, PILOT_HIDE );
1579 if ((
player.
p != NULL) && do_simulate)
1607 pilot_setFlag(
player.
p, PILOT_HIDE );
1610 if (pilot_isWithPlayer(p))
1611 pilot_setFlag( p, PILOT_HIDE );
1620 n = SYSTEM_SIMULATE_TIME_PRE / fps_min_simulation;
1621 for (
int i=0; i<n; i++)
1624 n = SYSTEM_SIMULATE_TIME_POST / fps_min_simulation;
1625 for (
int i=0; i<n; i++)
1637 pilot_rmFlag(
player.
p, PILOT_HIDE );
1640 if (pilot_isWithPlayer(p))
1641 pilot_rmFlag( p, PILOT_HIDE );
1661 Spob *p, *old_stack;
1666 spobstack_changed = 1;
1669 WARN(_(
"Creating new spob in non-debugging mode. Things are probably going to break horribly."));
1676 memset( p, 0,
sizeof(
Spob) );
1678 p->presence.faction = -1;
1681 p->lua_env = LUA_NOREF;
1682 p->lua_mem = LUA_NOREF;
1683 p->lua_init = LUA_NOREF;
1684 p->lua_load = LUA_NOREF;
1685 p->lua_unload = LUA_NOREF;
1686 p->lua_can_land= LUA_NOREF;
1687 p->lua_land = LUA_NOREF;
1688 p->lua_render = LUA_NOREF;
1689 p->lua_update = LUA_NOREF;
1690 p->lua_comm = LUA_NOREF;
1708 return _(p->display);
1727 stdList = standard_commodities();
1731 for (
int i=0; i<
array_size(spob_files); i++) {
1734 int ret =
spob_parse( &s, spob_files[i], stdList );
1745 free( spob_files[i] );
1773 for (
int i=0; i<
array_size(spob_files); i++) {
1778 free( spob_files[i] );
1784 free( spob_files[i] );
1788 node = doc->xmlChildrenNode;
1790 WARN(_(
"Malformed %s file: does not contain elements"), spob_files[i]);
1791 free( spob_files[i] );
1799 memset( &va, 0,
sizeof(va) );
1800 xmlr_attr_strd( node,
"name", va.
name );
1803 cur = node->children;
1806 if (xml_isNode(cur,
"presence")) {
1813 WARN(_(
"Unknown node '%s' in virtual spob '%s'"),cur->name,va.
name);
1814 }
while (xml_nextNode(cur));
1820 free( spob_files[i] );
1836 if (!spob_hasService( p, SPOB_SERVICE_INHABITED ))
1840 if (
areAllies(FACTION_PLAYER,p->presence.faction))
1845 if (
areEnemies(FACTION_PLAYER,p->presence.faction))
1855 if (!spob_hasService( p, SPOB_SERVICE_INHABITED )) {
1856 if (spob_hasService( p, SPOB_SERVICE_LAND ))
1862 if (
areAllies(FACTION_PLAYER,p->presence.faction))
1867 if (
areEnemies(FACTION_PLAYER,p->presence.faction))
1877 if (!spob_hasService( p, SPOB_SERVICE_INHABITED ))
1881 if (
areAllies(FACTION_PLAYER,p->presence.faction))
1886 if (
areEnemies(FACTION_PLAYER,p->presence.faction))
1888 return &cRestricted;
1899 free( p->land_msg );
1904 if (p->lua_can_land != LUA_NOREF) {
1906 lua_rawgeti(naevL, LUA_REGISTRYINDEX, p->lua_can_land);
1907 if (nlua_pcall( p->lua_env, 0, 2 )) {
1908 WARN(_(
"Spob '%s' failed to run '%s':\n%s"), p->name,
"can_land", lua_tostring(naevL,-1));
1913 p->can_land = lua_toboolean(naevL,-2);
1914 if (lua_isstring(naevL,-1))
1915 p->land_msg = strdup( lua_tostring(naevL,-1) );
1922 if (spob_hasService( p, SPOB_SERVICE_LAND )) {
1924 p->land_msg = strdup(_(
"Landing permission granted."));
1933 lua_rawgeti( naevL, LUA_REGISTRYINDEX, spob->
lua_mem );
1934 nlua_setenv( naevL, spob->
lua_env,
"mem" );
1948 do { if ((x) != LUA_NOREF) { \
1949 luaL_unref( naevL, LUA_REGISTRYINDEX, (x) ); \
1965 if (spob->lua_file == NULL)
1969 nlua_env env = spob_lua_get( &mem, spob->lua_file );
1986 lua_newtable( naevL );
1987 lua_pushvalue( naevL, -1 );
1988 spob->
lua_mem = luaL_ref( naevL, LUA_REGISTRYINDEX );
1991 lua_rawgeti( naevL, LUA_REGISTRYINDEX, mem );
1992 lua_pushnil( naevL );
1993 while (lua_next(naevL,-2) != 0) {
1994 lua_pushvalue( naevL, -2 );
1995 lua_pushvalue( naevL, -2 );
1996 lua_remove( naevL, -3 );
1997 lua_settable( naevL, -5 );
1999 lua_pop( naevL, 2 );
2004 lua_rawgeti(naevL, LUA_REGISTRYINDEX, spob->
lua_init);
2006 if (nlua_pcall( spob->
lua_env, 1, 0 )) {
2007 WARN(_(
"Spob '%s' failed to run '%s':\n%s"), spob->
name,
"init", lua_tostring(naevL,-1));
2023 lua_rawgeti(naevL, LUA_REGISTRYINDEX, spob->
lua_load);
2024 if (nlua_pcall( spob->
lua_env, 0, 2 )) {
2025 WARN(_(
"Spob '%s' failed to run '%s':\n%s"), spob->
name,
"load", lua_tostring(naevL,-1));
2034 else if (lua_isnil(naevL,-2)) {
2038 WARN(_(
"Spob '%s' ran '%s' but got non-texture or nil return value!"), spob->
name,
"load" );
2039 spob->
radius = luaL_optnumber(naevL,-1,-1.);
2070 for (
int i=0; i<
array_size(sys->spobs); i++) {
2071 Spob *spob = sys->spobs[i];
2075 lua_rawgeti(naevL, LUA_REGISTRYINDEX, spob->
lua_unload);
2076 if (nlua_pcall( spob->
lua_env, 0, 0 )) {
2077 WARN(_(
"Spob '%s' failed to run '%s':\n%s"), spob->
name,
"unload", lua_tostring(naevL,-1));
2095 xmlNodePtr cur = node->children;
2100 xmlr_float(cur,
"base", ap->
base);
2101 xmlr_float(cur,
"bonus", ap->
bonus);
2102 xmlr_int(cur,
"range", ap->
range);
2103 if (xml_isNode(cur,
"faction")) {
2107 }
while (xml_nextNode(cur));
2122 xmlNodePtr node, parent;
2130 parent = doc->xmlChildrenNode;
2131 if (parent == NULL) {
2132 WARN(_(
"Malformed %s file: does not contain elements"), filename);
2138 memset( spob, 0,
sizeof(
Spob) );
2156 xmlr_attr_strd( parent,
"name", spob->
name );
2158 node = parent->xmlChildrenNode;
2161 xml_onlyNodes(node);
2163 xmlr_strd(node,
"display", spob->
display);
2164 xmlr_strd(node,
"feature", spob->
feature);
2165 xmlr_strd(node,
"lua", spob->lua_file);
2166 xmlr_float(node,
"radius", spob->
radius);
2167 if (xml_isNode(node,
"marker")) {
2168 const char *s = xml_get(node);
2169 spob->
marker = shaders_getSimple( s );
2170 if (spob->
marker == NULL)
2171 WARN(_(
"Spob '%s' has unknown marker shader '%s'!"), spob->
name, s );
2175 if (xml_isNode(node,
"GFX")) {
2176 xmlNodePtr cur = node->children;
2179 if (xml_isNode(cur,
"space")) {
2181 snprintf( str,
sizeof(str), SPOB_GFX_SPACE_PATH
"%s", xml_get(cur));
2186 if (xml_isNode(cur,
"exterior")) {
2188 snprintf( str,
sizeof(str), SPOB_GFX_EXTERIOR_PATH
"%s", xml_get(cur));
2193 WARN(_(
"Unknown node '%s' in spob '%s'"),node->name,spob->
name);
2194 }
while (xml_nextNode(cur));
2197 else if (xml_isNode(node,
"pos")) {
2198 xmlr_attr_float( node,
"x", spob->
pos.
x );
2199 xmlr_attr_float( node,
"y", spob->
pos.
y );
2203 else if (xml_isNode(node,
"presence")) {
2209 else if (xml_isNode(node,
"general")) {
2210 xmlNodePtr cur = node->children;
2214 xmlr_strd(cur,
"class", spob->
class);
2216 xmlr_strd(cur,
"description", spob->
description );
2217 xmlr_float(cur,
"population", spob->
population );
2218 xmlr_float(cur,
"hide", spob->
hide );
2220 if (xml_isNode(cur,
"services")) {
2221 xmlNodePtr ccur = cur->children;
2225 xml_onlyNodes(ccur);
2227 if (xml_isNode(ccur,
"land"))
2228 spob->
services |= SPOB_SERVICE_LAND;
2229 else if (xml_isNode(ccur,
"refuel"))
2230 spob->
services |= SPOB_SERVICE_REFUEL | SPOB_SERVICE_INHABITED;
2231 else if (xml_isNode(ccur,
"bar"))
2232 spob->
services |= SPOB_SERVICE_BAR | SPOB_SERVICE_INHABITED;
2233 else if (xml_isNode(ccur,
"missions"))
2234 spob->
services |= SPOB_SERVICE_MISSIONS | SPOB_SERVICE_INHABITED;
2235 else if (xml_isNode(ccur,
"commodity"))
2236 spob->
services |= SPOB_SERVICE_COMMODITY | SPOB_SERVICE_INHABITED;
2237 else if (xml_isNode(ccur,
"outfits"))
2238 spob->
services |= SPOB_SERVICE_OUTFITS | SPOB_SERVICE_INHABITED;
2239 else if (xml_isNode(ccur,
"shipyard"))
2240 spob->
services |= SPOB_SERVICE_SHIPYARD | SPOB_SERVICE_INHABITED;
2241 else if (xml_isNode(ccur,
"nomissionspawn"))
2242 spob->
flags |= SPOB_NOMISNSPAWN;
2243 else if (xml_isNode(ccur,
"uninhabited"))
2244 spob->
flags |= SPOB_UNINHABITED;
2245 else if (xml_isNode(ccur,
"blackmarket"))
2246 spob->
services |= SPOB_SERVICE_BLACKMARKET;
2248 WARN(_(
"Spob '%s' has unknown services tag '%s'"), spob->
name, ccur->name);
2249 }
while (xml_nextNode(ccur));
2252 else if (xml_isNode(cur,
"commodities")) {
2253 xmlNodePtr ccur = cur->children;
2255 if (xml_isNode(ccur,
"commodity")) {
2257 Commodity *com = commodity_get( xml_get(ccur) );
2258 if (commodity_isFlag(com, COMMODITY_FLAG_STANDARD))
2263 }
while (xml_nextNode(ccur));
2265 else if (xml_isNode(cur,
"blackmarket")) {
2269 }
while (xml_nextNode(cur));
2272 else if (xml_isNode(node,
"tech")) {
2276 else if (xml_isNode(node,
"tags")) {
2277 xmlNodePtr cur = node->children;
2278 if (spob->
tags != NULL)
2279 WARN(_(
"Spob '%s' has duplicate '%s' node!"), spob->
name,
"tags");
2284 if (xml_isNode(cur,
"tag")) {
2285 char *tmp = xml_get(cur);
2290 WARN(_(
"Spob '%s' has unknown node in tags '%s'."), spob->
name, cur->name );
2291 }
while (xml_nextNode(cur));
2294 WARN(_(
"Unknown node '%s' in spob '%s'"),node->name,spob->
name);
2295 }
while (xml_nextNode(node));
2298 if (spob_isFlag(spob, SPOB_UNINHABITED))
2299 spob->
services &= ~SPOB_SERVICE_INHABITED;
2302 spob_setFlag(spob, SPOB_RADIUS);
2305 if (spob->lua_file == NULL) {
2308 spob->lua_file = strdup( str );
2314#define MELEMENT(o,s) if (o) WARN(_("Spob '%s' missing '%s' element"), spob->name, s)
2316 MELEMENT( spob_hasService(spob,SPOB_SERVICE_LAND) &&
2318 MELEMENT( spob_hasService(spob,SPOB_SERVICE_INHABITED) &&
2321 MELEMENT(spob->
class==NULL,
"class");
2322 MELEMENT( spob_hasService(spob,SPOB_SERVICE_LAND) &&
2324 MELEMENT( spob_hasService(spob,SPOB_SERVICE_BAR) &&
2326 MELEMENT( spob_hasService(spob,SPOB_SERVICE_INHABITED) &&
2329 MELEMENT( spob_hasService(spob,SPOB_SERVICE_INHABITED) && (spob_hasService(spob,SPOB_SERVICE_OUTFITS) ||
2330 spob_hasService(spob,SPOB_SERVICE_SHIPYARD)) &&
2331 (spob->
tech==NULL),
"tech" );
2339 if (spob_hasService(spob, SPOB_SERVICE_COMMODITY)) {
2398 if (spob_hasService( spob, SPOB_SERVICE_COMMODITY ))
2399 economy_initialiseSingleSystem( sys, spob );
2417 WARN(_(
"Unable to remove spob '%s' from NULL system."), spobname);
2424 if (sys->spobs[i] == spob)
2429 WARN(_(
"Spob '%s' not found in system '%s' for removal."), spobname, sys->name);
2434 array_erase( &sys->spobs, &sys->spobs[i], &sys->spobs[i+1] );
2435 array_erase( &sys->spobsid, &sys->spobsid[i], &sys->spobsid[i+1] );
2450 WARN(_(
"Unable to find spob '%s' and system '%s' in spob<->system stack."),
2451 spobname, sys->name );
2495 WARN(_(
"Unable to remove virtual spob '%s' from NULL system."), spobname);
2500 for (i=0; i<
array_size(sys->spobs_virtual); i++)
2501 if (strcmp(sys->spobs_virtual[i]->name, spobname)==0)
2506 WARN(_(
"Virtual spob '%s' not found in system '%s' for removal."), spobname, sys->name);
2511 array_erase( &sys->spobs_virtual, &sys->spobs_virtual[i], &sys->spobs_virtual[i+1] );
2556 WARN(_(
"Unable to remove jump point '%s' from NULL system."), jumpname);
2563 if (&sys->jumps[i] == jump)
2568 WARN(_(
"Jump point '%s' not found in system '%s' for removal."), jumpname, sys->name);
2573 array_erase( &sys->jumps, &sys->jumps[i], &sys->jumps[i+1] );
2588 memset( sys, 0,
sizeof(StarSystem) );
2608 systemstack_changed = 1;
2611 WARN(_(
"Creating new system in non-debugging mode. Things are probably going to break horribly."));
2642 for (
int j=0; j<
array_size(sys->jumps); j++) {
2644 JumpPoint *jp = &sys->jumps[j];
2650 dx = jp->target->pos.x - sys->pos.x;
2651 dy = jp->target->pos.y - sys->pos.y;
2652 a = atan2( dy, dx );
2657 if (jp->flags & JP_AUTOPOS)
2658 vec2_pset( &jp->pos, sys->radius, a );
2662 jp->angle = 2.*M_PI-
a;
2663 jp->cosa = cos(jp->angle);
2664 jp->sina = sin(jp->angle);
2687 for (
int j=0; j<
array_size(sys->spobsid); j++)
2688 sys->spobs[j] = &
spob_stack[ sys->spobsid[j] ];
2711 a->density = ASTEROID_DEFAULT_DENSITY;
2715 a->maxspeed = ASTEROID_DEFAULT_MAXSPEED;
2716 a->maxspin = ASTEROID_DEFAULT_MAXSPIN;
2717 a->thrust = ASTEROID_DEFAULT_THRUST;
2720 xmlr_attr_strd( node,
"label", a->label );
2723 cur = node->xmlChildrenNode;
2727 xmlr_float( cur,
"density", a->density );
2728 xmlr_float( cur,
"radius", a->radius );
2729 xmlr_float( cur,
"maxspeed", a->maxspeed );
2730 xmlr_float( cur,
"thrust", a->thrust );
2733 if (xml_isNode(cur,
"group")) {
2735 const char *name = xml_get(cur);
2736 xmlr_attr_float_def(cur,
"weight",w,1.);
2743 if (xml_isNode(cur,
"pos")) {
2746 xmlr_attr_float( cur,
"x", x );
2747 xmlr_attr_float( cur,
"y", y );
2750 vec2_cset( &a->pos, x, y );
2754 WARN(_(
"Asteroid Field in Star System '%s' has unknown node '%s'"), sys->name, node->name);
2755 }
while (xml_nextNode(cur));
2760#define MELEMENT(o,s) \
2761if (o) WARN(_("Asteroid Field in Star System '%s' has missing/invalid '%s' element"), sys->name, s)
2762 MELEMENT(!pos,
"pos");
2763 MELEMENT(a->radius<=0.,
"radius");
2786 memset( a, 0,
sizeof(*a) );
2792 cur = node->xmlChildrenNode;
2794 xml_onlyNodes( cur );
2796 xmlr_float( cur,
"radius", a->radius );
2799 if (xml_isNode(cur,
"pos")) {
2801 xmlr_attr_float( cur,
"x", x );
2802 xmlr_attr_float( cur,
"y", y );
2805 vec2_cset( &a->pos, x, y );
2808 WARN(_(
"Asteroid Exclusion Zone in Star System '%s' has unknown node '%s'"), sys->name, node->name);
2809 }
while (xml_nextNode(cur));
2811#define MELEMENT(o,s) \
2812if (o) WARN(_("Asteroid Exclusion Zone in Star System '%s' has missing/invalid '%s' element"), sys->name, s)
2813 MELEMENT(!pos,
"pos");
2814 MELEMENT(a->radius<=0.,
"radius");
2829 xmlNodePtr node, parent;
2838 parent = doc->xmlChildrenNode;
2839 if (parent == NULL) {
2840 WARN(_(
"Malformed %s file: does not contain elements"), filename);
2849 sys->ownerpresence = 0.;
2850 sys->nebu_hue = NEBULA_DEFAULT_HUE;
2853 xmlr_attr_strd( parent,
"name", sys->name );
2855 node = parent->xmlChildrenNode;
2858 xml_onlyNodes(node);
2860 if (xml_isNode(node,
"pos")) {
2862 xmlr_attr_float( node,
"x", sys->pos.x );
2863 xmlr_attr_float( node,
"y", sys->pos.y );
2866 else if (xml_isNode(node,
"general")) {
2867 xmlNodePtr cur = node->children;
2870 xmlr_strd( cur,
"background", sys->background );
2871 xmlr_strd( cur,
"map_shader", sys->map_shader );
2872 xmlr_strd( cur,
"features", sys->features );
2873 xmlr_int( cur,
"stars", sys->stars );
2874 xmlr_float( cur,
"radius", sys->radius );
2875 if (xml_isNode(cur,
"interference")) {
2877 sys->interference = xml_getFloat(cur);
2880 if (xml_isNode(cur,
"nebula")) {
2881 xmlr_attr_float( cur,
"volatility", sys->nebu_volatility );
2882 xmlr_attr_float_def( cur,
"hue", sys->nebu_hue, NEBULA_DEFAULT_HUE );
2883 sys->nebu_density = xml_getFloat(cur);
2886 if (xml_isNode(cur,
"nolanes")) {
2887 sys_setFlag( sys, SYSTEM_NOLANES );
2890 DEBUG(_(
"Unknown node '%s' in star system '%s'"),node->name,sys->name);
2891 }
while (xml_nextNode(cur));
2895 else if (xml_isNode(node,
"spobs")) {
2896 xmlNodePtr cur = node->children;
2899 if (xml_isNode(cur,
"spob")) {
2903 if (xml_isNode(cur,
"spob_virtual")) {
2907 DEBUG(_(
"Unknown node '%s' in star system '%s'"),node->name,sys->name);
2908 }
while (xml_nextNode(cur));
2912 if (xml_isNode(node,
"asteroids")) {
2913 xmlNodePtr cur = node->children;
2916 if (xml_isNode(cur,
"asteroid"))
2918 else if (xml_isNode(cur,
"exclusion"))
2920 }
while (xml_nextNode(cur));
2923 if (xml_isNode(node,
"stats")) {
2924 xmlNodePtr cur = node->children;
2929 ll->
next = sys->stats;
2933 WARN(_(
"System '%s' has unknown stat '%s'."), sys->name, cur->name);
2934 }
while (xml_nextNode(cur));
2938 if (xml_isNode(node,
"tags")) {
2939 xmlNodePtr cur = node->children;
2943 if (xml_isNode(cur,
"tag")) {
2944 char *tmp = xml_get(cur);
2949 WARN(_(
"System '%s' has unknown node in tags '%s'."), sys->name, cur->name );
2950 }
while (xml_nextNode(cur));
2955 if (xml_isNode(node,
"jumps") || xml_isNode(node,
"asteroids"))
2958 DEBUG(_(
"Unknown node '%s' in star system '%s'"),node->name,sys->name);
2959 }
while (xml_nextNode(node));
2968 sys->nebu_hue /= 360.;
2971 if (sys->map_shader != NULL)
2974#define MELEMENT(o,s) if (o) WARN(_("Star System '%s' missing '%s' element"), sys->name, s)
2975 if (sys->name == NULL) WARN(_(
"Star System '%s' missing 'name' tag"), sys->name);
2977 MELEMENT(sys->stars<0,
"stars");
2978 MELEMENT(sys->radius==0.,
"radius");
3024 for (
int i=0; i<
array_size(sys->presence); i++) {
3025 for (
int j=0; j<
array_size(sys->spobs); j++) {
3026 Spob *pnt = sys->spobs[j];
3052 xmlr_attr_strd( node,
"target", buf );
3054 WARN(_(
"JumpPoint node for system '%s' has no target attribute."), sys->name);
3058 if (target == NULL) {
3059 WARN(_(
"JumpPoint node for system '%s' has invalid target '%s'."), sys->name, buf );
3066 for (
int i=0; i<
array_size(sys->jumps); i++) {
3067 JumpPoint *jp = &sys->jumps[i];
3068 if (jp->targetid != target->id)
3071 WARN(_(
"Star System '%s' has duplicate jump point to '%s'."),
3072 sys->name, target->name );
3079 memset( j, 0,
sizeof(JumpPoint) );
3082 xmlr_attr_float_def( node,
"x", x, HUGE_VAL );
3083 xmlr_attr_float_def( node,
"y", y, HUGE_VAL );
3086 xmlr_attr_strd( node,
"type", buf );
3088 else if (strcmp(buf,
"hidden") == 0)
3089 jp_setFlag(j,JP_HIDDEN);
3090 else if (strcmp(buf,
"exitonly") == 0)
3091 jp_setFlag(j,JP_EXITONLY);
3094 xmlr_attr_float_def( node,
"hide", j->hide, HIDE_DEFAULT_JUMP);
3098 j->targetid = j->target->id;
3101 if (x < HUGE_VAL && y < HUGE_VAL)
3102 vec2_cset( &j->pos, x, y );
3104 jp_setFlag(j,JP_AUTOPOS);
3126 xmlr_attr_strd( node,
"target", buf );
3128 WARN(_(
"JumpPoint node for system '%s' has no target attribute."), sys->name);
3132 if (target == NULL) {
3133 WARN(_(
"JumpPoint node for system '%s' has invalid target '%s'."), sys->name, buf );
3140 for (
int i=0; i<
array_size(sys->jumps); i++) {
3141 JumpPoint *jp = &sys->jumps[i];
3142 if (jp->targetid != target->id)
3145 WARN(_(
"Star System '%s' has duplicate jump point to '%s'."),
3146 sys->name, target->name );
3153 memset( j, 0,
sizeof(JumpPoint) );
3158 j->targetid = j->target->id;
3164 cur = node->xmlChildrenNode;
3166 xmlr_float( cur,
"radius", j->radius );
3169 if (xml_isNode(cur,
"pos")) {
3171 xmlr_attr_float( cur,
"x", x );
3172 xmlr_attr_float( cur,
"y", y );
3175 vec2_cset( &j->pos, x, y );
3177 else if (xml_isNode(cur,
"autopos"))
3178 jp_setFlag(j,JP_AUTOPOS);
3179 else if (xml_isNode(cur,
"hidden"))
3180 jp_setFlag(j,JP_HIDDEN);
3181 else if (xml_isNode(cur,
"exitonly"))
3182 jp_setFlag(j,JP_EXITONLY);
3183 else if (xml_isNode(cur,
"hide")) {
3184 xmlr_float( cur,
"hide", j->hide );
3186 }
while (xml_nextNode(cur));
3188 if (!jp_isFlag(j,JP_AUTOPOS) && !pos)
3189 WARN(_(
"JumpPoint in system '%s' is missing pos element but does not have autopos flag."), sys->name);
3202 xmlNodePtr parent, node;
3209 parent = doc->xmlChildrenNode;
3210 if (parent == NULL) {
3215 node = parent->xmlChildrenNode;
3217 if (xml_isNode(node,
"jumps")) {
3218 xmlNodePtr cur = node->children;
3220 if (xml_isNode(cur,
"jump"))
3222 }
while (xml_nextNode(cur));
3224 }
while (xml_nextNode(node));
3293 sys->jumps[j].targetid = sys->jumps[j].target->id;
3326 char **system_files;
3327 Uint32 time = SDL_GetTicks();
3338 for (
int i=0; i<
array_size(system_files); i++) {
3346 sys.filename = system_files[i];
3374 time = SDL_GetTicks() - time;
3375 DEBUG( n_(
"Loaded %d Star System",
3377 DEBUG( n_(
" with %d Space Object in %.3f s",
3381 DEBUG( n_(
"Loaded %d Star System",
3383 DEBUG( n_(
" with %d Space Object",
3459 if (!jp_isUsable(jp))
3465 else if (jp_isFlag(jp, JP_HIDDEN))
3473 if (jp->hide == 0.) {
3484 if (p->lua_render != LUA_NOREF) {
3487 lua_rawgeti(naevL, LUA_REGISTRYINDEX, p->lua_render);
3488 if (nlua_pcall( p->lua_env, 0, 0 )) {
3489 WARN(_(
"Spob '%s' failed to run '%s':\n%s"), p->name,
"render", lua_tostring(naevL,-1));
3493 else if (p->gfx_space)
3502 if (p->lua_update == LUA_NOREF)
3506 lua_rawgeti(naevL, LUA_REGISTRYINDEX, p->lua_update);
3507 lua_pushnumber(naevL, dt);
3508 lua_pushnumber(naevL,
real_dt);
3509 if (nlua_pcall( p->lua_env, 2, 0 )) {
3510 WARN(_(
"Spob '%s' failed to run '%s':\n%s"), p->name,
"update", lua_tostring(naevL,-1));
3537 free(spb->lua_file);
3542 free( spb->
tags[j] );
3560 if (spb->
tech != NULL)
3587 free(sys->filename);
3589 free(sys->background);
3590 free(sys->map_shader);
3591 free(sys->features);
3600 free( sys->tags[j] );
3604 for (
int j=0; j <
array_size(sys->asteroids); j++)
3624 glDeleteProgram( ms->
program );
3637 sys_rmFlag(sys,SYSTEM_KNOWN);
3638 sys_rmFlag(sys,SYSTEM_HIDDEN);
3639 sys_rmFlag(sys,SYSTEM_PMARKED);
3641 jp_rmFlag(&sys->jumps[j],JP_KNOWN);
3656 sys_rmFlag( sys, SYSTEM_MARKED );
3657 sys->markers_computer = 0;
3658 sys->markers_plot = 0;
3659 sys->markers_high = 0;
3660 sys->markers_low = 0;
3664 spob_rmFlag( pnt, SPOB_MARKED );
3678static int space_addMarkerSystem(
int sysid, MissionMarkerType type )
3690 case SYSMARKER_COMPUTER:
3691 markers = &ssys->markers_computer;
3694 markers = &ssys->markers_low;
3696 case SYSMARKER_HIGH:
3697 markers = &ssys->markers_high;
3699 case SYSMARKER_PLOT:
3700 markers = &ssys->markers_plot;
3703 WARN(_(
"Unknown marker type."));
3709 sys_setFlag(ssys, SYSTEM_MARKED);
3714static int space_addMarkerSpob(
int pntid, MissionMarkerType type )
3717 MissionMarkerType stype;
3724 spob_setFlag( pnt, SPOB_MARKED );
3729 WARN(_(
"Marking spob '%s' that is not in any system!"), pnt->
name);
3732 stype = mission_markerTypeSpobToSystem( type );
3746 case SYSMARKER_COMPUTER:
3748 case SYSMARKER_HIGH:
3749 case SYSMARKER_PLOT:
3750 return space_addMarkerSystem( objid, type );
3751 case SPOBMARKER_COMPUTER:
3752 case SPOBMARKER_LOW:
3753 case SPOBMARKER_HIGH:
3754 case SPOBMARKER_PLOT:
3755 return space_addMarkerSpob( objid, type );
3757 WARN(_(
"Unknown marker type."));
3763static int space_rmMarkerSystem(
int sys, MissionMarkerType type )
3775 case SYSMARKER_COMPUTER:
3776 markers = &ssys->markers_computer;
3779 markers = &ssys->markers_low;
3781 case SYSMARKER_HIGH:
3782 markers = &ssys->markers_high;
3784 case SYSMARKER_PLOT:
3785 markers = &ssys->markers_plot;
3788 WARN(_(
"Unknown marker type."));
3794 if (*markers <= 0) {
3795 sys_rmFlag(ssys, SYSTEM_MARKED);
3802static int space_rmMarkerSpob(
int pntid, MissionMarkerType type )
3806 MissionMarkerType stype;
3812 spob_rmFlag( pnt, SPOB_MARKED );
3818 stype = mission_markerTypeSpobToSystem( type );
3832 case SYSMARKER_COMPUTER:
3834 case SYSMARKER_HIGH:
3835 case SYSMARKER_PLOT:
3836 return space_rmMarkerSystem( objid, type );
3837 case SPOBMARKER_COMPUTER:
3838 case SPOBMARKER_LOW:
3839 case SPOBMARKER_HIGH:
3840 case SPOBMARKER_PLOT:
3841 return space_rmMarkerSpob( objid, type );
3843 WARN(_(
"Unknown marker type."));
3856 xmlw_startElem(writer,
"space");
3860 if (!sys_isKnown(sys))
3863 xmlw_startElem(writer,
"known");
3864 xmlw_attr(writer,
"sys",
"%s",sys->name);
3865 if (sys_isFlag(sys, SYSTEM_PMARKED))
3866 xmlw_attr(writer,
"pmarked",
"%s",
"true");
3867 if (sys->note != NULL)
3868 xmlw_attr(writer,
"note",
"%s",sys->note);
3869 for (
int j=0; j<
array_size(sys->spobs); j++) {
3870 if (!spob_isKnown(sys->spobs[j]))
3872 xmlw_elem(writer,
"spob",
"%s", sys->spobs[j]->name);
3875 for (
int j=0; j<
array_size(sys->jumps); j++) {
3876 if (!jp_isKnown(&sys->jumps[j]))
3878 xmlw_elem(writer,
"jump",
"%s",(&sys->jumps[j])->target->name);
3881 xmlw_endElem(writer);
3883 xmlw_endElem(writer);
3900 node = parent->xmlChildrenNode;
3904 xml_onlyNodes(node);
3905 if (!xml_isNode(node,
"space"))
3908 cur = node->xmlChildrenNode;
3913 xml_onlyNodes( cur );
3914 if (!xml_isNode(cur,
"known"))
3917 xmlr_attr_strd(cur,
"sys",str);
3926 sys_setFlag(sys,SYSTEM_KNOWN);
3928 xmlr_attr_strd(cur,
"pmarked",str);
3930 sys_setFlag(sys,SYSTEM_PMARKED);
3934 xmlr_attr_strd(cur,
"note",str);
3936 xmlr_attr_strd(cur,
"note",sys->note);
3941 }
while (xml_nextNode(cur));
3942 }
while (xml_nextNode(node));
3956 xmlNodePtr node = parent->xmlChildrenNode;
3958 if (xml_isNode(node,
"spob") || xml_isNode(node,
"planet")) {
3963 else if (xml_isNode(node,
"jump")) {
3964 JumpPoint *jp =
jump_get(xml_get(node), sys);
3966 jp_setFlag(jp,JP_KNOWN);
3968 }
while (xml_nextNode(node));
3987 WARN(
"sys == NULL");
3992 for (
int i=0; i <
array_size(sys->presence); i++)
3993 if (sys->presence[i].faction == faction)
3999 sys->presence[n].faction = faction;
4016 double base = ap->
base;
4017 double bonus = ap->
bonus;
4018 double range = ap->
range;
4024 WARN(
"sys == NULL");
4033 if ((base == 0.) && (bonus == 0.))
4041 sys->presence[id].base =
MAX( sys->presence[
id].base, base );
4042 sys->presence[id].bonus += bonus;
4043 sys->presence[id].value = sys->presence[id].base + sys->presence[id].bonus;
4046 sys->presence[x].base =
MAX( sys->presence[x].base,
MAX(0., base*fgens[i].weight) );
4047 sys->presence[x].bonus +=
MAX(0., bonus*fgens[i].weight);
4048 sys->presence[x].value = sys->presence[x].base + sys->presence[x].bonus;
4062 for (
int i=0; i <
array_size(sys->jumps); i++) {
4063 if (sys->jumps[i].target->spilled == 0 && (usehidden || !jp_isFlag( &sys->jumps[i], JP_HIDDEN )) && !jp_isFlag( &sys->jumps[i], JP_EXITONLY )) {
4065 sys->jumps[i].target->spilled = 1;
4079 while (curSpill < range) {
4090 for (
int i=0; i<
array_size(cur->jumps); i++) {
4091 if (cur->jumps[i].target->spilled == 0 && (usehidden || !jp_isFlag( &cur->jumps[i], JP_HIDDEN )) && !jp_isFlag( &cur->jumps[i], JP_EXITONLY )) {
4093 cur->jumps[i].target->spilled = 1;
4099 spillfactor = 1. / (2. + (double)curSpill);
4100 cur->presence[x].base =
MAX( cur->presence[x].base, base * spillfactor );
4101 cur->presence[x].bonus += bonus * spillfactor;
4102 cur->presence[x].value = cur->presence[x].base + cur->presence[x].bonus;
4106 cur->presence[y].base =
MAX( cur->presence[y].base,
MAX(0., base*spillfactor*fgens[i].weight) );
4107 cur->presence[y].bonus +=
MAX(0., bonus*spillfactor*fgens[i].weight );
4108 cur->presence[y].value = cur->presence[y].base + cur->presence[y].bonus;
4143 WARN(
"sys == NULL");
4149 for (
int i=0; i <
array_size(sys->presence); i++) {
4150 if (sys->presence[i].faction == faction)
4151 return MAX(sys->presence[i].value, 0);
4172 WARN(
"sys == NULL");
4178 for (
int i=0; i <
array_size(sys->presence); i++) {
4179 if (sys->presence[i].faction == faction) {
4180 *base = sys->presence[i].base;
4181 *bonus = sys->presence[i].bonus;
4182 return MAX(sys->presence[i].value, 0);
4202 WARN(
"sys == NULL");
4212 for (
int i=0; i<
array_size(sys->spobs_virtual); i++)
4213 for (
int j=0; j<
array_size(sys->spobs_virtual[i]->presences); j++)
4255 WARN(
"sys == NULL");
4260 for (
int i=0; i <
array_size(sys->spobs); i++)
4277 sys->presence[id].curUsed -= amount;
4280 presence = &sys->presence[id];
4281 presence->
curUsed =
MAX( 0, sys->presence[
id].curUsed );
4287 nlua_getenv( naevL, env,
"decrease" );
4288 if (lua_isnil(naevL,-1)) {
4292 lua_pushnumber( naevL, presence->
curUsed );
4293 lua_pushnumber( naevL, presence->
value );
4294 lua_pushnumber( naevL, presence->
timer );
4297 if (nlua_pcall(env, 3, 1)) {
4298 WARN(_(
"Lua decrease script for faction '%s' : %s"),
4305 if (!lua_isnumber(naevL,-1)) {
4306 WARN(_(
"Lua spawn script for faction '%s' failed to return timer value."),
4311 presence->
timer = lua_tonumber(naevL,-1);
4323 space_landQueueSpob = pnt;
4334 static char pop[STRMAX_SHORT];
4335 double p = (double)population;
4343 snprintf( pop,
sizeof(pop),
"%.0f", p );
4345 char scratch[STRMAX_SHORT];
4346 const char *digits[] = {
"\xe2\x81\xb0",
"\xc2\xb9",
"\xc2\xb2",
"\xc2\xb3",
"\xe2\x81\xb4",
"\xe2\x81\xb5",
"\xe2\x81\xb6",
"\xe2\x81\xb7",
"\xe2\x81\xb8",
"\xe2\x81\xb9"};
4347 int state = 0, COEF = 0, E = 1, EXP = 4;
4349 snprintf( scratch,
sizeof(scratch),
"%.1e", p );
4350 for (
const char *
c = scratch; *
c;
c++) {
4351 if (state == COEF && *
c !=
'e')
4352 l +=
scnprintf( &pop[l],
sizeof(pop)-l,
"%c", *
c );
4353 else if (state == COEF ) {
4354 l +=
scnprintf( &pop[l],
sizeof(pop)-l,
"%s",
"\xc2\xb7" "10" );
4357 else if (state == E && (*
c ==
'+' || *
c ==
'0'))
4361 l +=
scnprintf( &pop[l],
sizeof(pop)-l,
"%s", digits[*
c-
'0'] );
4384 if (strcmp(t->
name,name)==0)
4392 ms->
name = strdup( name );
4393 ms->
program = gl_program_vert_frag(
"system_map.vert", name );
4396 ms->
time = glGetUniformLocation( ms->
program,
"time" );
4398 ms->
alpha = glGetUniformLocation( ms->
program,
"alpha" );
4403static int spob_lua_cmp(
const void *a,
const void *b )
4410static nlua_env spob_lua_get(
int *mem,
const char *filename )
4428 WARN(_(
"Failed to read spob Lua '%s'!"), filename );
4432 nlua_env env = nlua_newEnv();
4443 lua_newtable(naevL);
4444 lua_pushvalue(naevL, -1);
4445 lf->
lua_mem = luaL_ref( naevL, LUA_REGISTRYINDEX );
4446 nlua_setenv(naevL, env,
"mem");
4449 if (nlua_dobufenv(env, dat, sz, filename) != 0) {
4451 WARN(_(
"Lua Spob '%s' error:\n%s"), filename, lua_tostring(naevL,-1));
4453 spob_lua_free( lf );
4468 nlua_freeEnv( lf->
env );
4469 luaL_unref( naevL, LUA_REGISTRYINDEX, lf->
lua_mem );
#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_free(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 asteroids_update(double dt)
Controls fleet spawning.
void background_clear(void)
Cleans up the background stuff.
void background_initDust(int n)
Initializes background stars.
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.
int dtype_get(const char *name)
Gets the id of a dtype based on name.
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.
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.
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.
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 enter_sys)
Actually runs the updates.
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.
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.
LuaPilot lua_topilot(lua_State *L, int ind)
Lua bindings to interact with pilots.
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.
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....
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_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.
glTexture * gl_newImage(const char *path, const unsigned int flags)
Loads an image as a texture.
void gl_getSpriteFromDir(int *x, int *y, const glTexture *t, const double dir)
Sets x and y to be the appropriate sprite for glTexture using dir.
void gl_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.
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 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.
int system_addJumpDiff(StarSystem *sys, xmlNodePtr node)
Adds a jump point to a star system from a diff.
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.
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.
int space_isSimulationEffects(void)
returns whether or not we're simulating with effects.
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 space_sysLoad(xmlNodePtr parent)
Loads player's space properties from an XML node.
int space_sysReallyReachable(char *sysname)
Sees if a system can be reached via jumping.
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.
static int system_parseJumpPointDiff(const xmlNodePtr node, StarSystem *sys)
Parses a single jump point for a system, from unidiff.
const char * space_getRndSpob(int landable, unsigned int services, int(*filter)(Spob *p))
Gets the name of a random spob.
int system_rmJump(StarSystem *sys, const char *jumpname)
Removes a jump point from a star system.
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.
int spob_index(const Spob *p)
Gets the ID of a spob.
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.
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_sysSave(xmlTextWriterPtr writer)
Saves what is needed to be saved for space.
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.
StarSystem * system_get(const char *sysname)
Get the system from its name.
char * spob_getSystem(const char *spobname)
Get the name of a system from a spobname.
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.
static int getPresenceIndex(StarSystem *sys, int faction)
Gets the index of the presence element for a faction. Creates one if it doesn't exist.
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.
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.
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.
static int space_parseSpobs(xmlNodePtr parent, StarSystem *sys)
Parses spobs in a system.
void space_clearKnown(void)
Clears all system knowledge.
StarSystem * systems_stack
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 * space_populationStr(uint64_t population)
Gets the population in an approximated string. Note this function changes the string value each call,...
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 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.
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.
char ** space_getFactionSpob(int *factions, int landable)
Gets the name of all the spobs that belong to factions.
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.
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 group of asteroids.
Represents a single asteroid.
Core damage that an outfit does.
The actual hook parameter.
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.