naev 0.12.5
escort.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
9
10#include "escort.h"
11
12#include "array.h"
13#include "dialogue.h"
14#include "log.h"
15#include "nlua.h"
16#include "nlua_jump.h"
17#include "nlua_pilot.h"
18#include "player.h"
19
20/*
21 * Prototypes.
22 */
23/* Static */
24static int escort_command( const Pilot *parent, const char *cmd,
25 unsigned int index );
26
37int escort_addList( Pilot *p, const Ship *ship, EscortType_t type,
38 unsigned int id, int persist )
39{
40 Escort_t *escort;
41 if ( p->escorts == NULL )
42 p->escorts = array_create( Escort_t );
43 escort = &array_grow( &p->escorts );
44 escort->ship = ship;
45 escort->type = type;
46 escort->id = id;
47 escort->persist = persist;
48
49 return 0;
50}
51
58{
59 array_free( p->escorts );
60 p->escorts = NULL;
61}
62
70void escort_rmListIndex( Pilot *p, int i )
71{
72 array_erase( &p->escorts, &p->escorts[i], &p->escorts[i + 1] );
73}
74
82void escort_rmList( Pilot *p, unsigned int id )
83{
84 for ( int i = 0; i < array_size( p->escorts ); i++ ) {
85 if ( p->escorts[i].id == id ) {
86 escort_rmListIndex( p, i );
87 break;
88 }
89 }
90}
91
105unsigned int escort_create( Pilot *p, const Ship *ship, const vec2 *pos,
106 const vec2 *vel, double dir, EscortType_t type,
107 int add, int dockslot )
108{
109 Pilot *pe;
110 PilotFlags f;
111 unsigned int parent;
112
113 /* Get important stuff. */
114 parent = p->id;
115
116 /* Set flags. */
117 pilot_clearFlagsRaw( f );
118 // pilot_setFlagRaw( f, PILOT_NOJUMP );
119 if ( p->faction == FACTION_PLAYER ) {
120 pilot_setFlagRaw( f, PILOT_PERSIST );
121 pilot_setFlagRaw( f, PILOT_NOCLEAR );
122 }
123 if ( type == ESCORT_TYPE_BAY )
124 pilot_setFlagRaw( f, PILOT_CARRIED );
125
126 /* Create the pilot. */
127 pe = pilot_create( ship, NULL, p->faction, "escort", dir, pos, vel, f,
128 parent, dockslot );
129 pe->parent = parent;
130
131 /* Make invincible to player. */
132 if ( pe->parent == PLAYER_ID )
133 pilot_setFlag( pe, PILOT_INVINC_PLAYER );
134
135 /* Set some flags for consistent behaviour. */
136 if ( pilot_isFlag( p, PILOT_HOSTILE ) )
137 pilot_setFlag( pe, PILOT_HOSTILE );
138 if ( pilot_isFlag( p, PILOT_FRIENDLY ) )
139 pilot_setFlag( pe, PILOT_FRIENDLY );
140
141 /* Compute fighter bay bonuses. */
142 if ( pilot_isFlagRaw( f, PILOT_CARRIED ) ) {
143 /* Damage. */
144 if ( p->stats.fbay_damage != 1. ) {
145 pe->intrinsic_stats = ss_statsSetList(
146 pe->intrinsic_stats, SS_TYPE_D_LAUNCH_DAMAGE,
147 ss_statsGetRaw( &p->stats, SS_TYPE_D_FBAY_DAMAGE ), 0, 1 );
148 pe->intrinsic_stats = ss_statsSetList(
149 pe->intrinsic_stats, SS_TYPE_D_FORWARD_DAMAGE,
150 ss_statsGetRaw( &p->stats, SS_TYPE_D_FBAY_DAMAGE ), 0, 1 );
151 pe->intrinsic_stats = ss_statsSetList(
152 pe->intrinsic_stats, SS_TYPE_D_TURRET_DAMAGE,
153 ss_statsGetRaw( &p->stats, SS_TYPE_D_FBAY_DAMAGE ), 0, 1 );
154 }
155 /* Health. */
156 if ( p->stats.fbay_health != 1. ) {
157 pe->intrinsic_stats = ss_statsSetList(
158 pe->intrinsic_stats, SS_TYPE_D_ARMOUR_MOD,
159 ss_statsGetRaw( &p->stats, SS_TYPE_D_FBAY_HEALTH ), 0, 1 );
160 pe->intrinsic_stats = ss_statsSetList(
161 pe->intrinsic_stats, SS_TYPE_D_SHIELD_MOD,
162 ss_statsGetRaw( &p->stats, SS_TYPE_D_FBAY_HEALTH ), 0, 1 );
163 }
164 /* Movement. */
165 if ( p->stats.fbay_movement != 1. ) {
166 pe->intrinsic_stats = ss_statsSetList(
167 pe->intrinsic_stats, SS_TYPE_D_SPEED_MOD,
168 ss_statsGetRaw( &p->stats, SS_TYPE_D_FBAY_MOVEMENT ), 0, 1 );
169 pe->intrinsic_stats = ss_statsSetList(
170 pe->intrinsic_stats, SS_TYPE_D_TURN_MOD,
171 ss_statsGetRaw( &p->stats, SS_TYPE_D_FBAY_MOVEMENT ), 0, 1 );
172 pe->intrinsic_stats = ss_statsSetList(
173 pe->intrinsic_stats, SS_TYPE_D_ACCEL_MOD,
174 ss_statsGetRaw( &p->stats, SS_TYPE_D_FBAY_MOVEMENT ), 0, 1 );
175 }
176 /* Update stats. */
177 pilot_calcStats( pe );
178 }
179
180 /* Add to escort list. */
181 if ( add != 0 )
182 escort_addList( p, ship, type, pe->id, 1 );
183
184 return pe->id;
185}
186
200unsigned int escort_createRef( Pilot *p, Pilot *pe, const vec2 *pos,
201 const vec2 *vel, double dir, EscortType_t type,
202 int add, int dockslot )
203{
204 if ( pilot_get( pe->id ) == NULL ) /* Not on stack yet. */
205 pilot_addStack( pe ); /* Sets the ID, and resets internals. */
206 else
207 pilot_reset( pe ); /* Reset internals. */
208 pilot_weaponAuto( pe );
209 pe->parent = p->id;
210
211 /* Make invincible to player. */
212 if ( pe->parent == PLAYER_ID )
213 pilot_setFlag( pe, PILOT_INVINC_PLAYER );
214
215 /* Copy stuff over if necessary. */
216 if ( pos != NULL )
217 memcpy( &pe->solid.pos, pos, sizeof( vec2 ) );
218 if ( vel != NULL )
219 memcpy( &pe->solid.vel, vel, sizeof( vec2 ) );
220 pe->solid.dir = dir;
221
222 /* Set some flags for consistent behaviour. */
223 if ( p->faction == FACTION_PLAYER ) {
224 pilot_setFlag( pe, PILOT_PERSIST );
225 pilot_setFlag( pe, PILOT_NOCLEAR );
226 }
227 if ( pilot_isFlag( p, PILOT_HOSTILE ) )
228 pilot_setFlag( pe, PILOT_HOSTILE );
229 if ( pilot_isFlag( p, PILOT_FRIENDLY ) )
230 pilot_setFlag( pe, PILOT_FRIENDLY );
231
232 /* Add to escort list. */
233 if ( add != 0 )
234 escort_addList( p, pe->ship, type, pe->id, 1 );
235 pe->dockslot = dockslot;
236
237 return pe->id;
238}
239
243int escort_clearDeployed( Pilot *p, int slot )
244{
245 int q = 0;
246 /* Iterate backwards so we don't have to care about indices. */
247 for ( int j = array_size( p->escorts ) - 1; j >= 0; j-- ) {
248 Pilot *pe;
249 const Escort_t *e = &p->escorts[j];
250
251 /* Only try to dock fighters. */
252 if ( e->type != ESCORT_TYPE_BAY )
253 continue;
254
255 pe = pilot_get( e->id );
256 if ( pe == NULL )
257 continue;
258
259 /* See if matches slot. */
260 if ( ( slot >= 0 ) && ( slot != pe->dockslot ) )
261 continue;
262
263 /* Hack so it can dock. */
264 memcpy( &pe->solid.pos, &p->solid.pos, sizeof( vec2 ) );
265 memcpy( &pe->solid.vel, &p->solid.vel, sizeof( vec2 ) );
266 if ( pilot_dock( pe, p ) )
267 WARN( _( "Pilot '%s' has escort '%s' docking error!" ), p->name,
268 pe->name );
269 else
270 q++;
271 }
272 return q;
273}
274
283static int escort_command( const Pilot *parent, const char *cmd,
284 unsigned int idx )
285{
286 if ( array_size( parent->escorts ) == 0 )
287 return 1;
288
289 for ( int i = 0; i < array_size( parent->escorts ); i++ ) {
290 const Pilot *e = pilot_get( parent->escorts[i].id );
291 if ( e == NULL ) /* Most likely died. */
292 continue;
293
294 pilot_msg( parent, e, cmd, idx );
295 }
296
297 return 0;
298}
299
305int escorts_attack( Pilot *parent )
306{
307 int ret;
308 Pilot *t;
309
310 /* Avoid killing self. */
311 t = pilot_getTarget( parent );
312 if ( t == NULL )
313 return 1;
314 if ( t->faction == parent->faction )
315 return 1;
316
317 /* Send command. */
318 ret = 1;
319 if ( parent->target != parent->id ) {
320 lua_pushpilot( naevL, parent->target );
321 ret = escort_command( parent, "e_attack", -1 );
322 lua_pop( naevL, 1 );
323 }
324 if ( ( ret == 0 ) && ( parent == player.p ) ) {
325 const char *pltname;
326 if ( pilot_inRangePilot( parent, t, NULL ) > 0 )
327 pltname = t->name;
328 else
329 pltname = _( "Unknown" );
330
331 if ( pilot_isFlag( t, PILOT_DISABLED ) )
332 player_message( _( "#gEscorts: #0Destroying %s." ), pltname );
333 else
334 player_message( _( "#gEscorts: #0Engaging %s." ), pltname );
335 }
336 return ret;
337}
338
344int escorts_hold( const Pilot *parent )
345{
346 int ret = escort_command( parent, "e_hold", 0 );
347 if ( ( ret == 0 ) && ( parent == player.p ) )
348 player_message( _( "#gEscorts: #0Holding formation." ) );
349 return ret;
350}
351
357int escorts_return( const Pilot *parent )
358{
359 int ret = escort_command( parent, "e_return", 0 );
360 if ( ( ret == 0 ) && ( parent == player.p ) )
361 player_message( _( "#gEscorts: #0Returning to ship." ) );
362 return ret;
363}
364
370int escorts_clear( const Pilot *parent )
371{
372 int ret = escort_command( parent, "e_clear", 0 );
373 if ( ( ret == 0 ) && ( parent == player.p ) )
374 player_message( _( "#gEscorts: #0Clearing orders." ) );
375 return ret;
376}
377
385{
386 const char *title, *caption;
387 char *choice;
388 int ret = 1;
389
390 /* "Attack My Target" order is omitted deliberately since e is your
391 * target, making "Attack My Target" a useless command. */
392 const char *opts[] = { _( "Hold Formation" ), _( "Return To Ship" ),
393 _( "Clear Orders" ), _( "Cancel" ) };
394 const int nopts = 4;
395
396 /* Must not be NULL */
397 if ( e == NULL )
398 return 1;
399
400 title = _( "Escort Orders" );
401 caption = _( "Select the order to give to this escort." );
402
403 dialogue_makeChoice( title, caption, nopts );
404 for ( int i = 0; i < nopts; i++ )
405 dialogue_addChoice( title, caption, opts[i] );
406
407 choice = dialogue_runChoice();
408 if ( choice != NULL ) {
409 if ( strcmp( choice, opts[0] ) == 0 ) { /* Hold position */
410 pilot_msg( player.p, e, "e_hold", 0 );
411 ret = 0;
412 } else if ( strcmp( choice, opts[1] ) == 0 ) { /* Return to ship */
413 pilot_msg( player.p, e, "e_return", 0 );
414 ret = 0;
415 } else if ( strcmp( choice, opts[2] ) == 0 ) { /* Clear orders */
416 pilot_msg( player.p, e, "e_clear", 0 );
417 ret = 0;
418 }
419 }
420 free( choice );
421 return ret;
422}
423
430int escorts_jump( const Pilot *parent, const JumpPoint *jp )
431{
432 int ret;
433 LuaJump lj;
434
435 lj.destid = jp->targetid;
436 lj.srcid = cur_system->id;
437
438 lua_pushjump( naevL, lj );
439 ret = escort_command( parent, "hyperspace", -1 );
440 lua_pop( naevL, 1 );
441
442 if ( ( ret == 0 ) && ( parent == player.p ) )
443 player_message( _( "#gEscorts: #0Jumping." ) );
444 return ret;
445}
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition array.h:170
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
Definition array.h:148
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:179
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
Definition array.h:122
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Definition array.h:93
char * dialogue_runChoice(void)
Run the dialog and return the clicked string.
Definition dialogue.c:817
void dialogue_addChoice(const char *caption, const char *msg, const char *opt)
Add a choice to the dialog.
Definition dialogue.c:796
void dialogue_makeChoice(const char *caption, const char *msg, int opts)
Create the choice dialog. Need to add choices with below method.
Definition dialogue.c:773
void escort_rmList(Pilot *p, unsigned int id)
Remove from escorts list.
Definition escort.c:82
int escorts_hold(const Pilot *parent)
Have a pilot order its escorts to hold position.
Definition escort.c:344
static int escort_command(const Pilot *parent, const char *cmd, unsigned int index)
Runs an escort command on all of a pilot's escorts.
Definition escort.c:283
void escort_freeList(Pilot *p)
Remove all escorts from a pilot.
Definition escort.c:57
int escort_clearDeployed(Pilot *p, int slot)
Clears deployed escorts of a pilot.
Definition escort.c:243
unsigned int escort_create(Pilot *p, const Ship *ship, const vec2 *pos, const vec2 *vel, double dir, EscortType_t type, int add, int dockslot)
Creates an escort.
Definition escort.c:105
unsigned int escort_createRef(Pilot *p, Pilot *pe, const vec2 *pos, const vec2 *vel, double dir, EscortType_t type, int add, int dockslot)
Creates an escort from a reference.
Definition escort.c:200
int escort_addList(Pilot *p, const Ship *ship, EscortType_t type, unsigned int id, int persist)
Adds an escort to the escort list of a pilot.
Definition escort.c:37
int escorts_return(const Pilot *parent)
Have a pilot order its escorts to dock.
Definition escort.c:357
void escort_rmListIndex(Pilot *p, int i)
Remove from escorts list.
Definition escort.c:70
int escort_playerCommand(const Pilot *e)
Open a dialog for the player to issue a command to an escort.
Definition escort.c:384
int escorts_attack(Pilot *parent)
Have a pilot order its escorts to attack its target.
Definition escort.c:305
int escorts_jump(const Pilot *parent, const JumpPoint *jp)
Have a pilot order its escorts to jump.
Definition escort.c:430
int escorts_clear(const Pilot *parent)
Have a pilot order its escorts to clear orders.
Definition escort.c:370
void player_message(const char *fmt,...)
Adds a mesg to the queue to be displayed on screen.
Definition gui.c:353
lua_State * naevL
Definition nlua.c:54
LuaJump * lua_pushjump(lua_State *L, LuaJump jump)
Pushes a jump on the stack.
Definition nlua_jump.c:186
LuaPilot * lua_pushpilot(lua_State *L, LuaPilot pilot)
Pushes a pilot on the stack.
Definition nlua_pilot.c:576
unsigned int pilot_addStack(Pilot *p)
Adds a pilot to the stack.
Definition pilot.c:3690
Pilot * pilot_getTarget(Pilot *p)
Gets the target of a pilot using a fancy caching system.
Definition pilot.c:655
void pilot_msg(const Pilot *p, const Pilot *receiver, const char *type, unsigned int idx)
Sends a message.
Definition pilot.c:4531
void pilot_reset(Pilot *pilot)
Resets a pilot.
Definition pilot.c:3491
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
Definition pilot.c:640
Pilot * pilot_create(const Ship *ship, const char *name, int faction, const char *ai, const double dir, const vec2 *pos, const vec2 *vel, const PilotFlags flags, unsigned int dockpilot, int dockslot)
Creates a new pilot.
Definition pilot.c:3557
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:256
void pilot_calcStats(Pilot *pilot)
Recalculates the pilot's stats based on his outfits.
void pilot_weaponAuto(Pilot *p)
Tries to automatically set and create the pilot's weapon set.
Player_t player
Definition player.c:77
double ss_statsGetRaw(const ShipStats *s, ShipStatsType type)
Gets a ship stat value by name.
Definition shipstats.c:1108
StarSystem * cur_system
Definition space.c:110
Stores an escort.
Definition pilot.h:252
unsigned int id
Definition pilot.h:255
int persist
Definition pilot.h:257
EscortType_t type
Definition pilot.h:254
const Ship * ship
Definition pilot.h:253
Lua jump Wrapper.
Definition nlua_jump.h:14
int destid
Definition nlua_jump.h:16
int srcid
Definition nlua_jump.h:15
The representation of an in-game pilot.
Definition pilot.h:263
unsigned int id
Definition pilot.h:264
unsigned int parent
Definition pilot.h:390
const Ship * ship
Definition pilot.h:274
ShipStatList * intrinsic_stats
Definition pilot.h:345
int faction
Definition pilot.h:269
Solid solid
Definition pilot.h:275
char * name
Definition pilot.h:265
Escort_t * escorts
Definition pilot.h:391
unsigned int target
Definition pilot.h:400
int dockslot
Definition pilot.h:396
Represents a space ship.
Definition ship.h:97
int faction
Definition ship.h:108
vec2 vel
Definition physics.h:48
double dir
Definition physics.h:46
vec2 pos
Definition physics.h:49
Represents a 2d vector.
Definition vec2.h:45