naev 0.10.4
land_shipyard.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <assert.h>
11#include <math.h>
12#include <stdio.h>
13#include <stdlib.h>
14
15#include "naev.h"
18#include "land_shipyard.h"
19
20#include "array.h"
21#include "cond.h"
22#include "dialogue.h"
23#include "hook.h"
24#include "log.h"
25#include "map_find.h"
26#include "ndata.h"
27#include "nstring.h"
28#include "player.h"
29#include "player_fleet.h"
30#include "space.h"
31#include "tk/toolkit_priv.h"
32#include "toolkit.h"
33
34#define SHIP_GFX_W 256
35#define SHIP_GFX_H 256
36
37/*
38 * Vars.
39 */
40static Ship **shipyard_list = NULL;
41static Ship* shipyard_selected = NULL;
42static glTexture *shipyard_comm = NULL;
44/*
45 * Helper functions.
46 */
47static int shipyard_canAcquire( const Ship *ship, const Spob *spob, credits_t price );
48static void shipyard_buy( unsigned int wid, const char* str );
49static void shipyard_trade( unsigned int wid, const char* str );
50static void shipyard_rmouse( unsigned int wid, const char* widget_name );
51static void shipyard_renderSlots( double bx, double by, double bw, double bh, void *data );
52static void shipyard_renderSlotsRow( double bx, double by, double bw, const char *str, ShipOutfitSlot *s );
53static void shipyard_find( unsigned int wid, const char* str );
54
58void shipyard_open( unsigned int wid )
59{
60 ImageArrayCell *cships;
61 int nships;
62 int w, h, sw, sh;
63 int iw, ih;
64 int bw, bh, padding, off;
65 int iconsize;
66
67 /* Mark as generated. */
68 land_tabGenerate(LAND_WINDOW_SHIPYARD);
69
70 /* Init vars. */
72
73 /* Get window dimensions. */
74 window_dimWindow( wid, &w, &h );
75
76 /* Calculate image array dimensions. */
77 iw = 440 + (w - LAND_WIDTH);
78 ih = h - 60;
79
80 /* Ship image dimensions. */
81 sw = SHIP_GFX_W;
82 sh = SHIP_GFX_H;
83
84 /* Left padding + per-button padding * nbuttons */
85 padding = 40 + 20 * 4;
86
87 /* Calculate button dimensions. */
88 bw = (w - iw - padding) / 4;
89 bh = LAND_BUTTON_HEIGHT;
90
91 /* buttons */
92 off = -20;
93 window_addButtonKey( wid, off, 20,
94 bw, bh, "btnCloseShipyard",
95 _("Take Off"), land_buttonTakeoff, SDLK_t );
96 off -= 20+bw;
97 window_addButtonKey( wid, off, 20,
98 bw, bh, "btnTradeShip",
99 _("Trade-In"), shipyard_trade, SDLK_r );
100 off -= 20+bw;
101 window_addButtonKey( wid, off, 20,
102 bw, bh, "btnBuyShip",
103 _("Buy"), shipyard_buy, SDLK_b );
104 off -= 20+bw;
105 window_addButtonKey( wid, off, 20,
106 bw, bh, "btnFindShips",
107 _("Find Ships"), shipyard_find, SDLK_f );
108
109 /* target gfx */
110 window_addRect( wid, -40+4, -40+4, sw+8, sh+8, "rctTarget", &cBlack, 1 );
111 window_addImage( wid, -40, -40, sw, sh, "imgTarget", NULL, 0);
112
113 /* slot types */
114 window_addCust( wid, -20, -sh-50, sw-10, 80, "cstSlots", 0.,
115 shipyard_renderSlots, NULL, NULL, NULL, NULL );
116 window_canFocusWidget( wid, "cstSlots", 0 );
117
118 /* stat text */
119 window_addText( wid, -4, -sw-50-70-20, sw, -sh-60-70-20+h-bh, 0, "txtStats",
120 &gl_smallFont, NULL, NULL );
121
122 /* Placeholder text-boxes, calculated properly in shipyard_update(). */
123 window_addText( wid, iw+40, -35, 133, 427, 0, "txtSDesc", &gl_defFont, &cFontGrey, NULL );
124 window_addText( wid, iw+173, -35, w-sw-iw-208, 427, 0, "txtDDesc", &gl_defFont, NULL, NULL );
125 window_addText( wid, 20+iw+20, -462, w-(iw+40) - (sw+40), -482+h-bh, 0, "txtDescription", &gl_defFont, NULL, NULL );
126
127 /* set up the ships to buy/sell */
129 nships = array_size( shipyard_list );
130 cships = calloc( MAX(1,nships), sizeof(ImageArrayCell) );
131 if (nships <= 0) {
132 cships[0].image = NULL;
133 cships[0].caption = strdup(_("None"));
134 nships = 1;
135 }
136 else {
137 for (int i=0; i<nships; i++) {
138 cships[i].caption = strdup( _(shipyard_list[i]->name) );
139 cships[i].image = gl_dupTexture(shipyard_list[i]->gfx_store);
140 cships[i].layers = gl_copyTexArray( shipyard_list[i]->gfx_overlays, &cships[i].nlayers );
141 if (shipyard_list[i]->rarity > 0) {
142 glTexture *t = rarity_texture( shipyard_list[i]->rarity );
143 cships[i].layers = gl_addTexArray( cships[i].layers, &cships[i].nlayers, t );
144 }
145 }
146 }
147
148 iconsize = 128;
149 if (!conf.big_icons) {
150 if (toolkit_simImageArrayVisibleElements(iw,ih,iconsize,iconsize) < nships)
151 iconsize = 96;
152 /*
153 if (toolkit_simImageArrayVisibleElements(iw,ih,iconsize,iconsize) < nships)
154 iconsize = 64;
155 */
156 }
157 window_addImageArray( wid, 20, 20,
158 iw, ih, "iarShipyard", iconsize, iconsize,
159 cships, nships, shipyard_update, shipyard_rmouse, NULL );
160
161 /* write the shipyard stuff */
162 shipyard_update(wid, NULL);
163 /* Set default keyboard focuse to the list */
164 window_setFocus( wid , "iarShipyard" );
165}
171void shipyard_update( unsigned int wid, const char* str )
172{
173 (void)str;
174 int i, tw, th, y, w, h, sw, iw, bh;
175 Ship* ship;
176 char lbl[STRMAX], buf[STRMAX], buf_price[ECON_CRED_STRLEN], buf_credits[ECON_CRED_STRLEN];
177 char buf_license[STRMAX_SHORT];
178 double aspect, gw, gh;
179 size_t k = 0, l = 0;
180
181 i = toolkit_getImageArrayPos( wid, "iarShipyard" );
182
183 /* No ships */
184 if (i < 0 || array_size(shipyard_list) == 0) {
186 shipyard_comm = NULL;
187 window_modifyImage( wid, "imgTarget", NULL, 0, 0 );
188 window_disableButton( wid, "btnBuyShip");
189 window_disableButton( wid, "btnTradeShip");
190 window_modifyImage( wid, "imgTarget", NULL, 0, 0 );
191 window_modifyText( wid, "txtStats", NULL );
192 window_modifyText( wid, "txtDescription", NULL );
193 window_modifyText( wid, "txtSDesc", NULL );
194 window_modifyText( wid, "txtDDesc", NULL );
195 return;
196 }
197
198 ship = shipyard_list[i];
199 shipyard_selected = ship;
200
201 /* update image */
203 shipyard_comm = NULL;
205 aspect = shipyard_comm->w / shipyard_comm->h;
206 gw = MIN( shipyard_comm->w, SHIP_GFX_W );
207 gh = MIN( shipyard_comm->h, SHIP_GFX_H );
208 if (aspect > 1.)
209 gh /= aspect;
210 else
211 gw /= aspect;
212 window_destroyWidget( wid, "imgTarget" );
213 window_addImage( wid, -40-(SHIP_GFX_W-gw)/2, -30-(SHIP_GFX_H-gh)/2, gw, gh, "imgTarget", NULL, 0 );
214 window_modifyImage( wid, "imgTarget", shipyard_comm, gw, gh );
215
216 /* update text */
217 window_modifyText( wid, "txtStats", ship->desc_stats );
218 price2str( buf_price, ship_buyPrice(ship), player.p->credits, 2 );
219 credits2str( buf_credits, player.p->credits, 2 );
220
221 if (ship->license == NULL)
222 strncpy( buf_license, _("None"), sizeof(buf_license)-1 );
223 else if (player_hasLicense( ship->license ) ||
224 (land_spob != NULL && spob_hasService( land_spob, SPOB_SERVICE_BLACKMARKET )))
225 strncpy( buf_license, _(ship->license), sizeof(buf_license)-1 );
226 else
227 snprintf( buf_license, sizeof(buf_license), "#r%s#0", _(ship->license) );
228
229 k += scnprintf( &lbl[k], sizeof(lbl)-k, "%s", _("Model:") );
230 l += scnprintf( &buf[l], sizeof(buf)-l, "%s", _(ship->name) );
231 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Class:") );
232 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", _(ship_classDisplay(ship)) );
233 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Fabricator:") );
234 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", _(ship->fabricator) );
235 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Crew:") );
236 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%d", ship->crew );
237 if (player.fleet_capacity > 0) {
238 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Fleet Capacity:") );
239 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%d", ship->points );
240 }
241 /* Weapons & Manoeuvrability */
242 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n\n%s", _("Base Properties") );
243 l += scnprintf( &buf[l], sizeof(buf)-l, "\n\n%s", "");
244 if (ship->cpu > 0) {
245 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("CPU:") );
246 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%.0f %s", ship->cpu, n_( "teraflop", "teraflops", ship->cpu ) );
247 }
248 if (ship->mass) {
249 char buf_mass[ECON_MASS_STRLEN];
250 tonnes2str( buf_mass, ship->mass );
251 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Mass:") );
252 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", buf_mass );
253 }
254 if (ship->thrust) {
255 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Thrust:") );
256 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", "");
257 l += scnprintf( &buf[l], sizeof(buf)-l, _("%.0f kN/tonne"), ship->thrust );
258 }
259 if (ship->speed) {
260 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Speed:") );
261 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", "" );
262 l += scnprintf( &buf[l], sizeof(buf)-l, _("%.0f m/s"), ship->speed );
263 }
264 if (ship->turn) {
265 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Turn:") );
266 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", "" );
267 l += scnprintf( &buf[l], sizeof(buf)-l, _("%.0f deg/s"), ship->turn*180/M_PI );
268 }
269 if (ship->dt_default != 1.) {
270 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Time Constant:") );
271 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%.0f%%", ship->dt_default*100. );
272 }
273 /* Misc */
274 if (ship->dmg_absorb) {
275 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Absorption:") );
276 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", "" );
277 l += scnprintf( &buf[l], sizeof(buf)-l, _("%.0f%% damage"), ship->dmg_absorb*100. );
278 }
279 if (ship->shield || ship->shield_regen) {
280 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Shield:") );
281 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", "" );
282 l += scnprintf( &buf[l], sizeof(buf)-l, _("%.0f MJ (%.1f MW)"), ship->shield, ship->shield_regen );
283 }
284 if (ship->armour || ship->armour_regen) {
285 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Armour:") );
286 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", "" );
287 l += scnprintf( &buf[l], sizeof(buf)-l, _("%.0f MJ (%.1f MW)"), ship->armour, ship->armour_regen );
288 }
289 if (ship->energy || ship->energy_regen) {
290 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Energy:") );
291 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", "" );
292 l += scnprintf( &buf[l], sizeof(buf)-l, _("%.0f MJ (%.1f MW)"), ship->energy, ship->energy_regen );
293 }
294 if (ship->cap_cargo) {
295 char buf_cargo[ECON_MASS_STRLEN];
296 tonnes2str( buf_cargo, ship->cap_cargo );
297 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Cargo Space:") );
298 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", buf_cargo );
299 }
300 if (ship->fuel) {
301 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Fuel:") );
302 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%d %s", ship->fuel, n_( "unit", "units", ship->fuel ) );
303 }
304 if (ship->fuel_consumption != 100.) {
305 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Fuel Use:") );
306 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%d %s", ship->fuel_consumption, n_( "unit", "units", ship->fuel_consumption ) );
307 }
308
309 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n\n%s", _("Price:") );
310 l += scnprintf( &buf[l], sizeof(buf)-l, "\n\n%s", buf_price );
311 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Money:") );
312 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", buf_credits );
313 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("License:") );
314 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", buf_license );
315 if (ship->condstr) {
316 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Requires:") );
317 if (cond_check( ship->cond ))
318 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", _(ship->condstr) );
319 else
320 l += scnprintf( &buf[l], sizeof(buf)-l, "\n#r%s#0", _(ship->condstr) );
321 }
322
323 /* Calculate layout. */
324 window_dimWindow( wid, &w, &h );
325 iw = 440 + (w - LAND_WIDTH);
326 sw = SHIP_GFX_W;
327 bh = LAND_BUTTON_HEIGHT;
328 tw = gl_printWidthRaw( &gl_defFont, lbl );
329 th = gl_printHeightRaw( &gl_defFont, tw, lbl ) + gl_defFont.h;
330 y = -35;
331 window_modifyText( wid, "txtSDesc", lbl );
332 window_resizeWidget( wid, "txtSDesc", tw+20, th );
333 window_moveWidget( wid, "txtSDesc", 20+iw+20, y );
334 window_modifyText( wid, "txtDDesc", buf );
335 window_resizeWidget( wid, "txtDDesc", w-sw-40-(20+iw+20+128), th );
336 window_moveWidget( wid, "txtDDesc", 20+iw+20+tw+20, y );
337 y = MIN( y-th, -40-SHIP_GFX_H-20 );
338 window_modifyText( wid, "txtDescription", _(ship->description) );
339 window_resizeWidget( wid, "txtDescription", w-(20+iw+20) - (sw+40), y-20+h-bh );
340 window_moveWidget( wid, "txtDescription", 20+iw+20, y );
341
342 if (!shipyard_canBuy( ship->name, land_spob ))
343 window_disableButtonSoft( wid, "btnBuyShip");
344 else
345 window_enableButton( wid, "btnBuyShip");
346
347 if (!shipyard_canTrade( ship->name, land_spob ))
348 window_disableButtonSoft( wid, "btnTradeShip");
349 else
350 window_enableButton( wid, "btnTradeShip");
351}
352
357{
359 shipyard_list = NULL;
360 shipyard_selected = NULL;
362 shipyard_comm = NULL;
363}
364
370static void shipyard_find( unsigned int wid, const char* str )
371{
372 (void) str;
373 map_inputFindType(wid, "ship");
374}
375
381static void shipyard_rmouse( unsigned int wid, const char* widget_name )
382{
383 return shipyard_buy(wid, widget_name);
384}
385
391static void shipyard_buy( unsigned int wid, const char* str )
392{
393 (void)str;
394 int i;
395 char buf[STRMAX_SHORT];
396 Ship* ship;
397 HookParam hparam[2];
398
399 i = toolkit_getImageArrayPos( wid, "iarShipyard" );
400 if (i < 0 || array_size(shipyard_list) == 0)
401 return;
402
403 ship = shipyard_list[i];
404
405 credits_t targetprice = ship_buyPrice(ship);
406
407 if (land_errDialogue( ship->name, "buyShip" ))
408 return;
409
410 credits2str( buf, targetprice, 2 );
411 if (dialogue_YesNo(_("Are you sure?"), /* confirm */
412 _("Do you really want to spend %s on a new ship?"), buf )==0)
413 return;
414
415 /* Player just got a new ship */
416 snprintf( buf, sizeof(buf), _("Bought at %s in the %s system."), spob_name(land_spob), _(cur_system->name) );
417 if (player_newShip( ship, NULL, 0, buf, 0 ) == NULL) {
418 /* Player actually aborted naming process. */
419 return;
420 }
421 player_modCredits( -targetprice ); /* ouch, paying is hard */
422
423 /* Update shipyard. */
424 shipyard_update(wid, NULL);
425
426 /* Run hook. */
427 hparam[0].type = HOOK_PARAM_STRING;
428 hparam[0].u.str = ship->name;
429 hparam[1].type = HOOK_PARAM_SENTINEL;
430 hooks_runParam( "ship_buy", hparam );
431 land_needsTakeoff( 1 );
432}
433
434static int shipyard_canAcquire( const Ship *ship, const Spob *spob, credits_t price )
435{
436 int failure = 0;
437 int blackmarket = ((spob != NULL) && spob_hasService(spob, SPOB_SERVICE_BLACKMARKET));
438
439 /* Must have the necessary license. */
440 if (!blackmarket && !player_hasLicense(ship->license)) {
441 land_errDialogueBuild( _("You need the '%s' license to buy this ship."), _(ship->license) );
442 failure = 1;
443 }
444
445 /* Must meet conditional requirement. */
446 if (!blackmarket && (ship->cond!=NULL) && !cond_check( ship->cond )) {
447 land_errDialogueBuild( "%s", _(ship->condstr) );
448 failure = 1;
449 }
450
451 /* Must have enough credits. */
452 if (!player_hasCredits( price )) {
453 char buf[ECON_CRED_STRLEN];
454 credits2str( buf, price - player.p->credits, 2 );
455 land_errDialogueBuild( _("You need %s more."), buf);
456 failure = 1;
457 }
458 return !failure;
459}
460
466int shipyard_canBuy( const char *shipname, const Spob *spob )
467{
468 const Ship *ship = ship_get( shipname );
469 credits_t price = ship_buyPrice(ship);
470 return shipyard_canAcquire( ship, spob, price );
471}
472
477int can_sell( const char *shipname )
478{
479 int failure = 0;
480 if (strcmp( shipname, player.p->name )==0) { /* Already on-board. */
481 land_errDialogueBuild( _("You can't sell the ship you're piloting!") );
482 failure = 1;
483 }
484
485 return !failure;
486}
487
492int can_swap( const char *shipname )
493{
494 int failure = 0;
495 const Ship* ship = ship_get( shipname );
496 int diff;
497
499 diff = MAX( diff, pilot_cargoUsedMission(player.p) - ship->cap_cargo ); /* Has to fit all mission cargo. */
500 if (diff > 0) { /* Current ship has too much cargo. */
502 "You have %d tonne more cargo than the new ship can hold.",
503 "You have %d tonnes more cargo than the new ship can hold.",
504 diff ),
505 diff );
506 failure = 1;
507 }
508 if (pilot_hasDeployed(player.p)) { /* Escorts are in space. */
509 land_errDialogueBuild( _("You can't strand your fighters in space.") );
510 failure = 1;
511 }
512 return !failure;
513}
514
520int shipyard_canTrade( const char *shipname, const Spob *spob )
521{
522 const Ship *ship = ship_get( shipname );
523 credits_t price = ship_buyPrice(ship) - player_shipPrice(player.p->name);
524 return shipyard_canAcquire( ship, spob, price );
525}
526
532static void shipyard_trade( unsigned int wid, const char* str )
533{
534 (void)str;
535 int i;
536 char buf[STRMAX_SHORT], buf2[ECON_CRED_STRLEN],
537 buf3[ECON_CRED_STRLEN], buf4[ECON_CRED_STRLEN];
538 Ship* ship;
539
540 i = toolkit_getImageArrayPos( wid, "iarShipyard" );
541 if (i < 0 || shipyard_list == NULL)
542 return;
543
544 ship = shipyard_list[i];
545
546 credits_t targetprice = ship_buyPrice(ship);
547 credits_t playerprice = player_shipPrice(player.p->name);
548
549 if (land_errDialogue( ship->name, "tradeShip" ))
550 return;
551
552 credits2str( buf, targetprice, 2 );
553 credits2str( buf2, playerprice, 2 );
554 credits2str( buf3, targetprice - playerprice, 2 );
555 credits2str( buf4, playerprice - targetprice, 2 );
556
557 /* Display the correct dialogue depending on the new ship's price versus the player's. */
558 if ( targetprice == playerprice ) {
559 if (dialogue_YesNo(_("Are you sure?"), /* confirm */
560 _("Your %s is worth %s, exactly as much as the new ship, so no credits need be exchanged. Are you sure you want to trade your ship in?"),
561 _(player.p->ship->name), buf2)==0)
562 return;
563 }
564 else if ( targetprice < playerprice ) {
565 if (dialogue_YesNo(_("Are you sure?"), /* confirm */
566 _("Your %s is worth %s, more than the new ship. For your ship, you will get the new %s and %s. Are you sure you want to trade your ship in?"),
567 _(player.p->ship->name), buf2, _(ship->name), buf4)==0)
568 return;
569 }
570 else if ( targetprice > playerprice ) {
571 if (dialogue_YesNo(_("Are you sure?"), /* confirm */
572 _("Your %s is worth %s, so the new ship will cost %s. Are you sure you want to trade your ship in?"),
573 _(player.p->ship->name), buf2, buf3)==0)
574 return;
575 }
576
577 /* player just got a new ship */
578 snprintf( buf, sizeof(buf), _("Bought at %s in the %s system."), spob_name(land_spob), _(cur_system->name) );
579 if (player_newShip( ship, NULL, 1, buf, 0 ) == NULL)
580 return; /* Player aborted the naming process. */
581
582 player_modCredits( playerprice - targetprice ); /* Modify credits by the difference between ship values. */
583
584 land_refuel();
585
586 /* The newShip call will trigger a loadGUI that will recreate the land windows. Therefore the land ID will
587 * be void. We must reload in in order to properly update it again.*/
588 wid = land_getWid(LAND_WINDOW_SHIPYARD);
589
590 /* Update shipyard. */
591 shipyard_update(wid, NULL);
592}
593
597static void shipyard_renderSlots( double bx, double by, double bw, double bh, void *data )
598{
599 (void) data;
600 double x, y, w;
601 Ship *ship;
602
603 /* Make sure a valid ship is selected. */
604 ship = shipyard_selected;
605 if (ship == NULL)
606 return;
607
608 y = by + bh;
609
610 /* Draw rotated text. */
611 y -= 10+5;
612 gl_print( &gl_smallFont, bx, y, &cFontWhite, _("Slots:") );
613
614 x = bx + 10.;
615 w = bw - 10.;
616
617 /* Weapon slots. */
618 y -= 20;
619 shipyard_renderSlotsRow( x, y, w, _(OUTFIT_LABEL_WEAPON), ship->outfit_weapon );
620
621 /* Utility slots. */
622 y -= 20;
623 shipyard_renderSlotsRow( x, y, w, _(OUTFIT_LABEL_UTILITY), ship->outfit_utility );
624
625 /* Structure slots. */
626 y -= 20;
627 shipyard_renderSlotsRow( x, y, w, _(OUTFIT_LABEL_STRUCTURE), ship->outfit_structure );
628}
629
633static void shipyard_renderSlotsRow( double bx, double by, double bw, const char *str, ShipOutfitSlot *s )
634{
635 (void) bw;
636 double x;
637
638 x = bx;
639
640 /* Print text. */
641 gl_printMidRaw( &gl_smallFont, 30, bx-15, by, &cFontWhite, -1, str );
642
643 /* Draw squares. */
644 for (int i=0; i<array_size(s); i++) {
645 const glColour *c = outfit_slotSizeColour( &s[i].slot );
646 if (c == NULL)
647 c = &cBlack;
648
649 x += 15.;
650 toolkit_drawRect( x, by, 10, 10, c, NULL );
651
652 /* Add colour stripe depending on required/exclusiveness. */
653 if (s[i].required)
654 toolkit_drawTriangle( x, by, x+10, by+10, x, by+10, &cBrightRed );
655 else if (s[i].exclusive)
656 toolkit_drawTriangle( x, by, x+10, by+10, x, by+10, &cWhite );
657 else if (s[i].slot.spid != 0)
658 toolkit_drawTriangle( x, by, x+10, by+10, x, by+10, &cBlack );
659
660 gl_renderRectEmpty( x, by, 10, 10, &cBlack );
661 }
662}
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition: array.h:158
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition: array.h:168
int cond_check(const char *cond)
Checks to see if a condition is true.
Definition: cond.c:53
int dialogue_YesNo(const char *caption, const char *fmt,...)
Runs a dialogue with both yes and no options.
Definition: dialogue.c:344
int gl_printHeightRaw(const glFont *ft_font, const int width, const char *text)
Gets the height of a non-formatted string.
Definition: font.c:1026
glFont gl_smallFont
Definition: font.c:154
int gl_printWidthRaw(const glFont *ft_font, const char *text)
Gets the width that it would take to print some text.
Definition: font.c:960
glFont gl_defFont
Definition: font.c:153
int gl_printMidRaw(const glFont *ft_font, int width, double x, double y, const glColour *c, double outlineR, const char *text)
Displays text centered in position and width.
Definition: font.c:787
void gl_print(const glFont *ft_font, const double x, const double y, const glColour *c, const char *fmt,...)
Prints text on screen like printf.
Definition: font.c:690
int hooks_runParam(const char *stack, const HookParam *param)
Runs all the hooks of stack.
Definition: hook.c:967
unsigned int land_getWid(int window)
Gets the WID of a window by type.
Definition: land.c:963
void land_errDialogueBuild(const char *fmt,...)
Generates error dialogues used by several landing tabs.
Definition: land.c:288
int land_errDialogue(const char *name, const char *type)
Generates error dialogues used by several landing tabs.
Definition: land.c:256
Spob * land_spob
Definition: land.c:82
void land_buttonTakeoff(unsigned int wid, const char *unused)
Wrapper for takeoff mission button.
Definition: land.c:925
void land_refuel(void)
Refuels the player's current ship, if possible.
Definition: land.c:807
static void shipyard_renderSlotsRow(double bx, double by, double bw, const char *str, ShipOutfitSlot *s)
Renders a row of ship slots.
void shipyard_open(unsigned int wid)
Opens the shipyard window.
Definition: land_shipyard.c:58
int can_sell(const char *shipname)
Makes sure it's valid to sell a ship.
int shipyard_canBuy(const char *shipname, const Spob *spob)
Makes sure it's valid to buy a ship.
static void shipyard_find(unsigned int wid, const char *str)
Starts the map find with ship search selected.
int can_swap(const char *shipname)
Makes sure it's valid to change ships.
static glTexture * shipyard_comm
Definition: land_shipyard.c:42
static void shipyard_rmouse(unsigned int wid, const char *widget_name)
Player right-clicks on a ship.
void shipyard_cleanup(void)
Cleans up shipyard data.
static Ship ** shipyard_list
Definition: land_shipyard.c:40
int shipyard_canTrade(const char *shipname, const Spob *spob)
Makes sure it's valid to buy a ship, trading the old one in simultaneously.
static void shipyard_renderSlots(double bx, double by, double bw, double bh, void *data)
Custom widget render function for the slot widget.
static void shipyard_buy(unsigned int wid, const char *str)
Player attempts to buy a ship.
void shipyard_update(unsigned int wid, const char *str)
Updates the ships in the shipyard window.
static void shipyard_trade(unsigned int wid, const char *str)
Player attempts to buy a ship, trading the current ship in.
static Ship * shipyard_selected
Definition: land_shipyard.c:41
Header file with generic functions and naev-specifics.
#define MIN(x, y)
Definition: naev.h:40
#define MAX(x, y)
Definition: naev.h:39
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
void gl_renderRectEmpty(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
glTexture * gl_dupTexture(const glTexture *texture)
Duplicates a texture.
Definition: opengl_tex.c:809
glTexture ** gl_copyTexArray(glTexture **tex, int *n)
Copy a texture array.
Definition: opengl_tex.c:892
glTexture ** gl_addTexArray(glTexture **tex, int *n, glTexture *t)
Adds an element to a texture array.
Definition: opengl_tex.c:934
void gl_freeTexture(glTexture *texture)
Frees a texture.
Definition: opengl_tex.c:755
glTexture * rarity_texture(int rarity)
Definition: outfit.c:2726
const glColour * outfit_slotSizeColour(const OutfitSlot *os)
Gets the slot size colour for an outfit slot.
Definition: outfit.c:341
int pilot_cargoFree(const Pilot *p)
Gets the pilot's free cargo space.
Definition: pilot_cargo.c:51
int pilot_cargoUsedMission(const Pilot *p)
Gets how much mission cargo ship has on board.
Definition: pilot_cargo.c:203
int pilot_cargoUsed(const Pilot *p)
Gets how much cargo ship has on board.
Definition: pilot_cargo.c:189
int pilot_hasDeployed(Pilot *p)
Checks to see if the pilot has deployed ships.
Definition: pilot_outfit.c:251
int player_hasLicense(const char *license)
Checks to see if player has license.
Definition: player.c:2996
credits_t player_shipPrice(const char *shipname)
Calculates the price of one of the player's ships.
Definition: player.c:639
PlayerShip_t * player_newShip(const Ship *ship, const char *def_name, int trade, const char *acquired, int noname)
Creates a new ship for player.
Definition: player.c:382
credits_t player_modCredits(credits_t amount)
Modifies the amount of credits the player has.
Definition: player.c:947
Player_t player
Definition: player.c:73
int player_hasCredits(credits_t amount)
Checks to see if the player has enough credits.
Definition: player.c:936
int pfleet_cargoFree(void)
Gets the total amount of free cargo space in the player's fleet.
Definition: player_fleet.c:255
static const double c[]
Definition: rng.c:264
const char * ship_classDisplay(const Ship *s)
Gets the ship's display class in human readable form.
Definition: ship.c:162
credits_t ship_buyPrice(const Ship *s)
The ship buy price, includes default outfits.
Definition: ship.c:260
glTexture * ship_loadCommGFX(const Ship *s)
Loads the ship's comm graphic.
Definition: ship.c:289
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
const char * spob_name(const Spob *p)
Gets the translated name of a spob.
Definition: space.c:1705
The actual hook parameter.
Definition: hook.h:35
const char * str
Definition: hook.h:39
union HookParam::@4 u
HookParamType type
Definition: hook.h:36
credits_t credits
Definition: pilot.h:317
const Ship * ship
Definition: pilot.h:219
char * name
Definition: pilot.h:212
int big_icons
Definition: conf.h:126
Pilot * p
Definition: player.h:101
int fleet_capacity
Definition: player.h:131
Ship outfit slot.
Definition: ship.h:70
Represents a space ship.
Definition: ship.h:94
double shield_regen
Definition: ship.h:129
double dt_default
Definition: ship.h:123
double cap_cargo
Definition: ship.h:122
char * license
Definition: ship.h:105
char * name
Definition: ship.h:95
double thrust
Definition: ship.h:112
int fuel
Definition: ship.h:120
char * fabricator
Definition: ship.h:108
char * description
Definition: ship.h:109
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
char * condstr
Definition: ship.h:107
char * cond
Definition: ship.h:106
int points
Definition: ship.h:99
double cpu
Definition: ship.h:119
double speed
Definition: ship.h:114
ShipOutfitSlot * outfit_utility
Definition: ship.h:157
double turn
Definition: ship.h:113
char * desc_stats
Definition: ship.h:164
ShipOutfitSlot * outfit_weapon
Definition: ship.h:158
double energy
Definition: ship.h:130
double shield
Definition: ship.h:128
double mass
Definition: ship.h:118
ShipOutfitSlot * outfit_structure
Definition: ship.h:156
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Definition: space.h:88
tech_group_t * tech
Definition: space.h:116
int h
Definition: font.h:18
Abstraction for rendering sprite sheets.
Definition: opengl_tex.h:34
double w
Definition: opengl_tex.h:38
double h
Definition: opengl_tex.h:39
Ship ** tech_getShip(const tech_group_t *tech)
Gets all of the ships associated to a tech group.
Definition: tech.c:773
void window_setFocus(unsigned int wid, const char *wgtname)
Sets the focused widget in a window.
Definition: toolkit.c:2460
void window_dimWindow(unsigned int wid, int *w, int *h)
Gets the dimensions of a window.
Definition: toolkit.c:371
void window_canFocusWidget(unsigned int wid, const char *name, int canfocus)
Allows or disallows focusing a widget.
Definition: toolkit.c:523
void toolkit_drawRect(int x, int y, int w, int h, const glColour *c, const glColour *lc)
Draws a rectangle.
Definition: toolkit.c:1340
void window_moveWidget(unsigned int wid, const char *name, int x, int y)
Moves a widget.
Definition: toolkit.c:467
void toolkit_drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, const glColour *c)
Draws a rectangle.
Definition: toolkit.c:1388
void window_destroyWidget(unsigned int wid, const char *wgtname)
Destroys a widget in a window.
Definition: toolkit.c:1162
void window_resizeWidget(unsigned int wid, const char *name, int w, int h)
Resizes a widget.
Definition: toolkit.c:495