naev 0.10.4
pilot_outfit.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include "naev.h"
13#include "array.h"
14#include "escort.h"
15#include "gui.h"
16#include "log.h"
17#include "difficulty.h"
18#include "nstring.h"
19#include "nxml.h"
20#include "outfit.h"
21#include "pause.h"
22#include "pilot.h"
23#include "player.h"
24#include "slots.h"
25#include "space.h"
26#include "nlua.h"
27#include "nlua_pilot.h"
28#include "nlua_pilotoutfit.h"
29#include "nlua_outfit.h"
30
31/*
32 * Prototypes.
33 */
34static int pilot_hasOutfitLimit( const Pilot *p, const char *limit );
35static void pilot_calcStatsSlot( Pilot *pilot, PilotOutfitSlot *slot );
36
46void pilot_lockUpdateSlot( Pilot *p, PilotOutfitSlot *o, Pilot *t, double *a, double dt )
47{
48 double max, old;
49 double x,y, ang, arc;
50 int locked;
51
52 /* No target. */
53 if (t == NULL)
54 return;
55
56 /* Nota seeker. */
57 if (!outfit_isSeeker(o->outfit))
58 return;
59
60 /* Check arc. */
61 arc = o->outfit->u.lau.arc;
62 if (arc > 0.) {
63
64 /* We use an external variable to set and update the angle if necessary. */
65 if (*a < 0.) {
66 x = t->solid->pos.x - p->solid->pos.x;
67 y = t->solid->pos.y - p->solid->pos.y;
68 ang = ANGLE( x, y );
69 *a = FABS( angle_diff( ang, p->solid->dir ) );
70 }
71
72 /* Decay if not in arc. */
73 if (*a > arc) {
74 /* Limit decay to the lockon time for this launcher. */
75 max = o->outfit->u.lau.lockon;
76
77 /* When a lock is lost, immediately gain half the lock timer.
78 * This is meant as an incentive for the aggressor not to lose the lock,
79 * and for the target to try and break the lock. */
80 old = o->u.ammo.lockon_timer;
81 o->u.ammo.lockon_timer += dt;
82 if ((old <= 0.) && (o->u.ammo.lockon_timer > 0.))
83 o->u.ammo.lockon_timer += o->outfit->u.lau.lockon / 2.;
84
85 /* Cap at max. */
86 if (o->u.ammo.lockon_timer > max)
87 o->u.ammo.lockon_timer = max;
88
89 /* Out of arc. */
90 o->u.ammo.in_arc = 0;
91 return;
92 }
93 }
94
95 /* In arc. */
96 o->u.ammo.in_arc = 1;
97 locked = (o->u.ammo.lockon_timer < 0.);
98
99 /* Lower timer. When the timer reaches zero, the lock is established. */
100 max = -o->outfit->u.lau.lockon/3.;
101 if (o->u.ammo.lockon_timer > max) {
102 /* Targetting is linear and can't be faster than the time specified (can be slower though). */
103 double mod = pilot_ewWeaponTrack( p, t, o->outfit->u.lau.trackmin, o->outfit->u.lau.trackmax );
104 o->u.ammo.lockon_timer -= dt * mod / p->stats.launch_lockon;
105
106 /* Cap at -max/3. */
107 if (o->u.ammo.lockon_timer < max)
108 o->u.ammo.lockon_timer = max;
109
110 /* Trigger lockon hook. */
111 if (!locked && (o->u.ammo.lockon_timer < 0.))
112 pilot_runHook( p, PILOT_HOOK_LOCKON );
113 }
114}
115
122{
123 for (int i=0; i<array_size(p->outfits); i++) {
124 PilotOutfitSlot *o = p->outfits[i];
125 if (o->outfit == NULL)
126 continue;
127 if (!outfit_isSeeker(o->outfit))
128 continue;
129
130 /* Clear timer. */
131 o->u.ammo.lockon_timer = o->outfit->u.lau.lockon;
132
133 /* Clear arc. */
134 o->u.ammo.in_arc = 0;
135 }
136}
137
148int pilot_getMount( const Pilot *p, const PilotOutfitSlot *w, vec2 *v )
149{
150 double a, x, y;
151 double cm, sm;
152 const ShipMount *m;
153
154 /* Calculate the sprite angle. */
155 a = (double)(p->tsy * p->ship->gfx_space->sx + p->tsx);
156 a *= p->ship->mangle;
157
158 /* 2d rotation matrix
159 * [ x' ] [ cos sin ] [ x ]
160 * [ y' ] = [ -sin cos ] * [ y ]
161 *
162 * dir is inverted so that rotation is counter-clockwise.
163 */
164 m = &w->sslot->mount;
165 cm = cos(-a);
166 sm = sin(-a);
167 x = m->x * cm + m->y * sm;
168 y = m->x *-sm + m->y * cm;
169
170 /* Correction for ortho perspective. */
171 y *= M_SQRT1_2;
172
173 /* Don't forget to add height. */
174 y += m->h;
175
176 /* Get the mount and add the player.p offset. */
177 vec2_cset( v, x, y );
178
179 return 0;
180}
181
189int pilot_dock( Pilot *p, Pilot *target )
190{
191 int i;
192 PilotOutfitSlot* dockslot;
193
194 /* Must belong to target */
195 if (p->dockpilot != target->id)
196 return -1;
197
198 /* Must have a dockslot */
199 dockslot = pilot_getDockSlot( p );
200 if (dockslot == NULL)
201 return -1;
202
203 /* Must be close. */
204 if (vec2_dist(&p->solid->pos, &target->solid->pos) >
205 target->ship->gfx_space->sw * PILOT_SIZE_APPROX )
206 return -1;
207
208 /* Cannot be going much faster. */
209 if (vec2_dist2( &p->solid->vel, &target->solid->vel ) > pow2(MAX_HYPERSPACE_VEL))
210 return -1;
211
212 /* Grab dock ammo */
213 i = p->dockslot;
214
215 /* Try to add fighter. */
216 dockslot->u.ammo.deployed--;
217 p->dockpilot = 0;
218 p->dockslot = -1;
219
220 /* Add the pilot's outfit. */
221 if (pilot_addAmmo(target, target->outfits[i], 1) != 1)
222 return -1;
223
224 /* Remove from pilot's escort list. */
225 for (i=0; i<array_size(target->escorts); i++) {
226 if ((target->escorts[i].type == ESCORT_TYPE_BAY) &&
227 (target->escorts[i].id == p->id))
228 break;
229 }
230 /* Not found as pilot's escorts. */
231 if (i >= array_size(target->escorts))
232 return -1;
233 /* Free if last pilot. */
234 if (array_size(target->escorts) == 1)
235 escort_freeList(target);
236 else
237 escort_rmListIndex(target, i);
238
239 /* Destroy the pilot. */
240 pilot_delete(p);
241
242 return 0;
243}
244
252{
253 for (int i=0; i<array_size(p->outfits); i++) {
254 if (p->outfits[i]->outfit == NULL)
255 continue;
256 if (outfit_isFighterBay(p->outfits[i]->outfit))
257 if (p->outfits[i]->u.ammo.deployed > 0)
258 return 1;
259 }
260 return 0;
261}
262
273int pilot_addOutfitRaw( Pilot* pilot, const Outfit* outfit, PilotOutfitSlot *s )
274{
275 const Outfit *o;
276
277 /* Set the outfit. */
278 s->state = PILOT_OUTFIT_OFF;
279 s->outfit = outfit;
280
281 /* Set some default parameters. */
282 s->timer = 0.;
283
284 /* Some per-case scenarios. */
285 if (outfit_isFighterBay(outfit)) {
286 s->u.ammo.quantity = 0;
287 s->u.ammo.deployed = 0;
288 pilot->nfighterbays++;
289 }
290 else if (outfit_isTurret(outfit)) /* used to speed up AI */
291 pilot->nturrets++;
292 else if (outfit_isBolt(outfit))
293 pilot->ncannons++;
294 else if (outfit_isAfterburner(outfit))
295 pilot->nafterburners++;
296 if (outfit_isLauncher(outfit)) {
297 s->u.ammo.quantity = 0;
298 s->u.ammo.deployed = 0; /* Just in case. */
299 }
300
301 if (outfit_isBeam(outfit)) { /* Used to speed up some calculations. */
302 s->u.beamid = 0;
303 pilot->nbeams++;
304 }
305
306 /* Check if active. */
307 o = s->outfit;
308 s->active = outfit_isActive(o);
309
310 /* Update heat. */
312
313 /* Disable lua for now. */
314 s->lua_mem = LUA_NOREF;
315
316 /* Initialize if active thingy if necessary. */
317 pilot_outfitLAdd( pilot, s );
318
319 return 0;
320}
321
331int pilot_addOutfitTest( Pilot* pilot, const Outfit* outfit, PilotOutfitSlot *s, int warn )
332{
333 const char *str;
334
335 /* See if slot has space. */
336 if (s->outfit != NULL) {
337 if (warn)
338 WARN( _("Pilot '%s': trying to add outfit '%s' to slot that already has an outfit"),
339 pilot->name, outfit->name );
340 return -1;
341 }
342 else if ((outfit_cpu(outfit) < 0) &&
343 (pilot->cpu < ABS( outfit_cpu(outfit) ))) {
344 if (warn)
345 WARN( _("Pilot '%s': Not enough CPU to add outfit '%s'"),
346 pilot->name, outfit->name );
347 return -1;
348 }
349 else if ((str = pilot_canEquip( pilot, s, outfit)) != NULL) {
350 if (warn)
351 WARN( _("Pilot '%s': Trying to add outfit but %s"),
352 pilot->name, str );
353 return -1;
354 }
355 return 0;
356}
357
366int pilot_addOutfit( Pilot* pilot, const Outfit* outfit, PilotOutfitSlot *s )
367{
368 /* Test to see if outfit can be added. */
369 int ret = pilot_addOutfitTest( pilot, outfit, s, 1 );
370 if (ret != 0)
371 return -1;
372
373 /* Add outfit. */
374 ret = pilot_addOutfitRaw( pilot, outfit, s );
375
376 /* Recalculate the stats */
377 pilot_calcStats(pilot);
378
379 return ret;
380}
381
385int pilot_addOutfitIntrinsic( Pilot *pilot, const Outfit *outfit )
386{
388 int ret;
389
390 if (!outfit_isMod(outfit)) {
391 WARN(_("Instrinsic outfits must be modifiers!"));
392 return -1;
393 }
394
395 if (pilot->outfit_intrinsic==NULL)
397
398 s = &array_grow( &pilot->outfit_intrinsic );
399 ret = pilot_addOutfitRaw( pilot, outfit, s );
400 if (pilot->id > 0 && ret==0)
401 pilot_outfitLInit( pilot, s );
402 return ret;
403}
404
409{
410 int ret = pilot_rmOutfitRaw( pilot, s );
411 array_erase( &pilot->outfit_intrinsic, s, s+1 );
412 return ret;
413}
414
425{
426 int ret;
427
428 /* Force turn off if necessary. */
429 if (s->state==PILOT_OUTFIT_ON)
430 pilot_outfitOff( pilot, s );
431
432 /* Run remove hook if necessary. */
433 pilot_outfitLRemove( pilot, s );
434
435 /* Decrement counters if necessary. */
436 if (s->outfit != NULL) {
437 if (outfit_isTurret(s->outfit))
438 pilot->nturrets--;
439 else if (outfit_isBolt(s->outfit))
440 pilot->ncannons--;
441 else if (outfit_isAfterburner(s->outfit))
442 pilot->nafterburners--;
443 else if (outfit_isFighterBay(s->outfit))
444 pilot->nfighterbays--;
445 if (outfit_isBeam(s->outfit))
446 pilot->nbeams--;
447 }
448
449 /* Remove the outfit. */
450 ret = (s->outfit==NULL);
451 s->outfit = NULL;
452 s->weapset = -1;
453
454 /* Remove secondary and such if necessary. */
455 if (pilot->afterburner == s)
456 pilot->afterburner = NULL;
457
458 /* Clear Lua if necessary. */
459 if (s->lua_mem != LUA_NOREF) {
460 luaL_unref( naevL, LUA_REGISTRYINDEX, s->lua_mem );
461 s->lua_mem = LUA_NOREF;
462 }
463
464 return ret;
465}
466
467
476{
477 int ret;
478 const char *str = pilot_canEquip( pilot, s, NULL );
479 if (str != NULL) {
480 WARN(_("Pilot '%s': Trying to remove outfit but %s"),
481 pilot->name, str );
482 return -1;
483 }
484
485 ret = pilot_rmOutfitRaw( pilot, s );
486
487 /* recalculate the stats */
488 pilot_calcStats(pilot);
489
490 return ret;
491}
492
500{
501 for (int i=0; i<array_size(p->outfits); i++)
502 if ((p->outfits[i]->outfit != NULL) &&
503 !outfit_fitsSlot( p->outfits[i]->outfit, &p->outfits[i]->sslot->slot ))
504 return 0;
505 return 1;
506}
507
515{
516 for (int i=0; i<array_size(p->outfits); i++)
517 if (p->outfits[i]->sslot->required && p->outfits[i]->outfit == NULL)
518 return 0;
519 return 1;
520}
521
529{
530 return !pilot_reportSpaceworthy( p, NULL, 0 );
531}
532
541int pilot_reportSpaceworthy( const Pilot *p, char *buf, int bufSize )
542{
543#define SPACEWORTHY_CHECK(cond,msg) \
544 if (cond) { ret++; \
545 if (buf != NULL) { \
546 if (pos > 0) \
547 pos += scnprintf( &buf[pos], bufSize-pos, "\n" ); \
548 pos += scnprintf( &buf[pos], bufSize-pos, (msg) ); } }
549 int pos = 0;
550 int ret = 0;
551
552 /* Core Slots */
553 SPACEWORTHY_CHECK( !pilot_slotsCheckRequired(p), _("!! Not All Core Slots are equipped") );
554 /* CPU. */
555 SPACEWORTHY_CHECK( p->cpu < 0, _("!! Insufficient CPU") );
556
557 /* Movement. */
558 SPACEWORTHY_CHECK( p->thrust < 0, _("!! Insufficient Thrust") );
559 SPACEWORTHY_CHECK( p->speed < 0, _("!! Insufficient Speed") );
560 SPACEWORTHY_CHECK( p->turn < 0, _("!! Insufficient Turn") );
561
562 /* Health. */
563 SPACEWORTHY_CHECK( p->armour < 0., _("!! Insufficient Armour") );
564 SPACEWORTHY_CHECK( p->armour_regen < 0., _("!! Insufficient Armour Regeneration") );
565 SPACEWORTHY_CHECK( p->shield < 0., _("!! Insufficient Shield") );
566 SPACEWORTHY_CHECK( p->shield_regen < 0., _("!! Insufficient Shield Regeneration") );
567 SPACEWORTHY_CHECK( p->energy_max < 0., _("!! Insufficient Energy") );
568 SPACEWORTHY_CHECK( (p->energy_regen <= 0.) && (p->energy_max > 0.), _("!! Insufficient Energy Regeneration") );
569
570 /* Misc. */
571 SPACEWORTHY_CHECK( p->fuel_max < 0, _("!! Insufficient Fuel Maximum") );
572 SPACEWORTHY_CHECK( p->fuel_consumption < 0, _("!! Insufficient Fuel Consumption") );
573 SPACEWORTHY_CHECK( p->cargo_free < 0, _("!! Insufficient Free Cargo Space") );
574 SPACEWORTHY_CHECK( p->crew < 0, _("!! Insufficient Crew") );
575
576 /* No need to mess with the string. */
577 if (buf==NULL)
578 return ret;
579
580 /* Buffer is full, lets write that there is more then what's copied */
581 if (pos > bufSize-1) {
582 buf[bufSize-4]='.';
583 buf[bufSize-3]='.';
584 buf[bufSize-2]='.';
585 /* buf[bufSize-1]='\0'; already done for us */
586 }
587 else if (pos == 0) {
588 /* String is empty so no errors encountered */
589 pos += scnprintf( buf, bufSize, _("Spaceworthy"));
590 if (ship_isFlag(p->ship, SHIP_NOPLAYER))
591 pos += scnprintf( &buf[pos], bufSize-pos, "\n#o%s#0", _("Escort only") );
592 if (ship_isFlag(p->ship, SHIP_NOESCORT))
593 pos += scnprintf( &buf[pos], bufSize-pos, "\n#o%s#0", _("Lead ship only") );
594 }
595
596 return ret;
597}
598#undef SPACEWORTHY_CHECK
599
607static int pilot_hasOutfitLimit( const Pilot *p, const char *limit )
608{
609 for (int i = 0; i<array_size(p->outfits); i++) {
610 const Outfit *o = p->outfits[i]->outfit;
611 if (o == NULL)
612 continue;
613 if ((o->limit != NULL) && (strcmp(o->limit,limit)==0))
614 return 1;
615 }
616 return 0;
617}
618
627const char* pilot_canEquip( const Pilot *p, const PilotOutfitSlot *s, const Outfit *o )
628{
629 /* Just in case. */
630 if ((p==NULL) || (s==NULL))
631 return _("Nothing selected.");
632
633 if (o!=NULL) {
634 /* Check slot type. */
635 if (!outfit_fitsSlot( o, &s->sslot->slot ))
636 return _("Does not fit slot.");
637 /* Check outfit limit. */
638 if ((o->limit != NULL) && pilot_hasOutfitLimit( p, o->limit ))
639 return _("Already have an outfit of this type installed");
640 /* Check to see if already equipped unique. */
641 if (outfit_isProp(o,OUTFIT_PROP_UNIQUE) && (pilot_numOutfit(p,o)>0))
642 return _("Can only install unique outfit once.");
643 }
644 else {
645 /* Check fighter bay. */
646 if ((o==NULL) && (s!=NULL) && (s->u.ammo.deployed > 0))
647 return _("Recall the fighters first");
648 }
649
650 return NULL;
651}
652
661int pilot_addAmmo( Pilot* pilot, PilotOutfitSlot *s, int quantity )
662{
663 int q, max;
664
665 /* Failure cases. */
666 if (s->outfit == NULL) {
667 WARN(_("Pilot '%s': Trying to add ammo to unequipped slot."), pilot->name );
668 return 0;
669 }
671 return 0;
672
673 /* Add the ammo. */
674 max = pilot_maxAmmoO(pilot,s->outfit) - s->u.ammo.deployed;
675 q = s->u.ammo.quantity; /* Amount have. */
676 s->u.ammo.quantity += quantity;
677 s->u.ammo.quantity = MIN( max, s->u.ammo.quantity );
678 q = s->u.ammo.quantity - q; /* Amount actually added. */
679 pilot->mass_outfit += q * outfit_ammoMass( s->outfit );
680 pilot_updateMass( pilot );
681
682 return q;
683}
684
693int pilot_rmAmmo( Pilot* pilot, PilotOutfitSlot *s, int quantity )
694{
695 int q;
696
697 /* Failure cases. */
699 return 0;
700 else if (s->outfit == NULL) {
701 WARN(_("Pilot '%s': Trying to remove ammo from unequipped slot."), pilot->name );
702 return 0;
703 }
704
705 /* Remove ammo. */
706 q = MIN( quantity, s->u.ammo.quantity );
707 s->u.ammo.quantity -= q;
708 pilot->mass_outfit -= q * outfit_ammoMass( s->outfit );
709 pilot_updateMass( pilot );
710 /* We don't set the outfit to null so it "remembers" old ammo. */
711
712 return q;
713}
714
721int pilot_countAmmo( const Pilot *pilot )
722{
723 int nammo = 0;
724 for (int i=0; i<array_size(pilot->outfits); i++) {
725 const Outfit* outfit;
726 PilotOutfitSlot* po = pilot->outfits[i];
727 if (po == NULL)
728 continue;
729 outfit = po->outfit;
730 if (outfit == NULL)
731 continue;
732 if (!outfit_isLauncher(po->outfit))
733 continue;
734 nammo += po->u.ammo.quantity;
735 }
736 return nammo;
737}
738
745int pilot_maxAmmo( const Pilot *pilot )
746{
747 int max = 0;
748 for (int i=0; i<array_size(pilot->outfits); i++) {
749 const Outfit* outfit;
750 PilotOutfitSlot* po = pilot->outfits[i];
751 if (po == NULL)
752 continue;
753 outfit = po->outfit;
754 if (outfit == NULL)
755 continue;
756 if (!outfit_isLauncher(outfit))
757 continue;
758 max += outfit->u.lau.amount;
759 }
760 max = round( (double)max * pilot->stats.ammo_capacity );
761 return max;
762}
763
767int pilot_maxAmmoO( const Pilot *p, const Outfit *o )
768{
769 int max;
770 if (o==NULL)
771 return 0;
772 else if (outfit_isLauncher(o))
773 max = round( (double)o->u.lau.amount * p->stats.ammo_capacity );
774 else if (outfit_isFighterBay(o))
775 max = round( (double)o->u.bay.amount * p->stats.fbay_capacity );
776 else
777 max = 0;
778 return max;
779}
780
786void pilot_fillAmmo( Pilot* pilot )
787{
788 for (int i=0; i<array_size(pilot->outfits); i++) {
789 int ammo_threshold;
790 const Outfit *o = pilot->outfits[i]->outfit;
791
792 /* Must be valid outfit. */
793 if (o == NULL)
794 continue;
795
796 /* Initial (raw) ammo threshold */
797 ammo_threshold = pilot_maxAmmoO( pilot, o );
798
799 /* Adjust for deployed fighters if needed */
800 if (outfit_isFighterBay( o ))
801 ammo_threshold -= pilot->outfits[i]->u.ammo.deployed;
802
803 /* Add ammo. */
804 pilot_addAmmo( pilot, pilot->outfits[i],
805 ammo_threshold - pilot->outfits[i]->u.ammo.quantity );
806 }
807}
808
812static void pilot_calcStatsSlot( Pilot *pilot, PilotOutfitSlot *slot )
813{
814 const Outfit *o = slot->outfit;
815 ShipStats *s = &pilot->stats;
816
817 /* Outfit must exist. */
818 if (o==NULL)
819 return;
820
821 /* Modify CPU. */
822 pilot->cpu += outfit_cpu(o);
823
824 /* Add mass. */
825 pilot->mass_outfit += o->mass;
826
827 /* Keep a separate counter for required (core) outfits. */
828 if (sp_required( o->slot.spid ))
829 pilot->base_mass += o->mass;
830
831 /* Add ammo mass. */
832 if (outfit_isLauncher(o))
833 pilot->mass_outfit += slot->u.ammo.quantity * o->u.lau.ammo_mass;
834 else if (outfit_isFighterBay(o))
835 pilot->mass_outfit += slot->u.ammo.quantity * o->u.bay.ship_mass;
836
837 if (outfit_isAfterburner(o)) /* Afterburner */
838 pilot->afterburner = slot; /* Set afterburner */
839
840 /* Lua mods apply their stats. */
841 if (slot->lua_mem != LUA_NOREF)
842 ss_statsMerge( &pilot->stats, &slot->lua_stats );
843
844 /* Has update function. */
845 if (o->lua_update != LUA_NOREF)
846 pilot->outfitlupdate = 1;
847
848 /* Apply modifications. */
849 if (outfit_isMod(o)) { /* Modification */
850 /* Active outfits must be on to affect stuff. */
851 if (slot->active && !(slot->state==PILOT_OUTFIT_ON))
852 return;
853 /* Add stats. */
854 ss_statsModFromList( s, o->stats );
855
856 }
857 else if (outfit_isAfterburner(o)) { /* Afterburner */
858 /* Active outfits must be on to affect stuff. */
859 if (slot->active && !(slot->state==PILOT_OUTFIT_ON))
860 return;
861 /* Add stats. */
862 ss_statsModFromList( s, o->stats );
863 pilot_setFlag( pilot, PILOT_AFTERBURNER ); /* We use old school flags for this still... */
864 pilot->energy_loss += pilot->afterburner->outfit->u.afb.energy; /* energy loss */
865 }
866 else {
867 /* Always add stats for non mod/afterburners. */
868 ss_statsModFromList( s, o->stats );
869 }
870}
871
877void pilot_calcStats( Pilot* pilot )
878{
879 double ac, sc, ec, tm; /* temporary health coefficients to set */
880 ShipStats *s;
881
882 /*
883 * Set up the basic stuff
884 */
885 /* mass */
886 pilot->solid->mass = pilot->ship->mass;
887 pilot->base_mass = pilot->solid->mass;
888 /* cpu */
889 pilot->cpu = 0.;
890 /* movement */
891 pilot->thrust_base = pilot->ship->thrust;
892 pilot->turn_base = pilot->ship->turn;
893 pilot->speed_base = pilot->ship->speed;
894 /* crew */
895 pilot->crew = pilot->ship->crew;
896 /* cargo */
897 pilot->cap_cargo = pilot->ship->cap_cargo;
898 /* fuel_consumption. */
899 pilot->fuel_consumption = pilot->ship->fuel_consumption;
900 /* health */
901 ac = (pilot->armour_max > 0.) ? pilot->armour / pilot->armour_max : 0.;
902 sc = (pilot->shield_max > 0.) ? pilot->shield / pilot->shield_max : 0.;
903 ec = (pilot->energy_max > 0.) ? pilot->energy / pilot->energy_max : 0.;
904 pilot->armour_max = pilot->ship->armour;
905 pilot->shield_max = pilot->ship->shield;
906 pilot->fuel_max = pilot->ship->fuel;
907 pilot->armour_regen = pilot->ship->armour_regen;
908 pilot->shield_regen = pilot->ship->shield_regen;
909 /* Absorption. */
910 pilot->dmg_absorb = pilot->ship->dmg_absorb;
911 /* Energy. */
912 pilot->energy_max = pilot->ship->energy;
913 pilot->energy_regen = pilot->ship->energy_regen;
914 pilot->energy_loss = 0.; /* Initially no net loss. */
915 /* Misc. */
916 pilot->outfitlupdate = 0;
917 /* Stats. */
918 s = &pilot->stats;
919 tm = s->time_mod;
920 *s = pilot->ship->stats_array;
921
922 /* Player gets difficulty applied. */
923 if (pilot_isPlayer(pilot))
924 difficulty_apply( s );
925
926 /* Now add outfit changes */
927 pilot->mass_outfit = 0.;
928 for (int i=0; i<array_size(pilot->outfit_intrinsic); i++)
929 pilot_calcStatsSlot( pilot, &pilot->outfit_intrinsic[i] );
930 for (int i=0; i<array_size(pilot->outfits); i++)
931 pilot_calcStatsSlot( pilot, pilot->outfits[i] );
932
933 /* Merge stats. */
934 ss_statsMerge( &pilot->stats, &pilot->intrinsic_stats );
935
936 /* Compute effects. */
937 effect_compute( &pilot->stats, pilot->effects );
938
939 /* Apply system effects. */
940 if (cur_system->stats != NULL)
941 ss_statsModFromList( &pilot->stats, cur_system->stats );
942
943 /* Apply stealth malus. */
944 if (pilot_isFlag(pilot, PILOT_STEALTH)) {
945 s->thrust_mod *= 0.8;
946 s->turn_mod *= 0.8;
947 s->speed_mod *= 0.5;
948 }
949
950 /*
951 * Absolute increases.
952 */
953 /* Movement. */
954 pilot->thrust_base += s->thrust;
955 pilot->turn_base += s->turn * M_PI / 180.;
956 pilot->speed_base += s->speed;
957 /* Health. */
958 pilot->armour_max += s->armour;
959 pilot->armour_regen += s->armour_regen;
960 pilot->shield_max += s->shield;
961 pilot->shield_regen += s->shield_regen;
962 pilot->energy_max += s->energy;
963 pilot->energy_regen += s->energy_regen;
964 /* Misc. */
965 pilot->fuel_max += s->fuel;
966 pilot->cap_cargo += s->cargo;
967
968 /*
969 * Relative increases.
970 */
971 /* Movement. */
972 pilot->thrust_base *= s->thrust_mod;
973 pilot->turn_base *= s->turn_mod;
974 pilot->speed_base *= s->speed_mod;
975 /* Health. */
976 pilot->armour_max *= s->armour_mod;
977 pilot->armour_regen *= s->armour_regen_mod;
978 pilot->shield_max *= s->shield_mod;
979 pilot->shield_regen *= s->shield_regen_mod;
980 pilot->energy_max *= s->energy_mod;
981 pilot->energy_regen *= s->energy_regen_mod;
982 /* Enforce health to be at least 0 after mods, so that something like -1000% would just set it to 0 instead of negative. */
983 pilot->armour_regen = MAX( 0., pilot->armour_regen );
984 pilot->shield_regen = MAX( 0., pilot->shield_regen );
985 pilot->energy_regen = MAX( 0., pilot->energy_regen );
986 /* cpu */
987 pilot->cpu_max = (int)floor((float)(pilot->ship->cpu + s->cpu_max)*s->cpu_mod);
988 pilot->cpu += pilot->cpu_max; /* CPU is negative, this just sets it so it's based off of cpu_max. */
989 /* Misc. */
990 pilot->crew = pilot->crew * s->crew_mod + s->crew;
991 pilot->fuel_max *= s->fuel_mod;
992 pilot->cap_cargo *= s->cargo_mod;
994
995 /* Set maximum speed. */
996 if (!pilot_isFlag( pilot, PILOT_AFTERBURNER ))
997 pilot->solid->speed_max = pilot->speed_base;
998
999 /*
1000 * Flat increases.
1001 */
1002 pilot->armour_regen -= s->armour_regen_malus;
1003 pilot->shield_regen -= s->shield_regen_malus;
1004 pilot->energy_regen -= s->energy_regen_malus;
1005 pilot->energy_loss += s->energy_loss;
1006 pilot->dmg_absorb = CLAMP( 0., 1., pilot->dmg_absorb + s->absorb );
1007
1008 /* Give the pilot his health proportion back */
1009 pilot->armour = ac * pilot->armour_max;
1010 pilot->shield = sc * pilot->shield_max;
1011 pilot->energy = ec * pilot->energy_max;
1012
1013 /* Dump excess fuel */
1014 pilot->fuel = MIN( pilot->fuel, pilot->fuel_max );
1015
1016 /* Set final energy tau. */
1017 pilot->energy_tau = pilot->energy_max / pilot->energy_regen;
1018
1019 /* Cargo has to be reset. */
1020 pilot_cargoCalc(pilot);
1021
1022 /* Calculate mass. */
1023 pilot->solid->mass = MAX( s->mass_mod*pilot->ship->mass + pilot->stats.cargo_inertia*pilot->mass_cargo + pilot->mass_outfit, 0.);
1024
1025 /* Calculate the heat. */
1026 pilot_heatCalc( pilot );
1027
1028 /* Modulate by mass. */
1029 pilot_updateMass( pilot );
1030
1031 /* Update GUI as necessary. */
1032 gui_setGeneric( pilot );
1033
1034 /* Update weapon set range. */
1035 pilot_weapSetUpdateStats( pilot );
1036
1037 /* In case the time_mod has changed. */
1038 if (pilot_isPlayer(pilot) && (tm != s->time_mod))
1040}
1041
1046{
1047 pilot->armour = pilot->armour_max;
1048 pilot->shield = pilot->shield_max;
1049 pilot->energy = pilot->energy_max;
1050
1051 pilot->stress = 0.;
1052 pilot->stimer = 0.;
1053 pilot->sbonus = 0.;
1054
1055 pilot_fillAmmo( pilot );
1056
1057 for (int i=0; i<array_size(pilot->escorts); i++) {
1058 Escort_t *e = &pilot->escorts[i];
1059 Pilot *pe = pilot_get( e->id );
1060
1061 if (pe != NULL)
1062 pilot_healLanded( pe );
1063 }
1064}
1065
1069PilotOutfitSlot *pilot_getSlotByName( Pilot *pilot, const char *name )
1070{
1071 for (int i=0; i<array_size(pilot->outfits); i++) {
1072 PilotOutfitSlot *s = pilot->outfits[i];
1073 if ((s->sslot->name!=NULL) && (strcmp(s->sslot->name,name)==0))
1074 return s;
1075 }
1076 return NULL;
1077}
1078
1085{
1086 double mass, factor;
1087
1088 /* Set limit. */
1089 mass = pilot->solid->mass;
1090 if ((pilot->stats.engine_limit > 0.) && (mass > pilot->stats.engine_limit))
1091 factor = pilot->stats.engine_limit / mass;
1092 else
1093 factor = 1.;
1094
1095 pilot->thrust = factor * pilot->thrust_base * mass;
1096 pilot->turn = factor * pilot->turn_base;
1097 pilot->speed = factor * pilot->speed_base;
1098
1099/* limit the maximum speed if limiter is active */
1100 if (pilot_isFlag(pilot, PILOT_HASSPEEDLIMIT)) {
1101 pilot->speed = pilot->speed_limit - pilot->thrust / (mass * 3.);
1102 /* Speed must never go negative. */
1103 if (pilot->speed < 0.) {
1104 /* If speed DOES go negative, we have to lower thrust. */
1105 pilot->thrust = 3 * pilot->speed_limit * mass;
1106 pilot->speed = 0.;
1107 }
1108 }
1109 /* Need to recalculate electronic warfare mass change. */
1110 pilot_ewUpdateStatic( pilot );
1111}
1112
1120{
1121 const Outfit *oo;
1122 if (!o->active)
1123 return 0;
1124
1125 oo = o->outfit;
1126 if (oo == NULL)
1127 return 0;
1128 if (!outfit_isToggleable(oo))
1129 return 0;
1130
1131 return 1;
1132}
1133
1137static void pilot_outfitLRun( Pilot *p, void (*const func)( const Pilot *p, PilotOutfitSlot *po, const void *data ), const void *data )
1138{
1139 pilotoutfit_modified = 0;
1140 for (int i=0; i<array_size(p->outfits); i++) {
1141 PilotOutfitSlot *po = p->outfits[i];
1142 if (po->outfit==NULL)
1143 continue;
1144 func( p, po, data );
1145 }
1146 for (int i=0; i<array_size(p->outfit_intrinsic); i++) {
1147 PilotOutfitSlot *po = &p->outfit_intrinsic[i];
1148 if (po->outfit==NULL)
1149 continue;
1150 func( p, po, data );
1151 }
1152 /* Recalculate if anything changed. */
1153 if (pilotoutfit_modified)
1154 pilot_calcStats( p );
1155}
1156static void outfitLRunWarning( const Pilot *p, const Outfit *o, const char *name, const char *error )
1157{
1158 WARN( _("Pilot '%s''s outfit '%s' -> '%s':\n%s"), p->name, o->name, name, error );
1159}
1160
1164static void pilot_outfitLmem( PilotOutfitSlot *po, nlua_env env )
1165{
1166 /* Create the memory if necessary and initialize stats. */
1167 if (po->lua_mem == LUA_NOREF) {
1168 ss_statsInit( &po->lua_stats );
1169 lua_newtable(naevL); /* mem */
1170 po->lua_mem = luaL_ref(naevL,LUA_REGISTRYINDEX); /* */
1171 }
1172 /* Set the memory. */
1173 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1174 nlua_setenv( naevL, env, "mem" ); /* */
1175}
1176
1177static const char* pilot_outfitLDescExtra( const Pilot *p, const Outfit *o )
1178{
1179 static char descextra[STRMAX];
1180 const char *de;
1181 if (o->lua_descextra == LUA_NOREF)
1182 return o->desc_extra;
1183
1184 /* Set up the function: init( p, po ) */
1185 lua_rawgeti(naevL, LUA_REGISTRYINDEX, o->lua_descextra); /* f */
1186 if (p != NULL)
1187 lua_pushpilot( naevL, p->id ); /* f, p */
1188 else
1189 lua_pushnil( naevL ); /* f, p */
1190 lua_pushoutfit( naevL, o ); /* f, p, o */
1191 if (nlua_pcall( o->lua_env, 2, 1 )) { /* */
1192 outfitLRunWarning( p, o, "descextra", lua_tostring(naevL,-1) );
1193 lua_pop(naevL, 1);
1194 descextra[0] = '\0';
1195 return descextra;
1196 }
1197 de = luaL_checkstring( naevL, -1 );
1198 strncpy( descextra, de, sizeof(descextra)-1 );
1199 lua_pop( naevL, 1 );
1200 return descextra;
1201}
1202
1212const char* pilot_outfitDescription( const Pilot *p, const Outfit *o )
1213{
1214 static char o_description[STRMAX];
1215 const char *de = pilot_outfitLDescExtra( p, o );
1216 if (de == NULL)
1217 return _(o->desc_raw);
1218 snprintf( o_description, sizeof(o_description), "%s\n%s", _(o->desc_raw), de );
1219 return o_description;
1220
1221}
1222
1233const char* pilot_outfitSummary( const Pilot *p, const Outfit *o, int withname )
1234{
1235 static char o_summary[STRMAX];
1236 const char *de = pilot_outfitLDescExtra( p, o );
1237 if (de == NULL) {
1238 if (withname)
1239 snprintf( o_summary, sizeof(o_summary), "%s\n%s", _(o->name), o->summary_raw );
1240 else
1241 snprintf( o_summary, sizeof(o_summary), "%s", o->summary_raw );
1242 }
1243 else {
1244 if (withname)
1245 snprintf( o_summary, sizeof(o_summary), "%s\n%s\n%s", _(o->name), o->summary_raw, de );
1246 else
1247 snprintf( o_summary, sizeof(o_summary), "%s\n%s", o->summary_raw, de );
1248 }
1249 return o_summary;
1250}
1251
1258{
1259 pilotoutfit_modified = 0;
1260 for (int i=0; i<array_size(pilot->outfits); i++)
1261 pilot_outfitLInit( pilot, pilot->outfits[i] );
1262 for (int i=0; i<array_size(pilot->outfit_intrinsic); i++)
1263 pilot_outfitLInit( pilot, &pilot->outfit_intrinsic[i] );
1264 /* Recalculate if anything changed. */
1265 if (pilotoutfit_modified)
1266 pilot_calcStats( pilot );
1267}
1268
1273{
1274 if (po->outfit==NULL)
1275 return 0;
1276 if (po->outfit->lua_onadd == LUA_NOREF)
1277 return 0;
1278
1279 /* Create the memory if necessary and initialize stats. */
1280 pilot_outfitLmem( po, po->outfit->lua_env );
1281
1282 /* Set up the function: init( p, po ) */
1283 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_onadd); /* f */
1284 lua_pushpilot(naevL, pilot->id); /* f, p */
1285 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1286 if (nlua_pcall( po->outfit->lua_env, 2, 0 )) { /* */
1287 outfitLRunWarning( pilot, po->outfit, "onadd", lua_tostring(naevL,-1) );
1288 lua_pop(naevL, 1);
1289 return -1;
1290 }
1291 return 1;
1292}
1293
1298{
1299 if (po->outfit==NULL)
1300 return 0;
1301 if (po->outfit->lua_onremove == LUA_NOREF)
1302 return 0;
1303
1304 /* Create the memory if necessary and initialize stats. */
1305 pilot_outfitLmem( po, po->outfit->lua_env );
1306
1307 /* Set up the function: init( p, po ) */
1308 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_onremove); /* f */
1309 lua_pushpilot(naevL, pilot->id); /* f, p */
1310 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1311 if (nlua_pcall( po->outfit->lua_env, 2, 0 )) { /* */
1312 outfitLRunWarning( pilot, po->outfit, "onremove", lua_tostring(naevL,-1) );
1313 lua_pop(naevL, 1);
1314 return -1;
1315 }
1316 return 1;
1317}
1318
1327{
1328 int lua_init;
1329 nlua_env lua_env;
1330
1331 if (po->outfit==NULL)
1332 return 0;
1333
1334 if (po->outfit->lua_env==LUA_NOREF)
1335 return 0;
1336
1337 lua_init = po->outfit->lua_init;
1338 lua_env = po->outfit->lua_env;
1339
1340 /* Create the memory if necessary and initialize stats. */
1341 pilot_outfitLmem( po, lua_env );
1342
1343 if (lua_init == LUA_NOREF)
1344 return 0;
1345
1346 /* Set up the function: init( p, po ) */
1347 lua_rawgeti(naevL, LUA_REGISTRYINDEX, lua_init); /* f */
1348 lua_pushpilot(naevL, pilot->id); /* f, p */
1349 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1350 if (nlua_pcall( lua_env, 2, 0 )) { /* */
1351 outfitLRunWarning( pilot, po->outfit, "init", lua_tostring(naevL,-1) );
1352 lua_pop(naevL, 1);
1353 return -1;
1354 }
1355 return 1;
1356}
1357
1358static void outfitLUpdate( const Pilot *pilot, PilotOutfitSlot *po, const void *data )
1359{
1360 double dt;
1361 if (po->outfit->lua_update == LUA_NOREF)
1362 return;
1363
1364 nlua_env env = po->outfit->lua_env;
1365
1366 /* The data. */
1367 dt = *(double*)data;
1368
1369 /* Set the memory. */
1370 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1371 nlua_setenv(naevL, env, "mem"); /* */
1372
1373 /* Set up the function: update( p, po, dt ) */
1374 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_update); /* f */
1375 lua_pushpilot(naevL, pilot->id); /* f, p */
1376 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1377 lua_pushnumber(naevL, dt); /* f, p, po, dt */
1378 if (nlua_pcall( env, 3, 0 )) { /* */
1379 outfitLRunWarning( pilot, po->outfit, "update", lua_tostring(naevL,-1) );
1380 lua_pop(naevL, 1);
1381 }
1382}
1389void pilot_outfitLUpdate( Pilot *pilot, double dt )
1390{
1391 if (!pilot->outfitlupdate)
1392 return;
1393 pilot_outfitLRun( pilot, outfitLUpdate, &dt );
1394}
1395
1396static void outfitLOutofenergy( const Pilot *pilot, PilotOutfitSlot *po, const void *data )
1397{
1398 (void) data;
1399 if (po->outfit->lua_outofenergy == LUA_NOREF)
1400 return;
1401
1402 nlua_env env = po->outfit->lua_env;
1403
1404 /* Set the memory. */
1405 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1406 nlua_setenv(naevL, env, "mem"); /* */
1407
1408 /* Set up the function: outofenergy( p, po ) */
1409 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_outofenergy); /* f */
1410 lua_pushpilot(naevL, pilot->id); /* f, p */
1411 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1412 if (nlua_pcall( env, 2, 0 )) { /* */
1413 outfitLRunWarning( pilot, po->outfit, "outofenergy", lua_tostring(naevL,-1) );
1414 lua_pop(naevL, 1);
1415 }
1416}
1423{
1424 pilot_outfitLRun( pilot, outfitLOutofenergy, NULL );
1425}
1426
1428 double armour;
1429 double shield;
1430 unsigned int attacker;
1431};
1432static void outfitLOnhit( const Pilot *pilot, PilotOutfitSlot *po, const void *data )
1433{
1434 double armour, shield;
1435 unsigned int attacker;
1436 const struct OnhitData *odat;
1437
1438 if (po->outfit->lua_onhit == LUA_NOREF)
1439 return;
1440
1441 nlua_env env = po->outfit->lua_env;
1442
1443 /* Data. */
1444 odat = (const struct OnhitData*)data;
1445 armour = odat->armour;
1446 shield = odat->shield;
1447 attacker = odat->attacker;
1448
1449 /* Set the memory. */
1450 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1451 nlua_setenv(naevL, env, "mem"); /* */
1452
1453 /* Set up the function: onhit( p, po, armour, shield ) */
1454 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_onhit); /* f */
1455 lua_pushpilot(naevL, pilot->id); /* f, p */
1456 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1457 lua_pushnumber(naevL, armour ); /* f, p, po, a */
1458 lua_pushnumber(naevL, shield ); /* f, p, po, a, s */
1459 lua_pushpilot(naevL, attacker); /* f, p, po, a, s, attacker */
1460 if (nlua_pcall( env, 5, 0 )) { /* */
1461 outfitLRunWarning( pilot, po->outfit, "onhit", lua_tostring(naevL,-1) );
1462 lua_pop(naevL, 1);
1463 }
1464}
1473void pilot_outfitLOnhit( Pilot *pilot, double armour, double shield, unsigned int attacker )
1474{
1475 const struct OnhitData data = { .armour = armour, .shield = shield, .attacker = attacker };
1476 pilot_outfitLRun( pilot, outfitLOnhit, &data );
1477}
1478
1488{
1489 nlua_env env = po->outfit->lua_env;
1490 int ret;
1491 pilotoutfit_modified = 0;
1492
1493 /* Set the memory. */
1494 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1495 nlua_setenv(naevL, env, "mem"); /* */
1496
1497 /* Set up the function: ontoggle( p, po, armour, shield ) */
1498 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_ontoggle); /* f */
1499 lua_pushpilot(naevL, pilot->id); /* f, p */
1500 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1501 lua_pushboolean(naevL, on); /* f, p, po, on */
1502 if (nlua_pcall( env, 3, 1 )) { /* */
1503 outfitLRunWarning( pilot, po->outfit, "ontoggle", lua_tostring(naevL,-1) );
1504 lua_pop(naevL, 1);
1505 return 0;
1506 }
1507
1508 /* Handle return boolean. */
1509 ret = lua_toboolean(naevL, -1);
1510 lua_pop(naevL, 1);
1511 return ret || pilotoutfit_modified; /* Even if the script says it didn't change, it may have been modified. */
1512}
1513
1515 int done;
1516 int success;
1517 double timer;
1518};
1519static void outfitLCooldown( const Pilot *pilot, PilotOutfitSlot *po, const void *data )
1520{
1521 int done, success;
1522 double timer;
1523 const struct CooldownData *cdat;
1524
1525 if (po->outfit->lua_cooldown == LUA_NOREF)
1526 return;
1527
1528 nlua_env env = po->outfit->lua_env;
1529
1530 cdat = (const struct CooldownData*) data;
1531 done = cdat->done;
1532 success = cdat->success;
1533 timer = cdat->timer;
1534
1535 /* Set the memory. */
1536 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1537 nlua_setenv(naevL, env, "mem"); /* */
1538
1539 /* Set up the function: cooldown( p, po, done, success/timer ) */
1540 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_cooldown); /* f */
1541 lua_pushpilot(naevL, pilot->id); /* f, p */
1542 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1543 lua_pushboolean(naevL, done); /* f, p, po, done */
1544 if (done)
1545 lua_pushboolean(naevL, success); /* f, p, po, done, success */
1546 else
1547 lua_pushnumber(naevL, timer); /* f, p, po, done, timer */
1548 if (nlua_pcall( env, 4, 0 )) { /* */
1549 outfitLRunWarning( pilot, po->outfit, "cooldown", lua_tostring(naevL,-1) );
1550 lua_pop(naevL, 1);
1551 }
1552}
1561void pilot_outfitLCooldown( Pilot *pilot, int done, int success, double timer )
1562{
1563 const struct CooldownData data = { .done = done, .success = success, .timer = timer };
1564 pilot_outfitLRun( pilot, outfitLCooldown, &data );
1565}
1566
1567static void outfitLOnshoot( const Pilot *pilot, PilotOutfitSlot *po, const void *data )
1568{
1569 (void) data;
1570 if (po->outfit->lua_onshoot == LUA_NOREF)
1571 return;
1572
1573 nlua_env env = po->outfit->lua_env;
1574
1575 /* Set the memory. */
1576 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1577 nlua_setenv(naevL, env, "mem"); /* */
1578
1579 /* Set up the function: onshoot( p, po ) */
1580 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_onshoot); /* f */
1581 lua_pushpilot(naevL, pilot->id); /* f, p */
1582 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1583 if (nlua_pcall( env, 2, 0 )) { /* */
1584 outfitLRunWarning( pilot, po->outfit, "onshoot", lua_tostring(naevL,-1) );
1585 lua_pop(naevL, 1);
1586 }
1587}
1594{
1595 pilot_outfitLRun( pilot, outfitLOnshoot, NULL );
1596}
1597
1598static void outfitLOnstealth( const Pilot *pilot, PilotOutfitSlot *po, const void *data )
1599{
1600 (void) data;
1601 if (po->outfit->lua_onstealth == LUA_NOREF)
1602 return;
1603
1604 nlua_env env = po->outfit->lua_env;
1605
1606 /* Set the memory. */
1607 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1608 nlua_setenv(naevL, env, "mem"); /* */
1609
1610 /* Set up the function: onstealth( p, po, stealthed ) */
1611 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_onstealth); /* f */
1612 lua_pushpilot(naevL, pilot->id); /* f, p */
1613 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1614 lua_pushboolean(naevL, pilot_isFlag(pilot,PILOT_STEALTH) ); /* f, p, po, steathed */
1615 if (nlua_pcall( env, 3, 0 )) { /* */
1616 outfitLRunWarning( pilot, po->outfit, "onstealth", lua_tostring(naevL,-1) );
1617 lua_pop(naevL, 1);
1618 }
1619}
1627{
1628 pilot_outfitLRun( pilot, outfitLOnstealth, NULL );
1629 return pilotoutfit_modified;
1630}
1631
1632static void outfitLOnscan( const Pilot *pilot, PilotOutfitSlot *po, const void *data )
1633{
1634 (void) data;
1635 if (po->outfit->lua_onscan == LUA_NOREF)
1636 return;
1637
1638 nlua_env env = po->outfit->lua_env;
1639
1640 /* Set the memory. */
1641 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1642 nlua_setenv(naevL, env, "mem"); /* */
1643
1644 /* Set up the function: onscan( p, po, target ) */
1645 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_onscan); /* f */
1646 lua_pushpilot(naevL, pilot->id); /* f, p */
1647 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1648 lua_pushpilot(naevL, pilot->target); /* f, p, po, t */
1649 if (nlua_pcall( env, 3, 0 )) { /* */
1650 outfitLRunWarning( pilot, po->outfit, "onscan", lua_tostring(naevL,-1) );
1651 lua_pop(naevL, 1);
1652 }
1653}
1660{
1661 pilot_outfitLRun( pilot, outfitLOnscan, NULL );
1662}
1663
1664static void outfitLOnscanned( const Pilot *pilot, PilotOutfitSlot *po, const void *data )
1665{
1666 const Pilot *scanner;
1667 if (po->outfit->lua_onscanned == LUA_NOREF)
1668 return;
1669
1670 nlua_env env = po->outfit->lua_env;
1671 scanner = (const Pilot*) data;
1672
1673 /* Set the memory. */
1674 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1675 nlua_setenv(naevL, env, "mem"); /* */
1676
1677 /* Set up the function: onscanned( p, po, stealthed ) */
1678 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_onscanned); /* f */
1679 lua_pushpilot(naevL, pilot->id); /* f, p */
1680 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1681 lua_pushpilot(naevL, scanner->id); /* f, p, po, scanner */
1682 if (nlua_pcall( env, 3, 0 )) { /* */
1683 outfitLRunWarning( pilot, po->outfit, "onscanned", lua_tostring(naevL,-1) );
1684 lua_pop(naevL, 1);
1685 }
1686}
1693void pilot_outfitLOnscanned( Pilot *pilot, const Pilot *scanner )
1694{
1695 pilot_outfitLRun( pilot, outfitLOnscanned, scanner );
1696}
1697
1698static void outfitLOnland( const Pilot *pilot, PilotOutfitSlot *po, const void *data )
1699{
1700 (void) data;
1701 if (po->outfit->lua_land == LUA_NOREF)
1702 return;
1703
1704 nlua_env env = po->outfit->lua_env;
1705
1706 /* Set the memory. */
1707 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1708 nlua_setenv(naevL, env, "mem"); /* */
1709
1710 /* Set up the function: land( p, po ) */
1711 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_land); /* f */
1712 lua_pushpilot(naevL, pilot->id); /* f, p */
1713 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1714 if (nlua_pcall( env, 2, 0 )) { /* */
1715 outfitLRunWarning( pilot, po->outfit, "land", lua_tostring(naevL,-1) );
1716 lua_pop(naevL, 1);
1717 }
1718}
1725{
1726 pilot_outfitLRun( pilot, outfitLOnland, NULL );
1727}
1728
1729static void outfitLOntakeoff( const Pilot *pilot, PilotOutfitSlot *po, const void *data )
1730{
1731 (void) data;
1732 if (po->outfit->lua_takeoff == LUA_NOREF)
1733 return;
1734
1735 nlua_env env = po->outfit->lua_env;
1736
1737 /* Set the memory. */
1738 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1739 nlua_setenv(naevL, env, "mem"); /* */
1740
1741 /* Set up the function: takeoff( p, po ) */
1742 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_takeoff); /* f */
1743 lua_pushpilot(naevL, pilot->id); /* f, p */
1744 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1745 if (nlua_pcall( env, 2, 0 )) { /* */
1746 outfitLRunWarning( pilot, po->outfit, "takeoff", lua_tostring(naevL,-1) );
1747 lua_pop(naevL, 1);
1748 }
1749}
1756{
1757 pilot_outfitLRun( pilot, outfitLOntakeoff, NULL );
1758}
1759
1760static void outfitLOnjumpin( const Pilot *pilot, PilotOutfitSlot *po, const void *data )
1761{
1762 (void) data;
1763 if (po->outfit->lua_jumpin == LUA_NOREF)
1764 return;
1765
1766 nlua_env env = po->outfit->lua_env;
1767
1768 /* Set the memory. */
1769 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1770 nlua_setenv(naevL, env, "mem"); /* */
1771
1772 /* Set up the function: takeoff( p, po ) */
1773 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_jumpin); /* f */
1774 lua_pushpilot(naevL, pilot->id); /* f, p */
1775 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1776 if (nlua_pcall( env, 2, 0 )) { /* */
1777 outfitLRunWarning( pilot, po->outfit, "jumpin", lua_tostring(naevL,-1) );
1778 lua_pop(naevL, 1);
1779 }
1780}
1787{
1788 pilot_outfitLRun( pilot, outfitLOnjumpin, NULL );
1789}
1790
1797{
1798 /* TODO we might want to run this on intrinsic outfits too.. */
1799 pilotoutfit_modified = 0;
1800 for (int i=0; i<array_size(pilot->outfits); i++) {
1801 PilotOutfitSlot *po = pilot->outfits[i];
1802 if (po->outfit==NULL)
1803 continue;
1804 if (po->outfit->lua_cleanup == LUA_NOREF)
1805 continue;
1806 /* Pilot could be created and then erased without getting properly
1807 * initialized. */
1808 if (po->lua_mem == LUA_NOREF)
1809 continue;
1810
1811 nlua_env env = po->outfit->lua_env;
1812
1813 /* Set the memory. */
1814 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->lua_mem); /* mem */
1815 nlua_setenv(naevL, env, "mem"); /* */
1816
1817 /* Set up the function: cleanup( p, po ) */
1818 lua_rawgeti(naevL, LUA_REGISTRYINDEX, po->outfit->lua_cleanup); /* f */
1819 lua_pushpilot(naevL, pilot->id); /* f, p */
1820 lua_pushpilotoutfit(naevL, po); /* f, p, po */
1821 if (nlua_pcall( env, 2, 0 )) { /* */
1822 outfitLRunWarning( pilot, po->outfit, "cleanup", lua_tostring(naevL,-1) );
1823 lua_pop(naevL, 1);
1824 }
1825 }
1826 /* Pilot gets cleaned up so no need to recalculate stats. */
1827}
Provides macros to work with dynamic arrays.
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
Definition: array.h:140
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition: array.h:168
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
Definition: array.h:119
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Definition: array.h:93
void effect_compute(ShipStats *s, const Effect *efxlist)
Updates shipstats from effect list.
Definition: effect.c:410
void escort_freeList(Pilot *p)
Remove all escorts from a pilot.
Definition: escort.c:60
void escort_rmListIndex(Pilot *p, int i)
Remove from escorts list.
Definition: escort.c:75
void gui_setGeneric(const Pilot *pilot)
Calls trigger functions depending on who the pilot is.
Definition: gui.c:1798
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 ABS(x)
Definition: naev.h:36
#define pow2(x)
Definition: naev.h:46
#define FABS(x)
Definition: naev.h:37
#define MAX(x, y)
Definition: naev.h:39
const Outfit ** lua_pushoutfit(lua_State *L, const Outfit *outfit)
Pushes a outfit on the stack.
Definition: nlua_outfit.c:160
LuaPilot * lua_pushpilot(lua_State *L, LuaPilot pilot)
Pushes a pilot on the stack.
Definition: nlua_pilot.c:495
PilotOutfitSlot ** lua_pushpilotoutfit(lua_State *L, PilotOutfitSlot *po)
Pushes a pilot outfit on the stack.
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
Definition: nstring.c:178
int outfit_isBeam(const Outfit *o)
Checks if outfit is a beam type weapon.
Definition: outfit.c:488
double outfit_cpu(const Outfit *o)
Gets the outfit's cpu usage.
Definition: outfit.c:703
int outfit_isActive(const Outfit *o)
Checks if outfit is an active outfit.
Definition: outfit.c:434
int outfit_isLauncher(const Outfit *o)
Checks if outfit is a weapon launcher.
Definition: outfit.c:498
int outfit_isSeeker(const Outfit *o)
Checks if outfit is a seeking weapon.
Definition: outfit.c:508
int outfit_isToggleable(const Outfit *o)
Checks if outfit can be toggled.
Definition: outfit.c:450
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
int outfit_isTurret(const Outfit *o)
Checks if outfit is a turret class weapon.
Definition: outfit.c:521
double outfit_ammoMass(const Outfit *o)
Gets the outfit's ammunition mass.
Definition: outfit.c:840
int outfit_isMod(const Outfit *o)
Checks if outfit is a ship modification.
Definition: outfit.c:532
int outfit_isBolt(const Outfit *o)
Checks if outfit is bolt type weapon.
Definition: outfit.c:478
PilotOutfitSlot * pilot_getDockSlot(Pilot *p)
Gets the dock slot of the pilot.
Definition: pilot.c:749
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
Definition: pilot.c:589
void pilot_delete(Pilot *p)
Deletes a pilot.
Definition: pilot.c:2603
int pilot_numOutfit(const Pilot *p, const Outfit *o)
Checks to see how many of an outfit a pilot has.
Definition: pilot.c:2880
void pilot_cargoCalc(Pilot *pilot)
Calculates how much cargo ship has left and such.
Definition: pilot_cargo.c:220
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
void pilot_ewUpdateStatic(Pilot *p)
Updates the pilot's static electronic warfare properties.
Definition: pilot_ew.c:98
void pilot_heatCalcSlot(PilotOutfitSlot *o)
Calculates the heat parameters for a pilot's slot.
Definition: pilot_heat.c:91
void pilot_heatCalc(Pilot *p)
Calculates the heat parameters for a pilot.
Definition: pilot_heat.c:38
int pilot_runHook(Pilot *p, int hook_type)
Tries to run a pilot hook if he has it.
Definition: pilot_hook.c:106
int pilot_getMount(const Pilot *p, const PilotOutfitSlot *w, vec2 *v)
Gets the mount position of a pilot.
Definition: pilot_outfit.c:148
int pilot_rmOutfit(Pilot *pilot, PilotOutfitSlot *s)
Removes an outfit from the pilot.
Definition: pilot_outfit.c:475
static void pilot_outfitLmem(PilotOutfitSlot *po, nlua_env env)
Sets up the outfit memory for a slot.
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.
void pilot_outfitLCooldown(Pilot *pilot, int done, int success, double timer)
Handle cooldown hooks for outfits.
static int pilot_hasOutfitLimit(const Pilot *p, const char *limit)
Checks to see if a pilot has an outfit with a specific outfit type.
Definition: pilot_outfit.c:607
void pilot_outfitLOutfofenergy(Pilot *pilot)
Handles when the pilot runs out of energy.
const char * pilot_outfitDescription(const Pilot *p, const Outfit *o)
Gets the description of an outfit for a given pilot.
int pilot_hasDeployed(Pilot *p)
Checks to see if the pilot has deployed ships.
Definition: pilot_outfit.c:251
void pilot_healLanded(Pilot *pilot)
Cures the pilot as if he was landed.
int pilot_slotsCheckRequired(const Pilot *p)
Pilot required (core) slot filled check - makes sure they are filled.
Definition: pilot_outfit.c:514
int pilot_slotsCheckSafety(const Pilot *p)
Pilot slot safety check - makes sure stats are safe.
Definition: pilot_outfit.c:499
void pilot_outfitLOnshoot(Pilot *pilot)
Runs the pilot's Lua outfits onshoot script.
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
int pilot_addOutfit(Pilot *pilot, const Outfit *outfit, PilotOutfitSlot *s)
Adds an outfit to the pilot.
Definition: pilot_outfit.c:366
void pilot_outfitLOnjumpin(Pilot *pilot)
Runs Lua outfits when pilot jumps into a system.
int pilot_slotIsToggleable(const PilotOutfitSlot *o)
Checks to see if a slot has an active outfit that can be toggleable.
void pilot_outfitLOntakeoff(Pilot *pilot)
Runs Lua outfits when pilot takes off from a spob.
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
const char * pilot_outfitSummary(const Pilot *p, const Outfit *o, int withname)
Gets the summary of an outfit for a give pilot.
int pilot_rmOutfitRaw(Pilot *pilot, PilotOutfitSlot *s)
Removes an outfit from the pilot without doing any checks.
Definition: pilot_outfit.c:424
int pilot_outfitLRemove(Pilot *pilot, PilotOutfitSlot *po)
Outfit is removed froma ship.
static void pilot_calcStatsSlot(Pilot *pilot, PilotOutfitSlot *slot)
Computes the stats for a pilot's slot.
Definition: pilot_outfit.c:812
int pilot_countAmmo(const Pilot *pilot)
Gets the number of ammo units on the ship.
Definition: pilot_outfit.c:721
void pilot_lockClear(Pilot *p)
Clears pilot's missile lockon timers.
Definition: pilot_outfit.c:121
int pilot_outfitLOnstealth(Pilot *pilot)
Runs the pilot's Lua outfits onhit script.
void pilot_outfitLCleanup(Pilot *pilot)
Handle cleanup hooks for outfits.
PilotOutfitSlot * pilot_getSlotByName(Pilot *pilot, const char *name)
Gets the outfit slot by name.
int pilot_maxAmmo(const Pilot *pilot)
The maximum amount of ammo the pilot's current ship can hold.
Definition: pilot_outfit.c:745
void pilot_outfitLOnscan(Pilot *pilot)
Runs Lua outfits when pilot scanned their target.
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_outfitLAdd(Pilot *pilot, PilotOutfitSlot *po)
Outfit is added to a ship.
int pilot_outfitLOntoggle(Pilot *pilot, PilotOutfitSlot *po, int on)
Handle the manual toggle of an outfit.
int pilot_rmAmmo(Pilot *pilot, PilotOutfitSlot *s, int quantity)
Removes some ammo from the pilot stock.
Definition: pilot_outfit.c:693
void pilot_outfitLOnland(Pilot *pilot)
Runs Lua outfits when pilot lands on a spob.
int pilot_dock(Pilot *p, Pilot *target)
Docks the pilot on its target pilot.
Definition: pilot_outfit.c:189
void pilot_outfitLOnscanned(Pilot *pilot, const Pilot *scanner)
Runs Lua outfits when pilot was scanned by scanner.
const char * pilot_canEquip(const Pilot *p, const PilotOutfitSlot *s, const Outfit *o)
Checks to see if can equip/remove an outfit from a slot.
Definition: pilot_outfit.c:627
void pilot_lockUpdateSlot(Pilot *p, PilotOutfitSlot *o, Pilot *t, double *a, double dt)
Updates the lockons on the pilot's launchers.
Definition: pilot_outfit.c:46
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
void pilot_outfitLUpdate(Pilot *pilot, double dt)
Runs the pilot's Lua outfits update script.
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
static void pilot_outfitLRun(Pilot *p, void(*const func)(const Pilot *p, PilotOutfitSlot *po, const void *data), const void *data)
Wrapper that does all the work for us.
int pilot_isSpaceworthy(const Pilot *p)
Pilot safety check - makes sure stats are safe.
Definition: pilot_outfit.c:528
int pilot_addOutfitIntrinsic(Pilot *pilot, const Outfit *outfit)
Adds an outfit as an intrinsic slot.
Definition: pilot_outfit.c:385
void pilot_outfitLOnhit(Pilot *pilot, double armour, double shield, unsigned int attacker)
Runs the pilot's Lua outfits onhit script.
void pilot_outfitLInitAll(Pilot *pilot)
Runs the pilot's Lua outfits init script.
int pilot_outfitOff(Pilot *p, PilotOutfitSlot *o)
Disables a given active outfit.
void pilot_weapSetUpdateStats(Pilot *p)
Update the weapon sets given pilot stat changes.
Definition: pilot_weapon.c:548
void player_resetSpeed(void)
Resets the player speed stuff.
Definition: player.c:1416
static const double a[]
Definition: rng.c:247
int ss_statsMerge(ShipStats *dest, const ShipStats *src)
Merges two different ship stats.
Definition: shipstats.c:391
int ss_statsModFromList(ShipStats *stats, const ShipStatList *list)
Updates a stat structure from a stat list.
Definition: shipstats.c:543
int ss_statsInit(ShipStats *stats)
Initializes a stat structure.
Definition: shipstats.c:347
int sp_required(unsigned int spid)
Gets whether or not a slot property is required.
Definition: slots.c:170
StarSystem * cur_system
Definition: space.c:105
Stores an escort.
Definition: pilot.h:199
unsigned int id
Definition: pilot.h:202
EscortType_t type
Definition: pilot.h:201
double trackmax
Definition: outfit.h:196
double trackmin
Definition: outfit.h:195
double ammo_mass
Definition: outfit.h:204
unsigned int spid
Definition: outfit.h:102
A ship outfit, depends radically on the type.
Definition: outfit.h:304
int lua_ontoggle
Definition: outfit.h:349
int lua_onscan
Definition: outfit.h:355
char * limit
Definition: outfit.h:317
int lua_jumpin
Definition: outfit.h:359
OutfitLauncherData lau
Definition: outfit.h:373
int lua_cooldown
Definition: outfit.h:356
char * desc_raw
Definition: outfit.h:323
int lua_takeoff
Definition: outfit.h:358
int lua_outofenergy
Definition: outfit.h:351
int lua_land
Definition: outfit.h:357
int lua_onscanned
Definition: outfit.h:354
int lua_update
Definition: outfit.h:348
int lua_descextra
Definition: outfit.h:343
OutfitSlot slot
Definition: outfit.h:311
int lua_onhit
Definition: outfit.h:350
char * summary_raw
Definition: outfit.h:324
OutfitAfterburnerData afb
Definition: outfit.h:375
int lua_onshoot
Definition: outfit.h:352
OutfitFighterBayData bay
Definition: outfit.h:376
int lua_cleanup
Definition: outfit.h:347
ShipStatList * stats
Definition: outfit.h:335
nlua_env lua_env
Definition: outfit.h:342
int lua_onstealth
Definition: outfit.h:353
int lua_onadd
Definition: outfit.h:344
int lua_onremove
Definition: outfit.h:345
double mass
Definition: outfit.h:315
char * desc_extra
Definition: outfit.h:325
union Outfit::@22 u
char * name
Definition: outfit.h:305
int lua_init
Definition: outfit.h:346
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
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
ShipStats lua_stats
Definition: pilot.h:140
The representation of an in-game pilot.
Definition: pilot.h:210
Solid * solid
Definition: pilot.h:220
int nturrets
Definition: pilot.h:300
ShipStats stats
Definition: pilot.h:286
double shield
Definition: pilot.h:246
double speed_limit
Definition: pilot.h:239
unsigned int id
Definition: pilot.h:211
double thrust
Definition: pilot.h:235
double turn_base
Definition: pilot.h:241
int cpu_max
Definition: pilot.h:230
double crew
Definition: pilot.h:231
double energy_regen
Definition: pilot.h:259
PilotOutfitSlot ** outfits
Definition: pilot.h:292
PilotOutfitSlot * outfit_intrinsic
Definition: pilot.h:296
int outfitlupdate
Definition: pilot.h:304
double armour_max
Definition: pilot.h:247
double speed
Definition: pilot.h:237
ShipStats intrinsic_stats
Definition: pilot.h:285
double speed_base
Definition: pilot.h:238
const Ship * ship
Definition: pilot.h:219
double sbonus
Definition: pilot.h:360
double fuel_max
Definition: pilot.h:252
int ncannons
Definition: pilot.h:299
double thrust_base
Definition: pilot.h:236
double energy
Definition: pilot.h:257
double stress
Definition: pilot.h:245
double mass_cargo
Definition: pilot.h:222
double stimer
Definition: pilot.h:359
double energy_max
Definition: pilot.h:258
double fuel
Definition: pilot.h:253
double energy_loss
Definition: pilot.h:261
PilotOutfitSlot * afterburner
Definition: pilot.h:308
char * name
Definition: pilot.h:212
int nbeams
Definition: pilot.h:301
double mass_outfit
Definition: pilot.h:223
Escort_t * escorts
Definition: pilot.h:326
int cpu
Definition: pilot.h:229
double fuel_consumption
Definition: pilot.h:254
double base_mass
Definition: pilot.h:221
int nfighterbays
Definition: pilot.h:302
double energy_tau
Definition: pilot.h:260
double shield_regen
Definition: pilot.h:250
unsigned int target
Definition: pilot.h:334
int nafterburners
Definition: pilot.h:303
Effect * effects
Definition: pilot.h:289
double cap_cargo
Definition: pilot.h:232
double turn
Definition: pilot.h:240
double armour
Definition: pilot.h:244
double shield_max
Definition: pilot.h:248
double dmg_absorb
Definition: pilot.h:251
double armour_regen
Definition: pilot.h:249
Represents a ship weapon mount point.
Definition: ship.h:61
double x
Definition: ship.h:62
double y
Definition: ship.h:63
double h
Definition: ship.h:64
char * name
Definition: ship.h:72
OutfitSlot slot
Definition: ship.h:71
Represents ship statistics, properties ship can use.
Definition: shipstats.h:198
double thrust
Definition: shipstats.h:202
int crew
Definition: shipstats.h:306
double energy
Definition: shipstats.h:208
double armour_regen
Definition: shipstats.h:220
double armour
Definition: shipstats.h:219
int cargo
Definition: shipstats.h:305
double crew_mod
Definition: shipstats.h:253
double ammo_capacity
Definition: shipstats.h:260
double engine_limit
Definition: shipstats.h:293
double cargo_inertia
Definition: shipstats.h:238
double shield_regen_malus
Definition: shipstats.h:218
double shield_regen
Definition: shipstats.h:215
double mass_mod
Definition: shipstats.h:254
double energy_regen_malus
Definition: shipstats.h:212
double energy_loss
Definition: shipstats.h:213
double absorb
Definition: shipstats.h:232
int fuel
Definition: shipstats.h:303
double energy_regen
Definition: shipstats.h:209
double thrust_mod
Definition: shipstats.h:205
double turn_mod
Definition: shipstats.h:204
double armour_regen_mod
Definition: shipstats.h:222
double shield
Definition: shipstats.h:214
double shield_regen_mod
Definition: shipstats.h:217
double speed
Definition: shipstats.h:200
double speed_mod
Definition: shipstats.h:203
double engine_limit_rel
Definition: shipstats.h:292
double cpu_max
Definition: shipstats.h:231
double shield_mod
Definition: shipstats.h:216
double armour_regen_malus
Definition: shipstats.h:223
double fuel_mod
Definition: shipstats.h:229
double cpu_mod
Definition: shipstats.h:230
double energy_regen_mod
Definition: shipstats.h:211
double time_mod
Definition: shipstats.h:308
double energy_mod
Definition: shipstats.h:210
double turn
Definition: shipstats.h:201
double armour_mod
Definition: shipstats.h:221
double cargo_mod
Definition: shipstats.h:228
double shield_regen
Definition: ship.h:129
double cap_cargo
Definition: ship.h:122
glTexture * gfx_space
Definition: ship.h:137
ShipStats stats_array
Definition: ship.h:166
double thrust
Definition: ship.h:112
int fuel
Definition: ship.h:120
double energy_regen
Definition: ship.h:131
double armour
Definition: ship.h:126
int fuel_consumption
Definition: ship.h:121
double armour_regen
Definition: ship.h:127
int crew
Definition: ship.h:117
double dmg_absorb
Definition: ship.h:132
double cpu
Definition: ship.h:119
double speed
Definition: ship.h:114
double turn
Definition: ship.h:113
double energy
Definition: ship.h:130
double shield
Definition: ship.h:128
double mass
Definition: ship.h:118
double speed_max
Definition: physics.h:24
vec2 vel
Definition: physics.h:21
double mass
Definition: physics.h:18
vec2 pos
Definition: physics.h:22
double sw
Definition: opengl_tex.h:44
Represents a 2d vector.
Definition: vec2.h:32
double y
Definition: vec2.h:34
double x
Definition: vec2.h:33