naev 0.11.5
player_fleet.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 "player_fleet.h"
14
15#include "array.h"
16#include "dialogue.h"
17#include "escort.h"
18#include "land.h"
19#include "equipment.h"
20
24void pfleet_update (void)
25{
26 const PlayerShip_t *pships = player_getShipStack();
28 for (int i=0; i<array_size(pships); i++) {
29 const PlayerShip_t *ps = &pships[i];
30 if (ps->deployed)
31 player.fleet_used += ps->p->ship->points;
32 }
33
34 /* Redistribute the cargo. */
36}
37
45int pfleet_toggleDeploy( PlayerShip_t *ps, int deploy )
46{
47 /* When undeploying we want to make sure cargo fits. */
48 if (ps->deployed && !deploy) {
49 int idx;
50 Pilot *p = ps->p;
51 int q = pilot_cargoUsed( p ); /* Amount we have to allocate. */
52 int f = pfleet_cargoFree() - pilot_cargoFree( p ); /* Real free amount. */
53 if (f < q) {
54 char buf_amount[ECON_MASS_STRLEN], buf_free[ECON_MASS_STRLEN], buf_needed[ECON_MASS_STRLEN];
55 tonnes2str( buf_amount, q );
56 tonnes2str( buf_free, -f );
57 tonnes2str( buf_needed, q-f );
58 if (!dialogue_YesNo( _("Not Enough Cargo Space"), _("Your ship '%s' has %s of cargo but there is only %s of free space in the rest of the fleet. Get rid of %s of cargo to shrink your fleet?"), p->name, buf_amount, buf_free, buf_needed ))
59 return -1;
60 }
61 /* Try to make room for the commodities. */
62 idx = -1;
63 for (int i=0; i<array_size(player.p->escorts); i++) {
64 const Escort_t *e = &player.p->escorts[i];
65 const Pilot *pe = pilot_get( e->id );
66 if (pe == NULL)
67 continue;
68 if (e->type != ESCORT_TYPE_FLEET)
69 continue;
70 if (strcmp( pe->name, p->name )==0) {
71 idx = i;
72 break;
73 }
74 }
75 if (idx < 0)
76 WARN(_("Player deployed ship '%s' not found in escort list!"), p->name);
77 else
79
80 /* Try to add the cargo. */
81 for (int i=0; i<array_size(p->commodities); i++) {
82 const PilotCommodity *pc = &p->commodities[i];
84 pilot_cargoRm( p, pc->commodity, pc->quantity );
85 }
86 }
87 ps->deployed = deploy;
88 if (!ps->deployed) {
89 pilot_stackRemove( ps->p );
90 pilot_free( ps->p );
91 }
92 else
93 pfleet_deploy( ps );
95
96 /* Have to update GUI. */
97 equipment_updateShips( land_getWid( LAND_WINDOW_EQUIPMENT ), NULL );
98 return 0;
99}
100
110{
111 double a;
112 vec2 v;
113
114 /* Get the position. */
115 a = RNGF() * 2. * M_PI;
116 vec2_cset( &v, player.p->solid.pos.x + 50.*cos(a),
117 player.p->solid.pos.y + 50.*sin(a) );
118
119 /* Add the escort to the fleet. */
120 escort_createRef( player.p, ps->p, &v, NULL, a, ESCORT_TYPE_FLEET, 1, -1 );
121
122 /* Initialize. */
123 ai_pinit( ps->p, "escort" );
124 pilot_reset( ps->p );
125 pilot_setFlag( ps->p, PILOT_INVINC_PLAYER );
126 pilot_rmFlag( ps->p, PILOT_PLAYER );
127
128 /* AI only knows how to use auto weapon sets. */
129 pilot_weaponAuto( ps->p );
130
131 return 0;
132}
133
134static void shipCargo( PilotCommodity **pclist, Pilot *p, int remove )
135{
136 for (int i=array_size(p->commodities)-1; i>=0; i--) {
137 const PilotCommodity *pc = &p->commodities[i];
138 int q = pc->quantity;
139
140 /* Mission cargo gets added independently. */
141 if (pc->id > 0)
142 array_push_back( pclist, *pc );
143 else {
144 /* See if it can be added. */
145 int added = 0;
146 for (int j=0; j<array_size(*pclist); j++) {
147 PilotCommodity *lc = &(*pclist)[j];
148
149 /* Ignore mission cargo. */
150 if (lc->id > 0)
151 continue;
152
153 /* Cargo must match. */
154 if (pc->commodity != lc->commodity)
155 continue;
156
157 lc->quantity += q;
158 added = 1;
159 break;
160 }
161 if (!added)
162 array_push_back( pclist, *pc );
163 }
164
165 /* Remove the cargo. TODO use pilot_cargoRm somehow. */
166 if (remove)
167 array_erase( &p->commodities, &pc[0], &pc[1] );
168 }
169
170 /* Update cargo. */
171 if (remove)
172 pilot_cargoCalc( p );
173}
174
175static int pc_cmp( const void *pa, const void *pb )
176{
177 const PilotCommodity *pca, *pcb;
178 pca = (const PilotCommodity*) pa;
179 pcb = (const PilotCommodity*) pb;
180 /* Prioritize mission cargo first. */
181 if ((pca->id > 0) && (pcb->id==0))
182 return -1;
183 else if ((pca->id == 0) && (pcb->id > 0))
184 return +1;
185 /* Just do price at the end. */
186 return pcb->commodity->price - pca->commodity->price;
187}
188
193{
195
196 /* First build up a list of all the potential cargo. */
197 shipCargo( &pclist, player.p, 1 );
198 for (int i=0; i<array_size(player.p->escorts); i++) {
199 const Escort_t *e = &player.p->escorts[i];
200 Pilot *pe = pilot_get( e->id );
201 if (pe == NULL)
202 continue;
203 if (e->type != ESCORT_TYPE_FLEET)
204 continue;
205 shipCargo( &pclist, pe, 1 );
206 }
207
208 /* Sort based on base price. */
209 qsort( pclist, array_size(pclist), sizeof(PilotCommodity), pc_cmp );
210
211 /* Re-add the cargo. */
212 for (int i=0; i<array_size(pclist); i++) {
213 int q;
214 const PilotCommodity *pc = &pclist[i];
215
216 if (pc->id > 0)
217 q = pilot_cargoAddRaw( player.p, pc->commodity, pc->quantity, pc->id );
218 else {
219 q = pfleet_cargoAdd( pc->commodity, pc->quantity );
220 /* When landed, just stuff everything on the player's ship as they may not be ready for take-off yet. */
221 if (landed && (q < pc->quantity))
222 q += pilot_cargoAddRaw( player.p, pc->commodity, pc->quantity-q, pc->id );
223 }
224#ifdef DEBUGGING
225 if (q != pc->quantity)
226 WARN(_("Failure to add cargo '%s' to player fleet. Only %d of %d added."), pc->commodity->name, q, pc->quantity );
227#endif /* DEBUGGING */
228 (void) q;
229 }
230
231 array_free( pclist );
232}
233
240{
241 if (player.p == NULL)
242 return 0;
243 int cargo_used = pilot_cargoUsed( player.p );
244 if (player.fleet_capacity <= 0)
245 return cargo_used;
246 for (int i=0; i<array_size(player.p->escorts); i++) {
247 const Escort_t *e = &player.p->escorts[i];
248 const Pilot *pe = pilot_get( e->id );
249 if (pe == NULL)
250 continue;
251 if (e->type != ESCORT_TYPE_FLEET)
252 continue;
253 cargo_used += pilot_cargoUsed( pe );
254 }
255 return cargo_used;
256}
257
264{
265 if (player.p == NULL)
266 return 0;
267 int cargo_free = pilot_cargoFree( player.p );
268 if (player.fleet_capacity <= 0)
269 return cargo_free;
270 for (int i=0; i<array_size(player.p->escorts); i++) {
271 const Escort_t *e = &player.p->escorts[i];
272 const Pilot *pe = pilot_get( e->id );
273 if (pe == NULL)
274 continue;
275 if (e->type != ESCORT_TYPE_FLEET)
276 continue;
277 cargo_free += pilot_cargoFree( pe );
278 }
279 return cargo_free;
280}
281
289{
290 if (player.p == NULL)
291 return 0;
292 int amount = pilot_cargoOwned( player.p, com );
293 if (player.fleet_capacity <= 0)
294 return amount;
295 for (int i=0; i<array_size(player.p->escorts); i++) {
296 const Escort_t *e = &player.p->escorts[i];
297 const Pilot *pe = pilot_get( e->id );
298 if (pe == NULL)
299 continue;
300 if (e->type != ESCORT_TYPE_FLEET)
301 continue;
302 amount += pilot_cargoOwned( pe, com );
303 }
304 return amount;
305}
306
314int pfleet_cargoAdd( const Commodity *com, int q )
315{
316 if (player.p == NULL)
317 return 0;
318 int added = pilot_cargoAdd( player.p, com, q, 0 );
319 if ((player.fleet_capacity <= 0) || (q-added <= 0))
320 return added;
321 for (int i=0; i<array_size(player.p->escorts); i++) {
322 const Escort_t *e = &player.p->escorts[i];
323 Pilot *pe = pilot_get( e->id );
324 if (pe == NULL)
325 continue;
326 if (e->type != ESCORT_TYPE_FLEET)
327 continue;
328 added += pilot_cargoAdd( pe, com, q-added, 0 );
329 if (q-added <= 0)
330 break;
331 }
332 return added;
333}
334
343int pfleet_cargoRm( const Commodity *com, int q, int jet )
344{
345 int removed;
346 if (player.p == NULL)
347 return 0;
348 if (player.fleet_capacity <= 0)
349 return pilot_cargoRm( player.p, com, q );
350 removed = 0;
351 for (int i=0; i<array_size(player.p->escorts); i++) {
352 const Escort_t *e = &player.p->escorts[i];
353 Pilot *pe = pilot_get( e->id );
354 if (pe == NULL)
355 continue;
356 if (e->type != ESCORT_TYPE_FLEET)
357 continue;
358
359 if (jet)
360 removed += pilot_cargoJet( pe, com, q-removed, 0 );
361 else
362 removed += pilot_cargoRm( pe, com, q-removed );
363
364 if (q-removed <= 0)
365 break;
366 }
367 if (q-removed > 0) {
368 if (jet)
369 removed += pilot_cargoJet( player.p, com, q, 0 );
370 else
371 removed += pilot_cargoRm( player.p, com, q );
372 }
373 return removed;
374}
375
382{
384 shipCargo( &pclist, player.p, 0 );
385 for (int i=0; i<array_size(player.p->escorts); i++) {
386 const Escort_t *e = &player.p->escorts[i];
387 Pilot *pe = pilot_get( e->id );
388 if (pe == NULL)
389 continue;
390 if (e->type != ESCORT_TYPE_FLEET)
391 continue;
392 shipCargo( &pclist, pe, 0 );
393 }
394 return pclist;
395}
396
404{
406 int q = pilot_cargoOwned( player.p, com );
407 if (q > 0) {
408 PFleetCargo fc = { .p=player.p, .q=q };
409 array_push_back( &plist, fc );
410 }
411 for (int i=0; i<array_size(player.p->escorts); i++) {
412 const Escort_t *e = &player.p->escorts[i];
413 Pilot *pe = pilot_get( e->id );
414 if (pe == NULL)
415 continue;
416 if (e->type != ESCORT_TYPE_FLEET)
417 continue;
418 q = pilot_cargoOwned( pe, com );
419 if (q > 0) {
420 PFleetCargo fc = { .p=pe, .q=q };
421 array_push_back( &plist, fc );
422 }
423 }
424 return plist;
425}
int ai_pinit(Pilot *p, const char *ai)
Initializes the pilot in the ai.
Definition ai.c:496
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition array.h:158
#define array_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_push_back(ptr_array, element)
Adds a new element at the end of the array.
Definition array.h:129
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Definition array.h:93
void tonnes2str(char *str, int tonnes)
Converts tonnes to a usable string for displaying.
Definition commodity.c:108
int dialogue_YesNo(const char *caption, const char *fmt,...)
Runs a dialogue with both yes and no options.
Definition dialogue.c:352
void equipment_updateShips(unsigned int wid, const char *str)
Updates the player's ship window.
Definition equipment.c:1801
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:186
void escort_rmListIndex(Pilot *p, int i)
Remove from escorts list.
Definition escort.c:73
unsigned int land_getWid(int window)
Gets the WID of a window by type.
Definition land.c:889
int landed
Definition land.c:75
Header file with generic functions and naev-specifics.
void pilot_free(Pilot *p)
Frees and cleans up a pilot.
Definition pilot.c:3555
void pilot_stackRemove(Pilot *p)
Tries to remove a pilot from the stack.
Definition pilot.c:3640
void pilot_reset(Pilot *pilot)
Resets a pilot.
Definition pilot.c:3185
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
Definition pilot.c:620
int pilot_cargoFree(const Pilot *p)
Gets the pilot's free cargo space.
Definition pilot_cargo.c:51
int pilot_cargoRm(Pilot *pilot, const Commodity *cargo, int quantity)
Tries to get rid of quantity cargo from pilot.
int pilot_cargoOwned(const Pilot *pilot, const Commodity *cargo)
Gets how many of the commodity a pilot has.
Definition pilot_cargo.c:36
int pilot_cargoJet(Pilot *p, const Commodity *cargo, int quantity, int simulate)
Tries to get rid of quantity cargo from pilot, jetting it into space.
int pilot_cargoAdd(Pilot *pilot, const Commodity *cargo, int quantity, unsigned int id)
Tries to add quantity of cargo to pilot.
int pilot_cargoUsed(const Pilot *p)
Gets how much cargo ship has on board.
int pilot_cargoAddRaw(Pilot *pilot, const Commodity *cargo, int quantity, unsigned int id)
Adds cargo without checking the pilot's free space.
void pilot_cargoCalc(Pilot *pilot)
Calculates how much cargo ship has left and such.
void pilot_weaponAuto(Pilot *p)
Tries to automatically set and create the pilot's weapon set.
const PlayerShip_t * player_getShipStack(void)
Gets the array (array.h) of the player's ships.
Definition player.c:2644
Player_t player
Definition player.c:74
int pfleet_toggleDeploy(PlayerShip_t *ps, int deploy)
Toggles a player ship as deployed.
int pfleet_deploy(PlayerShip_t *ps)
Deploys a player's pilot.
PilotCommodity * pfleet_cargoList(void)
Gets a list of all the cargo in the fleet.
PFleetCargo * pfleet_cargoListShips(const Commodity *com)
Gets the list of ships that are carry a certain commodity in the player fleet and the amount they are...
int pfleet_cargoFree(void)
Gets the total amount of free cargo space in the player's fleet.
void pfleet_cargoRedistribute(void)
Redistributes the cargo in the player's fleet.
int pfleet_cargoOwned(const Commodity *com)
Gets the total amount of a commodity type owned by the player's fleet.
int pfleet_cargoAdd(const Commodity *com, int q)
Adds some cargo to the player's fleet.
int pfleet_cargoRm(const Commodity *com, int q, int jet)
Removes some cargo from the player's fleet.
int pfleet_cargoUsed(void)
Gets the total cargo space used by the player's fleet.
void pfleet_update(void)
Updates the used fleet capacity of the player.
Represents a commodity.
Definition commodity.h:43
char * name
Definition commodity.h:44
double price
Definition commodity.h:52
Stores an escort.
Definition pilot.h:206
unsigned int id
Definition pilot.h:209
EscortType_t type
Definition pilot.h:208
Stores a pilot commodity.
Definition pilot.h:179
const Commodity * commodity
Definition pilot.h:180
unsigned int id
Definition pilot.h:182
The representation of an in-game pilot.
Definition pilot.h:217
const Ship * ship
Definition pilot.h:226
Solid solid
Definition pilot.h:227
char * name
Definition pilot.h:219
Escort_t * escorts
Definition pilot.h:334
Player ship.
Definition player.h:73
int deployed
Definition player.h:80
Pilot * p
Definition player.h:74
Pilot * p
Definition player.h:101
int fleet_used
Definition player.h:125
int fleet_capacity
Definition player.h:126
int points
Definition ship.h:99
vec2 pos
Definition physics.h:49
Represents a 2d vector.
Definition vec2.h:32
double y
Definition vec2.h:34
double x
Definition vec2.h:33