23#include "map_overlay.h"
24#include "map_system.h"
32#include "player_autonav.h"
37#define BUTTON_WIDTH 100
38#define BUTTON_HEIGHT 30
39#define MAP_LOOP_PROT \
41#define MAP_TEXT_INDENT 45
42#define MAP_MARKER_CYCLE \
44#define MAP_MOVE_THRESHOLD 20.
45#define EASE_ALPHA ease_QuadraticInOut
47static const int RCOL_X = -10;
48static const int RCOL_TEXT_W =
50static const int RCOL_HEADER_W =
55static const int RCOL_W = 140 - ( -10 * 2 );
56static const int BBAR_H = 60;
61typedef struct FactionPresence_ {
70typedef struct CstMapWidget_ {
93static int map_selected = -1;
94static MapMode map_mode = MAPMODE_TRAVEL;
95static StarSystem **map_path =
97static int cur_commod = -1;
98static int cur_commod_mode = 0;
100static char **map_modes =
102static int listMapModeVisible =
104static double commod_av_gal_price = 0;
105static double map_dt = 0.;
106static int map_minimal_mode = 0;
107static double map_flyto_speed =
109static double map_mx = 0.;
110static double map_my = 0.;
111static char map_show_notes = 0;
127static void map_update_autonav(
unsigned int wid );
128static void map_update_status(
unsigned int wid,
const char *buf );
129static void map_update(
unsigned int wid );
131static void map_render(
double bx,
double by,
double w,
double h,
void *data );
132static void map_renderPath(
double x,
double y,
double zoom,
double radius,
134static void map_renderMarkers(
double x,
double y,
double zoom,
double r,
136static void map_renderCommod(
double bx,
double by,
double x,
double y,
137 double zoom,
double w,
double h,
double r,
138 int editor,
double a );
139static void map_renderCommodIgnorance(
double x,
double y,
double zoom,
140 const StarSystem *sys,
142static void map_drawMarker(
double x,
double y,
double zoom,
double r,
double a,
143 int num,
int cur,
int type );
145static void map_focusLose(
unsigned int wid,
const char *wgtname );
146static int map_mouse(
unsigned int wid,
const SDL_Event *event,
double mx,
147 double my,
double w,
double h,
double rx,
double ry,
150static void map_setup(
void );
151static void map_updateInternal(
CstMapWidget *cst,
double dt );
152static void map_reset(
CstMapWidget *cst, MapMode mode );
153static CstMapWidget *map_globalCustomData(
unsigned int wid );
154static int map_keyHandler(
unsigned int wid, SDL_Keycode key, SDL_Keymod mod,
156static void map_buttonZoom(
unsigned int wid,
const char *str );
157static void map_setMinimal(
unsigned int wid,
int value );
158static void map_buttonMarkSystem(
unsigned int wid,
const char *str );
159static void map_buttonSystemMap(
unsigned int wid,
const char *str );
160static void map_buttonMinimal(
unsigned int wid,
const char *str );
161static void map_buttonCommodity(
unsigned int wid,
const char *str );
162static void map_selectCur(
void );
163static void map_genModeList(
void );
164static void map_update_commod_av_price();
165static void map_onClose(
unsigned int wid,
const char *str );
182 if ( decorator_stack != NULL ) {
183 for (
int i = 0; i <
array_size( decorator_stack ); i++ )
186 decorator_stack = NULL;
195static int map_keyHandler(
unsigned int wid, SDL_Keycode key, SDL_Keymod mod,
201 if ( ( key == SDLK_SLASH ) || ( key == SDLK_f ) ) {
202 map_inputFind( wid, NULL );
209static int map_shouldRenderSys(
const StarSystem *sys,
int editor )
211 if ( sys_isFlag( sys, SYSTEM_HIDDEN ) )
213 if ( !sys_isFlag( sys, SYSTEM_HAS_KNOWN_FACTION_SPOB ) &&
214 !sys_isKnown( sys ) && !editor )
219static void map_setup(
void )
224 sys_rmFlag( sys, SYSTEM_DISCOVERED | SYSTEM_INTEREST );
227 sys_rmFlag( sys, SYSTEM_HAS_LANDABLE | SYSTEM_HAS_KNOWN_SPOB |
228 SYSTEM_HAS_KNOWN_FACTION_SPOB |
229 SYSTEM_HAS_KNOWN_LANDABLE );
230 for (
int j = 0; j <
array_size( sys->spobs ); j++ ) {
231 Spob *p = sys->spobs[j];
232 if ( !spob_isKnown( p ) )
234 sys_setFlag( sys, SYSTEM_HAS_KNOWN_SPOB );
235 if ( ( p->presence.base + p->presence.bonus ) > 0. )
236 sys_setFlag( sys, SYSTEM_HAS_KNOWN_FACTION_SPOB );
237 if ( !spob_hasService( p, SPOB_SERVICE_LAND ) )
239 sys_setFlag( sys, SYSTEM_HAS_KNOWN_LANDABLE );
242 sys_setFlag( sys, SYSTEM_HAS_LANDABLE );
246 for (
int j = 0; j <
array_size( sys->jumps ); j++ ) {
247 const JumpPoint *jp = &sys->jumps[j];
248 if ( jp_isFlag( jp, JP_EXITONLY ) || jp_isFlag( jp, JP_HIDDEN ) )
250 if ( !jp_isFlag( jp, JP_KNOWN ) ) {
257 for (
int j = 0; j <
array_size( sys->spobs ); j++ ) {
258 const Spob *p = sys->spobs[j];
259 if ( !spob_isKnown( p ) ) {
267 sys_setFlag( sys, SYSTEM_DISCOVERED );
284 const char *title = _(
"Star Map" );
285 const glColour cBG = { 0., 0., 0., 0.95 };
287 map_minimal_mode =
player.map_minimal;
288 listMapModeVisible = 0;
291 if ( pilot_isFlag(
player.p, PILOT_MANUAL_CONTROL ) )
306 if ( map_selected == -1 )
324 map_show( wid, 0, 0, w, h, 1., RCOL_W / 2., BBAR_H / 2. );
331 window_addRect( wid, (w-tw)/2., h-th, tw, th,
"rctTBar", &cBG, 0 );
337 window_addRect( wid, w - RCOL_W, 0, RCOL_W, h,
"rctRCol", &cBG, 0 );
338 window_addRect( wid, 0, 0, w, BBAR_H,
"rctBBar", &cBG, 0 );
367 window_addText( wid, -90 + 80, y, 160, 20, 1,
"txtSysname", &
gl_defFont,
368 NULL, system_nameKnown( cur ) );
372 window_addImage( wid, -90 + 32, y - 32, 0, 0,
"imgFaction", NULL, 0 );
376 window_addText( wid, x, y, RCOL_HEADER_W, 20, 0,
"txtSFaction",
378 window_addText( wid, x, y -
gl_smallFont.h - 5, rw, 300, 0,
"txtFaction",
383 window_addText( wid, x, y, RCOL_HEADER_W, 20, 0,
"txtSStanding",
385 window_addText( wid, x, y -
gl_smallFont.h - 5, rw, 300, 0,
"txtStanding",
390 window_addText( wid, x, y, RCOL_HEADER_W, 20, 0,
"txtSPresence",
392 window_addText( wid, x, y -
gl_smallFont.h - 5, rw, 300, 0,
"txtPresence",
397 window_addText( wid, x, y, RCOL_HEADER_W, 20, 0,
"txtSSpobs", &
gl_smallFont,
398 &cFontGrey, _(
"Space Objects:" ) );
399 window_addText( wid, x, y -
gl_smallFont.h - 5, rw, 300, 0,
"txtSpobs",
404 window_addText( wid, x, y, RCOL_HEADER_W, 20, 0,
"txtSServices",
406 window_addText( wid, x, y -
gl_smallFont.h - 5, rw, 300, 0,
"txtServices",
416 map_buttonCommodity );
429 map_setMinimal( wid, map_minimal_mode );
433 map_buttonSystemMap, SDLK_s );
437 map_buttonMarkSystem, SDLK_n );
446 "btnZoomIn",
"+", map_buttonZoom, SDLK_EQUALS );
448 "btnZoomOut",
"-", map_buttonZoom, SDLK_MINUS );
450 window_addText( wid, 20, 15, w - 40 - 7 * (
BUTTON_WIDTH + 20 ), 30, 0,
458 cst = map_globalCustomData( wid );
459 map_reset( cst, map_mode );
467 pilot_isFlag(
player.p, PILOT_NOJUMP ) ||
470 window_disableButton( wid,
"btnAutonav" );
478 window_disableButton( wid,
"btnFind" );
485static void map_update_commod_av_price(
void )
489 if ( cur_commod == -1 || map_selected == -1 ) {
490 commod_av_gal_price = 0;
494 c = commod_known[cur_commod];
495 if ( cur_commod_mode == 0 ) {
503 if ( ( !sys_isKnown( sys ) &&
504 !sys_isFlag( sys, SYSTEM_MARKED | SYSTEM_CMARKED ) &&
511 for (
int j = 0; j <
array_size( sys->spobs ); j++ ) {
512 const Spob *p = sys->spobs[j];
513 for (
int k = 0; k <
array_size( p->commodities ); k++ ) {
514 if ( p->commodities[k] ==
c ) {
515 if ( p->commodityPrice[k].cnt >
518 p->commodityPrice[k].sum / p->commodityPrice[k].cnt;
519 sumPrice += thisPrice;
527 totPrice += sumPrice / sumCnt;
532 if ( totPriceCnt > 0 )
533 totPrice /= totPriceCnt;
534 commod_av_gal_price = totPrice;
537 commod_av_gal_price = 0;
540static void map_update_autonav(
unsigned int wid )
545 int jumps = floor(
player.p->fuel /
player.p->fuel_consumption );
547 int rw = RCOL_HEADER_W;
548 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#n%s#0", _(
"Fuel: " ) );
549 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
550 n_(
"%d jump",
"%d jumps", jumps ), jumps );
551 sys = map_getDestination( &autonav );
552 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"\n#n%s#0", _(
"Autonav: " ) );
554 scnprintf( &buf[p],
sizeof( buf ) - p, _(
"Off" ) );
556 if ( autonav > jumps )
557 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#r" );
558 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
559 n_(
"%d jump",
"%d jumps", autonav ), autonav );
560 if ( autonav > jumps )
561 scnprintf( &buf[p],
sizeof( buf ) - p,
"#0" );
566 window_modifyText( wid,
"txtPlayerStatus", buf );
569static void map_update_status(
unsigned int wid,
const char *buf )
572 window_modifyText( wid,
"txtSystemStatus", buf );
586static void map_update(
unsigned int wid )
591 unsigned int services, services_u, services_h, services_f, services_r;
603 map_globalCustomData( wid )->mode = map_mode;
609 if ( !( sys_isFlag( sys, SYSTEM_MARKED | SYSTEM_CMARKED ) ) &&
615 map_update_commod_av_price();
618 if ( map_mode == MAPMODE_TRADE ) {
619 const Commodity *
c = commod_known[cur_commod];
620 if ( cur_commod_mode == 1 ) {
623 _(
"Showing %s prices relative to %s:\n"
624 "Positive/blue indicate profit while negative/orange values "
625 "indicate loss when sold at the corresponding system." ),
626 _(
c->name ), system_nameKnown( sys ) );
627 map_update_status( wid, buf );
629 snprintf( buf,
sizeof( buf ),
630 _(
"Showing known %s prices.\nGalaxy-wide average: %.2f" ),
631 _(
c->name ), commod_av_gal_price );
632 map_update_status( wid, buf );
635 map_update_status( wid, NULL );
646 window_modifyText( wid,
"txtSysname", system_nameKnown( sys ) );
648 if ( !sys_isKnown( sys ) ) {
650 window_modifyImage( wid,
"imgFaction", NULL, 0, 0 );
653 window_modifyText( wid,
"txtFaction", _(
"Unknown" ) );
659 window_modifyText( wid,
"txtStanding", _(
"Unknown" ) );
665 window_modifyText( wid,
"txtPresence", _(
"Unknown" ) );
671 window_modifyText( wid,
"txtSpobs", _(
"Unknown" ) );
677 window_modifyText( wid,
"txtServices", _(
"Unknown" ) );
680 map_update_autonav( wid );
685 map_update_status( wid, NULL );
691 for (
int i = 0; i <
array_size( sys->spobs ); i++ ) {
692 if ( !spob_isKnown( sys->spobs[i] ) )
694 if ( ( sys->spobs[i]->presence.faction >= 0 ) &&
698 if ( ( f == -1 ) && ( sys->spobs[i]->presence.faction >= 0 ) ) {
699 f = sys->spobs[i]->presence.faction;
701 sys->spobs[i]->presence.faction
702 && ( sys->spobs[i]->presence.faction >= 0 ) ) {
703 snprintf( buf,
sizeof( buf ), _(
"Multiple" ) );
709 window_modifyImage( wid,
"imgFaction", NULL, 0, 0 );
710 window_modifyText( wid,
"txtFaction", _(
"N/A" ) );
711 window_modifyText( wid,
"txtStanding", _(
"N/A" ) );
715 char standing[STRMAX_SHORT];
726 : logo->
w * (double)FACTION_LOGO_SM /
MAX( logo->
w, logo->
h );
729 : logo->
h * (double)FACTION_LOGO_SM /
MAX( logo->
w, logo->
h );
730 window_modifyImage( wid,
"imgFaction", logo, logow, logoh );
734 snprintf( standing,
sizeof( standing ),
"%s [#%c%.0f%%#0]",
736 faction_reputationColourCharSystem( f, sys ), reputation );
739 window_modifyText( wid,
"txtFaction", buf );
740 window_modifyText( wid,
"txtStanding", standing );
758 map_updateFactionPresence( wid,
"txtPresence", sys, 0 );
760 h = window_getTextHeight( wid,
"txtPresence" );
767 for (
int i = 0; i <
array_size( sys->spobs ); i++ ) {
768 const char *prefix, *suffix;
769 Spob *s = sys->spobs[i];
771 if ( !spob_isKnown( s ) )
782 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#%c%s%s%s#n", t, prefix,
785 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
",\n#%c%s%s%s#n", t,
789 if ( hasSpobs == 0 ) {
790 strncpy( buf, _(
"None" ),
sizeof( buf ) - 1 );
791 buf[
sizeof( buf ) - 1] =
'\0';
794 window_modifyText( wid,
"txtSpobs", buf );
809 for (
int i = 0; i <
array_size( sys->spobs ); i++ ) {
810 const Spob *pnt = sys->spobs[i];
811 if ( !spob_isKnown( pnt ) )
814 if ( !spob_hasService( pnt, SPOB_SERVICE_INHABITED ) )
831 for (
int i = SPOB_SERVICE_LAND; i <= SPOB_SERVICE_COMMODITY; i <<= 1 ) {
832 if ( services_f & i )
833 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#F+ %s\n",
835 else if ( services & i )
836 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#N~ %s\n",
838 else if ( services_h & i )
839 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#H!! %s\n",
841 else if ( services_r & i )
842 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#R* %s\n",
844 else if ( services_u & i )
845 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#I= %s\n",
848 if ( buf[0] ==
'\0' )
849 scnprintf( &buf[p],
sizeof( buf ) - p, _(
"None" ) );
851 window_modifyText( wid,
"txtServices", buf );
856 if ( ( map_mode == MAPMODE_TRAVEL ) || ( map_mode == MAPMODE_DISCOVER ) ) {
862 if ( sys->features != NULL )
863 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"%s", _( sys->features ) );
866 for (
int i = 0; i <
array_size( sys->spobs ); i++ ) {
867 const Spob *spob = sys->spobs[i];
870 if ( !spob_isKnown( spob ) )
872 if ( buf[0] !=
'\0' )
873 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
874 p_(
"system features",
", " ) );
880 for (
int i = 0; i <
array_size( sys->jumps ); i++ ) {
881 if ( sys->jumps[i].hide <= 0. ) {
887 if ( buf[0] !=
'\0' )
888 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
889 p_(
"system features",
", " ) );
890 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#g%s#0",
895 if ( sys->nebu_density > 0. ) {
898 if ( buf[0] !=
'\0' )
899 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
900 p_(
"system features",
", " ) );
903 if ( sys->nebu_density > 700. )
904 adj = p_(
"adj Nebula",
"Dense " );
905 else if ( sys->nebu_density < 300. )
906 adj = p_(
"adj Nebula",
"Light " );
911 if ( sys_isFlag( sys, SYSTEM_HIDENEBULADAMAGE ) )
912 snprintf( dmgstr,
sizeof( dmgstr ),
913 p_(
"nebula_volatility",
"??? %s" ), UNIT_POWER );
915 snprintf( dmgstr,
sizeof( dmgstr ),
916 p_(
"nebula_volatility",
"%.1f %s" ),
917 sys->nebu_volatility, UNIT_POWER );
920 if ( sys->nebu_volatility > SYS_VOLATILITY_VOLATILE ) {
921 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#r" );
922 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
923 _(
"Volatile %sNebula (%s)" ), adj, dmgstr );
924 }
else if ( sys->nebu_volatility > SYS_VOLATILITY_DANGEROUS ) {
925 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#o" );
926 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
927 _(
"Dangerous %sNebula (%s)" ), adj, dmgstr );
928 }
else if ( sys->nebu_volatility > 0. ) {
929 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#y" );
930 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
931 _(
"Unstable %sNebula (%s)" ), adj, dmgstr );
933 p +=
scnprintf( &buf[p],
sizeof( buf ) - p, _(
"%sNebula" ), adj );
934 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#0" );
937 if ( sys->interference > 0. ) {
939 if ( buf[0] !=
'\0' )
940 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
941 p_(
"system features",
", " ) );
943 itf = sys->interference;
944 if ( sys->interference > 70. ) {
945 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#r" );
946 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
947 _(
"Dense Interference (%.0f%%)" ), itf );
948 }
else if ( sys->interference > 30. ) {
949 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#o" );
950 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
951 _(
"Medium Interference (%.0f%%)" ), itf );
953 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#y" );
954 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
955 _(
"Light Interference (%.0f%%)" ), itf );
957 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#0" );
961 double density = sys->asteroid_density;
963 if ( buf[0] !=
'\0' )
964 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
965 p_(
"system features",
", " ) );
967 if ( density >= 1000. ) {
968 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#o" );
970 scnprintf( &buf[p],
sizeof( buf ) - p, _(
"Dense Asteroids" ) );
971 }
else if ( density <= 300. ) {
972 p +=
scnprintf( &buf[p],
sizeof( buf ) - p,
"#y" );
974 scnprintf( &buf[p],
sizeof( buf ) - p, _(
"Light Asteroids" ) );
976 p +=
scnprintf( &buf[p],
sizeof( buf ) - p, _(
"Asteroids" ) );
977 scnprintf( &buf[p],
sizeof( buf ) - p,
"#0" );
980 map_update_status( wid, buf );
984 map_update_autonav( wid );
992int map_isOpen(
void )
1008static void map_drawMarker(
double x,
double y,
double zoom,
double r,
double a,
1009 int num,
int cur,
int type )
1012 const glColour *colours[] = { &cMarkerNew, &cMarkerPlot, &cMarkerHigh,
1013 &cMarkerLow, &cMarkerComputer, &cMarkerNew };
1018 if ( ( num == 1 ) || ( num == 2 ) || ( num == 4 ) )
1020 else if ( num == 3 )
1022 else if ( num == 5 )
1027 alpha += M_PI * 2. * (double)cur / (
double)num;
1029 x = x + 3.0 * r * cos( alpha );
1030 y = y + 3.0 * r * sin( alpha );
1037 glUseProgram( shaders.notemarker.program );
1042 glUseProgram( shaders.sysmarker.program );
1044 col_blend( &col, colours[type], &cWhite,
1045 MIN( 1.0, 0.75 + 0.25 * sin( 2.0 * M_PI * map_dt ) ) );
1046 x += 0.25 * r * cos( alpha );
1047 y += 0.25 * r * sin( alpha );
1049 glUniform1i( shaders.sysmarker.parami, 1 );
1051 col_blend( &col, colours[type], &cWhite,
1052 MIN( 1.0, 1.0 + 0.25 * sin( 2.0 * M_PI * map_dt ) ) );
1053 glUniform1i( shaders.sysmarker.parami, 0 );
1067static void map_render(
double bx,
double by,
double w,
double h,
void *data )
1075 map_updateInternal( cst, dt );
1078 map_renderParams( bx, by, cst->
xpos, cst->
ypos, w, h, cst->
zoom, &x, &y,
1090 map_renderFactionDisks( x, y, z, r, 0, EASE_ALPHA( cst->
alpha_faction ) );
1094 map_renderSystemEnvironment( x, y, z, 0, EASE_ALPHA( cst->
alpha_env ) );
1097 map_renderJumps( x, y, z, r, 0 );
1101 map_renderPath( x, y, z, r, EASE_ALPHA( cst->
alpha_path ) );
1104 map_renderSystems( bx, by, x, y, z, w, h, r, cst->
mode );
1108 map_renderMarkers( x, y, z, r, EASE_ALPHA( cst->
alpha_markers ) );
1112 map_renderNames( bx, by, x, y, z, w, h, 0,
1117 map_renderCommod( bx, by, x, y, z, w, h, r, 0,
1122 map_renderNotes( bx, by, x, y, z, w, h, 0,
1126 if ( map_selected != -1 ) {
1128 glUseProgram( shaders.selectspob.program );
1129 glUniform1f( shaders.selectspob.dt, map_dt );
1130 gl_renderShader( x + sys->pos.x * z, y + sys->pos.y * z, 1.7 * r, 1.7 * r,
1131 0., &shaders.selectspob, &cRadar_tSpob, 1 );
1136 1.5 * r, &cRadar_tSpob, 0 );
1138 glClear( GL_DEPTH_BUFFER_BIT );
1144void map_renderParams(
double bx,
double by,
double xpos,
double ypos,
double w,
1145 double h,
double zoom,
double *x,
double *y,
double *r )
1147 *r = round(
CLAMP( 6., 20., 8. * zoom ) );
1148 *x = round( ( bx - xpos + w / 2 ) * 1. );
1149 *y = round( ( by - ypos + h / 2 ) * 1. );
1157void map_renderDecorators(
double x,
double y,
double zoom,
int editor,
1160 const glColour ccol = {
1161 .r = 1., .g = 1., .b = 1., .a = 2. / 3. * alpha };
1164 for (
int i = 0; i <
array_size( decorator_stack ); i++ ) {
1169 if ( decorator->
image == NULL )
1178 if ( sys_isFlag( sys, SYSTEM_HIDDEN ) )
1181 if ( !sys_isKnown( sys ) )
1193 if ( editor || visible == 1 ) {
1194 double tx = x + decorator->x * zoom;
1195 double ty = y + decorator->
y * zoom;
1197 int sw = decorator->
image->
sw * zoom;
1198 int sh = decorator->
image->
sh * zoom;
1209void map_renderFactionDisks(
double x,
double y,
double zoom,
double r,
1210 int editor,
double alpha )
1217 if ( !map_shouldRenderSys( sys, editor ) )
1220 tx = x + sys->pos.x * zoom;
1221 ty = y + sys->pos.y * zoom;
1224 if ( sys->faction != -1 ) {
1225 const glColour *col;
1226 double presence = sqrt( sys->ownerpresence );
1229 double sr = ( 40. + presence * 3. ) * zoom * 0.5;
1237 glUseProgram( shaders.factiondisk.program );
1238 glUniform1f( shaders.factiondisk.paramf, r / sr );
1247void map_renderSystemEnvironment(
double x,
double y,
double zoom,
int editor,
1255 if ( !map_shouldRenderSys( sys, editor ) )
1258 tx = x + sys->pos.x * zoom;
1259 ty = y + sys->pos.y * zoom;
1263 if ( sys->nebu_density > 0. ) {
1266 sw = ( 50. + sys->nebu_density * 50. / 1000. ) * zoom;
1270 projection = gl_view_matrix;
1271 mat4_translate_scale_xy( &projection, tx - sw / 2., ty - sh / 2., sw,
1275 glUseProgram( shaders.nebula_map.program );
1278 glUniform1f( shaders.nebula_map.hue, sys->nebu_hue );
1279 glUniform1f( shaders.nebula_map.alpha, alpha );
1280 gl_uniformMat4( shaders.nebula_map.projection, &projection );
1281 glUniform1f( shaders.nebula_map.time, map_dt / 10.0 );
1282 glUniform2f( shaders.nebula_map.globalpos, sys->pos.x, sys->pos.y );
1283 glUniform1f( shaders.nebula_map.volatility, sys->nebu_volatility );
1286 glEnableVertexAttribArray( shaders.nebula_map.vertex );
1289 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
1292 glDisableVertexAttribArray( shaders.nebula_map.vertex );
1295 }
else if ( sys->map_shader != NULL ) {
1302 projection = gl_view_matrix;
1303 mat4_translate_scale_xy( &projection, tx - sw / 2., ty - sh / 2., sw,
1307 glUseProgram( sys->ms->program );
1310 gl_uniformMat4( sys->ms->projection, &projection );
1311 glUniform1f( sys->ms->time, map_dt );
1312 glUniform2f( sys->ms->globalpos, sys->pos.x, sys->pos.y );
1313 glUniform1f( sys->ms->alpha, alpha );
1316 glEnableVertexAttribArray( sys->ms->vertex );
1319 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
1322 glDisableVertexAttribArray( sys->ms->vertex );
1332void map_renderJumps(
double x,
double y,
double zoom,
double radius,
1339 if ( !map_shouldRenderSys( sys, editor ) )
1342 x1 = x + sys->pos.x * zoom;
1343 y1 = y + sys->pos.y * zoom;
1345 for (
int j = 0; j <
array_size( sys->jumps ); j++ ) {
1346 double x2, y2, rx, ry, r, rw, rh;
1347 const glColour *col, *cole;
1348 const StarSystem *jsys = sys->jumps[j].target;
1349 if ( sys_isFlag( jsys, SYSTEM_HIDDEN ) )
1356 for (
int k = 0; k <
array_size( jsys->jumps ); k++ ) {
1357 if ( jsys->jumps[k].target == sys ) {
1358 if ( jp_isFlag( &jsys->jumps[k], JP_EXITONLY ) )
1360 else if ( jp_isFlag( &jsys->jumps[k], JP_HIDDEN ) )
1365 if ( jp_isFlag( &sys->jumps[j], JP_EXITONLY ) )
1367 else if ( jp_isFlag( &sys->jumps[j], JP_HIDDEN ) )
1372 x2 = x + jsys->pos.x * zoom;
1373 y2 = y + jsys->pos.y * zoom;
1376 r = atan2( ry, rx );
1377 rw = MOD( rx, ry ) / 2.;
1379 if ( sys->jumps[j].hide <= 0. ) {
1386 glUseProgram( shaders.jumplane.program );
1387 gl_uniformColour( shaders.jumplane.paramv, cole );
1388 glUniform1f( shaders.jumplane.paramf, radius );
1390 &shaders.jumplane, col, 1 );
1398void map_renderSystems(
double bx,
double by,
double x,
double y,
double zoom,
1399 double w,
double h,
double r, MapMode mode )
1405 if ( sys_isFlag( sys, SYSTEM_HIDDEN ) )
1410 if ( !map_shouldRenderSys( sys, mode == MAPMODE_EDITOR ) &&
1411 !sys_isFlag( sys, SYSTEM_MARKED | SYSTEM_CMARKED ) &&
1415 tx = x + sys->pos.x * zoom;
1416 ty = y + sys->pos.y * zoom;
1419 if ( !
rectOverlap( tx - r, ty - r, 2. * r, 2. * r, bx, by, w, h ) )
1423 if ( mode == MAPMODE_EDITOR || mode == MAPMODE_TRAVEL ||
1424 mode == MAPMODE_TRADE )
1428 if ( mode != MAPMODE_EDITOR && !sys_isKnown( sys ) )
1431 if ( mode == MAPMODE_EDITOR || mode == MAPMODE_TRAVEL ||
1432 mode == MAPMODE_TRADE ) {
1433 const glColour *col;
1436 if ( !sys_isFlag( sys, SYSTEM_HAS_KNOWN_SPOB ) &&
1437 mode != MAPMODE_EDITOR )
1441 if ( mode != MAPMODE_EDITOR && !sys_isKnown( sys ) )
1443 else if ( !sys_isFlag( sys, SYSTEM_HAS_KNOWN_FACTION_SPOB ) )
1445 else if ( mode == MAPMODE_EDITOR )
1447 else if ( areEnemiesSystem( FACTION_PLAYER, sys->faction, sys ) )
1449 else if ( !sys_isFlag( sys, SYSTEM_HAS_LANDABLE ) )
1451 else if ( areAlliesSystem( FACTION_PLAYER, sys->faction, sys ) )
1456 if ( mode == MAPMODE_EDITOR ) {
1461 }
else if ( mode == MAPMODE_DISCOVER ) {
1463 if ( sys_isFlag( sys, SYSTEM_DISCOVERED ) )
1472static void map_renderPath(
double x,
double y,
double zoom,
double radius,
1488 for (
int j = 0; j <
array_size( map_path ); j++ ) {
1490 double x1, y1, x2, y2, rx, ry, rw, rh, r;
1491 const StarSystem *sys2 = map_path[j];
1492 if ( sys_isFlag( sys1, SYSTEM_HIDDEN ) ||
1493 sys_isFlag( sys2, SYSTEM_HIDDEN ) )
1495 if ( jcur == jmax && jmax > 0 )
1497 else if ( jcur < 1 )
1503 x1 = x + sys1->pos.x * zoom;
1504 y1 = y + sys1->pos.y * zoom;
1505 x2 = x + sys2->pos.x * zoom;
1506 y2 = y + sys2->pos.y * zoom;
1509 r = atan2( ry, rx );
1510 rw = ( MOD( rx, ry ) + radius ) / 2.;
1513 glUseProgram( shaders.jumplanegoto.program );
1514 glUniform1f( shaders.jumplanegoto.dt, map_dt );
1515 glUniform1f( shaders.jumplanegoto.paramf, radius );
1516 glUniform1i( shaders.jumplanegoto.parami, ( jcur >= 1 ) );
1518 &shaders.jumplanegoto, &col, 1 );
1528void map_renderNotes(
double bx,
double by,
double x,
double y,
double zoom,
1529 double w,
double h,
int editor,
double alpha )
1534 if ( ( zoom <= 0.5 ) || editor )
1537 if ( map_show_notes )
1538 glClear( GL_DEPTH_BUFFER_BIT );
1542 double tx, ty, tw, th;
1547 if ( !sys_isFlag( sys, SYSTEM_PMARKED ) )
1550 if ( sys->note == NULL )
1554 tx = x + sys->pos.x * zoom;
1555 ty = y + sys->pos.y * zoom;
1558 if ( !map_show_notes &&
1559 ( (
pow2( tx - map_mx - bx ) +
pow2( ty - map_my - by ) ) >
1560 pow2( MAP_MOVE_THRESHOLD ) ) )
1563 if ( !map_show_notes )
1564 glClear( GL_DEPTH_BUFFER_BIT );
1574 col.a = alpha * 0.8;
1587void map_renderNames(
double bx,
double by,
double x,
double y,
double zoom,
1588 double w,
double h,
int editor,
double alpha )
1590 double tx, ty, vx, vy,
d, n;
1603 if ( !map_shouldRenderSys( sys, editor ) && !sys_isKnown( sys ) )
1609 tx = x + ( sys->pos.x + 12. ) * zoom;
1610 ty = y + ( sys->pos.y ) * zoom - font->
h * 0.5;
1613 if ( !
rectOverlap( tx, ty, textw, font->
h, bx, by, w, h ) )
1618 gl_printRaw( font, tx, ty, &col, -1, system_name( sys ) );
1622 if ( !editor || ( zoom <= 1.0 ) )
1627 for (
int j = 0; j <
array_size( sys->jumps ); j++ ) {
1628 const StarSystem *jsys = sys->jumps[j].target;
1630 vx = jsys->pos.x - sys->pos.x;
1631 vy = jsys->pos.y - sys->pos.y;
1632 n = sqrt(
pow2( vx ) +
pow2( vy ) );
1635 d =
MAX( n * 0.3 * zoom, 15 );
1636 tx = x + zoom * sys->pos.x +
d * vx;
1637 ty = y + zoom * sys->pos.y +
d * vy;
1639 n = sys->jumps[j].hide;
1641 snprintf( buf,
sizeof( buf ),
"#gH: %.2f", n );
1643 snprintf( buf,
sizeof( buf ),
"H: %.2f", n );
1654static void map_renderMarkers(
double x,
double y,
double zoom,
double r,
1663 if ( !sys_isFlag( sys, SYSTEM_MARKED | SYSTEM_CMARKED | SYSTEM_PMARKED ) )
1667 tx = x + sys->pos.x * zoom;
1668 ty = y + sys->pos.y * zoom;
1671 n = ( sys_isFlag( sys, SYSTEM_CMARKED ) ) ? 1 : 0;
1672 n += ( sys_isFlag( sys, SYSTEM_PMARKED ) ) ? 1 : 0;
1673 n += sys->markers_plot;
1674 n += sys->markers_high;
1675 n += sys->markers_low;
1676 n += sys->markers_computer;
1680 if ( sys_isFlag( sys, SYSTEM_PMARKED ) ) {
1681 map_drawMarker( tx, ty, zoom, r, a, n, j, 5 );
1684 if ( sys_isFlag( sys, SYSTEM_CMARKED ) ) {
1685 map_drawMarker( tx, ty, zoom, r, a, n, j, 0 );
1688 for ( m = 0; m < sys->markers_plot; m++ ) {
1689 map_drawMarker( tx, ty, zoom, r, a, n, j, 1 );
1692 for ( m = 0; m < sys->markers_high; m++ ) {
1693 map_drawMarker( tx, ty, zoom, r, a, n, j, 2 );
1696 for ( m = 0; m < sys->markers_low; m++ ) {
1697 map_drawMarker( tx, ty, zoom, r, a, n, j, 3 );
1700 for ( m = 0; m < sys->markers_computer; m++ ) {
1701 map_drawMarker( tx, ty, zoom, r, a, n, j, 4 );
1710static void map_renderSysBlack(
double bx,
double by,
double x,
double y,
1711 double zoom,
double w,
double h,
double r,
1719 if ( sys_isFlag( sys, SYSTEM_HIDDEN ) )
1724 if ( !map_shouldRenderSys( sys, editor ) &&
1725 !sys_isFlag( sys, SYSTEM_MARKED | SYSTEM_CMARKED ) &&
1729 tx = x + sys->pos.x * zoom;
1730 ty = y + sys->pos.y * zoom;
1733 if ( !
rectOverlap( tx - r, ty - r, r, r, bx, by, w, h ) )
1747void map_renderCommod(
double bx,
double by,
double x,
double y,
double zoom,
1748 double w,
double h,
double r,
int editor,
double a )
1754 if ( ( cur_commod == -1 ) || ( map_selected == -1 ) ||
1755 ( commod_known == NULL ) )
1758 c = commod_known[cur_commod];
1759 if ( cur_commod_mode == 1 ) {
1760 double curMaxPrice, curMinPrice;
1771 curMinPrice =
land_spob->commodityPrice[k].sum /
1773 curMaxPrice = curMinPrice;
1780 map_renderCommodIgnorance( x, y, zoom, sys,
c, a );
1781 map_renderSysBlack( bx, by, x, y, zoom, w, h, r, editor );
1788 double minPrice = HUGE_VAL;
1789 double maxPrice = 0;
1790 for (
int j = 0; j <
array_size( sys->spobs ); j++ ) {
1791 Spob *p = sys->spobs[j];
1792 for (
int k = 0; k <
array_size( p->commodities ); k++ ) {
1794 if ( p->commodities[k] !=
c )
1796 if ( p->commodityPrice[k].cnt <=
1800 p->commodityPrice[k].sum / p->commodityPrice[k].cnt;
1801 maxPrice =
MAX( thisPrice, maxPrice );
1802 minPrice =
MIN( thisPrice, minPrice );
1806 if ( maxPrice == 0 ) {
1807 map_renderCommodIgnorance( x, y, zoom, sys,
c, a );
1808 map_renderSysBlack( bx, by, x, y, zoom, w, h, r, editor );
1811 curMaxPrice = maxPrice;
1812 curMinPrice = minPrice;
1814 map_renderCommodIgnorance( x, y, zoom, sys,
c, a );
1815 map_renderSysBlack( bx, by, x, y, zoom, w, h, r, editor );
1823 if ( sys_isFlag( sys, SYSTEM_HIDDEN ) )
1828 if ( ( !sys_isKnown( sys ) &&
1829 !sys_isFlag( sys, SYSTEM_MARKED | SYSTEM_CMARKED ) &&
1834 tx = x + sys->pos.x * zoom;
1835 ty = y + sys->pos.y * zoom;
1838 if ( !
rectOverlap( tx - r, ty - r, r, r, bx, by, w, h ) )
1843 double minPrice = HUGE_VAL;
1844 double maxPrice = 0;
1845 for (
int j = 0; j <
array_size( sys->spobs ); j++ ) {
1846 Spob *p = sys->spobs[j];
1847 for (
int k = 0; k <
array_size( p->commodities ); k++ ) {
1849 if ( p->commodities[k] !=
c )
1851 if ( p->commodityPrice[k].cnt <=
1855 p->commodityPrice[k].sum / p->commodityPrice[k].cnt;
1856 maxPrice =
MAX( thisPrice, maxPrice );
1857 minPrice =
MIN( thisPrice, minPrice );
1863 if ( maxPrice > 0 ) {
1865 double best = maxPrice - curMinPrice;
1866 double worst = minPrice - curMaxPrice;
1871 y + ( sys->pos.y - 22 ) * zoom, &ccol,
"%.1f",
1873 best = tanh( 2 * best / curMinPrice );
1874 col_blend( &ccol, &cFontBlue, &cFontYellow, best );
1883 &ccol, _(
"%.1f ¤" ), worst );
1884 worst = tanh( -2 * worst / curMaxPrice );
1885 col_blend( &ccol, &cFontOrange, &cFontYellow, worst );
1906 if ( sys_isFlag( sys, SYSTEM_HIDDEN ) )
1911 if ( ( !sys_isKnown( sys ) &&
1912 !sys_isFlag( sys, SYSTEM_MARKED | SYSTEM_CMARKED ) &&
1917 tx = x + sys->pos.x * zoom;
1918 ty = y + sys->pos.y * zoom;
1921 if ( !
rectOverlap( tx - r, ty - r, r, r, bx, by, w, h ) )
1926 double sumPrice = 0;
1928 for (
int j = 0; j <
array_size( sys->spobs ); j++ ) {
1929 Spob *p = sys->spobs[j];
1930 for (
int k = 0; k <
array_size( p->commodities ); k++ ) {
1932 if ( p->commodities[k] !=
c )
1934 if ( p->commodityPrice[k].cnt <=
1938 p->commodityPrice[k].sum / p->commodityPrice[k].cnt;
1939 sumPrice += thisPrice;
1950 if ( sumPrice < commod_av_gal_price ) {
1951 frac = tanh( 5 * ( commod_av_gal_price / sumPrice - 1 ) );
1952 col_blend( &ccol, &cFontOrange, &cFontYellow, frac );
1954 frac = tanh( 5 * ( sumPrice / commod_av_gal_price - 1 ) );
1955 col_blend( &ccol, &cFontBlue, &cFontYellow, frac );
1960 &ccol, _(
"%.1f ¤" ), sumPrice );
1976static void map_renderCommodIgnorance(
double x,
double y,
double zoom,
1977 const StarSystem *sys,
1981 char buf[80], *line2;
1983 glColour col = cFontRed;
1986 snprintf( buf,
sizeof( buf ), _(
"No price info for\n%s here" ),
1988 line2 = u8_strchr( buf,
'\n', &charn );
1989 if ( line2 != NULL ) {
1993 y + ( sys->pos.y - 15. ) * zoom, &col, -1, line2 );
1997 y + ( sys->pos.y + 10. ) * zoom, &col, -1, buf );
2000static int factionPresenceCompare(
const void *a,
const void *b )
2008 return strcmp( fpa->
name, fpb->
name );
2020void map_updateFactionPresence(
const unsigned int wid,
const char *name,
2021 const StarSystem *sys,
int omniscient )
2024 char buf[STRMAX_SHORT] = {
'\0' };
2029 for (
int i = 0; i <
array_size( sys->presence ); i++ ) {
2032 if ( sys->presence[i].value <= 0. )
2038 fp.
name = N_(
"Unknown" );
2040 }
else if ( omniscient )
2044 fp.
value = sys->presence[i].value;
2048 for (
int j = 0; j <
array_size( presence ); j++ ) {
2049 if ( strcmp( fp.
name, presence[j].name ) == 0 ) {
2060 factionPresenceCompare );
2063 for (
int i = 0; i <
array_size( presence ); i++ ) {
2068 faction_reputationColourCharSystem(
faction_get( p->name ), sys );
2073 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"%s#0%s: #%c%.0f",
2074 ( l == 0 ) ?
"" :
"\n", _( p->name ), col, p->value );
2078 snprintf( buf,
sizeof( buf ), _(
"None" ) );
2080 window_modifyText( wid, name, buf );
2089static void map_focusLose(
unsigned int wid,
const char *wgtname )
2106static int map_mouse(
unsigned int wid,
const SDL_Event *event,
double mx,
2107 double my,
double w,
double h,
double rx,
double ry,
2114 const double t = 15. * 15.;
2116 switch ( event->type ) {
2117 case SDL_MOUSEWHEEL:
2119 if ( ( mx < 0. ) || ( mx > w ) || ( my < 0. ) || ( my > h ) )
2121 if ( event->wheel.y > 0 )
2122 map_buttonZoom( wid,
"btnZoomIn" );
2123 else if ( event->wheel.y < 0 )
2124 map_buttonZoom( wid,
"btnZoomOut" );
2127 case SDL_MOUSEBUTTONDOWN:
2129 if ( ( mx < 0. ) || ( mx > w ) || ( my < 0. ) || ( my > h ) )
2134 mx -= w / 2 - cst->
xpos;
2135 my -= h / 2 - cst->
ypos;
2142 if ( sys_isFlag( sys, SYSTEM_HIDDEN ) )
2146 if ( !sys_isFlag( sys, SYSTEM_MARKED | SYSTEM_CMARKED ) &&
2151 x = sys->pos.x * cst->
zoom;
2152 y = sys->pos.y * cst->
zoom;
2154 if ( (
pow2( mx - x ) +
pow2( my - y ) ) < t ) {
2155 if ( map_selected != -1 ) {
2157 sys_isKnown( sys ) ) {
2158 map_system_open( map_selected );
2162 map_select( sys, ( SDL_GetModState() & KMOD_SHIFT ) );
2168 case SDL_MOUSEBUTTONUP:
2172 case SDL_MOUSEMOTION:
2191static void map_buttonZoom(
unsigned int wid,
const char *str )
2202 if ( strcmp( str,
"btnZoomIn" ) == 0 ) {
2205 }
else if ( strcmp( str,
"btnZoomOut" ) == 0 ) {
2210 map_setZoom( wid, cst->
zoom );
2223static void map_genModeList(
void )
2226 const char *odd_template, *even_template;
2228 map_onClose( 0, NULL );
2232 for (
int j = 0; j <
array_size( sys->spobs ); j++ ) {
2233 Spob *p = sys->spobs[j];
2234 for (
int k = 0; k <
array_size( p->commodities ); k++ ) {
2235 if ( p->commodityPrice[k].cnt > 0 ) {
2238 for ( l = 0; l < totGot; l++ ) {
2239 if ( p->commodities[k] == commod_known[l] )
2242 if ( l == totGot ) {
2243 commod_known[totGot] = p->commodities[k];
2254 even_template = _(
"%s: Cost" );
2255 odd_template = _(
"%s: Trade" );
2256 for (
int i = 0; i < totGot; i++ ) {
2257 const char *commod_text = _( commod_known[i]->name );
2258 SDL_asprintf( &
array_grow( &map_modes ), even_template, commod_text );
2259 SDL_asprintf( &
array_grow( &map_modes ), odd_template, commod_text );
2269static void map_modeUpdate(
unsigned int wid,
const char *str )
2272 if ( listMapModeVisible == 2 ) {
2273 listMapModeVisible = 1;
2274 }
else if ( listMapModeVisible == 1 ) {
2275 int listpos = toolkit_getListPos( wid,
"lstMapMode" );
2277 if ( listpos == 0 ) {
2278 map_mode = MAPMODE_TRAVEL;
2281 }
else if ( listpos == 1 ) {
2282 map_mode = MAPMODE_DISCOVER;
2286 map_mode = MAPMODE_TRADE;
2287 cur_commod = ( listpos - MAPMODE_TRADE ) / 2;
2288 cur_commod_mode = ( listpos - MAPMODE_TRADE ) %
2298static void map_modeActivate(
unsigned int wid,
const char *str )
2300 map_modeUpdate( wid, str );
2301 listMapModeVisible = 0;
2305static void map_setMinimal(
unsigned int wid,
int value )
2307 map_minimal_mode = value;
2308 player.map_minimal = value;
2309 window_buttonCaption( wid,
"btnMinimal",
2310 ( value ) ? _(
"Normal View" ) : _(
"Minimal View" ) );
2316static void map_buttonMarkSystem(
unsigned int wid,
const char *str )
2320 if ( map_selected < 0 )
2326 if ( sys->note != NULL ) {
2328 _(
"Remove the following note about the #o%s#0 "
2329 "system?\n\n#o%s#0" ),
2330 system_nameKnown( sys ), sys->note ) )
2337 if ( sys_isFlag( sys, SYSTEM_PMARKED ) )
2338 sys_rmFlag( sys, SYSTEM_PMARKED );
2341 _(
"Write a note about the #o%s#0 system:" ),
2342 system_nameKnown( sys ) );
2343 if ( sys->note != NULL )
2344 sys_setFlag( sys, SYSTEM_PMARKED );
2351static void map_buttonSystemMap(
unsigned int wid,
const char *str )
2355 if ( map_selected != -1 )
2357 map_system_open( map_selected );
2363static void map_buttonMinimal(
unsigned int wid,
const char *str )
2366 map_setMinimal( wid, !map_minimal_mode );
2375static void map_buttonCommodity(
unsigned int wid,
const char *str )
2379 char **this_map_modes;
2383 mods = SDL_GetModState();
2384 if ( mods & ( KMOD_LCTRL | KMOD_RCTRL ) ) {
2385 static int cur_commod_last = 0;
2386 static int cur_commod_mode_last = 0;
2387 static int map_mode_last = MAPMODE_TRAVEL;
2388 if ( map_mode == MAPMODE_TRAVEL ) {
2389 map_mode = map_mode_last;
2390 cur_commod = cur_commod_last;
2391 if ( cur_commod == -1 )
2393 cur_commod_mode = cur_commod_mode_last;
2395 map_mode_last = map_mode;
2396 map_mode = MAPMODE_TRAVEL;
2397 cur_commod_last = cur_commod;
2398 cur_commod_mode_last = cur_commod_mode;
2401 if ( cur_commod >= (
array_size( map_modes ) - 1 ) / 2 )
2404 if ( listMapModeVisible ) {
2405 listMapModeVisible = 0;
2410 if ( listMapModeVisible ) {
2411 listMapModeVisible = 0;
2415 this_map_modes = calloc(
array_size( map_modes ),
sizeof(
char * ) );
2416 for (
int i = 0; i <
array_size( map_modes ); i++ ) {
2417 this_map_modes[i] = strdup( map_modes[i] );
2419 listMapModeVisible = 2;
2420 if ( map_mode == MAPMODE_TRAVEL )
2422 else if ( map_mode == MAPMODE_DISCOVER )
2425 defpos = cur_commod * 2 + MAPMODE_TRADE - cur_commod_mode;
2427 window_addList( wid, -10, 60, 200, 200,
"lstMapMode", this_map_modes,
2428 array_size( map_modes ), defpos, map_modeUpdate,
2437static void map_onClose(
unsigned int wid,
const char *str )
2441 free( commod_known );
2442 commod_known = NULL;
2443 for (
int i = 0; i <
array_size( map_modes ); i++ )
2444 free( map_modes[i] );
2449void map_cleanup(
void )
2458void map_close(
void )
2460 unsigned int wid =
window_get( MAP_WDWNAME );
2468void map_clear(
void )
2475static void map_updateInternal(
CstMapWidget *cst,
double dt )
2478 double mapmin = 1. - map_minimal_mode;
2480#define AMAX( x ) ( x ) = MIN( 1., ( x ) + dt )
2481#define AMIN( x ) ( x ) = MAX( 0., ( x ) - dt )
2482#define ATAR( x, y ) \
2484 ( x ) = MIN( y, ( x ) + dt ); \
2486 ( x ) = MAX( y, ( x ) - dt )
2487 switch ( cst->
mode ) {
2488 case MAPMODE_EDITOR:
2489 case MAPMODE_TRAVEL:
2499 case MAPMODE_DISCOVER:
2525 mod = MOD( dx, dy );
2526 if ( mod > DOUBLE_TOL ) {
2527 double angle = ANGLE( dx, dy );
2529 mod =
MIN( mod, dt * map_flyto_speed );
2530 cst->
xpos += mod * cos( angle );
2531 cst->
ypos += mod * sin( angle );
2538static void map_reset(
CstMapWidget *cst, MapMode mode )
2541 map_updateInternal( cst, 1000. );
2548static CstMapWidget *map_globalCustomData(
unsigned int wid )
2552 return ( wid > 0 ) ? window_custGetData( wid,
"cstMap" ) : NULL;
2558static void map_selectCur(
void )
2573StarSystem *map_getDestination(
int *jumps )
2578 if ( jumps != NULL )
2589StarSystem *
const *map_getRoute(
void )
2597void map_jump(
void )
2604 array_erase( &map_path, &map_path[0], &map_path[1] );
2611 if ( map_path[0] ==
cur_system->jumps[j].target ) {
2634void map_select(
const StarSystem *sys,
char shifted )
2637 unsigned int wid = 0;
2642 if ( sys == NULL ) {
2656 const vec2 *posstart = NULL;
2657 if (
player.p != NULL ) {
2658 posstart = &
player.p->solid.pos;
2660 map_path = map_getJumpPath(
cur_system, posstart, (StarSystem *)sys, 0,
2661 1, map_path, NULL );
2670 if ( map_path[0] ==
cur_system->jumps[i].target ) {
2686 window_enableButton( wid,
"btnAutonav" );
2688 window_disableButton( wid,
"btnAutonav" );
2700void map_cycleMissions(
int dir )
2703 StarSystem *dest = map_getDestination( NULL );
2705 int found_next_i = -1;
2706 int found_prev_i = -1;
2720 if ( !sys_isFlag( &
systems_stack[i], SYSTEM_MARKED | SYSTEM_PMARKED ) ||
2725 if ( found_next_i < 0 )
2743 if ( found_prev_i < 0 )
2750 if ( dir > 0 && found_next_i >= 0 )
2752 else if ( dir < 0 && found_prev_i >= 0 )
2758 map_select( target, 0 );
2759 map_center(
window_get( MAP_WDWNAME ), target->name );
2769void map_toggleNotes()
2771 map_show_notes = !map_show_notes;
2784typedef struct SysNode_ {
2796static SysNode *A_newNode( StarSystem *sys );
2797static int A_g(
const SysNode *n );
2798static double A_d(
const SysNode *n );
2804static void A_freeList(
SysNode *first );
2805static int map_decorator_parse(
MapDecorator *temp,
const char *file );
2807static SysNode *A_newNode( StarSystem *sys )
2820static int A_g(
const SysNode *n )
2825static double A_d(
const SysNode *n )
2832 return ( A_g( op1 ) < A_g( op2 ) ) ||
2833 ( A_g( op1 ) == A_g( op2 ) && A_d( op1 ) < A_d( op2 ) );
2840 if ( first == NULL )
2844 while ( n->
next != NULL )
2855 if ( first->sys == cur ) {
2864 if ( n->
sys == cur ) {
2870 }
while ( ( n = n->
next ) != NULL );
2879 if ( first == NULL )
2884 if ( n->
sys == cur )
2886 }
while ( ( n = n->
next ) != NULL );
2894 if ( first == NULL )
2900 if ( A_less( n, lowest ) )
2902 }
while ( ( n = n->
next ) != NULL );
2906static void A_freeList(
SysNode *first )
2910 if ( first == NULL )
2918 }
while ( ( n = n->
gnext ) != NULL );
2923void map_setZoom(
unsigned int wid,
double zoom )
2944StarSystem **map_getJumpPath( StarSystem *sysstart,
const vec2 *posstart,
2945 StarSystem *sysend,
int ignore_known,
2946 int show_hidden, StarSystem **old_data,
2947 double *o_distance )
2950 StarSystem *ssys, *esys, **res;
2969 if ( ssys == esys ||
array_size( ssys->jumps ) == 0 ) {
2982 const vec2 *p_pos_entry = ( ojumps > 0 ) ? NULL : posstart;
2984 StarSystem *prevsys = sysstart;
2986 prevsys = old_data[ojumps - 2];
2990 p_pos_entry = &jp->pos;
2995 open = closed = NULL;
2996 cur = A_newNode( ssys );
3000 cur->
pos = p_pos_entry;
3001 open = A_add( open, cur );
3004 while ( ( cur = A_lowest( open ) ) ) {
3007 if ( cur->
sys == esys )
3012 if ( j > MAP_LOOP_PROT )
3016 open = A_rm( open, cur->
sys );
3017 closed = A_add( closed, cur );
3018 cost = A_g( cur ) + 1;
3021 JumpPoint *jp = &cur->
sys->jumps[i];
3022 StarSystem *sys = jp->target;
3025 if ( !ignore_known ) {
3026 if ( !jp_isKnown( jp ) )
3031 if ( jp_isFlag( jp, JP_EXITONLY ) )
3035 if ( !show_hidden && jp_isFlag( jp, JP_HIDDEN ) )
3039 const SysNode n_cost = { .g = cost,
3041 ( ( cur->
pos != NULL )
3042 ? vec2_dist( cur->
pos, &jp->pos )
3046 ccost = A_in( closed, sys );
3047 if ( ( ccost != NULL ) && !A_less( &n_cost, ccost ) )
3052 ocost = A_in( open, sys );
3053 if ( ocost != NULL ) {
3054 if ( A_less( &n_cost, ocost ) )
3055 open = A_rm( open, sys );
3062 neighbour = A_newNode( sys );
3064 neighbour->
g = n_cost.
g;
3065 neighbour->
d = n_cost.
d;
3066 neighbour->
pos = ( jp_entry != NULL ) ? &jp_entry->pos : NULL;
3067 open = A_add( open, neighbour );
3075 if ( o_distance != NULL ) {
3076 *o_distance = cur->
d;
3080 if ( cur != NULL && esys == cur->
sys ) {
3081 int njumps = A_g( cur ) + ojumps;
3082 assert( njumps > ojumps );
3087 for (
int i = 0; i < njumps - ojumps; i++ ) {
3088 res[njumps - i - 1] = cur->
sys;
3108int map_map(
const Outfit *map )
3111 sys_setFlag( map->
u.
map->systems[i], SYSTEM_KNOWN );
3118 if ( sysname == NULL )
3119 WARN( _(
"Map '%s' is trying to set spob '%s' as known when it has no "
3125 const StarSystem *ss = map->
u.
map->systems[j];
3126 if ( strcmp( ss->name, sysname ) == 0 ) {
3132 WARN( _(
"Map '%s' is trying to set spob '%s' as known when it is "
3133 "not in the system list! '%s' is in the '%s' system!" ),
3140 jp_setFlag( map->
u.
map->jumps[i], JP_KNOWN );
3153int map_isUseless(
const Outfit *map )
3156 if ( !sys_isKnown( map->
u.
map->systems[i] ) )
3160 const Spob *p = map->
u.
map->spobs[i];
3163 if ( !spob_isKnown( p ) )
3168 if ( !jp_isKnown( map->
u.
map->jumps[i] ) )
3177int localmap_map(
const Outfit *lmap )
3189 if ( jp_isFlag( jp, JP_EXITONLY ) || jp_isFlag( jp, JP_HIDDEN ) )
3191 if ( mod * jp->hide <= detect )
3192 jp_setFlag( jp, JP_KNOWN );
3200 if ( mod * p->hide <= detect )
3212int localmap_isUseless(
const Outfit *lmap )
3224 if ( jp_isFlag( jp, JP_EXITONLY ) || jp_isFlag( jp, JP_HIDDEN ) )
3226 if ( ( mod * jp->hide <= detect ) && !jp_isKnown( jp ) )
3233 if ( ( mod * p->hide <= detect ) && !spob_isKnown( p ) )
3251void map_show(
int wid,
int x,
int y,
int w,
int h,
double zoom,
double xoff,
3257 window_addCust( wid, x, y, w, h,
"cstMap", 1, map_render, map_mouse, NULL,
3258 map_focusLose, cst );
3259 window_custSetDynamic( wid,
"cstMap", 1 );
3260 window_custFreeDataFunc( wid,
"cstMap", free );
3274 map_setZoom( wid, zoom );
3276 map_reset( cst, MAPMODE_TRAVEL );
3287int map_center(
int wid,
const char *sys )
3303 map_flyto_speed =
MIN( 2000.,
d / 0.2 );
3316 Uint32 time = SDL_GetTicks();
3321 for (
int i = 0; i <
array_size( decorator_files ); i++ ) {
3323 int ret = map_decorator_parse( &temp, decorator_files[i] );
3326 free( decorator_files[i] );
3331 if ( conf.devmode ) {
3332 time = SDL_GetTicks() - time;
3333 DEBUG( n_(
"Loaded %d map decorator in %.3f s",
3334 "Loaded %d map decorators in %.3f s",
3336 array_size( decorator_stack ), time / 1000. );
3338 DEBUG( n_(
"Loaded %d map decorator",
"Loaded %d map decorators",
3346static int map_decorator_parse(
MapDecorator *temp,
const char *file )
3349 xmlNodePtr node, parent;
3355 parent = doc->xmlChildrenNode;
3356 if ( strcmp( (
char *)parent->name,
"decorator" ) ) {
3357 WARN( _(
"Malformed %s file: missing root element 'decorator'" ), file );
3367 node = parent->xmlChildrenNode;
3369 xml_onlyNodes( node );
3370 xmlr_float( node,
"x", temp->x );
3371 xmlr_float( node,
"y", temp->
y );
3373 if ( xml_isNode( node,
"image" ) ) {
3375 1, OPENGL_TEX_MIPMAPS );
3377 if ( temp->
image == NULL )
3378 WARN( _(
"Could not load map decorator texture '%s'." ),
3383 WARN( _(
"Map decorator has unknown node '%s'." ), node->name );
3384 }
while ( xml_nextNode( node ) );
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
#define array_resize(ptr_array, new_size)
Resizes the array to accomodate new_size elements.
#define array_create_size(basic_type, capacity)
Creates a new dynamic array of ‘basic_type’ with an initial capacity.
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
#define array_back(ptr_array)
Returns the last element in the array.
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
void col_blend(glColour *blend, const glColour *fg, const glColour *bg, float alpha)
Blends two colours.
int commodity_getN(void)
Return the number of commodities globally.
StarSystem * systems_stack
char * dialogue_input(const char *title, int min, int max, const char *fmt,...)
Creates a dialogue that allows the player to write a message.
int dialogue_YesNo(const char *caption, const char *fmt,...)
Runs a dialogue with both yes and no options.
const char * faction_longname(int f)
Gets the faction's long name (formal, human-readable).
int faction_exists(const char *name)
Checks to see if a faction exists by name.
int faction_isKnown(int id)
Is the faction known?
const glTexture * faction_logo(int f)
Gets the faction's logo (ideally 256x256).
const char * faction_name(int f)
Gets a factions "real" (internal) name.
const glColour * faction_colour(int f)
Gets the colour of the faction.
const char * faction_getStandingTextAtValue(int f, double value)
Gets the player's standing in human readable form.
const char * faction_mapname(int f)
Gets the faction's map name (translated).
int faction_get(const char *name)
Gets a faction ID by name.
int gl_printHeightRaw(const glFont *ft_font, const int width, const char *text)
Gets the height of a non-formatted string.
void gl_printRaw(const glFont *ft_font, double x, double y, const glColour *c, double outlineR, const char *text)
Prints text on screen.
int gl_printWidthRaw(const glFont *ft_font, const char *text)
Gets the width that it would take to print some text.
void gl_print(const glFont *ft_font, const double x, const double y, const glColour *c, const char *fmt,...)
Prints text on screen like printf.
void gui_setNav(void)
Player just changed their nav computer target.
void mission_sysMark(void)
Marks all active systems that need marking.
double naev_getrealdt(void)
Gets the last delta-tick.
Header file with generic functions and naev-specifics.
char ** ndata_listRecursive(const char *path)
Lists all the visible files in a directory, at any depth.
int rectOverlap(double x, double y, double w, double h, double x2, double y2, double w2, double h2)
Checks whether two rectangles overlap at any point.
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
glTexture * xml_parseTexture(xmlNodePtr node, const char *path, int defsx, int defsy, const unsigned int flags)
Parses a texture handling the sx and sy elements.
xmlDocPtr xml_parsePhysFS(const char *filename)
Analogous to xmlParseMemory/xmlParseFile.
void gl_renderShader(double x, double y, double w, double h, double r, const SimpleShader *shd, const glColour *c, int center)
Renders a simple shader.
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.
void gl_renderCircle(double cx, double cy, double r, const glColour *c, int filled)
Draws a circle.
void gl_freeTexture(glTexture *texture)
Frees a texture.
void gl_vboActivateAttribOffset(gl_vbo *vbo, GLuint index, GLuint offset, GLint size, GLenum type, GLsizei stride)
Activates a VBO's offset.
int pilot_getJumps(const Pilot *p)
Gets the amount of jumps the pilot has left.
void player_targetHyperspaceSet(int id, int nomsg)
Sets the player's hyperspace target.
void player_hyperspacePreempt(int preempt)
Enables or disables jump points preempting spobs in autoface and target clearing.
void player_autonavStartWindow(unsigned int wid, const char *str)
Starts autonav and closes the window.
double system_getReputation(const StarSystem *sys, int faction)
Gets the local reputation of the player in a system or returns 0.
StarSystem * system_getIndex(int id)
Get the system by its index.
int spob_hasSystem(const Spob *spb)
Get whether or not a spob has a system (i.e. is on the map).
const char * spob_getSymbol(const Spob *p)
Gets the spob symbol.
char spob_getColourChar(const Spob *p)
Gets the spob colour char.
int space_sysReachable(const StarSystem *sys)
Sees if a system is reachable.
JumpPoint * jump_getTarget(const StarSystem *target, const StarSystem *sys)
Less safe version of jump_get that works with pointers.
int space_sysReachableFromSys(const StarSystem *target, const StarSystem *sys)
Sees if a system is reachable from another system.
StarSystem * system_get(const char *sysname)
Get the system from its name.
void spob_setKnown(Spob *p)
Sets a spob's known status, if it's real.
void spob_updateLand(Spob *p)
Updates the land possibilities of a spob.
const char * spob_getSystemName(const char *spobname)
Get the name of a system from a spobname.
int system_hasSpob(const StarSystem *sys)
See if the system has a spob.
const char * spob_name(const Spob *p)
Gets the translated name of a spob.
const char * spob_getServiceName(int service)
Gets the (English) name for a service code.
Faction presence container to be used for the map information stuff.
Images to be shown on the map.
A ship outfit, depends radically on the type.
union Outfit::@052125200133344144252153256241104103242010347340 u
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Node structure for A* pathfinding.
Represents a font in memory.
Abstraction for rendering sprite sheets.