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