naev 0.11.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"
15#include "nlua_munition.h"
16
17#include "array.h"
18#include "nlua.h"
19#include "nluadef.h"
20#include "nlua_faction.h"
21#include "nlua_outfit.h"
22#include "nlua_vec2.h"
23#include "nlua_pilot.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 );
43static const luaL_Reg munitionL_methods[] = {
44 /* General. */
45 { "__eq", munitionL_eq },
46 { "__tostring", munitionL_tostring },
47 { "exists", munitionL_exists },
48 { "clear", munitionL_clear },
49 { "getAll", munitionL_getAll },
50 { "getInrange", munitionL_getInrange },
51 /* Get properties. */
52 { "pos", munitionL_pos },
53 { "vel", munitionL_vel },
54 { "faction", munitionL_faction },
55 { "parent", munitionL_parent },
56 { "target", munitionL_target },
57 { "outfit", munitionL_outfit },
58 { "strength", munitionL_strength },
59 /* Set properties. */
60 { "strengthSet", munitionL_strengthSet },
61 /* End sentinal. */
62 {0,0},
63};
71int nlua_loadMunition( nlua_env env )
72{
73 nlua_register(env, MUNITION_METATABLE, munitionL_methods, 1);
74
75 /* Munition always loads ship and asteroid. */
76 nlua_loadOutfit(env);
77
78 return 0;
79}
80
95LuaMunition* lua_tomunition( lua_State *L, int ind )
96{
97 return ((LuaMunition*) lua_touserdata(L,ind));
98}
106LuaMunition* luaL_checkmunition( lua_State *L, int ind )
107{
108 if (lua_ismunition(L,ind))
109 return lua_tomunition(L,ind);
110 luaL_typerror(L, ind, MUNITION_METATABLE);
111 return lua_tomunition(L,ind); /* Just to shut compiler up, shouldn't be reached. */
112}
120Weapon* luaL_validmunition( lua_State *L, int ind )
121{
122 Weapon *w = munition_get( luaL_checkmunition(L,ind) );
123 if (w==NULL) {
124 NLUA_ERROR(L,_("Munition is invalid."));
125 return NULL;
126 }
127 return w;
128}
136LuaMunition* lua_pushmunition( lua_State *L, const Weapon *w )
137{
139 LuaMunition *lm = (LuaMunition*) lua_newuserdata(L, sizeof(LuaMunition));
140 lm->id = w->id;
141 lm->idx = w-weapon_stack;
142 luaL_getmetatable(L, MUNITION_METATABLE);
143 lua_setmetatable(L, -2);
144 return lm;
145}
153int lua_ismunition( lua_State *L, int ind )
154{
155 int ret;
156
157 if (lua_getmetatable(L,ind)==0)
158 return 0;
159 lua_getfield(L, LUA_REGISTRYINDEX, MUNITION_METATABLE);
160
161 ret = 0;
162 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
163 ret = 1;
164
165 lua_pop(L, 2); /* remove both metatables */
166 return ret;
167}
168
179static int munitionL_eq( lua_State *L )
180{
181 const LuaMunition *lm1 = luaL_checkmunition(L,1);
182 const LuaMunition *lm2 = luaL_checkmunition(L,2);
183 lua_pushboolean(L, lm1->id==lm2->id);
184 return 1;
185}
186
187static Weapon *munition_get( LuaMunition *lm )
188{
190 Weapon *w;
191
192 if ((lm->idx < (size_t)array_size(weapon_stack)) && (weapon_stack[lm->idx].id==lm->id))
193 return &weapon_stack[lm->idx];
194
195 w = weapon_getID( lm->id );
196 if (w==NULL)
197 return NULL;
198 lm->idx = w-weapon_stack; /* For next look ups. */
199 return w;
200}
201
211static int munitionL_tostring( lua_State *L )
212{
213 LuaMunition *lm = luaL_checkmunition( L, 1 );
214 Weapon *w = munition_get(lm);
215 if (w!=NULL)
216 lua_pushstring(L,_(w->outfit->name));
217 else
218 lua_pushstring(L,"(inexistent munition)");
219 return 1;
220}
221
229static int munitionL_exists( lua_State *L )
230{
231 LuaMunition *lm = luaL_checkmunition( L, 1 );
232 lua_pushboolean(L, munition_get(lm)!=NULL);
233 return 1;
234}
235
241static int munitionL_clear( lua_State *L )
242{
243 (void) L;
244 weapon_clear();
245 return 0;
246}
247
255static int munitionL_getAll( lua_State *L )
256{
258 int onlyhittable = lua_toboolean(L,1);
259 int n = 1;
260 lua_newtable(L);
261 for (int i=0; i<array_size(weapon_stack); i++) {
262 const Weapon *w = &weapon_stack[i];
263 if (weapon_isFlag(w,WEAPON_FLAG_DESTROYED))
264 continue;
265 if (onlyhittable && !weapon_isFlag(w,WEAPON_FLAG_HITTABLE))
266 continue;
267 lua_pushmunition( L, w );
268 lua_rawseti( L, -2, n++ );
269 }
270 return 1;
271}
272
273static int weapon_isHostile( const Weapon *w, const Pilot *p )
274{
275 if (p->id == w->parent)
276 return 0;
277
278 if ((w->target.type==TARGET_PILOT) && (w->target.u.id==p->id))
279 return 1;
280
281 /* Let hostiles hit player. */
282 if (p->faction == FACTION_PLAYER) {
283 const Pilot *parent = pilot_get(w->parent);
284 if (parent != NULL) {
285 if (pilot_isHostile(parent))
286 return 1;
287 }
288 }
289
290 /* Hit non-allies. */
291 if (areEnemies(w->faction, p->faction))
292 return 1;
293
294 return 0;
295}
296
306static int munitionL_getInrange( lua_State *L )
307{
309 const IntList *qt;
310 int n = 1;
311 const vec2 *pos = luaL_checkvector(L,1);
312 double range = luaL_checknumber(L,2);
313 const Pilot *p = luaL_optpilot(L,3,NULL);
314 double r2 = pow2(range);
315 int x, y, r;
316
317 x = round( pos->x );
318 y = round( pos->y );
319 r = ceil( range );
320
321 lua_newtable(L);
322 qt = weapon_collideQuery( x-r, y-r, x+r, y+r );
323 for (int i=0; i<il_size(qt); i++) {
324 const Weapon *w = &weapon_stack[ il_get(qt, i, 0) ];
325 if (weapon_isFlag(w,WEAPON_FLAG_DESTROYED))
326 continue;
327 if ((p!=NULL) && !weapon_isHostile(w,p))
328 continue;
329 if (vec2_dist2( &w->solid.pos, pos ) > r2 )
330 continue;
331 lua_pushmunition( L, w );
332 lua_rawseti( L, -2, n++ );
333 }
334 return 1;
335}
336
344static int munitionL_pos( lua_State *L )
345{
346 const Weapon *w = luaL_validmunition( L, 1 );
347 lua_pushvector( L, w->solid.pos );
348 return 1;
349}
350
358static int munitionL_vel( lua_State *L )
359{
360 const Weapon *w = luaL_validmunition( L, 1 );
361 lua_pushvector( L, w->solid.vel );
362 return 1;
363}
364
372static int munitionL_faction( lua_State *L )
373{
374 const Weapon *w = luaL_validmunition( L, 1 );
375 lua_pushfaction( L, w->faction );
376 return 1;
377}
378
386static int munitionL_parent( lua_State *L )
387{
388 const Weapon *w = luaL_validmunition( L, 1 );
389 lua_pushpilot( L, w->parent );
390 return 1;
391}
392
400static int munitionL_target( 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_outfit( lua_State *L )
415{
416 const Weapon *w = luaL_validmunition( L, 1 );
417 lua_pushoutfit( L, w->outfit );
418 return 1;
419}
420
431static int munitionL_strength( lua_State *L )
432{
433 const Weapon *w = luaL_validmunition( L, 1 );
434 lua_pushnumber( L, w->strength );
435 return 1;
436}
437
446static int munitionL_strengthSet( lua_State *L )
447{
448 Weapon *w = luaL_validmunition( L, 1 );
449 double sb = w->strength_base;
450 w->strength_base = luaL_checknumber( L, 2 );
451 w->strength *= w->strength_base / sb;
452 return 1;
453}
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
int areEnemies(int a, int b)
Checks whether two factions are enemies.
Definition faction.c:1227
Header file with generic functions and naev-specifics.
#define pow2(x)
Definition naev.h:46
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 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:97
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:563
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:678
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
Definition pilot.c:620
Lua Munition wrapper.
unsigned int id
The representation of an in-game pilot.
Definition pilot.h:217
In-game representation of a weapon.
Definition weapon.h:47
unsigned int id
Definition weapon.h:51
Represents a 2d vector.
Definition vec2.h:32
double y
Definition vec2.h:34
double x
Definition vec2.h:33
Weapon * weapon_getID(unsigned int id)
Gets a weapon by ID.
Definition weapon.c:174
void weapon_clear(void)
Clears all the weapons, does NOT free the layers.
Definition weapon.c:2680
Weapon * weapon_getStack(void)
Gets the weapon stack. Do not manipulate directly.
Definition weapon.c:138
static Weapon * weapon_stack
Definition weapon.c:66