naev 0.11.5
nlua_pilot.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_pilot.h"
16
17#include "ai.h"
18#include "array.h"
19#include "camera.h"
20#include "damagetype.h"
21#include "debug.h"
22#include "escort.h"
23#include "gui.h"
24#include "land_outfits.h"
25#include "log.h"
26#include "map.h"
27#include "nlua.h"
28#include "nlua_asteroid.h"
29#include "nlua_canvas.h"
30#include "nlua_colour.h"
31#include "nlua_gfx.h"
32#include "nlua_commodity.h"
33#include "nlua_faction.h"
34#include "nlua_jump.h"
35#include "nlua_pilotoutfit.h"
36#include "nlua_outfit.h"
37#include "nlua_spob.h"
38#include "nlua_ship.h"
39#include "nlua_system.h"
40#include "nlua_vec2.h"
41#include "nlua_tex.h"
42#include "nluadef.h"
43#include "pilot.h"
44#include "pilot_heat.h"
45#include "player.h"
46#include "rng.h"
47#include "space.h"
48#include "start.h"
49#include "weapon.h"
50
51/*
52 * From ai.c
53 */
54extern Pilot *cur_pilot;
55
56/*
57 * Prototypes.
58 */
59static int pilotL_getFriendOrFoe( lua_State *L, int friend );
60static Task *pilotL_newtask( lua_State *L, Pilot* p, const char *task );
61static int outfit_compareActive( const void *slot1, const void *slot2 );
62static int pilotL_setFlagWrapper( lua_State *L, int flag );
63static int pilot_outfitAddSlot( Pilot *p, const Outfit *o, PilotOutfitSlot *s, int bypass_cpu, int bypass_slot );
64static int luaL_checkweapset( lua_State *L, int idx );
65static PilotOutfitSlot *luaL_checkslot( lua_State *L, Pilot *p, int idx );
66
67/* Pilot metatable methods. */
68static int pilotL_add( lua_State *L );
69static int pilotL_clone( lua_State *L );
70static int pilotL_remove( lua_State *L );
71static int pilotL_explode( lua_State *L );
72static int pilotL_clear( lua_State *L );
73static int pilotL_clearSelect( lua_State *L );
74static int pilotL_canSpawn( lua_State *L );
75static int pilotL_toggleSpawn( lua_State *L );
76static int pilotL_getPilots( lua_State *L );
77static int pilotL_getAllies( lua_State *L );
78static int pilotL_getEnemies( lua_State *L );
79static int pilotL_getVisible( lua_State *L );
80static int pilotL_getInrange( lua_State *L );
81static int pilotL_eq( lua_State *L );
82static int pilotL_tostring( lua_State *L );
83static int pilotL_name( lua_State *L );
84static int pilotL_id( lua_State *L );
85static int pilotL_exists( lua_State *L );
86static int pilotL_target( lua_State *L );
87static int pilotL_setTarget( lua_State *L );
88static int pilotL_targetAsteroid( lua_State *L );
89static int pilotL_setTargetAsteroid( lua_State *L );
90static int pilotL_inrange( lua_State *L );
91static int pilotL_scandone( lua_State *L );
92static int pilotL_withPlayer( lua_State *L );
93static int pilotL_nav( lua_State *L );
94static int pilotL_navSpob( lua_State *L );
95static int pilotL_navJump( lua_State *L );
96static int pilotL_navJumpSet( lua_State *L );
97static int pilotL_weapsetActive( lua_State *L );
98static int pilotL_weapsetSetActive( lua_State *L );
99static int pilotL_weapset( lua_State *L );
100static int pilotL_weapsetList( lua_State *L );
101static int pilotL_weapsetType( lua_State *L );
102static int pilotL_weapsetAdd( lua_State *L );
103static int pilotL_weapsetAddType( lua_State *L );
104static int pilotL_weapsetRm( lua_State *L );
105static int pilotL_weapsetCleanup( lua_State *L );
106static int pilotL_weapsetHeat( lua_State *L );
107static int pilotL_weapsetSetInrange( lua_State *L );
108static int pilotL_weapsetAmmo( lua_State *L );
109static int pilotL_actives( lua_State *L );
110static int pilotL_outfitsList( lua_State *L );
111static int pilotL_outfits( lua_State *L );
112static int pilotL_outfitsEquip( lua_State *L );
113static int pilotL_outfitGet( lua_State *L );
114static int pilotL_outfitToggle( lua_State *L );
115static int pilotL_outfitReady( lua_State *L );
116static int pilotL_rename( lua_State *L );
117static int pilotL_position( lua_State *L );
118static int pilotL_velocity( lua_State *L );
119static int pilotL_isStopped( lua_State *L );
120static int pilotL_dir( lua_State *L );
121static int pilotL_signature( lua_State *L );
122static int pilotL_temp( lua_State *L );
123static int pilotL_mass( lua_State *L );
124static int pilotL_accel( lua_State *L );
125static int pilotL_speed( lua_State *L );
126static int pilotL_speed_max( lua_State *L );
127static int pilotL_turn( lua_State *L );
128static int pilotL_faction( lua_State *L );
129static int pilotL_areEnemies( lua_State *L );
130static int pilotL_areAllies( lua_State *L );
131static int pilotL_spaceworthy( lua_State *L );
132static int pilotL_setPosition( lua_State *L );
133static int pilotL_setVelocity( lua_State *L );
134static int pilotL_setDir( lua_State *L );
135static int pilotL_broadcast( lua_State *L );
136static int pilotL_comm( lua_State *L );
137static int pilotL_setFaction( lua_State *L );
138static int pilotL_setHostile( lua_State *L );
139static int pilotL_setFriendly( lua_State *L );
140static int pilotL_setInvincible( lua_State *L );
141static int pilotL_setInvincPlayer( lua_State *L );
142static int pilotL_setHide( lua_State *L );
143static int pilotL_setInvisible( lua_State *L );
144static int pilotL_setNoRender( lua_State *L );
145static int pilotL_setVisplayer( lua_State *L );
146static int pilotL_setVisible( lua_State *L );
147static int pilotL_setHilight( lua_State *L );
148static int pilotL_setBribed( lua_State *L );
149static int pilotL_getColour( lua_State *L );
150static int pilotL_colourChar( lua_State *L );
151static int pilotL_getHostile( lua_State *L );
152static int pilotL_flags( lua_State *L );
153static int pilotL_hasIllegal( lua_State *L );
154static int pilotL_setActiveBoard( lua_State *L );
155static int pilotL_setNoDeath( lua_State *L );
156static int pilotL_disable( lua_State *L );
157static int pilotL_cooldown( lua_State *L );
158static int pilotL_setCooldown( lua_State *L );
159static int pilotL_cooldownCycle( lua_State *L );
160static int pilotL_setNoJump( lua_State *L );
161static int pilotL_setNoLand( lua_State *L );
162static int pilotL_setNoClear( lua_State *L );
163static int pilotL_outfitAdd( lua_State *L );
164static int pilotL_outfitRm( lua_State *L );
165static int pilotL_outfitSlot( lua_State *L );
166static int pilotL_outfitAddSlot( lua_State *L );
167static int pilotL_outfitRmSlot( lua_State *L );
168static int pilotL_outfitAddIntrinsic( lua_State *L );
169static int pilotL_outfitRmIntrinsic( lua_State *L );
170static int pilotL_getFuel( lua_State *L );
171static int pilotL_setFuel( lua_State *L );
172static int pilotL_intrinsicReset( lua_State *L );
173static int pilotL_intrinsicSet( lua_State *L );
174static int pilotL_intrinsicGet( lua_State *L );
175static int pilotL_shippropReset( lua_State *L );
176static int pilotL_shippropSet( lua_State *L );
177static int pilotL_shippropGet( lua_State *L );
178static int pilotL_effectClear( lua_State *L );
179static int pilotL_effectAdd( lua_State *L );
180static int pilotL_effectRm( lua_State *L );
181static int pilotL_effectGet( lua_State *L );
182static int pilotL_ai( lua_State *L );
183static int pilotL_changeAI( lua_State *L );
184static int pilotL_setTemp( lua_State *L );
185static int pilotL_setHealth( lua_State *L );
186static int pilotL_setHealthAbs( lua_State *L );
187static int pilotL_addHealth( lua_State *L );
188static int pilotL_setEnergy( lua_State *L );
189static int pilotL_addEnergy( lua_State *L );
190static int pilotL_fillAmmo( lua_State *L );
191static int pilotL_setNoBoard( lua_State *L );
192static int pilotL_setNoDisable( lua_State *L );
193static int pilotL_setSpeedLimit( lua_State *L);
194static int pilotL_getHealth( lua_State *L );
195static int pilotL_getArmour( lua_State *L );
196static int pilotL_getShield( lua_State *L );
197static int pilotL_getEnergy( lua_State *L );
198static int pilotL_getLockon( lua_State *L );
199static int pilotL_getStats( lua_State *L );
200static int pilotL_getShipStat( lua_State *L );
201static int pilotL_getDetectedDistance( lua_State *L );
202static int pilotL_cargoFree( lua_State *L );
203static int pilotL_cargoHas( lua_State *L );
204static int pilotL_cargoAdd( lua_State *L );
205static int pilotL_cargoRm( lua_State *L );
206static int pilotL_cargoJet( lua_State *L );
207static int pilotL_cargoList( lua_State *L );
208static int pilotL_credits( lua_State *L );
209static int pilotL_worth( lua_State *L );
210static int pilotL_ship( lua_State *L );
211static int pilotL_points( lua_State *L );
212static int pilotL_radius( lua_State *L );
213static int pilotL_idle( lua_State *L );
214static int pilotL_control( lua_State *L );
215static int pilotL_memory( lua_State *L );
216static int pilotL_shipmemory( lua_State *L );
217static int pilotL_ainame( lua_State *L );
218static int pilotL_task( lua_State *L );
219static int pilotL_taskname( lua_State *L );
220static int pilotL_taskstack( lua_State *L );
221static int pilotL_taskdata( lua_State *L );
222static int pilotL_taskclear( lua_State *L );
223static int pilotL_pushtask( lua_State *L );
224static int pilotL_poptask( lua_State *L );
225static int pilotL_refuel( lua_State *L );
226static int pilotL_moveto( lua_State *L );
227static int pilotL_face( lua_State *L );
228static int pilotL_brake( lua_State *L );
229static int pilotL_follow( lua_State *L );
230static int pilotL_attack( lua_State *L );
231static int pilotL_board( lua_State *L );
232static int pilotL_runaway( lua_State *L );
233static int pilotL_gather( lua_State *L );
234static int pilotL_canHyperspace( lua_State *L );
235static int pilotL_hyperspace( lua_State *L );
236static int pilotL_stealth( lua_State *L );
237static int pilotL_tryStealth( lua_State *L );
238static int pilotL_land( lua_State *L );
239static int pilotL_hailPlayer( lua_State *L );
240static int pilotL_msg( lua_State *L );
241static int pilotL_mothership( lua_State *L );
242static int pilotL_leader( lua_State *L );
243static int pilotL_setLeader( lua_State *L );
244static int pilotL_followers( lua_State *L );
245static int pilotL_hookClear( lua_State *L );
246static int pilotL_choosePoint( lua_State *L );
247static int pilotL_collisionTest( lua_State *L );
248static int pilotL_damage( lua_State *L );
249static int pilotL_kill( lua_State *L );
250static int pilotL_knockback( lua_State *L );
251static int pilotL_calcStats( lua_State *L );
252static int pilotL_showEmitters( lua_State *L );
253static int pilotL_shipvarPeek( lua_State *L );
254static int pilotL_shipvarPush( lua_State *L );
255static int pilotL_shipvarPop( lua_State *L );
256static int pilotL_render( lua_State *L );
257static int pilotL_renderTo( lua_State *L );
258static const luaL_Reg pilotL_methods[] = {
259 /* General. */
260 { "add", pilotL_add },
261 { "clone", pilotL_clone },
262 { "rm", pilotL_remove },
263 { "explode", pilotL_explode },
264 { "get", pilotL_getPilots },
265 { "getAllies", pilotL_getAllies },
266 { "getEnemies", pilotL_getEnemies },
267 { "getVisible", pilotL_getVisible },
268 { "getInrange", pilotL_getInrange },
269 { "__eq", pilotL_eq },
270 { "__tostring", pilotL_tostring },
271 /* Info. */
272 { "name", pilotL_name },
273 { "id", pilotL_id },
274 { "exists", pilotL_exists },
275 { "target", pilotL_target },
276 { "setTarget", pilotL_setTarget },
277 { "targetAsteroid", pilotL_targetAsteroid },
278 { "setTargetAsteroid", pilotL_setTargetAsteroid },
279 { "inrange", pilotL_inrange },
280 { "scandone", pilotL_scandone },
281 { "withPlayer", pilotL_withPlayer },
282 { "nav", pilotL_nav },
283 { "navSpob", pilotL_navSpob },
284 { "navJump", pilotL_navJump },
285 { "navJumpSet", pilotL_navJumpSet },
286 { "weapsetActive", pilotL_weapsetActive },
287 { "weapsetSetActive", pilotL_weapsetSetActive },
288 { "weapset", pilotL_weapset },
289 { "weapsetList", pilotL_weapsetList },
290 { "weapsetType", pilotL_weapsetType },
291 { "weapsetAdd", pilotL_weapsetAdd },
292 { "weapsetAddType", pilotL_weapsetAddType },
293 { "weapsetRm", pilotL_weapsetRm },
294 { "weapsetCleanup", pilotL_weapsetCleanup },
295 { "weapsetHeat", pilotL_weapsetHeat },
296 { "weapsetSetInrange", pilotL_weapsetSetInrange },
297 { "weapsetAmmo", pilotL_weapsetAmmo },
298 { "actives", pilotL_actives },
299 { "outfitsList", pilotL_outfitsList },
300 { "outfits", pilotL_outfits },
301 { "outfitsEquip", pilotL_outfitsEquip },
302 { "outfitGet", pilotL_outfitGet },
303 { "outfitToggle", pilotL_outfitToggle },
304 { "outfitReady", pilotL_outfitReady },
305 { "rename", pilotL_rename },
306 { "pos", pilotL_position },
307 { "vel", pilotL_velocity },
308 { "isStopped", pilotL_isStopped },
309 { "dir", pilotL_dir },
310 { "signature", pilotL_signature },
311 { "temp", pilotL_temp },
312 { "mass", pilotL_mass },
313 { "accel", pilotL_accel },
314 { "speed", pilotL_speed },
315 { "speedMax", pilotL_speed_max },
316 { "turn", pilotL_turn },
317 { "cooldown", pilotL_cooldown },
318 { "faction", pilotL_faction },
319 { "areEnemies", pilotL_areEnemies },
320 { "areAllies", pilotL_areAllies },
321 { "spaceworthy", pilotL_spaceworthy },
322 { "health", pilotL_getHealth },
323 { "armour", pilotL_getArmour },
324 { "shield", pilotL_getShield },
325 { "energy", pilotL_getEnergy },
326 { "lockon", pilotL_getLockon },
327 { "stats", pilotL_getStats },
328 { "shipstat", pilotL_getShipStat },
329 { "detectedDistance", pilotL_getDetectedDistance },
330 { "colour", pilotL_getColour },
331 { "colourChar", pilotL_colourChar },
332 { "hostile", pilotL_getHostile },
333 { "flags", pilotL_flags },
334 { "hasIllegal", pilotL_hasIllegal },
335 /* System. */
336 { "clear", pilotL_clear },
337 { "clearSelect", pilotL_clearSelect },
338 { "canSpawn", pilotL_canSpawn },
339 { "toggleSpawn", pilotL_toggleSpawn },
340 /* Modify. */
341 { "ai", pilotL_ai },
342 { "changeAI", pilotL_changeAI },
343 { "setTemp", pilotL_setTemp },
344 { "setHealth", pilotL_setHealth },
345 { "setHealthAbs", pilotL_setHealthAbs },
346 { "addHealth", pilotL_addHealth },
347 { "setEnergy", pilotL_setEnergy },
348 { "addEnergy", pilotL_addEnergy },
349 { "fillAmmo", pilotL_fillAmmo },
350 { "setNoBoard", pilotL_setNoBoard },
351 { "setNoDisable", pilotL_setNoDisable },
352 { "setSpeedLimit", pilotL_setSpeedLimit },
353 { "setPos", pilotL_setPosition },
354 { "setVel", pilotL_setVelocity },
355 { "setDir", pilotL_setDir },
356 { "setFaction", pilotL_setFaction },
357 { "setHostile", pilotL_setHostile },
358 { "setFriendly", pilotL_setFriendly },
359 { "setInvincible", pilotL_setInvincible },
360 { "setInvincPlayer", pilotL_setInvincPlayer },
361 { "setHide", pilotL_setHide },
362 { "setInvisible", pilotL_setInvisible },
363 { "setNoRender", pilotL_setNoRender },
364 { "setVisplayer", pilotL_setVisplayer },
365 { "setVisible", pilotL_setVisible },
366 { "setHilight", pilotL_setHilight },
367 { "setBribed", pilotL_setBribed },
368 { "setActiveBoard", pilotL_setActiveBoard },
369 { "setNoDeath", pilotL_setNoDeath },
370 { "disable", pilotL_disable },
371 { "setCooldown", pilotL_setCooldown },
372 { "cooldownCycle", pilotL_cooldownCycle },
373 { "setNoJump", pilotL_setNoJump },
374 { "setNoLand", pilotL_setNoLand },
375 { "setNoClear", pilotL_setNoClear },
376 /* Talk. */
377 { "broadcast", pilotL_broadcast },
378 { "comm", pilotL_comm },
379 /* Outfits. */
380 { "outfitAdd", pilotL_outfitAdd },
381 { "outfitRm", pilotL_outfitRm },
382 { "outfitSlot", pilotL_outfitSlot },
383 { "outfitAddSlot", pilotL_outfitAddSlot },
384 { "outfitRmSlot", pilotL_outfitRmSlot },
385 { "outfitAddIntrinsic", pilotL_outfitAddIntrinsic },
386 { "outfitRmIntrinsic", pilotL_outfitRmIntrinsic },
387 { "fuel", pilotL_getFuel },
388 { "setFuel", pilotL_setFuel },
389 { "intrinsicReset", pilotL_intrinsicReset },
390 { "intrinsicSet", pilotL_intrinsicSet },
391 { "intrinsicGet", pilotL_intrinsicGet },
392 { "shippropReset", pilotL_shippropReset },
393 { "shippropSet", pilotL_shippropSet },
394 { "shippropGet", pilotL_shippropGet },
395 { "effectClear", pilotL_effectClear },
396 { "effectAdd", pilotL_effectAdd },
397 { "effectRm", pilotL_effectRm },
398 { "effects", pilotL_effectGet },
399 /* Ship. */
400 { "ship", pilotL_ship },
401 { "radius", pilotL_radius },
402 { "points", pilotL_points },
403 /* Cargo and moolah. */
404 { "cargoFree", pilotL_cargoFree },
405 { "cargoHas", pilotL_cargoHas },
406 { "cargoAdd", pilotL_cargoAdd },
407 { "cargoRm", pilotL_cargoRm },
408 { "cargoJet", pilotL_cargoJet },
409 { "cargoList", pilotL_cargoList },
410 { "credits", pilotL_credits },
411 { "worth", pilotL_worth },
412 /* Manual AI control. */
413 { "idle", pilotL_idle },
414 { "control", pilotL_control },
415 { "memory", pilotL_memory },
416 { "shipMemory", pilotL_shipmemory },
417 { "ainame", pilotL_ainame },
418 { "task", pilotL_task },
419 { "taskname", pilotL_taskname },
420 { "taskstack", pilotL_taskstack },
421 { "taskdata", pilotL_taskdata },
422 { "taskClear", pilotL_taskclear },
423 { "pushtask", pilotL_pushtask },
424 { "poptask", pilotL_poptask },
425 { "refuel", pilotL_refuel },
426 { "moveto", pilotL_moveto },
427 { "face", pilotL_face },
428 { "brake", pilotL_brake },
429 { "follow", pilotL_follow },
430 { "attack", pilotL_attack },
431 { "board", pilotL_board },
432 { "runaway", pilotL_runaway },
433 { "gather", pilotL_gather },
434 { "canHyperspace", pilotL_canHyperspace },
435 { "hyperspace", pilotL_hyperspace },
436 { "stealth", pilotL_stealth },
437 { "tryStealth", pilotL_tryStealth },
438 { "land", pilotL_land },
439 /* Misc. */
440 { "hailPlayer", pilotL_hailPlayer },
441 { "msg", pilotL_msg },
442 { "mothership" ,pilotL_mothership },
443 { "leader", pilotL_leader },
444 { "setLeader", pilotL_setLeader },
445 { "followers", pilotL_followers },
446 { "hookClear", pilotL_hookClear },
447 { "choosePoint", pilotL_choosePoint },
448 { "collisionTest", pilotL_collisionTest },
449 { "damage", pilotL_damage },
450 { "kill", pilotL_kill },
451 { "knockback", pilotL_knockback },
452 { "calcStats", pilotL_calcStats },
453 { "showEmitters", pilotL_showEmitters },
454 { "shipvarPeek", pilotL_shipvarPeek },
455 { "shipvarPush", pilotL_shipvarPush },
456 { "shipvarPop", pilotL_shipvarPop },
457 { "render", pilotL_render },
458 { "renderTo", pilotL_renderTo },
459 {0,0},
460};
468int nlua_loadPilot( nlua_env env )
469{
470 nlua_register(env, PILOT_METATABLE, pilotL_methods, 1);
471
472 /* Pilot always loads ship and asteroid. */
473 nlua_loadShip(env);
475
476 return 0;
477}
478
482static int pilotL_setFlagWrapper( lua_State *L, int flag )
483{
484 int state;
485 Pilot *p = luaL_validpilot(L,1);
486
487 /* Get state. */
488 if (lua_isnone(L,2))
489 state = 1;
490 else
491 state = lua_toboolean(L, 2);
492
493 /* Set or remove the flag. */
494 if (state)
495 pilot_setFlag( p, flag );
496 else
497 pilot_rmFlag( p, flag );
498
499 return 0;
500}
501
522LuaPilot lua_topilot( lua_State *L, int ind )
523{
524 return *((LuaPilot*) lua_touserdata(L,ind));
525}
533LuaPilot luaL_checkpilot( lua_State *L, int ind )
534{
535 if (lua_ispilot(L,ind))
536 return lua_topilot(L,ind);
537 luaL_typerror(L, ind, PILOT_METATABLE);
538 return 0;
539}
547Pilot* luaL_validpilot( lua_State *L, int ind )
548{
549 Pilot *p = pilot_get(luaL_checkpilot(L,ind));
550 if (p==NULL) {
551 NLUA_ERROR(L,_("Pilot is invalid."));
552 return NULL;
553 }
554 return p;
555}
563LuaPilot* lua_pushpilot( lua_State *L, LuaPilot pilot )
564{
565 LuaPilot *p = (LuaPilot*) lua_newuserdata(L, sizeof(LuaPilot));
566 *p = pilot;
567 luaL_getmetatable(L, PILOT_METATABLE);
568 lua_setmetatable(L, -2);
569 return p;
570}
578int lua_ispilot( lua_State *L, int ind )
579{
580 int ret;
581
582 if (lua_getmetatable(L,ind)==0)
583 return 0;
584 lua_getfield(L, LUA_REGISTRYINDEX, PILOT_METATABLE);
585
586 ret = 0;
587 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
588 ret = 1;
589
590 lua_pop(L, 2); /* remove both metatables */
591 return ret;
592}
593
604static int pilotL_choosePoint( lua_State *L )
605{
606 LuaFaction lf;
607 int ignore_rules, guerilla;
608 Spob *spob = NULL;
609 JumpPoint *jump = NULL;
610 vec2 vp;
611
612 /* Parameters. */
613 lf = luaL_validfaction(L,1);
614 ignore_rules = lua_toboolean(L,2);
615 guerilla = lua_toboolean(L,3);
616
617 pilot_choosePoint( &vp, &spob, &jump, lf, ignore_rules, guerilla );
618
619 if (spob != NULL)
620 lua_pushspob(L, spob->id );
621 else if (jump != NULL)
622 lua_pushsystem(L, jump->from->id);
623 else
624 lua_pushvector(L, vp);
625
626 return 1;
627}
628
658static int pilotL_add( lua_State *L )
659{
660 const Ship *ship;
661 const char *pilotname, *ai;
662 double a, r;
663 vec2 vv, vp, vn;
664 LuaFaction lf;
665 StarSystem *ss;
666 Spob *spob;
667 JumpPoint *jump;
668 PilotFlags flags;
669 int ignore_rules;
670 Pilot *p;
671
672 /* Default values. */
673 pilot_clearFlagsRaw( flags );
674 vectnull(&vn); /* Need to determine angle. */
675 ss = NULL;
676 jump = NULL;
677 spob = NULL;
678 a = 0.;
679
680 /* Parse first argument - Ship Name */
681 ship = luaL_validship(L,1);
682 /* Get faction from string or number. */
683 lf = luaL_validfaction(L,2);
684 /* Get pilotname argument if provided. */
685 pilotname = luaL_optstring( L, 4, _(ship->name) );
686
687 /* Handle position/origin argument. */
688 if (lua_isvector(L,3)) {
689 vp = *lua_tovector(L,3);
690 a = RNGF() * 2.*M_PI;
691 vectnull( &vv );
692 }
693 else if (lua_issystem(L,3))
694 ss = system_getIndex( lua_tosystem(L,3) );
695 else if (lua_isjump(L,3))
696 ss = system_getIndex( lua_tojump(L,3)->destid );
697 else if (lua_isspob(L,3)) {
698 spob = luaL_validspob(L,3);
699 pilot_setFlagRaw( flags, PILOT_TAKEOFF );
700 a = RNGF() * 2. * M_PI;
701 r = RNGF() * spob->radius;
702 vec2_cset( &vp,
703 spob->pos.x + r * cos(a),
704 spob->pos.y + r * sin(a) );
705 a = RNGF() * 2.*M_PI;
706 vectnull( &vv );
707 }
708 /* Random. */
709 else if (lua_isnoneornil(L,3)) {
710 /* Check if we should ignore the strict rules. */
711 ignore_rules = 0;
712 if (lua_isboolean(L,3) && lua_toboolean(L,3))
713 ignore_rules = 1;
714
715 /* Choose the spawn point and act in consequence.*/
716 pilot_choosePoint( &vp, &spob, &jump, lf, ignore_rules, 0 );
717
718 if (spob != NULL) {
719 pilot_setFlagRaw( flags, PILOT_TAKEOFF );
720 a = RNGF() * 2. * M_PI;
721 r = RNGF() * spob->radius;
722 vec2_cset( &vp,
723 spob->pos.x + r * cos(a),
724 spob->pos.y + r * sin(a) );
725 }
726 a = RNGF() * 2.*M_PI;
727 vectnull( &vv );
728 }
729 else
730 NLUA_INVALID_PARAMETER(L,3);
731
732 /* Handle system. */
733 if (ss != NULL) {
734 for (int i=0; i<array_size(cur_system->jumps); i++) {
735 if ((cur_system->jumps[i].target == ss)
736 && !jp_isFlag( cur_system->jumps[i].returnJump, JP_EXITONLY )) {
737 jump = cur_system->jumps[i].returnJump;
738 break;
739 }
740 }
741 if (jump == NULL) {
742 if (array_size(cur_system->jumps) > 0) {
743 WARN(_("Ship '%s' jumping in from non-adjacent system '%s' to '%s'."),
744 pilotname, ss->name, cur_system->name );
745 jump = cur_system->jumps[RNG_BASE(0, array_size(cur_system->jumps)-1)].returnJump;
746 }
747 else
748 WARN(_("Ship '%s' attempting to jump in from '%s', but '%s' has no jump points."),
749 pilotname, ss->name, cur_system->name );
750 }
751 }
752
753 /* Parse final argument - table of optional parameters */
754 ai = NULL;
755 if (lua_gettop( L ) >= 5 && !lua_isnil( L, 5 )) {
756 if (!lua_istable( L, 5 ))
757 return NLUA_ERROR( L, _("'parameters' should be a table of options or omitted!") );
758 lua_getfield( L, 5, "ai" );
759 ai = luaL_optstring( L, -1, NULL );
760 lua_pop( L, 1 );
761
762 lua_getfield( L, 5, "naked" );
763 if (lua_toboolean(L, -1))
764 pilot_setFlagRaw( flags, PILOT_NO_OUTFITS );
765 lua_pop( L, 1 );
766
767 lua_getfield( L, 5, "stealth" );
768 if (lua_toboolean(L, -1))
769 pilot_setFlagRaw( flags, PILOT_STEALTH );
770 lua_pop( L, 1 );
771 }
772
773 /* Set up velocities and such. */
774 if (jump != NULL) {
775 space_calcJumpInPos( cur_system, jump->from, &vp, &vv, &a, NULL );
776 pilot_setFlagRaw( flags, PILOT_HYP_END );
777 }
778
779 /* Make sure angle is valid. */
780 a = fmod( a, 2.*M_PI );
781 if (a < 0.)
782 a += 2.*M_PI;
783
784 /* Create the pilot. */
785 p = pilot_create( ship, pilotname, lf, ai, a, &vp, &vv, flags, 0, 0 );
786 lua_pushpilot(L,p->id);
787 if (jump==NULL) {
788 ai_newtask( L, p, "idle_wait", 0, 1 );
789 p->timer[0] = p->tcontrol;
790 }
791
792 /* TODO don't have space_calcJumpInPos called twice when stealth creating. */
793 if ((jump != NULL) && pilot_isFlagRaw( flags, PILOT_STEALTH )) {
794 space_calcJumpInPos( cur_system, jump->from, &p->solid.pos, &p->solid.vel, &p->solid.dir, p );
795 }
796 return 1;
797}
798
806static int pilotL_clone( lua_State *L )
807{
808 const Pilot *p = luaL_validpilot(L,1);
809 LuaPilot lp = pilot_clone( p );
810 lua_pushpilot( L, lp );
811 return 1;
812}
813
824static int pilotL_remove( lua_State *L )
825{
826 Pilot *p = pilot_get( luaL_checkpilot(L,1) );
827 if (p==NULL)
828 return 0;
829
830 /* Player is destroyed. */
831 if (pilot_isPlayer(p))
833
834 /* Deletes the pilot. */
835 pilot_delete(p);
836
837 return 0;
838}
839
851static int pilotL_explode( lua_State *L )
852{
853 Pilot *p = luaL_validpilot(L,1);
854
855 /* Run exploded hook that can be cancelled. */
856 pilot_setFlag( p, PILOT_EXPLODED );
857 pilot_runHook( p, PILOT_HOOK_EXPLODED );
858 if (!pilot_isFlag( p, PILOT_EXPLODED )) {
859 lua_pushboolean(L,0);
860 return 1;
861 }
862
863 /* Player is destroyed. */
864 if (pilot_isPlayer(p))
866
867 /* Deletes the pilot. */
868 pilot_delete(p);
869
870 lua_pushboolean(L,1);
871 return 0;
872}
873
874static void clearSelect( Pilot *const* pilot_stack, int f )
875{
876 for (int i=0; i<array_size(pilot_stack); i++) {
877 Pilot *pi = pilot_stack[i];
878 if (pilot_isFlag(pi, PILOT_DELETE) ||
879 pilot_isFlag(pi, PILOT_DEAD) ||
880 pilot_isFlag(pi, PILOT_HIDE))
881 continue;
882 if (pi->faction!=f)
883 continue;
884 pilot_delete(pi);
885 }
886}
896static int pilotL_clearSelect( lua_State *L )
897{
898 Pilot *const* pilot_stack = pilot_getAll();
899 if (lua_istable(L,1)) {
900 lua_pushnil(L);
901 while (lua_next(L, 1) != 0) {
902 clearSelect( pilot_stack, luaL_validfaction(L,-1) );
903 lua_pop(L,1);
904 }
905 lua_pop(L,1);
906 }
907 else
908 clearSelect( pilot_stack, luaL_validfaction(L,1) );
909
910 return 0;
911}
924static int pilotL_clear( lua_State *L )
925{
926 (void) L;
927 pilots_clear();
928 weapon_clear();
929 return 0;
930}
931
938static int pilotL_canSpawn( lua_State *L )
939{
940 lua_pushboolean( L, space_spawn );
941 return 1;
942}
943
944void toggleSpawn( int f, int b )
945{
946 /* Find the faction and set. */
947 for (int i=0; i<array_size(cur_system->presence); i++) {
948 if (cur_system->presence[i].faction != f)
949 continue;
950 cur_system->presence[i].disabled = b;
951 break;
952 }
953}
969static int pilotL_toggleSpawn( lua_State *L )
970{
971 int b = !lua_toboolean(L,2);
972
973 /* Setting it directly. */
974 if (!lua_isnoneornil(L,1)) {
975 if (lua_istable(L,1)) {
976 lua_pushnil(L);
977 while (lua_next(L, 1) != 0) {
978 toggleSpawn( luaL_validfaction(L,-1), b );
979 lua_pop(L,1);
980 }
981 lua_pop(L,1);
982 }
983 else if (lua_isfaction(L,1) || lua_isstring(L,1))
984 toggleSpawn( luaL_validfaction(L,1), b );
985 else if (lua_isboolean(L,1))
986 space_spawn = lua_toboolean(L,1);
987 else
988 NLUA_INVALID_PARAMETER(L,1);
989 }
990 /* Toggling. */
991 else
992 space_spawn = b;
993
994 lua_pushboolean(L, space_spawn);
995 return 1;
996}
1010static int pilotL_getPilots( lua_State *L )
1011{
1012 int d = lua_toboolean(L,2); /* Whether or not to get disabled. */
1013 Pilot *const* pilot_stack = pilot_getAll();
1014
1015 /* Check for belonging to faction. */
1016 if (lua_istable(L,1) || lua_isfaction(L,1)) {
1017 int *factions;
1018 if (lua_isfaction(L,1)) {
1019 factions = array_create( int );
1020 array_push_back( &factions, lua_tofaction(L,1) );
1021 }
1022 else {
1023 /* Get table length and preallocate. */
1024 factions = array_create_size( int, lua_objlen(L,1) );
1025 /* Load up the table. */
1026 lua_pushnil(L);
1027 while (lua_next(L, 1) != 0) {
1028 if (lua_isfaction(L,-1))
1029 array_push_back( &factions, lua_tofaction(L, -1) );
1030 lua_pop(L,1);
1031 }
1032 lua_pop(L,1);
1033 }
1034
1035 /* Now put all the matching pilots in a table. */
1036 lua_newtable(L);
1037 int k = 1;
1038 for (int i=0; i<array_size(pilot_stack); i++) {
1039 for (int j=0; j<array_size(factions); j++) {
1040 if ((pilot_stack[i]->faction == factions[j]) &&
1041 (d || !pilot_isDisabled(pilot_stack[i])) &&
1042 !pilot_isFlag(pilot_stack[i], PILOT_DELETE)) {
1043 lua_pushpilot(L, pilot_stack[i]->id); /* value */
1044 lua_rawseti(L,-2, k++); /* table[key] = value */
1045 }
1046 }
1047 }
1048
1049 /* clean up. */
1050 array_free( factions );
1051 }
1052 else if ((lua_isnil(L,1)) || (lua_gettop(L) == 0)) {
1053 /* Now put all the matching pilots in a table. */
1054 lua_newtable(L);
1055 int k = 1;
1056 for (int i=0; i<array_size(pilot_stack); i++) {
1057 if ((d || !pilot_isDisabled(pilot_stack[i])) &&
1058 !pilot_isFlag(pilot_stack[i], PILOT_DELETE)) {
1059 lua_pushpilot(L, pilot_stack[i]->id); /* value */
1060 lua_rawseti(L,-2,k++); /* table[key] = value */
1061 }
1062 }
1063 }
1064 else
1065 NLUA_INVALID_PARAMETER(L,1);
1066
1067 return 1;
1068}
1069
1070static int getFriendOrFoeTest( const Pilot *p, const Pilot *plt, int friend, double dd, int inrange, int dis, int fighters, const vec2 *v, LuaFaction lf )
1071{
1072 /* Check if dead. */
1073 if (pilot_isFlag(plt, PILOT_DELETE))
1074 return 0;
1075
1076 /* Ignore self. */
1077 if ((p!=NULL) && (p->id==plt->id))
1078 return 0;
1079
1080 /* Ignore fighters unless specified. */
1081 if (!fighters && pilot_isFlag(plt, PILOT_CARRIED))
1082 return 0;
1083
1084 /* Check distance if necessary. */
1085 if ((dd >= 0.) &&
1086 vec2_dist2(&plt->solid.pos, v) > dd)
1087 return 0;
1088
1089 /* Check if disabled. */
1090 if (dis && pilot_isDisabled(plt))
1091 return 0;
1092
1093 /* Check appropriate faction. */
1094 if (friend) {
1095 if (p==NULL) {
1096 if (!areAllies( lf, plt->faction ))
1097 return 0;
1098 }
1099 else {
1100 if (!pilot_areAllies( p, plt ))
1101 return 0;
1102 }
1103 }
1104 else {
1105 if (p==NULL) {
1106 if (!areEnemies( lf, plt->faction ))
1107 return 0;
1108 }
1109 else {
1110 if (inrange) {
1111 if (!pilot_validEnemy( p, plt ))
1112 return 0;
1113 }
1114 else {
1115 if (!pilot_areEnemies( p, plt ))
1116 return 0;
1117 }
1118 }
1119 }
1120
1121 /* Need extra check for friends. */
1122 if ((p!=NULL) && inrange && friend) {
1123 if (!pilot_inRangePilot( p, plt, NULL ))
1124 return 0;
1125 }
1126
1127 return 1;
1128}
1129
1130/*
1131 * Helper to get nearby friends or foes.
1132 */
1133static int pilotL_getFriendOrFoe( lua_State *L, int friend )
1134{
1135 int k;
1136 double dd;
1137 const Pilot *p;
1138 double dist;
1139 int inrange, dis, fighters;
1140 const vec2 *v;
1141 Pilot *const* pilot_stack;
1142 LuaFaction lf;
1143
1144 /* Check if using faction. */
1145 lf = -1;
1146 if (lua_isfaction(L,1))
1147 lf = lua_tofaction(L,1);
1148 else if (lua_isstring(L,1))
1149 lf = luaL_validfaction(L,1);
1150 /* Faction case. */
1151 if (lf >= 0) {
1152 dist = luaL_optnumber(L,2,-1.);
1153 v = luaL_checkvector(L,3);
1154 inrange = 0;
1155 dis = lua_toboolean(L,5);
1156 fighters = lua_toboolean(L,6);
1157 p = NULL;
1158 }
1159 /* Pilot case. */
1160 else {
1161 p = luaL_validpilot(L,1);
1162 dist = luaL_optnumber(L,2,-1.);
1163 v = luaL_optvector(L,3,&p->solid.pos);
1164 inrange = !lua_toboolean(L,4);
1165 dis = lua_toboolean(L,5);
1166 fighters = lua_toboolean(L,6);
1167 }
1168
1169 if (dist > 0.)
1170 dd = pow2(dist);
1171 else
1172 dd = -1.;
1173
1174 /* Now put all the matching pilots in a table. */
1176 lua_newtable(L);
1177 k = 1;
1178 if (dist >= 0. && dist < INFINITY) {
1179 int x, y, r;
1180 const IntList *qt;
1181 x = round(v->x);
1182 y = round(v->y);
1183 r = ceil(dist);
1184 qt = pilot_collideQuery( x-r, y-r, x+r, y+r );
1185 for (int i=0; i<il_size(qt); i++) {
1186 const Pilot *plt = pilot_stack[ il_get( qt, i, 0 ) ];
1187
1188 if (getFriendOrFoeTest( p, plt, friend, dd, inrange, dis, fighters, v, lf )) {
1189 lua_pushpilot(L, plt->id); /* value */
1190 lua_rawseti(L,-2, k++); /* table[key] = value */
1191 }
1192 }
1193 }
1194 else {
1195 for (int i=0; i<array_size(pilot_stack); i++) {
1196 const Pilot *plt = pilot_stack[i];
1197
1198 if (getFriendOrFoeTest( p, plt, friend, dd, inrange, dis, fighters, v, lf )) {
1199 lua_pushpilot(L, plt->id); /* value */
1200 lua_rawseti(L,-2, k++); /* table[key] = value */
1201 }
1202 }
1203 }
1204 return 1;
1205}
1206
1224static int pilotL_getAllies( lua_State *L )
1225{
1226 return pilotL_getFriendOrFoe( L, 1 );
1227}
1228
1246static int pilotL_getEnemies( lua_State *L )
1247{
1248 return pilotL_getFriendOrFoe( L, 0 );
1249}
1250
1264static int pilotL_getVisible( lua_State *L )
1265{
1266 int k;
1267 const Pilot *p = luaL_validpilot(L,1);
1268 int dis = lua_toboolean(L,2);
1269 Pilot *const* pilot_stack;
1270
1271 /* Now put all the matching pilots in a table. */
1273 lua_newtable(L);
1274 k = 1;
1275 for (int i=0; i<array_size(pilot_stack); i++) {
1276 /* Check if dead. */
1277 if (pilot_isFlag(pilot_stack[i], PILOT_DELETE))
1278 continue;
1279 /* Check if disabled. */
1280 if (dis && pilot_isDisabled(pilot_stack[i]))
1281 continue;
1282 /* Check visibilitiy. */
1283 if (!pilot_validTarget( p, pilot_stack[i] ))
1284 continue;
1285
1286 lua_pushpilot(L, pilot_stack[i]->id); /* value */
1287 lua_rawseti(L,-2,k++); /* table[key] = value */
1288 }
1289
1290 return 1;
1291}
1292
1304static int pilotL_getInrange( lua_State *L )
1305{
1306 int k;
1307 const vec2 *v = luaL_checkvector(L,1);
1308 double d = luaL_checknumber(L,2);
1309 int dis = lua_toboolean(L,3);
1310 int x, y, r;
1311 const IntList *qt;
1312 Pilot *const* pilot_stack = pilot_getAll();
1313
1314 d = pow2(d); /* Square it. */
1315
1316 /* Now put all the matching pilots in a table. */
1317 x = round(v->x);
1318 y = round(v->y);
1319 r = ceil(d);
1320 qt = pilot_collideQuery( x-r, y-r, x+r, y+r );
1321 lua_newtable(L);
1322 k = 1;
1323 for (int i=0; i<il_size(qt); i++) {
1324 Pilot *p = pilot_stack[ il_get( qt, i, 0 ) ];
1325
1326 /* Check if dead. */
1327 if (pilot_isFlag(p, PILOT_DELETE))
1328 continue;
1329 /* Check if hidden. */
1330 if (pilot_isFlag(p, PILOT_HIDE))
1331 continue;
1332 /* Check if disabled. */
1333 if (dis && pilot_isDisabled(p))
1334 continue;
1335
1336 /* Must be in range. */
1337 if (vec2_dist2( v, &p->solid.pos ) > d )
1338 continue;
1339
1340 lua_pushpilot(L, p->id); /* value */
1341 lua_rawseti(L,-2,k++); /* table[key] = value */
1342 }
1343
1344 return 1;
1345}
1346
1357static int pilotL_eq( lua_State *L )
1358{
1359 LuaPilot p1 = luaL_checkpilot(L,1);
1360 LuaPilot p2 = luaL_checkpilot(L,2);
1361 lua_pushboolean(L, p1 == p2);
1362 return 1;
1363}
1364
1374static int pilotL_tostring( lua_State *L )
1375{
1376 LuaPilot lp = luaL_checkpilot( L, 1 );
1377 const Pilot *p = pilot_get(lp);
1378 if (p!=NULL)
1379 lua_pushstring(L,p->name);
1380 else
1381 lua_pushstring(L,"(inexistent pilot)");
1382 return 1;
1383}
1384
1394static int pilotL_name( lua_State *L )
1395{
1396 const Pilot *p = luaL_validpilot(L,1);
1397 lua_pushstring(L, p->name);
1398 return 1;
1399}
1400
1410static int pilotL_id( lua_State *L )
1411{
1412 const Pilot *p = luaL_validpilot(L,1);
1413 lua_pushnumber(L, p->id);
1414 return 1;
1415}
1416
1428static int pilotL_exists( lua_State *L )
1429{
1430 int exists;
1431 const Pilot *p = pilot_get( luaL_checkpilot(L,1) );
1432
1433 /* Must still be kicking and alive. */
1434 if (p==NULL)
1435 exists = 0;
1436 else if (pilot_isFlag( p, PILOT_DEAD ) || pilot_isFlag( p, PILOT_HIDE ))
1437 exists = 0;
1438 else
1439 exists = 1;
1440
1441 /* Check if the pilot exists. */
1442 lua_pushboolean(L, exists);
1443 return 1;
1444}
1445
1455static int pilotL_target( lua_State *L )
1456{
1457 Pilot *p = luaL_validpilot(L,1);
1458 /* Must be valid. */
1459 if (pilot_getTarget(p) == NULL)
1460 return 0;
1461 /* Push target. */
1462 lua_pushpilot(L, p->target);
1463 return 1;
1464}
1465
1473static int pilotL_setTarget( lua_State *L )
1474{
1475 unsigned int t;
1476 Pilot *p = luaL_validpilot(L,1);
1477 if (lua_isnoneornil(L,2))
1478 t = p->id;
1479 else
1480 t = luaL_validpilot(L,2)->id;
1481 if (pilot_isPlayer(p))
1482 player_targetSet( t );
1483 else
1484 pilot_setTarget( p, t );
1485 return 0;
1486}
1487
1497static int pilotL_targetAsteroid( lua_State *L )
1498{
1499 LuaAsteroid_t la;
1500 const Pilot *p = luaL_validpilot(L,1);
1501 if (p->nav_asteroid < 0)
1502 return 0;
1503
1504 la.parent = p->nav_anchor;
1505 la.id = p->nav_asteroid;
1506 lua_pushasteroid(L, la);
1507 return 1;
1508}
1509
1517static int pilotL_setTargetAsteroid( lua_State *L )
1518{
1519 Pilot *p = luaL_validpilot(L,1);
1520 const LuaAsteroid_t *la = luaL_checkasteroid(L,2);
1521
1522 /* Set the target asteroid. */
1523 p->nav_anchor = la->parent;
1524 p->nav_asteroid = la->id;
1525
1526 /* Untarget pilot. */
1527 p->target = p->id;
1528 p->ptarget = NULL;
1529
1530 return 0;
1531}
1532
1546static int pilotL_inrange( lua_State *L )
1547{
1548 /* Parse parameters. */
1549 const Pilot *p = luaL_validpilot(L,1);
1550 if (lua_ispilot(L,2)) {
1551 const Pilot *t = luaL_validpilot(L,2);
1552
1553 /* Check if in range. */
1554 int ret = pilot_inRangePilot( p, t, NULL );
1555 if (ret == 1) { /* In range. */
1556 lua_pushboolean(L,1);
1557 lua_pushboolean(L,1);
1558 }
1559 else if (ret == 0) { /* Not in range. */
1560 lua_pushboolean(L,0);
1561 lua_pushboolean(L,0);
1562 }
1563 else { /* Detected fuzzy. */
1564 lua_pushboolean(L,1);
1565 lua_pushboolean(L,0);
1566 }
1567 return 2;
1568 }
1569 else if (lua_isasteroid(L,2)) {
1570 const LuaAsteroid_t *la = luaL_checkasteroid(L,2);
1571
1572 /* Check if in range. */
1573 lua_pushboolean(L, pilot_inRangeAsteroid( p, la->id, la->parent ));
1574 lua_pushboolean(L,1);
1575 return 2;
1576 }
1577 else {
1578 const vec2 *v = luaL_checkvector(L,2);
1579 lua_pushboolean(L, pilot_inRange( p, v->x, v->y ) );
1580 lua_pushboolean(L,1);
1581 return 2;
1582 }
1583}
1584
1591static int pilotL_scandone( lua_State *L )
1592{
1593 const Pilot *p = luaL_validpilot(L,1);
1594 lua_pushboolean(L, pilot_ewScanCheck( p ) );
1595 return 1;
1596}
1597
1605static int pilotL_withPlayer( lua_State *L )
1606{
1607 const Pilot *p = luaL_validpilot(L,1);
1608 lua_pushboolean(L, pilot_isWithPlayer(p));
1609 return 1;
1610}
1611
1622static int pilotL_nav( lua_State *L )
1623{
1624 const Pilot *p = luaL_validpilot(L,1);
1625 if (p->target == 0)
1626 return 0;
1627
1628 /* Get spob target. */
1629 if (p->nav_spob < 0)
1630 lua_pushnil(L);
1631 else
1632 lua_pushspob( L, cur_system->spobs[ p->nav_spob ]->id );
1633
1634 /* Get hyperspace target. */
1635 if (p->nav_hyperspace < 0)
1636 lua_pushnil(L);
1637 else {
1638 LuaSystem ls = cur_system->jumps[ p->nav_hyperspace ].targetid;
1639 lua_pushsystem( L, ls );
1640 }
1641
1642 return 2;
1643}
1644
1652static int pilotL_navSpob( lua_State *L )
1653{
1654 const Pilot *p = luaL_validpilot(L,1);
1655
1656 /* Get spob target. */
1657 if (p->nav_spob < 0)
1658 lua_pushnil(L);
1659 else
1660 lua_pushspob( L, cur_system->spobs[ p->nav_spob ]->id );
1661
1662 return 1;
1663}
1664
1672static int pilotL_navJump( lua_State *L )
1673{
1674 const Pilot *p = luaL_validpilot(L,1);
1675
1676 /* Get hyperspace target. */
1677 if (p->nav_hyperspace < 0)
1678 lua_pushnil(L);
1679 else {
1680 LuaJump lj;
1681 lj.srcid = cur_system->id;
1682 lj.destid = cur_system->jumps[ p->nav_hyperspace ].targetid;
1683 lua_pushjump( L, lj );
1684 }
1685
1686 return 1;
1687}
1688
1696static int pilotL_navJumpSet( lua_State *L )
1697{
1698 Pilot *p = luaL_validpilot(L,1);
1699 int jumpid = -1;
1700 if (!lua_isnoneornil(L,2)) {
1701 const LuaJump *lj = luaL_checkjump(L,2);
1702 if (cur_system->id != lj->srcid)
1703 return NLUA_ERROR(L,_("Jump source system doesn't match current system!"));
1704 /* jumpid = jp - cur_system->jumps; */
1705 for (int i=0; i<array_size(cur_system->jumps); i++)
1706 if (cur_system->jumps[ i ].targetid == lj->destid) {
1707 jumpid = i;
1708 break;
1709 }
1710 if (jumpid<0)
1711 return NLUA_ERROR(L,_("Jump destination system not found!"));
1712 }
1713
1714 if (pilot_isPlayer(p))
1715 map_select( cur_system->jumps[jumpid].target, 0 );
1716 else
1717 p->nav_hyperspace = jumpid;
1718
1719 return 1;
1720}
1721
1732static int pilotL_weapsetActive( lua_State *L )
1733{
1734 const Pilot *p = luaL_validpilot(L,1);
1735 lua_pushinteger( L, p->active_set+1 );
1736 return 1;
1737}
1738
1749static int pilotL_weapsetSetActive( lua_State *L )
1750{
1751 Pilot *p = luaL_validpilot(L,1);
1752 int id = luaL_checkweapset(L,2);
1753 if (pilot_weapSetTypeCheck(p,id)==WEAPSET_TYPE_SWITCH)
1754 pilot_weapSetPress(p,id,1);
1755 return 0;
1756}
1757
1763static int weapsetItem( lua_State *L, int *k, Pilot *p, const PilotOutfitSlot *slot, const Pilot *target )
1764{
1765 const Damage *dmg;
1766 const Outfit *o = slot->outfit;
1767 int is_lau, is_fb, active;
1768
1769 /* Check if we should add. */
1770 if (o == NULL)
1771 return 0;
1772 is_lau = outfit_isLauncher(o);
1773 is_fb = outfit_isFighterBay(o);
1774
1775 /* Must be valid weapon. */
1776 if (!(outfit_isBolt(o) || outfit_isBeam(o)
1777 || is_lau || is_fb))
1778 return 0;
1779
1780 /* Must be weapon. */
1781 if (outfit_isMod(o) ||
1783 return 0;
1784
1785 /* Set up new item. */
1786 lua_pushnumber(L,++(*k));
1787
1788 /* We'll store the data in a table. */
1789 lua_newtable(L);
1790
1791 /* Outfit. */
1792 lua_pushstring(L,"outfit");
1793 lua_pushoutfit(L,slot->outfit);
1794 lua_rawset(L,-3);
1795
1796 /* Beams require special handling. */
1797 if (outfit_isBeam(o)) {
1798 double delay, firemod, enermod;
1799 int has_beamid;
1800 pilot_getRateMod( &firemod, &enermod, p, slot->outfit );
1801
1802 /* When firing, cooldown is always zero. When recharging,
1803 * it's the usual 0-1 readiness value. */
1804 lua_pushstring(L,"cooldown");
1805 has_beamid = (slot->u.beamid > 0);
1806 if (has_beamid)
1807 lua_pushnumber(L, 0.);
1808 else {
1809 delay = (slot->timer / outfit_delay(o)) * firemod;
1810 lua_pushnumber( L, CLAMP( 0., 1., 1. -delay ) );
1811 }
1812 lua_rawset(L,-3);
1813
1814 /* When firing, slot->timer represents the remaining duration. */
1815 lua_pushstring(L,"charge");
1816 if (has_beamid)
1817 lua_pushnumber(L, CLAMP( 0., 1., slot->timer / o->u.bem.duration ) );
1818 else
1819 lua_pushnumber( L, CLAMP( 0., 1., 1. -delay ) );
1820 lua_rawset(L,-3);
1821 }
1822 else {
1823 double delay, firemod, enermod;
1824 /* Set cooldown. */
1825 lua_pushstring(L,"cooldown");
1826 pilot_getRateMod( &firemod, &enermod, p, slot->outfit );
1827 delay = outfit_delay(slot->outfit) * firemod;
1828 if (delay > 0.)
1829 lua_pushnumber( L, CLAMP( 0., 1., 1. - slot->timer / delay ) );
1830 else
1831 lua_pushnumber( L, 1. );
1832 lua_rawset(L,-3);
1833 }
1834
1835 /* Ammo quantity absolute. */
1836 if (is_lau || is_fb) {
1837 lua_pushstring(L,"left");
1838 lua_pushnumber( L, slot->u.ammo.quantity );
1839 lua_rawset(L,-3);
1840
1841 /* Ammo quantity relative. */
1842 lua_pushstring(L,"left_p");
1843 lua_pushnumber( L, (double)slot->u.ammo.quantity / (double)pilot_maxAmmoO(p,slot->outfit) );
1844 lua_rawset(L,-3);
1845 }
1846
1847 /* Launcher lockon. */
1848 if (is_lau) {
1849 double t = slot->u.ammo.lockon_timer;
1850 lua_pushstring(L, "lockon");
1851 if (t <= 0.)
1852 lua_pushnumber(L, 1.);
1853 else
1854 lua_pushnumber(L, 1. - (t / slot->outfit->u.lau.lockon));
1855 lua_rawset(L,-3);
1856
1857 /* Is in arc. */
1858 lua_pushstring(L, "in_arc");
1859 lua_pushboolean(L, slot->u.ammo.in_arc);
1860 lua_rawset(L,-3);
1861 }
1862
1863 /* Level. */
1864 lua_pushstring(L,"level");
1865 lua_pushnumber(L, slot->level+1);
1866 lua_rawset(L,-3);
1867
1868 active = 0;
1869 for (int id=0; id<PILOT_WEAPON_SETS; id++) {
1870 PilotWeaponSet *ws = pilot_weapSet( p, id );
1871 const PilotWeaponSetOutfit *po_list = ws->slots;
1872 if (!ws->active)
1873 continue;
1874 for (int i=0; i<array_size(po_list); i++) {
1875 if (po_list[i].slotid==slot->id) {
1876 active = 1;
1877 break;
1878 }
1879 }
1880 if (active)
1881 break;
1882 }
1883 lua_pushstring(L,"active");
1884 lua_pushboolean(L,active);
1885 lua_rawset(L,-3);
1886
1887 /* Temperature. */
1888 lua_pushstring(L,"heat");
1889 lua_pushnumber(L, pilot_heatFirePercent(slot->heat_T));
1890 lua_rawset(L,-3);
1891
1892 /* Type. */
1893 lua_pushstring(L, "type");
1894 lua_pushstring(L, outfit_getType(slot->outfit));
1895 lua_rawset(L,-3);
1896
1897 /* Damage type. */
1898 dmg = outfit_damage( slot->outfit );
1899 if (dmg != NULL) {
1900 lua_pushstring(L, "dtype");
1901 lua_pushstring(L, dtype_damageTypeToStr( dmg->type ) );
1902 lua_rawset(L,-3);
1903 }
1904
1905 /* Track. */
1906 if (outfit_isBolt(slot->outfit)) {
1907 lua_pushstring(L, "track");
1908 if (target != NULL)
1909 lua_pushnumber(L, pilot_ewWeaponTrack( p, target, slot->outfit->u.blt.trackmin, slot->outfit->u.blt.trackmax ));
1910 else
1911 lua_pushnumber(L, -1);
1912 lua_rawset(L,-3);
1913 }
1914
1915 /* Add to table. */
1916 lua_rawset(L,-3);
1917 return 1;
1918}
1919
1961static int pilotL_weapset( lua_State *L )
1962{
1963 Pilot *p, *target;
1964 int id, all;
1965
1966 /* Parse parameters. */
1967 all = 0;
1968 p = luaL_validpilot(L,1);
1969 if (lua_gettop(L) > 1) {
1970 if (lua_isnumber(L,2))
1971 id = luaL_checkinteger(L,2) - 1;
1972 else if (lua_isboolean(L,2)) {
1973 all = lua_toboolean(L,2);
1974 id = p->active_set;
1975 }
1976 else
1977 NLUA_INVALID_PARAMETER(L,2);
1978 }
1979 else
1980 id = p->active_set;
1981 id = CLAMP( 0, PILOT_WEAPON_SETS, id );
1982
1983 /* Get target. */
1984 target = (p->target != p->id) ? pilot_get(p->target) : NULL;
1985
1986 /* Push name. */
1987 lua_pushstring( L, pilot_weapSetName( p, id ) );
1988
1989 /* Push set. */
1990 lua_newtable( L );
1991 if (all) {
1992 int k = 0;
1993 for (int i=0; i<array_size(p->outfits); i++) {
1994 const PilotOutfitSlot *slot = p->outfits[i];
1995 weapsetItem( L, &k, p, slot, target );
1996 }
1997 }
1998 else {
1999 int k = 0;
2000 const PilotWeaponSetOutfit *po_list = pilot_weapSetList( p, id );
2001 for (int i=0; i<array_size(po_list); i++) {
2002 const PilotOutfitSlot *slot = p->outfits[ po_list[i].slotid ];
2003 weapsetItem( L, &k, p, slot, target );
2004 }
2005 }
2006
2007 return 2;
2008}
2009
2010static int luaL_checkweapset( lua_State *L, int idx )
2011{
2012 int ws = luaL_checkinteger(L,idx)-1;
2013 if ((ws < 0) || (ws > 9))
2014 return NLUA_ERROR(L,_("Invalid weapon set '%d'!"),idx);
2015 return ws;
2016}
2017
2018static PilotOutfitSlot *luaL_checkslot( lua_State *L, Pilot *p, int idx )
2019{
2020 if (lua_isnumber(L,idx)) {
2021 const int slotid = lua_tointeger(L,idx);
2022 if ((slotid < 1) || (slotid > array_size(p->outfits))) {
2023 NLUA_ERROR(L,_("Pilot '%s' with ship '%s' does not have a slot with id '%d'!"), p->name, _(p->ship->name), slotid );
2024 return NULL;
2025 }
2026 /* We have to convert from "Lua IDs" to "C" ids by subtracting 1. */
2027 return p->outfits[ slotid-1 ];
2028 }
2029
2030 const char *slotname = luaL_checkstring(L,idx);
2031 PilotOutfitSlot *s = pilot_getSlotByName( p, slotname );
2032 if (s==NULL) {
2033 WARN(_("Pilot '%s' with ship '%s' does not have named slot '%s'!"), p->name, _(p->ship->name), slotname );
2034 return NULL;
2035 }
2036 return s;
2037}
2038
2047static int pilotL_weapsetList( lua_State *L )
2048{
2049 const Pilot *p = luaL_validpilot(L,1);
2050 int id = luaL_checkweapset(L,2);
2051 const PilotWeaponSet *ws = &p->weapon_sets[id];
2052
2053 lua_newtable(L);
2054 for (int i=0; i<array_size(ws->slots); i++) {
2055 lua_pushinteger( L, ws->slots[i].slotid+1 );
2056 lua_rawseti( L, -2, i+1 );
2057 }
2058 return 1;
2059}
2060
2069static int pilotL_weapsetType( lua_State *L )
2070{
2071 Pilot *p = luaL_validpilot(L,1);
2072 int id = luaL_checkweapset(L,2);
2073 const char *type = luaL_checkstring(L,3);
2074 int typeid;
2075 if (strcmp(type,"switch")==0)
2076 typeid = WEAPSET_TYPE_SWITCH;
2077 else if (strcmp(type,"toggle")==0)
2078 typeid = WEAPSET_TYPE_TOGGLE;
2079 else if (strcmp(type,"hold")==0)
2080 typeid = WEAPSET_TYPE_HOLD;
2081 else
2082 return NLUA_ERROR(L,_("Invalid weapon set type '%s'!"),type);
2083 pilot_weapSetType( p, id, typeid );
2084 return 0;
2085}
2086
2095static int pilotL_weapsetAdd( lua_State *L )
2096{
2097 Pilot *p = luaL_validpilot(L,1);
2098 int id = luaL_checkweapset(L,2);
2099 const PilotOutfitSlot *o = luaL_checkslot(L,p,3);
2100 int level = luaL_optinteger(L,4,0);
2101 pilot_weapSetAdd( p, id, o, level );
2102 return 0;
2103}
2104
2113static int pilotL_weapsetAddType( lua_State *L )
2114{
2115 Pilot *p = luaL_validpilot(L,1);
2116 int id = luaL_checkweapset(L,2);
2117 const char *type = luaL_checkstring(L,3);
2118 int level = luaL_optinteger(L,4,0);
2119 for (int i=0; i<array_size(p->outfits); i++) {
2120 PilotOutfitSlot *pos = p->outfits[i];
2121 if (pos->outfit==NULL)
2122 continue;
2123 if ((strcmp(pos->outfit->name,type)==0) ||
2124 (strcmp(outfit_getType(pos->outfit),type)==0) ||
2125 (strcmp(outfit_getTypeBroad(pos->outfit),type)==0))
2126 pilot_weapSetAdd( p, id, pos, level );
2127 }
2128 return 0;
2129}
2130
2139static int pilotL_weapsetRm( lua_State *L )
2140{
2141 Pilot *p = luaL_validpilot(L,1);
2142 int id = luaL_checkweapset(L,2);
2143 const PilotOutfitSlot *o = luaL_checkslot(L,p,3);
2144 pilot_weapSetRm( p, id, o );
2145 return 0;
2146}
2147
2155static int pilotL_weapsetCleanup( lua_State *L )
2156{
2157 Pilot *p = luaL_validpilot(L,1);
2158 if (lua_isnoneornil(L,2)) {
2159 for (int i=0; i<PILOT_WEAPON_SETS; i++)
2160 pilot_weapSetCleanup( p, i );
2161 }
2162 else {
2163 int id = luaL_checkweapset(L,2);
2164 pilot_weapSetCleanup( p, id );
2165 }
2166 return 0;
2167}
2168
2190static int pilotL_weapsetHeat( lua_State *L )
2191{
2192 Pilot *p;
2193 PilotWeaponSetOutfit *po_list;
2194 int n, id, all;
2195 double heat, heat_mean, heat_peak, nweapons;
2196
2197 /* Defaults. */
2198 heat_mean = 0.;
2199 heat_peak = 0.;
2200 nweapons = 0;
2201
2202 /* Parse parameters. */
2203 all = 0;
2204 p = luaL_validpilot(L,1);
2205 if (lua_gettop(L) > 1) {
2206 if (lua_isnumber(L,2))
2207 id = luaL_checkinteger(L,2) - 1;
2208 else if (lua_isboolean(L,2)) {
2209 all = lua_toboolean(L,2);
2210 id = p->active_set;
2211 }
2212 else
2213 NLUA_INVALID_PARAMETER(L,2);
2214 }
2215 else
2216 id = p->active_set;
2217 id = CLAMP( 0, PILOT_WEAPON_SETS, id );
2218
2219 /* Push set. */
2220 po_list = all ? NULL : pilot_weapSetList( p, id );
2221 n = all ? array_size(p->outfits) : array_size(po_list);
2222
2223 for (int j=0; j<=PILOT_WEAPSET_MAX_LEVELS; j++) {
2224 /* Level to match. */
2225 int level_match = (j==PILOT_WEAPSET_MAX_LEVELS) ? -1 : j;
2226
2227 /* Iterate over weapons. */
2228 for (int i=0; i<n; i++) {
2229 int level;
2230 /* Get base look ups. */
2231 PilotOutfitSlot *slot = all ? p->outfits[i] : p->outfits[ po_list[i].slotid ];
2232 const Outfit *o = slot->outfit;
2233 if (o == NULL)
2234 continue;
2235
2236 level = all ? slot->level : po_list[i].level;
2237
2238 /* Must match level. */
2239 if (level != level_match)
2240 continue;
2241
2242 /* Must be weapon. */
2243 if (outfit_isMod(o) ||
2245 continue;
2246
2247 nweapons++;
2248 heat = pilot_heatFirePercent(slot->heat_T);
2249 heat_mean += heat;
2250 if (heat > heat_peak)
2251 heat_peak = heat;
2252 }
2253 }
2254
2255 /* Post-process. */
2256 if (nweapons > 0)
2257 heat_mean /= nweapons;
2258
2259 lua_pushnumber( L, heat_mean );
2260 lua_pushnumber( L, heat_peak );
2261
2262 return 2;
2263}
2264
2273static int pilotL_weapsetSetInrange( lua_State *L )
2274{
2275 Pilot *p = luaL_validpilot(L,1);
2276 int inrange = lua_toboolean(L,3);
2277 if (lua_isnoneornil(L,2)) {
2278 for (int i=0; i<PILOT_WEAPON_SETS; i++)
2279 pilot_weapSetInrange( p, i, inrange );
2280 }
2281 else {
2282 int id = luaL_checkweapset(L,2);
2283 pilot_weapSetInrange( p, id, inrange );
2284 }
2285 return 0;
2286}
2287
2297static int pilotL_weapsetAmmo( lua_State *L )
2298{
2299 Pilot *p = luaL_validpilot( L, 1 );
2300 int id = luaL_optinteger( L, 2, p->active_set );
2301 int level = luaL_optinteger( L, 3, -1 );
2302 lua_pushnumber(L, pilot_weapSetAmmo( p, id, level ) );
2303 return 1;
2304}
2305
2338static int pilotL_actives( lua_State *L )
2339{
2340 Pilot *p;
2341 int k, sort;
2342 PilotOutfitSlot **outfits;
2343 const char *str;
2344 double d;
2345
2346 /* Parse parameters. */
2347 p = luaL_validpilot(L,1);
2348 sort = lua_toboolean(L,2);
2349
2350 k = 0;
2351 lua_newtable(L);
2352
2353 if (sort) {
2354 outfits = array_copy( PilotOutfitSlot*, p->outfits );
2355 qsort( outfits, array_size(outfits), sizeof(PilotOutfitSlot*), outfit_compareActive );
2356 }
2357 else
2358 outfits = p->outfits;
2359
2360 for (int i=0; i<array_size(outfits); i++) {
2361 /* Get active outfits. */
2362 PilotOutfitSlot *o = outfits[i];
2363 int active;
2364 if (o->outfit == NULL)
2365 continue;
2366 if (!o->active)
2367 continue;
2368 if (!outfit_isMod(o->outfit) &&
2370 continue;
2371
2372 /* Set up for creation. */
2373 lua_pushnumber(L,++k);
2374 lua_newtable(L);
2375
2376 /* Outfit. */
2377 lua_pushstring(L,"outfit");
2378 lua_pushoutfit(L,o->outfit);
2379 lua_rawset(L,-3);
2380
2381 /* Type. */
2382 lua_pushstring(L, "type");
2383 lua_pushstring(L, outfit_getType(o->outfit));
2384 lua_rawset(L,-3);
2385
2386 /* Heat. */
2387 lua_pushstring(L, "heat");
2388 lua_pushnumber(L, 1.-pilot_heatEfficiencyMod(o->heat_T,
2389 o->outfit->overheat_min,
2390 o->outfit->overheat_max));
2391 lua_rawset(L,-3);
2392
2393 active = 0;
2394 for (int id=0; id<PILOT_WEAPON_SETS; id++) {
2395 PilotWeaponSet *ws = pilot_weapSet( p, id );
2396 const PilotWeaponSetOutfit *po_list = ws->slots;
2397 if (!ws->active)
2398 continue;
2399 for (int j=0; j<array_size(po_list); j++) {
2400 if (po_list[j].slotid==o->id) {
2401 active = 1;
2402 break;
2403 }
2404 }
2405 if (active)
2406 break;
2407 }
2408 lua_pushstring(L,"active");
2409 lua_pushboolean(L,active);
2410 lua_rawset(L,-3);
2411
2412 /* Find the first weapon set containing the outfit, if any. */
2413 if (outfits[i]->weapset != -1) {
2414 lua_pushstring(L, "weapset");
2415 lua_pushnumber(L, outfits[i]->weapset + 1);
2416 lua_rawset(L, -3);
2417 }
2418
2419 /* State and timer. */
2420 switch (o->state) {
2421 case PILOT_OUTFIT_OFF:
2422 str = "off";
2423 break;
2424 case PILOT_OUTFIT_WARMUP:
2425 str = "warmup";
2426 if (!outfit_isMod(o->outfit) || o->outfit->lua_env == LUA_NOREF)
2427 d = 1.; /* TODO add warmup stuff to normal active outfits (not sure if necessary though. */
2428 else
2429 d = o->progress;
2430 lua_pushstring(L,"warmup");
2431 lua_pushnumber(L, d );
2432 lua_rawset(L,-3);
2433 break;
2434 case PILOT_OUTFIT_ON:
2435 str = "on";
2436 if (!outfit_isMod(o->outfit) || o->outfit->lua_env == LUA_NOREF) {
2437 d = outfit_duration(o->outfit);
2438 if (d==0.)
2439 d = 1.;
2440 else if (!isinf(o->stimer))
2441 d = o->stimer / d;
2442 }
2443 else
2444 d = o->progress;
2445 lua_pushstring(L,"duration");
2446 lua_pushnumber(L, d );
2447 lua_rawset(L,-3);
2448 break;
2449 case PILOT_OUTFIT_COOLDOWN:
2450 str = "cooldown";
2451 if (!outfit_isMod(o->outfit) || o->outfit->lua_env == LUA_NOREF) {
2452 d = outfit_cooldown(o->outfit);
2453 if (d>0. && !isinf(o->stimer))
2454 d = o->stimer / d;
2455 }
2456 else
2457 d = o->progress;
2458 lua_pushstring(L,"cooldown");
2459 lua_pushnumber(L, d );
2460 lua_rawset(L,-3);
2461 break;
2462 default:
2463 str = "unknown";
2464 break;
2465 }
2466 lua_pushstring(L,"state");
2467 lua_pushstring(L,str);
2468 lua_rawset(L,-3);
2469
2470 /* Set table in table. */
2471 lua_rawset(L,-3);
2472 }
2473
2474 /* Clean up. */
2475 if (sort)
2476 array_free(outfits);
2477
2478 return 1;
2479}
2480
2484static int outfit_compareActive( const void *slot1, const void *slot2 )
2485{
2486 const PilotOutfitSlot *s1, *s2;
2487 s1 = *(const PilotOutfitSlot**) slot1;
2488 s2 = *(const PilotOutfitSlot**) slot2;
2489
2490 /* Compare weapon set indexes. */
2491 if (s1->weapset < s2->weapset)
2492 return +1;
2493 else if (s1->weapset > s2->weapset)
2494 return -1;
2495
2496 /* Compare positions within the outfit array. */
2497 if (s1->id < s2->id)
2498 return +1;
2499 else if (s1->id > s2->id)
2500 return -1;
2501
2502 return 0;
2503}
2504
2514static int pilotL_outfitsList( lua_State *L )
2515{
2516 int normal = 1;
2517 int intrinsics = 0;
2518 const Pilot *p = luaL_validpilot(L,1);
2519 const char *type = luaL_optstring(L,2,NULL);
2520 int skip_locked = lua_toboolean(L,3);
2521 OutfitSlotType ost = OUTFIT_SLOT_NULL;
2522
2523 /* Get type. */
2524 if (type != NULL) {
2525 if (strcmp(type,"all")==0)
2526 intrinsics = 1;
2527 else if (strcmp(type,"structure")==0)
2528 ost = OUTFIT_SLOT_STRUCTURE;
2529 else if (strcmp(type,"utility")==0)
2530 ost = OUTFIT_SLOT_UTILITY;
2531 else if (strcmp(type,"weapon")==0)
2532 ost = OUTFIT_SLOT_WEAPON;
2533 else if (strcmp(type,"intrinsic")==0) {
2534 intrinsics = 1;
2535 normal = 0;
2536 }
2537 else
2538 return NLUA_ERROR(L,_("Unknown slot type '%s'"), type);
2539 }
2540
2541 lua_newtable( L );
2542 int j = 1;
2543 if (normal) {
2544 for (int i=0; i<array_size(p->outfits); i++) {
2545 /* Get outfit. */
2546 if (p->outfits[i]->outfit == NULL)
2547 continue;
2548
2549 /* Only match specific type. */
2550 if ((ost!=OUTFIT_SLOT_NULL) && (p->outfits[i]->outfit->slot.type!=ost))
2551 continue;
2552
2553 /* Skip locked. */
2554 if (skip_locked && p->outfits[i]->sslot->locked)
2555 continue;
2556
2557 /* Set the outfit. */
2558 lua_pushoutfit( L, p->outfits[i]->outfit );
2559 lua_rawseti( L, -2, j++ );
2560 }
2561 }
2562 if (intrinsics) {
2563 for (int i=0; i<array_size(p->outfit_intrinsic); i++) {
2564 lua_pushoutfit( L, p->outfit_intrinsic[i].outfit );
2565 lua_rawseti( L, -2, j++ );
2566 }
2567 }
2568
2569 return 1;
2570}
2571
2581static int pilotL_outfits( lua_State *L )
2582{
2583 const Pilot *p = luaL_validpilot(L,1);
2584 lua_newtable( L );
2585 for (int i=0; i<array_size(p->outfits); i++) {
2586 if (p->outfits[i]->outfit == NULL)
2587 lua_pushboolean( L, 0 );
2588 else
2589 lua_pushoutfit( L, p->outfits[i]->outfit );
2590 lua_rawseti( L, -2, i+1 );
2591 }
2592 return 1;
2593}
2594
2604static int pilotL_outfitsEquip( lua_State *L )
2605{
2606 Pilot *p = luaL_validpilot(L,1);
2607 int ret = 0;
2608 /* Process outputs. */
2609 for (int i=1; ; i++) {
2610 const Outfit *o;
2611 PilotOutfitSlot *s;
2612
2613 lua_rawgeti(L,2,i);
2614 if (lua_isnil(L,-1)) {
2615 lua_pop(L,1);
2616 break;
2617 }
2618
2619 if (i > array_size(p->outfits)) {
2620 WARN(_("Trying to equip more outfits than slots available on pilot '%s'!"), p->name);
2621 lua_pop(L,1);
2622 break;
2623 }
2624
2625 /* No outfit. */
2626 if (!lua_toboolean(L,-1))
2627 continue;
2628
2629 o = luaL_validoutfit(L,-1);
2630 s = p->outfits[i-1];
2631 ret |= pilot_outfitAddSlot( p, o, s, 1, 1 );
2632
2633 lua_pop(L,1);
2634 }
2635 lua_pushboolean(L,!ret);
2636 return 1;
2637}
2638
2647static int pilotL_outfitGet( lua_State *L )
2648{
2649 /* Parse parameters */
2650 const Pilot *p = luaL_validpilot(L,1);
2651 int id = luaL_checkinteger(L,2)-1;
2652 if (id < 0 || id >= array_size(p->outfits))
2653 return NLUA_ERROR(L, _("Pilot '%s' outfit ID '%d' is out of range!"), p->name, id);
2654
2655 if (p->outfits[id]->outfit != NULL)
2656 lua_pushoutfit( L, p->outfits[id]->outfit );
2657 else
2658 lua_pushnil( L );
2659 return 1;
2660}
2661
2662static int outfitToggle( lua_State *L, Pilot *p, int id, int activate )
2663{
2664 if (id < 0 || id >= array_size(p->outfits))
2665 return NLUA_ERROR(L, _("Pilot '%s' outfit ID '%d' is out of range!"), p->name, id);
2666
2667 PilotOutfitSlot *po = p->outfits[id];
2668 const Outfit *o = po->outfit;
2669
2670 /* Ignore NULL outfits. */
2671 if (o == NULL)
2672 return 0;
2673
2674 if ((activate && (po->state != PILOT_OUTFIT_OFF)) ||
2675 (!activate && (po->state != PILOT_OUTFIT_ON)))
2676 return 0;
2677
2678 if (activate)
2679 return pilot_outfitOn( p, po );
2680 else
2681 return pilot_outfitOff( p, po );
2682}
2691static int pilotL_outfitToggle( lua_State *L )
2692{
2693 Pilot *p = luaL_validpilot(L,1);
2694 int activate = lua_toboolean(L,3);
2695 int n;
2696
2697 /* Can't do a thing. */
2698 if ((pilot_isDisabled(p)) || (pilot_isFlag(p, PILOT_COOLDOWN)))
2699 return 0;
2700
2701 if (lua_istable(L,2)) {
2702 n = 0;
2703 lua_pushnil(L);
2704 while (lua_next(L, 1) != 0) {
2705 n += outfitToggle( L, p, luaL_checkinteger(L,-1)-1, activate );
2706 lua_pop(L,1);
2707 }
2708 lua_pop(L,1);
2709 }
2710 else
2711 n = outfitToggle( L, p, luaL_checkinteger(L,2)-1, activate );
2712
2713 /* See if we have to do updates. */
2714 if (n>0 && pilot_isFlag(p,PILOT_STEALTH))
2715 pilot_destealth( p ); /* pilot_destealth should run calcStats already. */
2716 else if (n>0 || pilotoutfit_modified)
2717 pilot_calcStats( p );
2718
2719 lua_pushboolean(L,n);
2720 return 1;
2721}
2722
2731static int pilotL_outfitReady( lua_State *L )
2732{
2733 /* Parse parameters */
2734 const Pilot *p = luaL_validpilot(L,1);
2735 int id = luaL_checkinteger(L,2)-1;
2736 if (id < 0 || id >= array_size(p->outfits))
2737 return NLUA_ERROR(L, _("Pilot '%s' outfit ID '%d' is out of range!"), p->name, id);
2738
2739 if (p->outfits[id]->outfit != NULL)
2740 lua_pushboolean( L, p->outfits[id]->state==PILOT_OUTFIT_OFF );
2741 else
2742 lua_pushboolean( L, 0 );
2743 return 1;
2744}
2745
2755static int pilotL_rename( lua_State *L )
2756{
2757 /* Parse parameters */
2758 Pilot *p = luaL_validpilot(L,1);
2759 const char *name = luaL_checkstring(L,2);
2760
2761 /* Change name. */
2762 free(p->name);
2763 p->name = strdup(name);
2764
2765 return 0;
2766}
2767
2777static int pilotL_position( lua_State *L )
2778{
2779 const Pilot *p = luaL_validpilot(L,1);
2780 lua_pushvector(L, p->solid.pos);
2781 return 1;
2782}
2783
2793static int pilotL_velocity( lua_State *L )
2794{
2795 const Pilot *p = luaL_validpilot(L,1);
2796 lua_pushvector(L, p->solid.vel);
2797 return 1;
2798}
2799
2809static int pilotL_isStopped( lua_State *L )
2810{
2811 const Pilot *p = luaL_validpilot(L,1);
2812 lua_pushboolean(L,(VMOD(p->solid.vel) < MIN_VEL_ERR));
2813 return 1;
2814}
2815
2825static int pilotL_signature( lua_State *L )
2826{
2827 const Pilot *p = luaL_validpilot(L,1);
2828 lua_pushnumber( L, p->ew_signature );
2829 return 1;
2830}
2831
2841static int pilotL_dir( lua_State *L )
2842{
2843 const Pilot *p = luaL_validpilot(L,1);
2844 lua_pushnumber( L, p->solid.dir );
2845 return 1;
2846}
2847
2857static int pilotL_temp( lua_State *L )
2858{
2859 const Pilot *p = luaL_validpilot(L,1);
2860 lua_pushnumber( L, p->heat_T );
2861 return 1;
2862}
2863
2873static int pilotL_mass( lua_State *L )
2874{
2875 const Pilot *p = luaL_validpilot(L,1);
2876 lua_pushnumber( L, p->solid.mass );
2877 return 1;
2878}
2879
2887static int pilotL_accel( lua_State *L )
2888{
2889 const Pilot *p = luaL_validpilot(L,1);
2890 lua_pushnumber( L, p->accel );
2891 return 1;
2892}
2893
2901static int pilotL_speed( lua_State *L )
2902{
2903 const Pilot *p = luaL_validpilot(L,1);
2904 lua_pushnumber( L, p->speed );
2905 return 1;
2906}
2907
2916static int pilotL_speed_max( lua_State *L )
2917{
2918 const Pilot *p = luaL_validpilot(L,1);
2919 lua_pushnumber( L, solid_maxspeed( &p->solid, p->speed, p->accel ) );
2920 return 1;
2921}
2922
2930static int pilotL_turn( lua_State *L )
2931{
2932 const Pilot *p = luaL_validpilot(L,1);
2933 lua_pushnumber( L, p->turn * 180. / M_PI ); /* TODO use radians. */
2934 return 1;
2935}
2936
2946static int pilotL_faction( lua_State *L )
2947{
2948 const Pilot *p = luaL_validpilot(L,1);
2949 lua_pushfaction(L,p->faction);
2950 return 1;
2951}
2952
2961static int pilotL_areEnemies( lua_State *L )
2962{
2963 const Pilot *p = luaL_validpilot(L,1);
2964 const Pilot *t = luaL_validpilot(L,2);
2965 lua_pushboolean(L,pilot_areEnemies(p,t));
2966 return 1;
2967}
2968
2977static int pilotL_areAllies( lua_State *L )
2978{
2979 const Pilot *p = luaL_validpilot(L,1);
2980 const Pilot *t = luaL_validpilot(L,2);
2981 lua_pushboolean(L,pilot_areAllies(p,t));
2982 return 1;
2983}
2984
2997static int pilotL_spaceworthy( lua_State *L )
2998{
2999 char message[STRMAX_SHORT];
3000 const Pilot *p = luaL_validpilot(L,1);
3001 int worthy = !pilot_reportSpaceworthy( p, message, sizeof(message) );
3002 lua_pushboolean( L, worthy );
3003 lua_pushstring( L, message );
3004 return 2;
3005}
3006
3016static int pilotL_setPosition( lua_State *L )
3017{
3018 /* Parse parameters */
3019 Pilot *p = luaL_validpilot(L,1);
3020 const vec2 *vec = luaL_checkvector(L,2);
3021
3022 /* Insert skip in trail. */
3023 pilot_sample_trails( p, 1 );
3024
3025 /* Warp pilot to new position. */
3026 p->solid.pos = *vec;
3027
3028 /* Update if necessary. */
3029 if (pilot_isPlayer(p))
3030 cam_update( 0. );
3031
3032 return 0;
3033}
3034
3044static int pilotL_setVelocity( lua_State *L )
3045{
3046 /* Parse parameters */
3047 Pilot *p = luaL_validpilot(L,1);
3048 const vec2 *vec = luaL_checkvector(L,2);
3049
3050 /* Warp pilot to new position. */
3051 p->solid.vel = *vec;
3052 return 0;
3053}
3054
3066static int pilotL_setDir( lua_State *L )
3067{
3068 /* Parse parameters */
3069 Pilot *p = luaL_validpilot(L,1);
3070 double d = luaL_checknumber(L,2);
3071
3072 /* Set direction. */
3073 p->solid.dir = fmodf( d, 2*M_PI );
3074 if (p->solid.dir < 0.)
3075 p->solid.dir += 2*M_PI;
3076
3077 return 0;
3078}
3079
3092static int pilotL_broadcast( lua_State *L )
3093{
3094 /* Parse parameters. */
3095 if (lua_isstring(L,1)) {
3096 const char *s = luaL_checkstring(L,1);
3097 const char *msg = luaL_checkstring(L,2);
3098 const char *col = luaL_optstring(L,3,NULL);
3099
3100 player_message( _("#%cBroadcast %s>#0 \"%s\""), ((col==NULL)?'N':col[0]), s, msg );
3101 if (player.p)
3102 pilot_setCommMsg( player.p, msg );
3103 }
3104 else {
3105 Pilot *p = luaL_validpilot(L,1);
3106 const char *msg = luaL_checkstring(L,2);
3107 int ignore_int = lua_toboolean(L,3);
3108
3109 /* Broadcast message. */
3110 pilot_broadcast( p, msg, ignore_int );
3111 }
3112
3113 return 0;
3114}
3115
3132static int pilotL_comm( lua_State *L )
3133{
3134 if (lua_isstring(L,1)) {
3135 const char *s;
3136 const char *msg, *col;
3137 int raw;
3138
3139 if (player.p==NULL)
3140 return 0;
3141
3142 /* Parse parameters. */
3143 s = luaL_checkstring(L,1);
3144 if (lua_isstring(L,2)) {
3145 msg = luaL_checkstring(L,2);
3146 col = luaL_optstring(L,3,NULL);
3147 raw = lua_toboolean(L,4);
3148 }
3149 else {
3150 LuaPilot target = luaL_checkpilot(L,2);
3151 if (target != player.p->id)
3152 return 0;
3153 msg = luaL_checkstring(L,3);
3154 col = luaL_optstring(L,4,NULL);
3155 raw = lua_toboolean(L,5);
3156 }
3157
3158 /* Broadcast message. */
3159 if (raw)
3160 player_message( _("#%c%s>#0 %s"), ((col==NULL)?'N':col[0]), s, msg );
3161 else
3162 player_message( _("#%cComm %s>#0 \"%s\""), ((col==NULL)?'N':col[0]), s, msg );
3163 if (player.p)
3164 pilot_setCommMsg( player.p, msg );
3165 }
3166 else {
3167 Pilot *p;
3168 LuaPilot target;
3169 const char *msg;
3170 int ignore_int, raw;
3171
3172 /* Parse parameters. */
3173 p = luaL_validpilot(L,1);
3174 if (lua_isstring(L,2)) {
3175 target = 0;
3176 msg = luaL_checkstring(L,2);
3177 ignore_int = lua_toboolean(L,3);
3178 raw = lua_toboolean(L,4);
3179 }
3180 else {
3181 target = luaL_checkpilot(L,2);
3182 msg = luaL_checkstring(L,3);
3183 ignore_int = lua_toboolean(L,4);
3184 raw = lua_toboolean(L,5);
3185 }
3186
3187 if (player.p==NULL)
3188 return 0;
3189
3190 if (!ignore_int && !pilot_inRangePilot( player.p, p, NULL ))
3191 return 0;
3192
3193 /* Broadcast message. */
3194 if (target == 0 || target == PLAYER_ID) {
3195 char c = pilot_getFactionColourChar( p );
3196 if (raw)
3197 player_message( _("#%c%s>#0 %s"), c, p->name, msg );
3198 else
3199 player_message( _("#%cComm %s>#0 \"%s\""), c, p->name, msg );
3200
3201 /* Set comm message. */
3202 pilot_setCommMsg( p, msg );
3203 }
3204 }
3205 return 0;
3206}
3207
3218static int pilotL_setFaction( lua_State *L )
3219{
3220 /* Parse parameters. */
3221 Pilot *p = luaL_validpilot(L,1);
3222 int fid = luaL_validfaction(L,2);
3223 /* Set the new faction. */
3224 p->faction = fid;
3225 return 0;
3226}
3227
3238static int pilotL_setHostile( lua_State *L )
3239{
3240 /* Get the pilot. */
3241 Pilot *p = luaL_validpilot(L,1);
3242 int state;
3243
3244 /* Get state. */
3245 if (lua_isnone(L,2))
3246 state = 1;
3247 else
3248 state = lua_toboolean(L, 2);
3249
3250 /* Set as hostile. */
3251 if (state)
3253 else
3254 pilot_rmHostile(p);
3255
3256 return 0;
3257}
3258
3269static int pilotL_setFriendly( lua_State *L )
3270{
3271 /* Get the pilot. */
3272 Pilot *p = luaL_validpilot(L,1);
3273 int state;
3274
3275 /* Get state. */
3276 if (lua_isnone(L,2))
3277 state = 1;
3278 else
3279 state = lua_toboolean(L, 2);
3280
3281 /* Remove hostile and mark as friendly. */
3282 if (state)
3284 /* Remove friendly flag. */
3285 else
3287
3288 return 0;
3289}
3290
3302static int pilotL_setInvincible( lua_State *L )
3303{
3304 return pilotL_setFlagWrapper( L, PILOT_INVINCIBLE );
3305}
3306
3318static int pilotL_setInvincPlayer( lua_State *L )
3319{
3320 return pilotL_setFlagWrapper( L, PILOT_INVINC_PLAYER );
3321}
3322
3337static int pilotL_setHide( lua_State *L )
3338{
3339 return pilotL_setFlagWrapper( L, PILOT_HIDE );
3340}
3341
3352static int pilotL_setInvisible( lua_State *L )
3353{
3354 return pilotL_setFlagWrapper( L, PILOT_INVISIBLE );
3355}
3356
3367static int pilotL_setNoRender( lua_State *L )
3368{
3369 return pilotL_setFlagWrapper( L, PILOT_NORENDER );
3370}
3371
3383static int pilotL_setVisplayer( lua_State *L )
3384{
3385 return pilotL_setFlagWrapper( L, PILOT_VISPLAYER );
3386}
3387
3399static int pilotL_setVisible( lua_State *L )
3400{
3401 return pilotL_setFlagWrapper( L, PILOT_VISIBLE );
3402}
3403
3415static int pilotL_setHilight( lua_State *L )
3416{
3417 return pilotL_setFlagWrapper( L, PILOT_HILIGHT );
3418}
3419
3429static int pilotL_setBribed( lua_State *L )
3430{
3431 return pilotL_setFlagWrapper( L, PILOT_BRIBED );
3432}
3433
3443static int pilotL_setActiveBoard( lua_State *L )
3444{
3445 return pilotL_setFlagWrapper( L, PILOT_BOARDABLE );
3446}
3447
3457static int pilotL_setNoDeath( lua_State *L )
3458{
3459 return pilotL_setFlagWrapper( L, PILOT_NODEATH );
3460}
3461
3471static int pilotL_disable( lua_State *L )
3472{
3473 /* Get the pilot. */
3474 Pilot *p = luaL_validpilot(L,1);
3475 int permanent = !lua_toboolean(L,2);
3476
3477 /* Disable the pilot. */
3478 p->shield = 0.;
3479 p->stress = p->armour;
3480 pilot_updateDisable(p, 0);
3481
3482 if (permanent)
3483 pilot_setFlag(p, PILOT_DISABLED_PERM);
3484 else
3485 pilot_rmFlag(p, PILOT_DISABLED_PERM);
3486
3487 return 0;
3488}
3489
3500static int pilotL_cooldown( lua_State *L )
3501{
3502 const Pilot *p = luaL_validpilot(L,1);
3503 lua_pushboolean( L, pilot_isFlag(p, PILOT_COOLDOWN) );
3504 lua_pushboolean( L, pilot_isFlag(p, PILOT_COOLDOWN_BRAKE) );
3505 return 2;
3506}
3507
3517static int pilotL_setCooldown( lua_State *L )
3518{
3519 /* Get the pilot. */
3520 Pilot *p = luaL_validpilot(L,1);
3521 int state;
3522
3523 /* Get state. */
3524 if (lua_isnone(L,2))
3525 state = 1;
3526 else
3527 state = lua_toboolean(L, 2);
3528
3529 /* Set status. */
3530 if (state)
3531 pilot_cooldown( p, 1 );
3532 else
3533 pilot_cooldownEnd(p, NULL);
3534
3535 return 0;
3536}
3537
3544static int pilotL_cooldownCycle( lua_State *L )
3545{
3546 Pilot *p = luaL_validpilot(L,1);
3547 pilot_cooldown( p, 0 );
3548 p->ctimer = -1.;
3549 pilot_rmFlag(p, PILOT_COOLDOWN_BRAKE); /* Should allow triggering. */
3550 pilot_cooldownEnd( p, NULL );
3551 return 0;
3552}
3553
3563static int pilotL_setNoJump( lua_State *L )
3564{
3565 return pilotL_setFlagWrapper( L, PILOT_NOJUMP );
3566}
3567
3577static int pilotL_setNoLand( lua_State *L )
3578{
3579 return pilotL_setFlagWrapper( L, PILOT_NOLAND );
3580}
3581
3591static int pilotL_setNoClear( lua_State *L )
3592{
3593 return pilotL_setFlagWrapper( L, PILOT_NOCLEAR );
3594}
3595
3601static int pilot_outfitAddSlot( Pilot *p, const Outfit *o, PilotOutfitSlot *s, int bypass_cpu, int bypass_slot)
3602{
3603 int ret;
3604
3605 /* Must not have outfit (excluding default) already. */
3606 if ((s->outfit != NULL) &&
3607 (s->outfit != s->sslot->data))
3608 return 0;
3609
3610 /* Only do a basic check. */
3611 if (bypass_slot) {
3612 if (!outfit_fitsSlotType( o, &s->sslot->slot ))
3613 return 0;
3614 }
3615 else if (bypass_cpu) {
3616 if (!outfit_fitsSlot( o, &s->sslot->slot ))
3617 return 0;
3618 }
3619 /* Full check. */
3620 else {
3621 /* Must fit slot. */
3622 if (!outfit_fitsSlot( o, &s->sslot->slot ))
3623 return 0;
3624
3625 /* Test if can add outfit. */
3626 ret = pilot_addOutfitTest( p, o, s, 0 );
3627 if (ret)
3628 return -1;
3629 }
3630
3631 /* Add outfit - already tested. */
3632 ret = pilot_addOutfitRaw( p, o, s );
3633 if (ret==0) {
3634 pilot_outfitLInit( p, s );
3635
3636 /* Add ammo if needed. */
3637 pilot_addAmmo( p, s, pilot_maxAmmoO(p,o) );
3638 }
3639
3640 /* Update GUI if necessary. */
3641 if (pilot_isPlayer(p))
3642 gui_setShip();
3643
3644 return 1;
3645}
3646
3663static int pilotL_outfitAdd( lua_State *L )
3664{
3665 Pilot *p;
3666 const Outfit *o;
3667 int q, added, bypass_cpu, bypass_slot, slotid;
3668
3669 /* Get parameters. */
3670 p = luaL_validpilot(L,1);
3671 o = luaL_validoutfit(L,2);
3672 q = luaL_optinteger(L,3,1);
3673 bypass_cpu = lua_toboolean(L,4);
3674 bypass_slot = lua_toboolean(L,5);
3675
3676 /* Add outfit. */
3677 added = 0;
3678 slotid = -1;
3679 for (int i=0; i<array_size(p->outfits); i++) {
3680 int ret;
3681 PilotOutfitSlot *s = p->outfits[i];
3682
3683 /* Must still have to add outfit. */
3684 if (q <= 0)
3685 break;
3686
3687 /* Do tests and try to add. */
3688 ret = pilot_outfitAddSlot( p, o, s, bypass_cpu, bypass_slot );
3689 if (ret < 0)
3690 break;
3691 else if (ret==0)
3692 continue;
3693
3694 /* We added an outfit. */
3695 q--;
3696 added++;
3697 if (slotid < 0)
3698 slotid = i;
3699 }
3700
3701 /* Update stats. */
3702 if (added > 0) {
3703 pilot_calcStats( p );
3704
3705 /* Update the weapon sets. */
3706 if (p->autoweap)
3708
3709 /* Update equipment window if operating on the player's pilot. */
3710 if (player.p != NULL && player.p == p)
3712
3713 /* Update GUI if necessary. */
3714 if (pilot_isPlayer(p))
3715 gui_setShip();
3716 }
3717
3718 lua_pushnumber(L,added);
3719 if (slotid < 0)
3720 return 1;
3721 lua_pushinteger(L,slotid+1);
3722 return 2;
3723}
3724
3733static int pilotL_outfitSlot( lua_State *L )
3734{
3735 Pilot *p = luaL_validpilot(L,1);
3736 const PilotOutfitSlot *s= luaL_checkslot( L, p, 2 );
3737 if (s==NULL)
3738 return 0;
3739 if (s->outfit) {
3740 lua_pushoutfit(L,s->outfit);
3741 return 1;
3742 }
3743 return 0;
3744}
3745
3757static int pilotL_outfitAddSlot( lua_State *L )
3758{
3759 Pilot *p;
3760 const Outfit *o;
3761 int ret, added, bypass_cpu, bypass_slot;
3762 PilotOutfitSlot *s;
3763
3764 /* Get parameters. */
3765 p = luaL_validpilot(L,1);
3766 o = luaL_validoutfit(L,2);
3767 s = luaL_checkslot( L, p, 3 );
3768 bypass_cpu = lua_toboolean(L,4);
3769 bypass_slot = lua_toboolean(L,5);
3770 if (s==NULL)
3771 return 0;
3772
3773 /* Try to add. */
3774 ret = pilot_outfitAddSlot( p, o, s, bypass_cpu, bypass_slot );
3775 added = (ret>0);
3776
3777 /* Update stats. */
3778 if (added > 0) {
3779 pilot_calcStats( p );
3780
3781 /* Update the weapon sets. */
3782 if (p->autoweap)
3784
3785 /* Update equipment window if operating on the player's pilot. */
3786 if (player.p != NULL && player.p == p)
3788
3789 /* Update GUI if necessary. */
3790 if (pilot_isPlayer(p))
3791 gui_setShip();
3792 }
3793
3794 lua_pushboolean(L,added);
3795 return 1;
3796}
3797
3815static int pilotL_outfitRm( lua_State *L )
3816{
3817 Pilot *p;
3818 int q, removed, matched = 0;
3819
3820 /* Get parameters. */
3821 removed = 0;
3822 p = luaL_validpilot(L,1);
3823 q = luaL_optinteger(L,3,1);
3824
3825 if (lua_isstring(L,2)) {
3826 const char *outfit = luaL_checkstring(L,2);
3827
3828 /* If outfit is "all", we remove everything except cores and locked outfits. */
3829 if (strcmp(outfit,"all")==0) {
3830 for (int i=0; i<array_size(p->outfits); i++) {
3831 if (p->outfits[i]->sslot->required)
3832 continue;
3833 if (p->outfits[i]->sslot->locked)
3834 continue;
3835 pilot_rmOutfitRaw( p, p->outfits[i] );
3836 removed++;
3837 }
3838 pilot_calcStats( p ); /* Recalculate stats. */
3839 matched = 1;
3840 }
3841 /* If outfit is "cores", we remove cores only. */
3842 else if (strcmp(outfit,"cores")==0) {
3843 for (int i=0; i<array_size(p->outfits); i++) {
3844 if (!p->outfits[i]->sslot->required)
3845 continue;
3846 pilot_rmOutfitRaw( p, p->outfits[i] );
3847 removed++;
3848 }
3849 pilot_calcStats( p ); /* Recalculate stats. */
3850 matched = 1;
3851 }
3852 /* Purpose fallthrough for if the outfit is passed as a string. */
3853 }
3854
3855 if (!matched) {
3856 const Outfit *o = luaL_validoutfit(L,2);
3857
3858 /* Remove the outfit outfit. */
3859 for (int i=0; i<array_size(p->outfits); i++) {
3860 /* Must still need to remove. */
3861 if (q <= 0)
3862 break;
3863
3864 /* Not found. */
3865 if (p->outfits[i]->outfit != o)
3866 continue;
3867
3868 /* Remove outfit. */
3869 pilot_rmOutfit( p, p->outfits[i] );
3870 q--;
3871 removed++;
3872 }
3873 }
3874
3875 /* Update equipment window if operating on the player's pilot. */
3876 if (player.p != NULL && player.p == p && removed > 0)
3878
3879 lua_pushnumber( L, removed );
3880 return 1;
3881}
3882
3894static int pilotL_outfitRmSlot( lua_State *L )
3895{
3896 /* Get parameters. */
3897 int ret;
3898 Pilot *p = luaL_validpilot(L,1);
3899 PilotOutfitSlot *s = luaL_checkslot( L, p, 2 );
3900 if (s==NULL)
3901 return 0;
3902
3903 ret = !pilot_rmOutfitRaw( p, s );
3904 if (ret) {
3905 pilot_calcStats( p ); /* Recalculate stats. */
3906 /* Update equipment window if operating on the player's pilot. */
3907 if (player.p != NULL && player.p == p)
3909 }
3910
3911 lua_pushboolean( L, ret );
3912 return 1;
3913}
3914
3925static int pilotL_outfitAddIntrinsic( lua_State *L )
3926{
3927 Pilot *p = luaL_validpilot(L,1);
3928 const Outfit *o = luaL_validoutfit(L,2);
3929 int ret = pilot_addOutfitIntrinsic( p, o );
3930 if (ret==0)
3931 pilot_calcStats(p);
3932 lua_pushboolean(L,ret);
3933
3934 /* Update GUI if necessary. */
3935 if (pilot_isPlayer(p))
3936 gui_setShip();
3937 return 1;
3938}
3939
3951static int pilotL_outfitRmIntrinsic( lua_State *L )
3952{
3953 Pilot *p = luaL_validpilot(L,1);
3954 const Outfit *o = luaL_validoutfit(L,2);
3955 lua_pushboolean(L,pilot_rmOutfitIntrinsic( p, o ));
3956 return 1;
3957}
3958
3965static int pilotL_getFuel( lua_State *L )
3966{
3967 const Pilot *p = luaL_validpilot(L,1);
3968 lua_pushnumber(L, p->fuel);
3969 return 1;
3970}
3971
3983static int pilotL_setFuel( lua_State *L )
3984{
3985 Pilot *p = luaL_validpilot(L,1);
3986
3987 /* Get the parameter. */
3988 if (lua_isboolean(L,2)) {
3989 if (lua_toboolean(L,2))
3990 p->fuel = p->fuel_max;
3991 else
3992 p->fuel = 0;
3993 }
3994 else if (lua_isnumber(L,2)) {
3995 p->fuel = CLAMP( 0, p->fuel_max, lua_tonumber(L,2) );
3996 }
3997 else
3998 NLUA_INVALID_PARAMETER(L,2);
3999
4000 /* Return amount of fuel. */
4001 lua_pushnumber(L, p->fuel);
4002 return 1;
4003}
4004
4010static int pilotL_intrinsicReset( lua_State *L )
4011{
4012 Pilot *p = luaL_validpilot(L,1);
4013 ss_free( p->intrinsic_stats );
4014 p->intrinsic_stats = NULL;
4015 pilot_calcStats( p );
4016 return 0;
4017}
4018
4030static int pilotL_intrinsicSet( lua_State *L )
4031{
4032 Pilot *p = luaL_validpilot(L,1);
4033 const char *name;
4034 double value;
4035 int replace;
4036 /* Case individual parameter. */
4037 if (!lua_istable(L,2)) {
4038 name = luaL_checkstring(L,2);
4039 value = luaL_checknumber(L,3);
4040 replace = lua_toboolean(L,4);
4041 p->intrinsic_stats = ss_statsSetList( p->intrinsic_stats, ss_typeFromName(name), value, replace, 0 );
4042 pilot_calcStats( p );
4043 return 0;
4044 }
4045 replace = lua_toboolean(L,4);
4046 /* Case set of parameters. */
4047 lua_pushnil(L);
4048 while (lua_next(L,2) != 0) {
4049 name = luaL_checkstring(L,-2);
4050 value = luaL_checknumber(L,-1);
4051 p->intrinsic_stats = ss_statsSetList( p->intrinsic_stats, ss_typeFromName(name), value, replace, 0 );
4052 lua_pop(L,1);
4053 }
4054 lua_pop(L,1);
4055 pilot_calcStats( p );
4056 return 0;
4057}
4058
4068static int pilotL_intrinsicGet( lua_State *L )
4069{
4070 const Pilot *p = luaL_validpilot(L,1);
4071 const char *name = luaL_optstring(L,2,NULL);
4072 int internal = lua_toboolean(L,3);
4073 ShipStats ss;
4074 /* TODO get directly the stat from the list. */
4075 ss_statsInit( &ss );
4076 ss_statsMergeFromList( &ss, p->intrinsic_stats );
4077 ss_statsGetLua( L, &ss, name, internal );
4078 return 1;
4079}
4080
4081
4087static int pilotL_shippropReset( lua_State *L )
4088{
4089 Pilot *p = luaL_validpilot(L,1);
4090 ss_free( p->ship_stats );
4091 p->ship_stats = NULL;
4092 pilot_calcStats( p );
4093 return 0;
4094}
4095
4106static int pilotL_shippropSet( lua_State *L )
4107{
4108 /* TODO merge with intrinsicSet */
4109 Pilot *p = luaL_validpilot(L,1);
4110 const char *name;
4111 double value;
4112
4113 if (p->ship->lua_env == LUA_NOREF)
4114 return NLUA_ERROR(L,_("Trying to set ship property of pilot '%s' flying ship '%s' with no ship Lua enabled!"), p->name, p->ship->name);
4115
4116 /* Case individual parameter. */
4117 if (!lua_istable(L,2)) {
4118 name = luaL_checkstring(L,2);
4119 value = luaL_checknumber(L,3);
4120 p->ship_stats = ss_statsSetList( p->ship_stats, ss_typeFromName(name), value, 1, 0 );
4121 pilot_calcStats( p );
4122 return 0;
4123 }
4124 /* Case set of parameters. */
4125 lua_pushnil(L);
4126 while (lua_next(L,2) != 0) {
4127 name = luaL_checkstring(L,-2);
4128 value = luaL_checknumber(L,-1);
4129 p->ship_stats = ss_statsSetList( p->ship_stats, ss_typeFromName(name), value, 1, 0 );
4130 lua_pop(L,1);
4131 }
4132 lua_pop(L,1);
4133 pilot_calcStats( p );
4134 return 0;
4135}
4136
4146static int pilotL_shippropGet( lua_State *L )
4147{
4148 const Pilot *p = luaL_validpilot(L,1);
4149 const char *name = luaL_optstring(L,2,NULL);
4150 int internal = lua_toboolean(L,3);
4151 ShipStats ss;
4152 /* TODO get directly the stat from the list. */
4153 ss_statsInit( &ss );
4154 ss_statsMergeFromList( &ss, p->ship_stats );
4155 ss_statsGetLua( L, &ss, name, internal );
4156 return 1;
4157}
4158
4168static int pilotL_effectClear( lua_State *L )
4169{
4170 Pilot *p = luaL_validpilot(L,1);
4171 int keepdebuffs = lua_toboolean(L,2);
4172 int keepbuffs = lua_toboolean(L,3);
4173 int keepothers = lua_toboolean(L,4);
4174 if (!keepdebuffs && !keepbuffs && !keepothers)
4175 effect_clear( &p->effects );
4176 else
4177 effect_clearSpecific( &p->effects, !keepdebuffs, !keepbuffs, !keepothers );
4178 pilot_calcStats( p );
4179 return 0;
4180}
4181
4192static int pilotL_effectAdd( lua_State *L )
4193{
4194 Pilot *p = luaL_validpilot(L,1);
4195 const char *effectname = luaL_checkstring(L,2);
4196 double duration = luaL_optnumber(L,3,-1.);
4197 double scale = luaL_optnumber(L,4,1.);
4198 const EffectData *efx = effect_get( effectname );
4199 if (efx != NULL) {
4200 if (!effect_add( &p->effects, efx, duration, scale, p->id ))
4201 pilot_calcStats( p );
4202 lua_pushboolean(L,1);
4203 }
4204 else
4205 lua_pushboolean(L,0);
4206 return 1;
4207}
4208
4217static int pilotL_effectRm( lua_State *L )
4218{
4219 Pilot *p = luaL_validpilot(L,1);
4220 if (lua_isnumber(L,2)) {
4221 int idx = lua_tointeger(L,2);
4222 if (effect_rm( &p->effects, idx ))
4223 pilot_calcStats( p );
4224 }
4225 else {
4226 const char *effectname = luaL_checkstring(L,2);
4227 int all = lua_toboolean(L,3);
4228 const EffectData *efx = effect_get( effectname );
4229 if (efx != NULL) {
4230 if (effect_rmType( &p->effects, efx, all ))
4231 pilot_calcStats( p );
4232 }
4233 }
4234 return 0;
4235}
4236
4244static int pilotL_effectGet( lua_State *L )
4245{
4246 const Pilot *p = luaL_validpilot(L,1);
4247 lua_newtable(L);
4248 for (int i=0; i<array_size(p->effects); i++) {
4249 const Effect *e = &p->effects[i];
4250 lua_newtable(L);
4251
4252 lua_pushstring(L,e->data->name);
4253 lua_setfield(L,-2,"name");
4254
4255 lua_pushnumber(L,e->timer);
4256 lua_setfield(L,-2,"timer");
4257
4258 lua_pushnumber(L,e->timer);
4259 lua_setfield(L,-2,"strength");
4260
4261 lua_pushnumber(L,e->data->duration);
4262 lua_setfield(L,-2,"duration");
4263
4265 lua_setfield(L,-2,"icon");
4266
4267 if (e->data->flags & EFFECT_BUFF) {
4268 lua_pushboolean(L,1);
4269 lua_setfield(L,-2,"buff");
4270 }
4271
4272 if (e->data->flags & EFFECT_DEBUFF) {
4273 lua_pushboolean(L,1);
4274 lua_setfield(L,-2,"debuff");
4275 }
4276
4277 lua_rawseti(L,-2,i+1);
4278 }
4279 return 1;
4280}
4281
4289static int pilotL_ai( lua_State *L )
4290{
4291 const Pilot *p = luaL_validpilot(L,1);
4292 if (p->ai == NULL)
4293 return 0;
4294 lua_pushstring( L, p->ai->name );
4295 return 1;
4296}
4297
4307static int pilotL_changeAI( lua_State *L )
4308{
4309 int ret;
4310 /* Get parameters. */
4311 Pilot *p = luaL_validpilot(L,1);
4312 const char *str = luaL_checkstring(L,2);
4313
4314 /* Get rid of current AI. */
4315 ai_destroy(p);
4316
4317 /* Create the new AI. */
4318 ret = ai_pinit( p, str );
4319 lua_pushboolean(L, ret);
4320 return 1;
4321}
4322
4337static int pilotL_setTemp( lua_State *L )
4338{
4339 Pilot *p;
4340 int setOutfits = 1;
4341 double kelvins;
4342
4343 /* Handle parameters. */
4344 p = luaL_validpilot(L,1);
4345 kelvins = luaL_checknumber(L, 2);
4346 setOutfits = !lua_toboolean(L,3);
4347
4348 /* Temperature must not go below base temp. */
4349 kelvins = MAX(kelvins, CONST_SPACE_STAR_TEMP);
4350
4351 /* Handle pilot ship. */
4352 p->heat_T = kelvins;
4353
4354 /* Handle pilot outfits (maybe). */
4355 if (setOutfits)
4356 for (int i=0; i < array_size(p->outfits); i++)
4357 p->outfits[i]->heat_T = kelvins;
4358
4359 return 0;
4360}
4361
4377static int pilotL_setHealth( lua_State *L )
4378{
4379 Pilot *p;
4380 double a, s, st;
4381
4382 /* Handle parameters. */
4383 p = luaL_validpilot(L,1);
4384 a = luaL_optnumber(L, 2, 100.*p->armour / p->armour_max);
4385 s = luaL_optnumber(L, 3, 100.*p->shield / p->shield_max);
4386 st = luaL_optnumber(L,4,0.);
4387
4388 a /= 100.;
4389 s /= 100.;
4390 st /= 100.;
4391
4392 /* Set health. */
4393 p->armour = a * p->armour_max;
4394 p->shield = s * p->shield_max;
4395 p->stress = st * p->armour;
4396
4397 /* Clear death hooks if not dead. */
4398 if (p->armour > 0.) {
4399 pilot_rmFlag( p, PILOT_DISABLED );
4400 pilot_rmFlag( p, PILOT_DEAD );
4401 pilot_rmFlag( p, PILOT_DEATH_SOUND );
4402 pilot_rmFlag( p, PILOT_EXPLODED );
4403 pilot_rmFlag( p, PILOT_DELETE );
4404 if (pilot_isPlayer(p))
4405 player_rmFlag( PLAYER_DESTROYED );
4406 }
4407 pilot_rmFlag( p, PILOT_DISABLED_PERM ); /* Remove permanent disable. */
4408
4409 /* Update disable status. */
4410 pilot_updateDisable(p, 0);
4411
4412 return 0;
4413}
4414
4426static int pilotL_setHealthAbs( lua_State *L )
4427{
4428 Pilot *p;
4429 double a, s, st;
4430
4431 /* Handle parameters. */
4432 p = luaL_validpilot(L,1);
4433 a = luaL_optnumber(L, 2, p->armour);
4434 s = luaL_optnumber(L, 3, p->shield);
4435 st = luaL_optnumber(L,4,p->stress);
4436
4437 /* Set health. */
4438 p->armour = CLAMP( 0., p->armour_max, a );
4439 p->shield = CLAMP( 0., p->shield_max, s );
4440 p->stress = CLAMP( 0., p->armour_max, st );
4441
4442 /* Clear death hooks if not dead. */
4443 if (p->armour > 0.) {
4444 pilot_rmFlag( p, PILOT_DISABLED );
4445 pilot_rmFlag( p, PILOT_DEAD );
4446 pilot_rmFlag( p, PILOT_DEATH_SOUND );
4447 pilot_rmFlag( p, PILOT_EXPLODED );
4448 pilot_rmFlag( p, PILOT_DELETE );
4449 if (pilot_isPlayer(p))
4450 player_rmFlag( PLAYER_DESTROYED );
4451 }
4452 pilot_rmFlag( p, PILOT_DISABLED_PERM ); /* Remove permanent disable. */
4453
4454 /* Update disable status. */
4455 pilot_updateDisable(p, 0);
4456
4457 return 0;
4458}
4459
4470static int pilotL_addHealth( lua_State *L )
4471{
4472 Pilot *p;
4473 double a, s;
4474
4475 /* Handle parameters. */
4476 p = luaL_validpilot(L,1);
4477 a = luaL_optnumber(L, 2, 0.);
4478 s = luaL_optnumber(L, 3, 0.);
4479
4480 /* Set health. */
4481 p->armour = CLAMP( 0., p->armour_max, p->armour + a );
4482 p->shield = CLAMP( 0., p->shield_max, p->shield + s );
4483
4484 /* Update disable status. */
4485 pilot_updateDisable(p, 0);
4486
4487 return 0;
4488}
4489
4501static int pilotL_setEnergy( lua_State *L )
4502{
4503 /* Handle parameters. */
4504 Pilot *p = luaL_validpilot(L,1);
4505 double e = luaL_checknumber(L,2);
4506 int absolute = lua_toboolean(L,3);
4507
4508 if (absolute)
4509 p->energy = CLAMP( 0., p->energy_max, e );
4510 else
4511 p->energy = (e/100.) * p->energy_max;
4512
4513 return 0;
4514}
4515
4523static int pilotL_addEnergy( lua_State *L )
4524{
4525 /* Handle parameters. */
4526 Pilot *p = luaL_validpilot(L,1);
4527 double e = luaL_checknumber(L,2);
4528 p->energy = CLAMP( 0., p->energy_max, p->energy+e );
4529 return 0;
4530}
4531
4538static int pilotL_fillAmmo( lua_State *L )
4539{
4540 Pilot *p = luaL_validpilot(L,1);
4541 pilot_fillAmmo( p );
4542 return 0;
4543}
4544
4557static int pilotL_setNoBoard( lua_State *L )
4558{
4559 Pilot *p = luaL_validpilot(L,1);
4560 int disable;
4561 if (lua_isnone(L,2))
4562 disable = 1;
4563 else
4564 disable = lua_toboolean(L, 2);
4565
4566 /* See if should prevent boarding. */
4567 if (disable)
4568 pilot_setFlag(p, PILOT_NOBOARD);
4569 else
4570 pilot_rmFlag(p, PILOT_NOBOARD);
4571
4572 return 0;
4573}
4574
4587static int pilotL_setNoDisable( lua_State *L )
4588{
4589 Pilot *p = luaL_validpilot(L,1);
4590 int nodisable;
4591 if (lua_isnone(L,2))
4592 nodisable = 1;
4593 else
4594 nodisable = lua_toboolean(L, 2);
4595
4596 /* See if should prevent disabling. */
4597 if (nodisable)
4598 pilot_setFlag(p, PILOT_NODISABLE);
4599 else
4600 pilot_rmFlag(p, PILOT_NODISABLE);
4601
4602 return 0;
4603}
4604
4617static int pilotL_setSpeedLimit(lua_State* L)
4618{
4619 /* Handle parameters. */
4620 Pilot *p = luaL_validpilot(L,1);
4621 double s = luaL_checknumber(L, 2);
4622
4623 /* Limit the speed */
4624 p->speed_limit = s;
4625 if (s > 0.)
4626 pilot_setFlag( p, PILOT_HASSPEEDLIMIT );
4627 else
4628 pilot_rmFlag( p, PILOT_HASSPEEDLIMIT );
4629
4630 pilot_updateMass(p); /* Updates the true speed limit. */
4631 return 0;
4632}
4633
4647static int pilotL_getHealth( lua_State *L )
4648{
4649 const Pilot *p = luaL_validpilot(L,1);
4650 int absolute = lua_toboolean(L,2);
4651 /* Return parameters. */
4652 if (absolute) {
4653 lua_pushnumber(L, p->armour );
4654 lua_pushnumber(L, p->shield );
4655 }
4656 else {
4657 lua_pushnumber(L,(p->armour_max > 0.) ? p->armour / p->armour_max * 100. : 0. );
4658 lua_pushnumber(L,(p->shield_max > 0.) ? p->shield / p->shield_max * 100. : 0. );
4659 }
4660 lua_pushnumber(L, MIN( 1., p->stress / p->armour ) * 100. );
4661 lua_pushboolean(L, pilot_isDisabled(p));
4662 return 4;
4663}
4664
4675static int pilotL_getArmour( lua_State *L )
4676{
4677 const Pilot *p = luaL_validpilot(L,1);
4678 int absolute = lua_toboolean(L,2);
4679 if (absolute)
4680 lua_pushnumber(L, p->armour );
4681 else
4682 lua_pushnumber(L,(p->armour_max > 0.) ? p->armour / p->armour_max * 100. : 0. );
4683 return 1;
4684}
4685
4696static int pilotL_getShield( lua_State *L )
4697{
4698 const Pilot *p = luaL_validpilot(L,1);
4699 int absolute = lua_toboolean(L,2);
4700 if (absolute)
4701 lua_pushnumber(L, p->shield );
4702 else
4703 lua_pushnumber(L,(p->shield_max > 0.) ? p->shield / p->shield_max * 100. : 0. );
4704 return 1;
4705}
4706
4717static int pilotL_getEnergy( lua_State *L )
4718{
4719 const Pilot *p = luaL_validpilot(L,1);
4720 int absolute = lua_toboolean(L,2);
4721 if (absolute)
4722 lua_pushnumber(L, p->energy );
4723 else
4724 lua_pushnumber(L, (p->energy_max > 0.) ? p->energy / p->energy_max * 100. : 0. );
4725 return 1;
4726}
4727
4737static int pilotL_getLockon( lua_State *L )
4738{
4739 const Pilot *p = luaL_validpilot(L,1);
4740 lua_pushnumber(L, p->lockons );
4741 return 1;
4742}
4743
4744#define PUSH_DOUBLE( L, name, value ) \
4745lua_pushstring( L, name ); \
4746lua_pushnumber( L, value ); \
4747lua_rawset( L, -3 )
4748#define PUSH_INT( L, name, value ) \
4749lua_pushstring( L, name ); \
4750lua_pushinteger( L, value ); \
4751lua_rawset( L, -3 )
4785static int pilotL_getStats( lua_State *L )
4786{
4787 const Pilot *p = luaL_validpilot(L,1);
4788 /* Create table with information. */
4789 lua_newtable(L);
4790 /* Core. */
4791 PUSH_DOUBLE( L, "cpu", p->cpu );
4792 PUSH_INT( L, "cpu_max", p->cpu_max );
4793 PUSH_INT( L, "crew", (int)round( p->crew ) );
4794 PUSH_INT( L, "fuel", p->fuel );
4795 PUSH_INT( L, "fuel_max", p->fuel_max );
4796 PUSH_INT( L, "fuel_consumption", p->fuel_consumption );
4797 PUSH_DOUBLE( L, "mass", p->solid.mass );
4798 /* Movement. */
4799 PUSH_DOUBLE( L, "accel", p->accel );
4800 PUSH_DOUBLE( L, "speed", p->speed );
4801 PUSH_DOUBLE( L, "turn", p->turn*180./M_PI ); /* Convert back to grad. */
4802 PUSH_DOUBLE( L, "speed_max", solid_maxspeed(&p->solid, p->speed, p->accel) );
4803 /* Health. */
4804 PUSH_DOUBLE( L, "absorb", p->dmg_absorb );
4805 PUSH_DOUBLE( L, "armour", p->armour_max );
4806 PUSH_DOUBLE( L, "shield", p->shield_max );
4807 PUSH_DOUBLE( L, "energy", p->energy_max );
4808 PUSH_DOUBLE( L, "armour_regen", p->armour_regen );
4809 PUSH_DOUBLE( L, "shield_regen", p->shield_regen );
4810 PUSH_DOUBLE( L, "energy_regen", p->energy_regen );
4811 /* Stats. */
4812 PUSH_DOUBLE( L, "ew_detection", p->ew_detection );
4813 PUSH_DOUBLE( L, "ew_signature", p->ew_signature );
4814 PUSH_DOUBLE( L, "ew_stealth", p->ew_stealth );
4815 PUSH_DOUBLE( L, "jump_delay", ntime_convertSeconds( pilot_hyperspaceDelay(p) ) );
4816 PUSH_INT( L, "jumps", pilot_getJumps(p) );
4817
4818 return 1;
4819}
4820#undef PUSH_DOUBLE
4821#undef PUSH_INT
4822
4834static int pilotL_getShipStat( lua_State *L )
4835{
4836 const Pilot *p = luaL_validpilot(L,1);
4837 const char *str = luaL_optstring(L,2,NULL);
4838 int internal = lua_toboolean(L,3);
4839 ss_statsGetLua( L, &p->stats, str, internal );
4840 return 1;
4841}
4842
4849static int pilotL_getDetectedDistance( lua_State *L )
4850{
4851 const Pilot *p = luaL_validpilot(L,1);
4852 if (pilot_isFlag(p,PILOT_STEALTH))
4853 lua_pushnumber( L, p->ew_stealth );
4854 else
4855 lua_pushnumber( L, p->ew_detection );
4856 return 1;
4857}
4858
4866static int pilotL_cargoFree( lua_State *L )
4867{
4868 const Pilot *p = luaL_validpilot(L,1);
4869 lua_pushnumber(L, pilot_cargoFree(p) );
4870 return 1;
4871}
4872
4883static int pilotL_cargoHas( lua_State *L )
4884{
4885 const Pilot *p = luaL_validpilot(L, 1);
4886 const Commodity *cargo = luaL_validcommodity(L, 2);
4887 int quantity = pilot_cargoOwned(p, cargo);
4888 lua_pushnumber(L, quantity);
4889 return 1;
4890}
4891
4905static int pilotL_cargoAdd( lua_State *L )
4906{
4907 /* Parse parameters. */
4908 Pilot *p = luaL_validpilot(L, 1);
4909 const Commodity *cargo = luaL_validcommodity(L, 2);
4910 int quantity = luaL_checknumber(L, 3);
4911
4912 if (quantity < 0)
4913 return NLUA_ERROR( L, _("Quantity must be positive for pilot.cargoAdd (if removing, use pilot.cargoRm)") );
4914
4915 /* Try to add the cargo. */
4916 quantity = pilot_cargoAdd( p, cargo, quantity, 0 );
4917 lua_pushnumber( L, quantity );
4918 return 1;
4919}
4920
4921static int pilotL_cargoRmHelper( lua_State *L, int jet )
4922{
4923 Pilot *p;
4924 int quantity;
4925 Commodity *cargo = NULL;
4926
4927 /* Parse parameters. */
4928 p = luaL_validpilot(L, 1);
4929
4930 if (lua_isstring(L, 2)) {
4931 const char *str = lua_tostring(L, 2);
4932
4933 /* Check for special strings. */
4934 if (strcmp(str, "all") == 0) {
4935 quantity = pilot_cargoRmAll(p, 0);
4936 lua_pushnumber(L, quantity);
4937 return 1;
4938 }
4939 }
4940
4941 /* No special string handling, just handle as a normal commodity. */
4942 cargo = luaL_validcommodity(L, 2);
4943 quantity = luaL_checknumber(L, 3);
4944
4945 if (quantity < 0)
4946 return NLUA_ERROR(L,_("Quantity must be positive for pilot.cargoRm (if adding, use pilot.cargoAdd)"));
4947
4948 /* Try to remove the cargo. */
4949 if (jet)
4950 quantity = pilot_cargoJet( p, cargo, quantity, 0 );
4951 else
4952 quantity = pilot_cargoRm( p, cargo, quantity );
4953
4954 lua_pushnumber(L, quantity);
4955 return 1;
4956}
4957
4973static int pilotL_cargoRm( lua_State *L )
4974{
4975 return pilotL_cargoRmHelper( L, 0 );
4976}
4977
4990static int pilotL_cargoJet( lua_State *L )
4991{
4992 return pilotL_cargoRmHelper( L, 1 );
4993}
4994
5012static int pilotL_cargoList( lua_State *L )
5013{
5014 const Pilot *p = luaL_validpilot(L,1);
5015 lua_newtable(L); /* t */
5016 for (int i=0; i<array_size(p->commodities); i++) {
5017 PilotCommodity *pc = &p->commodities[i];
5018
5019 /* Represents the cargo. */
5020 lua_newtable(L); /* t, t */
5021
5022 lua_pushstring(L, "name"); /* t, t, i */
5023 lua_pushstring(L, pc->commodity->name); /* t, t, i, s */
5024 lua_rawset(L,-3); /* t, t */
5025
5026 lua_pushstring(L, "c"); /* t, t, i */
5027 lua_pushcommodity(L, (Commodity*)pc->commodity); /* t, t, i, s */
5028 lua_rawset(L,-3); /* t, t */
5029
5030 lua_pushstring(L, "q"); /* t, t, i */
5031 lua_pushnumber(L, pc->quantity); /* t, t, i, s */
5032 lua_rawset(L,-3); /* t, t */
5033
5034 lua_pushstring(L, "m"); /* t, t, i */
5035 lua_pushboolean(L, pc->id); /* t, t, i, s */
5036 lua_rawset(L,-3); /* t, t */
5037
5038 lua_rawseti(L,-2,i+1); /* t */
5039 }
5040 return 1;
5041
5042}
5043
5052static int pilotL_credits( lua_State *L )
5053{
5054 Pilot *p = luaL_validpilot(L,1);
5055 pilot_modCredits( p, luaL_optlong( L, 2, 0 ) );
5056 lua_pushnumber( L, p->credits );
5057 return 1;
5058}
5059
5068static int pilotL_worth( lua_State *L )
5069{
5070 const Pilot *p = luaL_validpilot(L,1);
5071 lua_pushnumber( L, pilot_worth(p, lua_toboolean(L,2)) );
5072 return 1;
5073}
5074
5084static int pilotL_getColour( lua_State *L )
5085{
5086 const Pilot *p = luaL_validpilot(L,1);
5087 const glColour *col = pilot_getColour(p);
5088 lua_pushcolour( L, *col );
5089 return 1;
5090}
5091
5099static int pilotL_colourChar( lua_State *L )
5100{
5101 const Pilot *p = luaL_validpilot(L,1);
5102 char str[2];
5103 str[0] = pilot_getFactionColourChar( p );
5104 str[1] = '\0';
5105 lua_pushstring(L,str);
5106 return 1;
5107}
5108
5118static int pilotL_getHostile( lua_State *L )
5119{
5120 const Pilot *p = luaL_validpilot(L,1);
5121 lua_pushboolean( L, pilot_isHostile( p ) );
5122 return 1;
5123}
5124
5128struct pL_flag {
5129 const char *name;
5130 int id;
5131};
5132static const struct pL_flag pL_flags[] = {
5133 { .name = "stealth", .id = PILOT_STEALTH },
5134 { .name = "refueling", .id = PILOT_REFUELING },
5135 { .name = "invisible", .id = PILOT_INVISIBLE },
5136 { .name = "disabled", .id = PILOT_DISABLED },
5137 { .name = "landing", .id = PILOT_LANDING },
5138 { .name = "takingoff", .id = PILOT_TAKEOFF },
5139 { .name = "jumpprep", .id = PILOT_HYP_PREP },
5140 { .name = "jumpingin", .id = PILOT_HYP_END },
5141 { .name = "jumpingout", .id = PILOT_HYPERSPACE },
5142 { .name = "manualcontrol", .id = PILOT_MANUAL_CONTROL },
5143 { .name = "carried", .id = PILOT_CARRIED },
5144 { .name = "hailing", .id = PILOT_HAILING },
5145 { .name = "bribed", .id = PILOT_BRIBED },
5146 { .name = "boardable", .id = PILOT_BOARDABLE },
5147 { .name = "nojump", .id = PILOT_NOJUMP },
5148 { .name = "noland", .id = PILOT_NOLAND },
5149 { .name = "nodeath", .id = PILOT_NODEATH },
5150 { .name = "nodisable", .id = PILOT_NODISABLE },
5151 { .name = "visible", .id = PILOT_VISIBLE },
5152 { .name = "visplayer", .id = PILOT_VISPLAYER },
5153 { .name = "hilight", .id = PILOT_HILIGHT },
5154 { .name = "norender", .id = PILOT_NORENDER },
5155 { .name = "hide", .id = PILOT_HIDE },
5156 { .name = "invincible", .id = PILOT_INVINCIBLE },
5157 { .name = "invinc_player", .id = PILOT_INVINC_PLAYER },
5158 { .name = "friendly", .id = PILOT_FRIENDLY },
5159 { .name = "hostile", .id = PILOT_HOSTILE },
5160 { .name = "combat", .id = PILOT_COMBAT },
5161 {NULL, -1}
5162};
5197static int pilotL_flags( lua_State *L )
5198{
5199 const Pilot *p = luaL_validpilot(L,1);
5200 const char *name = luaL_optstring( L, 2, NULL );
5201
5202 if (name != NULL) {
5203 for (int i=0; pL_flags[i].name != NULL; i++)
5204 if (strcmp(pL_flags[i].name,name)==0) {
5205 lua_pushboolean( L, pilot_isFlag( p, pL_flags[i].id ) );
5206 return 1;
5207 }
5208#if DEBUGGING
5209 WARN(_("Tried to access unknown flag '%s' for pilot '%s'!"), name, p->name);
5210#endif /* DEBUGGING */
5211 return 0;
5212 }
5213
5214 /* Create flag table. */
5215 lua_newtable(L);
5216 for (int i=0; pL_flags[i].name != NULL; i++) {
5217 lua_pushboolean( L, pilot_isFlag( p, pL_flags[i].id ) );
5218 lua_setfield(L, -2, pL_flags[i].name);
5219 }
5220 return 1;
5221}
5222
5230static int pilotL_hasIllegal( lua_State *L )
5231{
5232 const Pilot *p = luaL_validpilot(L,1);
5233 int f = luaL_validfaction(L,2);
5234 lua_pushboolean(L, pilot_hasIllegal(p,f));
5235 return 1;
5236}
5237
5247static int pilotL_ship( lua_State *L )
5248{
5249 const Pilot *p = luaL_validpilot(L,1);
5250 lua_pushship(L, p->ship);
5251 return 1;
5252}
5253
5261static int pilotL_radius( lua_State *L )
5262{
5263 const Pilot *p = luaL_validpilot(L,1);
5264 lua_pushnumber(L, PILOT_SIZE_APPROX * 0.5 * (p->ship->gfx_space->sw+p->ship->gfx_space->sh));
5265 return 1;
5266}
5267
5277static int pilotL_points( lua_State *L )
5278{
5279 const Pilot *p = luaL_validpilot(L,1);
5280 lua_pushinteger(L, p->ship->points);
5281 return 1;
5282}
5283
5293static int pilotL_idle( lua_State *L )
5294{
5295 const Pilot *p = luaL_validpilot(L,1);
5296 lua_pushboolean(L, p->task==0);
5297 return 1;
5298}
5299
5321static int pilotL_control( lua_State *L )
5322{
5323 Pilot *p;
5324 int enable, cleartasks;
5325
5326 /* Handle parameters. */
5327 p = luaL_validpilot(L,1);
5328 if (lua_isnone(L,2))
5329 enable = 1;
5330 else
5331 enable = lua_toboolean(L, 2);
5332 if (lua_isnone(L,3))
5333 cleartasks = enable ^ pilot_isFlag(p, PILOT_MANUAL_CONTROL);
5334 else
5335 cleartasks = lua_toboolean(L, 3);
5336
5337 if (enable) {
5338 int isp = pilot_isPlayer(p);
5339 if (isp)
5340 player_autonavAbort(NULL); /* Has to be run before setting the flag. */
5341 pilot_setFlag(p, PILOT_MANUAL_CONTROL);
5342 if (isp)
5343 ai_pinit( p, "player" );
5344 }
5345 else {
5346 pilot_rmFlag(p, PILOT_MANUAL_CONTROL);
5347 if (pilot_isPlayer(p))
5348 ai_destroy( p );
5349 /* Note, we do not set p->ai to NULL, we just clear the tasks and memory.
5350 * This is because the player always has an ai named "player", which is
5351 * used for manual control among other things. Basically a pilot always
5352 * has to have an AI even if it's the player for things to work. */
5353 }
5354
5355 /* Clear task if changing state. */
5356 if (cleartasks)
5357 pilotL_taskclear( L );
5358
5359 return 0;
5360}
5361
5373static int pilotL_memory( lua_State *L )
5374{
5375 const Pilot *p = luaL_validpilot(L,1);
5376 /* Set the pilot's memory. */
5377 if (p->ai == NULL)
5378 return NLUA_ERROR(L,_("Pilot '%s' does not have an AI!"),p->name);
5379 lua_rawgeti( L, LUA_REGISTRYINDEX, p->lua_mem );
5380 return 1;
5381}
5382
5391static int pilotL_shipmemory( lua_State *L )
5392{
5393 Pilot *p = luaL_validpilot(L,1);
5394 /* Possible it's not initialized yet, so we do the dirty work here. */
5395 if (p->lua_ship_mem == LUA_NOREF) {
5396 lua_newtable( naevL ); /* mem */
5397 p->lua_ship_mem = luaL_ref( naevL, LUA_REGISTRYINDEX ); /* */
5398 }
5399 lua_rawgeti( L, LUA_REGISTRYINDEX, p->lua_ship_mem );
5400 return 1;
5401}
5402
5410static int pilotL_ainame( lua_State *L )
5411{
5412 const Pilot *p = luaL_validpilot(L,1);
5413 if (p->ai == NULL)
5414 return 0;
5415 lua_pushstring(L, p->ai->name);
5416 return 1;
5417}
5418
5427static int pilotL_task( lua_State *L )
5428{
5429 Pilot *p = luaL_validpilot(L,1);
5430 Task *t = ai_curTask(p);
5431 if (t) {
5432 lua_pushstring(L, t->name);
5433 if (t->dat != LUA_NOREF) {
5434 lua_rawgeti(L, LUA_REGISTRYINDEX, t->dat);
5435 return 2;
5436 }
5437 return 1;
5438 }
5439 return 0;
5440}
5441
5450static int pilotL_taskname( lua_State *L )
5451{
5452 Pilot *p = luaL_validpilot(L,1);
5453 Task *t = ai_curTask(p);
5454 if (t) {
5455 lua_pushstring(L, t->name);
5456 if (t->subtask != NULL) {
5457 lua_pushstring(L, t->subtask->name);
5458 return 2;
5459 }
5460 return 1;
5461 }
5462 return 0;
5463}
5464
5471static int pilotL_taskstack( lua_State *L )
5472{
5473 Pilot *p = luaL_validpilot(L,1);
5474 int n;
5475
5476 lua_newtable(L);
5477 n = 1;
5478 for (Task *t=p->task; t!=NULL; t=t->next) {
5479 if (t->done)
5480 continue;
5481 lua_pushstring(L,t->name);
5482 lua_rawseti(L,-2,n++);
5483 }
5484
5485 return 1;
5486}
5487
5495static int pilotL_taskdata( lua_State *L )
5496{
5497 Pilot *p = luaL_validpilot(L,1);
5498 Task *t = ai_curTask(p);
5499 if (t && (t->dat != LUA_NOREF)) {
5500 lua_rawgeti(L, LUA_REGISTRYINDEX, t->dat);
5501 return 1;
5502 }
5503 return 0;
5504}
5505
5514static int pilotL_taskclear( lua_State *L )
5515{
5516 Pilot *p = luaL_validpilot(L,1);
5517 ai_cleartasks( p );
5518 return 0;
5519}
5520
5531static int pilotL_pushtask( lua_State *L )
5532{
5533 Pilot *p = luaL_validpilot(L,1);
5534 const char *task = luaL_checkstring(L,2);
5535
5536 if (pilot_isPlayer(p) && !pilot_isFlag(p,PILOT_MANUAL_CONTROL))
5537 return 0;
5538
5539 Task *t = ai_newtask( L, p, task, 0, 1 );
5540 if (!lua_isnoneornil(L,3)) {
5541 lua_pushvalue( L, 3 );
5542 t->dat = luaL_ref( L, LUA_REGISTRYINDEX );
5543 }
5544 return 0;
5545}
5546
5555static int pilotL_poptask( lua_State *L )
5556{
5557 Pilot *p = luaL_validpilot(L,1);
5558 Task *t = ai_curTask( p );
5559 /* Tasks must exist. */
5560 if (t == NULL)
5561 return NLUA_ERROR(L, _("Trying to pop task when there are no tasks on the stack."));
5562 t->done = 1;
5563 return 0;
5564}
5565
5574static int pilotL_refuel( lua_State *L )
5575{
5576 Pilot *p = luaL_validpilot(L,1);
5577 const Pilot *target = luaL_validpilot(L,2);
5578 double amount = luaL_optinteger(L,3,100);
5579 pilot_rmFlag( p, PILOT_HYP_PREP);
5580 pilot_rmFlag( p, PILOT_HYP_BRAKE );
5581 pilot_rmFlag( p, PILOT_HYP_BEGIN);
5582 pilot_setFlag( p, PILOT_REFUELING);
5583 ai_refuel( p, target->id );
5584 p->refuel_amount = amount;
5585 return 0;
5586}
5587
5591static Task *pilotL_newtask( lua_State *L, Pilot* p, const char *task )
5592{
5593 Task *t;
5594
5595 /* Must be on manual control. */
5596 if (!pilot_isFlag( p, PILOT_MANUAL_CONTROL)) {
5597 NLUA_ERROR( L, _("Pilot '%s' is not on manual control."), p->name );
5598 return NULL;
5599 }
5600
5601 /* Creates the new task. */
5602 t = ai_newtask( L, p, task, 0, 1 );
5603 if (t==NULL) {
5604 NLUA_ERROR( L, _("Failed to create new task for pilot '%s'."), p->name );
5605 return NULL;
5606 }
5607
5608 return t;
5609}
5610
5630static int pilotL_moveto( lua_State *L )
5631{
5632 Pilot *p;
5633 Task *t;
5634 vec2 *vec;
5635 int brake, compensate;
5636 const char *tsk;
5637
5638 /* Get parameters. */
5639 p = luaL_validpilot(L,1);
5640 vec = luaL_checkvector(L,2);
5641 if (lua_isnone(L,3))
5642 brake = 1;
5643 else
5644 brake = lua_toboolean(L,3);
5645 if (lua_isnone(L,4))
5646 compensate = 1;
5647 else
5648 compensate = lua_toboolean(L,4);
5649
5650 /* Set the task. */
5651 if (brake) {
5652 tsk = "moveto";
5653 }
5654 else {
5655 if (compensate)
5656 tsk = "moveto_nobrake";
5657 else
5658 tsk = "moveto_nobrake_raw";
5659 }
5660 t = pilotL_newtask( L, p, tsk );
5661 lua_pushvector( L, *vec );
5662 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5663
5664 return 0;
5665}
5666
5679static int pilotL_face( lua_State *L )
5680{
5681 Pilot *p, *pt;
5682 vec2 *vec;
5683 Task *t;
5684 int towards;
5685
5686 /* Get parameters. */
5687 pt = NULL;
5688 vec = NULL;
5689 p = luaL_validpilot(L,1);
5690 if (lua_ispilot(L,2))
5691 pt = luaL_validpilot(L,2);
5692 else
5693 vec = luaL_checkvector(L,2);
5694 towards = lua_toboolean(L,3);
5695
5696 /* Set the task. */
5697 if (towards)
5698 t = pilotL_newtask( L, p, "face_towards" );
5699 else
5700 t = pilotL_newtask( L, p, "face" );
5701 if (pt != NULL) {
5702 lua_pushpilot(L, pt->id);
5703 }
5704 else {
5705 lua_pushvector(L, *vec);
5706 }
5707 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5708
5709 return 0;
5710}
5711
5721static int pilotL_brake( lua_State *L )
5722{
5723 Pilot *p = luaL_validpilot(L,1);
5724 pilotL_newtask( L, p, "brake" );
5725 return 0;
5726}
5727
5741static int pilotL_follow( lua_State *L )
5742{
5743 Pilot *p, *pt;
5744 Task *t;
5745 int accurate;
5746
5747 /* Get parameters. */
5748 p = luaL_validpilot(L,1);
5749 pt = luaL_validpilot(L,2);
5750 accurate = lua_toboolean(L,3);
5751
5752 /* Set the task. */
5753 if (accurate == 0)
5754 t = pilotL_newtask( L, p, "follow" );
5755 else
5756 t = pilotL_newtask( L, p, "follow_accurate" );
5757
5758 lua_pushpilot(L, pt->id);
5759 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5760
5761 return 0;
5762}
5763
5777static int pilotL_attack( lua_State *L )
5778{
5779 Pilot *p;
5780 Task *t;
5781 unsigned int pid;
5782
5783 /* Get parameters. */
5784 p = luaL_validpilot(L,1);
5785 if (!lua_isnoneornil(L,2)) {
5786 const Pilot *pt = luaL_validpilot(L,2);
5787 pid = pt->id;
5788 }
5789 else {
5790 pid = pilot_getNearestEnemy( p );
5791 if (pid == 0) /* No enemy found. */
5792 return 0;
5793 }
5794
5795 /* Set the task. */
5796 t = pilotL_newtask( L, p, "attack_forced" );
5797 lua_pushpilot(L, pid);
5798 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5799
5800 return 0;
5801}
5802
5815static int pilotL_board( lua_State *L )
5816{
5817 Pilot *p, *pt;
5818 Task *t;
5819
5820 /* Get parameters. */
5821 p = luaL_validpilot(L,1);
5822 pt = luaL_validpilot(L,2);
5823
5824 /* Set the task. */
5825 t = pilotL_newtask( L, p, "board" );
5826 lua_pushpilot(L, pt->id);
5827 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5828
5829 return 0;
5830}
5831
5849static int pilotL_runaway( lua_State *L )
5850{
5851 /* Get parameters. */
5852 Pilot *p = luaL_validpilot(L,1);
5853 const Pilot *pt = luaL_validpilot(L,2);
5854
5855 /* Set the task depending on the last parameter. */
5856 if (lua_isnoneornil(L,3)) {
5857 Task *t = pilotL_newtask( L, p, "runaway" );
5858 lua_pushpilot(L, pt->id);
5859 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5860 }
5861 else {
5862 if (lua_isboolean(L,3)) {
5863 int nojump = lua_toboolean(L,3);
5864 Task *t = pilotL_newtask( L, p, (nojump) ? "runaway_nojump" : "runaway" );
5865 lua_pushpilot(L, pt->id);
5866 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5867 }
5868 else if (lua_isjump(L,3)) {
5869 const LuaJump *lj = lua_tojump(L,3);
5870 Task *t = pilotL_newtask( L, p, "runaway_jump" );
5871 lua_newtable(L);
5872 lua_pushpilot(L, pt->id);
5873 lua_rawseti( L, -2, 1 );
5874 lua_pushjump(L, *lj);
5875 lua_rawseti( L, -2, 2 );
5876 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5877 }
5878 else if (lua_isspob(L,3)) {
5879 LuaSpob lp = lua_tospob(L,3);
5880 Task *t = pilotL_newtask( L, p, "runaway_land" );
5881 lua_newtable(L);
5882 lua_pushpilot(L, pt->id);
5883 lua_rawseti( L, -2, 1 );
5884 lua_pushspob(L, lp);
5885 lua_rawseti( L, -2, 2 );
5886 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5887 }
5888 else
5889 NLUA_INVALID_PARAMETER(L,3);
5890 }
5891
5892 return 0;
5893}
5894
5902static int pilotL_gather( lua_State *L )
5903{
5904 Pilot *p = luaL_validpilot(L,1);
5905 Task *t = pilotL_newtask( L, p, "gather" );
5906 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5907 return 0;
5908}
5909
5917static int pilotL_canHyperspace( lua_State *L )
5918{
5919 const Pilot *p = luaL_validpilot(L,1);
5920 lua_pushboolean(L, space_canHyperspace(p));
5921 return 1;
5922}
5923
5935static int pilotL_hyperspace( lua_State *L )
5936{
5937 Pilot *p;
5938 Task *t;
5939 StarSystem *ss;
5940 JumpPoint *jp;
5941 LuaJump lj;
5942 int noshoot;
5943
5944 /* Get parameters. */
5945 p = luaL_validpilot(L,1);
5946 if (lua_isjump(L,2))
5947 ss = system_getIndex( lua_tojump(L,2)->destid );
5948 else
5949 ss = (lua_isnoneornil(L,2)) ? NULL : luaL_validsystem(L,2);
5950 noshoot = lua_toboolean(L,3);
5951
5952 /* Set the task. */
5953 if (noshoot)
5954 t = pilotL_newtask( L, p, "hyperspace" );
5955 else
5956 t = pilotL_newtask( L, p, "hyperspace_shoot" );
5957
5958 if (ss == NULL)
5959 return 0;
5960 /* Find the jump. */
5961 for (int i=0; i < array_size(cur_system->jumps); i++) {
5962 jp = &cur_system->jumps[i];
5963 if (jp->target != ss)
5964 continue;
5965 /* Found target. */
5966
5967 if (jp_isFlag( jp, JP_EXITONLY ))
5968 return NLUA_ERROR( L, _("Pilot '%s' can't jump out exit only jump '%s'"), p->name, ss->name );
5969
5970 /* Push jump. */
5971 lj.srcid = cur_system->id;
5972 lj.destid = jp->targetid;
5973 lua_pushjump(L, lj);
5974 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5975 return 0;
5976 }
5977 /* Not found. */
5978 return NLUA_ERROR( L, _("System '%s' is not adjacent to current system '%s'"), ss->name, cur_system->name );
5979}
5980
5990static int pilotL_stealth( lua_State *L )
5991{
5992 Pilot *p = luaL_validpilot(L,1);
5993 /* Set the task. */
5994 Task *t = pilotL_newtask( L, p, "stealth" );
5995 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5996 return 0;
5997}
5998
6006static int pilotL_tryStealth( lua_State *L )
6007{
6008 Pilot *p = luaL_validpilot(L,1);
6009 lua_pushboolean( L, pilot_stealth(p) );
6010 return 1;
6011}
6012
6024static int pilotL_land( lua_State *L )
6025{
6026 Pilot *p;
6027 Task *t;
6028 Spob *pnt;
6029 int noshoot;
6030
6031 /* Get parameters. */
6032 p = luaL_validpilot(L,1);
6033 if (lua_isnoneornil(L,2))
6034 pnt = NULL;
6035 else
6036 pnt = luaL_validspob( L, 2 );
6037 noshoot = lua_toboolean(L,3);
6038
6039 /* Set the task. */
6040 if (noshoot)
6041 t = pilotL_newtask( L, p, "land" );
6042 else
6043 t = pilotL_newtask( L, p, "land_shoot" );
6044
6045 if (pnt != NULL) {
6046 int i;
6047 /* Find the spob. */
6048 for (i=0; i < array_size(cur_system->spobs); i++) {
6049 if (cur_system->spobs[i] == pnt) {
6050 break;
6051 }
6052 }
6053 if (i >= array_size(cur_system->spobs))
6054 return NLUA_ERROR( L, _("Spob '%s' not found in system '%s'"), pnt->name, cur_system->name );
6055
6056 p->nav_spob = i;
6057 if (p->id == PLAYER_ID)
6058 gui_setNav();
6059
6060 lua_pushspob(L, pnt->id);
6061 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
6062 }
6063
6064 return 0;
6065}
6066
6077static int pilotL_hailPlayer( lua_State *L )
6078{
6079 Pilot *p;
6080 int enable;
6081
6082 /* Get parameters. */
6083 p = luaL_validpilot(L,1);
6084 if (lua_isnone(L,2))
6085 enable = 1;
6086 else
6087 enable = lua_toboolean(L,2);
6088
6089 /* Set the flag. */
6090 if (enable) {
6091 /* Send message. */
6092 char c = pilot_getFactionColourChar( p );
6093 player_message( _("#%c%s#0 is hailing you."), c, p->name );
6094
6095 /* Set flag. */
6096 pilot_setFlag( p, PILOT_HAILING );
6098 }
6099 else
6100 pilot_rmFlag( p, PILOT_HAILING );
6101
6102 return 0;
6103}
6104
6116static int pilotL_msg( lua_State *L )
6117{
6118 Pilot *p;
6119 const char *type;
6120 unsigned int data;
6121
6122 if (lua_isnoneornil(L,1))
6123 p = NULL;
6124 else
6125 p = luaL_validpilot(L,1);
6126 type = luaL_checkstring(L,3);
6127 data = lua_gettop(L) > 3 ? 4 : 0;
6128
6129 if (!lua_istable(L,2)) {
6130 const Pilot *receiver = luaL_validpilot(L,2);
6131 pilot_msg(p, receiver, type, data);
6132 }
6133 else {
6134 lua_pushnil(L);
6135 while (lua_next(L, 2) != 0) {
6136 const Pilot *receiver = luaL_validpilot(L,-1);
6137 pilot_msg(p, receiver, type, data);
6138 lua_pop(L, 1);
6139 }
6140 lua_pop(L, 1);
6141 }
6142
6143 return 0;
6144}
6145
6153static int pilotL_mothership( lua_State *L )
6154{
6155 const Pilot *p = luaL_validpilot(L, 1);
6156 if (p->dockpilot != 0) {
6157 const Pilot *l = pilot_get( p->dockpilot );
6158 if ((l == NULL) || pilot_isFlag( l, PILOT_DEAD )) {
6159 lua_pushnil(L);
6160 }
6161 else
6162 lua_pushpilot(L, p->dockpilot);
6163 }
6164 else
6165 lua_pushnil(L);
6166 return 1;
6167}
6168
6176static int pilotL_leader( lua_State *L )
6177{
6178 Pilot *p = luaL_validpilot(L, 1);
6179 if (p->parent != 0) {
6180 const Pilot *l = pilot_get( p->parent );
6181 if ((l == NULL) || pilot_isFlag( l, PILOT_DEAD )) {
6182 p->parent = 0; /* Clear parent for future calls. */
6183 lua_pushnil(L);
6184 }
6185 else
6186 lua_pushpilot(L, p->parent);
6187 }
6188 else
6189 lua_pushnil(L);
6190 return 1;
6191}
6192
6204static int pilotL_setLeader( lua_State *L )
6205{
6206 Pilot *p = luaL_validpilot(L, 1);
6207 Pilot *prev_leader = pilot_get( p->parent );
6208
6209 /* Remove from previous leader's follower list */
6210 if (prev_leader != NULL) {
6211 int found = 0;
6212 for (int i=0; i<array_size(prev_leader->escorts); i++) {
6213 const Escort_t *e = &prev_leader->escorts[i];
6214 if (e->id != p->id)
6215 continue;
6216 if (e->type != ESCORT_TYPE_MERCENARY)
6217 return NLUA_ERROR(L,_("Trying to change the leader of pilot '%s' that is a deployed fighter or part of the player fleet!"), p->name);
6218 escort_rmListIndex( prev_leader, i );
6219 found = 1;
6220 break;
6221 }
6222 if (!found)
6223 WARN(_("Pilot '%s' not found in followers of '%s'"), p->name, prev_leader->name );
6224 }
6225
6226 /* Just clear parent, will already be gone from parent escort list. */
6227 if (lua_isnoneornil(L, 2)) {
6228 p->parent = 0;
6229 }
6230 else {
6231 PilotOutfitSlot* dockslot;
6232 Pilot *leader = luaL_validpilot(L, 2);
6233
6234 /* Don't allow setting a pilot's leader to themselves. */
6235 if (p->id == leader->id)
6236 return NLUA_ERROR(L,_("Trying to set pilot '%s' to be their own leader!"),p->name);
6237
6238 if ((leader->parent != 0) && (leader->parent != p->id)) {
6239 Pilot *leader_leader = pilot_get(leader->parent);
6240 if (leader_leader != NULL)
6241 leader = leader_leader;
6242 }
6243
6244 p->parent = leader->id;
6245
6246 /* Reset dock slot */
6247 dockslot = pilot_getDockSlot( p );
6248 if (dockslot != NULL) {
6249 dockslot->u.ammo.deployed--;
6250 p->dockpilot = 0;
6251 p->dockslot = -1;
6252 }
6253
6254 /* TODO: Figure out escort type */
6255 escort_addList( leader, p->ship, ESCORT_TYPE_MERCENARY, p->id, 0 );
6256
6257 /* If the pilot has followers, they should be given the new leader as well, and be added as escorts. */
6258 for (int i=array_size(p->escorts)-1; i>=0; i--) {
6259 const Escort_t *e = &p->escorts[i];
6260 /* We don't want to deal with fighter bays this way. */
6261 if (e->type != ESCORT_TYPE_MERCENARY)
6262 continue;
6263 Pilot *pe = pilot_get( e->id );
6264 if (pe == NULL) {
6265 escort_rmListIndex( p, i ); /* MIght as well remove if they're not there. */
6266 continue;
6267 }
6268
6269 /* Setting an escort as leader, so we clear the leader of the escort. */
6270 if (pe->id == p->parent) {
6271 escort_rmListIndex( p, i );
6272 pe->parent = 0;
6273 continue;
6274 }
6275
6276 pe->parent = p->parent;
6277
6278 /* Add escort to parent. */
6279 escort_addList( leader, pe->ship, e->type, pe->id, 0 );
6280 escort_rmListIndex( p, i );
6281 }
6282 }
6283
6284 return 0;
6285}
6286
6294static int pilotL_followers( lua_State *L )
6295{
6296 const Pilot *p = luaL_validpilot(L, 1);
6297 int idx = 1;
6298
6299 lua_newtable(L);
6300 for (int i=0; i < array_size(p->escorts); i++) {
6301 /* Make sure the followers are valid. */
6302 const Pilot *pe = pilot_get( p->escorts[i].id );
6303 if ((pe==NULL) || pilot_isFlag( pe, PILOT_DEAD ) || pilot_isFlag( pe, PILOT_HIDE ))
6304 continue;
6305 lua_pushpilot(L, p->escorts[i].id);
6306 lua_rawseti(L, -2, idx++);
6307 }
6308
6309 return 1;
6310}
6311
6321static int pilotL_hookClear( lua_State *L )
6322{
6323 Pilot *p = luaL_validpilot(L,1);
6324 pilot_clearHooks( p );
6325 return 0;
6326}
6327
6328static const CollPoly *getCollPoly( const Pilot *p )
6329{
6330 int k = p->ship->gfx_space->sx * p->tsy + p->tsx;
6331 return &p->ship->polygon[k];
6332}
6341static int pilotL_collisionTest( lua_State *L )
6342{
6343 vec2 crash;
6344 const Pilot *p = luaL_validpilot(L,1);
6345
6346 /* Asteroid treated separately. */
6347 if (lua_isasteroid(L,2)) {
6348 Asteroid *a = luaL_validasteroid( L, 2 );
6349 CollPoly rpoly;
6350 RotatePolygon( &rpoly, a->polygon, (float) a->ang );
6351 int ret = CollidePolygon( getCollPoly(p), &p->solid.pos,
6352 &rpoly, &a->sol.pos, &crash );
6353 free(rpoly.x);
6354 free(rpoly.y);
6355 if (!ret)
6356 return 0;
6357 lua_pushvector( L, crash );
6358 return 1;
6359 }
6360
6361 Pilot *t = luaL_validpilot(L,2);
6362
6363 /* Shouldn't be invincible. */
6364 if (pilot_isFlag( t, PILOT_INVINCIBLE ))
6365 return 0;
6366
6367 /* Shouldn't be landing or taking off. */
6368 if (pilot_isFlag( t, PILOT_LANDING) ||
6369 pilot_isFlag( t, PILOT_TAKEOFF ) ||
6370 pilot_isFlag( t, PILOT_NONTARGETABLE))
6371 return 0;
6372
6373 /* Must be able to target. */
6374 if (!pilot_canTarget( t ))
6375 return 0;
6376
6377 int ret = CollidePolygon( getCollPoly(p), &p->solid.pos, getCollPoly(t), &t->solid.pos, &crash );
6378 if (!ret)
6379 return 0;
6380
6381 lua_pushvector( L, crash );
6382 return 1;
6383}
6384
6397static int pilotL_damage( lua_State *L )
6398{
6399 Damage dmg;
6400 Pilot *p, *parent;
6401 double damage;
6402
6403 p = luaL_validpilot(L,1);
6404 dmg.damage = luaL_checknumber(L,2);
6405 dmg.disable = luaL_optnumber(L,3,0.);
6406 dmg.penetration = luaL_optnumber(L,4,0.) / 100.;
6407 dmg.type = dtype_get( luaL_optstring(L,5,"raw") );
6408 parent = (lua_isnoneornil(L,6)) ? NULL : luaL_validpilot(L,6);
6409
6410 damage = pilot_hit( p, NULL, parent, &dmg, NULL, LUA_NOREF, 1 );
6411 if (parent != NULL)
6412 weapon_hitAI( p, parent, damage );
6413
6414 lua_pushnumber(L, damage);
6415 return 1;
6416}
6417
6426static int pilotL_kill( lua_State *L )
6427{
6428 Pilot *p = luaL_validpilot(L,1);
6429 p->armour = -1.;
6430 pilot_dead( p, 0 );
6431 return 0;
6432}
6433
6447static int pilotL_knockback( lua_State *L )
6448{
6449 Pilot *p1 = luaL_validpilot(L,1);
6450 double m1 = p1->solid.mass;
6451 vec2 *v1 = &p1->solid.vel;
6452 vec2 *x1 = &p1->solid.pos;
6453 Pilot *p2;
6454 double m2;
6455 vec2 *v2;
6456 vec2 *x2;
6457 double e;
6458 if (lua_ispilot(L,2)) {
6459 p2 = luaL_validpilot(L,2);
6460 m2 = p2->solid.mass;
6461 v2 = &p2->solid.vel;
6462 x2 = &p2->solid.pos;
6463 e = luaL_optnumber(L,3,1.);
6464 }
6465 else {
6466 p2 = NULL;
6467 m2 = luaL_checknumber(L,2);
6468 v2 = luaL_checkvector(L,3);
6469 x2 = luaL_optvector(L,4,x1);
6470 e = luaL_optnumber(L,5,1.);
6471 }
6472
6473 /* Pure inlastic case. */
6474 if (e==0.) {
6475 double vx = (m1*v1->x + m2*v2->x) / (m1+m2);
6476 double vy = (m1*v1->y + m2*v2->y) / (m1+m2);
6477 vec2_cset( &p1->solid.vel, vx, vy );
6478 if (p2 != NULL)
6479 vec2_cset( &p2->solid.vel, vx, vy );
6480 return 0.;
6481 }
6482
6483 /* Pure elastic. */
6484 double norm = pow2(x1->x-x2->x) + pow2(x1->y-x2->y);
6485 double a1 = -e * (2.*m2)/(m1+m2);
6486 if (norm > 0.)
6487 a1 *= ((v1->x-v2->x)*(x1->x-x2->x) + (v1->y-v2->y)*(x1->y-x2->y)) / norm;
6488
6489 vec2_cadd( &p1->solid.vel, a1*(x1->x-x2->x), a1*(x1->y-x2->y) );
6490 if (p2 != NULL) {
6491 double a2 = -e * (2.*m1)/(m2+m1);
6492 if (norm > 0.)
6493 a2 *= ((v2->x-v1->x)*(x2->x-x1->x) + (v2->y-v1->y)*(x2->y-x1->y)) / norm;
6494 vec2_cadd( &p2->solid.vel, a2*(x2->x-x1->x), a2*(x2->y-x1->y) );
6495 }
6496
6497 /* Modulate. TODO this is probably totally wrong and needs fixing to be physicaly correct. */
6498 if (e != 1.) {
6499 double vx = (m1*v1->x + m2*v2->x) / (m1+m2);
6500 double vy = (m1*v1->y + m2*v2->y) / (m1+m2);
6501 vec2_cset( &p1->solid.vel, e*v1->x + (1.-e)*vx, e*v1->y + (1.-e)*vy );
6502 if (p2 != NULL)
6503 vec2_cset( &p2->solid.vel, e*v2->x + (1.-e)*vx, e*v2->y + (1.-e)*vy );
6504 }
6505
6506 return 0;
6507}
6508
6515static int pilotL_calcStats( lua_State *L )
6516{
6517 Pilot *p = luaL_validpilot(L,1);
6518 pilot_calcStats( p );
6519 return 0;
6520}
6521
6531static int pilotL_showEmitters( lua_State *L )
6532{
6533 int state;
6534
6535 /* Get state. */
6536 if (lua_gettop(L) > 0)
6537 state = lua_toboolean(L, 1);
6538 else
6539 state = 1;
6540
6541 /* Toggle the markers. */
6542#if DEBUGGING
6543 if (state)
6544 debug_setFlag(DEBUG_MARK_EMITTER);
6545 else
6546 debug_rmFlag(DEBUG_MARK_EMITTER);
6547#else /* DEBUGGING */
6548 (void) state;
6549 return NLUA_ERROR(L, _("Requires a debug build."));
6550#endif /* DEBUGGING */
6551
6552 return 0;
6553}
6554
6565static int pilotL_shipvarPeek( lua_State *L )
6566{
6567 const Pilot *p = luaL_validpilot(L,1);
6568 const char *str = luaL_checkstring(L,2);
6569 const lvar *var = lvar_get( p->shipvar, str );
6570 if (var != NULL)
6571 return lvar_push( L, var );
6572 return 0;
6573}
6574
6583static int pilotL_shipvarPush( lua_State *L )
6584{
6585 Pilot *p = luaL_validpilot(L,1);
6586 const char *str = luaL_checkstring(L,2);
6587 lvar var = lvar_tovar( L, str, 3 );
6588 if (p->shipvar==NULL)
6589 p->shipvar = array_create( lvar );
6590 lvar_addArray( &p->shipvar, &var, 1 );
6591 return 0;
6592}
6593
6601static int pilotL_shipvarPop( lua_State *L )
6602{
6603 Pilot *p = luaL_validpilot(L,1);
6604 const char *str = luaL_checkstring(L,2);
6605 lvar *var = lvar_get( p->shipvar, str );
6606 if (var != NULL)
6607 lvar_rmArray( &p->shipvar, var );
6608 return 0;
6609}
6610
6618static int pilotL_render( lua_State *L )
6619{
6620 LuaCanvas_t lc;
6621 int w, h;
6622 Pilot *p = luaL_validpilot(L,1);
6623
6624 /* TODO handle when effects make the ship render larger than it really is. */
6625 w = p->ship->gfx_space->sw;
6626 h = p->ship->gfx_space->sh;
6627 if (canvas_new( &lc, w, h ))
6628 return NLUA_ERROR( L, _("Error setting up framebuffer!"));
6629
6630 /* I'me really stumped at why we need to pass gl_screen here for it to work... */
6632
6633 lua_pushcanvas( L, lc );
6634 return 1;
6635}
6636
6646static int pilotL_renderTo( lua_State *L )
6647{
6648 Pilot *p = luaL_validpilot( L, 1 );
6649 LuaCanvas_t *lc = luaL_checkcanvas( L, 2 );
6650
6651 /* TODO handle when effects make the ship render larger than it really is. */
6652 if ((lc->tex->w < p->ship->gfx_space->sw) || (lc->tex->h < p->ship->gfx_space->sh))
6653 WARN(_("Canvas is too small to fully render '%s': %.0f x %.0f < %.0f x %.0f"),
6654 p->name, lc->tex->w, lc->tex->h,
6655 p->ship->gfx_space->sw, p->ship->gfx_space->sh );
6656
6657 /* I'me really stumped at why we need to pass gl_screen here for it to work... */
6659
6660 lua_pushnumber( L, p->ship->gfx_space->sw );
6661 lua_pushnumber( L, p->ship->gfx_space->sh );
6662 return 2;
6663}
Task * ai_newtask(lua_State *L, Pilot *p, const char *func, int subtask, int pos)
Creates a new AI task.
Definition ai.c:1117
Task * ai_curTask(Pilot *pilot)
Gets the current running task.
Definition ai.c:383
void ai_refuel(Pilot *refueler, unsigned int target)
Has a pilot attempt to refuel the other.
Definition ai.c:1018
void ai_cleartasks(Pilot *p)
Clears the pilot's tasks.
Definition ai.c:550
void ai_destroy(Pilot *p)
Destroys the ai part of the pilot.
Definition ai.c:563
int ai_pinit(Pilot *p, const char *ai)
Initializes the pilot in the ai.
Definition ai.c:496
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition array.h:158
#define array_copy(basic_type, ptr_array)
Returns a shallow copy of the input array.
Definition array.h:218
#define array_create_size(basic_type, capacity)
Creates a new dynamic array of ‘basic_type’ with an initial capacity.
Definition array.h:102
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:168
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
Definition array.h:129
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Definition array.h:93
void cam_update(double dt)
Updates the camera.
Definition camera.c:221
void RotatePolygon(CollPoly *rpolygon, CollPoly *ipolygon, float theta)
Rotates a polygon.
Definition collision.c:332
int CollidePolygon(const CollPoly *at, const vec2 *ap, const CollPoly *bt, const vec2 *bp, vec2 *crash)
Checks whether or not two polygons collide. /!\ The function is not symmetric: the points of polygon ...
Definition collision.c:260
int dtype_get(const char *name)
Gets the id of a dtype based on name.
Definition damagetype.c:159
const char * dtype_damageTypeToStr(int type)
Gets the human readable string from damage type.
Definition damagetype.c:185
int effect_rmType(Effect **efxlist, const EffectData *efx, int all)
Removes an effect type from an effect list.
Definition effect.c:421
int effect_rm(Effect **efxlist, int idx)
Removes an effect from an effect list by index.
Definition effect.c:390
int effect_add(Effect **efxlist, const EffectData *efx, double duration, double strength, unsigned int parent)
Adds an effect to an effect list.
Definition effect.c:299
void effect_clearSpecific(Effect **efxlist, int debuffs, int buffs, int others)
Clears specific types of effects.
Definition effect.c:453
const EffectData * effect_get(const char *name)
Gets an effect by name.
Definition effect.c:244
void effect_clear(Effect **efxlist)
Clears an effect list, removing all active effects.
Definition effect.c:492
int escort_addList(Pilot *p, const Ship *ship, EscortType_t type, unsigned int id, int persist)
Adds an escort to the escort list of a pilot.
Definition escort.c:40
void escort_rmListIndex(Pilot *p, int i)
Remove from escorts list.
Definition escort.c:73
int areEnemies(int a, int b)
Checks whether two factions are enemies.
Definition faction.c:1227
int areAllies(int a, int b)
Checks whether two factions are allies or not.
Definition faction.c:1253
void gui_setShip(void)
Player just upgraded their ship or modified it.
Definition gui.c:1791
void gui_setNav(void)
Player just changed their nav computer target.
Definition gui.c:1775
void player_message(const char *fmt,...)
Adds a mesg to the queue to be displayed on screen.
Definition gui.c:335
void outfits_updateEquipmentOutfits(void)
Updates the outfitter and equipment outfit image arrays.
int lvar_addArray(lvar **arr, const lvar *new_var, int sort)
Adds a var to a var array.
Definition lvar.c:161
void lvar_rmArray(lvar **arr, lvar *rm_var)
Removes a var from a var array.
Definition lvar.c:188
lvar * lvar_get(const lvar *arr, const char *str)
Gets a lua var by name.
Definition lvar.c:39
lvar lvar_tovar(lua_State *L, const char *name, int idx)
Gets a lua variable from an index from a lua state.
Definition lvar.c:84
int lvar_push(lua_State *L, const lvar *v)
Pushes a lua var to a lua state.
Definition lvar.c:54
Header file with generic functions and naev-specifics.
#define MIN(x, y)
Definition naev.h:40
#define CLAMP(a, b, x)
Definition naev.h:41
#define pow2(x)
Definition naev.h:46
#define MAX(x, y)
Definition naev.h:39
int nlua_loadAsteroid(nlua_env env)
Loads the asteroid library.
int lua_isasteroid(lua_State *L, int ind)
Checks to see if ind is a asteroid.
LuaAsteroid_t * luaL_checkasteroid(lua_State *L, int ind)
Gets asteroid at index or raises error if there is no asteroid at index.
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.
glColour * lua_pushcolour(lua_State *L, glColour colour)
Pushes a colour on the stack.
Commodity ** lua_pushcommodity(lua_State *L, Commodity *commodity)
Pushes a commodity on the stack.
Commodity * luaL_validcommodity(lua_State *L, int ind)
Makes sure the commodity is valid or raises a Lua error.
LuaFaction * lua_pushfaction(lua_State *L, LuaFaction faction)
Pushes a faction on the stack.
LuaFaction luaL_validfaction(lua_State *L, int ind)
Gets faction (or faction name) at index, raising an error if type isn't a valid faction.
int lua_isfaction(lua_State *L, int ind)
Checks to see if ind is a faction.
LuaFaction lua_tofaction(lua_State *L, int ind)
Gets faction at index.
LuaJump * luaL_checkjump(lua_State *L, int ind)
Gets jump at index raising an error if isn't a jump.
Definition nlua_jump.c:103
LuaJump * lua_pushjump(lua_State *L, LuaJump jump)
Pushes a jump on the stack.
Definition nlua_jump.c:185
int lua_isjump(lua_State *L, int ind)
Checks to see if ind is a jump.
Definition nlua_jump.c:201
LuaJump * lua_tojump(lua_State *L, int ind)
This module allows you to handle the jumps from Lua.
Definition nlua_jump.c:92
const Outfit * luaL_validoutfit(lua_State *L, int ind)
Makes sure the outfit is valid or raises a Lua error.
const Outfit ** lua_pushoutfit(lua_State *L, const Outfit *outfit)
Pushes a outfit on the stack.
static int pilotL_weapsetActive(lua_State *L)
Gets the ID (number from 1 to 10) of the current active weapset.
static int pilotL_setVisible(lua_State *L)
Marks the pilot as always visible for other pilots.
static int pilotL_weapsetAmmo(lua_State *L)
Gets the ammo left of a weapon set.
static int pilotL_setHealthAbs(lua_State *L)
Sets the health of a pilot in absolute value.
static int pilotL_intrinsicGet(lua_State *L)
Allows getting an intrinsic stats of a pilot, or gets all of them if name is not specified.
static int pilotL_getVisible(lua_State *L)
Gets visible pilots to a pilot.
static int pilotL_isStopped(lua_State *L)
Checks to see if a pilot is stopped.
static int pilotL_clone(lua_State *L)
Clones a pilot. It will share nearly all properties including outfits.
Definition nlua_pilot.c:806
static int pilotL_setHide(lua_State *L)
Sets the pilot's hide status.
static int pilotL_calcStats(lua_State *L)
Forces a recomputation of the pilots' stats.
static int pilotL_weapsetAddType(lua_State *L)
Adds an outfit to a pilot's weapon set.
static int pilotL_refuel(lua_State *L)
Tries to refuel a pilot.
static int pilotL_eq(lua_State *L)
Checks to see if pilot and p are the same.
static int pilotL_moveto(lua_State *L)
Makes the pilot move to a position.
static int pilotL_hailPlayer(lua_State *L)
Marks the pilot as hailing the player.
static int pilotL_setEnergy(lua_State *L)
Sets the energy of a pilot.
static int pilotL_setFriendly(lua_State *L)
Controls the pilot's friendliness towards the player.
static int pilotL_cargoJet(lua_State *L)
Tries to remove a cargo from a pilot's ship and jet it into space.
static int pilotL_outfitRm(lua_State *L)
Removes an outfit from a pilot.
static int pilotL_outfitRmIntrinsic(lua_State *L)
Removes an intrinsic outfit from the pilot.
static int pilotL_actives(lua_State *L)
Gets the active outfits and their states of the pilot.
static int pilotL_cargoFree(lua_State *L)
Gets the free cargo space the pilot has.
static int pilotL_weapsetRm(lua_State *L)
Removes an outfit from a pilot's weapon set.
static int pilotL_setNoLand(lua_State *L)
Enables or disables landing for a pilot.
static int pilotL_targetAsteroid(lua_State *L)
Gets the asteroid target of the pilot.
static int pilotL_setActiveBoard(lua_State *L)
Allows the pilot to be boarded when not disabled.
static int pilotL_brake(lua_State *L)
Makes the pilot brake.
static int pilotL_withPlayer(lua_State *L)
Checks to see if pilot is with player.
static int pilotL_canHyperspace(lua_State *L)
Checks to see if the pilot can currently hyperspace (as in has target jump and is in range).
static int pilotL_spaceworthy(lua_State *L)
Checks the pilot's spaceworthiness.
static int pilotL_render(lua_State *L)
Renders the pilot to a canvas.
static int pilotL_runaway(lua_State *L)
Makes the pilot runaway from another pilot.
static int pilotL_land(lua_State *L)
Tells the pilot to land.
static int pilotL_weapsetList(lua_State *L)
Get a list of all the outfits in a weapon set.
LuaPilot lua_topilot(lua_State *L, int ind)
Lua bindings to interact with pilots.
Definition nlua_pilot.c:522
static int pilotL_memory(lua_State *L)
Gets a pilots memory table.
LuaPilot * lua_pushpilot(lua_State *L, LuaPilot pilot)
Pushes a pilot on the stack.
Definition nlua_pilot.c:563
static int pilotL_choosePoint(lua_State *L)
Returns a suitable jumpin spot for a given pilot. Lua usage parameter: point = pilot....
Definition nlua_pilot.c:604
static int pilotL_setNoClear(lua_State *L)
Enables or disables making the the pilot exempt from pilot.clear().
static int pilotL_canSpawn(lua_State *L)
Returns if pilots can can spawn naturally in the current system.
Definition nlua_pilot.c:938
static int pilotL_setNoJump(lua_State *L)
Enables or disables a pilot's hyperspace engine.
static int pilotL_setLeader(lua_State *L)
Set a pilots leader.
static int pilotL_taskclear(lua_State *L)
Clears all the tasks of the pilot.
static int pilotL_nav(lua_State *L)
Gets the nav target of the pilot.
static int pilotL_credits(lua_State *L)
Handles the pilots credits.
static int pilotL_taskdata(lua_State *L)
Gets the data of the task the pilot is currently doing.
static int pilotL_setInvisible(lua_State *L)
Sets the pilot's invisibility status.
static int pilotL_exists(lua_State *L)
Checks to see if pilot is still in the system and alive.
static int pilotL_hasIllegal(lua_State *L)
Checks to see if the pilot has illegal stuff to a faction.
static int pilotL_setTemp(lua_State *L)
Sets the temperature of a pilot.
static int pilotL_clearSelect(lua_State *L)
Removes all pilots belonging to a faction from the system.
Definition nlua_pilot.c:896
static int pilotL_outfitRmSlot(lua_State *L)
Removes an outfit from a pilot's named slot.
Pilot * luaL_validpilot(lua_State *L, int ind)
Makes sure the pilot is valid or raises a Lua error.
Definition nlua_pilot.c:547
static int pilotL_tostring(lua_State *L)
Gets the pilot's current (translated) name or notes it is inexistent.
static int pilotL_toggleSpawn(lua_State *L)
Disables or enables pilot spawning in the current system.
Definition nlua_pilot.c:969
static int pilotL_getEnergy(lua_State *L)
Gets the pilot's energy.
static int pilotL_points(lua_State *L)
Gets the points the pilot costs.
static int pilotL_weapsetType(lua_State *L)
Sets the type of a weapon set for a pilot.
static int pilotL_showEmitters(lua_State *L)
Toggles the emitter marker.
static int pilotL_getShield(lua_State *L)
Gets the pilot's shield.
static int pilotL_msg(lua_State *L)
Sends a message to another pilot.
static int pilotL_setBribed(lua_State *L)
Makes pilot act as if bribed by the player.
static int pilotL_cargoRm(lua_State *L)
Tries to remove cargo from the pilot's ship.
static int pilotL_knockback(lua_State *L)
Knocks back a pilot. It can either accept two pilots, or a pilot and an element represented by mass,...
static int pilotL_hookClear(lua_State *L)
Clears the pilot's hooks.
static int pilotL_setNoRender(lua_State *L)
Sets the pilot's norender status.
static int pilotL_taskname(lua_State *L)
Gets the name of the task the pilot is currently doing.
static int pilotL_intrinsicReset(lua_State *L)
Resets the intrinsic stats of a pilot.
static int pilotL_pushtask(lua_State *L)
Pushes a new task to the pilot's AI.
static int pilotL_mothership(lua_State *L)
Gets a pilots mothership (only exists for deployed pilots). Guaranteed to exist or will be nil.
static int pilotL_getHealth(lua_State *L)
Gets the pilot's health.
static int pilotL_cargoAdd(lua_State *L)
Tries to add cargo to the pilot's ship.
static int pilot_outfitAddSlot(Pilot *p, const Outfit *o, PilotOutfitSlot *s, int bypass_cpu, int bypass_slot)
Adds an outfit to a specific slot.
static int pilotL_damage(lua_State *L)
Damages a pilot.
static int pilotL_ai(lua_State *L)
Gets the pilot's AI.
static int pilotL_shippropGet(lua_State *L)
Allows getting an ship property stats of a pilot, or gets all of them if name is not specified.
static int pilotL_cooldownCycle(lua_State *L)
Makes the pilot do an instant full cooldown cycle.
static int pilotL_velocity(lua_State *L)
Gets the pilot's velocity.
static int pilotL_disable(lua_State *L)
Disables a pilot.
static int pilotL_weapsetSetInrange(lua_State *L)
Sets whether a pilot's weapon set does inrange checks.
static int pilotL_comm(lua_State *L)
Sends a message to the target or player if no target is passed.
static int pilotL_tryStealth(lua_State *L)
Tries to make the pilot stealth.
static int pilotL_fillAmmo(lua_State *L)
Fills up the pilot's ammo.
static const luaL_Reg pilotL_methods[]
Definition nlua_pilot.c:258
static int pilotL_setHealth(lua_State *L)
Sets the health of a pilot.
static int pilotL_getInrange(lua_State *L)
Gets visible pilots to a pilot within a certain distance.
static int pilotL_weapsetSetActive(lua_State *L)
Sets the ID (number from 1 to 10) of the current active weapset.
static int pilotL_changeAI(lua_State *L)
Changes the pilot's AI.
static int pilotL_setTarget(lua_State *L)
Sets the pilot target of the pilot.
static int pilotL_getEnemies(lua_State *L)
Gets hostile pilots to a pilot (or faction) within a certain distance.
static int pilotL_name(lua_State *L)
Gets the pilot's current (translated) name.
static int pilotL_getColour(lua_State *L)
Gets the pilot's colour based on hostility or friendliness to the player.
static int pilotL_scandone(lua_State *L)
Checks to see if a pilot is done scanning its target.
static Task * pilotL_newtask(lua_State *L, Pilot *p, const char *task)
Does a new task.
static int pilotL_shipvarPeek(lua_State *L)
Peeks at a ship variable.
static int pilotL_getShipStat(lua_State *L)
Gets a shipstat from a Pilot by name, or a table containing all the ship stats if not specified.
static int pilotL_setNoDisable(lua_State *L)
Sets the ability of the pilot to be disabled.
static int pilotL_colourChar(lua_State *L)
Gets the pilot's colour character based on hostility or friendliness to the player....
static int pilotL_cargoHas(lua_State *L)
Checks to see how many tonnes of a specific type of cargo the pilot has.
static int pilotL_setFuel(lua_State *L)
Sets the fuel of a pilot.
static int pilotL_stealth(lua_State *L)
Tells the pilot to try to stealth.
static int pilotL_navJump(lua_State *L)
Gets the nav jump target of the pilot.
static int pilotL_outfits(lua_State *L)
Gets a mapping of outfit slot IDs and outfits of a pilot.
static int pilotL_outfitSlot(lua_State *L)
Checks to see outfit a pilot has in a slot.
static int pilotL_outfitsList(lua_State *L)
Gets the outfits of a pilot.
static int pilotL_ainame(lua_State *L)
Gets the name of the task the pilot is currently doing.
static int outfit_compareActive(const void *slot1, const void *slot2)
qsort compare function for active outfits.
static int pilotL_shipvarPop(lua_State *L)
Pops a ship variable.
static int pilotL_setCooldown(lua_State *L)
Starts or stops a pilot's cooldown mode.
static int pilotL_face(lua_State *L)
Makes the pilot face a target.
static int pilotL_clear(lua_State *L)
Clears the current system of pilots. Used for epic battles and such.
Definition nlua_pilot.c:924
static int pilotL_shippropSet(lua_State *L)
Allows setting ship property stats of a pilot.
static int pilotL_rename(lua_State *L)
Changes the pilot's name.
static int pilotL_mass(lua_State *L)
Gets the mass of a pilot.
static int pilotL_navSpob(lua_State *L)
Gets the nav spob target of the pilot.
static const struct pL_flag pL_flags[]
static int pilotL_collisionTest(lua_State *L)
Tests to see if two ships collide.
static int pilotL_setHostile(lua_State *L)
Controls the pilot's hostility towards the player.
static int pilotL_outfitsEquip(lua_State *L)
Equips a pilot with a set of outfits.
static int pilotL_getAllies(lua_State *L)
Gets friendly pilots to a pilot (or faction) within a certain distance.
static int pilotL_dir(lua_State *L)
Gets the pilot's direction.
static int pilotL_setPosition(lua_State *L)
Sets the pilot's position.
static int pilotL_attack(lua_State *L)
Makes the pilot attack another pilot.
static int pilotL_setFlagWrapper(lua_State *L, int flag)
Wrapper to simplify flag setting stuff.
Definition nlua_pilot.c:482
int nlua_loadPilot(nlua_env env)
Loads the pilot library.
Definition nlua_pilot.c:468
static int pilotL_getArmour(lua_State *L)
Gets the pilot's armour.
static int pilotL_setSpeedLimit(lua_State *L)
Limits the speed of a pilot.
static int pilotL_navJumpSet(lua_State *L)
Sets the hyperspace navigation target for the pilot.
static int pilotL_weapsetCleanup(lua_State *L)
Cleans up a weapon set. This removes all properties of the weapon set and resets it.
static int pilotL_control(lua_State *L)
Sets manual control of the pilot.
static int pilotL_followers(lua_State *L)
Get all of a pilots followers.
Pilot * cur_pilot
Definition ai.c:338
static int pilotL_outfitToggle(lua_State *L)
Toggles an outfit.
static int pilotL_setNoBoard(lua_State *L)
Sets the ability to board the pilot.
static int pilotL_leader(lua_State *L)
Gets a pilots leader. Guaranteed to exist or will be nil.
static int pilotL_outfitGet(lua_State *L)
Gets a pilot's outfit by ID.
static int pilotL_temp(lua_State *L)
Gets the temperature of a pilot.
static int pilotL_getFuel(lua_State *L)
Gets the amount of fuel the pilot has.
static int pilotL_weapsetHeat(lua_State *L)
Gets heat information for a weapon set.
static int pilotL_setHilight(lua_State *L)
Makes pilot stand out on radar and the likes.
static int pilotL_shipvarPush(lua_State *L)
Pushes a ship variable.
static int pilotL_areAllies(lua_State *L)
Checks to see if two pilots are allies.
static int pilotL_outfitAddIntrinsic(lua_State *L)
Adds an intrinsic outfit to the pilot.
static int pilotL_addHealth(lua_State *L)
Adds health to a pilot.
static int pilotL_getLockon(lua_State *L)
Gets the lockons on the pilot.
static int pilotL_radius(lua_State *L)
Gets the rough radius of the ship, useful for collision stuff.
static int pilotL_getDetectedDistance(lua_State *L)
Gets the distance that a pilot can be currently detect at.
static int pilotL_effectRm(lua_State *L)
Removes an effect from the pilot.
static int pilotL_remove(lua_State *L)
Removes a pilot without explosions or anything.
Definition nlua_pilot.c:824
static int pilotL_intrinsicSet(lua_State *L)
Allows setting intrinsic stats of a pilot.
static int pilotL_kill(lua_State *L)
Kills a pilot.
static int pilotL_setFaction(lua_State *L)
Sets the pilot's faction.
static int pilotL_worth(lua_State *L)
Gets the worth of a pilot (total value of ship and outfits).
int lua_ispilot(lua_State *L, int ind)
Checks to see if ind is a pilot.
Definition nlua_pilot.c:578
static int pilotL_outfitReady(lua_State *L)
Sees if an outfit is ready to use.
static int pilotL_signature(lua_State *L)
Gets the pilot's signature.
static int pilotL_position(lua_State *L)
Gets the pilot's position.
static int pilotL_explode(lua_State *L)
Removes a pilot as if it exploded.
Definition nlua_pilot.c:851
static int pilotL_getStats(lua_State *L)
Gets stats of the pilot.
static int pilotL_poptask(lua_State *L)
Pops the current task from the pilot's AI.
static int pilotL_gather(lua_State *L)
Makes the pilot gather stuff.
static int pilotL_setInvincPlayer(lua_State *L)
Sets the pilot's invincibility status towards the player.
static int pilotL_cargoList(lua_State *L)
Lists the cargo the pilot has.
static int pilotL_setNoDeath(lua_State *L)
Makes it so the pilot never dies, stays at 1. armour.
static int pilotL_speed_max(lua_State *L)
Gets the maximum speed of a pilot.
static int pilotL_id(lua_State *L)
Gets the ID of the pilot.
static int pilotL_getHostile(lua_State *L)
Returns whether the pilot is hostile to the player.
static int pilotL_board(lua_State *L)
Makes the pilot board another pilot.
static int pilotL_broadcast(lua_State *L)
Makes the pilot broadcast a message.
static int pilotL_cooldown(lua_State *L)
Gets a pilot's cooldown state.
static int pilotL_setDir(lua_State *L)
Sets the pilot's direction.
static int pilotL_weapsetAdd(lua_State *L)
Adds an outfit to a pilot's weapon set.
static int pilotL_accel(lua_State *L)
Gets the accel of a pilot.
static int pilotL_task(lua_State *L)
Gets the name and data of a pilot's current task.
static int pilotL_shipmemory(lua_State *L)
Gets a pilots ship memory table.
static int weapsetItem(lua_State *L, int *k, Pilot *p, const PilotOutfitSlot *slot, const Pilot *target)
Sets up an item in a weapon set.
static int pilotL_areEnemies(lua_State *L)
Checks to see if two pilots are enemies.
static int pilotL_setVelocity(lua_State *L)
Sets the pilot's velocity.
static int pilotL_taskstack(lua_State *L)
Gets the name of all the pilot's current tasks (not subtasks).
static int pilotL_inrange(lua_State *L)
Checks to see if a target pilot is in range of a pilot.
static int pilotL_setInvincible(lua_State *L)
Sets the pilot's invincibility status.
LuaPilot luaL_checkpilot(lua_State *L, int ind)
Gets pilot at index or raises error if there is no pilot at index.
Definition nlua_pilot.c:533
static int pilotL_outfitAdd(lua_State *L)
Adds an outfit to a pilot.
static int pilotL_follow(lua_State *L)
Makes the pilot follow another pilot.
static int pilotL_effectAdd(lua_State *L)
Adds an effect to a pilot.
static int pilotL_outfitAddSlot(lua_State *L)
Adds an outfit to a pilot by slot name.
static int pilotL_ship(lua_State *L)
Gets the pilot's ship.
static int pilotL_flags(lua_State *L)
Gets the pilot's flags.
static int pilotL_addEnergy(lua_State *L)
Adds (or subtracts) energy to a pilot.
static int pilotL_hyperspace(lua_State *L)
Tells the pilot to hyperspace.
static int pilotL_speed(lua_State *L)
Gets the speed of a pilot.
static int pilotL_getPilots(lua_State *L)
Gets the pilots available in the system by a certain criteria.
static int pilotL_setVisplayer(lua_State *L)
Marks the pilot as always visible for the player.
static int pilotL_effectGet(lua_State *L)
Gets the effects on a pilot.
static int pilotL_faction(lua_State *L)
Gets the pilot's faction.
static int pilotL_shippropReset(lua_State *L)
Resets the ship property stats of a pilot.
static int pilotL_setTargetAsteroid(lua_State *L)
Sets the pilot's asteroid target.
static int pilotL_renderTo(lua_State *L)
Renders the pilot to a canvas.
static int pilotL_target(lua_State *L)
Gets the pilot target of the pilot.
static int pilotL_weapset(lua_State *L)
Gets the weapset weapon of the pilot.
static int pilotL_idle(lua_State *L)
Checks to see if the pilot is idle.
static int pilotL_effectClear(lua_State *L)
Clears the effect on a pilot.
static int pilotL_add(lua_State *L)
Adds a ship with an AI and faction to the system (instead of a predefined fleet).
Definition nlua_pilot.c:658
static int pilotL_turn(lua_State *L)
Gets the turn of a pilot.
const Ship ** lua_pushship(lua_State *L, const Ship *ship)
Pushes a ship on the stack.
Definition nlua_ship.c:166
int nlua_loadShip(nlua_env env)
Loads the ship library.
Definition nlua_ship.c:90
const Ship * luaL_validship(lua_State *L, int ind)
Makes sure the ship is valid or raises a Lua error.
Definition nlua_ship.c:141
LuaSpob lua_tospob(lua_State *L, int ind)
This module allows you to handle the spobs from Lua.
Definition nlua_spob.c:149
LuaSpob * lua_pushspob(lua_State *L, LuaSpob spob)
Pushes a spob on the stack.
Definition nlua_spob.c:201
Spob * luaL_validspob(lua_State *L, int ind)
Gets a spob directly.
Definition nlua_spob.c:174
int lua_isspob(lua_State *L, int ind)
Checks to see if ind is a spob.
Definition nlua_spob.c:216
LuaSystem * lua_pushsystem(lua_State *L, LuaSystem sys)
Pushes a system on the stack.
StarSystem * luaL_validsystem(lua_State *L, int ind)
Gets system (or system name) at index raising an error if type doesn't match.
LuaSystem lua_tosystem(lua_State *L, int ind)
Lua system module.
int lua_issystem(lua_State *L, int ind)
Checks to see if ind is a system.
glTexture ** lua_pushtex(lua_State *L, glTexture *texture)
Pushes a texture on the stack.
Definition nlua_tex.c:130
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
double ntime_convertSeconds(ntime_t t)
Converts the time to seconds.
Definition ntime.c:153
glInfo gl_screen
Definition opengl.c:51
glTexture * gl_dupTexture(const glTexture *texture)
Duplicates a texture.
Definition opengl_tex.c:917
int outfit_isBeam(const Outfit *o)
Checks if outfit is a beam type weapon.
Definition outfit.c:554
int outfit_isLauncher(const Outfit *o)
Checks if outfit is a weapon launcher.
Definition outfit.c:564
const char * outfit_getTypeBroad(const Outfit *o)
Gets the outfit's broad type.
Definition outfit.c:976
int outfit_fitsSlot(const Outfit *o, const OutfitSlot *s)
Checks to see if an outfit fits a slot.
Definition outfit.c:1047
int outfit_isFighterBay(const Outfit *o)
Checks if outfit is a fighter bay.
Definition outfit.c:616
int outfit_isAfterburner(const Outfit *o)
Checks if outfit is an afterburner.
Definition outfit.c:607
const char * outfit_getType(const Outfit *o)
Gets the outfit's specific type.
Definition outfit.c:945
int outfit_isMod(const Outfit *o)
Checks if outfit is a ship modification.
Definition outfit.c:598
const Damage * outfit_damage(const Outfit *o)
Gets the outfit's damage.
Definition outfit.c:713
double outfit_duration(const Outfit *o)
Gets the outfit's duration.
Definition outfit.c:917
double outfit_cooldown(const Outfit *o)
Gets the outfit's cooldown.
Definition outfit.c:932
int outfit_isBolt(const Outfit *o)
Checks if outfit is bolt type weapon.
Definition outfit.c:544
double outfit_delay(const Outfit *o)
Gets the outfit's delay.
Definition outfit.c:734
int outfit_fitsSlotType(const Outfit *o, const OutfitSlot *s)
Checks to see if an outfit fits a slot type (ignoring size).
Definition outfit.c:1092
char pilot_getFactionColourChar(const Pilot *p)
Gets the faction colour char, works like faction_getColourChar but for a pilot.
Definition pilot.c:1080
void pilot_choosePoint(vec2 *vp, Spob **spob, JumpPoint **jump, int lf, int ignore_rules, int guerilla)
Finds a spawn point for a pilot.
Definition pilot.c:3442
int pilot_isHostile(const Pilot *p)
Checks to see if pilot is hostile to the player.
Definition pilot.c:678
void pilot_updateDisable(Pilot *p, unsigned int shooter)
Handles pilot disabling. Set or unset the disable status depending on health and stress values.
Definition pilot.c:1550
void pilot_cooldown(Pilot *p, int dochecks)
Begins active cooldown, reducing hull and outfit temperatures.
Definition pilot.c:893
void pilot_rmHostile(Pilot *p)
Unmarks a pilot as hostile to player.
Definition pilot.c:1233
int pilot_validEnemy(const Pilot *p, const Pilot *target)
Checks to see if a pilot is a valid enemy for another pilot.
Definition pilot.c:277
int pilot_areEnemies(const Pilot *p, const Pilot *target)
Like areEnemies but for pilots.
Definition pilot.c:745
void pilots_clear(void)
Clears all the pilots except the player and clear-exempt pilots.
Definition pilot.c:3772
Pilot * pilot_getTarget(Pilot *p)
Gets the target of a pilot using a fancy caching system.
Definition pilot.c:634
void pilot_msg(const Pilot *p, const Pilot *receiver, const char *type, unsigned int idx)
Sends a message.
Definition pilot.c:4120
void pilot_dead(Pilot *p, unsigned int killer)
Pilot is dead, now will slowly explode.
Definition pilot.c:1628
void pilot_cooldownEnd(Pilot *p, const char *reason)
Terminates active cooldown.
Definition pilot.c:959
credits_t pilot_modCredits(Pilot *p, credits_t amount)
Modifies the amount of credits the pilot has.
Definition pilot.c:3004
unsigned int pilot_getNearestEnemy(const Pilot *p)
Gets the nearest enemy to the pilot.
Definition pilot.c:323
void pilot_setFriendly(Pilot *p)
Marks pilot as friendly to player.
Definition pilot.c:1251
int pilot_validTarget(const Pilot *p, const Pilot *target)
Checks to see if a pilot is a valid target for another pilot.
Definition pilot.c:237
PilotOutfitSlot * pilot_getDockSlot(Pilot *p)
Gets the dock slot of the pilot.
Definition pilot.c:776
int pilot_hasIllegal(const Pilot *p, int faction)
Checks to see if the pilot has illegal stuf to a faction.
Definition pilot.c:4153
void pilot_setCommMsg(Pilot *p, const char *s)
Sets the overhead communication message of the pilot.
Definition pilot.c:1096
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
Definition pilot.c:620
ntime_t pilot_hyperspaceDelay(const Pilot *p)
Calculates the hyperspace delay for a pilot.
Definition pilot.c:2948
void pilot_broadcast(Pilot *p, const char *msg, int ignore_int)
Has the pilot broadcast a message.
Definition pilot.c:1111
void pilot_setHostile(Pilot *p)
Marks pilot as hostile to player.
Definition pilot.c:1066
const glColour * pilot_getColour(const Pilot *p)
Gets a pilot's colour.
Definition pilot.c:1284
static Pilot ** pilot_stack
Definition pilot.c:61
Pilot *const * pilot_getAll(void)
Gets the pilot stack.
Definition pilot.c:94
int pilot_canTarget(const Pilot *p)
Same as pilot_validTarget but without the range check.
Definition pilot.c:254
credits_t pilot_worth(const Pilot *p, int count_unique)
Gets the price or worth of a pilot in credits.
Definition pilot.c:4096
void pilot_rmFriendly(Pilot *p)
Unmarks a pilot as friendly to player.
Definition pilot.c:1262
int pilot_areAllies(const Pilot *p, const Pilot *target)
Like areAllies but for pilots.
Definition pilot.c:721
int pilot_getJumps(const Pilot *p)
Gets the amount of jumps the pilot has left.
Definition pilot.c:1273
void pilot_delete(Pilot *p)
Deletes a pilot.
Definition pilot.c:2687
double pilot_hit(Pilot *p, const Solid *w, const Pilot *pshooter, const Damage *dmg, const Outfit *outfit, int lua_mem, int reset)
Damages the pilot.
Definition pilot.c:1338
void pilot_renderFramebuffer(Pilot *p, GLuint fbo, double fw, double fh)
Renders a pilot to a framebuffer.
Definition pilot.c:1792
Pilot * pilot_create(const Ship *ship, const char *name, int faction, const char *ai, const double dir, const vec2 *pos, const vec2 *vel, const PilotFlags flags, unsigned int dockpilot, int dockslot)
Creates a new pilot.
Definition pilot.c:3248
void pilot_sample_trails(Pilot *p, int none)
Updates the given pilot's trail emissions.
Definition pilot.c:2601
void pilot_setTarget(Pilot *p, unsigned int id)
Sets the target of the pilot.
Definition pilot.c:1308
unsigned int pilot_clone(const Pilot *ref)
Clones an existing pilot.
Definition pilot.c:3319
int pilot_cargoRmAll(Pilot *pilot, int cleanup)
Gets rid of all cargo from pilot. Can remove mission cargo.
int pilot_cargoFree(const Pilot *p)
Gets the pilot's free cargo space.
Definition pilot_cargo.c:51
int pilot_cargoRm(Pilot *pilot, const Commodity *cargo, int quantity)
Tries to get rid of quantity cargo from pilot.
int pilot_cargoOwned(const Pilot *pilot, const Commodity *cargo)
Gets how many of the commodity a pilot has.
Definition pilot_cargo.c:36
int pilot_cargoJet(Pilot *p, const Commodity *cargo, int quantity, int simulate)
Tries to get rid of quantity cargo from pilot, jetting it into space.
int pilot_cargoAdd(Pilot *pilot, const Commodity *cargo, int quantity, unsigned int id)
Tries to add quantity of cargo to pilot.
int pilot_inRangePilot(const Pilot *p, const Pilot *target, double *dist2)
Check to see if a pilot is in sensor range of another.
Definition pilot_ew.c:244
int pilot_ewScanCheck(const Pilot *p)
Checks to see if a scan is done.
Definition pilot_ew.c:71
void pilot_destealth(Pilot *p)
Destealths a pilot.
Definition pilot_ew.c:552
double pilot_ewWeaponTrack(const Pilot *p, const Pilot *t, double trackmin, double trackmax)
Calculates the weapon lead (1. is 100%, 0. is 0%)..
Definition pilot_ew.c:389
int pilot_inRangeAsteroid(const Pilot *p, int ast, int fie)
Check to see if an asteroid is in sensor range of the pilot.
Definition pilot_ew.c:309
int pilot_inRange(const Pilot *p, double x, double y)
Check to see if a position is in range of the pilot.
Definition pilot_ew.c:221
int pilot_stealth(Pilot *p)
Stealths a pilot.
Definition pilot_ew.c:513
double pilot_heatEfficiencyMod(double T, double Tb, double Tc)
Returns a 0:1 modifier representing efficiency (1. being normal).
Definition pilot_heat.c:235
double pilot_heatFirePercent(double T)
Returns a 0:2 level of fire, 0:1 is the accuracy point, 1:2 is fire rate point.
Definition pilot_heat.c:293
void pilot_clearHooks(Pilot *p)
Clears the pilots hooks.
Definition pilot_hook.c:206
int pilot_runHook(Pilot *p, int hook_type)
Tries to run a pilot hook if he has it.
Definition pilot_hook.c:106
int pilot_rmOutfit(Pilot *pilot, PilotOutfitSlot *s)
Removes an outfit from the pilot.
void pilot_updateMass(Pilot *pilot)
Updates the pilot stats after mass change.
int pilot_maxAmmoO(const Pilot *p, const Outfit *o)
Gets the maximum available ammo for a pilot for a specific outfit.
void pilot_calcStats(Pilot *pilot)
Recalculates the pilot's stats based on his outfits.
void pilot_fillAmmo(Pilot *pilot)
Fills pilot's ammo completely.
int pilot_addAmmo(Pilot *pilot, PilotOutfitSlot *s, int quantity)
Adds some ammo to the pilot stock.
int pilot_rmOutfitRaw(Pilot *pilot, PilotOutfitSlot *s)
Removes an outfit from the pilot without doing any checks.
int pilot_outfitLInit(const Pilot *pilot, PilotOutfitSlot *po)
Runs the pilot's Lua outfits init script for an outfit.
PilotOutfitSlot * pilot_getSlotByName(Pilot *pilot, const char *name)
Gets the outfit slot by name.
int pilot_reportSpaceworthy(const Pilot *p, char *buf, int bufSize)
Pilot safety report - makes sure stats are safe.
int pilot_addOutfitTest(Pilot *pilot, const Outfit *outfit, const PilotOutfitSlot *s, int warn)
Tests to see if an outfit can be added.
int pilot_addOutfitRaw(Pilot *pilot, const Outfit *outfit, PilotOutfitSlot *s)
Adds an outfit to the pilot, ignoring CPU or other limits.
int pilot_rmOutfitIntrinsic(Pilot *pilot, const Outfit *outfit)
Removes an outfit from an intrinsic slot.
int pilot_addOutfitIntrinsic(Pilot *pilot, const Outfit *outfit)
Adds an outfit as an intrinsic slot.
int pilot_weapSetTypeCheck(Pilot *p, int id)
Checks the current weapon set type.
void pilot_getRateMod(double *rate_mod, double *energy_mod, const Pilot *p, const Outfit *o)
Gets applicable fire rate and energy modifications for a pilot's weapon.
void pilot_weapSetInrange(Pilot *p, int id, int inrange)
Changes the weapon set inrange property.
void pilot_weapSetCleanup(Pilot *p, int id)
Cleans up a weapon set.
void pilot_weapSetRm(Pilot *p, int id, const PilotOutfitSlot *o)
Removes a slot from a weapon set.
PilotWeaponSet * pilot_weapSet(Pilot *p, int id)
Gets a weapon set from id.
PilotWeaponSetOutfit * pilot_weapSetList(Pilot *p, int id)
Lists the items in a pilot weapon set.
int pilot_outfitOn(Pilot *p, PilotOutfitSlot *o)
Enable a given active outfit.
double pilot_weapSetAmmo(Pilot *p, int id, int level)
Gets the ammo of the current pilot weapon set.
void pilot_weaponAuto(Pilot *p)
Tries to automatically set and create the pilot's weapon set.
void pilot_weapSetPress(Pilot *p, int id, int type)
Handles a weapon set press.
const char * pilot_weapSetName(Pilot *p, int id)
Gets the name of a weapon set.
int pilot_outfitOff(Pilot *p, PilotOutfitSlot *o)
Disables a given active outfit.
void pilot_weapSetType(Pilot *p, int id, WeaponSetType type)
Changes the weapon sets mode.
void pilot_weapSetAdd(Pilot *p, int id, const PilotOutfitSlot *o, int level)
Adds an outfit to a weapon set.
void player_hailStart(void)
Starts the hail sounds and aborts autoNav.
Definition player.c:1923
void player_targetSet(unsigned int id)
Sets the player's target.
Definition player.c:2137
Player_t player
Definition player.c:74
void player_destroyed(void)
Player blew up in a fireball.
Definition player.c:2549
void player_autonavAbort(const char *reason)
Aborts autonav.
static const double c[]
Definition rng.c:264
static const double d[]
Definition rng.c:273
void ss_free(ShipStatList *ll)
Frees a list of ship stats.
Definition shipstats.c:887
int ss_statsMergeFromList(ShipStats *stats, const ShipStatList *list)
Updates a stat structure from a stat list.
Definition shipstats.c:627
int ss_statsGetLua(lua_State *L, const ShipStats *s, const char *name, int internal)
Gets a ship stat value by name and pushes it to Lua.
Definition shipstats.c:1054
ShipStatsType ss_typeFromName(const char *name)
Gets the type from the name.
Definition shipstats.c:685
int ss_statsInit(ShipStats *stats)
Initializes a stat structure.
Definition shipstats.c:430
int space_canHyperspace(const Pilot *p)
Checks to make sure if pilot is far enough away to hyperspace.
Definition space.c:469
StarSystem * system_getIndex(int id)
Get the system by its index.
Definition space.c:989
int space_calcJumpInPos(const StarSystem *in, const StarSystem *out, vec2 *pos, vec2 *vel, double *dir, const Pilot *p)
Calculates the jump in pos for a pilot.
Definition space.c:527
StarSystem * cur_system
Definition space.c:106
int space_spawn
Definition space.c:117
Represents a single asteroid.
Definition asteroid.h:77
Represents a polygon used for collision detection.
Definition collision.h:13
float * x
Definition collision.h:14
float * y
Definition collision.h:15
Represents a commodity.
Definition commodity.h:43
char * name
Definition commodity.h:44
Core damage that an outfit does.
Definition outfit.h:138
int type
Definition outfit.h:139
double disable
Definition outfit.h:142
double penetration
Definition outfit.h:140
double damage
Definition outfit.h:141
Pilot ship effect data.
Definition effect.h:16
double duration
Definition effect.h:21
char * name
Definition effect.h:17
glTexture * icon
Definition effect.h:25
unsigned int flags
Definition effect.h:22
Pilot ship effect.
Definition effect.h:46
const EffectData * data
Definition effect.h:47
double timer
Definition effect.h:49
Stores an escort.
Definition pilot.h:206
unsigned int id
Definition pilot.h:209
EscortType_t type
Definition pilot.h:208
Wrapper to canvass.
Definition nlua_canvas.h:19
glTexture * tex
Definition nlua_canvas.h:21
Lua jump Wrapper.
Definition nlua_jump.h:14
int destid
Definition nlua_jump.h:16
int srcid
Definition nlua_jump.h:15
double duration
Definition outfit.h:182
double trackmin
Definition outfit.h:159
double trackmax
Definition outfit.h:160
A ship outfit, depends radically on the type.
Definition outfit.h:328
OutfitLauncherData lau
Definition outfit.h:406
OutfitBeamData bem
Definition outfit.h:405
OutfitBoltData blt
Definition outfit.h:404
double overheat_max
Definition outfit.h:358
union Outfit::@12 u
nlua_env lua_env
Definition outfit.h:371
double overheat_min
Definition outfit.h:357
char * name
Definition outfit.h:329
Stores a pilot commodity.
Definition pilot.h:179
const Commodity * commodity
Definition pilot.h:180
unsigned int id
Definition pilot.h:182
double lockon_timer
Definition pilot.h:101
Stores an outfit the pilot has.
Definition pilot.h:108
unsigned int beamid
Definition pilot.h:134
PilotOutfitAmmo ammo
Definition pilot.h:135
double stimer
Definition pilot.h:124
double heat_T
Definition pilot.h:117
double progress
Definition pilot.h:127
PilotOutfitState state
Definition pilot.h:123
double timer
Definition pilot.h:125
ShipOutfitSlot * sslot
Definition pilot.h:114
const Outfit * outfit
Definition pilot.h:112
A pilot Weapon Set Outfit.
Definition pilot.h:146
A weapon set represents a set of weapons that have an action.
Definition pilot.h:164
PilotWeaponSetOutfit * slots
Definition pilot.h:167
The representation of an in-game pilot.
Definition pilot.h:217
unsigned int id
Definition pilot.h:218
unsigned int parent
Definition pilot.h:333
const Ship * ship
Definition pilot.h:226
int faction
Definition pilot.h:222
Solid solid
Definition pilot.h:227
char * name
Definition pilot.h:219
Escort_t * escorts
Definition pilot.h:334
Pilot * p
Definition player.h:101
const Outfit * data
Definition ship.h:76
OutfitSlot slot
Definition ship.h:71
Represents ship statistics, properties ship can use.
Definition shipstats.h:198
Represents a space ship.
Definition ship.h:94
char * name
Definition ship.h:95
vec2 vel
Definition physics.h:48
double mass
Definition physics.h:45
vec2 pos
Definition physics.h:49
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Definition space.h:89
double radius
Definition space.h:95
char * name
Definition space.h:91
vec2 pos
Definition space.h:94
int id
Definition space.h:90
Basic AI task.
Definition ai.h:24
char * name
Definition ai.h:26
struct Task_ * subtask
Definition ai.h:30
int done
Definition ai.h:28
int dat
Definition ai.h:32
int rh
Definition opengl.h:51
int rw
Definition opengl.h:50
double w
Definition opengl_tex.h:40
double h
Definition opengl_tex.h:41
Contains a mission variable.
Definition lvar.h:24
Small struct to handle flags.
const char * name
Definition msgcat.c:199
Represents a 2d vector.
Definition vec2.h:32
double y
Definition vec2.h:34
double x
Definition vec2.h:33
void weapon_clear(void)
Clears all the weapons, does NOT free the layers.
Definition weapon.c:2680
void weapon_hitAI(Pilot *p, const Pilot *shooter, double dmg)
Informs the AI if needed that it's been hit.
Definition weapon.c:1429