naev 0.11.5
nlua_asteroid.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <lauxlib.h>
11
12#include "naev.h"
15#include "nlua_asteroid.h"
16
17#include "array.h"
18#include "space.h"
19#include "nluadef.h"
20#include "nlua_vec2.h"
21#include "nlua_commodity.h"
22#include "nlua_pilot.h"
23
24/* Asteroid methods. */
25static int asteroidL_eq( lua_State *L );
26static int asteroidL_getAll( lua_State *L );
27static int asteroidL_get( lua_State *L );
28static int asteroidL_exists( lua_State *L );
29static int asteroidL_state( lua_State *L );
30static int asteroidL_setState( lua_State *L );
31static int asteroidL_field( lua_State *L );
32static int asteroidL_pos( lua_State *L );
33static int asteroidL_vel( lua_State *L );
34static int asteroidL_setPos( lua_State *L );
35static int asteroidL_setVel( lua_State *L );
36static int asteroidL_scanned( lua_State *L );
37static int asteroidL_timer( lua_State *L );
38static int asteroidL_setTimer( lua_State *L );
39static int asteroidL_armour( lua_State *L );
40static int asteroidL_setArmour( lua_State *L );
41static int asteroidL_alertRange( lua_State *L );
42static int asteroidL_materials( lua_State *L );
43static const luaL_Reg asteroidL_methods[] = {
44 { "__eq", asteroidL_eq },
45 { "getAll", asteroidL_getAll },
46 { "get", asteroidL_get },
47 { "exists", asteroidL_exists },
48 { "state", asteroidL_state },
49 { "setState", asteroidL_setState },
50 { "field", asteroidL_field },
51 { "pos", asteroidL_pos },
52 { "vel", asteroidL_vel },
53 { "setPos", asteroidL_setPos },
54 { "setVel", asteroidL_setVel },
55 { "scanned", asteroidL_scanned },
56 { "timer", asteroidL_timer },
57 { "setTimer", asteroidL_setTimer },
58 { "armour", asteroidL_armour },
59 { "setArmour", asteroidL_setArmour },
60 { "alertRange", asteroidL_alertRange },
61 { "materials", asteroidL_materials },
62 {0,0}
63};
71int nlua_loadAsteroid( nlua_env env )
72{
73 nlua_register(env, ASTEROID_METATABLE, asteroidL_methods, 1);
74 return 0;
75}
76
84LuaAsteroid_t* lua_toasteroid( lua_State *L, int ind )
85{
86 return (LuaAsteroid_t*) lua_touserdata(L,ind);
87}
95LuaAsteroid_t* luaL_checkasteroid( lua_State *L, int ind )
96{
97 if (lua_isasteroid(L,ind))
98 return lua_toasteroid(L,ind);
99 luaL_typerror(L, ind, ASTEROID_METATABLE);
100 return NULL;
101}
109Asteroid* luaL_validasteroid( lua_State *L, int ind )
110{
111 Asteroid *a;
112 if (lua_isasteroid(L, ind)) {
113 const LuaAsteroid_t *la = luaL_checkasteroid(L, ind);
114#if DEBUGGING
115 if ((la->parent < 0) || (la->parent >= array_size(cur_system->asteroids))) {
116 NLUA_ERROR(L,_("Asteroid field '%d' is out of range!"),la->parent);
117 return NULL;
118 }
119#endif /* DEBUGGING */
120 AsteroidAnchor *field = &cur_system->asteroids[ la->parent ];
121#if DEBUGGING
122 if ((la->id < 0) || (la->id >= field->nb)) {
123 NLUA_ERROR(L,_("Asteroid '%d' in field '%d' is out of range!"),la->id,la->parent);
124 return NULL;
125 }
126#endif /* DEBUGGING */
127 a = &field->asteroids[ la->id ];
128 }
129 else {
130 luaL_typerror(L, ind, ASTEROID_METATABLE);
131 return NULL;
132 }
133
134 if (a == NULL) {
135 NLUA_ERROR(L, _("Asteroid is invalid"));
136 return NULL;
137 }
138
139 return a;
140}
149{
150 LuaAsteroid_t *la = (LuaAsteroid_t*) lua_newuserdata(L, sizeof(LuaAsteroid_t));
151 *la = asteroid;
152 luaL_getmetatable(L, ASTEROID_METATABLE);
153 lua_setmetatable(L, -2);
154 return la;
155}
163int lua_isasteroid( lua_State *L, int ind )
164{
165 int ret;
166
167 if (lua_getmetatable(L,ind)==0)
168 return 0;
169 lua_getfield(L, LUA_REGISTRYINDEX, ASTEROID_METATABLE);
170
171 ret = 0;
172 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
173 ret = 1;
174
175 lua_pop(L, 2); /* remove both metatables */
176 return ret;
177}
178
193static int asteroidL_eq( lua_State *L )
194{
195 LuaAsteroid_t *a1, *a2;
196 a1 = luaL_checkasteroid(L,1);
197 a2 = luaL_checkasteroid(L,2);
198 lua_pushboolean( L, (memcmp( a1, a2, sizeof(LuaAsteroid_t) )==0) );
199 return 1;
200}
201
208static int asteroidL_getAll( lua_State *L )
209{
210 int n = 1;
211 lua_newtable(L);
212 for (int i=0; i<array_size(cur_system->asteroids); i++) {
213 const AsteroidAnchor *ast = &cur_system->asteroids[i];
214 for (int j=0; j<ast->nb; j++) {
215 const Asteroid *a = &ast->asteroids[j];
216 LuaAsteroid_t la = {
217 .parent = a->parent,
218 .id = a->id,
219 };
220
221 lua_pushasteroid( L, la );
222 lua_rawseti( L, -2, n++ );
223 }
224 }
225
226 return 1;
227}
228
236static int asteroidL_get( lua_State *L )
237{
238 LuaAsteroid_t la;
239 int field = -1;
240 const vec2 *pos = NULL;
241
242 /* No asteroids, so everything just returns nil. */
243 if (array_size(cur_system->asteroids) <= 0)
244 return 0;
245
246 if (lua_isvector(L,1))
247 pos = lua_tovector(L,1);
248
249 else if (lua_ispilot(L,1))
250 pos = &luaL_validpilot(L,1)->solid.pos;
251
252 else if (lua_isnoneornil(L,1)) {
253 int max_field = array_size(cur_system->asteroids) - 1;
254 field = (max_field < 0 ? max_field : RNG(0, max_field));
255 }
256 else if (lua_isnumber(L,1)) {
257 field = luaL_checkinteger(L,1)-1;
258 if ((field < 0) || (field >= array_size(cur_system->asteroids)))
259 NLUA_INVALID_PARAMETER(L,1);
260 }
261 else
262 NLUA_INVALID_PARAMETER(L,1);
263
264 /* Get random asteroid. */
265 if ((pos==NULL) && (field >= 0)) {
266 /* Random asteroid. */
267 int ast = RNG(0,cur_system->asteroids[field].nb-1);
268 int bad_asteroid = 0;
269 Asteroid *a = &cur_system->asteroids[field].asteroids[ast];
270
271 if (a->state != ASTEROID_FG) {
272 /* Switch to next index until we find a valid one, or until we come full-circle. */
273 bad_asteroid = 1;
274 for (int i=0; i<cur_system->asteroids[field].nb; i++) {
275 ast = (ast+1) % cur_system->asteroids[field].nb;
276 a = &cur_system->asteroids[field].asteroids[ast];
277 if (a->state == ASTEROID_FG) {
278 bad_asteroid = 0;
279 break;
280 }
281 }
282 }
283
284 if (bad_asteroid)
285 return 0;
286
287 la.parent = field;
288 la.id = ast;
289 lua_pushasteroid(L,la);
290 return 1;
291 }
292
293 /* Try to find nearest asteroid. */
294 Asteroid *a_closest = NULL;
295 double dist2 = HUGE_VAL;
296 for (int i=0; i<array_size(cur_system->asteroids); i++) {
298 for (int j=0; j<ast->nb; j++) {
299 double d2;
300 Asteroid *a = &ast->asteroids[j];
301
302 if (a->state != ASTEROID_FG)
303 continue;
304
305 d2 = vec2_dist2( pos, &a->sol.pos );
306 if (d2 > dist2)
307 continue;
308
309 a_closest = a;
310 dist2 = d2;
311 }
312 }
313 if (a_closest==NULL)
314 return 0;
315
316 /* Got an asteroid, ship it. */
317 la.parent = a_closest->parent;
318 la.id = a_closest->id;
319 lua_pushasteroid(L,la);
320 return 1;
321}
322
330static int asteroidL_exists( lua_State *L )
331{
332 if (!lua_isasteroid(L, 1)) {
333 lua_pushboolean(L, 0);
334 return 1;
335 }
336
337 const LuaAsteroid_t *la = luaL_checkasteroid(L, 1);
338 if ((la->parent < 0) || (la->parent >= array_size(cur_system->asteroids))) {
339 lua_pushboolean(L, 0);
340 return 1;
341 }
342
343 AsteroidAnchor *field = &cur_system->asteroids[ la->parent ];
344 if ((la->id < 0) || (la->id >= field->nb)) {
345 lua_pushboolean(L, 0);
346 return 1;
347 }
348
349 const Asteroid *a = &field->asteroids[ la->id ];
350 lua_pushboolean(L, (a->state==ASTEROID_FG));
351 return 1;
352}
353
361static int asteroidL_state( lua_State *L )
362{
363 const Asteroid *ast = luaL_validasteroid(L,1);
364 const char *state = NULL;
365 switch (ast->state) {
366 case ASTEROID_FG:
367 state = "FG";
368 break;
369 case ASTEROID_XB:
370 state = "XB";
371 break;
372 case ASTEROID_BX:
373 state = "BX";
374 break;
375 case ASTEROID_XX_TO_BG:
376 state = "XX_TO_BG";
377 break;
378 case ASTEROID_FG_TO_BG:
379 state = "FG_TO_BG";
380 break;
381 case ASTEROID_BG_TO_FG:
382 state = "BG_TO_FG";
383 break;
384 case ASTEROID_BG_TO_XX:
385 state = "BG_TO_XX";
386 break;
387 case ASTEROID_XX:
388 state = "XX";
389 break;
390 }
391 lua_pushstring( L, state );
392 return 1;
393}
394
402static int asteroidL_setState( lua_State *L )
403{
404 Asteroid *ast = luaL_validasteroid(L,1);
405 const char *state = luaL_checkstring(L,2);
406 if (strcmp(state,"FG")==0)
407 ast->state = ASTEROID_FG;
408 else if (strcmp(state,"XB")==0)
409 ast->state = ASTEROID_XB;
410 else if (strcmp(state,"BX")==0)
411 ast->state = ASTEROID_BX;
412 else if (strcmp(state,"XX_TO_BG")==0)
413 ast->state = ASTEROID_XX_TO_BG;
414 else if (strcmp(state,"FG_TO_BG")==0)
415 ast->state = ASTEROID_FG_TO_BG;
416 else if (strcmp(state,"BG_TO_FG")==0)
417 ast->state = ASTEROID_BG_TO_FG;
418 else if (strcmp(state,"BG_TO_XX")==0)
419 ast->state = ASTEROID_BG_TO_XX;
420 else if (strcmp(state,"XX")==0)
421 ast->state = ASTEROID_XX;
422 else
423 NLUA_INVALID_PARAMETER(L,2);
424 return 0;
425}
426
434static int asteroidL_field( lua_State *L )
435{
436 const LuaAsteroid_t *la = luaL_checkasteroid(L,1);
437 lua_pushinteger(L,la->parent+1);
438 return 1;
439}
440
448static int asteroidL_pos( lua_State *L )
449{
450 const Asteroid *a = luaL_validasteroid(L,1);
451 lua_pushvector(L,a->sol.pos);
452 return 1;
453}
454
462static int asteroidL_vel( lua_State *L )
463{
464 const Asteroid *a = luaL_validasteroid(L,1);
465 lua_pushvector(L,a->sol.vel);
466 return 1;
467}
468
476static int asteroidL_setPos( lua_State *L )
477{
479 const vec2 *v = luaL_checkvector(L,2);
480 a->sol.pos = *v;
481 return 0;
482}
483
491static int asteroidL_setVel( lua_State *L )
492{
494 const vec2 *v = luaL_checkvector(L,2);
495 a->sol.vel = *v;
496 return 0;
497}
498
506static int asteroidL_scanned( lua_State *L )
507{
508 const Asteroid *a = luaL_validasteroid(L,1);
509 lua_pushboolean(L,a->scanned);
510 return 1;
511}
512
521static int asteroidL_timer( lua_State *L )
522{
523 const Asteroid *a = luaL_validasteroid(L,1);
524 lua_pushnumber(L,a->timer);
525 lua_pushnumber(L,a->timer_max);
526 return 2;
527}
528
536static int asteroidL_setTimer( lua_State *L )
537{
539 a->timer = luaL_checknumber(L,2);
540 a->timer_max = MAX( a->timer_max, a->timer );
541 return 0;
542}
543
551static int asteroidL_armour( lua_State *L )
552{
553 const Asteroid *a = luaL_validasteroid(L,1);
554 lua_pushnumber(L,a->armour);
555 return 1;
556}
557
565static int asteroidL_setArmour( lua_State *L )
566{
568 a->armour = luaL_checknumber(L,2);
569 if (a->armour <= 0.)
570 asteroid_explode( a, -1, 0. );
571 return 0;
572}
573
581static int asteroidL_alertRange( lua_State *L )
582{
584 lua_pushnumber(L,a->type->alert_range);
585 return 1;
586}
587
595static int asteroidL_materials( lua_State *L )
596{
598 const AsteroidType *at = a->type;
599
600 lua_newtable(L);
601 for (int i=0; i<array_size(at->material); i++) {
602 const AsteroidReward *mat = &at->material[i];
603 lua_newtable(L);
604
605 lua_pushcommodity( L, mat->material );
606 lua_setfield(L,-2,"commodity");
607
608 lua_pushnumber( L, mat->quantity );
609 lua_setfield(L,-2,"quantity");
610
611 lua_pushnumber( L, mat->rarity );
612 lua_setfield(L,-2,"rarity");
613
614 lua_rawseti( L, -2, i+1 );
615 }
616
617 return 1;
618}
Provides macros to work with dynamic arrays.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:168
void asteroid_explode(Asteroid *a, int max_rarity, double mining_bonus)
Makes an asteroid explode.
Definition asteroid.c:1092
Header file with generic functions and naev-specifics.
#define MAX(x, y)
Definition naev.h:39
static const luaL_Reg asteroidL_methods[]
static int asteroidL_state(lua_State *L)
Gets the state of an asteroid.
static int asteroidL_vel(lua_State *L)
Gets the velocity of an asteroid.
static int asteroidL_setState(lua_State *L)
Sets the state of an asteroid.
static int asteroidL_field(lua_State *L)
Gets the field the asteroid belongs to (useful for getting more asteroids from the same field).
static int asteroidL_scanned(lua_State *L)
Gets whether or not an asteroid got scanned.
static int asteroidL_exists(lua_State *L)
Checks to see if an asteroid exists.
static int asteroidL_materials(lua_State *L)
Gets the materials the asteroid can potentially drop.
static int asteroidL_setVel(lua_State *L)
Sets the velocity of an asteroid.
int nlua_loadAsteroid(nlua_env env)
Loads the asteroid library.
static int asteroidL_get(lua_State *L)
Gets an asteroid in the system.
static int asteroidL_alertRange(lua_State *L)
Gets the alert range of an asteroid.
static int asteroidL_setTimer(lua_State *L)
Sets the time left on the asteroid.
static int asteroidL_getAll(lua_State *L)
Gets all the asteroids in the system.
int lua_isasteroid(lua_State *L, int ind)
Checks to see if ind is a asteroid.
static int asteroidL_eq(lua_State *L)
Lua bindings to interact with asteroid.
LuaAsteroid_t * luaL_checkasteroid(lua_State *L, int ind)
Gets asteroid at index or raises error if there is no asteroid at index.
static int asteroidL_pos(lua_State *L)
Gets the position of an asteroid.
static int asteroidL_setPos(lua_State *L)
Sets the position of an asteroid.
static int asteroidL_setArmour(lua_State *L)
Sets the armour of the asteroid.
LuaAsteroid_t * lua_pushasteroid(lua_State *L, LuaAsteroid_t asteroid)
Pushes a asteroid on the stack.
Asteroid * luaL_validasteroid(lua_State *L, int ind)
Gets asteroid at index raising an error if type doesn't match.
LuaAsteroid_t * lua_toasteroid(lua_State *L, int ind)
Gets asteroid at index.
static int asteroidL_armour(lua_State *L)
Gets the armour (health) left on the asteroid.
static int asteroidL_timer(lua_State *L)
Gets the time left on the asteroid.
Commodity ** lua_pushcommodity(lua_State *L, Commodity *commodity)
Pushes a commodity on the stack.
Pilot * luaL_validpilot(lua_State *L, int ind)
Makes sure the pilot is valid or raises a Lua error.
Definition nlua_pilot.c:547
int lua_ispilot(lua_State *L, int ind)
Checks to see if ind is a pilot.
Definition nlua_pilot.c:578
int lua_isvector(lua_State *L, int ind)
Checks to see if ind is a vector.
Definition nlua_vec2.c:161
vec2 * luaL_checkvector(lua_State *L, int ind)
Gets vector at index making sure type is valid.
Definition nlua_vec2.c:130
vec2 * lua_tovector(lua_State *L, int ind)
Represents a 2D vector in Lua.
Definition nlua_vec2.c:119
vec2 * lua_pushvector(lua_State *L, vec2 vec)
Pushes a vector on the stack.
Definition nlua_vec2.c:145
StarSystem * cur_system
Definition space.c:106
Represents an asteroid field anchor.
Definition asteroid.h:100
Asteroid * asteroids
Definition asteroid.h:105
Represents a potential reward from the asteroid.
Definition asteroid.h:39
Commodity * material
Definition asteroid.h:40
Represents a type of asteroid.
Definition asteroid.h:48
AsteroidReward * material
Definition asteroid.h:53
Represents a single asteroid.
Definition asteroid.h:77
int id
Definition asteroid.h:79
int state
Definition asteroid.h:81
int parent
Definition asteroid.h:80
Solid solid
Definition pilot.h:227
vec2 pos
Definition physics.h:49
Represents a 2d vector.
Definition vec2.h:32