naev 0.10.4
map_system.c
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
5#include <float.h>
6#include <math.h>
7#include <stdio.h>
8#include <stdlib.h>
9
10#include "naev.h"
13#include "map.h"
14
15#include "array.h"
16#include "background.h"
17#include "colour.h"
18#include "dialogue.h"
19#include "economy.h"
20#include "faction.h"
21#include "gui.h"
22#include "land_outfits.h"
23#include "log.h"
24#include "mapData.h"
25#include "map_find.h"
26#include "map_system.h"
27#include "mission.h"
28#include "ndata.h"
29#include "nmath.h"
30#include "nstring.h"
31#include "opengl.h"
32#include "player.h"
33#include "space.h"
34#include "toolkit.h"
35
36#define BUTTON_WIDTH 80
37#define BUTTON_HEIGHT 30
39static StarSystem *cur_sys_sel = NULL;
40static int cur_spob_sel = 0;
41static Spob *cur_spobObj_sel = NULL;
42static Outfit **cur_spob_sel_outfits = NULL;
43static Ship **cur_spob_sel_ships = NULL;
44static int pitch = 0;
45static int nameWidth = 0;
46static int nshow = 0;
47static char infobuf[STRMAX];
48static unsigned int starCnt = 1;
49glTexture **bgImages;
51#define MAP_SYSTEM_WDWNAME "wdwSystemMap"
52#define MAPSYS_OUTFITS "mapSysOutfits"
53#define MAPSYS_SHIPS "mapSysShips"
54#define MAPSYS_TRADE "mapSysTrade"
55
56/*
57 * extern
58 */
59/*land.c*/
60//extern int landed;
61//extern Spob* land_spob;
62
63/*
64 * prototypes
65 */
66void map_system_cleanup( unsigned int wid, const char *str );
67int map_system_isOpen( void );
68
69/* Update. */
70void map_system_updateSelected( unsigned int wid );
71
72/* Render. */
73static void map_system_render( double bx, double by, double w, double h, void *data );
74/* Mouse. */
75static int map_system_mouse( unsigned int wid, SDL_Event* event, double mx, double my,
76 double w, double h, double rx, double ry, void *data );
77/* Misc. */
78static int map_system_keyHandler( unsigned int wid, SDL_Keycode key, SDL_Keymod mod );
79void map_system_show( int wid, int x, int y, int w, int h);
80
81static void map_system_genOutfitsList( unsigned int wid, float goodsSpace, float outfitSpace, float shipSpace );
82static void map_system_genShipsList( unsigned int wid, float goodsSpace, float outfitSpace, float shipSpace );
83static void map_system_genTradeList( unsigned int wid, float goodsSpace, float outfitSpace, float shipSpace );
84
85static void map_system_array_update( unsigned int wid, const char* str );
86
87void map_system_buyCommodPrice( unsigned int wid, const char *str );
88
94int map_system_init( void )
95{
96 return 0;
97}
98
104int map_system_load( void )
105{
106 return 0;
107}
108
112void map_system_exit( void )
113{
114 for (int i=0; i<array_size(bgImages); i++)
115 gl_freeTexture( bgImages[i] );
116 array_free( bgImages );
117 bgImages=NULL;
118}
119
123void map_system_cleanup( unsigned int wid, const char *str )
124{
125 (void) wid;
126 (void) str;
127
128 if (cur_sys_sel != cur_system)
129 space_gfxUnload( cur_sys_sel );
130
131 for (int i=0; i<array_size(bgImages); i++)
132 gl_freeTexture( bgImages[i] );
133 array_free( bgImages );
134 bgImages = NULL;
135 array_free( cur_spob_sel_outfits );
136 cur_spob_sel_outfits = NULL;
137 array_free( cur_spob_sel_ships );
138 cur_spob_sel_ships = NULL;
139}
140
144static int map_system_keyHandler( unsigned int wid, SDL_Keycode key, SDL_Keymod mod )
145{
146 (void) mod;
147 if (key == SDLK_m) {
148 window_close( wid, NULL );
149 return 1;
150 }
151 if (key == SDLK_UP) {
152 cur_spob_sel = MAX( cur_spob_sel-1, 0 );
153 map_system_updateSelected( wid );
154 return 1;
155 }
156 if (key == SDLK_DOWN) {
157 cur_spob_sel = MIN( cur_spob_sel+1, nshow );
158 map_system_updateSelected( wid );
159 return 1;
160 }
161 return 0;
162}
163
167void map_system_open( int sys_selected )
168{
169 unsigned int wid;
170 int w, h;
171 StarSystem *tmp_sys;
172 /* Destroy window if exists. */
173 wid = window_get( MAP_SYSTEM_WDWNAME );
174 if ( wid > 0 ) {
175 window_destroy( wid );
176 return;
177 }
178 cur_spobObj_sel = NULL;
179 memset( infobuf,0,sizeof(infobuf) );
180 pitch = 0;
181 nameWidth = 0;
182 nshow = 0;
183 starCnt = 1;
184
185 /* get the selected system. */
186 cur_sys_sel = system_getIndex( sys_selected );
187 cur_spob_sel = 0;
188 /* Set up window size. */
189 w = MAX(600, SCREEN_W - 140);
190 h = MAX(540, SCREEN_H - 140);
191
192 /* create the window. */
193 wid = window_create( MAP_SYSTEM_WDWNAME, _("System Info"), -1, -1, w, h );
195 window_onCleanup( wid, map_system_cleanup );
196 window_handleKeys( wid, map_system_keyHandler );
197 window_addText( wid, 40, h-30, 160, 20, 1, "txtSysname",
198 &gl_defFont, &cFontGreen, _(cur_sys_sel->name) );
199 window_addImage( wid, -90 + 32, h-30, 0, 0, "imgFaction", NULL, 0 );
200 /* Close button */
201 window_addButton( wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
202 "btnClose", _("Close"), window_close );
203 /* commodity price purchase button */
204 window_addButton( wid, -40-BUTTON_WIDTH, 20, BUTTON_WIDTH*3, BUTTON_HEIGHT,
205 "btnBuyCommodPrice", _("Buy commodity price info"), map_system_buyCommodPrice );
206 window_disableButton( wid, "btnBuyCommodPrice");
207
208 /* Load the spob gfx if necessary */
209 if (cur_sys_sel != cur_system)
210 space_gfxLoad( cur_sys_sel );
211 /* get textures for the stars. The first will be the nebula */
212 /* There seems no other reliable way of getting the correct images -*/
213 /* these are determined by a random number generator in lua */
214 /* This is a bit nasty - luckily Naev is single threaded! */
215 tmp_sys = cur_system;
216 cur_system = cur_sys_sel;
217 /* load background images */
219 background_load ( cur_system->background );
220 bgImages = background_getTextures();
221 if ( array_size( bgImages ) <= 1 )
222 starCnt = 0;
224 /* and reload the images for the current system */
225 cur_system = tmp_sys;
226 background_load( cur_system->background );
227
228 map_system_show( wid, 20, 60, w-40, h-100);
229 map_system_updateSelected( wid );
230}
231
237int map_system_isOpen( void)
238{
239 return window_exists( MAP_SYSTEM_WDWNAME );
240}
241
252void map_system_show( int wid, int x, int y, int w, int h)
253{
254 window_addCust( wid, x, y, w, h,
255 "cstMapSys", 1, map_system_render, map_system_mouse, NULL, NULL, NULL );
256}
257
268static void map_system_render( double bx, double by, double w, double h, void *data )
269{
270 (void) data;
271 int i, vis_index;
272 double iw, ih;
273 StarSystem *sys = cur_sys_sel;
274 Spob *p;
275 static int phase=0;
276 glColour ccol;
277 char buf[STRMAX];
278 int cnt;
279 double ast_nb, ast_area;
280 double f;
281 int hasPresence = 0;
282 double unknownPresence = 0;
283 char t;
284 int txtHeight;
285 const glTexture *logo;
286 int offset;
287
288 phase++;
289
290 if (phase > 150) {
291 phase = 0;
292 starCnt++;
293 if ( starCnt >= (unsigned int) array_size( bgImages ) ) {
294 if ( array_size( bgImages ) <= 1)
295 starCnt = 0;
296 else
297 starCnt = 1;
298 }
299 }
300 /* background */
301 gl_renderRect( bx, by, w, h, &cBlack );
302
303 vis_index=0;
304 offset = h - pitch*nshow;
305 for (i=0; i<array_size(sys->spobs); i++) {
306 p = sys->spobs[i];
307 if (!spob_isKnown( p ))
308 continue;
309 vis_index++;
310 if (p->gfx_space == NULL)
311 WARN( _("No gfx for %s…"),p->name );
312 else {
313 ih = pitch;
314 iw = ih;
315 if (p->gfx_space->w > p->gfx_space->h)
316 ih = ih * p->gfx_space->h / p->gfx_space->w;
317 else if ( p->gfx_space->w < p->gfx_space->h )
318 iw = iw * p->gfx_space->w / p->gfx_space->h;
319 gl_renderScale( p->gfx_space, bx+(pitch-iw)/2+2, by+(nshow-vis_index-1)*pitch + (pitch-ih)/2 + offset, iw, ih, &cWhite );
320 }
321 gl_printRaw( &gl_smallFont, bx + 5 + pitch, by + (nshow-vis_index-0.5)*pitch + offset,
322 (cur_spob_sel == vis_index ? &cFontGreen : &cFontWhite), -1., spob_name(p) );
323 }
324 /* draw the star */
325 ih = pitch;
326 iw = ih;
327 if (array_size( bgImages ) > 0) {
328 if ( bgImages[starCnt]->w > bgImages[starCnt]->h )
329 ih = ih * bgImages[starCnt]->h / bgImages[starCnt]->w;
330 else if ( bgImages[starCnt]->w < bgImages[starCnt]->h )
331 iw = iw * bgImages[starCnt]->w / bgImages[starCnt]->h;
332 ccol.r=ccol.g=ccol.b=ccol.a=1;
333 if ( phase > 120 && array_size( bgImages ) > 2 )
334 ccol.a = cos ( (phase-121)/30. *M_PI/2.);
335 gl_renderScale( bgImages[starCnt], bx+2 , by+(nshow-1)*pitch + (pitch-ih)/2 + offset, iw , ih, &ccol );
336 if ( phase > 120 && array_size( bgImages ) > 2) {
337 /* fade in the next star */
338 ih=pitch;
339 iw=ih;
340 i = starCnt + 1;
341 if ( i >= array_size( bgImages ) ) {
342 if ( array_size( bgImages ) <= 1 )
343 i=0;
344 else
345 i=1;
346 }
347 if ( bgImages[i]->w > bgImages[i]->h )
348 ih = ih * bgImages[i]->h / bgImages[i]->w;
349 else if ( bgImages[i]->w < bgImages[i]->h )
350 iw = iw * bgImages[i]->w / bgImages[i]->h;
351 ccol.a = 1 - ccol.a;
352 gl_renderScale( bgImages[i], bx+2, by+(nshow-1)*pitch + (pitch-ih)/2 + offset, iw, ih, &ccol );
353 }
354 }
355 else {
356 /* no nebula or star images - probably due to nebula */
357 txtHeight = gl_printHeightRaw( &gl_smallFont,pitch,_("Obscured by the nebula") );
358 gl_printTextRaw( &gl_smallFont, pitch, txtHeight, (bx+2),
359 (by + (nshow-0.5)*pitch + offset), 0, &cFontRed, -1., _("Obscured by the nebula") );
360 }
361 gl_printRaw( &gl_smallFont, bx + 5 + pitch, by + (nshow-0.5)*pitch + offset,
362 (cur_spob_sel == 0 ? &cFontGreen : &cFontWhite), -1., _(sys->name) );
363 if ((cur_spob_sel==0) && array_size( bgImages ) > 0) {
364 /* make use of space to draw a nice nebula */
365 double imgw,imgh, s;
366 iw = w - 50 - pitch - nameWidth;
367 ih = h;
368 imgw = bgImages[0]->w;
369 imgh = bgImages[0]->h;
370 s = MIN( iw / imgw, ih / imgh );
371 imgw *= s;
372 imgh *= s;
373 gl_renderScale( bgImages[0], bx+w-iw+(iw-imgw)*0.5, by+h-ih+(ih-imgh)*0.5, imgw, imgh, &cWhite );
374 }
375 /* draw marker around currently selected spob */
376 ccol.r=0; ccol.g=0.6+0.4*sin( phase/150.*2*M_PI ); ccol.b=0; ccol.a=1;
377 ih=15;
378 iw=3;
379 gl_renderRect( bx+1, by+(nshow-cur_spob_sel-1)*pitch + offset, iw, ih, &ccol );
380 gl_renderRect( bx+1, by+(nshow-cur_spob_sel)*pitch-ih + offset, iw, ih, &ccol );
381 gl_renderRect( bx+pitch+3-iw, by+(nshow-cur_spob_sel-1)*pitch + offset, iw, ih, &ccol );
382 gl_renderRect( bx+pitch+3-iw, by+(nshow-cur_spob_sel)*pitch-ih + offset, iw, ih, &ccol );
383 gl_renderRect( bx+1, by+(nshow-cur_spob_sel-1)*pitch + offset, ih, iw, &ccol );
384 gl_renderRect( bx+1, by+(nshow-cur_spob_sel)*pitch-iw + offset, ih, iw, &ccol );
385 gl_renderRect( bx+pitch+3-ih, by+(nshow-cur_spob_sel-1)*pitch + offset, ih, iw, &ccol );
386 gl_renderRect( bx+pitch+3-ih, by+(nshow-cur_spob_sel)*pitch-iw + offset, ih, iw, &ccol );
387 cnt=0;
388 buf[0]='\0';
389 if (cur_spob_sel == 0) {
390 int infopos = 0;
391 int stars = MAX( array_size( bgImages )-1, 0 );
392 cnt+=scnprintf( &buf[cnt], sizeof(buf)-cnt, _("System: %s\n"), _(sys->name) );
393 /* display sun information */
394 cnt+=scnprintf( &buf[cnt], sizeof(buf)-cnt, n_("%d-star system\n", "%d-star system\n", stars), stars );
395
396 /* Nebula. */
397 if (sys->nebu_density > 0. ) {
398 /* Volatility */
399 if (sys->nebu_volatility > 700.)
400 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Nebula: Volatile, ") );
401 else if (sys->nebu_volatility > 300.)
402 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Nebula: Dangerous, ") );
403 else if (sys->nebu_volatility > 0.)
404 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Nebula: Unstable, ") );
405 else
406 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Nebula: Stable, ") );
407
408 /* Density */
409 if (sys->nebu_density > 700.)
410 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Dense\n") );
411 else if (sys->nebu_density < 300.)
412 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Light\n") );
413 else
414 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Medium\n") );
415 } else
416 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Nebula: None\n") );
417
418 /* Interference. */
419 if (sys->interference > 0. ) {
420 if (sys->interference > 700.)
421 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Interference: Dense\n") );
422 else if (sys->interference < 300.)
423 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Interference: Light\n") );
424 }
425 /* Asteroids. */
426 if (array_size(sys->asteroids) > 0 ) {
427 ast_nb = ast_area = 0.;
428 for ( i=0; i<array_size(sys->asteroids); i++ ) {
429 ast_nb += sys->asteroids[i].nb;
430 ast_area = MAX( ast_area, sys->asteroids[i].area );
431 }
432 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Asteroid field density: %.2g\n"), ast_nb*ASTEROID_REF_AREA/ast_area );
433 }
434 /* Faction */
435 f = -1;
436 for (i=0; i<array_size(sys->spobs); i++) {
437 if (spob_isKnown( sys->spobs[i] )) {
438 if ((f==-1) && (sys->spobs[i]->presence.faction>=0) ) {
439 f = sys->spobs[i]->presence.faction;
440 } else if (f != sys->spobs[i]->presence.faction && (sys->spobs[i]->presence.faction>=0) ) {
441 cnt+=scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Faction: Multiple\n") );
442 break;
443 }
444 }
445 }
446 if (f == -1 ) {
447 cnt+=scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Faction: N/A\n") );
448 } else {
449 if (i==array_size(sys->spobs)) /* saw them all and all the same */
450 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Faction: %s\nStanding: %s\n"), faction_longname(f), faction_getStandingText( f ) );
451 /* display the logo */
452 logo = faction_logo( f );
453 if ( logo != NULL ) {
454 gl_renderScale( logo, bx + pitch + nameWidth + 200,
455 by + h - 21, 20, 20, &cWhite );
456 }
457 }
458 /* Get presence. */
459 hasPresence = 0;
460 unknownPresence = 0;
461 for ( i=0; i < array_size(sys->presence); i++ ) {
462 if (sys->presence[i].value <= 0)
463 continue;
464 hasPresence = 1;
465 if ( faction_isKnown( sys->presence[i].faction ) ) {
466 t = faction_getColourChar( sys->presence[i].faction );
467 cnt += scnprintf( &buf[cnt], sizeof( buf ) - cnt, "#0%s: #%c%.0f\n",
468 faction_shortname( sys->presence[i].faction ),
469 t, sys->presence[i].value);
470 } else
471 unknownPresence += sys->presence[i].value;
472 }
473 if (unknownPresence != 0)
474 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, "#0%s: #%c%.0f\n",
475 _("Unknown"), 'N', unknownPresence );
476 if (hasPresence == 0)
477 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Presence: N/A\n"));
478 txtHeight=gl_printHeightRaw(&gl_smallFont,(w - nameWidth-pitch-60)/2,buf);
479 gl_printTextRaw( &gl_smallFont, (w - nameWidth - pitch - 60) / 2, txtHeight,
480 bx + 10 + pitch + nameWidth, by + h - 10 - txtHeight, 0, &cFontWhite, -1., buf );
481
482 /* Jumps. */
483 for (i=0; i<array_size(sys->jumps); i++) {
484 if (jp_isUsable ( &sys->jumps[i])) {
485 if (infopos == 0) /* First jump */
486 infopos = scnprintf( infobuf, sizeof(infobuf), _(" Jump points to:\n") );
487 if (sys_isKnown( sys->jumps[i].target ))
488 infopos += scnprintf( &infobuf[infopos], sizeof(infobuf)-infopos, " %s\n", _(sys->jumps[i].target->name) );
489 else
490 infopos += scnprintf( &infobuf[infopos], sizeof(infobuf)-infopos, _(" Unknown system\n") );
491 }
492 }
493 } else {
494 /* display spob info */
495 p = cur_spobObj_sel;
496 if (p->presence.faction >= 0 ) {/* show the faction */
497 char factionBuf[64];
498 logo = faction_logo( p->presence.faction );
499 if (logo != NULL)
500 gl_renderScale( logo, bx + pitch + nameWidth + 200, by + h - 21, 20, 20, &cWhite );
501
502 snprintf( factionBuf, 64, "%s", faction_shortname( p->presence.faction ) );
503 gl_printTextRaw( &gl_smallFont, (w - nameWidth-pitch - 60) / 2, 20,
504 bx+pitch+nameWidth + 230, by + h - 31, 0, &cFontWhite, -1., factionBuf );
505 }
506
507 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("Spob: %s\nPlanetary class: %s Population: roughly %s\n"), spob_name(p), _(p->class), space_populationStr( p->population ) );
508 if (!spob_hasService( p, SPOB_SERVICE_INHABITED ))
509 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, _("No space port here\n") );
510 else if (p->can_land)
511 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, "#g%s#0", _("You can land here\n") );
512 else if (areEnemies( FACTION_PLAYER, p->presence.faction))
513 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, "#o%s#0", _("Not advisable to land here\n") );
514 else
515 cnt += scnprintf( &buf[cnt], sizeof(buf)-cnt, "#r%s#0", _("You cannot land here\n") );
516
517 if (infobuf[0]=='\0') {
518 int infocnt = 0;
519
520 /* Add a description */
521 infocnt += scnprintf( &infobuf[infocnt], sizeof(infobuf)-infocnt, "%s\n\n", (p->description==NULL?_("No description available"):_(p->description)) );
522
523 /* show some additional information */
524 infocnt += scnprintf( &infobuf[infocnt], sizeof(infobuf)-infocnt, "%s\n"
525 "%s\n%s\n%s\n%s\n%s\n%s\n%s",
526 spob_hasService( p, SPOB_SERVICE_LAND) ? _("This system is landable") : _("This system is not landable"),
527 spob_hasService( p, SPOB_SERVICE_INHABITED) ? _("This system is inhabited") : _("This system is not inhabited"),
528 spob_hasService( p, SPOB_SERVICE_REFUEL) ? _("You can refuel here") : _("You cannot refuel here"),
529 spob_hasService( p, SPOB_SERVICE_BAR) ? _("This system has a bar") : _("This system does not have a bar"),
530 spob_hasService( p, SPOB_SERVICE_MISSIONS) ? _("This system offers missions") : _("This system does not offer missions"),
531 spob_hasService( p, SPOB_SERVICE_COMMODITY) ? _("This system has a trade outlet") : _("This system does not have a trade outlet"),
532 spob_hasService( p, SPOB_SERVICE_OUTFITS) ? _("This system sells ship equipment") : _("This system does not sell ship equipment"),
533 spob_hasService( p, SPOB_SERVICE_SHIPYARD) ? _("This system sells ships") : _("This system does not sell ships"));
534 if (p->bar_description && spob_hasService( p, SPOB_SERVICE_BAR ))
535 infocnt += scnprintf( &infobuf[infocnt], sizeof(infobuf)-infocnt, "\n\n%s", _(p->bar_description) );
536 }
537
538 txtHeight = gl_printHeightRaw( &gl_smallFont, (w - nameWidth-pitch-60)/2, buf );
539
540 gl_printTextRaw( &gl_smallFont, (w - nameWidth - pitch - 60) / 2, txtHeight,
541 bx + 10 + pitch + nameWidth, by + h - 10 - txtHeight, 0, &cFontWhite, -1., buf );
542 }
543
544 /* show the trade/outfit/ship info */
545 if (infobuf[0]!='\0') {
546 txtHeight = gl_printHeightRaw( &gl_smallFont, (w - nameWidth-pitch-60)/2, infobuf );
547 gl_printTextRaw( &gl_smallFont, (w - nameWidth - pitch - 60) / 2, txtHeight,
548 bx + 10 + pitch + nameWidth, by + 10, 0, &cFontGrey, -1., infobuf );
549 }
550}
551
562static int map_system_mouse( unsigned int wid, SDL_Event* event, double mx, double my,
563 double w, double h, double rx, double ry, void *data )
564{
565 (void) data;
566 (void) rx;
567 (void) ry;
568
569 switch (event->type) {
570 case SDL_MOUSEBUTTONDOWN:
571 /* Must be in bounds. */
572 if ((mx < 0.) || (mx > w) || (my < 0.) || (my > h))
573 return 0;
574 if (mx < pitch && my > 0) {
575 if (cur_spob_sel != (h-my) / pitch) {
576 cur_spob_sel = ( h-my) / pitch;
577 map_system_updateSelected( wid );
578 }
579 return 1;
580 }
581 break;
582 }
583 return 0;
584}
585
586static void map_system_array_update( unsigned int wid, const char* str )
587{
588 int i;
589 Ship *ship;
590 char buf_price[ECON_CRED_STRLEN], buf_license[STRMAX_SHORT], buf_mass[ECON_MASS_STRLEN];
591 size_t l = 0;
592
593 infobuf[0] = '\0';
594 i = toolkit_getImageArrayPos( wid, str );
595 if (i < 0)
596 return;
597 if ((strcmp( str, MAPSYS_OUTFITS ) == 0)) {
598 Outfit *outfit = cur_spob_sel_outfits[i];
599 double mass = outfit->mass;
600
601 /* new text */
602 price2str( buf_price, outfit->price, player.p->credits, 2 );
603 if (outfit->license == NULL)
604 buf_license[0] = '\0';
605 else if (player_hasLicense( outfit->license ) ||
606 (cur_spobObj_sel != NULL && spob_hasService( cur_spobObj_sel, SPOB_SERVICE_BLACKMARKET )))
607 strncpy( buf_license, _(outfit->license), sizeof(buf_license)-1 );
608 else
609 snprintf( buf_license, sizeof( buf_license ), "#r%s#0", _(outfit->license) );
610
611 if (outfit_isLauncher(outfit))
612 mass += outfit_amount( outfit ) * outfit->u.lau.ammo_mass;
613 else if (outfit_isFighterBay(outfit))
614 mass += outfit_amount( outfit ) * outfit->u.bay.ship_mass;
615 snprintf( buf_mass, sizeof(buf_mass), n_( "%d t", "%d t", (int)round( mass ) ), (int)round( mass ) );
616
617 l += outfit_getNameWithClass( outfit, &infobuf[l], sizeof(infobuf)-l );
618 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "%s\n\n", pilot_outfitDescription( player.p, outfit ) );
619
620 /* FIXME: The point of this misery is to split desc_short into a 2-column layout.
621 * It works poorly, but if we don't do this, check out e.g. the TeraCom Medusa Launcher in a 720p window. */
622 char *desc_start = &infobuf[l];
623 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "%s\n\n", pilot_outfitSummary( player.p, outfit, 0 ) );
624 while ( (desc_start = strchr( desc_start, '\n' )) != NULL ) {
625 char *tab_pos = desc_start;
626 desc_start = strchr( &tab_pos[1], '\n' );
627 if (desc_start == NULL)
628 break;
629 *tab_pos = '\t';
630 desc_start++;
631 }
632
633 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "#n%s#0 %d ", _("Owned:"), player_outfitOwned( outfit ) );
634 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "#n%s#0 %s ", _("Mass:"), buf_mass );
635 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "#n%s#0 %s ", _("Price:"), buf_price );
636 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "%s", buf_license );
637 }
638 else if ((strcmp( str, MAPSYS_SHIPS ) == 0)) {
639 char buf_cargo[ECON_MASS_STRLEN];
640 ship = cur_spob_sel_ships[i];
641
642 /* update text */
643 price2str( buf_price, ship_buyPrice( ship ), player.p->credits, 2 );
644 tonnes2str( buf_mass, ship->mass );
645 tonnes2str( buf_cargo, ship->cap_cargo );
646 if (ship->license == NULL)
647 strncpy( buf_license, _("None"), sizeof(buf_license)-1 );
648 else if (player_hasLicense( ship->license )
649 || (cur_spobObj_sel != NULL && spob_hasService( cur_spobObj_sel, SPOB_SERVICE_BLACKMARKET )))
650 strncpy( buf_license, _(ship->license), sizeof(buf_license)-1 );
651 else
652 snprintf( buf_license, sizeof(buf_license), "#r%s#0", _(ship->license) );
653
654 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "#n%s#0 %s", _("Model:"), _(ship->name) );
655 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, " #n%s#0 %s", _("Class:"), _(ship_classDisplay(ship)) );
656 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n\n%s\n", _(ship->description) );
657 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n#n%s#0 %s", _("Fabricator:"), _(ship->fabricator) );
658 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, " #n%s#0 %d", _("Crew:"), ship->crew );
659 /* Weapons & Manoeuvrability */
660 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n#n%s#0 %.0f %s", _("CPU:"), ship->cpu, n_( "teraflop", "teraflops", ship->cpu ) );
661 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, " #n%s#0 %s", _("Mass:"), buf_mass );
662 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n#n%s#0 ", _("Thrust:") );
663 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, _("%.0f kN/tonne"), ship->thrust );
664 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, " #n%s#0 ", _("Speed:") );
665 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, _("%.0f m/s"), ship->speed );
666 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n#n%s#0 ", _("Turn:") );
667 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, _("%.0f deg/s"), ship->turn*180./M_PI );
668 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, " #n%s#0 %.0f%%", _("Time Constant:"), ship->dt_default*100. );
669 /* Misc */
670 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n#n%s#0 ", _("Absorption:") );
671 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, _("%.0f%% damage"), ship->dmg_absorb*100. );
672 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n#n%s#0 ", _("Shield:") );
673 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, _("%.0f MJ (%.1f MW)"), ship->shield, ship->shield_regen );
674 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, " #n%s#0 ", _("Armour:") );
675 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, _("%.0f MJ (%.1f MW)"), ship->armour, ship->armour_regen );
676 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n#n%s#0 ", _("Energy:") );
677 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, _("%.0f MJ (%.1f MW)"), ship->energy, ship->energy_regen );
678 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n#n%s#0 %s", _("Cargo Space:"), buf_cargo );
679 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n#n%s#0 %d %s", _("Fuel:"), ship->fuel, n_( "unit", "units", ship->fuel ) );
680 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, " #n%s#0 %d %s", _("Fuel Use:"),
681 ship->fuel_consumption, n_( "unit", "units", ship->fuel_consumption ) );
682 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n#n%s#0 %s", _("Price:"), buf_price );
683 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, " #n%s#0 %s", _("License:"), buf_license );
684 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n%s", ship->desc_stats );
685 }
686 else if ((strcmp( str, MAPSYS_TRADE ) == 0)) {
687 Commodity *com;
688 credits_t mean;
689 double std;
690 credits_t globalmean;
691 double globalstd;
692 char buf_mean[ECON_CRED_STRLEN], buf_globalmean[ECON_CRED_STRLEN];
693 char buf_std[ECON_CRED_STRLEN], buf_globalstd[ECON_CRED_STRLEN];
694 char buf_buy_price[ECON_CRED_STRLEN];
695 int owned;
696 com = cur_spobObj_sel->commodities[i];
697 economy_getAveragePrice( com, &globalmean, &globalstd );
698 economy_getAverageSpobPrice( com, cur_spobObj_sel, &mean, &std );
699 credits2str( buf_mean, mean, -1 );
700 snprintf( buf_std, sizeof(buf_std), "%.1f ¤", std ); /* TODO credit2str could learn to do this... */
701 credits2str( buf_globalmean, globalmean, -1 );
702 snprintf( buf_globalstd, sizeof(buf_globalstd), "%.1f ¤", globalstd ); /* TODO credit2str could learn to do this... */
703 owned=pilot_cargoOwned( player.p, com );
704
705 l = scnprintf( infobuf, sizeof(infobuf)-l, "%s\n\n%s\n\n", _(com->name), _(com->description) );
706
707 if ( owned > 0 ) {
708 credits2str( buf_buy_price, com->lastPurchasePrice, -1 );
709 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, n_(
710 "#nYou have:#0 %d tonne, purchased at %s/t\n",
711 "#nYou have:#0 %d tonnes, purchased at %s/t\n",
712 owned), owned, buf_buy_price );
713 }
714 else
715 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, n_(
716 "#nYou have:#0 %d tonne\n",
717 "#nYou have:#0 %d tonnes\n",
718 owned), owned );
719
720 l += scnprintf( &infobuf[l], sizeof(infobuf)-l,"#n%s#0 ", _("Average price seen here:") );
721 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, _("%s/t ± %s/t"), buf_mean, buf_std );
722 l += scnprintf( &infobuf[l], sizeof(infobuf)-l,"\n#n%s#0 ", _("Average price seen everywhere:") );
723 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, _("%s/t ± %s/t"), buf_globalmean, buf_globalstd );
724 l += scnprintf( &infobuf[l], sizeof(infobuf)-l, "\n%s", "" );
725 }
726 else
727 WARN( _("Unexpected call to map_system_array_update\n") );
728}
729
730void map_system_updateSelected( unsigned int wid )
731{
732 StarSystem *sys=cur_sys_sel;
733 Spob *last=NULL;
734 int spobObjChanged = 0;
735 int w, h;
736 Spob *p;
737 int textw;
738 int noutfits,nships,ngoods;
739 Outfit **outfits;
740 Ship **ships;
741 float g,o,s;
742 nameWidth = 0; /* get the widest spob/star name */
743 nshow=1;/* start at 1 for the sun*/
744 infobuf[0] = '\0'; /* clear buffer. */
745 for (int i=0; i<array_size(sys->spobs); i++) {
746 p = sys->spobs[i];
747 if (spob_isKnown( p )) {
749 if ( textw > nameWidth )
750 nameWidth = textw;
751 last = p;
752 if ( cur_spob_sel == nshow ) {
753 if ( cur_spobObj_sel != p )
754 spobObjChanged = 1;
755 cur_spobObj_sel = p;
756 }
757 nshow++;
758 }
759 }
760 /* get width of star name text */
761 textw = gl_printWidthRaw( &gl_smallFont, _(sys->name) );
762 if ( textw > nameWidth )
763 nameWidth = textw;
764
765 window_dimWindow( wid, &w, &h );
766
767 pitch = (h-100) / nshow;
768 if ( pitch > w/5 )
769 pitch = w/5;
770
771 if ( cur_spob_sel >= nshow ) {
772 cur_spob_sel = nshow-1;
773 if ( cur_spobObj_sel != last ) {
774 cur_spobObj_sel = last;
775 spobObjChanged = 1;
776 }
777 }
778 if ( cur_spob_sel <= 0 ) {
779 /* star selected */
780 cur_spob_sel = 0;
781 if ( cur_spobObj_sel != NULL ) {
782 cur_spobObj_sel = NULL;
783 spobObjChanged = 1;
784 }
785 }
786
787 if ( spobObjChanged ) {
788 infobuf[0]='\0';
789 if ( cur_spobObj_sel == NULL ) {
790 /*The star*/
791 noutfits = 0;
792 nships = 0;
793 ngoods = 0;
794 window_disableButton( wid, "btnBuyCommodPrice" );
795 } else {
796 /* get number of each to decide how much space the lists can have */
797 outfits = tech_getOutfit( cur_spobObj_sel->tech );
798 noutfits = array_size( outfits );
799 array_free( outfits );
800 ships = tech_getShip( cur_spobObj_sel->tech );
801 nships = array_size( ships );
802 array_free( ships );
803 ngoods = array_size( cur_spobObj_sel->commodities );
804 /* to buy commodity info, need to be landed, and the selected system must sell them! */
805 if ( landed && spob_hasService( cur_spobObj_sel, SPOB_SERVICE_COMMODITY ) )
806 window_enableButton( wid, "btnBuyCommodPrice" );
807 else
808 window_disableButton( wid, "btnBuyCommodPrice" );
809 }
810 /* determine the ratio of space */
811 s=g=o=0;
812 if ( ngoods != 0 )
813 g=0.35;
814
815 if ( noutfits != 0 ) {
816 if ( nships != 0 ) {
817 s=0.25;
818 o=1-g-s;
819 } else
820 o=1-g;
821 } else if ( nships!=0 )
822 s=1-g;
823 /* ensure total is ~1 */
824 g += 1 - g - o - s;
825 map_system_genOutfitsList( wid, g, o, s );
826 map_system_genShipsList( wid, g, o, s );
827 map_system_genTradeList( wid, g, o, s );
828 }
829}
830
836static void map_system_genOutfitsList( unsigned int wid, float goodsSpace, float outfitSpace, float shipSpace )
837{
838 int i;
839 ImageArrayCell *coutfits;
840 int noutfits;
841 int w, h;
842 int xpos, xw, ypos, yh;
843 int iconsize;
844 static Spob *spobDone = NULL;
845
846 window_dimWindow( wid, &w, &h );
847 if (spobDone == cur_spobObj_sel) {
848 if (widget_exists( wid, MAPSYS_OUTFITS ))
849 return;
850 } else {
851 if (widget_exists( wid, MAPSYS_OUTFITS )) {
852 window_destroyWidget( wid, MAPSYS_OUTFITS );
853 }
854 }
855 spobDone = cur_spobObj_sel;
856
857 /* Clean up array if exists. */
858 array_free( cur_spob_sel_outfits );
859 cur_spob_sel_outfits = NULL;
860
861 /* set up the outfits to buy/sell */
862 if (cur_spobObj_sel == NULL)
863 return;
864
865 /* No outfitter. */
866 if (!spob_hasService( cur_spobObj_sel, SPOB_SERVICE_OUTFITS ))
867 return;
868
869 cur_spob_sel_outfits = tech_getOutfit( cur_spobObj_sel->tech );
870 noutfits = array_size( cur_spob_sel_outfits );
871
872 if (noutfits <= 0)
873 return;
874 coutfits = outfits_imageArrayCells( (const Outfit**)cur_spob_sel_outfits, &noutfits, player.p );
875
876 xw = ( w - nameWidth - pitch - 60 ) / 2;
877 xpos = 35 + pitch + nameWidth + xw;
878 i = (goodsSpace!=0) + (outfitSpace!=0) + (shipSpace!=0);
879 yh = (h - 100 - (i+1)*5 ) * outfitSpace;
880 ypos = 65 + 5*(shipSpace!=0) + (h - 100 - (i+1)*5)*shipSpace;
881
882 iconsize = 64;
883 if (toolkit_simImageArrayVisibleElements( xw, yh, iconsize, iconsize ) < noutfits)
884 iconsize = 48;
885 window_addImageArray( wid, xpos, ypos,
886 xw, yh, MAPSYS_OUTFITS, iconsize, iconsize,
887 coutfits, noutfits, map_system_array_update, NULL, NULL );
888 toolkit_unsetSelection( wid, MAPSYS_OUTFITS );
889}
890
891static void map_system_genShipsList( unsigned int wid, float goodsSpace, float outfitSpace, float shipSpace )
892{
893 ImageArrayCell *cships;
894 int nships;
895 int xpos, ypos, xw, yh;
896 static Spob *spobDone=NULL;
897 int i, w, h, iconsize;
898 window_dimWindow( wid, &w, &h );
899
900 /* set up the ships that can be bought here */
901 if (spobDone == cur_spobObj_sel) {
902 if (widget_exists( wid, MAPSYS_SHIPS ))
903 return;
904 }
905 else {
906 if (widget_exists( wid, MAPSYS_SHIPS )) {
907 window_destroyWidget( wid, MAPSYS_SHIPS );
908 array_free( cur_spob_sel_ships );
909 cur_spob_sel_ships = NULL;
910 }
911 assert(cur_spob_sel_ships == NULL);
912 }
913 spobDone = cur_spobObj_sel;
914
915 /* set up the outfits to buy/sell */
916 if (cur_spobObj_sel == NULL)
917 return;
918
919 /* No shipyard. */
920 if (!spob_hasService( cur_spobObj_sel, SPOB_SERVICE_SHIPYARD ))
921 return;
922
923 cur_spob_sel_ships = tech_getShip( cur_spobObj_sel->tech );
924 nships = array_size( cur_spob_sel_ships );
925
926 if (nships <= 0)
927 return;
928
929 cships = calloc( nships, sizeof(ImageArrayCell) );
930 for ( i=0; i<nships; i++ ) {
931 cships[i].image = gl_dupTexture( cur_spob_sel_ships[i]->gfx_store );
932 cships[i].caption = strdup( _(cur_spob_sel_ships[i]->name) );
933 }
934 xw = (w - nameWidth - pitch - 60)/2;
935 xpos = 35 + pitch + nameWidth + xw;
936 i = (goodsSpace!=0) + (outfitSpace!=0) + (shipSpace!=0);
937 yh = (h - 100 - (i+1)*5 ) * shipSpace;
938 ypos = 65;
939
940 iconsize = 48;
941 if (toolkit_simImageArrayVisibleElements( xw, yh, iconsize, iconsize ) < nships )
942 iconsize = 48;
943 window_addImageArray( wid, xpos, ypos,
944 xw, yh, MAPSYS_SHIPS, iconsize, iconsize,
945 cships, nships, map_system_array_update, NULL, NULL );
946 toolkit_unsetSelection( wid, MAPSYS_SHIPS );
947}
948
949static void map_system_genTradeList( unsigned int wid, float goodsSpace, float outfitSpace, float shipSpace )
950{
951 static Spob *spobDone=NULL;
952 int i, ngoods;
953 ImageArrayCell *cgoods;
954 int xpos, ypos, xw, yh, w, h, iconsize;
955 window_dimWindow( wid, &w, &h );
956
957 /* set up the commodities that can be bought here */
958 if ( spobDone == cur_spobObj_sel ) {
959 if ( widget_exists( wid, MAPSYS_TRADE ) ) {
960 return;
961 }
962 } else {
963 if ( widget_exists( wid, MAPSYS_TRADE ) ) {
964 window_destroyWidget( wid, MAPSYS_TRADE );
965 }
966 }
967
968 /* goods list */
969 if (cur_spobObj_sel == NULL)
970 return;
971
972 /* No shipyard. */
973 if (!spob_hasService( cur_spobObj_sel, SPOB_SERVICE_COMMODITY ))
974 return;
975
976 spobDone = cur_spobObj_sel;
977
978 ngoods = array_size( cur_spobObj_sel->commodities );
979
980 if (ngoods <= 0)
981 return;
982 cgoods = calloc( ngoods, sizeof(ImageArrayCell) );
983 for ( i=0; i<ngoods; i++ ) {
984 cgoods[i].image = gl_dupTexture( cur_spobObj_sel->commodities[i]->gfx_store );
985 cgoods[i].caption = strdup( _(cur_spobObj_sel->commodities[i]->name) );
986 }
987 /* set up the goods to buy/sell */
988 xw = (w - nameWidth - pitch - 60)/2;
989 xpos = 35 + pitch + nameWidth + xw;
990 i = (goodsSpace!=0) + (outfitSpace!=0) + (shipSpace!=0);
991 yh = (h - 100 - (i+1)*5 ) * goodsSpace;
992 ypos = 60 + 5*i + (h-100 - (i+1)*5 )*(outfitSpace + shipSpace);
993
994 iconsize = 48;
995 if (toolkit_simImageArrayVisibleElements( xw, yh, iconsize, iconsize ) < ngoods )
996 iconsize = 48;
997 window_addImageArray( wid, xpos, ypos,
998 xw, yh, MAPSYS_TRADE, iconsize, iconsize,
999 cgoods, ngoods, map_system_array_update, NULL, NULL );
1000 toolkit_unsetSelection( wid, MAPSYS_TRADE );
1001}
1002
1006void map_system_buyCommodPrice( unsigned int wid, const char *str )
1007{
1008 (void) wid;
1009 (void) str;
1010 int njumps = 0;
1011 StarSystem **syslist;
1012 int cost;
1013 char coststr[ECON_CRED_STRLEN];
1014 ntime_t t = ntime_get();
1015
1016 /* find number of jumps */
1017 if ((strcmp( cur_system->name, cur_sys_sel->name ) == 0)) {
1018 cost = 500;
1019 njumps = 0;
1020 }
1021 else {
1022 syslist=map_getJumpPath( cur_system->name, cur_sys_sel->name, 1, 0, NULL);
1023 if ( syslist == NULL ) {
1024 /* no route */
1025 dialogue_msg( _("Unavailable"), _("Commodity prices for %s are not available here at the moment."), _(cur_spobObj_sel->name) );
1026 return;
1027 } else {
1028 cost = 500 + 300 * array_size( syslist );
1029 array_free ( syslist );
1030 }
1031 }
1032
1033 /* get the time at which this purchase will be made (2 periods per jump ago)*/
1034 t -= ( njumps * 2 + 0.2 ) * NT_PERIOD_SECONDS * 1000;
1035 credits2str( coststr, cost, -1 );
1036 if (!player_hasCredits( cost ))
1037 dialogue_msg( _("Insufficient Credits"), _("You need %s to purchase this information."), coststr );
1038 else if (array_size( cur_spobObj_sel->commodities ) == 0)
1039 dialogue_msgRaw( _("No commodities sold here"),_("There are no commodities sold here."));
1040 else if ( cur_spobObj_sel->commodityPrice[0].updateTime >= t )
1041 dialogue_msgRaw( _("Already Up-to-date"), _("You have newer information that what is available.") );
1042 else {
1043 int ret = dialogue_YesNo( _("Purchase commodity prices?"), _("Purchase %g period old pricing information for %s for %s?"),
1044 njumps*2+0.2, _(cur_spobObj_sel->name), coststr );
1045 if (ret) {
1046 player_modCredits( -cost );
1047 economy_averageSeenPricesAtTime( cur_spobObj_sel, t );
1048 map_system_array_update( wid, MAPSYS_TRADE );
1049 }
1050 }
1051}
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
glTexture ** background_getTextures(void)
returns the background images, and number of these
Definition: background.c:564
void background_clear(void)
Cleans up the background stuff.
Definition: background.c:509
int background_load(const char *name)
Loads a background script by name.
Definition: background.c:447
#define BUTTON_HEIGHT
Definition: board.c:33
#define BUTTON_WIDTH
Definition: board.c:32
void dialogue_msg(const char *caption, const char *fmt,...)
Opens a dialogue window with an ok button and a message.
Definition: dialogue.c:218
void dialogue_msgRaw(const char *caption, const char *msg)
Opens a dialogue window with an ok button and a fixed message.
Definition: dialogue.c:261
int dialogue_YesNo(const char *caption, const char *fmt,...)
Runs a dialogue with both yes and no options.
Definition: dialogue.c:344
int economy_getAveragePrice(const Commodity *com, credits_t *mean, double *std)
Gets the average price of a good as seen by the player (anywhere).
Definition: economy.c:242
int economy_getAverageSpobPrice(const Commodity *com, const Spob *p, credits_t *mean, double *std)
Gets the average price of a good on a spob in a system, using a rolling average over the times the pl...
Definition: economy.c:172
const char * faction_longname(int f)
Gets the faction's long name (formal, human-readable).
Definition: faction.c:346
int faction_isKnown(int id)
Is the faction known?
Definition: faction.c:273
char faction_getColourChar(int f)
Gets the faction character associated to its standing with the player.
Definition: faction.c:1040
const glTexture * faction_logo(int f)
Gets the faction's logo (ideally 256x256).
Definition: faction.c:451
int areEnemies(int a, int b)
Checks whether two factions are enemies.
Definition: faction.c:1197
const char * faction_shortname(int f)
Gets a factions short name (human-readable).
Definition: faction.c:323
const char * faction_getStandingText(int f)
Gets the player's standing in human readable form.
Definition: faction.c:1054
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
void gl_printRaw(const glFont *ft_font, double x, double y, const glColour *c, double outlineR, const char *text)
Prints text on screen.
Definition: font.c:616
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_printTextRaw(const glFont *ft_font, const int width, const int height, double bx, double by, int line_height, const glColour *c, double outlineR, const char *text)
Prints a block of text that fits in the dimensions given.
Definition: font.c:869
int landed
Definition: land.c:74
ImageArrayCell * outfits_imageArrayCells(const Outfit **outfits, int *noutfits, const Pilot *p)
Generates image array cells corresponding to outfits.
Definition: land_outfits.c:687
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
ntime_t ntime_get(void)
Gets the current time.
Definition: ntime.c:108
void gl_renderRect(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
Definition: opengl_render.c:90
void gl_renderScale(const glTexture *texture, double bx, double by, double bw, double bh, const glColour *c)
Blits a texture scaling it.
glTexture * gl_dupTexture(const glTexture *texture)
Duplicates a texture.
Definition: opengl_tex.c:809
void gl_freeTexture(glTexture *texture)
Frees a texture.
Definition: opengl_tex.c:755
int outfit_isLauncher(const Outfit *o)
Checks if outfit is a weapon launcher.
Definition: outfit.c:498
size_t outfit_getNameWithClass(const Outfit *outfit, char *buf, size_t size)
Gets a brief name/class description suitable for the title section of an outfitter screen.
Definition: outfit.c:394
int outfit_isFighterBay(const Outfit *o)
Checks if outfit is a fighter bay.
Definition: outfit.c:550
int outfit_amount(const Outfit *o)
Gets the amount an outfit can hold.
Definition: outfit.c:670
int pilot_cargoOwned(const Pilot *pilot, const Commodity *cargo)
Gets how many of the commodity a pilot has.
Definition: pilot_cargo.c:36
const char * pilot_outfitDescription(const Pilot *p, const Outfit *o)
Gets the description of an outfit for a given pilot.
const char * pilot_outfitSummary(const Pilot *p, const Outfit *o, int withname)
Gets the summary of an outfit for a give pilot.
int player_hasLicense(const char *license)
Checks to see if player has license.
Definition: player.c:2996
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 player_outfitOwned(const Outfit *o)
Gets how many of the outfit the player owns.
Definition: player.c:2701
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
void space_gfxUnload(StarSystem *sys)
Unloads all the graphics for a star system.
Definition: space.c:2068
StarSystem * system_getIndex(int id)
Get the system by its index.
Definition: space.c:944
StarSystem * cur_system
Definition: space.c:105
const char * space_populationStr(uint64_t population)
Gets the population in an approximated string. Note this function changes the string value each call,...
Definition: space.c:4332
const char * spob_name(const Spob *p)
Gets the translated name of a spob.
Definition: space.c:1705
void space_gfxLoad(StarSystem *sys)
Loads all the graphics for a star system.
Definition: space.c:2057
int64_t updateTime
Definition: commodity.h:74
Represents a commodity.
Definition: commodity.h:43
char * description
Definition: commodity.h:45
glTexture * gfx_store
Definition: commodity.h:53
char * name
Definition: commodity.h:44
credits_t lastPurchasePrice
Definition: commodity.h:57
double ammo_mass
Definition: outfit.h:204
A ship outfit, depends radically on the type.
Definition: outfit.h:304
credits_t price
Definition: outfit.h:322
OutfitLauncherData lau
Definition: outfit.h:373
OutfitFighterBayData bay
Definition: outfit.h:376
char * license
Definition: outfit.h:312
double mass
Definition: outfit.h:315
union Outfit::@22 u
credits_t credits
Definition: pilot.h:317
Pilot * p
Definition: player.h:101
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
double cpu
Definition: ship.h:119
double speed
Definition: ship.h:114
double turn
Definition: ship.h:113
char * desc_stats
Definition: ship.h:164
double energy
Definition: ship.h:130
double shield
Definition: ship.h:128
double mass
Definition: ship.h:118
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Definition: space.h:88
Commodity ** commodities
Definition: space.h:114
tech_group_t * tech
Definition: space.h:116
char * name
Definition: space.h:90
CommodityPrice * commodityPrice
Definition: space.h:115
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
Outfit ** tech_getOutfit(const tech_group_t *tech)
Gets all of the outfits associated to a tech group.
Definition: tech.c:725
unsigned int window_create(const char *name, const char *displayname, const int x, const int y, const int w, const int h)
Creates a window.
Definition: toolkit.c:696
void window_dimWindow(unsigned int wid, int *w, int *h)
Gets the dimensions of a window.
Definition: toolkit.c:371
void window_setCancel(unsigned int wid, void(*cancel)(unsigned int, const char *))
Sets the default cancel function of the window.
Definition: toolkit.c:900
void window_handleKeys(unsigned int wid, int(*keyhandler)(unsigned int, SDL_Keycode, SDL_Keymod))
Sets the key handler for the window.
Definition: toolkit.c:972
void window_destroyWidget(unsigned int wid, const char *wgtname)
Destroys a widget in a window.
Definition: toolkit.c:1162
unsigned int window_get(const char *wdwname)
Gets the ID of a window.
Definition: toolkit.c:671
void window_onCleanup(unsigned int wid, void(*fptr)(unsigned int, const char *))
Sets the cleanup function of the window.
Definition: toolkit.c:858
int window_exists(const char *wdwname)
Checks to see if a window exists.
Definition: toolkit.c:598
int widget_exists(unsigned int wid, const char *wgtname)
Checks to see if a widget exists.
Definition: toolkit.c:1139
void window_close(unsigned int wid, const char *str)
Helper function to automatically close the window calling it.
Definition: toolkit.c:1031
void window_destroy(unsigned int wid)
Kills the window.
Definition: toolkit.c:1042