2 * See Licensing and Copyright notice in naev.h
8 * @brief Lua system module.
11 #include "nlua_system.h"
19 #include "nlua_faction.h"
20 #include "nlua_vec2.h"
21 #include "nlua_planet.h"
28 /* System metatable methods */
29 static int systemL_cur( lua_State
*L
);
30 static int systemL_get( lua_State
*L
);
31 static int systemL_eq( lua_State
*L
);
32 static int systemL_name( lua_State
*L
);
33 static int systemL_faction( lua_State
*L
);
34 static int systemL_nebula( lua_State
*L
);
35 static int systemL_jumpdistance( lua_State
*L
);
36 static int systemL_adjacent( lua_State
*L
);
37 static int systemL_hasPresence( lua_State
*L
);
38 static int systemL_planets( lua_State
*L
);
39 static int systemL_security( lua_State
*L
);
40 static const luaL_reg system_methods
[] = {
41 { "cur", systemL_cur
},
42 { "get", systemL_get
},
43 { "__eq", systemL_eq
},
44 { "__tostring", systemL_name
},
45 { "name", systemL_name
},
46 { "faction", systemL_faction
},
47 { "nebula", systemL_nebula
},
48 { "jumpDist", systemL_jumpdistance
},
49 { "adjacentSystems", systemL_adjacent
},
50 { "hasPresence", systemL_hasPresence
},
51 { "planets", systemL_planets
},
52 { "security", systemL_security
},
54 }; /**< System metatable methods. */
58 * @brief Loads the system library.
60 * @param L State to load system library into.
61 * @param readonly Load read only functions?
62 * @return 0 on success.
64 int nlua_loadSystem( lua_State
*L
, int readonly
)
66 (void)readonly
; /* only read only atm */
68 /* Create the metatable */
69 luaL_newmetatable(L
, SYSTEM_METATABLE
);
71 /* Create the access table */
73 lua_setfield(L
,-2,"__index");
75 /* Register the values */
76 luaL_register(L
, NULL
, system_methods
);
79 lua_setfield(L
, LUA_GLOBALSINDEX
, SYSTEM_METATABLE
);
81 return 0; /* No error */
86 * @brief Lua system module.
88 * This module allows you to use the Star Systems from Lua.
90 * Typical example would be something like:
92 * cur = system.get() -- Gets current system
93 * sys = system.get( "Gamma Polaris" )
99 * @brief Gets system at index.
101 * @param L Lua state to get system from.
102 * @param ind Index position of system.
103 * @return The LuaSystem at ind.
105 LuaSystem
* lua_tosystem( lua_State
*L
, int ind
)
107 return (LuaSystem
*) lua_touserdata(L
,ind
);
110 * @brief Gets system at index raising an error if type doesn't match.
112 * @param L Lua state to get system from.
113 * @param ind Index position of system.
114 * @return The LuaSystem at ind.
116 LuaSystem
* luaL_checksystem( lua_State
*L
, int ind
)
118 if (lua_issystem(L
,ind
))
119 return lua_tosystem(L
,ind
);
120 luaL_typerror(L
, ind
, SYSTEM_METATABLE
);
125 * @brief Pushes a system on the stack.
127 * @param L Lua state to push system onto.
128 * @param sys System to push.
129 * @return System just pushed.
131 LuaSystem
* lua_pushsystem( lua_State
*L
, LuaSystem sys
)
134 s
= (LuaSystem
*) lua_newuserdata(L
, sizeof(LuaSystem
));
136 luaL_getmetatable(L
, SYSTEM_METATABLE
);
137 lua_setmetatable(L
, -2);
142 * @brief Checks to see if ind is a system.
144 * @param L Lua state to check.
145 * @param ind Index position to check.
146 * @return 1 if there is a system at index position.
148 int lua_issystem( lua_State
*L
, int ind
)
152 if (lua_getmetatable(L
,ind
)==0)
154 lua_getfield(L
, LUA_REGISTRYINDEX
, SYSTEM_METATABLE
);
157 if (lua_rawequal(L
, -1, -2)) /* does it have the correct mt? */
160 lua_pop(L
, 2); /* remove both metatables */
166 * @brief Gets the current system.
168 * @usage sys = system.cur() -- Gets the current system
170 * @luareturn Current system.
173 static int systemL_cur( lua_State
*L
)
177 lua_pushsystem(L
,sys
);
183 * @brief Gets a system.
185 * Behaves differently depending on what you pass as param:
186 * - nil : -OBSOLETE- Gets the current system. Use system.cur() instead.
187 * - string : Gets the system by name.
188 * - planet : Gets the system by planet.
190 * @usage sys = system.get( p ) -- Gets system where planet 'p' is located.
191 * @usage sys = system.get( "Gamma Polaris" ) -- Gets the system by name.
193 * @luaparam param Read description for details.
194 * @luareturn System metatable matching param.
195 * @luafunc get( param )
197 static int systemL_get( lua_State
*L
)
202 /* Get current system with no parameters */
203 if (lua_gettop(L
) == 0) {
206 /* Passing a string (systemname) */
207 else if (lua_isstring(L
,1)) {
208 sys
.s
= system_get( lua_tostring(L
,1) );
210 /* Passing a planet */
211 else if (lua_isplanet(L
,1)) {
212 p
= lua_toplanet(L
,1);
213 sys
.s
= system_get( planet_getSystem( p
->p
->name
) );
215 else NLUA_INVALID_PARAMETER();
217 /* Error checking. */
219 NLUA_ERROR(L
, "No matching systems found.");
223 /* return the system */
224 lua_pushsystem(L
,sys
);
229 * @brief Check systems for equality.
231 * Allows you to use the '=' operator in Lua with systems.
233 * @usage if sys == system.get( "Draygar" ) then -- Do something
235 * @luaparam s System comparing.
236 * @luaparam comp System to compare against.
237 * @luareturn true if both systems are the same.
238 * @luafunc __eq( s, comp )
240 static int systemL_eq( lua_State
*L
)
243 a
= luaL_checksystem(L
,1);
244 b
= luaL_checksystem(L
,2);
246 lua_pushboolean(L
,1);
248 lua_pushboolean(L
,0);
253 * @brief Returns the system's name.
255 * @usage name = sys:name()
257 * @luaparam s System to get name of.
258 * @luareturn The name of the system.
261 static int systemL_name( lua_State
*L
)
264 sys
= luaL_checksystem(L
,1);
265 lua_pushstring(L
,sys
->s
->name
);
270 * @brief Gets system factions.
273 * sys = system.get() -- Get current system
274 * facts = sys:faction() -- Get factions
275 * if facts["Empire"] then
276 * -- Do something since there is at least one Empire planet in the system
280 * @luaparam s System to get the factions of.
281 * @luareturn A table containing all the factions in the system.
282 * @luafunc faction( s )
284 static int systemL_faction( lua_State
*L
)
288 sys
= luaL_checksystem(L
,1);
290 /* Return result in table */
292 for (i
=0; i
<sys
->s
->nplanets
; i
++) {
293 if (sys
->s
->planets
[i
]->faction
> 0) { /* Faction must be valid */
294 lua_pushboolean(L
,1); /* value */
295 lua_setfield(L
,-2,faction_name(sys
->s
->planets
[i
]->faction
)); /* key */
296 /* allows syntax foo = space.faction("foo"); if foo["bar"] then ... end */
305 * @brief Gets the system's nebula parameters.
307 * @usage density, volatility = sys:nebula()
309 * @luaparam s System to get nebula parameters from.
310 * @luareturn The density and volatility of the system.
311 * @luafunc nebula( s )
313 static int systemL_nebula( lua_State
*L
)
316 sys
= luaL_checksystem(L
,1);
318 /* Push the density and volatility. */
319 lua_pushnumber(L
, sys
->s
->nebu_density
);
320 lua_pushnumber(L
, sys
->s
->nebu_volatility
);
327 * @brief Gets jump distance from current system, or to another.
329 * Does different things depending on the parameter type:
330 * - nil : Gets distance from current system.
331 * - string : Gets distance from system matching name.
332 * - system : Gets distance from system
334 * @usage d = sys:jumpDist() -- Distance from current system.
335 * @usage d = sys:jumpDist( "Draygar" ) -- Distance from system Draygar.
336 * @usage d = sys:jumpDist( another_sys ) -- Distance from system another_sys.
338 * @luaparam param See description.
339 * @luareturn Number of jumps to system.
340 * @luafunc jumpDist( param )
342 static int systemL_jumpdistance( lua_State
*L
)
344 LuaSystem
*sys
, *sysp
;
347 const char *start
, *goal
;
349 sys
= luaL_checksystem(L
,1);
350 start
= sys
->s
->name
;
352 if (lua_gettop(L
) > 1) {
353 if (lua_isstring(L
,2))
354 goal
= lua_tostring(L
,2);
355 else if (lua_issystem(L
,2)) {
356 sysp
= lua_tosystem(L
,2);
357 goal
= sysp
->s
->name
;
359 else NLUA_INVALID_PARAMETER();
362 goal
= cur_system
->name
;
364 s
= map_getJumpPath( &jumps
, start
, goal
, 1, NULL
);
367 lua_pushnumber(L
,jumps
);
373 * @brief Gets all the ajacent systems to a system.
375 * @usage for k,v in pairs( sys:adjacentSystems() ) do -- Iterate over adjacent systems.
377 * @luaparam s System to get adjacent systems of.
378 * @luareturn A table with all the adjacent systems.
379 * @luafunc adjacentSystems( s )
381 static int systemL_adjacent( lua_State
*L
)
384 LuaSystem
*sys
, sysp
;
386 sys
= luaL_checksystem(L
,1);
388 /* Push all adjacent systems. */
390 for (i
=0; i
<sys
->s
->njumps
; i
++) {
391 sysp
.s
= system_getIndex( sys
->s
->jumps
[i
] );
392 lua_pushnumber(L
,i
+1); /* key */
393 lua_pushsystem(L
,sysp
); /* value */
402 * @brief Checks to see if a faction has presence in a system.
404 * This checks to see if the faction has a possibility of having any ships at all
405 * be randomly generated in the system.
407 * @usage if sys:hasPresence( "Empire" ) then -- Checks to see if Empire has ships in the system
408 * @usage if sys:hasPresence( faction.get("Pirate") ) then -- Checks to see if the Pirate has ships in the system
410 * @luaparam s System to check to see if has presence of a certain faction.
411 * @luaparam f Faction or name of faction to check to see if has presence in the system.
412 * @luareturn true If faction has presence in the system, false otherwise.
413 * @luafunc hasPresence( s, f )
415 static int systemL_hasPresence( lua_State
*L
)
422 sys
= luaL_checksystem(L
,1);
424 /* Get the second parameter. */
425 if (lua_isstring(L
,2)) {
426 fct
= faction_get( lua_tostring(L
,2) );
428 else if (lua_isfaction(L
,2)) {
429 lf
= lua_tofaction(L
,2);
432 else NLUA_INVALID_PARAMETER();
434 /* Try to find a fleet of the faction. */
436 for (i
=0; i
<sys
->s
->nfleets
; i
++) {
437 if (sys
->s
->fleets
[i
].fleet
->faction
== fct
) {
443 lua_pushboolean(L
, found
);
449 * @brief Gets the planets in a system.
451 * @usage for k,v in pairs( sys:planets() ) do -- Iterate over planets in system
452 * @usage if #sys:planets() > 0then -- System has planets
454 * @luaparam s System to get planets of
455 * @luareturn A table with all the planets
456 * @luafunc planets( s )
458 static int systemL_planets( lua_State
*L
)
464 sys
= luaL_checksystem(L
,1);
466 /* Push all planets. */
468 for (i
=0; i
<sys
->s
->nplanets
; i
++) {
469 p
.p
= sys
->s
->planets
[i
];
470 lua_pushnumber(L
,i
+1); /* key */
471 lua_pushplanet(L
,p
); /* value */
480 * @brief Gets the security level in a system.
482 * @usage sec = sys:security()
484 * @luaparam s System to get security level of.
485 * @luareturn The security level in sys (in % -> 25 = 25%).
486 * @luafunc security( s )
488 static int systemL_security( lua_State
*L
)
492 sys
= luaL_checksystem(L
,1);
494 lua_pushnumber(L
, sys
->s
->security
* 100. );