naev 0.12.5
nlua_munition.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
12#include "naev.h"
14
15#include "nlua_munition.h"
16
17#include "array.h"
18#include "nlua.h"
19#include "nlua_faction.h"
20#include "nlua_outfit.h"
21#include "nlua_pilot.h"
22#include "nlua_vec2.h"
23#include "nluadef.h"
24
25/* Prototypes. */
26static Weapon *munition_get( LuaMunition *lm );
27
28/* Munition metatable methods. */
29static int munitionL_eq( lua_State *L );
30static int munitionL_tostring( lua_State *L );
31static int munitionL_exists( lua_State *L );
32static int munitionL_clear( lua_State *L );
33static int munitionL_getAll( lua_State *L );
34static int munitionL_getInrange( lua_State *L );
35static int munitionL_pos( lua_State *L );
36static int munitionL_vel( lua_State *L );
37static int munitionL_faction( lua_State *L );
38static int munitionL_parent( lua_State *L );
39static int munitionL_target( lua_State *L );
40static int munitionL_outfit( lua_State *L );
41static int munitionL_strength( lua_State *L );
42static int munitionL_strengthSet( lua_State *L );
43
44static const luaL_Reg munitionL_methods[] = {
45 /* General. */
46 { "__eq", munitionL_eq },
47 { "__tostring", munitionL_tostring },
48 { "exists", munitionL_exists },
49 { "clear", munitionL_clear },
50 { "getAll", munitionL_getAll },
51 { "getInrange", munitionL_getInrange },
52 /* Get properties. */
53 { "pos", munitionL_pos },
54 { "vel", munitionL_vel },
55 { "faction", munitionL_faction },
56 { "parent", munitionL_parent },
57 { "target", munitionL_target },
58 { "outfit", munitionL_outfit },
59 { "strength", munitionL_strength },
60 /* Set properties. */
61 { "strengthSet", munitionL_strengthSet },
62 /* End sentinal. */
63 { 0, 0 },
64};
65
72int nlua_loadMunition( nlua_env env )
73{
74 nlua_register( env, MUNITION_METATABLE, munitionL_methods, 1 );
75
76 /* Munition always loads ship and asteroid. */
77 nlua_loadOutfit( env );
78
79 return 0;
80}
81
96LuaMunition *lua_tomunition( lua_State *L, int ind )
97{
98 return ( (LuaMunition *)lua_touserdata( L, ind ) );
99}
100
108LuaMunition *luaL_checkmunition( lua_State *L, int ind )
109{
110 if ( lua_ismunition( L, ind ) )
111 return lua_tomunition( L, ind );
112 luaL_typerror( L, ind, MUNITION_METATABLE );
113 return lua_tomunition(
114 L, ind ); /* Just to shut compiler up, shouldn't be reached. */
115}
116
123Weapon *luaL_validmunition( lua_State *L, int ind )
124{
125 Weapon *w = munition_get( luaL_checkmunition( L, ind ) );
126 if ( w == NULL ) {
127 NLUA_ERROR( L, _( "Munition is invalid." ) );
128 return NULL;
129 }
130 return w;
131}
132
139LuaMunition *lua_pushmunition( lua_State *L, const Weapon *w )
140{
142 LuaMunition *lm = (LuaMunition *)lua_newuserdata( L, sizeof( LuaMunition ) );
143 lm->id = w->id;
144 lm->idx = w - weapon_stack;
145 luaL_getmetatable( L, MUNITION_METATABLE );
146 lua_setmetatable( L, -2 );
147 return lm;
148}
149
156int lua_ismunition( lua_State *L, int ind )
157{
158 int ret;
159
160 if ( lua_getmetatable( L, ind ) == 0 )
161 return 0;
162 lua_getfield( L, LUA_REGISTRYINDEX, MUNITION_METATABLE );
163
164 ret = 0;
165 if ( lua_rawequal( L, -1, -2 ) ) /* does it have the correct mt? */
166 ret = 1;
167
168 lua_pop( L, 2 ); /* remove both metatables */
169 return ret;
170}
171
182static int munitionL_eq( lua_State *L )
183{
184 const LuaMunition *lm1 = luaL_checkmunition( L, 1 );
185 const LuaMunition *lm2 = luaL_checkmunition( L, 2 );
186 lua_pushboolean( L, lm1->id == lm2->id );
187 return 1;
188}
189
190static Weapon *munition_get( LuaMunition *lm )
191{
193 Weapon *w;
194
195 if ( ( lm->idx < (size_t)array_size( weapon_stack ) ) &&
196 ( weapon_stack[lm->idx].id == lm->id ) )
197 return &weapon_stack[lm->idx];
198
199 w = weapon_getID( lm->id );
200 if ( w == NULL )
201 return NULL;
202 lm->idx = w - weapon_stack; /* For next look ups. */
203 return w;
204}
205
217static int munitionL_tostring( lua_State *L )
218{
219 LuaMunition *lm = luaL_checkmunition( L, 1 );
220 Weapon *w = munition_get( lm );
221 if ( w != NULL )
222 lua_pushstring( L, _( w->outfit->name ) );
223 else
224 lua_pushstring( L, "(inexistent munition)" );
225 return 1;
226}
227
235static int munitionL_exists( lua_State *L )
236{
237 LuaMunition *lm = luaL_checkmunition( L, 1 );
238 lua_pushboolean( L, munition_get( lm ) != NULL );
239 return 1;
240}
241
247static int munitionL_clear( lua_State *L )
248{
249 (void)L;
250 weapon_clear();
251 return 0;
252}
253
262static int munitionL_getAll( lua_State *L )
263{
265 int onlyhittable = lua_toboolean( L, 1 );
266 int n = 1;
267 lua_newtable( L );
268 for ( int i = 0; i < array_size( weapon_stack ); i++ ) {
269 const Weapon *w = &weapon_stack[i];
270 if ( weapon_isFlag( w, WEAPON_FLAG_DESTROYED ) )
271 continue;
272 if ( onlyhittable && !weapon_isFlag( w, WEAPON_FLAG_HITTABLE ) )
273 continue;
274 lua_pushmunition( L, w );
275 lua_rawseti( L, -2, n++ );
276 }
277 return 1;
278}
279
286static int weapon_isHostile( const Weapon *w, const Pilot *p )
287{
288 if ( p->id == w->parent )
289 return 0;
290
291 if ( ( w->target.type == TARGET_PILOT ) && ( w->target.u.id == p->id ) )
292 return 1;
293
294 /* Let hostiles hit player. */
295 if ( p->faction == FACTION_PLAYER ) {
296 const Pilot *parent = pilot_get( w->parent );
297 if ( parent != NULL ) {
298 if ( pilot_isHostile( parent ) )
299 return 1;
300 }
301 }
302
303 /* Hit non-allies. */
304 if ( areEnemies( w->faction, p->faction ) )
305 return 1;
306
307 return 0;
308}
309
320static int munitionL_getInrange( lua_State *L )
321{
323 const IntList *qt;
324 int n = 1;
325 const vec2 *pos = luaL_checkvector( L, 1 );
326 double range = luaL_checknumber( L, 2 );
327 const Pilot *p = luaL_optpilot( L, 3, NULL );
328 double r2 = pow2( range );
329 int x, y, r;
330
331 x = round( pos->x );
332 y = round( pos->y );
333 r = ceil( range );
334
335 lua_newtable( L );
336 qt = weapon_collideQuery( x - r, y - r, x + r, y + r );
337 for ( int i = 0; i < il_size( qt ); i++ ) {
338 const Weapon *w = &weapon_stack[il_get( qt, i, 0 )];
339 if ( weapon_isFlag( w, WEAPON_FLAG_DESTROYED ) )
340 continue;
341 if ( ( p != NULL ) && !weapon_isHostile( w, p ) )
342 continue;
343 if ( vec2_dist2( &w->solid.pos, pos ) > r2 )
344 continue;
345 lua_pushmunition( L, w );
346 lua_rawseti( L, -2, n++ );
347 }
348 return 1;
349}
350
358static int munitionL_pos( lua_State *L )
359{
360 const Weapon *w = luaL_validmunition( L, 1 );
361 lua_pushvector( L, w->solid.pos );
362 return 1;
363}
364
372static int munitionL_vel( lua_State *L )
373{
374 const Weapon *w = luaL_validmunition( L, 1 );
375 lua_pushvector( L, w->solid.vel );
376 return 1;
377}
378
386static int munitionL_faction( lua_State *L )
387{
388 const Weapon *w = luaL_validmunition( L, 1 );
389 lua_pushfaction( L, w->faction );
390 return 1;
391}
392
400static int munitionL_parent( lua_State *L )
401{
402 const Weapon *w = luaL_validmunition( L, 1 );
403 lua_pushpilot( L, w->parent );
404 return 1;
405}
406
414static int munitionL_target( lua_State *L )
415{
416 const Weapon *w = luaL_validmunition( L, 1 );
417 lua_pushpilot( L, w->parent );
418 return 1;
419}
420
428static int munitionL_outfit( lua_State *L )
429{
430 const Weapon *w = luaL_validmunition( L, 1 );
431 lua_pushoutfit( L, w->outfit );
432 return 1;
433}
434
447static int munitionL_strength( lua_State *L )
448{
449 const Weapon *w = luaL_validmunition( L, 1 );
450 lua_pushnumber( L, w->strength );
451 return 1;
452}
453
463static int munitionL_strengthSet( lua_State *L )
464{
465 Weapon *w = luaL_validmunition( L, 1 );
466 double sb = w->strength_base;
467 w->strength_base = luaL_checknumber( L, 2 );
468 w->strength *= w->strength_base / sb;
469 return 1;
470}
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:179
int areEnemies(int a, int b)
Checks whether two factions are enemies.
Definition faction.c:1450
Header file with generic functions and naev-specifics.
#define pow2(x)
Definition naev.h:53
LuaFaction * lua_pushfaction(lua_State *L, LuaFaction faction)
Pushes a faction on the stack.
int nlua_loadMunition(nlua_env env)
Loads the munition library.
static int munitionL_exists(lua_State *L)
Checks to see if a munition still exists.
static int munitionL_getAll(lua_State *L)
Gets all the munitions in the system.
int lua_ismunition(lua_State *L, int ind)
Checks to see if ind is a munition.
LuaMunition * lua_tomunition(lua_State *L, int ind)
Lua bindings to interact with munitions.
static int munitionL_pos(lua_State *L)
Gets the position of the munition.
static int munitionL_strengthSet(lua_State *L)
Sets the strength of a munition.
LuaMunition * luaL_checkmunition(lua_State *L, int ind)
Gets munition at index or raises error if there is no munition at index.
static int munitionL_target(lua_State *L)
Gets the target of the munition.
static const luaL_Reg munitionL_methods[]
static int weapon_isHostile(const Weapon *w, const Pilot *p)
Sees if a weapon is hostile to a pilot or not.
static int munitionL_getInrange(lua_State *L)
Get munitions in range. Note that this can only get hittable munitions.
static int munitionL_outfit(lua_State *L)
Gets the outfit corresponding to the munition.
static int munitionL_parent(lua_State *L)
Gets the parent of the munition.
static int munitionL_tostring(lua_State *L)
Gets the munition's current (translated) name or notes it is inexistent.
static int munitionL_eq(lua_State *L)
Checks to see if munition and p are the same.
static int munitionL_strength(lua_State *L)
Gets the strength of a munition.
static int munitionL_clear(lua_State *L)
Clears all the munitions in the system.
Weapon * luaL_validmunition(lua_State *L, int ind)
Makes sure the munition is valid or raises a Lua error.
static int munitionL_faction(lua_State *L)
Gets the faction of the munition.
LuaMunition * lua_pushmunition(lua_State *L, const Weapon *w)
Pushes a weapon as a munition on the stack.
static int munitionL_vel(lua_State *L)
Gets the velocity of the munition.
int nlua_loadOutfit(nlua_env env)
Loads the outfit library.
Definition nlua_outfit.c:99
const Outfit ** lua_pushoutfit(lua_State *L, const Outfit *outfit)
Pushes a outfit on the stack.
LuaPilot * lua_pushpilot(lua_State *L, LuaPilot pilot)
Pushes a pilot on the stack.
Definition nlua_pilot.c:576
vec2 * luaL_checkvector(lua_State *L, int ind)
Gets vector at index making sure type is valid.
Definition nlua_vec2.c:130
vec2 * lua_pushvector(lua_State *L, vec2 vec)
Pushes a vector on the stack.
Definition nlua_vec2.c:145
int pilot_isHostile(const Pilot *p)
Checks to see if pilot is hostile to the player.
Definition pilot.c:699
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
Definition pilot.c:640
Lua Munition wrapper.
unsigned int id
The representation of an in-game pilot.
Definition pilot.h:263
In-game representation of a weapon.
Definition weapon.h:48
Represents a 2d vector.
Definition vec2.h:45
double y
Definition vec2.h:47
double x
Definition vec2.h:46
Weapon * weapon_getID(unsigned int id)
Gets a weapon by ID.
Definition weapon.c:190
void weapon_clear(void)
Clears all the weapons, does NOT free the layers.
Definition weapon.c:2849
Weapon * weapon_getStack(void)
Gets the weapon stack. Do not manipulate directly.
Definition weapon.c:154
static Weapon * weapon_stack
Definition weapon.c:72