naev 0.10.4
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 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#endif /* DEBUGGING */
118 AsteroidAnchor *field = &cur_system->asteroids[ la->parent ];
119#if DEBUGGING
120 if ((la->id < 0) || (la->id >= field->nb))
121 NLUA_ERROR(L,_("Asteroid '%d' in field '%d' is out of range!"),la->id,la->parent);
122#endif /* DEBUGGING */
123 a = &field->asteroids[ la->id ];
124 }
125 else {
126 luaL_typerror(L, ind, ASTEROID_METATABLE);
127 return NULL;
128 }
129
130 if (a == NULL)
131 NLUA_ERROR(L, _("Asteroid is invalid"));
132
133 return a;
134}
143{
144 LuaAsteroid_t *la = (LuaAsteroid_t*) lua_newuserdata(L, sizeof(LuaAsteroid_t));
145 *la = asteroid;
146 luaL_getmetatable(L, ASTEROID_METATABLE);
147 lua_setmetatable(L, -2);
148 return la;
149}
157int lua_isasteroid( lua_State *L, int ind )
158{
159 int ret;
160
161 if (lua_getmetatable(L,ind)==0)
162 return 0;
163 lua_getfield(L, LUA_REGISTRYINDEX, ASTEROID_METATABLE);
164
165 ret = 0;
166 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
167 ret = 1;
168
169 lua_pop(L, 2); /* remove both metatables */
170 return ret;
171}
172
187static int asteroidL_eq( lua_State *L )
188{
189 LuaAsteroid_t *a1, *a2;
190 a1 = luaL_checkasteroid(L,1);
191 a2 = luaL_checkasteroid(L,2);
192 lua_pushboolean( L, (memcmp( a1, a2, sizeof(LuaAsteroid_t) )==0) );
193 return 1;
194}
195
202static int asteroidL_getAll( lua_State *L )
203{
204 int n = 1;
205 lua_newtable(L);
206 for (int i=0; i<array_size(cur_system->asteroids); i++) {
207 AsteroidAnchor *ast = &cur_system->asteroids[i];
208 for (int j=0; j<ast->nb; j++) {
209 Asteroid *a = &ast->asteroids[j];
210 LuaAsteroid_t la = {
211 .parent = a->parent,
212 .id = a->id,
213 };
214
215 lua_pushasteroid( L, la );
216 lua_rawseti( L, -2, n++ );
217 }
218 }
219
220 return 1;
221}
222
230static int asteroidL_get( lua_State *L )
231{
232 LuaAsteroid_t la;
233 int field = -1;
234 const vec2 *pos = NULL;
235
236 /* No asteroids, so everything just returns nil. */
237 if (array_size(cur_system->asteroids) <= 0)
238 return 0;
239
240 if (lua_isvector(L,1))
241 pos = lua_tovector(L,1);
242
243 else if (lua_ispilot(L,1))
244 pos = &luaL_validpilot(L,1)->solid->pos;
245
246 else if (lua_isnoneornil(L,1)) {
247 int max_field = array_size(cur_system->asteroids) - 1;
248 field = (max_field < 0 ? max_field : RNG(0, max_field));
249 }
250 else if (lua_isnumber(L,1)) {
251 field = luaL_checkinteger(L,1)-1;
252 if ((field < 0) || (field >= array_size(cur_system->asteroids)))
253 NLUA_INVALID_PARAMETER(L);
254 }
255 else
256 NLUA_INVALID_PARAMETER(L);
257
258 /* Get random asteroid. */
259 if ((pos==NULL) && (field >= 0)) {
260 /* Random asteroid. */
261 int ast = RNG(0,cur_system->asteroids[field].nb-1);
262 int bad_asteroid = 0;
263 Asteroid *a = &cur_system->asteroids[field].asteroids[ast];
264
265 if (a->state != ASTEROID_FG) {
266 /* Switch to next index until we find a valid one, or until we come full-circle. */
267 bad_asteroid = 1;
268 for (int i=0; i<cur_system->asteroids[field].nb; i++) {
269 ast = (ast+1) % cur_system->asteroids[field].nb;
270 a = &cur_system->asteroids[field].asteroids[ast];
271 if (a->state == ASTEROID_FG) {
272 bad_asteroid = 0;
273 break;
274 }
275 }
276 }
277
278 if (bad_asteroid)
279 return 0;
280
281 la.parent = field;
282 la.id = ast;
283 lua_pushasteroid(L,la);
284 return 1;
285 }
286
287 /* Try to find nearest asteroid. */
288 Asteroid *a_closest = NULL;
289 double dist2 = HUGE_VAL;
290 for (int i=0; i<array_size(cur_system->asteroids); i++) {
291 AsteroidAnchor *ast = &cur_system->asteroids[i];
292 for (int j=0; j<ast->nb; j++) {
293 double d2;
294 Asteroid *a = &ast->asteroids[j];
295
296 if (a->state != ASTEROID_FG)
297 continue;
298
299 d2 = vec2_dist2( pos, &a->pos );
300 if (d2 > dist2)
301 continue;
302
303 a_closest = a;
304 dist2 = d2;
305 }
306 }
307 if (a_closest==NULL)
308 return 0;
309
310 /* Got an asteroid, ship it. */
311 la.parent = a_closest->parent;
312 la.id = a_closest->id;
313 lua_pushasteroid(L,la);
314 return 1;
315}
316
324static int asteroidL_exists( lua_State *L )
325{
326 if (!lua_isasteroid(L, 1)) {
327 lua_pushboolean(L, 0);
328 return 1;
329 }
330
332 if ((la->parent < 0) || (la->parent >= array_size(cur_system->asteroids))) {
333 lua_pushboolean(L, 0);
334 return 1;
335 }
336
337 AsteroidAnchor *field = &cur_system->asteroids[ la->parent ];
338 if ((la->id < 0) || (la->id >= field->nb)) {
339 lua_pushboolean(L, 0);
340 return 1;
341 }
342
343 Asteroid *a = &field->asteroids[ la->id ];
344 lua_pushboolean(L, (a->state==ASTEROID_FG));
345 return 1;
346}
347
355static int asteroidL_state( lua_State *L )
356{
357 Asteroid *ast = luaL_validasteroid(L,1);
358 const char *state = NULL;
359 switch (ast->state) {
360 case ASTEROID_FG:
361 state = "FG";
362 break;
363 case ASTEROID_XB:
364 state = "XB";
365 break;
366 case ASTEROID_BX:
367 state = "BX";
368 break;
369 case ASTEROID_XX_TO_BG:
370 state = "XX_TO_BG";
371 break;
372 case ASTEROID_FG_TO_BG:
373 state = "FG_TO_BG";
374 break;
375 case ASTEROID_BG_TO_FG:
376 state = "BG_TO_FG";
377 break;
378 case ASTEROID_BG_TO_XX:
379 state = "BG_TO_XX";
380 break;
381 case ASTEROID_XX:
382 state = "XX";
383 break;
384 }
385 lua_pushstring( L, state );
386 return 1;
387}
388
396static int asteroidL_setState( lua_State *L )
397{
398 Asteroid *ast = luaL_validasteroid(L,1);
399 const char *state = luaL_checkstring(L,2);
400 if (strcmp(state,"FG")==0)
401 ast->state = ASTEROID_FG;
402 else if (strcmp(state,"XB")==0)
403 ast->state = ASTEROID_XB;
404 else if (strcmp(state,"BX")==0)
405 ast->state = ASTEROID_BX;
406 else if (strcmp(state,"XX_TO_BG")==0)
407 ast->state = ASTEROID_XX_TO_BG;
408 else if (strcmp(state,"FG_TO_BG")==0)
409 ast->state = ASTEROID_FG_TO_BG;
410 else if (strcmp(state,"BG_TO_FG")==0)
411 ast->state = ASTEROID_BG_TO_FG;
412 else if (strcmp(state,"BG_TO_XX")==0)
413 ast->state = ASTEROID_BG_TO_XX;
414 else if (strcmp(state,"XX")==0)
415 ast->state = ASTEROID_XX;
416 else
417 NLUA_INVALID_PARAMETER(L);
418 return 0;
419}
420
428static int asteroidL_field( lua_State *L )
429{
431 lua_pushinteger(L,la->parent+1);
432 return 1;
433}
434
442static int asteroidL_pos( lua_State *L )
443{
445 lua_pushvector(L,a->pos);
446 return 1;
447}
448
456static int asteroidL_vel( lua_State *L )
457{
459 lua_pushvector(L,a->vel);
460 return 1;
461}
462
470static int asteroidL_setPos( lua_State *L )
471{
473 vec2 *v = luaL_checkvector(L,2);
474 a->pos = *v;
475 return 0;
476}
477
485static int asteroidL_setVel( lua_State *L )
486{
488 vec2 *v = luaL_checkvector(L,2);
489 a->vel = *v;
490 return 0;
491}
492
500static int asteroidL_scanned( lua_State *L )
501{
503 lua_pushboolean(L,a->scanned);
504 return 1;
505}
506
515static int asteroidL_timer( lua_State *L )
516{
518 lua_pushnumber(L,a->timer);
519 lua_pushnumber(L,a->timer_max);
520 return 2;
521}
522
530static int asteroidL_setTimer( lua_State *L )
531{
533 a->timer = luaL_checknumber(L,2);
534 a->timer_max = MAX( a->timer_max, a->timer );
535 return 0;
536}
537
545static int asteroidL_armour( lua_State *L )
546{
548 lua_pushnumber(L,a->armour);
549 return 1;
550}
551
559static int asteroidL_setArmour( lua_State *L )
560{
562 a->armour = luaL_checknumber(L,2);
563 if (a->armour <= 0.)
564 asteroid_explode( a, -1, 0. );
565 return 0;
566}
567
575static int asteroidL_alertRange( lua_State *L )
576{
578 lua_pushnumber(L,a->type->alert_range);
579 return 1;
580}
581
589static int asteroidL_materials( lua_State *L )
590{
592 const AsteroidType *at = a->type;
593
594 lua_newtable(L);
595 for (int i=0; i<array_size(at->material); i++) {
596 const AsteroidReward *mat = &at->material[i];
597 lua_newtable(L);
598
599 lua_pushcommodity( L, mat->material );
600 lua_setfield(L,-2,"commodity");
601
602 lua_pushnumber( L, mat->quantity );
603 lua_setfield(L,-2,"quantity");
604
605 lua_pushnumber( L, mat->rarity );
606 lua_setfield(L,-2,"rarity");
607
608 lua_rawseti( L, -2, i+1 );
609 }
610
611 return 1;
612}
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:1049
Header file with generic functions and naev-specifics.
#define MAX(x, y)
Definition: naev.h:39
static const luaL_Reg asteroidL_methods[]
Definition: nlua_asteroid.c:43
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.
Definition: nlua_asteroid.c:71
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.
Definition: nlua_asteroid.c:95
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.
Definition: nlua_asteroid.c:84
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:478
int lua_ispilot(lua_State *L, int ind)
Checks to see if ind is a pilot.
Definition: nlua_pilot.c:510
int lua_isvector(lua_State *L, int ind)
Checks to see if ind is a vector.
Definition: nlua_vec2.c:155
vec2 * luaL_checkvector(lua_State *L, int ind)
Gets vector at index making sure type is valid.
Definition: nlua_vec2.c:124
vec2 * lua_tovector(lua_State *L, int ind)
Represents a 2D vector in Lua.
Definition: nlua_vec2.c:113
vec2 * lua_pushvector(lua_State *L, vec2 vec)
Pushes a vector on the stack.
Definition: nlua_vec2.c:139
static const double a[]
Definition: rng.c:247
StarSystem * cur_system
Definition: space.c:105
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:38
Commodity * material
Definition: asteroid.h:39
Represents a type of asteroid.
Definition: asteroid.h:47
AsteroidReward * material
Definition: asteroid.h:52
Represents a single asteroid.
Definition: asteroid.h:76
int id
Definition: asteroid.h:78
int state
Definition: asteroid.h:80
int parent
Definition: asteroid.h:79
Solid * solid
Definition: pilot.h:220
vec2 pos
Definition: physics.h:22
Represents a 2d vector.
Definition: vec2.h:32