naev 0.10.4
escort.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 "escort.h"
14
15#include "array.h"
16#include "dialogue.h"
17#include "hook.h"
18#include "log.h"
19#include "nlua.h"
20#include "nluadef.h"
21#include "nstring.h"
22#include "player.h"
23
24/*
25 * Prototypes.
26 */
27/* Static */
28static int escort_command( Pilot *parent, const char *cmd, unsigned int index );
29
40int escort_addList( Pilot *p, const char *ship, EscortType_t type,
41 unsigned int id, int persist )
42{
43 Escort_t *escort;
44 if (p->escorts == NULL)
45 p->escorts = array_create( Escort_t );
46 escort = &array_grow( &p->escorts );
47 escort->ship = strdup(ship);
48 escort->type = type;
49 escort->id = id;
50 escort->persist = persist;
51
52 return 0;
53}
54
61{
62 for (int i=0; i<array_size(p->escorts); i++)
63 free(p->escorts[i].ship);
64 array_free(p->escorts);
65 p->escorts = NULL;
66}
67
75void escort_rmListIndex( Pilot *p, int i )
76{
77 free(p->escorts[i].ship);
78 array_erase( &p->escorts, &p->escorts[i], &p->escorts[i+1] );
79}
80
88void escort_rmList( Pilot *p, unsigned int id )
89{
90 for (int i=0; i<array_size(p->escorts); i++) {
91 if (p->escorts[i].id == id) {
92 escort_rmListIndex( p, i );
93 break;
94 }
95 }
96}
97
111unsigned int escort_create( Pilot *p, const char *ship,
112 const vec2 *pos, const vec2 *vel, double dir,
113 EscortType_t type, int add, int dockslot )
114{
115 const Ship *s;
116 Pilot *pe;
117 unsigned int e;
118 PilotFlags f;
119 unsigned int parent;
120
121 /* Get important stuff. */
122 parent = p->id;
123 s = ship_get(ship);
124
125 /* Set flags. */
126 pilot_clearFlagsRaw( f );
127 pilot_setFlagRaw( f, PILOT_NOJUMP );
128 if (p->faction == FACTION_PLAYER) {
129 pilot_setFlagRaw( f, PILOT_PERSIST );
130 pilot_setFlagRaw( f, PILOT_NOCLEAR );
131 }
132 if (type == ESCORT_TYPE_BAY)
133 pilot_setFlagRaw( f, PILOT_CARRIED );
134
135 /* Create the pilot. */
136 e = pilot_create( s, NULL, p->faction, "escort", dir, pos, vel, f, parent, dockslot );
137 pe = pilot_get(e);
138 pe->parent = parent;
139
140 /* Make invincible to player. */
141 if (pe->parent == PLAYER_ID)
142 pilot_setFlag( pe, PILOT_INVINC_PLAYER );
143
144 /* Set some flags for consistent behaviour. */
145 if (pilot_isFlag(p, PILOT_HOSTILE))
146 pilot_setFlag( pe, PILOT_HOSTILE );
147 if (pilot_isFlag(p, PILOT_FRIENDLY))
148 pilot_setFlag( pe, PILOT_FRIENDLY );
149
150 /* Compute fighter bay bonuses. */
151 if (pilot_isFlagRaw( f, PILOT_CARRIED )) {
152 /* Damage. */
153 pe->intrinsic_stats.launch_damage *= p->stats.fbay_damage;
154 pe->intrinsic_stats.fwd_damage *= p->stats.fbay_damage;
155 pe->intrinsic_stats.tur_damage *= p->stats.fbay_damage;
156 /* Health. */
157 pe->intrinsic_stats.armour_mod *= p->stats.fbay_health;
158 pe->intrinsic_stats.shield_mod *= p->stats.fbay_health;
159 /* Movement. */
160 pe->intrinsic_stats.speed_mod *= p->stats.fbay_movement;
161 pe->intrinsic_stats.turn_mod *= p->stats.fbay_movement;
162 pe->intrinsic_stats.thrust_mod *= p->stats.fbay_movement;
163 /* Update stats. */
164 pilot_calcStats( pe );
165 }
166
167 /* Add to escort list. */
168 if (add != 0)
169 escort_addList( p, ship, type, e, 1 );
170
171 return e;
172}
173
187unsigned int escort_createRef( Pilot *p, Pilot *pe,
188 const vec2 *pos, const vec2 *vel, double dir,
189 EscortType_t type, int add, int dockslot )
190{
191 if (pilot_get( pe->id ) == NULL) /* Not on stack yet. */
192 pilot_addStack( pe ); /* Sets the ID, and resets internals. */
193 else
194 pilot_reset( pe ); /* Reset internals. */
195 pe->parent = p->id;
196
197 /* Make invincible to player. */
198 if (pe->parent == PLAYER_ID)
199 pilot_setFlag( pe, PILOT_INVINC_PLAYER );
200
201 /* Copy stuff over if necessary. */
202 if (pos != NULL)
203 memcpy( &pe->solid->pos, pos, sizeof(vec2) );
204 if (vel != NULL)
205 memcpy( &pe->solid->vel, vel, sizeof(vec2) );
206 pe->solid->dir = dir;
207
208 /* Set some flags for consistent behaviour. */
209 if (p->faction == FACTION_PLAYER) {
210 pilot_setFlag( pe, PILOT_PERSIST );
211 pilot_setFlag( pe, PILOT_NOCLEAR );
212 }
213 if (pilot_isFlag(p, PILOT_HOSTILE))
214 pilot_setFlag( pe, PILOT_HOSTILE );
215 if (pilot_isFlag(p, PILOT_FRIENDLY))
216 pilot_setFlag( pe, PILOT_FRIENDLY );
217
218 /* Add to escort list. */
219 if (add != 0)
220 escort_addList( p, pe->ship->name, type, pe->id, 1 );
221 pe->dockslot = dockslot;
222
223 return pe->id;
224}
225
230{
231 int q = 0;
232 /* Iterate backwards so we don't have to care about indices. */
233 for (int j=array_size(p->escorts)-1; j>=0; j--) {
234 Pilot *pe;
235 Escort_t *e = &p->escorts[j];
236
237 /* Only try to dock fighters. */
238 if (e->type != ESCORT_TYPE_BAY)
239 continue;
240
241 pe = pilot_get( e->id );
242 if (pe==NULL)
243 continue;
244 /* Hack so it can dock. */
245 memcpy( &pe->solid->pos, &p->solid->pos, sizeof(vec2) );
246 memcpy( &pe->solid->vel, &p->solid->vel, sizeof(vec2) );
247 if (pilot_dock( pe, p ))
248 WARN(_("Pilot '%s' has escort '%s' docking error!"), p->name, pe->name);
249 else
250 q++;
251 }
252 return q;
253}
254
263static int escort_command( Pilot *parent, const char *cmd, unsigned int idx )
264{
265 if (array_size(parent->escorts) == 0)
266 return 1;
267
268 for (int i=0; i<array_size(parent->escorts); i++) {
269 Pilot *e = pilot_get( parent->escorts[i].id );
270 if (e == NULL) /* Most likely died. */
271 continue;
272
273 pilot_msg( parent, e, cmd, idx );
274 }
275
276 return 0;
277}
278
284int escorts_attack( Pilot *parent )
285{
286 int ret;
287 Pilot *t;
288
289 /* Avoid killing self. */
290 t = pilot_getTarget( parent );
291 if (t == NULL)
292 return 1;
293 if (t->faction == parent->faction)
294 return 1;
295
296 /* Send command. */
297 ret = 1;
298 if (parent->target != parent->id) {
299 lua_pushpilot(naevL, parent->target);
300 ret = escort_command( parent, "e_attack", -1 );
301 lua_pop(naevL, 1);
302 }
303 if ((ret == 0) && (parent == player.p)) {
304 if (pilot_isFlag(t, PILOT_DISABLED))
305 player_message(_("#gEscorts: #0Destroying %s."), t->name);
306 else
307 player_message(_("#gEscorts: #0Engaging %s."), t->name);
308 }
309 return ret;
310}
311
317int escorts_hold( Pilot *parent )
318{
319 int ret = escort_command( parent, "e_hold", 0 );
320 if ((ret == 0) && (parent == player.p))
321 player_message(_("#gEscorts: #0Holding formation."));
322 return ret;
323}
324
330int escorts_return( Pilot *parent )
331{
332 int ret = escort_command( parent, "e_return", 0 );
333 if ((ret == 0) && (parent == player.p))
334 player_message(_("#gEscorts: #0Returning to ship."));
335 return ret;
336}
337
343int escorts_clear( Pilot *parent )
344{
345 int ret = escort_command( parent, "e_clear", 0 );
346 if ((ret == 0) && (parent == player.p))
347 player_message(_("#gEscorts: #0Clearing orders."));
348 return ret;
349}
350
358{
359 const char *title, *caption;
360 char *choice;
361 int ret = 1;
362
363 /* "Attack My Target" order is omitted deliberately since e is your
364 * target, making "Attack My Target" a useless command. */
365 const char *opts[] = {
366 _("Hold Position"),
367 _("Return To Ship"),
368 _("Clear Orders"),
369 _("Cancel")
370 };
371 const int nopts = 4;
372
373 /* Must not be NULL */
374 if (e == NULL)
375 return 1;
376
377 title = _("Escort Orders");
378 caption = _("Select the order to give to this escort.");
379
380 dialogue_makeChoice( title, caption, nopts );
381 for (int i=0; i<nopts; i++)
382 dialogue_addChoice( title, caption, opts[i] );
383
384 choice = dialogue_runChoice();
385 if (choice != NULL) {
386 if (strcmp(choice, opts[0]) == 0) { /* Hold position */
387 pilot_msg( player.p, e, "e_hold", 0 );
388 ret = 0;
389 }
390 else if (strcmp(choice, opts[1]) == 0) { /* Return to ship */
391 pilot_msg( player.p, e, "e_return", 0 );
392 ret = 0;
393 }
394 else if (strcmp(choice, opts[2]) == 0) { /* Clear orders */
395 pilot_msg( player.p, e, "e_clear", 0 );
396 ret = 0;
397 }
398 }
399 free( choice );
400 return ret;
401}
402
409int escorts_jump( Pilot *parent, JumpPoint *jp )
410{
411 int ret;
412 LuaJump lj;
413
414 lj.destid = jp->targetid;
415 lj.srcid = cur_system->id;
416
417 lua_pushjump( naevL, lj );
418 ret = escort_command( parent, "hyperspace", -1 );
419 lua_pop(naevL, 1);
420
421 if ((ret == 0) && (parent == player.p))
422 player_message(_("#gEscorts: #0Jumping."));
423 return ret;
424}
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_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
char * dialogue_runChoice(void)
Run the dialog and return the clicked string.
Definition: dialogue.c:792
void dialogue_addChoice(const char *caption, const char *msg, const char *opt)
Add a choice to the dialog.
Definition: dialogue.c:770
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:748
static int escort_command(Pilot *parent, const char *cmd, unsigned int index)
Runs an escort command on all of a pilot's escorts.
Definition: escort.c:263
void escort_rmList(Pilot *p, unsigned int id)
Remove from escorts list.
Definition: escort.c:88
void escort_freeList(Pilot *p)
Remove all escorts from a pilot.
Definition: escort.c:60
unsigned int escort_create(Pilot *p, const char *ship, const vec2 *pos, const vec2 *vel, double dir, EscortType_t type, int add, int dockslot)
Creates an escort.
Definition: escort.c:111
int escorts_jump(Pilot *parent, JumpPoint *jp)
Have a pilot order its escorts to jump.
Definition: escort.c:409
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:187
void escort_rmListIndex(Pilot *p, int i)
Remove from escorts list.
Definition: escort.c:75
int escort_playerCommand(Pilot *e)
Open a dialog for the player to issue a command to an escort.
Definition: escort.c:357
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 escort_clearDeployed(Pilot *p)
Clears deployed escorts of a pilot.
Definition: escort.c:229
int escorts_return(Pilot *parent)
Have a pilot order its escorts to dock.
Definition: escort.c:330
int escorts_attack(Pilot *parent)
Have a pilot order its escorts to attack its target.
Definition: escort.c:284
int escorts_hold(Pilot *parent)
Have a pilot order its escorts to hold position.
Definition: escort.c:317
int escorts_clear(Pilot *parent)
Have a pilot order its escorts to clear orders.
Definition: escort.c:343
void player_message(const char *fmt,...)
Adds a mesg to the queue to be displayed on screen.
Definition: gui.c:330
Header file with generic functions and naev-specifics.
LuaJump * lua_pushjump(lua_State *L, LuaJump jump)
Pushes a jump on the stack.
Definition: nlua_jump.c:182
LuaPilot * lua_pushpilot(lua_State *L, LuaPilot pilot)
Pushes a pilot on the stack.
Definition: nlua_pilot.c:495
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
unsigned int pilot_addStack(Pilot *p)
Adds a pilot to the stack.
Definition: pilot.c:3262
void pilot_msg(Pilot *p, Pilot *receiver, const char *type, unsigned int idx)
Sends a message.
Definition: pilot.c:3941
Pilot * pilot_getTarget(Pilot *p)
Gets the target of a pilot using a fancy caching system.
Definition: pilot.c:607
void pilot_reset(Pilot *pilot)
Resets a pilot.
Definition: pilot.c:3088
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
Definition: pilot.c:589
void pilot_calcStats(Pilot *pilot)
Recalculates the pilot's stats based on his outfits.
Definition: pilot_outfit.c:877
int pilot_dock(Pilot *p, Pilot *target)
Docks the pilot on its target pilot.
Definition: pilot_outfit.c:189
Player_t player
Definition: player.c:73
const Ship * ship_get(const char *name)
Gets a ship based on its name.
Definition: ship.c:73
StarSystem * cur_system
Definition: space.c:105
Stores an escort.
Definition: pilot.h:199
unsigned int id
Definition: pilot.h:202
int persist
Definition: pilot.h:204
EscortType_t type
Definition: pilot.h:201
char * ship
Definition: pilot.h:200
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:210
Solid * solid
Definition: pilot.h:220
unsigned int id
Definition: pilot.h:211
unsigned int parent
Definition: pilot.h:325
ShipStats intrinsic_stats
Definition: pilot.h:285
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
unsigned int target
Definition: pilot.h:334
int dockslot
Definition: pilot.h:331
Pilot * p
Definition: player.h:101
double launch_damage
Definition: shipstats.h:259
double thrust_mod
Definition: shipstats.h:205
double turn_mod
Definition: shipstats.h:204
double tur_damage
Definition: shipstats.h:282
double fwd_damage
Definition: shipstats.h:275
double speed_mod
Definition: shipstats.h:203
double shield_mod
Definition: shipstats.h:216
double armour_mod
Definition: shipstats.h:221
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
vec2 pos
Definition: physics.h:22
Represents a 2d vector.
Definition: vec2.h:32