naev 0.10.4
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 "nlua.h"
27#include "nlua_asteroid.h"
28#include "nlua_canvas.h"
29#include "nlua_colour.h"
30#include "nlua_gfx.h"
31#include "nlua_commodity.h"
32#include "nlua_faction.h"
33#include "nlua_jump.h"
34#include "nlua_pilotoutfit.h"
35#include "nlua_outfit.h"
36#include "nlua_spob.h"
37#include "nlua_ship.h"
38#include "nlua_system.h"
39#include "nlua_vec2.h"
40#include "nlua_tex.h"
41#include "nluadef.h"
42#include "pilot.h"
43#include "pilot_heat.h"
44#include "player.h"
45#include "rng.h"
46#include "space.h"
47#include "weapon.h"
48
49/*
50 * From ai.c
51 */
52extern Pilot *cur_pilot;
53
54/*
55 * Prototypes.
56 */
57static int pilotL_getFriendOrFoe( lua_State *L, int friend );
58static Task *pilotL_newtask( lua_State *L, Pilot* p, const char *task );
59static int outfit_compareActive( const void *slot1, const void *slot2 );
60static int pilotL_setFlagWrapper( lua_State *L, int flag );
61static int pilot_outfitAddSlot( Pilot *p, const Outfit *o, PilotOutfitSlot *s, int bypass_slot, int bypass_cpu );
62
63/* Pilot metatable methods. */
64static int pilotL_add( lua_State *L );
65static int pilotL_clone( lua_State *L );
66static int pilotL_remove( lua_State *L );
67static int pilotL_clear( lua_State *L );
68static int pilotL_clearSelect( lua_State *L );
69static int pilotL_canSpawn( lua_State *L );
70static int pilotL_toggleSpawn( lua_State *L );
71static int pilotL_getPilots( lua_State *L );
72static int pilotL_getAllies( lua_State *L );
73static int pilotL_getEnemies( lua_State *L );
74static int pilotL_getVisible( lua_State *L );
75static int pilotL_getInrange( lua_State *L );
76static int pilotL_eq( lua_State *L );
77static int pilotL_name( lua_State *L );
78static int pilotL_id( lua_State *L );
79static int pilotL_exists( lua_State *L );
80static int pilotL_target( lua_State *L );
81static int pilotL_setTarget( lua_State *L );
82static int pilotL_targetAsteroid( lua_State *L );
83static int pilotL_setTargetAsteroid( lua_State *L );
84static int pilotL_inrange( lua_State *L );
85static int pilotL_inrangeAsteroid( lua_State *L );
86static int pilotL_scandone( lua_State *L );
87static int pilotL_withPlayer( lua_State *L );
88static int pilotL_nav( lua_State *L );
89static int pilotL_activeWeapset( lua_State *L );
90static int pilotL_weapset( lua_State *L );
91static int pilotL_weapsetHeat( lua_State *L );
92static int pilotL_actives( lua_State *L );
93static int pilotL_outfitsList( lua_State *L );
94static int pilotL_outfits( lua_State *L );
95static int pilotL_outfitGet( lua_State *L );
96static int pilotL_outfitToggle( lua_State *L );
97static int pilotL_outfitReady( lua_State *L );
98static int pilotL_rename( lua_State *L );
99static int pilotL_position( lua_State *L );
100static int pilotL_velocity( lua_State *L );
101static int pilotL_isStopped( lua_State *L );
102static int pilotL_dir( lua_State *L );
103static int pilotL_evasion( lua_State *L );
104static int pilotL_temp( lua_State *L );
105static int pilotL_mass( lua_State *L );
106static int pilotL_faction( lua_State *L );
107static int pilotL_spaceworthy( lua_State *L );
108static int pilotL_setPosition( lua_State *L );
109static int pilotL_setVelocity( lua_State *L );
110static int pilotL_setDir( lua_State *L );
111static int pilotL_broadcast( lua_State *L );
112static int pilotL_comm( lua_State *L );
113static int pilotL_setFaction( lua_State *L );
114static int pilotL_setHostile( lua_State *L );
115static int pilotL_setFriendly( lua_State *L );
116static int pilotL_setInvincible( lua_State *L );
117static int pilotL_setInvincPlayer( lua_State *L );
118static int pilotL_setHide( lua_State *L );
119static int pilotL_setInvisible( lua_State *L );
120static int pilotL_setNoRender( lua_State *L );
121static int pilotL_setVisplayer( lua_State *L );
122static int pilotL_setVisible( lua_State *L );
123static int pilotL_setHilight( lua_State *L );
124static int pilotL_setBribed( lua_State *L );
125static int pilotL_getColour( lua_State *L );
126static int pilotL_getHostile( lua_State *L );
127static int pilotL_flags( lua_State *L );
128static int pilotL_hasIllegal( lua_State *L );
129static int pilotL_setActiveBoard( lua_State *L );
130static int pilotL_setNoDeath( lua_State *L );
131static int pilotL_disable( lua_State *L );
132static int pilotL_cooldown( lua_State *L );
133static int pilotL_setCooldown( lua_State *L );
134static int pilotL_cooldownCycle( lua_State *L );
135static int pilotL_setNoJump( lua_State *L );
136static int pilotL_setNoLand( lua_State *L );
137static int pilotL_setNoClear( lua_State *L );
138static int pilotL_outfitAdd( lua_State *L );
139static int pilotL_outfitRm( lua_State *L );
140static int pilotL_outfitSlot( lua_State *L );
141static int pilotL_outfitAddSlot( lua_State *L );
142static int pilotL_outfitRmSlot( lua_State *L );
143static int pilotL_outfitAddIntrinsic( lua_State *L );
144static int pilotL_outfitRmIntrinsic( lua_State *L );
145static int pilotL_setFuel( lua_State *L );
146static int pilotL_intrinsicReset( lua_State *L );
147static int pilotL_intrinsicSet( lua_State *L );
148static int pilotL_intrinsicGet( lua_State *L );
149static int pilotL_effectClear( lua_State *L );
150static int pilotL_effectAdd( lua_State *L );
151static int pilotL_effectRm( lua_State *L );
152static int pilotL_effectGet( lua_State *L );
153static int pilotL_ai( lua_State *L );
154static int pilotL_changeAI( lua_State *L );
155static int pilotL_setTemp( lua_State *L );
156static int pilotL_setHealth( lua_State *L );
157static int pilotL_addHealth( lua_State *L );
158static int pilotL_setEnergy( lua_State *L );
159static int pilotL_fillAmmo( lua_State *L );
160static int pilotL_setNoboard( lua_State *L );
161static int pilotL_setNoDisable( lua_State *L );
162static int pilotL_setSpeedLimit( lua_State *L);
163static int pilotL_getHealth( lua_State *L );
164static int pilotL_getEnergy( lua_State *L );
165static int pilotL_getLockon( lua_State *L );
166static int pilotL_getStats( lua_State *L );
167static int pilotL_getShipStat( lua_State *L );
168static int pilotL_getDetectedDistance( lua_State *L );
169static int pilotL_cargoFree( lua_State *L );
170static int pilotL_cargoHas( lua_State *L );
171static int pilotL_cargoAdd( lua_State *L );
172static int pilotL_cargoRm( lua_State *L );
173static int pilotL_cargoJet( lua_State *L );
174static int pilotL_cargoList( lua_State *L );
175static int pilotL_credits( lua_State *L );
176static int pilotL_ship( lua_State *L );
177static int pilotL_points( lua_State *L );
178static int pilotL_idle( lua_State *L );
179static int pilotL_control( lua_State *L );
180static int pilotL_memory( lua_State *L );
181static int pilotL_ainame( lua_State *L );
182static int pilotL_task( lua_State *L );
183static int pilotL_taskname( lua_State *L );
184static int pilotL_taskstack( lua_State *L );
185static int pilotL_taskdata( lua_State *L );
186static int pilotL_taskclear( lua_State *L );
187static int pilotL_pushtask( lua_State *L );
188static int pilotL_poptask( lua_State *L );
189static int pilotL_refuel( lua_State *L );
190static int pilotL_moveto( lua_State *L );
191static int pilotL_face( lua_State *L );
192static int pilotL_brake( lua_State *L );
193static int pilotL_follow( lua_State *L );
194static int pilotL_attack( lua_State *L );
195static int pilotL_board( lua_State *L );
196static int pilotL_runaway( lua_State *L );
197static int pilotL_gather( lua_State *L );
198static int pilotL_hyperspace( lua_State *L );
199static int pilotL_stealth( lua_State *L );
200static int pilotL_tryStealth( lua_State *L );
201static int pilotL_land( lua_State *L );
202static int pilotL_hailPlayer( lua_State *L );
203static int pilotL_msg( lua_State *L );
204static int pilotL_mothership( lua_State *L );
205static int pilotL_leader( lua_State *L );
206static int pilotL_setLeader( lua_State *L );
207static int pilotL_followers( lua_State *L );
208static int pilotL_hookClear( lua_State *L );
209static int pilotL_choosePoint( lua_State *L );
210static int pilotL_collisionTest( lua_State *L );
211static int pilotL_damage( lua_State *L );
212static int pilotL_kill( lua_State *L );
213static int pilotL_knockback( lua_State *L );
214static int pilotL_calcStats( lua_State *L );
215static int pilotL_showEmitters( lua_State *L );
216static int pilotL_shipvarPeek( lua_State *L );
217static int pilotL_shipvarPush( lua_State *L );
218static int pilotL_shipvarPop( lua_State *L );
219static int pilotL_render( lua_State *L );
220static int pilotL_renderTo( lua_State *L );
221static const luaL_Reg pilotL_methods[] = {
222 /* General. */
223 { "add", pilotL_add },
224 { "clone", pilotL_clone },
225 { "rm", pilotL_remove },
226 { "get", pilotL_getPilots },
227 { "getAllies", pilotL_getAllies },
228 { "getEnemies", pilotL_getEnemies },
229 { "getVisible", pilotL_getVisible },
230 { "getInrange", pilotL_getInrange },
231 { "__eq", pilotL_eq },
232 { "__tostring", pilotL_name },
233 /* Info. */
234 { "name", pilotL_name },
235 { "id", pilotL_id },
236 { "exists", pilotL_exists },
237 { "target", pilotL_target },
238 { "setTarget", pilotL_setTarget },
239 { "targetAsteroid", pilotL_targetAsteroid },
240 { "setTargetAsteroid", pilotL_setTargetAsteroid },
241 { "inrange", pilotL_inrange },
242 { "inrangeAsteroid", pilotL_inrangeAsteroid },
243 { "scandone", pilotL_scandone },
244 { "withPlayer", pilotL_withPlayer },
245 { "nav", pilotL_nav },
246 { "activeWeapset", pilotL_activeWeapset },
247 { "weapset", pilotL_weapset },
248 { "weapsetHeat", pilotL_weapsetHeat },
249 { "actives", pilotL_actives },
250 { "outfitsList", pilotL_outfitsList },
251 { "outfits", pilotL_outfits },
252 { "outfitGet", pilotL_outfitGet },
253 { "outfitToggle", pilotL_outfitToggle },
254 { "outfitReady", pilotL_outfitReady },
255 { "rename", pilotL_rename },
256 { "pos", pilotL_position },
257 { "vel", pilotL_velocity },
258 { "isStopped", pilotL_isStopped },
259 { "dir", pilotL_dir },
260 { "evasion", pilotL_evasion },
261 { "temp", pilotL_temp },
262 { "mass", pilotL_mass },
263 { "cooldown", pilotL_cooldown },
264 { "faction", pilotL_faction },
265 { "spaceworthy", pilotL_spaceworthy },
266 { "health", pilotL_getHealth },
267 { "energy", pilotL_getEnergy },
268 { "lockon", pilotL_getLockon },
269 { "stats", pilotL_getStats },
270 { "shipstat", pilotL_getShipStat },
271 { "detectedDistance", pilotL_getDetectedDistance },
272 { "colour", pilotL_getColour },
273 { "hostile", pilotL_getHostile },
274 { "flags", pilotL_flags },
275 { "hasIllegal", pilotL_hasIllegal },
276 /* System. */
277 { "clear", pilotL_clear },
278 { "clearSelect", pilotL_clearSelect },
279 { "canSpawn", pilotL_canSpawn },
280 { "toggleSpawn", pilotL_toggleSpawn },
281 /* Modify. */
282 { "ai", pilotL_ai },
283 { "changeAI", pilotL_changeAI },
284 { "setTemp", pilotL_setTemp },
285 { "setHealth", pilotL_setHealth },
286 { "addHealth", pilotL_addHealth },
287 { "setEnergy", pilotL_setEnergy },
288 { "fillAmmo", pilotL_fillAmmo },
289 { "setNoboard", pilotL_setNoboard },
290 { "setNoDisable", pilotL_setNoDisable },
291 { "setSpeedLimit", pilotL_setSpeedLimit },
292 { "setPos", pilotL_setPosition },
293 { "setVel", pilotL_setVelocity },
294 { "setDir", pilotL_setDir },
295 { "setFaction", pilotL_setFaction },
296 { "setHostile", pilotL_setHostile },
297 { "setFriendly", pilotL_setFriendly },
298 { "setInvincible", pilotL_setInvincible },
299 { "setInvincPlayer", pilotL_setInvincPlayer },
300 { "setHide", pilotL_setHide },
301 { "setInvisible", pilotL_setInvisible },
302 { "setNoRender", pilotL_setNoRender },
303 { "setVisplayer", pilotL_setVisplayer },
304 { "setVisible", pilotL_setVisible },
305 { "setHilight", pilotL_setHilight },
306 { "setBribed", pilotL_setBribed },
307 { "setActiveBoard", pilotL_setActiveBoard },
308 { "setNoDeath", pilotL_setNoDeath },
309 { "disable", pilotL_disable },
310 { "setCooldown", pilotL_setCooldown },
311 { "cooldownCycle", pilotL_cooldownCycle },
312 { "setNoJump", pilotL_setNoJump },
313 { "setNoLand", pilotL_setNoLand },
314 { "setNoClear", pilotL_setNoClear },
315 /* Talk. */
316 { "broadcast", pilotL_broadcast },
317 { "comm", pilotL_comm },
318 /* Outfits. */
319 { "outfitAdd", pilotL_outfitAdd },
320 { "outfitRm", pilotL_outfitRm },
321 { "outfitSlot", pilotL_outfitSlot },
322 { "outfitAddSlot", pilotL_outfitAddSlot },
323 { "outfitRmSlot", pilotL_outfitRmSlot },
324 { "outfitAddIntrinsic", pilotL_outfitAddIntrinsic },
325 { "outfitRmIntrinsic", pilotL_outfitRmIntrinsic },
326 { "setFuel", pilotL_setFuel },
327 { "intrinsicReset", pilotL_intrinsicReset },
328 { "intrinsicSet", pilotL_intrinsicSet },
329 { "intrinsicGet", pilotL_intrinsicGet },
330 { "effectClear", pilotL_effectClear },
331 { "effectAdd", pilotL_effectAdd },
332 { "effectRm", pilotL_effectRm },
333 { "effectGet", pilotL_effectGet },
334 /* Ship. */
335 { "ship", pilotL_ship },
336 { "points", pilotL_points },
337 /* Cargo and moolah. */
338 { "cargoFree", pilotL_cargoFree },
339 { "cargoHas", pilotL_cargoHas },
340 { "cargoAdd", pilotL_cargoAdd },
341 { "cargoRm", pilotL_cargoRm },
342 { "cargoJet", pilotL_cargoJet },
343 { "cargoList", pilotL_cargoList },
344 { "credits", pilotL_credits },
345 /* Manual AI control. */
346 { "idle", pilotL_idle },
347 { "control", pilotL_control },
348 { "memory", pilotL_memory },
349 { "ainame", pilotL_ainame },
350 { "task", pilotL_task },
351 { "taskname", pilotL_taskname },
352 { "taskstack", pilotL_taskstack },
353 { "taskdata", pilotL_taskdata },
354 { "taskClear", pilotL_taskclear },
355 { "pushtask", pilotL_pushtask },
356 { "poptask", pilotL_poptask },
357 { "refuel", pilotL_refuel },
358 { "moveto", pilotL_moveto },
359 { "face", pilotL_face },
360 { "brake", pilotL_brake },
361 { "follow", pilotL_follow },
362 { "attack", pilotL_attack },
363 { "board", pilotL_board },
364 { "runaway", pilotL_runaway },
365 { "gather", pilotL_gather },
366 { "hyperspace", pilotL_hyperspace },
367 { "stealth", pilotL_stealth },
368 { "tryStealth", pilotL_tryStealth },
369 { "land", pilotL_land },
370 /* Misc. */
371 { "hailPlayer", pilotL_hailPlayer },
372 { "msg", pilotL_msg },
373 { "mothership" ,pilotL_mothership },
374 { "leader", pilotL_leader },
375 { "setLeader", pilotL_setLeader },
376 { "followers", pilotL_followers },
377 { "hookClear", pilotL_hookClear },
378 { "choosePoint", pilotL_choosePoint },
379 { "collisionTest", pilotL_collisionTest },
380 { "damage", pilotL_damage },
381 { "kill", pilotL_kill },
382 { "knockback", pilotL_knockback },
383 { "calcStats", pilotL_calcStats },
384 { "showEmitters", pilotL_showEmitters },
385 { "shipvarPeek", pilotL_shipvarPeek },
386 { "shipvarPush", pilotL_shipvarPush },
387 { "shipvarPop", pilotL_shipvarPop },
388 { "render", pilotL_render },
389 { "renderTo", pilotL_renderTo },
390 {0,0},
391};
399int nlua_loadPilot( nlua_env env )
400{
401 nlua_register(env, PILOT_METATABLE, pilotL_methods, 1);
402
403 /* Pilot always loads ship and asteroid. */
404 nlua_loadShip(env);
406
407 return 0;
408}
409
413static int pilotL_setFlagWrapper( lua_State *L, int flag )
414{
415 int state;
416 Pilot *p = luaL_validpilot(L,1);
417
418 /* Get state. */
419 if (lua_isnone(L,2))
420 state = 1;
421 else
422 state = lua_toboolean(L, 2);
423
424 /* Set or remove the flag. */
425 if (state)
426 pilot_setFlag( p, flag );
427 else
428 pilot_rmFlag( p, flag );
429
430 return 0;
431}
432
453LuaPilot lua_topilot( lua_State *L, int ind )
454{
455 return *((LuaPilot*) lua_touserdata(L,ind));
456}
464LuaPilot luaL_checkpilot( lua_State *L, int ind )
465{
466 if (lua_ispilot(L,ind))
467 return lua_topilot(L,ind);
468 luaL_typerror(L, ind, PILOT_METATABLE);
469 return 0;
470}
478Pilot* luaL_validpilot( lua_State *L, int ind )
479{
480 Pilot *p = pilot_get(luaL_checkpilot(L,ind));
481 if (p==NULL) {
482 NLUA_ERROR(L,_("Pilot is invalid."));
483 return NULL;
484 }
485
486 return p;
487}
495LuaPilot* lua_pushpilot( lua_State *L, LuaPilot pilot )
496{
497 LuaPilot *p = (LuaPilot*) lua_newuserdata(L, sizeof(LuaPilot));
498 *p = pilot;
499 luaL_getmetatable(L, PILOT_METATABLE);
500 lua_setmetatable(L, -2);
501 return p;
502}
510int lua_ispilot( lua_State *L, int ind )
511{
512 int ret;
513
514 if (lua_getmetatable(L,ind)==0)
515 return 0;
516 lua_getfield(L, LUA_REGISTRYINDEX, PILOT_METATABLE);
517
518 ret = 0;
519 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
520 ret = 1;
521
522 lua_pop(L, 2); /* remove both metatables */
523 return ret;
524}
525
536static int pilotL_choosePoint( lua_State *L )
537{
538 LuaFaction lf;
539 int ignore_rules, guerilla;
540 Spob *spob = NULL;
541 JumpPoint *jump = NULL;
542 vec2 vp;
543
544 /* Parameters. */
545 lf = luaL_validfaction(L,1);
546 ignore_rules = lua_toboolean(L,2);
547 guerilla = lua_toboolean(L,3);
548
549 pilot_choosePoint( &vp, &spob, &jump, lf, ignore_rules, guerilla );
550
551 if (spob != NULL)
552 lua_pushspob(L, spob->id );
553 else if (jump != NULL)
554 lua_pushsystem(L, jump->from->id);
555 else
556 lua_pushvector(L, vp);
557
558 return 1;
559}
560
589static int pilotL_add( lua_State *L )
590{
591 const Ship *ship;
592 const char *pilotname, *ai;
593 unsigned int p;
594 double a, r;
595 vec2 vv, vp, vn;
596 LuaFaction lf;
597 StarSystem *ss;
598 Spob *spob;
599 JumpPoint *jump;
600 PilotFlags flags;
601 int ignore_rules;
602 Pilot *pplt;
603
604 /* Default values. */
605 pilot_clearFlagsRaw( flags );
606 vectnull(&vn); /* Need to determine angle. */
607 ss = NULL;
608 jump = NULL;
609 spob = NULL;
610 a = 0.;
611
612 /* Parse first argument - Ship Name */
613 ship = luaL_validship(L,1);
614 /* Get faction from string or number. */
615 lf = luaL_validfaction(L,2);
616 /* Get pilotname argument if provided. */
617 pilotname = luaL_optstring( L, 4, _(ship->name) );
618
619 /* Handle position/origin argument. */
620 if (lua_isvector(L,3)) {
621 vp = *lua_tovector(L,3);
622 a = RNGF() * 2.*M_PI;
623 vectnull( &vv );
624 }
625 else if (lua_issystem(L,3))
626 ss = system_getIndex( lua_tosystem(L,3) );
627 else if (lua_isjump(L,3))
628 ss = system_getIndex( lua_tojump(L,3)->destid );
629 else if (lua_isspob(L,3)) {
630 spob = luaL_validspob(L,3);
631 pilot_setFlagRaw( flags, PILOT_TAKEOFF );
632 a = RNGF() * 2. * M_PI;
633 r = RNGF() * spob->radius;
634 vec2_cset( &vp,
635 spob->pos.x + r * cos(a),
636 spob->pos.y + r * sin(a) );
637 a = RNGF() * 2.*M_PI;
638 vectnull( &vv );
639 }
640 /* Random. */
641 else if (lua_isnoneornil(L,3)) {
642 /* Check if we should ignore the strict rules. */
643 ignore_rules = 0;
644 if (lua_isboolean(L,3) && lua_toboolean(L,3))
645 ignore_rules = 1;
646
647 /* Choose the spawn point and act in consequence.*/
648 pilot_choosePoint( &vp, &spob, &jump, lf, ignore_rules, 0 );
649
650 if (spob != NULL) {
651 pilot_setFlagRaw( flags, PILOT_TAKEOFF );
652 a = RNGF() * 2. * M_PI;
653 r = RNGF() * spob->radius;
654 vec2_cset( &vp,
655 spob->pos.x + r * cos(a),
656 spob->pos.y + r * sin(a) );
657 a = RNGF() * 2.*M_PI;
658 vectnull( &vv );
659 }
660 else {
661 a = RNGF() * 2.*M_PI;
662 vectnull( &vv );
663 }
664 }
665 else
666 NLUA_INVALID_PARAMETER(L);
667
668 /* Handle system. */
669 if (ss != NULL) {
670 for (int i=0; i<array_size(cur_system->jumps); i++) {
671 if ((cur_system->jumps[i].target == ss)
672 && !jp_isFlag( cur_system->jumps[i].returnJump, JP_EXITONLY )) {
673 jump = cur_system->jumps[i].returnJump;
674 break;
675 }
676 }
677 if (jump == NULL) {
678 if (array_size(cur_system->jumps) > 0) {
679 WARN(_("Ship '%s' jumping in from non-adjacent system '%s' to '%s'."),
680 pilotname, ss->name, cur_system->name );
681 jump = cur_system->jumps[RNG_BASE(0, array_size(cur_system->jumps)-1)].returnJump;
682 }
683 else
684 WARN(_("Ship '%s' attempting to jump in from '%s', but '%s' has no jump points."),
685 pilotname, ss->name, cur_system->name );
686 }
687 }
688
689 /* Parse final argument - table of optional parameters */
690 ai = NULL;
691 if (lua_gettop( L ) >= 5 && !lua_isnil( L, 5 )) {
692 if (!lua_istable( L, 5 )) {
693 NLUA_ERROR( L, _("'parameters' should be a table of options or omitted!") );
694 return 0;
695 }
696 lua_getfield( L, 5, "ai" );
697 ai = luaL_optstring( L, -1, NULL );
698 lua_pop( L, 1 );
699
700 lua_getfield( L, 5, "naked" );
701 if (lua_toboolean(L, -1))
702 pilot_setFlagRaw( flags, PILOT_NO_OUTFITS );
703 lua_pop( L, 1 );
704
705 lua_getfield( L, 5, "stealth" );
706 if (lua_toboolean(L, -1))
707 pilot_setFlagRaw( flags, PILOT_STEALTH );
708 lua_pop( L, 1 );
709 }
710
711 /* Set up velocities and such. */
712 if (jump != NULL) {
713 space_calcJumpInPos( cur_system, jump->from, &vp, &vv, &a, NULL );
714 pilot_setFlagRaw( flags, PILOT_HYP_END );
715 }
716
717 /* Make sure angle is valid. */
718 a = fmod( a, 2.*M_PI );
719 if (a < 0.)
720 a += 2.*M_PI;
721
722 /* Create the pilot. */
723 p = pilot_create( ship, pilotname, lf, ai, a, &vp, &vv, flags, 0, 0 );
724 lua_pushpilot(L,p);
725 pplt = pilot_get( p );
726
727 /* TODO don't have space_calcJumpInPos called twice when stealth creating. */
728 if ((jump != NULL) && pilot_isFlagRaw( flags, PILOT_STEALTH )) {
729 space_calcJumpInPos( cur_system, jump->from, &pplt->solid->pos, &pplt->solid->vel, &pplt->solid->dir, pplt );
730 }
731 return 1;
732}
733
741static int pilotL_clone( lua_State *L )
742{
743 Pilot *p = luaL_validpilot(L,1);
744 LuaPilot lp = pilot_clone( p );
745 lua_pushpilot( L, lp );
746 return 1;
747}
748
757static int pilotL_remove( lua_State *L )
758{
759 Pilot *p = luaL_validpilot(L,1);
760
761 /* Make sure it's not the player. */
762 if (player.p == p) {
763 NLUA_ERROR( L, _("Trying to remove the bloody player!") );
764 return 0;
765 }
766
767 /* Deletes the pilot. */
768 pilot_delete(p);
769
770 return 0;
771}
781static int pilotL_clearSelect( lua_State *L )
782{
783 int f = luaL_validfaction(L,1);
784 Pilot *const* pilot_stack = pilot_getAll();
785
786 for (int i=0; i<array_size(pilot_stack); i++)
787 if ((pilot_stack[i]->faction == f) &&
788 !pilot_isFlag(pilot_stack[i], PILOT_DELETE) &&
789 !pilot_isFlag(pilot_stack[i], PILOT_DEAD) &&
790 !pilot_isFlag(pilot_stack[i], PILOT_HIDE))
792
793 return 0;
794}
807static int pilotL_clear( lua_State *L )
808{
809 (void) L;
810 pilots_clear();
811 weapon_clear();
812 return 0;
813}
814
821static int pilotL_canSpawn( lua_State *L )
822{
823 lua_pushboolean( L, space_spawn );
824 return 1;
825}
826
842static int pilotL_toggleSpawn( lua_State *L )
843{
844 /* Setting it directly. */
845 if (!lua_isnoneornil(L,1)) {
846 if (lua_isfaction(L,1) || lua_isstring(L,1)) {
847 int f = luaL_validfaction(L,1);
848 int b = !lua_toboolean(L,2);
849
850 /* Find the faction and set. */
851 for (int i=0; i<array_size(cur_system->presence); i++) {
852 if (cur_system->presence[i].faction != f)
853 continue;
854 cur_system->presence[i].disabled = b;
855 break;
856 }
857
858 }
859 else if (lua_isboolean(L,1))
860 space_spawn = lua_toboolean(L,1);
861 else
862 NLUA_INVALID_PARAMETER(L);
863 }
864 /* Toggling. */
865 else
867
868 lua_pushboolean(L, space_spawn);
869 return 1;
870}
884static int pilotL_getPilots( lua_State *L )
885{
886 int d = lua_toboolean(L,2); /* Whether or not to get disabled. */
887 Pilot *const* pilot_stack = pilot_getAll();
888
889 /* Check for belonging to faction. */
890 if (lua_istable(L,1) || lua_isfaction(L,1)) {
891 int *factions;
892 if (lua_isfaction(L,1)) {
893 factions = array_create( int );
894 array_push_back( &factions, lua_tofaction(L,1) );
895 }
896 else {
897 /* Get table length and preallocate. */
898 factions = array_create_size( int, lua_objlen(L,1) );
899 /* Load up the table. */
900 lua_pushnil(L);
901 while (lua_next(L, 1) != 0) {
902 if (lua_isfaction(L,-1))
903 array_push_back( &factions, lua_tofaction(L, -1) );
904 lua_pop(L,1);
905 }
906 }
907
908 /* Now put all the matching pilots in a table. */
909 lua_newtable(L);
910 int k = 1;
911 for (int i=0; i<array_size(pilot_stack); i++) {
912 for (int j=0; j<array_size(factions); j++) {
913 if ((pilot_stack[i]->faction == factions[j]) &&
914 (d || !pilot_isDisabled(pilot_stack[i])) &&
915 !pilot_isFlag(pilot_stack[i], PILOT_DELETE)) {
916 lua_pushpilot(L, pilot_stack[i]->id); /* value */
917 lua_rawseti(L,-2, k++); /* table[key] = value */
918 }
919 }
920 }
921
922 /* clean up. */
923 array_free( factions );
924 }
925 else if ((lua_isnil(L,1)) || (lua_gettop(L) == 0)) {
926 /* Now put all the matching pilots in a table. */
927 lua_newtable(L);
928 int k = 1;
929 for (int i=0; i<array_size(pilot_stack); i++) {
930 if ((d || !pilot_isDisabled(pilot_stack[i])) &&
931 !pilot_isFlag(pilot_stack[i], PILOT_DELETE)) {
932 lua_pushpilot(L, pilot_stack[i]->id); /* value */
933 lua_rawseti(L,-2,k++); /* table[key] = value */
934 }
935 }
936 }
937 else {
938 NLUA_INVALID_PARAMETER(L);
939 }
940
941 return 1;
942}
943
944/*
945 * Helper to get nearby friends or foes.
946 */
947static int pilotL_getFriendOrFoe( lua_State *L, int friend )
948{
949 int k;
950 double dd, d2;
951 Pilot *p;
952 double dist;
953 int inrange, dis, fighters;
954 vec2 *v;
955 Pilot *const* pilot_stack;
956 LuaFaction lf;
957
958 /* Check if using faction. */
959 lf = -1;
960 if (lua_isfaction(L,1))
961 lf = lua_tofaction(L,1);
962 else if (lua_isstring(L,1))
963 lf = luaL_validfaction(L,1);
964 /* Faction case. */
965 if (lf >= 0) {
966 dist = luaL_optnumber(L,2,-1.);
967 v = luaL_checkvector(L,3);
968 inrange = 0;
969 dis = lua_toboolean(L,5);
970 fighters = lua_toboolean(L,6);
971 p = NULL;
972 }
973 /* Pilot case. */
974 else {
975 p = luaL_validpilot(L,1);
976 dist = luaL_optnumber(L,2,-1.);
977 v = luaL_optvector(L,3,&p->solid->pos);
978 inrange = !lua_toboolean(L,4);
979 dis = lua_toboolean(L,5);
980 fighters = lua_toboolean(L,6);
981 }
982
983 dd = pow2(dist);
984 d2 = -1.;
985
986 /* Now put all the matching pilots in a table. */
988 lua_newtable(L);
989 k = 1;
990 for (int i=0; i<array_size(pilot_stack); i++) {
991 Pilot *plt = pilot_stack[i];
992
993 /* Check if dead. */
994 if (pilot_isFlag(plt, PILOT_DELETE))
995 continue;
996
997 /* Ignore fighters unless specified. */
998 if (!fighters && pilot_isFlag(plt, PILOT_CARRIED))
999 continue;
1000
1001 /* Check distance if necessary. */
1002 if ((dist >= 0.) &&
1003 vec2_dist2(&plt->solid->pos, v) > dd)
1004 continue;
1005
1006 /* Check if disabled. */
1007 if (dis && pilot_isDisabled(plt))
1008 continue;
1009
1010 /* Check appropriate faction. */
1011 if (friend) {
1012 if (p==NULL) {
1013 if (!areAllies( lf, plt->faction ))
1014 continue;
1015 }
1016 else {
1017 if (!pilot_areAllies( p, plt ))
1018 continue;
1019 }
1020 }
1021 else {
1022 if (p==NULL) {
1023 if (!areEnemies( lf, plt->faction ))
1024 continue;
1025 }
1026 else {
1027 if (inrange) {
1028 if (!pilot_validEnemy( p, plt ))
1029 continue;
1030 }
1031 else {
1032 if (!pilot_areEnemies( p, plt ))
1033 continue;
1034 }
1035 }
1036 }
1037
1038 /* Need extra check for friends. */
1039 if ((p!=NULL) && inrange && friend) {
1040 if (!pilot_inRangePilot( p, plt, &d2 ))
1041 continue;
1042 }
1043
1044 lua_pushpilot(L, plt->id); /* value */
1045 lua_rawseti(L,-2, k++); /* table[key] = value */
1046 }
1047 return 1;
1048}
1049
1065static int pilotL_getAllies( lua_State *L )
1066{
1067 return pilotL_getFriendOrFoe( L, 1 );
1068}
1069
1085static int pilotL_getEnemies( lua_State *L )
1086{
1087 return pilotL_getFriendOrFoe( L, 0 );
1088}
1089
1098static int pilotL_getVisible( lua_State *L )
1099{
1100 int k;
1101 Pilot *p = luaL_validpilot(L,1);
1102 int dis = lua_toboolean(L,2);
1103 Pilot *const* pilot_stack;
1104
1105 /* Now put all the matching pilots in a table. */
1107 lua_newtable(L);
1108 k = 1;
1109 for (int i=0; i<array_size(pilot_stack); i++) {
1110 /* Check if dead. */
1111 if (pilot_isFlag(pilot_stack[i], PILOT_DELETE))
1112 continue;
1113 /* Check if disabled. */
1114 if (dis && pilot_isDisabled(pilot_stack[i]))
1115 continue;
1116 /* Check visibilitiy. */
1117 if (!pilot_validTarget( p, pilot_stack[i] ))
1118 continue;
1119
1120 lua_pushpilot(L, pilot_stack[i]->id); /* value */
1121 lua_rawseti(L,-2,k++); /* table[key] = value */
1122 }
1123
1124 return 1;
1125}
1126
1136static int pilotL_getInrange( lua_State *L )
1137{
1138 int k;
1139 vec2 *v = luaL_checkvector(L,1);
1140 double d = luaL_checknumber(L,2);
1141 int dis = lua_toboolean(L,3);
1142 Pilot *const* pilot_stack;
1143
1144 d = pow2(d); /* Square it. */
1145
1146 /* Now put all the matching pilots in a table. */
1148 lua_newtable(L);
1149 k = 1;
1150 for (int i=0; i<array_size(pilot_stack); i++) {
1151 Pilot *p = pilot_stack[i];
1152
1153 /* Check if dead. */
1154 if (pilot_isFlag(p, PILOT_DELETE))
1155 continue;
1156 /* Check if hidden. */
1157 if (pilot_isFlag(p, PILOT_HIDE))
1158 continue;
1159 /* Check if disabled. */
1160 if (dis && pilot_isDisabled(p))
1161 continue;
1162
1163 /* Must be in range. */
1164 if (vec2_dist2( v, &p->solid->pos ) > d )
1165 continue;
1166
1167 lua_pushpilot(L, p->id); /* value */
1168 lua_rawseti(L,-2,k++); /* table[key] = value */
1169 }
1170
1171 return 1;
1172}
1173
1184static int pilotL_eq( lua_State *L )
1185{
1186 LuaPilot p1 = luaL_checkpilot(L,1);
1187 LuaPilot p2 = luaL_checkpilot(L,2);
1188 lua_pushboolean(L, p1 == p2);
1189 return 1;
1190}
1191
1201static int pilotL_name( lua_State *L )
1202{
1203 Pilot *p = luaL_validpilot(L,1);
1204 lua_pushstring(L, p->name);
1205 return 1;
1206}
1207
1217static int pilotL_id( lua_State *L )
1218{
1219 Pilot *p = luaL_validpilot(L,1);
1220 lua_pushnumber(L, p->id);
1221 return 1;
1222}
1223
1235static int pilotL_exists( lua_State *L )
1236{
1237 int exists;
1238 Pilot *p = pilot_get( luaL_checkpilot(L,1) );
1239
1240 /* Must still be kicking and alive. */
1241 if (p==NULL)
1242 exists = 0;
1243 else if (pilot_isFlag( p, PILOT_DEAD ) || pilot_isFlag( p, PILOT_HIDE ))
1244 exists = 0;
1245 else
1246 exists = 1;
1247
1248 /* Check if the pilot exists. */
1249 lua_pushboolean(L, exists);
1250 return 1;
1251}
1252
1262static int pilotL_target( lua_State *L )
1263{
1264 Pilot *p = luaL_validpilot(L,1);
1265 if (p->target == 0)
1266 return 0;
1267 /* Must be valid. */
1268 if (pilot_getTarget(p) == NULL)
1269 return 0;
1270 /* Push target. */
1271 lua_pushpilot(L, p->target);
1272 return 1;
1273}
1274
1282static int pilotL_setTarget( lua_State *L )
1283{
1284 unsigned int t;
1285 Pilot *p = luaL_validpilot(L,1);
1286 if (lua_isnoneornil(L,2))
1287 t = p->id;
1288 else
1289 t = luaL_validpilot(L,2)->id;
1290 if (pilot_isPlayer(p))
1291 player_targetSet( t );
1292 else
1293 pilot_setTarget( p, t );
1294 return 0;
1295}
1296
1306static int pilotL_targetAsteroid( lua_State *L )
1307{
1308 LuaAsteroid_t la;
1309
1310 Pilot *p = luaL_validpilot(L,1);
1311 if (p->nav_asteroid < 0)
1312 return 0;
1313
1314 la.parent = p->nav_anchor;
1315 la.id = p->nav_asteroid;
1316 lua_pushasteroid(L, la);
1317 return 1;
1318}
1319
1327static int pilotL_setTargetAsteroid( lua_State *L )
1328{
1329 Pilot *p = luaL_validpilot(L,1);
1331
1332 /* Set the target asteroid. */
1333 p->nav_anchor = la->parent;
1334 p->nav_asteroid = la->id;
1335
1336 /* Untarget pilot. */
1337 p->target = p->id;
1338 p->ptarget = NULL;
1339
1340 return 0;
1341}
1342
1354static int pilotL_inrange( lua_State *L )
1355{
1356 /* Parse parameters. */
1357 Pilot *p = luaL_validpilot(L,1);
1358 Pilot *t = luaL_validpilot(L,2);
1359
1360 /* Check if in range. */
1361 int ret = pilot_inRangePilot( p, t, NULL );
1362 if (ret == 1) { /* In range. */
1363 lua_pushboolean(L,1);
1364 lua_pushboolean(L,1);
1365 }
1366 else if (ret == 0) { /* Not in range. */
1367 lua_pushboolean(L,0);
1368 lua_pushboolean(L,0);
1369 }
1370 else { /* Detected fuzzy. */
1371 lua_pushboolean(L,1);
1372 lua_pushboolean(L,0);
1373 }
1374 return 2;
1375}
1376
1385static int pilotL_inrangeAsteroid( lua_State *L )
1386{
1387 /* Parse parameters. */
1388 Pilot *p = luaL_validpilot(L,1);
1390
1391 /* Check if in range. */
1392 lua_pushboolean(L, pilot_inRangeAsteroid( p, la->id, la->parent ));
1393 return 1;
1394}
1395
1402static int pilotL_scandone( lua_State *L )
1403{
1404 Pilot *p = luaL_validpilot(L,1);
1405 lua_pushboolean(L, pilot_ewScanCheck( p ) );
1406 return 1;
1407}
1408
1416static int pilotL_withPlayer( lua_State *L )
1417{
1418 Pilot *p = luaL_validpilot(L,1);
1419 lua_pushboolean(L, pilot_isWithPlayer(p));
1420 return 1;
1421}
1422
1435static int pilotL_nav( lua_State *L )
1436{
1437 LuaSystem ls;
1438 Pilot *p;
1439
1440 /* Get pilot. */
1441 p = luaL_validpilot(L,1);
1442 if (p->target == 0)
1443 return 0;
1444
1445 /* Get spob target. */
1446 if (p->nav_spob < 0)
1447 lua_pushnil(L);
1448 else
1449 lua_pushspob( L, cur_system->spobs[ p->nav_spob ]->id );
1450
1451 /* Get hyperspace target. */
1452 if (p->nav_hyperspace < 0)
1453 lua_pushnil(L);
1454 else {
1455 ls = cur_system->jumps[ p->nav_hyperspace ].targetid;
1456 lua_pushsystem( L, ls );
1457 }
1458
1459 return 2;
1460}
1461
1472static int pilotL_activeWeapset( lua_State *L )
1473{
1474 Pilot *p = luaL_validpilot(L,1);
1475 lua_pushnumber( L, p->active_set + 1 );
1476 return 1;
1477}
1478
1520static int pilotL_weapset( lua_State *L )
1521{
1522 Pilot *p, *target;
1523 int k, n;
1524 PilotWeaponSetOutfit *po_list;
1525 PilotOutfitSlot *slot;
1526 const Outfit *o;
1527 double delay, firemod, enermod, t;
1528 int id, all, level;
1529 int is_lau, is_fb;
1530 const Damage *dmg;
1531 int has_beamid;
1532
1533 /* Parse parameters. */
1534 all = 0;
1535 p = luaL_validpilot(L,1);
1536 if (lua_gettop(L) > 1) {
1537 if (lua_isnumber(L,2))
1538 id = luaL_checkinteger(L,2) - 1;
1539 else if (lua_isboolean(L,2)) {
1540 all = lua_toboolean(L,2);
1541 id = p->active_set;
1542 }
1543 else
1544 NLUA_INVALID_PARAMETER(L);
1545 }
1546 else
1547 id = p->active_set;
1548 id = CLAMP( 0, PILOT_WEAPON_SETS, id );
1549
1550 /* Get target. */
1551 if (p->target != p->id)
1552 target = pilot_get( p->target );
1553 else
1554 target = NULL;
1555
1556 /* Push name. */
1557 lua_pushstring( L, pilot_weapSetName( p, id ) );
1558
1559 /* Push set. */
1560 po_list = all ? NULL : pilot_weapSetList( p, id );
1561 n = all ? array_size(p->outfits) : array_size(po_list);
1562
1563 k = 0;
1564 lua_newtable(L);
1565 for (int j=0; j<=PILOT_WEAPSET_MAX_LEVELS; j++) {
1566 /* Level to match. */
1567 int level_match = (j==PILOT_WEAPSET_MAX_LEVELS) ? -1 : j;
1568
1569 /* Iterate over weapons. */
1570 for (int i=0; i<n; i++) {
1571 /* Get base look ups. */
1572 slot = all ? p->outfits[i] : p->outfits[ po_list[i].slotid ];
1573 o = slot->outfit;
1574 if (o == NULL)
1575 continue;
1576 is_lau = outfit_isLauncher(o);
1577 is_fb = outfit_isFighterBay(o);
1578
1579 /* Must be valid weapon. */
1580 if (all && !(outfit_isBolt(o) || outfit_isBeam(o)
1581 || is_lau || is_fb))
1582 continue;
1583
1584 level = slot->level;
1585
1586 /* Must match level. */
1587 if (level != level_match)
1588 continue;
1589
1590 /* Must be weapon. */
1591 if (outfit_isMod(o) ||
1593 continue;
1594
1595 /* Set up for creation. */
1596 lua_pushnumber(L,++k);
1597 lua_newtable(L);
1598
1599 /* Name. */
1600 lua_pushstring(L,"name");
1601 lua_pushstring(L,slot->outfit->name);
1602 lua_rawset(L,-3);
1603
1604 /* Beams require special handling. */
1605 if (outfit_isBeam(o)) {
1606 pilot_getRateMod( &firemod, &enermod, p, slot->outfit );
1607
1608 /* When firing, cooldown is always zero. When recharging,
1609 * it's the usual 0-1 readiness value.
1610 */
1611 lua_pushstring(L,"cooldown");
1612 has_beamid = (slot->u.beamid > 0);
1613 if (has_beamid)
1614 lua_pushnumber(L, 0.);
1615 else {
1616 delay = (slot->timer / outfit_delay(o)) * firemod;
1617 lua_pushnumber( L, CLAMP( 0., 1., 1. -delay ) );
1618 }
1619 lua_rawset(L,-3);
1620
1621 /* When firing, slot->timer represents the remaining duration. */
1622 lua_pushstring(L,"charge");
1623 if (has_beamid)
1624 lua_pushnumber(L, CLAMP( 0., 1., slot->timer / o->u.bem.duration ) );
1625 else
1626 lua_pushnumber( L, CLAMP( 0., 1., 1. -delay ) );
1627 lua_rawset(L,-3);
1628 }
1629 else {
1630 /* Set cooldown. */
1631 lua_pushstring(L,"cooldown");
1632 pilot_getRateMod( &firemod, &enermod, p, slot->outfit );
1633 delay = outfit_delay(slot->outfit) * firemod;
1634 if (delay > 0.)
1635 lua_pushnumber( L, CLAMP( 0., 1., 1. - slot->timer / delay ) );
1636 else
1637 lua_pushnumber( L, 1. );
1638 lua_rawset(L,-3);
1639 }
1640
1641 /* Ammo quantity absolute. */
1642 if (is_lau || is_fb) {
1643 lua_pushstring(L,"left");
1644 lua_pushnumber( L, slot->u.ammo.quantity );
1645 lua_rawset(L,-3);
1646
1647 /* Ammo quantity relative. */
1648 lua_pushstring(L,"left_p");
1649 lua_pushnumber( L, (double)slot->u.ammo.quantity / (double)pilot_maxAmmoO(p,slot->outfit) );
1650 lua_rawset(L,-3);
1651 }
1652
1653 /* Launcher lockon. */
1654 if (is_lau) {
1655 t = slot->u.ammo.lockon_timer;
1656 lua_pushstring(L, "lockon");
1657 if (t <= 0.)
1658 lua_pushnumber(L, 1.);
1659 else
1660 lua_pushnumber(L, 1. - (t / slot->outfit->u.lau.lockon));
1661 lua_rawset(L,-3);
1662
1663 /* Is in arc. */
1664 lua_pushstring(L, "in_arc");
1665 lua_pushboolean(L, slot->u.ammo.in_arc);
1666 lua_rawset(L,-3);
1667 }
1668
1669 /* Level. */
1670 lua_pushstring(L,"level");
1671 lua_pushnumber(L, level+1);
1672 lua_rawset(L,-3);
1673
1674 /* Temperature. */
1675 lua_pushstring(L,"temp");
1676 lua_pushnumber(L, pilot_heatFirePercent(slot->heat_T));
1677 lua_rawset(L,-3);
1678
1679 /* Type. */
1680 lua_pushstring(L, "type");
1681 lua_pushstring(L, outfit_getType(slot->outfit));
1682 lua_rawset(L,-3);
1683
1684 /* Damage type. */
1685 dmg = outfit_damage( slot->outfit );
1686 if (dmg != NULL) {
1687 lua_pushstring(L, "dtype");
1688 lua_pushstring(L, dtype_damageTypeToStr( dmg->type ) );
1689 lua_rawset(L,-3);
1690 }
1691
1692 /* Track. */
1693 if (slot->outfit->type == OUTFIT_TYPE_TURRET_BOLT) {
1694 lua_pushstring(L, "track");
1695 if (target != NULL)
1696 lua_pushnumber(L, pilot_ewWeaponTrack( p, target, slot->outfit->u.blt.trackmin, slot->outfit->u.blt.trackmax ));
1697 else
1698 lua_pushnumber(L, -1);
1699 lua_rawset(L,-3);
1700 }
1701
1702 /* Set table in table. */
1703 lua_rawset(L,-3);
1704 }
1705 }
1706 return 2;
1707}
1708
1730static int pilotL_weapsetHeat( lua_State *L )
1731{
1732 Pilot *p;
1733 PilotWeaponSetOutfit *po_list;
1734 int n, id, all;
1735 double heat, heat_mean, heat_peak, nweapons;
1736
1737 /* Defaults. */
1738 heat_mean = 0.;
1739 heat_peak = 0.;
1740 nweapons = 0;
1741
1742 /* Parse parameters. */
1743 all = 0;
1744 p = luaL_validpilot(L,1);
1745 if (lua_gettop(L) > 1) {
1746 if (lua_isnumber(L,2))
1747 id = luaL_checkinteger(L,2) - 1;
1748 else if (lua_isboolean(L,2)) {
1749 all = lua_toboolean(L,2);
1750 id = p->active_set;
1751 }
1752 else
1753 NLUA_INVALID_PARAMETER(L);
1754 }
1755 else
1756 id = p->active_set;
1757 id = CLAMP( 0, PILOT_WEAPON_SETS, id );
1758
1759 /* Push set. */
1760 po_list = all ? NULL : pilot_weapSetList( p, id );
1761 n = all ? array_size(p->outfits) : array_size(po_list);
1762
1763 for (int j=0; j<=PILOT_WEAPSET_MAX_LEVELS; j++) {
1764 /* Level to match. */
1765 int level_match = (j==PILOT_WEAPSET_MAX_LEVELS) ? -1 : j;
1766
1767 /* Iterate over weapons. */
1768 for (int i=0; i<n; i++) {
1769 int level;
1770 /* Get base look ups. */
1771 PilotOutfitSlot *slot = all ? p->outfits[i] : p->outfits[ po_list[i].slotid ];
1772 const Outfit *o = slot->outfit;
1773 if (o == NULL)
1774 continue;
1775
1776 level = all ? slot->level : po_list[i].level;
1777
1778 /* Must match level. */
1779 if (level != level_match)
1780 continue;
1781
1782 /* Must be weapon. */
1783 if (outfit_isMod(o) ||
1785 continue;
1786
1787 nweapons++;
1788 heat = pilot_heatFirePercent(slot->heat_T);
1789 heat_mean += heat;
1790 if (heat > heat_peak)
1791 heat_peak = heat;
1792 }
1793 }
1794
1795 /* Post-process. */
1796 if (nweapons > 0)
1797 heat_mean /= nweapons;
1798
1799 lua_pushnumber( L, heat_mean );
1800 lua_pushnumber( L, heat_peak );
1801
1802 return 2;
1803}
1804
1836static int pilotL_actives( lua_State *L )
1837{
1838 Pilot *p;
1839 int k, sort;
1840 PilotOutfitSlot **outfits;
1841 const char *str;
1842 double d;
1843
1844 /* Parse parameters. */
1845 p = luaL_validpilot(L,1);
1846 sort = lua_toboolean(L,2);
1847
1848 k = 0;
1849 lua_newtable(L);
1850
1851 if (sort) {
1852 outfits = array_copy( PilotOutfitSlot*, p->outfits );
1853 qsort( outfits, array_size(outfits), sizeof(PilotOutfitSlot*), outfit_compareActive );
1854 }
1855 else
1856 outfits = p->outfits;
1857
1858 for (int i=0; i<array_size(outfits); i++) {
1859 /* Get active outfits. */
1860 PilotOutfitSlot *o = outfits[i];
1861 if (o->outfit == NULL)
1862 continue;
1863 if (!o->active)
1864 continue;
1865 if (!outfit_isMod(o->outfit) &&
1867 continue;
1868
1869 /* Set up for creation. */
1870 lua_pushnumber(L,++k);
1871 lua_newtable(L);
1872
1873 /* Name. */
1874 lua_pushstring(L,"name");
1875 lua_pushstring(L,o->outfit->name);
1876 lua_rawset(L,-3);
1877
1878 /* Type. */
1879 lua_pushstring(L, "type");
1880 lua_pushstring(L, outfit_getType(o->outfit));
1881 lua_rawset(L,-3);
1882
1883 /* Heat. */
1884 lua_pushstring(L, "temp");
1885 lua_pushnumber(L, 1 - pilot_heatEfficiencyMod(o->heat_T,
1886 o->outfit->u.afb.heat_base,
1887 o->outfit->u.afb.heat_cap));
1888 lua_rawset(L,-3);
1889
1890 /* Find the first weapon set containing the outfit, if any. */
1891 if (outfits[i]->weapset != -1) {
1892 lua_pushstring(L, "weapset");
1893 lua_pushnumber(L, outfits[i]->weapset + 1);
1894 lua_rawset(L, -3);
1895 }
1896
1897 /* State and timer. */
1898 switch (o->state) {
1899 case PILOT_OUTFIT_OFF:
1900 str = "off";
1901 break;
1902 case PILOT_OUTFIT_WARMUP:
1903 str = "warmup";
1904 if (!outfit_isMod(o->outfit) || o->outfit->lua_env == LUA_NOREF)
1905 d = 1.; /* TODO add warmup stuff to normal active outfits (not sure if necessary though. */
1906 else
1907 d = o->progress;
1908 lua_pushstring(L,"warmup");
1909 lua_pushnumber(L, d );
1910 lua_rawset(L,-3);
1911 break;
1912 case PILOT_OUTFIT_ON:
1913 str = "on";
1914 if (!outfit_isMod(o->outfit) || o->outfit->lua_env == LUA_NOREF) {
1915 d = outfit_duration(o->outfit);
1916 if (d==0.)
1917 d = 1.;
1918 else if (!isinf(o->stimer))
1919 d = o->stimer / d;
1920 }
1921 else
1922 d = o->progress;
1923 lua_pushstring(L,"duration");
1924 lua_pushnumber(L, d );
1925 lua_rawset(L,-3);
1926 break;
1927 case PILOT_OUTFIT_COOLDOWN:
1928 str = "cooldown";
1929 if (!outfit_isMod(o->outfit) || o->outfit->lua_env == LUA_NOREF) {
1930 d = outfit_cooldown(o->outfit);
1931 if (d==0.)
1932 d = 0.;
1933 else if (!isinf(o->stimer))
1934 d = o->stimer / d;
1935 }
1936 else
1937 d = o->progress;
1938 lua_pushstring(L,"cooldown");
1939 lua_pushnumber(L, d );
1940 lua_rawset(L,-3);
1941 break;
1942 default:
1943 str = "unknown";
1944 break;
1945 }
1946 lua_pushstring(L,"state");
1947 lua_pushstring(L,str);
1948 lua_rawset(L,-3);
1949
1950 /* Set table in table. */
1951 lua_rawset(L,-3);
1952 }
1953
1954 /* Clean up. */
1955 if (sort)
1956 array_free(outfits);
1957
1958 return 1;
1959}
1960
1964static int outfit_compareActive( const void *slot1, const void *slot2 )
1965{
1966 const PilotOutfitSlot *s1, *s2;
1967
1968 s1 = *(const PilotOutfitSlot**) slot1;
1969 s2 = *(const PilotOutfitSlot**) slot2;
1970
1971 /* Compare weapon set indexes. */
1972 if (s1->weapset < s2->weapset)
1973 return +1;
1974 else if (s1->weapset > s2->weapset)
1975 return -1;
1976
1977 /* Compare positions within the outfit array. */
1978 if (s1->id < s2->id)
1979 return +1;
1980 else if (s1->id > s2->id)
1981 return -1;
1982
1983 return 0;
1984}
1985
1995static int pilotL_outfitsList( lua_State *L )
1996{
1997 int normal = 1;
1998 int intrinsics = 0;
1999 Pilot *p = luaL_validpilot(L,1);
2000 const char *type = luaL_optstring(L,2,NULL);
2001 int skip_locked = lua_toboolean(L,3);
2002 OutfitSlotType ost = OUTFIT_SLOT_NULL;
2003
2004 /* Get type. */
2005 if (type != NULL) {
2006 if (strcmp(type,"all")==0)
2007 intrinsics = 1;
2008 else if (strcmp(type,"structure")==0)
2009 ost = OUTFIT_SLOT_STRUCTURE;
2010 else if (strcmp(type,"utility")==0)
2011 ost = OUTFIT_SLOT_UTILITY;
2012 else if (strcmp(type,"weapon")==0)
2013 ost = OUTFIT_SLOT_WEAPON;
2014 else if (strcmp(type,"intrinsic")==0) {
2015 intrinsics = 1;
2016 normal = 0;
2017 }
2018 else
2019 NLUA_ERROR(L,_("Unknown slot type '%s'"), type);
2020 }
2021
2022 lua_newtable( L );
2023 if (normal) {
2024 int j = 1;
2025 for (int i=0; i<array_size(p->outfits); i++) {
2026 /* Get outfit. */
2027 if (p->outfits[i]->outfit == NULL)
2028 continue;
2029
2030 /* Only match specific type. */
2031 if ((ost!=OUTFIT_SLOT_NULL) && (p->outfits[i]->outfit->slot.type!=ost))
2032 continue;
2033
2034 /* Skip locked. */
2035 if (skip_locked && p->outfits[i]->sslot->locked)
2036 continue;
2037
2038 /* Set the outfit. */
2039 lua_pushoutfit( L, p->outfits[i]->outfit );
2040 lua_rawseti( L, -2, j++ );
2041 }
2042 }
2043 if (intrinsics) {
2044 for (int i=0; i<array_size(p->outfit_intrinsic); i++) {
2045 lua_pushoutfit( L, p->outfit_intrinsic[i].outfit );
2046 lua_rawseti( L, -2, i+1 );
2047 }
2048 }
2049
2050 return 1;
2051}
2052
2060static int pilotL_outfits( lua_State *L )
2061{
2062 Pilot *p = luaL_validpilot(L,1);
2063 lua_newtable( L );
2064 for (int i=0; i<array_size(p->outfits); i++) {
2065 if (p->outfits[i]->outfit == NULL)
2066 lua_pushboolean( L, 0 );
2067 else
2068 lua_pushoutfit( L, p->outfits[i]->outfit );
2069 lua_rawseti( L, -2, i+1 );
2070 }
2071 return 1;
2072}
2073
2082static int pilotL_outfitGet( lua_State *L )
2083{
2084 /* Parse parameters */
2085 Pilot *p = luaL_validpilot(L,1);
2086 int id = luaL_checkinteger(L,2)-1;
2087 if (id < 0 || id >= array_size(p->outfits))
2088 NLUA_ERROR(L, _("Pilot '%s' outfit ID '%d' is out of range!"), p->name, id);
2089
2090 if (p->outfits[id]->outfit != NULL)
2091 lua_pushoutfit( L, p->outfits[id]->outfit );
2092 else
2093 lua_pushnil( L );
2094 return 1;
2095}
2096
2105static int pilotL_outfitToggle( lua_State *L )
2106{
2107 int isstealth, n = 0;
2108 Pilot *p = luaL_validpilot(L,1);
2109 int id = luaL_checkinteger(L,2)-1;
2110 int activate = lua_toboolean(L,3);
2111 if (id < 0 || id >= array_size(p->outfits))
2112 NLUA_ERROR(L, _("Pilot '%s' outfit ID '%d' is out of range!"), p->name, id);
2113 PilotOutfitSlot *po = p->outfits[id];
2114 const Outfit *o = po->outfit;
2115
2116 /* Ignore NULL outfits. */
2117 if (o == NULL)
2118 return 0;
2119
2120 /* Can't do a thing. */
2121 if ((pilot_isDisabled(p)) || (pilot_isFlag(p, PILOT_COOLDOWN)))
2122 return 0;
2123
2124 if ((activate && (po->state != PILOT_OUTFIT_OFF)) ||
2125 (!activate && (po->state != PILOT_OUTFIT_ON)))
2126 return 0;
2127
2128 if (activate)
2129 n = pilot_outfitOn( p, po );
2130 else
2131 n = pilot_outfitOff( p, po );
2132
2133 isstealth = pilot_isFlag( p, PILOT_STEALTH );
2134 if (n>0 && isstealth)
2135 pilot_destealth( p ); /* pilot_destealth should run calcStats already. */
2136 else if (n>0 || pilotoutfit_modified)
2137 pilot_calcStats( p );
2138
2139 lua_pushboolean(L,n);
2140 return 1;
2141}
2142
2151static int pilotL_outfitReady( lua_State *L )
2152{
2153 /* Parse parameters */
2154 Pilot *p = luaL_validpilot(L,1);
2155 int id = luaL_checkinteger(L,2)-1;
2156 if (id < 0 || id >= array_size(p->outfits))
2157 NLUA_ERROR(L, _("Pilot '%s' outfit ID '%d' is out of range!"), p->name, id);
2158
2159 if (p->outfits[id]->outfit != NULL)
2160 lua_pushboolean( L, p->outfits[id]->state==PILOT_OUTFIT_OFF );
2161 else
2162 lua_pushboolean( L, 0 );
2163 return 1;
2164}
2165
2175static int pilotL_rename( lua_State *L )
2176{
2177 /* Parse parameters */
2178 Pilot *p = luaL_validpilot(L,1);
2179 const char *name = luaL_checkstring(L,2);
2180
2181 /* Change name. */
2182 free(p->name);
2183 p->name = strdup(name);
2184
2185 return 0;
2186}
2187
2197static int pilotL_position( lua_State *L )
2198{
2199 Pilot *p = luaL_validpilot(L,1);
2200 lua_pushvector(L, p->solid->pos);
2201 return 1;
2202}
2203
2213static int pilotL_velocity( lua_State *L )
2214{
2215 Pilot *p = luaL_validpilot(L,1);
2216 lua_pushvector(L, p->solid->vel);
2217 return 1;
2218}
2219
2229static int pilotL_isStopped( lua_State *L )
2230{
2231 Pilot *p = luaL_validpilot(L,1);
2232 lua_pushboolean(L,(VMOD(p->solid->vel) < MIN_VEL_ERR));
2233 return 1;
2234}
2235
2245static int pilotL_evasion( lua_State *L )
2246{
2247 Pilot *p = luaL_validpilot(L,1);
2248 lua_pushnumber( L, p->ew_evasion );
2249 return 1;
2250}
2251
2261static int pilotL_dir( lua_State *L )
2262{
2263 Pilot *p = luaL_validpilot(L,1);
2264 lua_pushnumber( L, p->solid->dir );
2265 return 1;
2266}
2267
2277static int pilotL_temp( lua_State *L )
2278{
2279 Pilot *p = luaL_validpilot(L,1);
2280 lua_pushnumber( L, p->heat_T );
2281 return 1;
2282}
2283
2293static int pilotL_mass( lua_State *L )
2294{
2295 Pilot *p = luaL_validpilot(L,1);
2296 lua_pushnumber( L, p->solid->mass );
2297 return 1;
2298}
2299
2309static int pilotL_faction( lua_State *L )
2310{
2311 Pilot *p = luaL_validpilot(L,1);
2312 lua_pushfaction(L,p->faction);
2313 return 1;
2314}
2315
2328static int pilotL_spaceworthy( lua_State *L )
2329{
2330 char message[STRMAX_SHORT];
2331 Pilot *p = luaL_validpilot(L,1);
2332 int worthy = !pilot_reportSpaceworthy( p, message, sizeof(message) );
2333 lua_pushboolean( L, worthy );
2334 lua_pushstring( L, message );
2335 return 2;
2336}
2337
2347static int pilotL_setPosition( lua_State *L )
2348{
2349 /* Parse parameters */
2350 Pilot *p = luaL_validpilot(L,1);
2351 vec2 *vec = luaL_checkvector(L,2);
2352
2353 /* Insert skip in trail. */
2354 pilot_sample_trails( p, 1 );
2355
2356 /* Warp pilot to new position. */
2357 p->solid->pos = *vec;
2358
2359 /* Update if necessary. */
2360 if (pilot_isPlayer(p))
2361 cam_update( 0. );
2362
2363 return 0;
2364}
2365
2375static int pilotL_setVelocity( lua_State *L )
2376{
2377 /* Parse parameters */
2378 Pilot *p = luaL_validpilot(L,1);
2379 vec2 *vec = luaL_checkvector(L,2);
2380
2381 /* Warp pilot to new position. */
2382 p->solid->vel = *vec;
2383 return 0;
2384}
2385
2397static int pilotL_setDir( lua_State *L )
2398{
2399 /* Parse parameters */
2400 Pilot *p = luaL_validpilot(L,1);
2401 double d = luaL_checknumber(L,2);
2402
2403 /* Set direction. */
2404 p->solid->dir = fmodf( d, 2*M_PI );
2405 if (p->solid->dir < 0.)
2406 p->solid->dir += 2*M_PI;
2407
2408 return 0;
2409}
2410
2423static int pilotL_broadcast( lua_State *L )
2424{
2425 /* Parse parameters. */
2426 if (lua_isstring(L,1)) {
2427 const char *s = luaL_checkstring(L,1);
2428 const char *msg = luaL_checkstring(L,2);
2429 const char *col = luaL_optstring(L,3,NULL);
2430
2431 player_message( _("#%cBroadcast %s>#0 \"%s\""), ((col==NULL)?'N':col[0]), s, msg );
2432 if (player.p)
2433 pilot_setCommMsg( player.p, msg );
2434 }
2435 else {
2436 Pilot *p = luaL_validpilot(L,1);
2437 const char *msg = luaL_checkstring(L,2);
2438 int ignore_int = lua_toboolean(L,3);
2439
2440 /* Broadcast message. */
2441 pilot_broadcast( p, msg, ignore_int );
2442 }
2443
2444 return 0;
2445}
2446
2463static int pilotL_comm( lua_State *L )
2464{
2465 if (lua_isstring(L,1)) {
2466 const char *s;
2467 LuaPilot target;
2468 const char *msg, *col;
2469 int raw;
2470
2471 if (player.p==NULL)
2472 return 0;
2473
2474 /* Parse parameters. */
2475 s = luaL_checkstring(L,1);
2476 if (lua_isstring(L,2)) {
2477 msg = luaL_checkstring(L,2);
2478 col = luaL_optstring(L,3,NULL);
2479 raw = lua_toboolean(L,4);
2480 }
2481 else {
2482 target = luaL_checkpilot(L,2);
2483 if (target != player.p->id)
2484 return 0;
2485 msg = luaL_checkstring(L,3);
2486 col = luaL_optstring(L,4,NULL);
2487 raw = lua_toboolean(L,5);
2488 }
2489
2490 /* Broadcast message. */
2491 if (raw)
2492 player_message( _("#%c%s>#0 %s"), ((col==NULL)?'N':col[0]), s, msg );
2493 else
2494 player_message( _("#%cComm %s>#0 \"%s\""), ((col==NULL)?'N':col[0]), s, msg );
2495 if (player.p)
2496 pilot_setCommMsg( player.p, msg );
2497 }
2498 else {
2499 Pilot *p;
2500 LuaPilot target;
2501 const char *msg;
2502 int ignore_int, raw;
2503
2504 /* Parse parameters. */
2505 p = luaL_validpilot(L,1);
2506 if (lua_isstring(L,2)) {
2507 target = 0;
2508 msg = luaL_checkstring(L,2);
2509 ignore_int = lua_toboolean(L,3);
2510 raw = lua_toboolean(L,4);
2511 }
2512 else {
2513 target = luaL_checkpilot(L,2);
2514 msg = luaL_checkstring(L,3);
2515 ignore_int = lua_toboolean(L,4);
2516 raw = lua_toboolean(L,5);
2517 }
2518
2519 if (player.p==NULL)
2520 return 0;
2521
2522 if (!ignore_int && !pilot_inRangePilot( player.p, p, NULL ))
2523 return 0;
2524
2525 /* Broadcast message. */
2526 if (target == 0 || target == PLAYER_ID) {
2527 char c = pilot_getFactionColourChar( p );
2528 if (raw)
2529 player_message( _("#%c%s>#0 %s"), c, p->name, msg );
2530 else
2531 player_message( _("#%cComm %s>#0 \"%s\""), c, p->name, msg );
2532
2533 /* Set comm message. */
2534 pilot_setCommMsg( p, msg );
2535 }
2536 }
2537 return 0;
2538}
2539
2550static int pilotL_setFaction( lua_State *L )
2551{
2552 /* Parse parameters. */
2553 Pilot *p = luaL_validpilot(L,1);
2554 int fid = luaL_validfaction(L,2);
2555
2556 /* Set the new faction. */
2557 p->faction = fid;
2558
2559 return 0;
2560}
2561
2572static int pilotL_setHostile( lua_State *L )
2573{
2574 Pilot *p;
2575 int state;
2576
2577 /* Get the pilot. */
2578 p = luaL_validpilot(L,1);
2579
2580 /* Get state. */
2581 if (lua_isnone(L,2))
2582 state = 1;
2583 else
2584 state = lua_toboolean(L, 2);
2585
2586 /* Set as hostile. */
2587 if (state)
2589 else
2590 pilot_rmHostile(p);
2591
2592 return 0;
2593}
2594
2605static int pilotL_setFriendly( lua_State *L )
2606{
2607 Pilot *p;
2608 int state;
2609
2610 /* Get the pilot. */
2611 p = luaL_validpilot(L,1);
2612
2613 /* Get state. */
2614 if (lua_isnone(L,2))
2615 state = 1;
2616 else
2617 state = lua_toboolean(L, 2);
2618
2619 /* Remove hostile and mark as friendly. */
2620 if (state)
2622 /* Remove friendly flag. */
2623 else
2625
2626 return 0;
2627}
2628
2640static int pilotL_setInvincible( lua_State *L )
2641{
2642 return pilotL_setFlagWrapper( L, PILOT_INVINCIBLE );
2643}
2644
2656static int pilotL_setInvincPlayer( lua_State *L )
2657{
2658 return pilotL_setFlagWrapper( L, PILOT_INVINC_PLAYER );
2659}
2660
2675static int pilotL_setHide( lua_State *L )
2676{
2677 return pilotL_setFlagWrapper( L, PILOT_HIDE );
2678}
2679
2690static int pilotL_setInvisible( lua_State *L )
2691{
2692 return pilotL_setFlagWrapper( L, PILOT_INVISIBLE );
2693}
2694
2705static int pilotL_setNoRender( lua_State *L )
2706{
2707 return pilotL_setFlagWrapper( L, PILOT_NORENDER );
2708}
2709
2721static int pilotL_setVisplayer( lua_State *L )
2722{
2723 return pilotL_setFlagWrapper( L, PILOT_VISPLAYER );
2724}
2725
2737static int pilotL_setVisible( lua_State *L )
2738{
2739 return pilotL_setFlagWrapper( L, PILOT_VISIBLE );
2740}
2741
2753static int pilotL_setHilight( lua_State *L )
2754{
2755 return pilotL_setFlagWrapper( L, PILOT_HILIGHT );
2756}
2757
2767static int pilotL_setBribed( lua_State *L )
2768{
2769 return pilotL_setFlagWrapper( L, PILOT_BRIBED );
2770}
2771
2781static int pilotL_setActiveBoard( lua_State *L )
2782{
2783 return pilotL_setFlagWrapper( L, PILOT_BOARDABLE );
2784}
2785
2795static int pilotL_setNoDeath( lua_State *L )
2796{
2797 return pilotL_setFlagWrapper( L, PILOT_NODEATH );
2798}
2799
2809static int pilotL_disable( lua_State *L )
2810{
2811 /* Get the pilot. */
2812 Pilot *p = luaL_validpilot(L,1);
2813 int permanent = !lua_toboolean(L,2);
2814
2815 /* Disable the pilot. */
2816 p->shield = 0.;
2817 p->stress = p->armour;
2818 pilot_updateDisable(p, 0);
2819
2820 if (permanent)
2821 pilot_setFlag(p, PILOT_DISABLED_PERM);
2822 else
2823 pilot_rmFlag(p, PILOT_DISABLED_PERM);
2824
2825 return 0;
2826}
2827
2838static int pilotL_cooldown( lua_State *L )
2839{
2840 Pilot *p = luaL_validpilot(L,1);
2841 lua_pushboolean( L, pilot_isFlag(p, PILOT_COOLDOWN) );
2842 lua_pushboolean( L, pilot_isFlag(p, PILOT_COOLDOWN_BRAKE) );
2843 return 2;
2844}
2845
2855static int pilotL_setCooldown( lua_State *L )
2856{
2857 Pilot *p;
2858 int state;
2859
2860 /* Get the pilot. */
2861 p = luaL_validpilot(L,1);
2862
2863 /* Get state. */
2864 if (lua_isnone(L,2))
2865 state = 1;
2866 else
2867 state = lua_toboolean(L, 2);
2868
2869 /* Set status. */
2870 if (state)
2871 pilot_cooldown( p, 1 );
2872 else
2873 pilot_cooldownEnd(p, NULL);
2874
2875 return 0;
2876}
2877
2884static int pilotL_cooldownCycle( lua_State *L )
2885{
2886 Pilot *p = luaL_validpilot(L,1);
2887 pilot_cooldown( p, 0 );
2888 p->ctimer = -1.;
2889 pilot_rmFlag(p, PILOT_COOLDOWN_BRAKE); /* Should allow triggering. */
2890 pilot_cooldownEnd( p, NULL );
2891 return 0;
2892}
2893
2903static int pilotL_setNoJump( lua_State *L )
2904{
2905 return pilotL_setFlagWrapper( L, PILOT_NOJUMP );
2906}
2907
2917static int pilotL_setNoLand( lua_State *L )
2918{
2919 return pilotL_setFlagWrapper( L, PILOT_NOLAND );
2920}
2921
2931static int pilotL_setNoClear( lua_State *L )
2932{
2933 return pilotL_setFlagWrapper( L, PILOT_NOCLEAR );
2934}
2935
2939static int pilot_outfitAddSlot( Pilot *p, const Outfit *o, PilotOutfitSlot *s, int bypass_cpu, int bypass_slot)
2940{
2941 int ret;
2942
2943 /* Must not have outfit (excluding default) already. */
2944 if ((s->outfit != NULL) &&
2945 (s->outfit != s->sslot->data))
2946 return 0;
2947
2948 /* Only do a basic check. */
2949 if (bypass_slot) {
2950 if (!outfit_fitsSlotType( o, &s->sslot->slot ))
2951 return 0;
2952 }
2953 else if (bypass_cpu) {
2954 if (!outfit_fitsSlot( o, &s->sslot->slot ))
2955 return 0;
2956 }
2957 /* Full check. */
2958 else {
2959 /* Must fit slot. */
2960 if (!outfit_fitsSlot( o, &s->sslot->slot ))
2961 return 0;
2962
2963 /* Test if can add outfit. */
2964 ret = pilot_addOutfitTest( p, o, s, 0 );
2965 if (ret)
2966 return -1;
2967 }
2968
2969 /* Add outfit - already tested. */
2970 ret = pilot_addOutfitRaw( p, o, s );
2971 if (ret==0)
2972 pilot_outfitLInit( p, s );
2973
2974 /* Add ammo if needed. */
2975 if (ret==0)
2976 pilot_addAmmo( p, s, pilot_maxAmmoO(p,o) );
2977 return 1;
2978}
2979
2995static int pilotL_outfitAdd( lua_State *L )
2996{
2997 Pilot *p;
2998 const Outfit *o;
2999 int q, added, bypass_cpu, bypass_slot;
3000
3001 /* Get parameters. */
3002 p = luaL_validpilot(L,1);
3003 o = luaL_validoutfit(L,2);
3004 q = luaL_optinteger(L,3,1);
3005 bypass_cpu = lua_toboolean(L,4);
3006 bypass_slot = lua_toboolean(L,5);
3007
3008 /* Add outfit. */
3009 added = 0;
3010 for (int i=0; i<array_size(p->outfits); i++) {
3011 int ret;
3012 PilotOutfitSlot *s = p->outfits[i];
3013
3014 /* Must still have to add outfit. */
3015 if (q <= 0)
3016 break;
3017
3018 /* Do tests and try to add. */
3019 ret = pilot_outfitAddSlot( p, o, s, bypass_cpu, bypass_slot );
3020 if (ret < 0)
3021 break;
3022 else if (ret==0)
3023 continue;
3024
3025 /* We added an outfit. */
3026 q--;
3027 added++;
3028 }
3029
3030 /* Update stats. */
3031 if (added > 0)
3032 pilot_calcStats( p );
3033
3034 /* Update the weapon sets. */
3035 if ((added > 0) && p->autoweap)
3037
3038 /* Update equipment window if operating on the player's pilot. */
3039 if (player.p != NULL && player.p == p && added > 0)
3041
3042 lua_pushnumber(L,added);
3043 return 1;
3044}
3045
3054static int pilotL_outfitSlot( lua_State *L )
3055{
3056 Pilot *p = luaL_validpilot(L,1);
3057 const char *slotname = luaL_checkstring(L,2);
3058 PilotOutfitSlot *s = pilot_getSlotByName( p, slotname );
3059 if (s==NULL) {
3060 WARN(_("Pilot '%s' with ship '%s' does not have named slot '%s'!"), p->name, _(p->ship->name), slotname );
3061 return 0;
3062 }
3063 if (s->outfit) {
3064 lua_pushoutfit(L,s->outfit);
3065 return 1;
3066 }
3067 return 0;
3068}
3069
3081static int pilotL_outfitAddSlot( lua_State *L )
3082{
3083 Pilot *p;
3084 const Outfit *o;
3085 int ret, added, bypass_cpu, bypass_slot;
3086 const char *slotname;
3087
3088 /* Get parameters. */
3089 p = luaL_validpilot(L,1);
3090 o = luaL_validoutfit(L,2);
3091 slotname = luaL_checkstring(L,3);
3092 bypass_cpu = lua_toboolean(L,4);
3093 bypass_slot = lua_toboolean(L,5);
3094
3095 /* Case named slot. */
3096 PilotOutfitSlot *s = pilot_getSlotByName( p, slotname );
3097 if (s==NULL) {
3098 WARN(_("Pilot '%s' with ship '%s' does not have named slot '%s'!"), p->name, _(p->ship->name), slotname );
3099 return 0;
3100 }
3101 else {
3102 ret = pilot_outfitAddSlot( p, o, s, bypass_cpu, bypass_slot );
3103 added = (ret>0);
3104 }
3105
3106 /* Update stats. */
3107 if (added > 0)
3108 pilot_calcStats( p );
3109
3110 /* Update the weapon sets. */
3111 if ((added > 0) && p->autoweap)
3113
3114 /* Update equipment window if operating on the player's pilot. */
3115 if (player.p != NULL && player.p == p && added > 0)
3117
3118 lua_pushboolean(L,added);
3119 return 1;
3120}
3121
3139static int pilotL_outfitRm( lua_State *L )
3140{
3141 Pilot *p;
3142 int q, removed, matched = 0;
3143
3144 /* Get parameters. */
3145 removed = 0;
3146 p = luaL_validpilot(L,1);
3147 q = luaL_optinteger(L,3,1);
3148
3149 if (lua_isstring(L,2)) {
3150 const char *outfit = luaL_checkstring(L,2);
3151
3152 /* If outfit is "all", we remove everything except cores and locked outfits. */
3153 if (strcmp(outfit,"all")==0) {
3154 for (int i=0; i<array_size(p->outfits); i++) {
3155 if (p->outfits[i]->sslot->required)
3156 continue;
3157 if (p->outfits[i]->sslot->locked)
3158 continue;
3159 pilot_rmOutfitRaw( p, p->outfits[i] );
3160 removed++;
3161 }
3162 pilot_calcStats( p ); /* Recalculate stats. */
3163 matched = 1;
3164 }
3165 /* If outfit is "cores", we remove cores only. */
3166 else if (strcmp(outfit,"cores")==0) {
3167 for (int i=0; i<array_size(p->outfits); i++) {
3168 if (!p->outfits[i]->sslot->required)
3169 continue;
3170 pilot_rmOutfitRaw( p, p->outfits[i] );
3171 removed++;
3172 }
3173 pilot_calcStats( p ); /* Recalculate stats. */
3174 matched = 1;
3175 }
3176 /* Purpose fallthrough for if the outfit is passed as a string. */
3177 }
3178
3179 if (!matched) {
3180 const Outfit *o = luaL_validoutfit(L,2);
3181
3182 /* Remove the outfit outfit. */
3183 for (int i=0; i<array_size(p->outfits); i++) {
3184 /* Must still need to remove. */
3185 if (q <= 0)
3186 break;
3187
3188 /* Not found. */
3189 if (p->outfits[i]->outfit != o)
3190 continue;
3191
3192 /* Remove outfit. */
3193 pilot_rmOutfit( p, p->outfits[i] );
3194 q--;
3195 removed++;
3196 }
3197 }
3198
3199 /* Update equipment window if operating on the player's pilot. */
3200 if (player.p != NULL && player.p == p && removed > 0)
3202
3203 lua_pushnumber( L, removed );
3204 return 1;
3205}
3206
3218static int pilotL_outfitRmSlot( lua_State *L )
3219{
3220 /* Get parameters. */
3221 int ret, removed = 0;
3222 Pilot *p = luaL_validpilot(L,1);
3223 const char *slotname = luaL_checkstring(L,2);
3224 PilotOutfitSlot *s = pilot_getSlotByName( p, slotname );
3225 if (s==NULL) {
3226 WARN(_("Pilot '%s' with ship '%s' does not have named slot '%s'!"), p->name, _(p->ship->name), slotname );
3227 return 0;
3228 }
3229
3230 ret = !pilot_rmOutfitRaw( p, s );
3231 if (ret) {
3232 pilot_calcStats( p ); /* Recalculate stats. */
3233 /* Update equipment window if operating on the player's pilot. */
3234 if (player.p != NULL && player.p == p && removed > 0)
3236 }
3237
3238 lua_pushboolean( L, ret );
3239 return 1;
3240}
3241
3252static int pilotL_outfitAddIntrinsic( lua_State *L )
3253{
3254 Pilot *p = luaL_validpilot(L,1);
3255 const Outfit *o = luaL_validoutfit(L,2);
3256 int ret = pilot_addOutfitIntrinsic( p, o );
3257 if (ret==0)
3258 pilot_calcStats(p);
3259 lua_pushboolean(L,ret);
3260 return 1;
3261}
3262
3273static int pilotL_outfitRmIntrinsic( lua_State *L )
3274{
3275 Pilot *p = luaL_validpilot(L,1);
3276 const Outfit *o = luaL_validoutfit(L,2);
3277 for (int i=0; i<array_size(p->outfit_intrinsic); i++) {
3278 PilotOutfitSlot *s = &p->outfit_intrinsic[i];
3279 int ret;
3280 if (s->outfit != o)
3281 continue;
3282 ret = pilot_rmOutfitIntrinsic( p, s );
3283 if (ret==0)
3284 pilot_calcStats(p);
3285 lua_pushboolean(L,ret);
3286 return 1;
3287 }
3288 lua_pushboolean(L,0);
3289 return 1;
3290}
3291
3303static int pilotL_setFuel( lua_State *L )
3304{
3305 Pilot *p = luaL_validpilot(L,1);
3306
3307 /* Get the parameter. */
3308 if (lua_isboolean(L,2)) {
3309 if (lua_toboolean(L,2))
3310 p->fuel = p->fuel_max;
3311 else
3312 p->fuel = 0;
3313 }
3314 else if (lua_isnumber(L,2)) {
3315 p->fuel = CLAMP( 0, p->fuel_max, lua_tonumber(L,2) );
3316 }
3317 else
3318 NLUA_INVALID_PARAMETER(L);
3319
3320 /* Return amount of fuel. */
3321 lua_pushnumber(L, p->fuel);
3322 return 1;
3323}
3324
3330static int pilotL_intrinsicReset( lua_State *L )
3331{
3332 Pilot *p = luaL_validpilot(L,1);
3333 ss_statsInit( &p->intrinsic_stats );
3334 pilot_calcStats( p );
3335 return 0;
3336}
3337
3349static int pilotL_intrinsicSet( lua_State *L )
3350{
3351 Pilot *p = luaL_validpilot(L,1);
3352 const char *name;
3353 double value;
3354 int replace;
3355 /* Case individual parameter. */
3356 if (!lua_istable(L,2)) {
3357 name = luaL_checkstring(L,2);
3358 value = luaL_checknumber(L,3);
3359 replace = lua_toboolean(L,4);
3360 ss_statsSet( &p->intrinsic_stats, name, value, replace );
3361 pilot_calcStats( p );
3362 return 0;
3363 }
3364 replace = lua_toboolean(L,4);
3365 /* Case set of parameters. */
3366 lua_pushnil(L);
3367 while (lua_next(L,2) != 0) {
3368 name = luaL_checkstring(L,-2);
3369 value = luaL_checknumber(L,-1);
3370 ss_statsSet( &p->intrinsic_stats, name, value, replace );
3371 lua_pop(L,1);
3372 }
3373 lua_pop(L,1);
3374 pilot_calcStats( p );
3375 return 0;
3376}
3377
3387static int pilotL_intrinsicGet( lua_State *L )
3388{
3389 Pilot *p = luaL_validpilot(L,1);
3390 const char *name = luaL_optstring(L,2,NULL);
3391 int internal = lua_toboolean(L,3);
3392 ss_statsGetLua( L, &p->intrinsic_stats, name, internal );
3393 return 1;
3394}
3395
3402static int pilotL_effectClear( lua_State *L )
3403{
3404 Pilot *p = luaL_validpilot(L,1);
3405 effect_clear( &p->effects );
3406 pilot_calcStats( p );
3407 return 0;
3408}
3409
3420static int pilotL_effectAdd( lua_State *L )
3421{
3422 Pilot *p = luaL_validpilot(L,1);
3423 const char *effectname = luaL_checkstring(L,2);
3424 double duration = luaL_optnumber(L,3,-1.);
3425 double scale = luaL_optnumber(L,4,1.);
3426 const EffectData *efx = effect_get( effectname );
3427 if (efx != NULL) {
3428 if (!effect_add( &p->effects, efx, duration, scale, p->id ))
3429 pilot_calcStats( p );
3430 lua_pushboolean(L,1);
3431 }
3432 else
3433 lua_pushboolean(L,0);
3434 return 1;
3435}
3436
3445static int pilotL_effectRm( lua_State *L )
3446{
3447 Pilot *p = luaL_validpilot(L,1);
3448 const char *effectname = luaL_checkstring(L,2);
3449 int all = lua_toboolean(L,3);
3450 const EffectData *efx = effect_get( effectname );
3451 if (efx != NULL) {
3452 if (effect_rm( &p->effects, efx, all ))
3453 pilot_calcStats( p );
3454 }
3455 return 0;
3456}
3457
3465static int pilotL_effectGet( lua_State *L )
3466{
3467 Pilot *p = luaL_validpilot(L,1);
3468 lua_newtable(L);
3469 for (int i=0; i<array_size(p->effects); i++) {
3470 Effect *e = &p->effects[i];
3471 lua_newtable(L);
3472
3473 lua_pushstring(L,e->data->name);
3474 lua_setfield(L,-2,"name");
3475
3476 lua_pushnumber(L,e->timer);
3477 lua_setfield(L,-2,"timer");
3478
3479 lua_pushnumber(L,e->data->duration);
3480 lua_setfield(L,-2,"duration");
3481
3483 lua_setfield(L,-2,"icon");
3484
3485 lua_rawseti(L,-2,i+1);
3486 }
3487 return 1;
3488}
3489
3497static int pilotL_ai( lua_State *L )
3498{
3499 /* Get parameters. */
3500 Pilot *p = luaL_validpilot(L,1);
3501 if (p->ai == NULL)
3502 return 0;
3503 lua_pushstring( L, p->ai->name );
3504 return 1;
3505}
3506
3516static int pilotL_changeAI( lua_State *L )
3517{
3518 int ret;
3519 /* Get parameters. */
3520 Pilot *p = luaL_validpilot(L,1);
3521 const char *str = luaL_checkstring(L,2);
3522
3523 /* Get rid of current AI. */
3524 ai_destroy(p);
3525
3526 /* Create the new AI. */
3527 ret = ai_pinit( p, str );
3528 lua_pushboolean(L, ret);
3529 return 1;
3530}
3531
3546static int pilotL_setTemp( lua_State *L )
3547{
3548 Pilot *p;
3549 int setOutfits = 1;
3550 double kelvins;
3551
3552 /* Handle parameters. */
3553 p = luaL_validpilot(L,1);
3554 kelvins = luaL_checknumber(L, 2);
3555 setOutfits = !lua_toboolean(L,3);
3556
3557 /* Temperature must not go below base temp. */
3558 kelvins = MAX(kelvins, CONST_SPACE_STAR_TEMP);
3559
3560 /* Handle pilot ship. */
3561 p->heat_T = kelvins;
3562
3563 /* Handle pilot outfits (maybe). */
3564 if (setOutfits)
3565 for (int i=0; i < array_size(p->outfits); i++)
3566 p->outfits[i]->heat_T = kelvins;
3567
3568 return 0;
3569}
3570
3586static int pilotL_setHealth( lua_State *L )
3587{
3588 Pilot *p;
3589 double a, s, st;
3590
3591 /* Handle parameters. */
3592 p = luaL_validpilot(L,1);
3593 a = luaL_optnumber(L, 2, 100.*p->armour / p->armour_max);
3594 s = luaL_optnumber(L, 3, 100.*p->shield / p->shield_max);
3595 st = luaL_optnumber(L,4,0.);
3596
3597 a /= 100.;
3598 s /= 100.;
3599 st /= 100.;
3600
3601 /* Set health. */
3602 p->armour = a * p->armour_max;
3603 p->shield = s * p->shield_max;
3604 p->stress = st * p->armour;
3605
3606 /* Clear death hooks if not dead. */
3607 if (p->armour > 0.) {
3608 pilot_rmFlag( p, PILOT_DISABLED );
3609 pilot_rmFlag( p, PILOT_DEAD );
3610 pilot_rmFlag( p, PILOT_DEATH_SOUND );
3611 pilot_rmFlag( p, PILOT_EXPLODED );
3612 pilot_rmFlag( p, PILOT_DELETE );
3613 if (pilot_isPlayer(p))
3614 player_rmFlag( PLAYER_DESTROYED );
3615 }
3616 pilot_rmFlag( p, PILOT_DISABLED_PERM ); /* Remove permanent disable. */
3617
3618 /* Update disable status. */
3619 pilot_updateDisable(p, 0);
3620
3621 return 0;
3622}
3623
3634static int pilotL_addHealth( lua_State *L )
3635{
3636 Pilot *p;
3637 double a, s;
3638
3639 /* Handle parameters. */
3640 p = luaL_validpilot(L,1);
3641 a = luaL_optnumber(L, 2, 0.);
3642 s = luaL_optnumber(L, 3, 0.);
3643
3644 /* Set health. */
3645 p->armour = CLAMP( 0., p->armour_max, p->armour + a );
3646 p->shield = CLAMP( 0., p->shield_max, p->shield + s );
3647
3648 /* Update disable status. */
3649 pilot_updateDisable(p, 0);
3650
3651 return 0;
3652}
3653
3665static int pilotL_setEnergy( lua_State *L )
3666{
3667 /* Handle parameters. */
3668 Pilot *p = luaL_validpilot(L,1);
3669 double e = luaL_checknumber(L,2);
3670 int absolute = lua_toboolean(L,3);
3671
3672 if (absolute)
3673 p->energy = CLAMP( 0, p->energy_max, e );
3674 else
3675 p->energy = (e/100.) * p->energy_max;
3676
3677 return 0;
3678}
3679
3686static int pilotL_fillAmmo( lua_State *L )
3687{
3688 Pilot *p = luaL_validpilot(L,1);
3689 pilot_fillAmmo( p );
3690 return 0;
3691}
3692
3705static int pilotL_setNoboard( lua_State *L )
3706{
3707 Pilot *p;
3708 int disable;
3709
3710 /* Handle parameters. */
3711 p = luaL_validpilot(L,1);
3712 if (lua_isnone(L,2))
3713 disable = 1;
3714 else
3715 disable = lua_toboolean(L, 2);
3716
3717 /* See if should prevent boarding. */
3718 if (disable)
3719 pilot_setFlag(p, PILOT_NOBOARD);
3720 else
3721 pilot_rmFlag(p, PILOT_NOBOARD);
3722
3723 return 0;
3724}
3725
3738static int pilotL_setNoDisable( lua_State *L )
3739{
3740 Pilot *p;
3741 int disable;
3742
3743 /* Handle parameters. */
3744 p = luaL_validpilot(L,1);
3745 if (lua_isnone(L,2))
3746 disable = 1;
3747 else
3748 disable = lua_toboolean(L, 2);
3749
3750 /* See if should prevent disabling. */
3751 if (disable)
3752 pilot_setFlag(p, PILOT_NODISABLE);
3753 else
3754 pilot_rmFlag(p, PILOT_NODISABLE);
3755
3756 return 0;
3757}
3758
3771static int pilotL_setSpeedLimit(lua_State* L)
3772{
3773 /* Handle parameters. */
3774 Pilot *p = luaL_validpilot(L,1);
3775 double s = luaL_checknumber(L, 2);
3776
3777 /* Limit the speed */
3778 p->speed_limit = s;
3779 if (s > 0.)
3780 pilot_setFlag( p, PILOT_HASSPEEDLIMIT );
3781 else
3782 pilot_rmFlag( p, PILOT_HASSPEEDLIMIT );
3783
3785 return 0;
3786}
3787
3801static int pilotL_getHealth( lua_State *L )
3802{
3803 Pilot *p = luaL_validpilot(L,1);
3804 int absolute = lua_toboolean(L,2);
3805
3806 /* Return parameters. */
3807 if (absolute) {
3808 lua_pushnumber(L, p->armour );
3809 lua_pushnumber(L, p->shield );
3810 }
3811 else {
3812 lua_pushnumber(L,(p->armour_max > 0.) ? p->armour / p->armour_max * 100. : 0. );
3813 lua_pushnumber(L,(p->shield_max > 0.) ? p->shield / p->shield_max * 100. : 0. );
3814 }
3815 lua_pushnumber(L, MIN( 1., p->stress / p->armour ) * 100. );
3816 lua_pushboolean(L, pilot_isDisabled(p));
3817
3818 return 4;
3819}
3820
3831static int pilotL_getEnergy( lua_State *L )
3832{
3833 Pilot *p = luaL_validpilot(L,1);
3834 int absolute = lua_toboolean(L,2);
3835
3836 if (absolute)
3837 lua_pushnumber(L, p->energy );
3838 else
3839 lua_pushnumber(L, (p->energy_max > 0.) ? p->energy / p->energy_max * 100. : 0. );
3840
3841 return 1;
3842}
3843
3853static int pilotL_getLockon( lua_State *L )
3854{
3855 Pilot *p = luaL_validpilot(L,1);
3856 lua_pushnumber(L, p->lockons );
3857 return 1;
3858}
3859
3860#define PUSH_DOUBLE( L, name, value ) \
3861lua_pushstring( L, name ); \
3862lua_pushnumber( L, value ); \
3863lua_rawset( L, -3 )
3864#define PUSH_INT( L, name, value ) \
3865lua_pushstring( L, name ); \
3866lua_pushinteger( L, value ); \
3867lua_rawset( L, -3 )
3901static int pilotL_getStats( lua_State *L )
3902{
3903 Pilot *p = luaL_validpilot(L,1);
3904
3905 /* Create table with information. */
3906 lua_newtable(L);
3907 /* Core. */
3908 PUSH_DOUBLE( L, "cpu", p->cpu );
3909 PUSH_INT( L, "cpu_max", p->cpu_max );
3910 PUSH_INT( L, "crew", (int)round( p->crew ) );
3911 PUSH_INT( L, "fuel", p->fuel );
3912 PUSH_INT( L, "fuel_max", p->fuel_max );
3913 PUSH_INT( L, "fuel_consumption", p->fuel_consumption );
3914 PUSH_DOUBLE( L, "mass", p->solid->mass );
3915 /* Movement. */
3916 PUSH_DOUBLE( L, "thrust", p->thrust / p->solid->mass );
3917 PUSH_DOUBLE( L, "speed", p->speed );
3918 PUSH_DOUBLE( L, "turn", p->turn * 180. / M_PI ); /* Convert back to grad. */
3919 PUSH_DOUBLE( L, "speed_max", solid_maxspeed(p->solid, p->speed, p->thrust) );
3920 /* Health. */
3921 PUSH_DOUBLE( L, "absorb", p->dmg_absorb );
3922 PUSH_DOUBLE( L, "armour", p->armour_max );
3923 PUSH_DOUBLE( L, "shield", p->shield_max );
3924 PUSH_DOUBLE( L, "energy", p->energy_max );
3925 PUSH_DOUBLE( L, "armour_regen", p->armour_regen );
3926 PUSH_DOUBLE( L, "shield_regen", p->shield_regen );
3927 PUSH_DOUBLE( L, "energy_regen", p->energy_regen );
3928 /* Stats. */
3929 PUSH_DOUBLE( L, "ew_detection", p->ew_detection );
3930 PUSH_DOUBLE( L, "ew_evasion", p->ew_evasion );
3931 PUSH_DOUBLE( L, "ew_stealth", p->ew_stealth );
3932 PUSH_DOUBLE( L, "jump_delay", ntime_convertSeconds( pilot_hyperspaceDelay(p) ) );
3933 PUSH_INT( L, "jumps", pilot_getJumps(p) );
3934
3935 return 1;
3936}
3937#undef PUSH_DOUBLE
3938#undef PUSH_INT
3939
3949static int pilotL_getShipStat( lua_State *L )
3950{
3951 Pilot *p = luaL_validpilot(L,1);
3952 const char *str = luaL_optstring(L,2,NULL);
3953 int internal = lua_toboolean(L,3);
3954 ss_statsGetLua( L, &p->stats, str, internal );
3955 return 1;
3956}
3957
3964static int pilotL_getDetectedDistance( lua_State *L )
3965{
3966 Pilot *p = luaL_validpilot(L,1);
3967 if (pilot_isFlag(p,PILOT_STEALTH))
3968 lua_pushnumber( L, p->ew_stealth );
3969 else
3970 lua_pushnumber( L, p->ew_detection );
3971 return 1;
3972}
3973
3981static int pilotL_cargoFree( lua_State *L )
3982{
3983 Pilot *p = luaL_validpilot(L,1);
3984 lua_pushnumber(L, pilot_cargoFree(p) );
3985 return 1;
3986}
3987
3998static int pilotL_cargoHas( lua_State *L )
3999{
4000 Pilot *p = luaL_validpilot(L, 1);
4001 const Commodity *cargo = luaL_validcommodity(L, 2);
4002 int quantity = pilot_cargoOwned(p, cargo);
4003 lua_pushnumber(L, quantity);
4004 return 1;
4005}
4006
4020static int pilotL_cargoAdd( lua_State *L )
4021{
4022 /* Parse parameters. */
4023 Pilot *p = luaL_validpilot(L, 1);
4024 const Commodity *cargo = luaL_validcommodity(L, 2);
4025 int quantity = luaL_checknumber(L, 3);
4026
4027 if (quantity < 0) {
4028 NLUA_ERROR( L, _("Quantity must be positive for pilot.cargoAdd (if removing, use pilot.cargoRm)") );
4029 return 0;
4030 }
4031
4032 /* Try to add the cargo. */
4033 quantity = pilot_cargoAdd( p, cargo, quantity, 0 );
4034 lua_pushnumber( L, quantity );
4035 return 1;
4036}
4037
4038static int pilotL_cargoRmHelper( lua_State *L, int jet )
4039{
4040 Pilot *p;
4041 int quantity;
4042 Commodity *cargo = NULL;
4043
4044 /* Parse parameters. */
4045 p = luaL_validpilot(L, 1);
4046
4047 if (lua_isstring(L, 2)) {
4048 const char *str = lua_tostring(L, 2);
4049
4050 /* Check for special strings. */
4051 if (strcmp(str, "all") == 0) {
4052 quantity = pilot_cargoRmAll(p, 0);
4053 lua_pushnumber(L, quantity);
4054 return 1;
4055 }
4056 }
4057
4058 /* No special string handling, just handle as a normal commodity. */
4059 cargo = luaL_validcommodity(L, 2);
4060 quantity = luaL_checknumber(L, 3);
4061
4062 if (quantity < 0) {
4063 NLUA_ERROR(L,
4064 _("Quantity must be positive for pilot.cargoRm (if adding, use"
4065 " pilot.cargoAdd)"));
4066 return 0;
4067 }
4068
4069 /* Try to remove the cargo. */
4070 if (jet)
4071 quantity = pilot_cargoJet( p, cargo, quantity, 0 );
4072 else
4073 quantity = pilot_cargoRm( p, cargo, quantity );
4074
4075 lua_pushnumber(L, quantity);
4076 return 1;
4077}
4078
4094static int pilotL_cargoRm( lua_State *L )
4095{
4096 return pilotL_cargoRmHelper( L, 0 );
4097}
4098
4111static int pilotL_cargoJet( lua_State *L )
4112{
4113 return pilotL_cargoRmHelper( L, 1 );
4114}
4115
4133static int pilotL_cargoList( lua_State *L )
4134{
4135 Pilot *p = luaL_validpilot(L,1);
4136 lua_newtable(L); /* t */
4137 for (int i=0; i<array_size(p->commodities); i++) {
4138 PilotCommodity *pc = &p->commodities[i];
4139
4140 /* Represents the cargo. */
4141 lua_newtable(L); /* t, t */
4142
4143 lua_pushstring(L, "name"); /* t, t, i */
4144 lua_pushstring(L, pc->commodity->name); /* t, t, i, s */
4145 lua_rawset(L,-3); /* t, t */
4146
4147 lua_pushstring(L, "c"); /* t, t, i */
4148 lua_pushcommodity(L, (Commodity*)pc->commodity); /* t, t, i, s */
4149 lua_rawset(L,-3); /* t, t */
4150
4151 lua_pushstring(L, "q"); /* t, t, i */
4152 lua_pushnumber(L, pc->quantity); /* t, t, i, s */
4153 lua_rawset(L,-3); /* t, t */
4154
4155 lua_pushstring(L, "m"); /* t, t, i */
4156 lua_pushboolean(L, pc->id); /* t, t, i, s */
4157 lua_rawset(L,-3); /* t, t */
4158
4159 lua_rawseti(L,-2,i+1); /* t */
4160 }
4161 return 1;
4162
4163}
4164
4173static int pilotL_credits( lua_State *L )
4174{
4175 Pilot *p = luaL_validpilot(L,1);
4176 pilot_modCredits( p, luaL_optlong( L, 2, 0 ) );
4177 lua_pushnumber( L, p->credits );
4178 return 1;
4179}
4180
4190static int pilotL_getColour( lua_State *L )
4191{
4192 Pilot *p = luaL_validpilot(L,1);
4193 const glColour *col = pilot_getColour(p);
4194 lua_pushcolour( L, *col );
4195 return 1;
4196}
4197
4207static int pilotL_getHostile( lua_State *L )
4208{
4209 Pilot *p = luaL_validpilot(L,1);
4210 lua_pushboolean( L, pilot_isHostile( p ) );
4211 return 1;
4212}
4213
4217struct pL_flag {
4218 const char *name;
4219 int id;
4220};
4221static const struct pL_flag pL_flags[] = {
4222 { .name = "stealth", .id = PILOT_STEALTH },
4223 { .name = "refueling", .id = PILOT_REFUELING },
4224 { .name = "invisible", .id = PILOT_INVISIBLE },
4225 { .name = "disabled", .id = PILOT_DISABLED },
4226 { .name = "takingoff", .id = PILOT_TAKEOFF },
4227 { .name = "jumpingin", .id = PILOT_HYP_END },
4228 { .name = "jumpingout", .id = PILOT_HYPERSPACE },
4229 { .name = "manualcontrol", .id = PILOT_MANUAL_CONTROL },
4230 { .name = "carried", .id = PILOT_CARRIED },
4231 { .name = "hailing", .id = PILOT_HAILING },
4232 { .name = "bribed", .id = PILOT_BRIBED },
4233 { .name = "boardable", .id = PILOT_BOARDABLE },
4234 { .name = "nojump", .id = PILOT_NOJUMP },
4235 { .name = "noland", .id = PILOT_NOLAND },
4236 { .name = "nodeath", .id = PILOT_NODEATH },
4237 { .name = "nodisable", .id = PILOT_NODISABLE },
4238 { .name = "visible", .id = PILOT_VISIBLE },
4239 { .name = "visplayer", .id = PILOT_VISPLAYER },
4240 { .name = "hilight", .id = PILOT_HILIGHT },
4241 { .name = "norender", .id = PILOT_NORENDER },
4242 { .name = "hide", .id = PILOT_HIDE },
4243 { .name = "invincible", .id = PILOT_INVINCIBLE },
4244 { .name = "invinc_player", .id = PILOT_INVINC_PLAYER },
4245 { .name = "friendly", .id = PILOT_FRIENDLY },
4246 { .name = "hostile", .id = PILOT_HOSTILE },
4247 { .name = "combat", .id = PILOT_COMBAT },
4248 {NULL, -1}
4249};
4283static int pilotL_flags( lua_State *L )
4284{
4285 Pilot *p = luaL_validpilot(L,1);
4286 const char *name = luaL_optstring( L, 2, NULL );
4287
4288 if (name != NULL) {
4289 for (int i=0; pL_flags[i].name != NULL; i++)
4290 if (strcmp(pL_flags[i].name,name)==0) {
4291 lua_pushboolean( L, pilot_isFlag( p, pL_flags[i].id ) );
4292 return 1;
4293 }
4294#if DEBUGGING
4295 WARN(_("Tried to access unknown flag '%s' for pilot '%s'!"), name, p->name);
4296#endif /* DEBUGGING */
4297 return 0;
4298 }
4299
4300 /* Create flag table. */
4301 lua_newtable(L);
4302 for (int i=0; pL_flags[i].name != NULL; i++) {
4303 lua_pushboolean( L, pilot_isFlag( p, pL_flags[i].id ) );
4304 lua_setfield(L, -2, pL_flags[i].name);
4305 }
4306 return 1;
4307}
4308
4316static int pilotL_hasIllegal( lua_State *L )
4317{
4318 Pilot *p = luaL_validpilot(L,1);
4319 int f = luaL_validfaction(L,2);
4320 lua_pushboolean(L, pilot_hasIllegal(p,f));
4321 return 1;
4322}
4323
4333static int pilotL_ship( lua_State *L )
4334{
4335 Pilot *p = luaL_validpilot(L,1);
4336 lua_pushship(L, p->ship);
4337 return 1;
4338}
4339
4349static int pilotL_points( lua_State *L )
4350{
4351 Pilot *p = luaL_validpilot(L,1);
4352 lua_pushinteger(L, p->ship->points);
4353 return 1;
4354}
4355
4365static int pilotL_idle( lua_State *L )
4366{
4367 Pilot *p = luaL_validpilot(L,1);
4368 lua_pushboolean(L, p->task==0);
4369 return 1;
4370}
4371
4393static int pilotL_control( lua_State *L )
4394{
4395 Pilot *p;
4396 int enable, cleartasks;
4397
4398 /* Handle parameters. */
4399 p = luaL_validpilot(L,1);
4400 if (lua_isnone(L,2))
4401 enable = 1;
4402 else
4403 enable = lua_toboolean(L, 2);
4404 if (lua_isnone(L,3))
4405 cleartasks = enable ^ pilot_isFlag(p, PILOT_MANUAL_CONTROL);
4406 else
4407 cleartasks = lua_toboolean(L, 3);
4408
4409 if (enable) {
4410 int isp = pilot_isPlayer(p);
4411 if (isp)
4412 player_autonavAbort(NULL); /* Has to be run before setting the flag. */
4413 pilot_setFlag(p, PILOT_MANUAL_CONTROL);
4414 if (isp)
4415 ai_pinit( p, "player" );
4416 }
4417 else {
4418 pilot_rmFlag(p, PILOT_MANUAL_CONTROL);
4419 if (pilot_isPlayer(p))
4420 ai_destroy( p );
4421 /* Note, we do not set p->ai to NULL, we just clear the tasks and memory.
4422 * This is because the player always has an ai named "player", which is
4423 * used for manual control among other things. Basically a pilot always
4424 * has to have an AI even if it's the player for things to work. */
4425 }
4426
4427 /* Clear task if changing state. */
4428 if (cleartasks)
4429 pilotL_taskclear( L );
4430
4431 return 0;
4432}
4433
4445static int pilotL_memory( lua_State *L )
4446{
4447 /* Get the pilot. */
4448 Pilot *p = luaL_validpilot(L,1);
4449
4450 /* Set the pilot's memory. */
4451 if (p->ai == NULL) {
4452 NLUA_ERROR(L,_("Pilot '%s' does not have an AI!"),p->name);
4453 return 0;
4454 }
4455
4456 lua_rawgeti( L, LUA_REGISTRYINDEX, p->lua_mem );
4457 return 1;
4458}
4459
4467static int pilotL_ainame( lua_State *L )
4468{
4469 Pilot *p = luaL_validpilot(L,1);
4470 if (p->ai == NULL)
4471 return 0;
4472 lua_pushstring(L, p->ai->name);
4473 return 1;
4474}
4475
4484static int pilotL_task( lua_State *L )
4485{
4486 Pilot *p = luaL_validpilot(L,1);
4487 Task *t = ai_curTask(p);
4488 if (t) {
4489 lua_pushstring(L, t->name);
4490 if (t->dat != LUA_NOREF) {
4491 lua_rawgeti(L, LUA_REGISTRYINDEX, t->dat);
4492 return 2;
4493 }
4494 return 1;
4495 }
4496 return 0;
4497}
4498
4507static int pilotL_taskname( lua_State *L )
4508{
4509 Pilot *p = luaL_validpilot(L,1);
4510 Task *t = ai_curTask(p);
4511 if (t) {
4512 lua_pushstring(L, t->name);
4513 if (t->subtask != NULL) {
4514 lua_pushstring(L, t->subtask->name);
4515 return 2;
4516 }
4517 return 1;
4518 }
4519 return 0;
4520}
4521
4528static int pilotL_taskstack( lua_State *L )
4529{
4530 Pilot *p = luaL_validpilot(L,1);
4531 int n;
4532
4533 lua_newtable(L);
4534 n = 1;
4535 for (Task *t=p->task; t!=NULL; t=t->next) {
4536 if (t->done)
4537 continue;
4538 lua_pushstring(L,t->name);
4539 lua_rawseti(L,-2,n++);
4540 }
4541
4542 return 1;
4543}
4544
4552static int pilotL_taskdata( lua_State *L )
4553{
4554 Pilot *p = luaL_validpilot(L,1);
4555 Task *t = ai_curTask(p);
4556 if (t && (t->dat != LUA_NOREF)) {
4557 lua_rawgeti(L, LUA_REGISTRYINDEX, t->dat);
4558 return 1;
4559 }
4560 return 0;
4561}
4562
4571static int pilotL_taskclear( lua_State *L )
4572{
4573 Pilot *p = luaL_validpilot(L,1);
4574 ai_cleartasks( p );
4575 return 0;
4576}
4577
4588static int pilotL_pushtask( lua_State *L )
4589{
4590 Pilot *p = luaL_validpilot(L,1);
4591 const char *task = luaL_checkstring(L,2);
4592
4593 if (pilot_isPlayer(p) && !pilot_isFlag(p,PILOT_MANUAL_CONTROL))
4594 return 0;
4595
4596 Task *t = ai_newtask( L, p, task, 0, 1 );
4597 if (!lua_isnoneornil(L,3)) {
4598 lua_pushvalue( L, 3 );
4599 t->dat = luaL_ref( L, LUA_REGISTRYINDEX );
4600 }
4601 return 0;
4602}
4603
4612static int pilotL_poptask( lua_State *L )
4613{
4614 Pilot *p = luaL_validpilot(L,1);
4615 Task *t = ai_curTask( p );
4616 /* Tasks must exist. */
4617 if (t == NULL) {
4618 NLUA_ERROR(L, _("Trying to pop task when there are no tasks on the stack."));
4619 return 0;
4620 }
4621 t->done = 1;
4622 return 0;
4623}
4624
4633static int pilotL_refuel( lua_State *L )
4634{
4635 Pilot *p = luaL_validpilot(L,1);
4636 Pilot *target = luaL_validpilot(L,2);
4637 double amount = luaL_optinteger(L,3,100);
4638 pilot_rmFlag( p, PILOT_HYP_PREP);
4639 pilot_rmFlag( p, PILOT_HYP_BRAKE );
4640 pilot_rmFlag( p, PILOT_HYP_BEGIN);
4641 pilot_setFlag( p, PILOT_REFUELING);
4642 ai_refuel( p, target->id );
4643 p->refuel_amount = amount;
4644 return 0;
4645}
4646
4650static Task *pilotL_newtask( lua_State *L, Pilot* p, const char *task )
4651{
4652 Task *t;
4653
4654 /* Must be on manual control. */
4655 if (!pilot_isFlag( p, PILOT_MANUAL_CONTROL)) {
4656 NLUA_ERROR( L, _("Pilot is not on manual control.") );
4657 return 0;
4658 }
4659
4660 /* Creates the new task. */
4661 t = ai_newtask( L, p, task, 0, 1 );
4662
4663 return t;
4664}
4665
4685static int pilotL_moveto( lua_State *L )
4686{
4687 Pilot *p;
4688 Task *t;
4689 vec2 *vec;
4690 int brake, compensate;
4691 const char *tsk;
4692
4693 /* Get parameters. */
4694 p = luaL_validpilot(L,1);
4695 vec = luaL_checkvector(L,2);
4696 if (lua_isnone(L,3))
4697 brake = 1;
4698 else
4699 brake = lua_toboolean(L,3);
4700 if (lua_isnone(L,4))
4701 compensate = 1;
4702 else
4703 compensate = lua_toboolean(L,4);
4704
4705 /* Set the task. */
4706 if (brake) {
4707 tsk = "moveto";
4708 }
4709 else {
4710 if (compensate)
4711 tsk = "moveto_nobrake";
4712 else
4713 tsk = "moveto_nobrake_raw";
4714 }
4715 t = pilotL_newtask( L, p, tsk );
4716 lua_pushvector( L, *vec );
4717 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
4718
4719 return 0;
4720}
4721
4734static int pilotL_face( lua_State *L )
4735{
4736 Pilot *p, *pt;
4737 vec2 *vec;
4738 Task *t;
4739 int towards;
4740
4741 /* Get parameters. */
4742 pt = NULL;
4743 vec = NULL;
4744 p = luaL_validpilot(L,1);
4745 if (lua_ispilot(L,2))
4746 pt = luaL_validpilot(L,2);
4747 else
4748 vec = luaL_checkvector(L,2);
4749 towards = lua_toboolean(L,3);
4750
4751 /* Set the task. */
4752 if (towards)
4753 t = pilotL_newtask( L, p, "face_towards" );
4754 else
4755 t = pilotL_newtask( L, p, "face" );
4756 if (pt != NULL) {
4757 lua_pushpilot(L, pt->id);
4758 }
4759 else {
4760 lua_pushvector(L, *vec);
4761 }
4762 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
4763
4764 return 0;
4765}
4766
4776static int pilotL_brake( lua_State *L )
4777{
4778 Pilot *p = luaL_validpilot(L,1);
4779 pilotL_newtask( L, p, "brake" );
4780 return 0;
4781}
4782
4796static int pilotL_follow( lua_State *L )
4797{
4798 Pilot *p, *pt;
4799 Task *t;
4800 int accurate;
4801
4802 /* Get parameters. */
4803 p = luaL_validpilot(L,1);
4804 pt = luaL_validpilot(L,2);
4805 accurate = lua_toboolean(L,3);
4806
4807 /* Set the task. */
4808 if (accurate == 0)
4809 t = pilotL_newtask( L, p, "follow" );
4810 else
4811 t = pilotL_newtask( L, p, "follow_accurate" );
4812
4813 lua_pushpilot(L, pt->id);
4814 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
4815
4816 return 0;
4817}
4818
4832static int pilotL_attack( lua_State *L )
4833{
4834 Pilot *p;
4835 Task *t;
4836 unsigned int pid;
4837
4838 /* Get parameters. */
4839 p = luaL_validpilot(L,1);
4840 if (!lua_isnoneornil(L,2)) {
4841 Pilot *pt = luaL_validpilot(L,2);
4842 pid = pt->id;
4843 }
4844 else {
4845 pid = pilot_getNearestEnemy( p );
4846 if (pid == 0) /* No enemy found. */
4847 return 0;
4848 }
4849
4850 /* Set the task. */
4851 t = pilotL_newtask( L, p, "attack_forced" );
4852 lua_pushpilot(L, pid);
4853 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
4854
4855 return 0;
4856}
4857
4870static int pilotL_board( lua_State *L )
4871{
4872 Pilot *p, *pt;
4873 Task *t;
4874
4875 /* Get parameters. */
4876 p = luaL_validpilot(L,1);
4877 pt = luaL_validpilot(L,2);
4878
4879 /* Set the task. */
4880 t = pilotL_newtask( L, p, "board" );
4881 lua_pushpilot(L, pt->id);
4882 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
4883
4884 return 0;
4885}
4886
4904static int pilotL_runaway( lua_State *L )
4905{
4906 /* Get parameters. */
4907 Pilot *p = luaL_validpilot(L,1);
4908 Pilot *pt = luaL_validpilot(L,2);
4909
4910 /* Set the task depending on the last parameter. */
4911 if (lua_isnoneornil(L,3)) {
4912 Task *t = pilotL_newtask( L, p, "runaway" );
4913 lua_pushpilot(L, pt->id);
4914 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
4915 }
4916 else {
4917 if (lua_isboolean(L,3)) {
4918 int nojump = lua_toboolean(L,3);
4919 Task *t = pilotL_newtask( L, p, (nojump) ? "runaway_nojump" : "runaway" );
4920 lua_pushpilot(L, pt->id);
4921 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
4922 }
4923 else if (lua_isjump(L,3)) {
4924 LuaJump *lj = lua_tojump(L,3);
4925 Task *t = pilotL_newtask( L, p, "runaway_jump" );
4926 lua_newtable(L);
4927 lua_pushpilot(L, pt->id);
4928 lua_rawseti( L, -2, 1 );
4929 lua_pushjump(L, *lj);
4930 lua_rawseti( L, -2, 2 );
4931 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
4932 }
4933 else if (lua_isspob(L,3)) {
4934 LuaSpob lp = lua_tospob(L,3);
4935 Task *t = pilotL_newtask( L, p, "runaway_land" );
4936 lua_newtable(L);
4937 lua_pushpilot(L, pt->id);
4938 lua_rawseti( L, -2, 1 );
4939 lua_pushspob(L, lp);
4940 lua_rawseti( L, -2, 2 );
4941 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
4942 }
4943 else
4944 NLUA_INVALID_PARAMETER(L);
4945 }
4946
4947 return 0;
4948}
4949
4957static int pilotL_gather( lua_State *L )
4958{
4959 Pilot *p;
4960 Task *t;
4961
4962 /* Get parameters. */
4963 p = luaL_validpilot(L,1);
4964
4965 /* Set the task. */
4966 t = pilotL_newtask( L, p, "gather" );
4967 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
4968
4969 return 0;
4970}
4971
4983static int pilotL_hyperspace( lua_State *L )
4984{
4985 Pilot *p;
4986 Task *t;
4987 StarSystem *ss;
4988 JumpPoint *jp;
4989 LuaJump lj;
4990 int noshoot;
4991
4992 /* Get parameters. */
4993 p = luaL_validpilot(L,1);
4994 if (lua_isjump(L,2))
4995 ss = system_getIndex( lua_tojump(L,2)->destid );
4996 else
4997 ss = (lua_isnoneornil(L,2)) ? NULL : luaL_validsystem(L,2);
4998 noshoot = lua_toboolean(L,3);
4999
5000 /* Set the task. */
5001 if (noshoot)
5002 t = pilotL_newtask( L, p, "hyperspace" );
5003 else
5004 t = pilotL_newtask( L, p, "hyperspace_shoot" );
5005
5006 if (ss == NULL)
5007 return 0;
5008 /* Find the jump. */
5009 for (int i=0; i < array_size(cur_system->jumps); i++) {
5010 jp = &cur_system->jumps[i];
5011 if (jp->target != ss)
5012 continue;
5013 /* Found target. */
5014
5015 if (jp_isFlag( jp, JP_EXITONLY )) {
5016 NLUA_ERROR( L, _("Pilot '%s' can't jump out exit only jump '%s'"), p->name, ss->name );
5017 return 0;
5018 }
5019
5020 /* Push jump. */
5021 lj.srcid = cur_system->id;
5022 lj.destid = jp->targetid;
5023 lua_pushjump(L, lj);
5024 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5025 return 0;
5026 }
5027 /* Not found. */
5028 NLUA_ERROR( L, _("System '%s' is not adjacent to current system '%s'"), ss->name, cur_system->name );
5029 return 0;
5030}
5031
5041static int pilotL_stealth( lua_State *L )
5042{
5043 /* Get parameters. */
5044 Pilot *p = luaL_validpilot(L,1);
5045
5046 /* Set the task. */
5047 Task *t = pilotL_newtask( L, p, "stealth" );
5048 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5049
5050 return 0;
5051}
5052
5060static int pilotL_tryStealth( lua_State *L )
5061{
5062 Pilot *p = luaL_validpilot(L,1);
5063 lua_pushboolean( L, pilot_stealth(p) );
5064 return 1;
5065}
5066
5078static int pilotL_land( lua_State *L )
5079{
5080 Pilot *p;
5081 Task *t;
5082 Spob *pnt;
5083 int noshoot;
5084
5085 /* Get parameters. */
5086 p = luaL_validpilot(L,1);
5087 if (lua_isnoneornil(L,2))
5088 pnt = NULL;
5089 else
5090 pnt = luaL_validspob( L, 2 );
5091 noshoot = lua_toboolean(L,3);
5092
5093 /* Set the task. */
5094 if (noshoot)
5095 t = pilotL_newtask( L, p, "land" );
5096 else
5097 t = pilotL_newtask( L, p, "land_shoot" );
5098
5099 if (pnt != NULL) {
5100 int i;
5101 /* Find the spob. */
5102 for (i=0; i < array_size(cur_system->spobs); i++) {
5103 if (cur_system->spobs[i] == pnt) {
5104 break;
5105 }
5106 }
5107 if (i >= array_size(cur_system->spobs)) {
5108 NLUA_ERROR( L, _("Spob '%s' not found in system '%s'"), pnt->name, cur_system->name );
5109 return 0;
5110 }
5111
5112 p->nav_spob = i;
5113 if (p->id == PLAYER_ID)
5114 gui_setNav();
5115
5116 lua_pushspob(L, pnt->id);
5117 t->dat = luaL_ref(L, LUA_REGISTRYINDEX);
5118 }
5119
5120 return 0;
5121}
5122
5133static int pilotL_hailPlayer( lua_State *L )
5134{
5135 Pilot *p;
5136 int enable;
5137
5138 /* Get parameters. */
5139 p = luaL_validpilot(L,1);
5140 if (lua_isnone(L,2))
5141 enable = 1;
5142 else
5143 enable = lua_toboolean(L,2);
5144
5145 /* Set the flag. */
5146 if (enable) {
5147 /* Send message. */
5148 char c = pilot_getFactionColourChar( p );
5149 player_message( _("#%c%s#0 is hailing you."), c, p->name );
5150
5151 /* Set flag. */
5152 pilot_setFlag( p, PILOT_HAILING );
5154 }
5155 else
5156 pilot_rmFlag( p, PILOT_HAILING );
5157
5158 return 0;
5159}
5160
5172static int pilotL_msg( lua_State *L )
5173{
5174 Pilot *p, *receiver=NULL;
5175 const char *type;
5176 unsigned int data;
5177
5178 if (lua_isnoneornil(L,1))
5179 p = NULL;
5180 else
5181 p = luaL_validpilot(L,1);
5182 type = luaL_checkstring(L,3);
5183 data = lua_gettop(L) > 3 ? 4 : 0;
5184
5185 if (!lua_istable(L,2)) {
5186 receiver = luaL_validpilot(L,2);
5187 pilot_msg(p, receiver, type, data);
5188 }
5189 else {
5190 lua_pushnil(L);
5191 while (lua_next(L, 2) != 0) {
5192 receiver = luaL_validpilot(L,-1);
5193 pilot_msg(p, receiver, type, data);
5194 lua_pop(L, 1);
5195 }
5196 lua_pop(L, 1);
5197 }
5198
5199 return 0;
5200}
5201
5209static int pilotL_mothership( lua_State *L )
5210{
5211 Pilot *p = luaL_validpilot(L, 1);
5212 if (p->dockpilot != 0) {
5213 Pilot *l = pilot_get( p->dockpilot );
5214 if ((l == NULL) || pilot_isFlag( l, PILOT_DEAD )) {
5215 lua_pushnil(L);
5216 }
5217 else
5218 lua_pushpilot(L, p->dockpilot);
5219 }
5220 else
5221 lua_pushnil(L);
5222 return 1;
5223}
5224
5232static int pilotL_leader( lua_State *L )
5233{
5234 Pilot *p = luaL_validpilot(L, 1);
5235 if (p->parent != 0) {
5236 Pilot *l = pilot_get( p->parent );
5237 if ((l == NULL) || pilot_isFlag( l, PILOT_DEAD )) {
5238 p->parent = 0; /* Clear parent for future calls. */
5239 lua_pushnil(L);
5240 }
5241 else
5242 lua_pushpilot(L, p->parent);
5243 }
5244 else
5245 lua_pushnil(L);
5246 return 1;
5247}
5248
5260static int pilotL_setLeader( lua_State *L )
5261{
5262 Pilot *p = luaL_validpilot(L, 1);
5263 Pilot *prev_leader = pilot_get( p->parent );
5264
5265 /* Remove from previous leader's follower list */
5266 if (prev_leader != NULL) {
5267 int found = 0;
5268 for (int i=0; i<array_size(prev_leader->escorts); i++) {
5269 Escort_t *e = &prev_leader->escorts[i];
5270 if (e->id != p->id)
5271 continue;
5272 if (e->type != ESCORT_TYPE_MERCENARY) {
5273 NLUA_ERROR(L,_("Trying to change the leader of pilot '%s' that is a deployed fighter or part of the player fleet!"), p->name);
5274 return 0;
5275 }
5276 escort_rmListIndex( prev_leader, i );
5277 found = 1;
5278 break;
5279 }
5280 if (!found)
5281 WARN(_("Pilot '%s' not found in followers of '%s'"), p->name, prev_leader->name );
5282 }
5283
5284 /* Just clear parent, will already be gone from parent escort list. */
5285 if (lua_isnoneornil(L, 2)) {
5286 p->parent = 0;
5287 }
5288 else {
5289 PilotOutfitSlot* dockslot;
5290 Pilot *leader = luaL_validpilot(L, 2);
5291
5292 /* Don't allow setting a pilot's leader to themselves. */
5293 if (p->id == leader->id)
5294 NLUA_ERROR(L,_("Trying to set pilot '%s' to be their own leader!"),p->name);
5295
5296 if ((leader->parent != 0) && (leader->parent != p->id)) {
5297 Pilot *leader_leader = pilot_get(leader->parent);
5298 if (leader_leader != NULL)
5299 leader = leader_leader;
5300 }
5301
5302 p->parent = leader->id;
5303
5304 /* Reset dock slot */
5305 dockslot = pilot_getDockSlot( p );
5306 if (dockslot != NULL) {
5307 dockslot->u.ammo.deployed--;
5308 p->dockpilot = 0;
5309 p->dockslot = -1;
5310 }
5311
5312 /* TODO: Figure out escort type */
5313 escort_addList( leader, p->ship->name, ESCORT_TYPE_MERCENARY, p->id, 0 );
5314
5315 /* If the pilot has followers, they should be given the new leader as well, and be added as escorts. */
5316 for (int i=array_size(p->escorts)-1; i>=0; i--) {
5317 Escort_t *e = &p->escorts[i];
5318 /* We don't want to deal with fighter bays this way. */
5319 if (e->type != ESCORT_TYPE_MERCENARY)
5320 continue;
5321 Pilot *pe = pilot_get( e->id );
5322 if (pe == NULL) {
5323 escort_rmListIndex( p, i ); /* MIght as well remove if they're not there. */
5324 continue;
5325 }
5326
5327 /* Setting an escort as leader, so we clear the leader of the escort. */
5328 if (pe->id == p->parent) {
5329 escort_rmListIndex( p, i );
5330 pe->parent = 0;
5331 continue;
5332 }
5333
5334 pe->parent = p->parent;
5335
5336 /* Add escort to parent. */
5337 escort_addList( leader, pe->ship->name, e->type, pe->id, 0 );
5338 escort_rmListIndex( p, i );
5339 }
5340 }
5341
5342 return 0;
5343}
5344
5352static int pilotL_followers( lua_State *L )
5353{
5354 Pilot *p = luaL_validpilot(L, 1);
5355 int idx = 1;
5356
5357 lua_newtable(L);
5358 for (int i=0; i < array_size(p->escorts); i++) {
5359 /* Make sure the followers are valid. */
5360 Pilot *pe = pilot_get( p->escorts[i].id );
5361 if ((pe==NULL) || pilot_isFlag( pe, PILOT_DEAD ) || pilot_isFlag( pe, PILOT_HIDE ))
5362 continue;
5363 lua_pushpilot(L, p->escorts[i].id);
5364 lua_rawseti(L, -2, idx++);
5365 }
5366
5367 return 1;
5368}
5369
5379static int pilotL_hookClear( lua_State *L )
5380{
5381 Pilot *p = luaL_validpilot(L,1);
5382 pilot_clearHooks( p );
5383 return 0;
5384}
5385
5386static const CollPoly *getCollPoly( const Pilot *p )
5387{
5388 int k = p->ship->gfx_space->sx * p->tsy + p->tsx;
5389 return &p->ship->polygon[k];
5390}
5399static int pilotL_collisionTest( lua_State *L )
5400{
5401 vec2 crash;
5402 Pilot *p = luaL_validpilot(L,1);
5403
5404 /* Asteroid treated separately. */
5405 if (lua_isasteroid(L,2)) {
5406 Asteroid *a = luaL_validasteroid( L, 2 );
5407 CollPoly rpoly;
5408 RotatePolygon( &rpoly, a->polygon, (float) a->ang );
5409 int ret = CollidePolygon( getCollPoly(p), &p->solid->pos,
5410 &rpoly, &a->pos, &crash );
5411 free(rpoly.x);
5412 free(rpoly.y);
5413 if (!ret)
5414 return 0;
5415 lua_pushvector( L, crash );
5416 return 1;
5417 }
5418
5419 Pilot *t = luaL_validpilot(L,2);
5420
5421 /* Shouldn't be invincible. */
5422 if (pilot_isFlag( t, PILOT_INVINCIBLE ))
5423 return 0;
5424
5425 /* Shouldn't be landing or taking off. */
5426 if (pilot_isFlag( t, PILOT_LANDING) ||
5427 pilot_isFlag( t, PILOT_TAKEOFF ) ||
5428 pilot_isFlag( t, PILOT_NONTARGETABLE))
5429 return 0;
5430
5431 /* Must be able to target. */
5432 if (!pilot_canTarget( t ))
5433 return 0;
5434
5435 int ret = CollidePolygon( getCollPoly(p), &p->solid->pos, getCollPoly(t), &t->solid->pos, &crash );
5436 if (!ret)
5437 return 0;
5438
5439 lua_pushvector( L, crash );
5440 return 1;
5441}
5442
5455static int pilotL_damage( lua_State *L )
5456{
5457 Damage dmg;
5458 Pilot *p, *parent;
5459 double damage;
5460
5461 p = luaL_validpilot(L,1);
5462 dmg.damage = luaL_checknumber(L,2);
5463 dmg.disable = luaL_optnumber(L,3,0.);
5464 dmg.penetration = luaL_optnumber(L,4,0.) / 100.;
5465 dmg.type = dtype_get( luaL_optstring(L,5,"normal") );
5466 parent = (lua_isnoneornil(L,6)) ? NULL : luaL_validpilot(L,6);
5467
5468 damage = pilot_hit( p, NULL, parent, &dmg, NULL, LUA_NOREF, 1 );
5469 if (parent != NULL)
5470 weapon_hitAI( p, parent, damage );
5471
5472 lua_pushnumber(L, damage);
5473 return 1;
5474}
5475
5484static int pilotL_kill( lua_State *L )
5485{
5486 Pilot *p = luaL_validpilot(L,1);
5487 p->armour = -1.;
5488 pilot_dead( p, 0 );
5489 return 0;
5490}
5491
5505static int pilotL_knockback( lua_State *L )
5506{
5507 Pilot *p1 = luaL_validpilot(L,1);
5508 double m1 = p1->solid->mass;
5509 vec2 *v1 = &p1->solid->vel;
5510 vec2 *x1 = &p1->solid->pos;
5511 Pilot *p2;
5512 double m2;
5513 vec2 *v2;
5514 vec2 *x2;
5515 double e;
5516 if (lua_ispilot(L,2)) {
5517 p2 = luaL_validpilot(L,2);
5518 m2 = p2->solid->mass;
5519 v2 = &p2->solid->vel;
5520 x2 = &p2->solid->pos;
5521 e = luaL_optnumber(L,3,1.);
5522 }
5523 else {
5524 p2 = NULL;
5525 m2 = luaL_checknumber(L,2);
5526 v2 = luaL_checkvector(L,3);
5527 x2 = luaL_optvector(L,4,x1);
5528 e = luaL_optnumber(L,5,1.);
5529 }
5530
5531 /* Pure inlastic case. */
5532 if (e==0.) {
5533 double vx = (m1*v1->x + m2*v2->x) / (m1+m2);
5534 double vy = (m1*v1->y + m2*v2->y) / (m1+m2);
5535 vec2_cset( &p1->solid->vel, vx, vy );
5536 if (p2 != NULL)
5537 vec2_cset( &p2->solid->vel, vx, vy );
5538 return 0.;
5539 }
5540
5541 /* Pure elastic. */
5542 double norm = pow2(x1->x-x2->x) + pow2(x1->y-x2->y);
5543 double a1 = -e * (2.*m2)/(m1+m2);
5544 if (norm > 0.)
5545 a1 *= ((v1->x-v2->x)*(x1->x-x2->x) + (v1->y-v2->y)*(x1->y-x2->y)) / norm;
5546
5547 vec2_cadd( &p1->solid->vel, a1*(x1->x-x2->x), a1*(x1->y-x2->y) );
5548 if (p2 != NULL) {
5549 double a2 = -e * (2.*m1)/(m2+m1);
5550 if (norm > 0.)
5551 a2 *= ((v2->x-v1->x)*(x2->x-x1->x) + (v2->y-v1->y)*(x2->y-x1->y)) / norm;
5552 vec2_cadd( &p2->solid->vel, a2*(x2->x-x1->x), a2*(x2->y-x1->y) );
5553 }
5554
5555 /* Modulate. TODO this is probably totally wrong and needs fixing to be physicaly correct. */
5556 if (e != 1.) {
5557 double vx = (m1*v1->x + m2*v2->x) / (m1+m2);
5558 double vy = (m1*v1->y + m2*v2->y) / (m1+m2);
5559 vec2_cset( &p1->solid->vel, e*v1->x + (1.-e)*vx, e*v1->y + (1.-e)*vy );
5560 if (p2 != NULL)
5561 vec2_cset( &p2->solid->vel, e*v2->x + (1.-e)*vx, e*v2->y + (1.-e)*vy );
5562 }
5563
5564 return 0;
5565}
5566
5573static int pilotL_calcStats( lua_State *L )
5574{
5575 Pilot *p = luaL_validpilot(L,1);
5576 pilot_calcStats( p );
5577 return 0;
5578}
5579
5589static int pilotL_showEmitters( lua_State *L )
5590{
5591 int state;
5592
5593 /* Get state. */
5594 if (lua_gettop(L) > 0)
5595 state = lua_toboolean(L, 1);
5596 else
5597 state = 1;
5598
5599 /* Toggle the markers. */
5600#if DEBUGGING
5601 if (state)
5602 debug_setFlag(DEBUG_MARK_EMITTER);
5603 else
5604 debug_rmFlag(DEBUG_MARK_EMITTER);
5605#else /* DEBUGGING */
5606 (void) state;
5607 NLUA_ERROR(L, _("Requires a debug build."));
5608#endif /* DEBUGGING */
5609
5610 return 0;
5611}
5612
5623static int pilotL_shipvarPeek( lua_State *L )
5624{
5625 Pilot *p = luaL_validpilot(L,1);
5626 const char *str = luaL_checkstring(L,2);
5627 lvar *var = lvar_get( p->shipvar, str );
5628 if (var != NULL)
5629 return lvar_push( L, var );
5630 return 0;
5631}
5632
5641static int pilotL_shipvarPush( lua_State *L )
5642{
5643 Pilot *p = luaL_validpilot(L,1);
5644 const char *str = luaL_checkstring(L,2);
5645 lvar var = lvar_tovar( L, str, 3 );
5646 if (p->shipvar==NULL)
5647 p->shipvar = array_create( lvar );
5648 lvar_addArray( &p->shipvar, &var, 1 );
5649 return 0;
5650}
5651
5659static int pilotL_shipvarPop( lua_State *L )
5660{
5661 Pilot *p = luaL_validpilot(L,1);
5662 const char *str = luaL_checkstring(L,2);
5663 lvar *var = lvar_get( p->shipvar, str );
5664 if (var != NULL)
5665 lvar_rmArray( &p->shipvar, var );
5666 return 0;
5667}
5668
5676static int pilotL_render( lua_State *L )
5677{
5678 LuaCanvas_t lc;
5679 int w, h;
5680 Pilot *p = luaL_validpilot(L,1);
5681
5682 /* TODO handle when effects make the ship render larger than it really is. */
5683 w = p->ship->gfx_space->sw;
5684 h = p->ship->gfx_space->sh;
5685 if (canvas_new( &lc, w, h ))
5686 NLUA_ERROR( L, _("Error setting up framebuffer!"));
5687
5688 /* I'me really stumped at why we need to pass gl_screen here for it to work... */
5690
5691 lua_pushcanvas( L, lc );
5692 return 1;
5693}
5694
5704static int pilotL_renderTo( lua_State *L )
5705{
5706 Pilot *p = luaL_validpilot( L, 1 );
5707 LuaCanvas_t *lc = luaL_checkcanvas( L, 2 );
5708
5709 /* TODO handle when effects make the ship render larger than it really is. */
5710 if ((lc->tex->w < p->ship->gfx_space->sw) || (lc->tex->h < p->ship->gfx_space->sh))
5711 WARN(_("Canvas is too small to fully render '%s': %.0f x %.0f < %.0f x %.0f"),
5712 p->name, lc->tex->w, lc->tex->h,
5713 p->ship->gfx_space->sw, p->ship->gfx_space->sh );
5714
5715 /* I'me really stumped at why we need to pass gl_screen here for it to work... */
5717
5718 lua_pushnumber( L, p->ship->gfx_space->sw );
5719 lua_pushnumber( L, p->ship->gfx_space->sh );
5720 return 2;
5721}
Task * ai_newtask(lua_State *L, Pilot *p, const char *func, int subtask, int pos)
Creates a new AI task.
Definition: ai.c:1051
Task * ai_curTask(Pilot *pilot)
Gets the current running task.
Definition: ai.c:381
void ai_refuel(Pilot *refueler, unsigned int target)
Has a pilot attempt to refuel the other.
Definition: ai.c:937
void ai_cleartasks(Pilot *p)
Clears the pilot's tasks.
Definition: ai.c:485
void ai_destroy(Pilot *p)
Destroys the ai part of the pilot.
Definition: ai.c:498
int ai_pinit(Pilot *p, const char *ai)
Initializes the pilot in the ai.
Definition: ai.c:434
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:325
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:254
int dtype_get(const char *name)
Gets the id of a dtype based on name.
Definition: damagetype.c:144
const char * dtype_damageTypeToStr(int type)
Gets the human readable string from damage type.
Definition: damagetype.c:168
int effect_rm(Effect **efxlist, const EffectData *efx, int all)
Removes an effect from an effect list.
Definition: effect.c:358
const EffectData * effect_get(const char *name)
Gets an effect by name.
Definition: effect.c:222
void effect_clear(Effect **efxlist)
Clears an effect list, removing all active effects.
Definition: effect.c:387
int effect_add(Effect **efxlist, const EffectData *efx, double duration, double scale, unsigned int parent)
Adds an effect to an effect list.
Definition: effect.c:277
void escort_rmListIndex(Pilot *p, int i)
Remove from escorts list.
Definition: escort.c:75
int escort_addList(Pilot *p, const char *ship, EscortType_t type, unsigned int id, int persist)
Adds an escort to the escort list of a pilot.
Definition: escort.c:40
int areEnemies(int a, int b)
Checks whether two factions are enemies.
Definition: faction.c:1197
int areAllies(int a, int b)
Checks whether two factions are allies or not.
Definition: faction.c:1222
void gui_setNav(void)
Player just changed their nav computer target.
Definition: gui.c:1749
void player_message(const char *fmt,...)
Adds a mesg to the queue to be displayed on screen.
Definition: gui.c:330
void outfits_updateEquipmentOutfits(void)
Updates the outfitter and equipment outfit image arrays.
Definition: land_outfits.c:523
int lvar_addArray(lvar **arr, lvar *new_var, int sort)
Adds a var to a var array.
Definition: lvar.c:160
void lvar_rmArray(lvar **arr, lvar *rm_var)
Removes a var from a var array.
Definition: lvar.c:187
lvar * lvar_get(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.
Definition: nlua_asteroid.c:71
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.
Definition: nlua_asteroid.c:95
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.
Definition: nlua_colour.c:103
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.
Definition: nlua_faction.c:192
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.
Definition: nlua_faction.c:177
int lua_isfaction(lua_State *L, int ind)
Checks to see if ind is a faction.
Definition: nlua_faction.c:208
LuaFaction lua_tofaction(lua_State *L, int ind)
Gets faction at index.
Definition: nlua_faction.c:155
LuaJump * lua_pushjump(lua_State *L, LuaJump jump)
Pushes a jump on the stack.
Definition: nlua_jump.c:182
int lua_isjump(lua_State *L, int ind)
Checks to see if ind is a jump.
Definition: nlua_jump.c:198
LuaJump * lua_tojump(lua_State *L, int ind)
This module allows you to handle the jumps from Lua.
Definition: nlua_jump.c:89
const Outfit * luaL_validoutfit(lua_State *L, int ind)
Makes sure the outfit is valid or raises a Lua error.
Definition: nlua_outfit.c:135
const Outfit ** lua_pushoutfit(lua_State *L, const Outfit *outfit)
Pushes a outfit on the stack.
Definition: nlua_outfit.c:160
static int pilotL_setVisible(lua_State *L)
Marks the pilot as always visible for other pilots.
Definition: nlua_pilot.c:2737
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.
Definition: nlua_pilot.c:3387
static int pilotL_getVisible(lua_State *L)
Gets visible pilots to a pilot within a certain distance.
Definition: nlua_pilot.c:1098
static int pilotL_isStopped(lua_State *L)
Checks to see if a pilot is stopped.
Definition: nlua_pilot.c:2229
static int pilotL_clone(lua_State *L)
Clones a pilot. It will share nearly all properties including outfits.
Definition: nlua_pilot.c:741
static int pilotL_setHide(lua_State *L)
Sets the pilot's hide status.
Definition: nlua_pilot.c:2675
static int pilotL_calcStats(lua_State *L)
Forces a recomputation of the pilots' stats.
Definition: nlua_pilot.c:5573
static int pilotL_refuel(lua_State *L)
Tries to refuel a pilot.
Definition: nlua_pilot.c:4633
static int pilotL_eq(lua_State *L)
Checks to see if pilot and p are the same.
Definition: nlua_pilot.c:1184
static int pilotL_moveto(lua_State *L)
Makes the pilot move to a position.
Definition: nlua_pilot.c:4685
static int pilotL_hailPlayer(lua_State *L)
Marks the pilot as hailing the player.
Definition: nlua_pilot.c:5133
static int pilotL_setEnergy(lua_State *L)
Sets the energy of a pilot.
Definition: nlua_pilot.c:3665
static int pilotL_setFriendly(lua_State *L)
Controls the pilot's friendliness towards the player.
Definition: nlua_pilot.c:2605
static int pilotL_cargoJet(lua_State *L)
Tries to remove a cargo from a pilot's ship and jet it into space.
Definition: nlua_pilot.c:4111
static int pilotL_activeWeapset(lua_State *L)
Gets the ID (number from 1 to 10) of the current active weapset.
Definition: nlua_pilot.c:1472
static int pilotL_outfitRm(lua_State *L)
Removes an outfit from a pilot.
Definition: nlua_pilot.c:3139
static int pilotL_outfitRmIntrinsic(lua_State *L)
Removes an intrinsic outfit from the pilot.
Definition: nlua_pilot.c:3273
static int pilotL_actives(lua_State *L)
Gets the active outfits and their states of the pilot.
Definition: nlua_pilot.c:1836
static int pilotL_cargoFree(lua_State *L)
Gets the free cargo space the pilot has.
Definition: nlua_pilot.c:3981
static int pilotL_setNoLand(lua_State *L)
Enables or disables landing for a pilot.
Definition: nlua_pilot.c:2917
static int pilotL_targetAsteroid(lua_State *L)
Gets the asteroid target of the pilot.
Definition: nlua_pilot.c:1306
static int pilotL_setActiveBoard(lua_State *L)
Allows the pilot to be boarded when not disabled.
Definition: nlua_pilot.c:2781
static int pilotL_brake(lua_State *L)
Makes the pilot brake.
Definition: nlua_pilot.c:4776
static int pilotL_withPlayer(lua_State *L)
Checks to see if pilot is with player.
Definition: nlua_pilot.c:1416
static int pilotL_spaceworthy(lua_State *L)
Checks the pilot's spaceworthiness.
Definition: nlua_pilot.c:2328
static int pilotL_render(lua_State *L)
Renders the pilot to a canvas.
Definition: nlua_pilot.c:5676
static int pilotL_runaway(lua_State *L)
Makes the pilot runaway from another pilot.
Definition: nlua_pilot.c:4904
static int pilotL_land(lua_State *L)
Tells the pilot to land.
Definition: nlua_pilot.c:5078
LuaPilot lua_topilot(lua_State *L, int ind)
Lua bindings to interact with pilots.
Definition: nlua_pilot.c:453
static int pilotL_memory(lua_State *L)
Gets a pilots memory table.
Definition: nlua_pilot.c:4445
LuaPilot * lua_pushpilot(lua_State *L, LuaPilot pilot)
Pushes a pilot on the stack.
Definition: nlua_pilot.c:495
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:536
static int pilotL_setNoClear(lua_State *L)
Enables or disables making the the pilot exempt from pilot.clear().
Definition: nlua_pilot.c:2931
static int pilotL_canSpawn(lua_State *L)
Returns if pilots can can spawn naturally in the current system.
Definition: nlua_pilot.c:821
static int pilotL_setNoJump(lua_State *L)
Enables or disables a pilot's hyperspace engine.
Definition: nlua_pilot.c:2903
static int pilotL_setLeader(lua_State *L)
Set a pilots leader.
Definition: nlua_pilot.c:5260
static int pilotL_taskclear(lua_State *L)
Clears all the tasks of the pilot.
Definition: nlua_pilot.c:4571
static int pilotL_nav(lua_State *L)
Gets the nav target of the pilot.
Definition: nlua_pilot.c:1435
static int pilotL_credits(lua_State *L)
Handles the pilots credits.
Definition: nlua_pilot.c:4173
static int pilotL_taskdata(lua_State *L)
Gets the data of the task the pilot is currently doing.
Definition: nlua_pilot.c:4552
static int pilotL_setInvisible(lua_State *L)
Sets the pilot's invisibility status.
Definition: nlua_pilot.c:2690
static int pilotL_exists(lua_State *L)
Checks to see if pilot is still in the system and alive.
Definition: nlua_pilot.c:1235
static int pilotL_hasIllegal(lua_State *L)
Checks to see if the pilot has illegal stuff to a faction.
Definition: nlua_pilot.c:4316
static int pilotL_setTemp(lua_State *L)
Sets the temperature of a pilot.
Definition: nlua_pilot.c:3546
static int pilotL_clearSelect(lua_State *L)
Removes all pilots belonging to a faction from the system.
Definition: nlua_pilot.c:781
static int pilotL_outfitRmSlot(lua_State *L)
Removes an outfit from a pilot's named slot.
Definition: nlua_pilot.c:3218
Pilot * luaL_validpilot(lua_State *L, int ind)
Makes sure the pilot is valid or raises a Lua error.
Definition: nlua_pilot.c:478
static int pilotL_toggleSpawn(lua_State *L)
Disables or enables pilot spawning in the current system.
Definition: nlua_pilot.c:842
static int pilotL_getEnergy(lua_State *L)
Gets the pilot's energy.
Definition: nlua_pilot.c:3831
static int pilotL_points(lua_State *L)
Gets the points the pilot costs.
Definition: nlua_pilot.c:4349
static int pilotL_showEmitters(lua_State *L)
Toggles the emitter marker.
Definition: nlua_pilot.c:5589
static int pilotL_msg(lua_State *L)
Sends a message to another pilot.
Definition: nlua_pilot.c:5172
static int pilotL_setBribed(lua_State *L)
Makes pilot act as if bribed by the player.
Definition: nlua_pilot.c:2767
static int pilotL_cargoRm(lua_State *L)
Tries to remove cargo from the pilot's ship.
Definition: nlua_pilot.c:4094
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,...
Definition: nlua_pilot.c:5505
static int pilotL_hookClear(lua_State *L)
Clears the pilot's hooks.
Definition: nlua_pilot.c:5379
static int pilotL_setNoRender(lua_State *L)
Sets the pilot's norender status.
Definition: nlua_pilot.c:2705
static int pilotL_taskname(lua_State *L)
Gets the name of the task the pilot is currently doing.
Definition: nlua_pilot.c:4507
static int pilotL_intrinsicReset(lua_State *L)
Resets the intrinsic stats of a pilot.
Definition: nlua_pilot.c:3330
static int pilotL_pushtask(lua_State *L)
Pushes a new task to the pilot's AI.
Definition: nlua_pilot.c:4588
static int pilotL_mothership(lua_State *L)
Gets a pilots mothership (only exists for deployed pilots). Guaranteed to exist or will be nil.
Definition: nlua_pilot.c:5209
static int pilotL_getHealth(lua_State *L)
Gets the pilot's health.
Definition: nlua_pilot.c:3801
static int pilotL_cargoAdd(lua_State *L)
Tries to add cargo to the pilot's ship.
Definition: nlua_pilot.c:4020
static int pilot_outfitAddSlot(Pilot *p, const Outfit *o, PilotOutfitSlot *s, int bypass_slot, int bypass_cpu)
Adds an outfit to a specific slot.
Definition: nlua_pilot.c:2939
static int pilotL_damage(lua_State *L)
Damages a pilot.
Definition: nlua_pilot.c:5455
static int pilotL_ai(lua_State *L)
Gets the pilot's AI.
Definition: nlua_pilot.c:3497
static int pilotL_cooldownCycle(lua_State *L)
Makes the pilot do an instant full cooldown cycle.
Definition: nlua_pilot.c:2884
static int pilotL_velocity(lua_State *L)
Gets the pilot's velocity.
Definition: nlua_pilot.c:2213
static int pilotL_disable(lua_State *L)
Disables a pilot.
Definition: nlua_pilot.c:2809
static int pilotL_comm(lua_State *L)
Sends a message to the target or player if no target is passed.
Definition: nlua_pilot.c:2463
static int pilotL_tryStealth(lua_State *L)
Tries to make the pilot stealth.
Definition: nlua_pilot.c:5060
static int pilotL_setNoboard(lua_State *L)
Sets the ability to board the pilot.
Definition: nlua_pilot.c:3705
static int pilotL_fillAmmo(lua_State *L)
Fills up the pilot's ammo.
Definition: nlua_pilot.c:3686
static const luaL_Reg pilotL_methods[]
Definition: nlua_pilot.c:221
static int pilotL_setHealth(lua_State *L)
Sets the health of a pilot.
Definition: nlua_pilot.c:3586
static int pilotL_getInrange(lua_State *L)
Gets visible pilots to a pilot within a certain distance.
Definition: nlua_pilot.c:1136
static int pilotL_changeAI(lua_State *L)
Changes the pilot's AI.
Definition: nlua_pilot.c:3516
static int pilotL_setTarget(lua_State *L)
Sets the pilot target of the pilot.
Definition: nlua_pilot.c:1282
static int pilotL_getEnemies(lua_State *L)
Gets hostile pilots to a pilot (or faction) within a certain distance.
Definition: nlua_pilot.c:1085
static int pilotL_name(lua_State *L)
Gets the pilot's current (translated) name.
Definition: nlua_pilot.c:1201
static int pilotL_getColour(lua_State *L)
Gets the pilot's colour based on hostility or friendliness to the player.
Definition: nlua_pilot.c:4190
static int pilotL_scandone(lua_State *L)
Checks to see if a pilot is done scanning its target.
Definition: nlua_pilot.c:1402
static Task * pilotL_newtask(lua_State *L, Pilot *p, const char *task)
Does a new task.
Definition: nlua_pilot.c:4650
static int pilotL_shipvarPeek(lua_State *L)
Peeks at a ship variable.
Definition: nlua_pilot.c:5623
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.
Definition: nlua_pilot.c:3949
static int pilotL_setNoDisable(lua_State *L)
Sets the ability of the pilot to be disabled.
Definition: nlua_pilot.c:3738
static int pilotL_cargoHas(lua_State *L)
Checks to see how many tonnes of a specific type of cargo the pilot has.
Definition: nlua_pilot.c:3998
static int pilotL_setFuel(lua_State *L)
Sets the fuel of a pilot.
Definition: nlua_pilot.c:3303
static int pilotL_stealth(lua_State *L)
Tells the pilot to try to stealth.
Definition: nlua_pilot.c:5041
static int pilotL_outfits(lua_State *L)
Gets a mapping of outfit slot IDs and outfits of a pilot.
Definition: nlua_pilot.c:2060
static int pilotL_outfitSlot(lua_State *L)
Checks to see outfit a pilot has in a slot.
Definition: nlua_pilot.c:3054
static int pilotL_outfitsList(lua_State *L)
Gets the outfits of a pilot.
Definition: nlua_pilot.c:1995
static int pilotL_ainame(lua_State *L)
Gets the name of the task the pilot is currently doing.
Definition: nlua_pilot.c:4467
static int outfit_compareActive(const void *slot1, const void *slot2)
qsort compare function for active outfits.
Definition: nlua_pilot.c:1964
static int pilotL_shipvarPop(lua_State *L)
Pops a ship variable.
Definition: nlua_pilot.c:5659
static int pilotL_setCooldown(lua_State *L)
Starts or stops a pilot's cooldown mode.
Definition: nlua_pilot.c:2855
static int pilotL_face(lua_State *L)
Makes the pilot face a target.
Definition: nlua_pilot.c:4734
static int pilotL_clear(lua_State *L)
Clears the current system of pilots. Used for epic battles and such.
Definition: nlua_pilot.c:807
static int pilotL_rename(lua_State *L)
Changes the pilot's name.
Definition: nlua_pilot.c:2175
static int pilotL_mass(lua_State *L)
Gets the mass of a pilot.
Definition: nlua_pilot.c:2293
static const struct pL_flag pL_flags[]
Definition: nlua_pilot.c:4221
static int pilotL_collisionTest(lua_State *L)
Tests to see if two ships collide.
Definition: nlua_pilot.c:5399
static int pilotL_setHostile(lua_State *L)
Controls the pilot's hostility towards the player.
Definition: nlua_pilot.c:2572
static int pilotL_getAllies(lua_State *L)
Gets friendly pilots to a pilot (or faction) within a certain distance.
Definition: nlua_pilot.c:1065
static int pilotL_dir(lua_State *L)
Gets the pilot's direction.
Definition: nlua_pilot.c:2261
static int pilotL_setPosition(lua_State *L)
Sets the pilot's position.
Definition: nlua_pilot.c:2347
static int pilotL_attack(lua_State *L)
Makes the pilot attack another pilot.
Definition: nlua_pilot.c:4832
static int pilotL_setFlagWrapper(lua_State *L, int flag)
Wrapper to simplify flag setting stuff.
Definition: nlua_pilot.c:413
int nlua_loadPilot(nlua_env env)
Loads the pilot library.
Definition: nlua_pilot.c:399
static int pilotL_setSpeedLimit(lua_State *L)
Limits the speed of a pilot.
Definition: nlua_pilot.c:3771
static int pilotL_control(lua_State *L)
Sets manual control of the pilot.
Definition: nlua_pilot.c:4393
static int pilotL_followers(lua_State *L)
Get all of a pilots followers.
Definition: nlua_pilot.c:5352
Pilot * cur_pilot
Definition: ai.c:336
static int pilotL_outfitToggle(lua_State *L)
Toggles an outfit.
Definition: nlua_pilot.c:2105
static int pilotL_leader(lua_State *L)
Gets a pilots leader. Guaranteed to exist or will be nil.
Definition: nlua_pilot.c:5232
static int pilotL_outfitGet(lua_State *L)
Gets a pilot's outfit by ID.
Definition: nlua_pilot.c:2082
static int pilotL_temp(lua_State *L)
Gets the temperature of a pilot.
Definition: nlua_pilot.c:2277
static int pilotL_weapsetHeat(lua_State *L)
Gets heat information for a weapon set.
Definition: nlua_pilot.c:1730
static int pilotL_setHilight(lua_State *L)
Makes pilot stand out on radar and the likes.
Definition: nlua_pilot.c:2753
static int pilotL_shipvarPush(lua_State *L)
Pushes a ship variable.
Definition: nlua_pilot.c:5641
static int pilotL_outfitAddIntrinsic(lua_State *L)
Adds an intrinsic outfit to the pilot.
Definition: nlua_pilot.c:3252
static int pilotL_addHealth(lua_State *L)
Adds health to a pilot.
Definition: nlua_pilot.c:3634
static int pilotL_getLockon(lua_State *L)
Gets the lockons on the pilot.
Definition: nlua_pilot.c:3853
static int pilotL_getDetectedDistance(lua_State *L)
Gets the distance that a pilot can be currently detect at.
Definition: nlua_pilot.c:3964
static int pilotL_effectRm(lua_State *L)
Removes an effect from the pilot.
Definition: nlua_pilot.c:3445
static int pilotL_remove(lua_State *L)
Removes a pilot without explosions or anything.
Definition: nlua_pilot.c:757
static int pilotL_intrinsicSet(lua_State *L)
Allows setting intrinsic stats of a pilot.
Definition: nlua_pilot.c:3349
static int pilotL_kill(lua_State *L)
Kills a pilot.
Definition: nlua_pilot.c:5484
static int pilotL_setFaction(lua_State *L)
Sets the pilot's faction.
Definition: nlua_pilot.c:2550
int lua_ispilot(lua_State *L, int ind)
Checks to see if ind is a pilot.
Definition: nlua_pilot.c:510
static int pilotL_outfitReady(lua_State *L)
Sees if an outfit is ready to use.
Definition: nlua_pilot.c:2151
static int pilotL_position(lua_State *L)
Gets the pilot's position.
Definition: nlua_pilot.c:2197
static int pilotL_getStats(lua_State *L)
Gets stats of the pilot.
Definition: nlua_pilot.c:3901
static int pilotL_poptask(lua_State *L)
Pops the current task from the pilot's AI.
Definition: nlua_pilot.c:4612
static int pilotL_gather(lua_State *L)
Makes the pilot gather stuff.
Definition: nlua_pilot.c:4957
static int pilotL_setInvincPlayer(lua_State *L)
Sets the pilot's invincibility status towards the player.
Definition: nlua_pilot.c:2656
static int pilotL_cargoList(lua_State *L)
Lists the cargo the pilot has.
Definition: nlua_pilot.c:4133
static int pilotL_setNoDeath(lua_State *L)
Makes it so the pilot never dies, stays at 1. armour.
Definition: nlua_pilot.c:2795
static int pilotL_id(lua_State *L)
Gets the ID of the pilot.
Definition: nlua_pilot.c:1217
static int pilotL_getHostile(lua_State *L)
Returns whether the pilot is hostile to the player.
Definition: nlua_pilot.c:4207
static int pilotL_board(lua_State *L)
Makes the pilot board another pilot.
Definition: nlua_pilot.c:4870
static int pilotL_broadcast(lua_State *L)
Makes the pilot broadcast a message.
Definition: nlua_pilot.c:2423
static int pilotL_cooldown(lua_State *L)
Gets a pilot's cooldown state.
Definition: nlua_pilot.c:2838
static int pilotL_setDir(lua_State *L)
Sets the pilot's direction.
Definition: nlua_pilot.c:2397
static int pilotL_task(lua_State *L)
Gets the name and data of a pilot's current task.
Definition: nlua_pilot.c:4484
static int pilotL_inrangeAsteroid(lua_State *L)
Checks to see if an asteroid is in range of a pilot.
Definition: nlua_pilot.c:1385
static int pilotL_setVelocity(lua_State *L)
Sets the pilot's velocity.
Definition: nlua_pilot.c:2375
static int pilotL_taskstack(lua_State *L)
Gets the name of all the pilot's current tasks (not subtasks).
Definition: nlua_pilot.c:4528
static int pilotL_inrange(lua_State *L)
Checks to see if a target pilot is in range of a pilot.
Definition: nlua_pilot.c:1354
static int pilotL_evasion(lua_State *L)
Gets the pilot's evasion.
Definition: nlua_pilot.c:2245
static int pilotL_setInvincible(lua_State *L)
Sets the pilot's invincibility status.
Definition: nlua_pilot.c:2640
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:464
static int pilotL_outfitAdd(lua_State *L)
Adds an outfit to a pilot.
Definition: nlua_pilot.c:2995
static int pilotL_follow(lua_State *L)
Makes the pilot follow another pilot.
Definition: nlua_pilot.c:4796
static int pilotL_effectAdd(lua_State *L)
Adds an effect to a pilot.
Definition: nlua_pilot.c:3420
static int pilotL_outfitAddSlot(lua_State *L)
Adds an outfit to a pilot by slot name.
Definition: nlua_pilot.c:3081
static int pilotL_ship(lua_State *L)
Gets the pilot's ship.
Definition: nlua_pilot.c:4333
static int pilotL_flags(lua_State *L)
Gets the pilot's flags.
Definition: nlua_pilot.c:4283
static int pilotL_hyperspace(lua_State *L)
Tells the pilot to hyperspace.
Definition: nlua_pilot.c:4983
static int pilotL_getPilots(lua_State *L)
Gets the pilots available in the system by a certain criteria.
Definition: nlua_pilot.c:884
static int pilotL_setVisplayer(lua_State *L)
Marks the pilot as always visible for the player.
Definition: nlua_pilot.c:2721
static int pilotL_effectGet(lua_State *L)
Gets the effects on a pilot.
Definition: nlua_pilot.c:3465
static int pilotL_faction(lua_State *L)
Gets the pilot's faction.
Definition: nlua_pilot.c:2309
static int pilotL_setTargetAsteroid(lua_State *L)
Sets the pilot's asteroid target.
Definition: nlua_pilot.c:1327
static int pilotL_renderTo(lua_State *L)
Renders the pilot to a canvas.
Definition: nlua_pilot.c:5704
static int pilotL_target(lua_State *L)
Gets the pilot target of the pilot.
Definition: nlua_pilot.c:1262
static int pilotL_weapset(lua_State *L)
Gets the weapset weapon of the pilot.
Definition: nlua_pilot.c:1520
static int pilotL_idle(lua_State *L)
Checks to see if the pilot is idle.
Definition: nlua_pilot.c:4365
static int pilotL_effectClear(lua_State *L)
Clears the effect on a pilot.
Definition: nlua_pilot.c:3402
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:589
const Ship ** lua_pushship(lua_State *L, const Ship *ship)
Pushes a ship on the stack.
Definition: nlua_ship.c:164
int nlua_loadShip(nlua_env env)
Loads the ship library.
Definition: nlua_ship.c:88
const Ship * luaL_validship(lua_State *L, int ind)
Makes sure the ship is valid or raises a Lua error.
Definition: nlua_ship.c:139
LuaSpob lua_tospob(lua_State *L, int ind)
This module allows you to handle the spobs from Lua.
Definition: nlua_spob.c:139
LuaSpob * lua_pushspob(lua_State *L, LuaSpob spob)
Pushes a spob on the stack.
Definition: nlua_spob.c:192
Spob * luaL_validspob(lua_State *L, int ind)
Gets a spob directly.
Definition: nlua_spob.c:164
int lua_isspob(lua_State *L, int ind)
Checks to see if ind is a spob.
Definition: nlua_spob.c:207
LuaSystem * lua_pushsystem(lua_State *L, LuaSystem sys)
Pushes a system on the stack.
Definition: nlua_system.c:185
StarSystem * luaL_validsystem(lua_State *L, int ind)
Gets system (or system name) at index raising an error if type doesn't match.
Definition: nlua_system.c:156
LuaSystem lua_tosystem(lua_State *L, int ind)
Lua system module.
Definition: nlua_system.c:130
int lua_issystem(lua_State *L, int ind)
Checks to see if ind is a system.
Definition: nlua_system.c:201
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:155
vec2 * luaL_checkvector(lua_State *L, int ind)
Gets vector at index making sure type is valid.
Definition: nlua_vec2.c:124
vec2 * lua_tovector(lua_State *L, int ind)
Represents a 2D vector in Lua.
Definition: nlua_vec2.c:113
vec2 * lua_pushvector(lua_State *L, vec2 vec)
Pushes a vector on the stack.
Definition: nlua_vec2.c:139
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:809
int outfit_isBeam(const Outfit *o)
Checks if outfit is a beam type weapon.
Definition: outfit.c:488
int outfit_isLauncher(const Outfit *o)
Checks if outfit is a weapon launcher.
Definition: outfit.c:498
int outfit_fitsSlot(const Outfit *o, const OutfitSlot *s)
Checks to see if an outfit fits a slot.
Definition: outfit.c:981
int outfit_isFighterBay(const Outfit *o)
Checks if outfit is a fighter bay.
Definition: outfit.c:550
int outfit_isAfterburner(const Outfit *o)
Checks if outfit is an afterburner.
Definition: outfit.c:541
const char * outfit_getType(const Outfit *o)
Gets the outfit's specific type.
Definition: outfit.c:879
int outfit_isMod(const Outfit *o)
Checks if outfit is a ship modification.
Definition: outfit.c:532
const Damage * outfit_damage(const Outfit *o)
Gets the outfit's damage.
Definition: outfit.c:647
double outfit_duration(const Outfit *o)
Gets the outfit's duration.
Definition: outfit.c:851
double outfit_cooldown(const Outfit *o)
Gets the outfit's cooldown.
Definition: outfit.c:866
int outfit_isBolt(const Outfit *o)
Checks if outfit is bolt type weapon.
Definition: outfit.c:478
double outfit_delay(const Outfit *o)
Gets the outfit's delay.
Definition: outfit.c:658
int outfit_fitsSlotType(const Outfit *o, const OutfitSlot *s)
Checks to see if an outfit fits a slot type (ignoring size).
Definition: outfit.c:1025
char pilot_getFactionColourChar(const Pilot *p)
Gets the faction colour char, works like faction_getColourChar but for a pilot.
Definition: pilot.c:1125
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:3345
int pilot_isHostile(const Pilot *p)
Checks to see if pilot is hostile to the player.
Definition: pilot.c:651
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:1598
void pilot_cooldown(Pilot *p, int dochecks)
Begins active cooldown, reducing hull and outfit temperatures.
Definition: pilot.c:941
unsigned int 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:3151
void pilot_rmHostile(Pilot *p)
Unmarks a pilot as hostile to player.
Definition: pilot.c:1276
void pilot_msg(Pilot *p, Pilot *receiver, const char *type, unsigned int idx)
Sends a message.
Definition: pilot.c:3941
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:266
int pilot_areEnemies(const Pilot *p, const Pilot *target)
Like areEnemies but for pilots.
Definition: pilot.c:718
void pilots_clear(void)
Clears all the pilots except the player and clear-exempt pilots.
Definition: pilot.c:3624
Pilot * pilot_getTarget(Pilot *p)
Gets the target of a pilot using a fancy caching system.
Definition: pilot.c:607
ntime_t pilot_hyperspaceDelay(Pilot *p)
Calculates the hyperspace delay for a pilot.
Definition: pilot.c:2855
void pilot_dead(Pilot *p, unsigned int killer)
Pilot is dead, now will slowly explode.
Definition: pilot.c:1676
void pilot_cooldownEnd(Pilot *p, const char *reason)
Terminates active cooldown.
Definition: pilot.c:1004
credits_t pilot_modCredits(Pilot *p, credits_t amount)
Modifies the amount of credits the pilot has.
Definition: pilot.c:2911
unsigned int pilot_getNearestEnemy(const Pilot *p)
Gets the nearest enemy to the pilot.
Definition: pilot.c:312
void pilot_setFriendly(Pilot *p)
Marks pilot as friendly to player.
Definition: pilot.c:1294
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:226
PilotOutfitSlot * pilot_getDockSlot(Pilot *p)
Gets the dock slot of the pilot.
Definition: pilot.c:749
int pilot_hasIllegal(const Pilot *p, int faction)
Checks to see if the pilot has illegal stuf to a faction.
Definition: pilot.c:3974
void pilot_setCommMsg(Pilot *p, const char *s)
Sets the overhead communication message of the pilot.
Definition: pilot.c:1139
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
Definition: pilot.c:589
void pilot_broadcast(Pilot *p, const char *msg, int ignore_int)
Has the pilot broadcast a message.
Definition: pilot.c:1154
void pilot_setHostile(Pilot *p)
Marks pilot as hostile to player.
Definition: pilot.c:1111
const glColour * pilot_getColour(const Pilot *p)
Gets a pilot's colour.
Definition: pilot.c:1327
static Pilot ** pilot_stack
Definition: pilot.c:57
Pilot *const * pilot_getAll(void)
Gets the pilot stack.
Definition: pilot.c:83
int pilot_canTarget(const Pilot *p)
Same as pilot_validTarget but without the range check.
Definition: pilot.c:243
void pilot_rmFriendly(Pilot *p)
Unmarks a pilot as friendly to player.
Definition: pilot.c:1305
int pilot_areAllies(const Pilot *p, const Pilot *target)
Like areAllies but for pilots.
Definition: pilot.c:694
int pilot_getJumps(const Pilot *p)
Gets the amount of jumps the pilot has left.
Definition: pilot.c:1316
void pilot_delete(Pilot *p)
Deletes a pilot.
Definition: pilot.c:2603
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:1381
void pilot_renderFramebuffer(Pilot *p, GLuint fbo, double fw, double fh)
Renders a pilot to a framebuffer.
Definition: pilot.c:1778
void pilot_sample_trails(Pilot *p, int none)
Updates the given pilot's trail emissions.
Definition: pilot.c:2529
void pilot_setTarget(Pilot *p, unsigned int id)
Sets the target of the pilot.
Definition: pilot.c:1351
unsigned int pilot_clone(const Pilot *ref)
Clones an existing pilot.
Definition: pilot.c:3223
int pilot_cargoRmAll(Pilot *pilot, int cleanup)
Gets rid of all cargo from pilot. Can remove mission cargo.
Definition: pilot_cargo.c:348
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.
Definition: pilot_cargo.c:390
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.
Definition: pilot_cargo.c:404
int pilot_cargoAdd(Pilot *pilot, const Commodity *cargo, int quantity, unsigned int id)
Tries to add quantity of cargo to pilot.
Definition: pilot_cargo.c:169
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:242
int pilot_ewScanCheck(const Pilot *p)
Checks to see if a scan is done.
Definition: pilot_ew.c:75
void pilot_destealth(Pilot *p)
Destealths a pilot.
Definition: pilot_ew.c:549
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:387
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:307
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:252
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:314
void pilot_clearHooks(Pilot *p)
Clears the pilots hooks.
Definition: pilot_hook.c:206
int pilot_rmOutfit(Pilot *pilot, PilotOutfitSlot *s)
Removes an outfit from the pilot.
Definition: pilot_outfit.c:475
int pilot_outfitLInit(Pilot *pilot, PilotOutfitSlot *po)
Runs the pilot's Lua outfits init script for an outfit.
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.
Definition: pilot_outfit.c:767
void pilot_calcStats(Pilot *pilot)
Recalculates the pilot's stats based on his outfits.
Definition: pilot_outfit.c:877
void pilot_fillAmmo(Pilot *pilot)
Fills pilot's ammo completely.
Definition: pilot_outfit.c:786
int pilot_addAmmo(Pilot *pilot, PilotOutfitSlot *s, int quantity)
Adds some ammo to the pilot stock.
Definition: pilot_outfit.c:661
int pilot_rmOutfitRaw(Pilot *pilot, PilotOutfitSlot *s)
Removes an outfit from the pilot without doing any checks.
Definition: pilot_outfit.c:424
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.
Definition: pilot_outfit.c:541
int pilot_addOutfitTest(Pilot *pilot, const Outfit *outfit, PilotOutfitSlot *s, int warn)
Tests to see if an outfit can be added.
Definition: pilot_outfit.c:331
int pilot_rmOutfitIntrinsic(Pilot *pilot, PilotOutfitSlot *s)
Removes an outfit from an intrinsic slot.
Definition: pilot_outfit.c:408
int pilot_addOutfitRaw(Pilot *pilot, const Outfit *outfit, PilotOutfitSlot *s)
Adds an outfit to the pilot, ignoring CPU or other limits.
Definition: pilot_outfit.c:273
int pilot_addOutfitIntrinsic(Pilot *pilot, const Outfit *outfit)
Adds an outfit as an intrinsic slot.
Definition: pilot_outfit.c:385
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.
PilotWeaponSetOutfit * pilot_weapSetList(Pilot *p, int id)
Lists the items in a pilot weapon set.
Definition: pilot_weapon.c:731
int pilot_outfitOn(Pilot *p, PilotOutfitSlot *o)
Enable a given active outfit.
void pilot_weaponAuto(Pilot *p)
Tries to automatically set and create the pilot's weapon set.
const char * pilot_weapSetName(Pilot *p, int id)
Gets the name of a weapon set.
Definition: pilot_weapon.c:381
int pilot_outfitOff(Pilot *p, PilotOutfitSlot *o)
Disables a given active outfit.
void player_hailStart(void)
Starts the hail sounds and aborts autoNav.
Definition: player.c:1881
void player_targetSet(unsigned int id)
Sets the player's target.
Definition: player.c:2112
Player_t player
Definition: player.c:73
void player_autonavAbort(const char *reason)
Aborts autonav.
static const double c[]
Definition: rng.c:264
static const double a[]
Definition: rng.c:247
static const double d[]
Definition: rng.c:273
static const double b[]
Definition: rng.c:256
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:967
int ss_statsInit(ShipStats *stats)
Initializes a stat structure.
Definition: shipstats.c:347
int ss_statsSet(ShipStats *s, const char *name, double value, int overwrite)
Sets a ship stat by name.
Definition: shipstats.c:819
StarSystem * system_getIndex(int id)
Get the system by its index.
Definition: space.c:944
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:495
StarSystem * cur_system
Definition: space.c:105
int space_spawn
Definition: space.c:116
Represents a single asteroid.
Definition: asteroid.h:76
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:111
int type
Definition: outfit.h:112
double disable
Definition: outfit.h:115
double penetration
Definition: outfit.h:113
double damage
Definition: outfit.h:114
Pilot ship effect data.
Definition: effect.h:13
double duration
Definition: effect.h:18
char * name
Definition: effect.h:14
glTexture * icon
Definition: effect.h:21
Pilot ship effect.
Definition: effect.h:41
const EffectData * data
Definition: effect.h:42
double timer
Definition: effect.h:44
Stores an escort.
Definition: pilot.h:199
unsigned int id
Definition: pilot.h:202
EscortType_t type
Definition: pilot.h:201
Wrapper to canvass.
Definition: nlua_canvas.h:19
GLuint fbo
Definition: nlua_canvas.h:20
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:158
double trackmin
Definition: outfit.h:130
double trackmax
Definition: outfit.h:131
A ship outfit, depends radically on the type.
Definition: outfit.h:304
OutfitLauncherData lau
Definition: outfit.h:373
OutfitBeamData bem
Definition: outfit.h:372
OutfitBoltData blt
Definition: outfit.h:371
OutfitType type
Definition: outfit.h:369
OutfitAfterburnerData afb
Definition: outfit.h:375
nlua_env lua_env
Definition: outfit.h:342
union Outfit::@22 u
char * name
Definition: outfit.h:305
Stores a pilot commodity.
Definition: pilot.h:172
const Commodity * commodity
Definition: pilot.h:173
unsigned int id
Definition: pilot.h:175
int quantity
Definition: pilot.h:174
int deployed
Definition: pilot.h:100
int quantity
Definition: pilot.h:99
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
The representation of an in-game pilot.
Definition: pilot.h:210
Solid * solid
Definition: pilot.h:220
unsigned int id
Definition: pilot.h:211
unsigned int parent
Definition: pilot.h:325
const Ship * ship
Definition: pilot.h:219
int faction
Definition: pilot.h:215
char * name
Definition: pilot.h:212
Escort_t * escorts
Definition: pilot.h:326
Pilot * p
Definition: player.h:101
const Outfit * data
Definition: ship.h:76
OutfitSlot slot
Definition: ship.h:71
Represents a space ship.
Definition: ship.h:94
char * name
Definition: ship.h:95
vec2 vel
Definition: physics.h:21
double dir
Definition: physics.h:19
double mass
Definition: physics.h:18
vec2 pos
Definition: physics.h:22
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Definition: space.h:88
double radius
Definition: space.h:94
char * name
Definition: space.h:90
vec2 pos
Definition: space.h:93
int id
Definition: space.h:89
Basic AI task.
Definition: ai.h:25
char * name
Definition: ai.h:27
struct Task_ * subtask
Definition: ai.h:31
int done
Definition: ai.h:29
int dat
Definition: ai.h:33
int rh
Definition: opengl.h:47
int rw
Definition: opengl.h:46
double w
Definition: opengl_tex.h:38
double h
Definition: opengl_tex.h:39
Contains a mission variable.
Definition: lvar.h:24
Small struct to handle flags.
Definition: nlua_pilot.c:4217
const char * name
Definition: nlua_pilot.c:4218
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:2161
void weapon_hitAI(Pilot *p, const Pilot *shooter, double dmg)
Informs the AI if needed that it's been hit.
Definition: weapon.c:1227