24#include "map_system.h"
25#include "map_overlay.h"
38#define BUTTON_WIDTH 100
39#define BUTTON_HEIGHT 30
40#define MAP_LOOP_PROT 1000
41#define MAP_TEXT_INDENT 45
42#define MAP_MARKER_CYCLE 750
43#define MAP_MOVE_THRESHOLD 20.
44#define EASE_ALPHA ease_QuadraticInOut
46static const int RCOL_X = -10;
47static const int RCOL_TEXT_W = 135;
48static const int RCOL_HEADER_W = 140;
51static const int RCOL_W = 140 - (-10*2);
52static const int BBAR_H = 60;
57typedef struct FactionPresence_ {
66typedef struct CstMapWidget_ {
88static int map_selected = -1;
89static MapMode map_mode = MAPMODE_TRAVEL;
90static StarSystem **map_path = NULL;
91static int cur_commod = -1;
92static int cur_commod_mode = 0;
94static char** map_modes = NULL;
95static int listMapModeVisible = 0;
96static double commod_av_gal_price = 0;
97static double map_dt = 0.;
98static int map_minimal_mode = 0;
99static double map_flyto_speed = 1500.;
100static double map_mx = 0.;
101static double map_my = 0.;
102static char map_show_notes = 0;
118static void map_update_autonav(
unsigned int wid );
119static void map_update_status(
unsigned int wid,
const char *buf );
120static void map_update(
unsigned int wid );
122static void map_render(
double bx,
double by,
double w,
double h,
void *data );
123static void map_renderPath(
double x,
double y,
double zoom,
double radius,
double alpha );
124static void map_renderMarkers(
double x,
double y,
double zoom,
double r,
double a );
125static void map_renderCommod(
double bx,
double by,
double x,
double y,
126 double zoom,
double w,
double h,
double r,
int editor,
double a );
127static void map_renderCommodIgnorance(
double x,
double y,
double zoom,
128 const StarSystem *sys,
const Commodity *
c,
double a );
129static void map_drawMarker(
double x,
double y,
double zoom,
130 double r,
double a,
int num,
int cur,
int type );
132static void map_focusLose(
unsigned int wid,
const char* wgtname );
133static int map_mouse(
unsigned int wid,
const SDL_Event* event,
double mx,
double my,
134 double w,
double h,
double rx,
double ry,
void *data );
136static void map_setup (
void);
137static void map_updateInternal(
CstMapWidget *cst,
double dt );
138static void map_reset(
CstMapWidget* cst, MapMode mode );
139static CstMapWidget* map_globalCustomData(
unsigned int wid );
140static int map_keyHandler(
unsigned int wid, SDL_Keycode key, SDL_Keymod mod,
int isrepeat );
141static void map_buttonZoom(
unsigned int wid,
const char* str );
142static void map_setMinimal(
unsigned int wid,
int value );
143static void map_buttonMarkSystem(
unsigned int wid,
const char* str );
144static void map_buttonSystemMap(
unsigned int wid,
const char* str );
145static void map_buttonMinimal(
unsigned int wid,
const char* str );
146static void map_buttonCommodity(
unsigned int wid,
const char* str );
147static void map_selectCur (
void);
148static void map_genModeList(
void);
149static void map_update_commod_av_price();
150static void map_onClose(
unsigned int wid,
const char *str );
167 if (decorator_stack != NULL) {
168 for (
int i=0; i<
array_size(decorator_stack); i++)
171 decorator_stack = NULL;
180static int map_keyHandler(
unsigned int wid, SDL_Keycode key, SDL_Keymod mod,
int isrepeat )
185 if ((key == SDLK_SLASH) || (key == SDLK_f)) {
186 map_inputFind( wid, NULL );
193static void map_setup (
void)
196 for (
int i=0; i<
array_size(systems_stack); i++) {
198 sys_rmFlag( sys, SYSTEM_DISCOVERED | SYSTEM_INTEREST );
201 sys_rmFlag( sys, SYSTEM_HAS_LANDABLE );
202 for (
int j=0; j<
array_size(sys->spobs); j++) {
203 Spob *p = sys->spobs[j];
204 if (!spob_isKnown(p))
206 if (!spob_hasService(p, SPOB_SERVICE_LAND))
208 sys_setFlag( sys, SYSTEM_HAS_KNOWN_LANDABLE );
211 sys_setFlag( sys, SYSTEM_HAS_LANDABLE );
215 for (
int j=0; j<
array_size(sys->jumps); j++) {
216 const JumpPoint *jp = &sys->jumps[j];
217 if (jp_isFlag(jp, JP_EXITONLY) || jp_isFlag(jp, JP_HIDDEN))
219 if (!jp_isFlag(jp, JP_KNOWN)) {
226 for (
int j=0; j<
array_size(sys->spobs); j++) {
227 const Spob *p = sys->spobs[j];
228 if (!spob_isKnown(p)) {
236 sys_setFlag( sys, SYSTEM_DISCOVERED );
253 const char *title = _(
"Star Map");
254 const glColour cBG = { 0., 0., 0., 0.95 };
257 listMapModeVisible = 0;
260 if (pilot_isFlag(
player.
p, PILOT_MANUAL_CONTROL ))
275 if (map_selected == -1)
293 map_show( wid, 0, 0, w, h, 1., RCOL_W/2., BBAR_H/2. );
300 window_addRect( wid, (w-tw)/2., h-th, tw, th,
"rctTBar", &cBG, 0 );
306 window_addRect( wid, w-RCOL_W, 0, RCOL_W, h,
"rctRCol", &cBG, 0 );
307 window_addRect( wid, 0, 0, w, BBAR_H,
"rctBBar", &cBG, 0 );
336 window_addText( wid, -90 + 80, y, 160, 20, 1,
"txtSysname",
341 window_addImage( wid, -90 + 32, y - 32, 0, 0,
"imgFaction", NULL, 0 );
345 window_addText( wid, x, y, RCOL_HEADER_W, 20, 0,
"txtSFaction",
347 window_addText( wid, x, y-
gl_smallFont.
h-5, rw, 300, 0,
"txtFaction",
352 window_addText( wid, x, y, RCOL_HEADER_W, 20, 0,
"txtSStanding",
354 window_addText( wid, x, y-
gl_smallFont.
h-5, rw, 300, 0,
"txtStanding",
359 window_addText( wid, x, y, RCOL_HEADER_W, 20, 0,
"txtSPresence",
361 window_addText( wid, x, y-
gl_smallFont.
h-5, rw, 300, 0,
"txtPresence",
366 window_addText( wid, x, y, RCOL_HEADER_W, 20, 0,
"txtSSpobs",
368 window_addText( wid, x, y-
gl_smallFont.
h-5, rw, 300, 0,
"txtSpobs",
373 window_addText( wid, x, y, RCOL_HEADER_W, 20, 0,
"txtSServices",
375 window_addText( wid, x, y-
gl_smallFont.
h-5, rw, 300, 0,
"txtServices",
380 window_addButton( wid, -20, y, BUTTON_WIDTH, BUTTON_HEIGHT,
383 window_addButton( wid, -20 - (BUTTON_WIDTH+20), y, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnCommod", _(
"Mode"), map_buttonCommodity );
385 window_addButtonKey( wid, -20 - 2*(BUTTON_WIDTH+20), y, BUTTON_WIDTH, BUTTON_HEIGHT,
386 "btnFind", _(
"Find"), map_inputFind, SDLK_f );
388 window_addButtonKey( wid, -20 - 3*(BUTTON_WIDTH+20), y, BUTTON_WIDTH, BUTTON_HEIGHT,
391 window_addButtonKey( wid, -20 - 4*(BUTTON_WIDTH+20), y, BUTTON_WIDTH, BUTTON_HEIGHT,
392 "btnMinimal", NULL, map_buttonMinimal, SDLK_v );
393 map_setMinimal( wid, map_minimal_mode );
395 window_addButtonKey( wid, -20 - 5*(BUTTON_WIDTH+20), y, BUTTON_WIDTH, BUTTON_HEIGHT,
396 "btnSystem", _(
"System Info"), map_buttonSystemMap, SDLK_s );
398 window_addButtonKey( wid, -20 - 6*(BUTTON_WIDTH+20), y, BUTTON_WIDTH, BUTTON_HEIGHT,
399 "btnMarkSystem", _(
"Toggle Note"), map_buttonMarkSystem, SDLK_n );
407 window_addButtonKey( wid, -60, 30 + BUTTON_HEIGHT, 30, BUTTON_HEIGHT,
"btnZoomIn",
"+", map_buttonZoom, SDLK_EQUALS );
408 window_addButtonKey( wid, -20, 30 + BUTTON_HEIGHT, 30, BUTTON_HEIGHT,
"btnZoomOut",
"-", map_buttonZoom, SDLK_MINUS );
410 window_addText( wid, 20, 15, w - 40 - 7*(BUTTON_WIDTH+20), 30, 0,
414 window_addText( wid, -20, 40+BUTTON_HEIGHT*2, rw, 30, 0,
418 cst = map_globalCustomData(wid);
419 map_reset( cst, map_mode );
427 window_disableButton( wid,
"btnAutonav" );
433 window_disableButton( wid,
"btnFind" );
440static void map_update_commod_av_price (
void)
444 if (cur_commod == -1 || map_selected == -1) {
445 commod_av_gal_price = 0;
449 c = commod_known[cur_commod];
450 if (cur_commod_mode == 0) {
453 for (
int i=0; i<
array_size(systems_stack); i++) {
457 if ((!sys_isKnown(sys) && !sys_isFlag(sys, SYSTEM_MARKED | SYSTEM_CMARKED)
464 for (
int j=0 ; j<
array_size(sys->spobs); j++) {
465 Spob *p = sys->spobs[j];
466 for (
int k=0; k<
array_size(p->commodities); k++) {
467 if (p->commodities[k] ==
c) {
468 if (p->commodityPrice[k].cnt > 0) {
469 thisPrice = p->commodityPrice[k].sum / p->commodityPrice[k].cnt;
470 sumPrice += thisPrice;
478 totPrice += sumPrice / sumCnt;
484 totPrice /= totPriceCnt;
485 commod_av_gal_price = totPrice;
489 commod_av_gal_price = 0;
492static void map_update_autonav(
unsigned int wid )
499 int rw = RCOL_HEADER_W;
500 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#n%s#0", _(
"Fuel: ") );
501 p +=
scnprintf(&buf[p],
sizeof(buf)-p, n_(
"%d jump",
"%d jumps", jumps), jumps );
502 sys = map_getDestination( &autonav );
503 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"\n#n%s#0", _(
"Autonav: ") );
505 scnprintf(&buf[p],
sizeof(buf)-p, _(
"Off") );
508 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#r" );
509 p +=
scnprintf(&buf[p],
sizeof(buf)-p, n_(
"%d jump",
"%d jumps", autonav), autonav );
511 scnprintf(&buf[p],
sizeof(buf)-p,
"#0" );
516 window_modifyText( wid,
"txtPlayerStatus", buf );
519static void map_update_status(
unsigned int wid,
const char *buf )
522 window_modifyText( wid,
"txtSystemStatus", buf );
536static void map_update(
unsigned int wid )
541 unsigned int services, services_u, services_h, services_f, services_r;
553 map_globalCustomData(wid)->
mode = map_mode;
559 if (!(sys_isFlag(sys, SYSTEM_MARKED | SYSTEM_CMARKED)) &&
565 map_update_commod_av_price();
568 if (map_mode == MAPMODE_TRADE) {
569 const Commodity *
c = commod_known[cur_commod];
570 if (cur_commod_mode == 1) {
571 snprintf( buf,
sizeof(buf),
572 _(
"Showing %s prices relative to %s:\n"
573 "Positive/blue indicate profit while negative/orange values indicate loss when sold at the corresponding system."),
574 _(
c->name), _(sys->name) );
575 map_update_status( wid, buf );
578 snprintf(buf,
sizeof(buf), _(
"Showing known %s prices.\nGalaxy-wide average: %.2f"), _(
c->name), commod_av_gal_price);
579 map_update_status( wid, buf );
583 map_update_status( wid, NULL );
592 if (!sys_isKnown(sys)) {
596 if (sys_isFlag(sys, SYSTEM_MARKED | SYSTEM_CMARKED))
597 window_modifyText( wid,
"txtSysname", _(sys->name) );
599 window_modifyText( wid,
"txtSysname", _(
"Unknown") );
602 window_modifyImage( wid,
"imgFaction", NULL, 0, 0 );
605 window_modifyText( wid,
"txtFaction", _(
"Unknown") );
611 window_modifyText( wid,
"txtStanding", _(
"Unknown") );
617 window_modifyText( wid,
"txtPresence", _(
"Unknown") );
623 window_modifyText( wid,
"txtSpobs", _(
"Unknown") );
629 window_modifyText( wid,
"txtServices", _(
"Unknown") );
632 map_update_autonav( wid );
637 map_update_status( wid, NULL );
642 window_modifyText( wid,
"txtSysname", _(sys->name) );
646 for (
int i=0; i<
array_size(sys->spobs); i++) {
647 if (!spob_isKnown(sys->spobs[i]))
649 if ((sys->spobs[i]->presence.faction >= 0)
653 if ((f == -1) && (sys->spobs[i]->presence.faction >= 0)) {
654 f = sys->spobs[i]->presence.faction;
656 else if (f != sys->spobs[i]->presence.faction
657 && (sys->spobs[i]->presence.faction >= 0)) {
658 snprintf( buf,
sizeof(buf), _(
"Multiple") );
664 window_modifyImage( wid,
"imgFaction", NULL, 0, 0 );
665 window_modifyText( wid,
"txtFaction", _(
"N/A") );
666 window_modifyText( wid,
"txtStanding", _(
"N/A") );
679 logow = logo == NULL ? 0 : logo->
w * (double)FACTION_LOGO_SM /
MAX( logo->
w, logo->
h );
680 logoh = logo == NULL ? 0 : logo->
h * (double)FACTION_LOGO_SM /
MAX( logo->
w, logo->
h );
681 window_modifyImage( wid,
"imgFaction", logo, logow, logoh );
684 -90 + logow/2, -20 - 32 - 10 -
gl_defFont.
h + logoh/2);
688 window_modifyText( wid,
"txtFaction", buf );
689 window_modifyText( wid,
"txtStanding", fcttext );
707 map_updateFactionPresence( wid,
"txtPresence", sys, 0 );
709 h = window_getTextHeight( wid,
"txtPresence" );
716 for (
int i=0; i<
array_size(sys->spobs); i++) {
717 const char *prefix, *suffix;
718 Spob *s = sys->spobs[i];
720 if (!spob_isKnown(s))
731 p +=
scnprintf( &buf[p],
sizeof(buf)-p,
"#%c%s%s%s#n",
734 p +=
scnprintf( &buf[p],
sizeof(buf)-p,
",\n#%c%s%s%s#n",
739 strncpy( buf, _(
"None"),
sizeof(buf)-1 );
740 buf[
sizeof(buf)-1] =
'\0';
743 window_modifyText( wid,
"txtSpobs", buf );
758 for (
int i=0; i<
array_size(sys->spobs); i++) {
759 const Spob *pnt = sys->spobs[i];
760 if (!spob_isKnown(pnt))
763 if (!spob_hasService( pnt, SPOB_SERVICE_INHABITED ))
779 for (
int i=SPOB_SERVICE_LAND; i<=SPOB_SERVICE_SHIPYARD; i<<=1) {
782 else if (services & i)
784 else if (services_h & i)
786 else if (services_r & i)
788 else if (services_u & i)
792 scnprintf( &buf[p],
sizeof(buf)-p, _(
"None"));
794 window_modifyText( wid,
"txtServices", buf );
799 if ((map_mode==MAPMODE_TRAVEL) || (map_mode==MAPMODE_DISCOVER)) {
805 if (sys->features != NULL)
806 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"%s", _(sys->features) );
809 for (
int i=0; i<
array_size(sys->spobs); i++) {
810 const Spob *spob = sys->spobs[i];
813 if (!spob_isKnown(spob))
816 p +=
scnprintf(&buf[p],
sizeof(buf)-p, p_(
"system features",
", "));
822 for (
int i=0; i<
array_size(sys->jumps); i++) {
823 if (sys->jumps[i].hide<=0.) {
830 p +=
scnprintf(&buf[p],
sizeof(buf)-p, p_(
"system features",
", "));
831 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#g%s#0", _(
"Trade Lane") );
835 if (sys->nebu_density > 0.) {
839 p +=
scnprintf(&buf[p],
sizeof(buf)-p, p_(
"system features",
", "));
842 if (sys->nebu_density > 700.)
843 adj = p_(
"adj Nebula",
"Dense ");
844 else if (sys->nebu_density < 300.)
845 adj = p_(
"adj Nebula",
"Light ");
850 dmg = sys->nebu_volatility;
851 if (sys->nebu_volatility > 50.) {
852 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#r" );
853 p +=
scnprintf(&buf[p],
sizeof(buf)-p, _(
"Volatile %sNebula (%.1f %s)"), adj, dmg, UNIT_POWER);
855 else if (sys->nebu_volatility > 20.) {
856 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#o" );
857 p +=
scnprintf(&buf[p],
sizeof(buf)-p, _(
"Dangerous %sNebula (%.1f %s)"), adj, dmg, UNIT_POWER);
859 else if (sys->nebu_volatility > 0.) {
860 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#y" );
861 p +=
scnprintf(&buf[p],
sizeof(buf)-p, _(
"Unstable %sNebula (%.1f %s)"), adj, dmg, UNIT_POWER);
864 p +=
scnprintf(&buf[p],
sizeof(buf)-p, _(
"%sNebula"), adj);
865 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#0" );
868 if (sys->interference > 0.) {
871 p +=
scnprintf(&buf[p],
sizeof(buf)-p, p_(
"system features",
", "));
873 itf = sys->interference;
874 if (sys->interference > 700.) {
875 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#r" );
876 p +=
scnprintf(&buf[p],
sizeof(buf)-p, _(
"Dense Interference (%.0f%%)"), itf);
878 else if (sys->interference > 300.) {
879 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#o" );
880 p +=
scnprintf(&buf[p],
sizeof(buf)-p, _(
"Medium Interference (%.0f%%)"), itf);
883 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#y" );
884 p +=
scnprintf(&buf[p],
sizeof(buf)-p, _(
"Light Interference (%.0f%%)"), itf);
886 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#0" );
890 double density = sys->asteroid_density;
893 p +=
scnprintf(&buf[p],
sizeof(buf)-p, p_(
"system features",
", "));
895 if (density >= 1000.) {
896 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#o" );
897 p +=
scnprintf(&buf[p],
sizeof(buf)-p, _(
"Dense Asteroids"));
899 else if (density <= 300.) {
900 p +=
scnprintf(&buf[p],
sizeof(buf)-p,
"#y" );
901 p +=
scnprintf(&buf[p],
sizeof(buf)-p, _(
"Light Asteroids"));
904 p +=
scnprintf(&buf[p],
sizeof(buf)-p, _(
"Asteroids"));
905 scnprintf(&buf[p],
sizeof(buf)-p,
"#0" );
908 map_update_status( wid, buf );
912 map_update_autonav( wid );
936static void map_drawMarker(
double x,
double y,
double zoom,
937 double r,
double a,
int num,
int cur,
int type )
940 const glColour* colours[] = {
941 &cMarkerNew, &cMarkerPlot, &cMarkerHigh, &cMarkerLow, &cMarkerComputer, &cMarkerNew
947 if ((num == 1) || (num == 2) || (num == 4))
956 alpha += M_PI*2. * (double)cur/(
double)num;
958 x = x + 3.0*r * cos(alpha);
959 y = y + 3.0*r * sin(alpha);
966 glUseProgram(shaders.notemarker.program);
971 glUseProgram(shaders.sysmarker.program);
973 col_blend( &col, colours[type], &cWhite,
MIN(1.0, 0.75 + 0.25*sin(2.0*M_PI*map_dt)) );
974 x += 0.25*r * cos(alpha);
975 y += 0.25*r * sin(alpha);
977 glUniform1i( shaders.sysmarker.parami, 1 );
980 col_blend( &col, colours[type], &cWhite,
MIN(1.0, 1.0 + 0.25*sin(2.0*M_PI*map_dt)) );
981 glUniform1i( shaders.sysmarker.parami, 0 );
995static void map_render(
double bx,
double by,
double w,
double h,
void *data )
1003 map_updateInternal( cst, dt );
1006 map_renderParams( bx, by, cst->
xpos, cst->
ypos, w, h, cst->
zoom, &x, &y, &r );
1017 map_renderFactionDisks( x, y, z, r, 0, EASE_ALPHA(cst->
alpha_faction) );
1021 map_renderSystemEnvironment( x, y, z, 0, EASE_ALPHA(cst->
alpha_env) );
1024 map_renderJumps( x, y, z, r, 0 );
1028 map_renderPath( x, y, z, r, EASE_ALPHA(cst->
alpha_path) );
1031 map_renderSystems( bx, by, x, y, z, w, h, r, cst->
mode );
1035 map_renderMarkers( x, y, z, r, EASE_ALPHA(cst->
alpha_markers) );
1039 map_renderNames( bx, by, x, y, z, w, h, 0, EASE_ALPHA(cst->
alpha_names) );
1043 map_renderCommod( bx, by, x, y, z, w, h, r, 0, EASE_ALPHA(cst->
alpha_commod) );
1047 map_renderNotes( bx, by, x, y, z, w, h, 0, EASE_ALPHA(cst->
alpha_markers) );
1050 if (map_selected != -1) {
1052 glUseProgram( shaders.selectspob.program );
1053 glUniform1f( shaders.selectspob.dt, map_dt );
1055 1.7*r, 1.7*r, 0., &shaders.selectspob, &cRadar_tSpob, 1 );
1061 1.5*r, &cRadar_tSpob, 0 );
1063 glClear( GL_DEPTH_BUFFER_BIT );
1069void map_renderParams(
double bx,
double by,
double xpos,
double ypos,
1070 double w,
double h,
double zoom,
double *x,
double *y,
double *r )
1072 *r = round(
CLAMP(6., 20., 8.*zoom));
1073 *x = round((bx - xpos + w/2) * 1.);
1074 *y = round((by - ypos + h/2) * 1.);
1082void map_renderDecorators(
double x,
double y,
double zoom,
int editor,
double alpha )
1084 const glColour ccol = { .r=1., .g=1., .b=1., .a=2./3.*alpha };
1087 for (
int i=0; i<
array_size(decorator_stack); i++) {
1092 if (decorator->
image == NULL)
1097 for (
int j=0; j<
array_size(systems_stack) && visible==0; j++) {
1100 if (sys_isFlag(sys, SYSTEM_HIDDEN))
1103 if (!sys_isKnown(sys))
1115 if (editor || visible==1) {
1116 double tx = x + decorator->x*zoom;
1117 double ty = y + decorator->
y*zoom;
1119 int sw = decorator->
image->
sw*zoom;
1120 int sh = decorator->
image->
sh*zoom;
1123 tx - sw*0.5, ty - sh*0.5, sw, sh, &ccol );
1131void map_renderFactionDisks(
double x,
double y,
double zoom,
double r,
int editor,
double alpha )
1133 for (
int i=0; i<
array_size(systems_stack); i++) {
1138 if (sys_isFlag(sys,SYSTEM_HIDDEN))
1141 if ((!sys_isFlag(sys, SYSTEM_HAS_KNOWN_LANDABLE) || !sys_isKnown(sys)) && !editor)
1144 tx = x + sys->pos.x*zoom;
1145 ty = y + sys->pos.y*zoom;
1148 if (sys->faction != -1) {
1149 const glColour *col;
1150 double presence = sqrt(sys->ownerpresence);
1153 double sr = (40. + presence * 3.) * zoom * 0.5;
1161 glUseProgram(shaders.factiondisk.program);
1162 glUniform1f(shaders.factiondisk.paramf, r / sr );
1171void map_renderSystemEnvironment(
double x,
double y,
double zoom,
int editor,
double alpha )
1173 for (
int i=0; i<
array_size(systems_stack); i++) {
1178 if (sys_isFlag(sys,SYSTEM_HIDDEN))
1181 if (!sys_isKnown(sys) && !editor)
1184 tx = x + sys->pos.x*zoom;
1185 ty = y + sys->pos.y*zoom;
1189 if (sys->nebu_density > 0.) {
1192 sw = (50. + sys->nebu_density * 50. / 1000.) * zoom;
1196 projection = gl_view_matrix;
1201 glUseProgram(shaders.nebula_map.program);
1204 glUniform1f(shaders.nebula_map.hue, sys->nebu_hue);
1205 glUniform1f(shaders.nebula_map.alpha, alpha);
1206 gl_uniformMat4(shaders.nebula_map.projection, &projection);
1207 glUniform1f(shaders.nebula_map.time, map_dt / 10.0);
1208 glUniform2f(shaders.nebula_map.globalpos, sys->pos.x, sys->pos.y );
1209 glUniform1f(shaders.nebula_map.volatility, sys->nebu_volatility );
1212 glEnableVertexAttribArray( shaders.nebula_map.vertex );
1214 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
1217 glDisableVertexAttribArray( shaders.nebula_map.vertex );
1221 else if (sys->map_shader != NULL) {
1228 projection = gl_view_matrix;
1233 glUseProgram( sys->ms->program );
1236 gl_uniformMat4(sys->ms->projection, &projection);
1237 glUniform1f(sys->ms->time, map_dt);
1238 glUniform2f(sys->ms->globalpos, sys->pos.x, sys->pos.y );
1239 glUniform1f(sys->ms->alpha, alpha);
1242 glEnableVertexAttribArray( sys->ms->vertex );
1244 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
1247 glDisableVertexAttribArray( sys->ms->vertex );
1257void map_renderJumps(
double x,
double y,
double zoom,
double radius,
int editor )
1259 for (
int i=0; i<
array_size(systems_stack); i++) {
1263 if (sys_isFlag(sys,SYSTEM_HIDDEN))
1266 if (!sys_isKnown(sys) && !editor)
1269 x1 = x + sys->pos.x * zoom;
1270 y1 = y + sys->pos.y * zoom;
1272 for (
int j=0; j <
array_size(sys->jumps); j++) {
1273 double x2,y2, rx,ry, r, rw,rh;
1274 const glColour *col, *cole;
1275 StarSystem *jsys = sys->jumps[j].target;
1276 if (sys_isFlag(jsys,SYSTEM_HIDDEN))
1283 for (
int k=0; k <
array_size(jsys->jumps); k++) {
1284 if (jsys->jumps[k].target == sys) {
1285 if (jp_isFlag(&jsys->jumps[k], JP_EXITONLY))
1287 else if (jp_isFlag(&jsys->jumps[k], JP_HIDDEN))
1292 if (jp_isFlag(&sys->jumps[j], JP_EXITONLY))
1294 else if (jp_isFlag(&sys->jumps[j], JP_HIDDEN))
1299 x2 = x + jsys->pos.x * zoom;
1300 y2 = y + jsys->pos.y * zoom;
1303 r = atan2( ry, rx );
1306 if (sys->jumps[j].hide<=0.) {
1314 glUseProgram( shaders.jumplane.program );
1315 gl_uniformColour( shaders.jumplane.paramv, cole );
1316 glUniform1f( shaders.jumplane.paramf, radius );
1317 gl_renderShader( (x1+x2)/2., (y1+y2)/2., rw, rh, r, &shaders.jumplane, col, 1 );
1325void map_renderSystems(
double bx,
double by,
double x,
double y,
1326 double zoom,
double w,
double h,
double r, MapMode mode )
1328 for (
int i=0; i<
array_size(systems_stack); i++) {
1332 if (sys_isFlag(sys,SYSTEM_HIDDEN))
1336 if ((!sys_isKnown(sys) && !sys_isFlag(sys, SYSTEM_MARKED | SYSTEM_CMARKED)
1340 tx = x + sys->pos.x*zoom;
1341 ty = y + sys->pos.y*zoom;
1344 if (!
rectOverlap(tx-r, ty-r, 2.*r, 2.*r, bx, by, w, h))
1348 if (mode == MAPMODE_EDITOR || mode == MAPMODE_TRAVEL || mode == MAPMODE_TRADE)
1352 if (mode != MAPMODE_EDITOR && !sys_isKnown(sys))
1355 if (mode == MAPMODE_EDITOR || mode == MAPMODE_TRAVEL || mode == MAPMODE_TRADE) {
1356 const glColour *col;
1359 if (!sys_isFlag(sys, SYSTEM_HAS_KNOWN_LANDABLE) && mode != MAPMODE_EDITOR)
1362 if (mode != MAPMODE_EDITOR && !sys_isKnown(sys))
1364 else if (sys->faction < 0)
1366 else if (mode == MAPMODE_EDITOR)
1368 else if (
areEnemies(FACTION_PLAYER,sys->faction))
1370 else if (!sys_isFlag(sys, SYSTEM_HAS_LANDABLE))
1372 else if (
areAllies(FACTION_PLAYER,sys->faction))
1377 if (mode == MAPMODE_EDITOR) {
1384 else if (mode == MAPMODE_DISCOVER) {
1386 if (sys_isFlag( sys, SYSTEM_DISCOVERED ))
1395static void map_renderPath(
double x,
double y,
double zoom,
double radius,
double alpha )
1412 double x1,y1, x2,y2, rx,ry, rw,rh, r;
1413 StarSystem *sys2 = map_path[j];
1414 if (sys_isFlag(sys1,SYSTEM_HIDDEN) || sys_isFlag(sys2,SYSTEM_HIDDEN))
1416 if (jcur == jmax && jmax > 0)
1424 x1 = x + sys1->pos.x * zoom;
1425 y1 = y + sys1->pos.y * zoom;
1426 x2 = x + sys2->pos.x * zoom;
1427 y2 = y + sys2->pos.y * zoom;
1430 r = atan2( ry, rx );
1431 rw = (MOD(rx,ry)+radius)/2.;
1434 glUseProgram( shaders.jumplanegoto.program );
1435 glUniform1f( shaders.jumplanegoto.dt, map_dt );
1436 glUniform1f( shaders.jumplanegoto.paramf, radius );
1437 glUniform1i( shaders.jumplanegoto.parami, (jcur >= 1) );
1438 gl_renderShader( (x1+x2)/2., (y1+y2)/2., rw, rh, r, &shaders.jumplanegoto, &col, 1 );
1448void map_renderNotes(
double bx,
double by,
double x,
double y,
1449 double zoom,
double w,
double h,
int editor,
double alpha )
1454 if ((zoom <= 0.5) || editor)
1458 glClear( GL_DEPTH_BUFFER_BIT );
1461 for (
int i=0; i<
array_size(systems_stack); i++) {
1462 double tx,ty, tw,th;
1467 if (!sys_isFlag(sys,SYSTEM_PMARKED))
1470 if (sys->note == NULL)
1474 tx = x + sys->pos.x*zoom;
1475 ty = y + sys->pos.y*zoom;
1478 if (!map_show_notes && ((
pow2(tx-map_mx-bx)+
pow2(ty-map_my-by)) >
pow2(MAP_MOVE_THRESHOLD)))
1481 if (!map_show_notes)
1482 glClear( GL_DEPTH_BUFFER_BIT );
1505void map_renderNames(
double bx,
double by,
double x,
double y,
1506 double zoom,
double w,
double h,
int editor,
double alpha )
1508 double tx,ty, vx,vy,
d,n;
1517 for (
int i=0; i<
array_size(systems_stack); i++) {
1520 if (sys_isFlag(sys,SYSTEM_HIDDEN))
1524 if (!editor && !sys_isKnown(sys))
1530 tx = x + (sys->pos.x+12.) * zoom;
1531 ty = y + (sys->pos.y) * zoom - font->
h*0.5;
1534 if (!
rectOverlap(tx, ty, textw, font->
h, bx, by, w, h))
1539 gl_printRaw( font, tx, ty, &col, -1, _(sys->name) );
1543 if (!editor || (zoom <= 1.0))
1546 for (
int i=0; i<
array_size(systems_stack); i++) {
1548 for (
int j=0; j<
array_size(sys->jumps); j++) {
1549 StarSystem *jsys = sys->jumps[j].target;
1551 vx = jsys->pos.x - sys->pos.x;
1552 vy = jsys->pos.y - sys->pos.y;
1556 d =
MAX(n*0.3*zoom, 15);
1557 tx = x + zoom*sys->pos.x +
d*vx;
1558 ty = y + zoom*sys->pos.y +
d*vy;
1560 n = sys->jumps[j].hide;
1562 snprintf( buf,
sizeof(buf),
"#gH: %.2f", n );
1564 snprintf( buf,
sizeof(buf),
"H: %.2f", n );
1575static void map_renderMarkers(
double x,
double y,
double zoom,
double r,
double a )
1577 for (
int i=0; i<
array_size(systems_stack); i++) {
1583 if (!sys_isFlag(sys, SYSTEM_MARKED | SYSTEM_CMARKED | SYSTEM_PMARKED))
1587 tx = x + sys->pos.x*zoom;
1588 ty = y + sys->pos.y*zoom;
1591 n = (sys_isFlag(sys, SYSTEM_CMARKED)) ? 1 : 0;
1592 n += (sys_isFlag(sys, SYSTEM_PMARKED)) ? 1 : 0;
1593 n += sys->markers_plot;
1594 n += sys->markers_high;
1595 n += sys->markers_low;
1596 n += sys->markers_computer;
1600 if (sys_isFlag(sys, SYSTEM_PMARKED)) {
1601 map_drawMarker( tx, ty, zoom, r, a, n, j, 5 );
1604 if (sys_isFlag(sys, SYSTEM_CMARKED)) {
1605 map_drawMarker( tx, ty, zoom, r, a, n, j, 0 );
1608 for (m=0; m<sys->markers_plot; m++) {
1609 map_drawMarker( tx, ty, zoom, r, a, n, j, 1 );
1612 for (m=0; m<sys->markers_high; m++) {
1613 map_drawMarker( tx, ty, zoom, r, a, n, j, 2 );
1616 for (m=0; m<sys->markers_low; m++) {
1617 map_drawMarker( tx, ty, zoom, r, a, n, j, 3 );
1620 for (m=0; m<sys->markers_computer; m++) {
1621 map_drawMarker( tx, ty, zoom, r, a, n, j, 4 );
1630static void map_renderSysBlack(
double bx,
double by,
double x,
double y,
double zoom,
double w,
double h,
double r,
int editor )
1632 for (
int i=0; i<
array_size(systems_stack); i++) {
1637 if (sys_isFlag(sys,SYSTEM_HIDDEN))
1641 if ((!sys_isKnown(sys) && !sys_isFlag(sys, SYSTEM_MARKED | SYSTEM_CMARKED)
1645 tx = x + sys->pos.x*zoom;
1646 ty = y + sys->pos.y*zoom;
1649 if (!
rectOverlap(tx - r, ty - r, r, r, bx, by, w, h))
1663void map_renderCommod(
double bx,
double by,
double x,
double y,
1664 double zoom,
double w,
double h,
double r,
int editor,
double a )
1670 if ((cur_commod == -1) || (map_selected == -1) || (commod_known == NULL))
1673 c = commod_known[cur_commod];
1674 if (cur_commod_mode == 1) {
1675 double curMaxPrice, curMinPrice;
1687 curMaxPrice = curMinPrice;
1692 map_renderCommodIgnorance( x, y, zoom, sys,
c, a );
1693 map_renderSysBlack( bx, by, x, y, zoom, w, h, r, editor );
1700 double minPrice = HUGE_VAL;
1701 double maxPrice = 0;
1702 for (
int j=0; j<
array_size(sys->spobs); j++) {
1703 Spob *p = sys->spobs[j];
1704 for (
int k=0; k<
array_size(p->commodities); k++) {
1706 if (p->commodities[k] !=
c)
1708 if (p->commodityPrice[k].cnt <= 0)
1710 thisPrice = p->commodityPrice[k].sum / p->commodityPrice[k].cnt;
1711 maxPrice =
MAX( thisPrice, maxPrice );
1712 minPrice =
MIN( thisPrice, minPrice );
1717 if (maxPrice == 0) {
1718 map_renderCommodIgnorance( x, y, zoom, sys,
c, a );
1719 map_renderSysBlack( bx, by, x, y, zoom, w, h, r, editor );
1722 curMaxPrice = maxPrice;
1723 curMinPrice = minPrice;
1726 map_renderCommodIgnorance( x, y, zoom, sys,
c, a );
1727 map_renderSysBlack( bx, by, x, y, zoom, w, h, r, editor );
1731 for (
int i=0; i<
array_size(systems_stack); i++) {
1735 if (sys_isFlag(sys,SYSTEM_HIDDEN))
1739 if ((!sys_isKnown(sys) && !sys_isFlag(sys, SYSTEM_MARKED | SYSTEM_CMARKED)
1743 tx = x + sys->pos.x*zoom;
1744 ty = y + sys->pos.y*zoom;
1747 if (!
rectOverlap(tx - r, ty - r, r, r, bx, by, w, h))
1752 double minPrice = HUGE_VAL;
1753 double maxPrice = 0;
1754 for (
int j=0; j<
array_size(sys->spobs); j++) {
1755 Spob *p = sys->spobs[j];
1756 for (
int k=0; k<
array_size(p->commodities); k++) {
1758 if (p->commodities[k] !=
c)
1760 if (p->commodityPrice[k].cnt <= 0)
1762 thisPrice = p->commodityPrice[k].sum / p->commodityPrice[k].cnt;
1763 maxPrice =
MAX( thisPrice, maxPrice );
1764 minPrice =
MIN( thisPrice, minPrice );
1772 double best = maxPrice - curMinPrice;
1773 double worst= minPrice - curMaxPrice;
1777 gl_print(&
gl_smallFont, x + (sys->pos.x+11) * zoom, y + (sys->pos.y-22)*zoom, &ccol,
"%.1f",best);
1778 best = tanh ( 2*best / curMinPrice );
1779 col_blend( &ccol, &cFontBlue, &cFontYellow, best );
1787 worst = tanh ( -2*worst/ curMaxPrice );
1788 col_blend( &ccol, &cFontOrange, &cFontYellow, worst );
1806 for (
int i=0; i<
array_size(systems_stack); i++) {
1810 if (sys_isFlag(sys,SYSTEM_HIDDEN))
1814 if ((!sys_isKnown(sys) && !sys_isFlag(sys, SYSTEM_MARKED | SYSTEM_CMARKED)
1818 tx = x + sys->pos.x*zoom;
1819 ty = y + sys->pos.y*zoom;
1822 if (!
rectOverlap(tx - r, ty - r, r, r, bx, by, w, h))
1827 double sumPrice = 0;
1829 for (
int j=0; j<
array_size(sys->spobs); j++) {
1830 Spob *p = sys->spobs[j];
1831 for (
int k=0; k<
array_size(p->commodities); k++) {
1833 if (p->commodities[k] !=
c)
1835 if (p->commodityPrice[k].cnt <= 0)
1837 thisPrice = p->commodityPrice[k].sum / p->commodityPrice[k].cnt;
1838 sumPrice += thisPrice;
1849 if (sumPrice < commod_av_gal_price) {
1850 frac = tanh(5*(commod_av_gal_price / sumPrice - 1));
1851 col_blend( &ccol, &cFontOrange, &cFontYellow, frac );
1854 frac = tanh(5*(sumPrice / commod_av_gal_price - 1));
1855 col_blend( &ccol, &cFontBlue, &cFontYellow, frac );
1875static void map_renderCommodIgnorance(
double x,
double y,
double zoom,
1876 const StarSystem *sys,
const Commodity *
c,
double a )
1879 char buf[80], *line2;
1881 glColour col = cFontRed;
1884 snprintf( buf,
sizeof(buf), _(
"No price info for\n%s here"), _(
c->name) );
1885 line2 = u8_strchr( buf,
'\n', &charn );
1886 if (line2 != NULL) {
1895static int factionPresenceCompare(
const void *a,
const void *b )
1904 return strcmp( fpa->
name, fpb->
name );
1915void map_updateFactionPresence(
const unsigned int wid,
const char *name,
const StarSystem *sys,
int omniscient )
1918 char buf[STRMAX_SHORT] = {
'\0'};
1923 for (
int i=0; i<
array_size(sys->presence); i++) {
1926 if (sys->presence[i].value <= 0.)
1932 fp.
name = N_(
"Unknown");
1935 else if (omniscient)
1939 fp.
value = sys->presence[i].value;
1944 if (strcmp(fp.
name,presence[j].name)==0) {
1966 l +=
scnprintf( &buf[l],
sizeof(buf) - l,
"%s#0%s: #%c%.0f", (l==0) ?
"" :
"\n",
1967 _(p->name), col, p->value );
1971 snprintf( buf,
sizeof(buf), _(
"None") );
1973 window_modifyText( wid, name, buf );
1982static void map_focusLose(
unsigned int wid,
const char* wgtname )
1999static int map_mouse(
unsigned int wid,
const SDL_Event* event,
double mx,
double my,
2000 double w,
double h,
double rx,
double ry,
void *data )
2006 const double t = 15.*15.;
2008 switch (event->type) {
2009 case SDL_MOUSEWHEEL:
2011 if ((mx < 0.) || (mx > w) || (my < 0.) || (my > h))
2013 if (event->wheel.y > 0)
2014 map_buttonZoom( wid,
"btnZoomIn" );
2015 else if (event->wheel.y < 0)
2016 map_buttonZoom( wid,
"btnZoomOut" );
2019 case SDL_MOUSEBUTTONDOWN:
2021 if ((mx < 0.) || (mx > w) || (my < 0.) || (my > h))
2026 mx -= w/2 - cst->
xpos;
2027 my -= h/2 - cst->
ypos;
2030 for (
int i=0; i<
array_size(systems_stack); i++) {
2034 if (sys_isFlag(sys, SYSTEM_HIDDEN))
2038 if (!sys_isFlag(sys, SYSTEM_MARKED | SYSTEM_CMARKED)
2043 x = sys->pos.x * cst->
zoom;
2044 y = sys->pos.y * cst->
zoom;
2047 if (map_selected != -1) {
2049 map_system_open( map_selected );
2053 map_select( sys, (SDL_GetModState() & KMOD_SHIFT) );
2059 case SDL_MOUSEBUTTONUP:
2063 case SDL_MOUSEMOTION:
2082static void map_buttonZoom(
unsigned int wid,
const char* str )
2093 if (strcmp(str,
"btnZoomIn")==0) {
2097 else if (strcmp(str,
"btnZoomOut")==0) {
2102 map_setZoom( wid, cst->
zoom );
2114static void map_genModeList(
void)
2117 const char *odd_template, *even_template;
2119 map_onClose( 0, NULL );
2121 for (
int i=0; i<
array_size(systems_stack); i++) {
2123 for (
int j=0 ; j<
array_size(sys->spobs); j++) {
2124 Spob *p = sys->spobs[j];
2125 for (
int k=0; k<
array_size(p->commodities); k++) {
2126 if (p->commodityPrice[k].cnt > 0 ) {
2129 for (l=0 ; l<totGot; l++) {
2130 if ( p->commodities[k] == commod_known[l] )
2134 commod_known[totGot] = p->commodities[k];
2145 even_template = _(
"%s: Cost");
2146 odd_template = _(
"%s: Trade");
2147 for (
int i=0; i<totGot; i++) {
2148 const char *commod_text = _(commod_known[i]->name);
2149 SDL_asprintf( &
array_grow( &map_modes ), even_template, commod_text );
2150 SDL_asprintf( &
array_grow( &map_modes ), odd_template, commod_text );
2160static void map_modeUpdate(
unsigned int wid,
const char* str )
2163 if (listMapModeVisible==2) {
2164 listMapModeVisible=1;
2166 else if (listMapModeVisible == 1) {
2167 int listpos = toolkit_getListPos( wid,
"lstMapMode" );
2170 map_mode = MAPMODE_TRAVEL;
2174 else if (listpos == 1) {
2175 map_mode = MAPMODE_DISCOVER;
2180 map_mode = MAPMODE_TRADE;
2181 cur_commod = (listpos - MAPMODE_TRADE) / 2;
2182 cur_commod_mode = (listpos - MAPMODE_TRADE) % 2 ;
2191static void map_modeActivate(
unsigned int wid,
const char* str )
2193 map_modeUpdate( wid, str );
2194 listMapModeVisible = 0;
2198static void map_setMinimal(
unsigned int wid,
int value )
2200 map_minimal_mode = value;
2202 window_buttonCaption( wid,
"btnMinimal", (value) ? _(
"Normal View") : _(
"Minimal View") );
2208static void map_buttonMarkSystem(
unsigned int wid,
const char* str )
2212 if (map_selected != -1) {
2216 if (sys->note != NULL) {
2222 if (sys_isFlag(sys, SYSTEM_PMARKED))
2223 sys_rmFlag(sys, SYSTEM_PMARKED);
2225 sys->note =
dialogue_input(_(
"Add System Note"), 0, 60, _(
"Write a note about the #o%s#0 system:"), sys_isKnown(sys) ? _(sys->name) : _(
"Unknown") );
2226 if (sys->note != NULL)
2227 sys_setFlag(sys, SYSTEM_PMARKED);
2235static void map_buttonSystemMap(
unsigned int wid,
const char* str )
2239 if (map_selected != -1)
2241 map_system_open( map_selected );
2247static void map_buttonMinimal(
unsigned int wid,
const char* str )
2250 map_setMinimal( wid, !map_minimal_mode );
2259static void map_buttonCommodity(
unsigned int wid,
const char* str )
2263 char **this_map_modes;
2266 mods = SDL_GetModState();
2267 if (mods & (KMOD_LCTRL | KMOD_RCTRL)) {
2268 static int cur_commod_last = 0;
2269 static int cur_commod_mode_last = 0;
2270 static int map_mode_last = MAPMODE_TRAVEL;
2271 if (map_mode == MAPMODE_TRAVEL) {
2272 map_mode = map_mode_last;
2273 cur_commod = cur_commod_last;
2274 if (cur_commod == -1)
2276 cur_commod_mode = cur_commod_mode_last;
2279 map_mode_last = map_mode;
2280 map_mode = MAPMODE_TRAVEL;
2281 cur_commod_last = cur_commod;
2282 cur_commod_mode_last = cur_commod_mode;
2285 if (cur_commod >= (
array_size(map_modes)-1)/2 )
2288 if (listMapModeVisible) {
2289 listMapModeVisible = 0;
2295 if (listMapModeVisible) {
2296 listMapModeVisible = 0;
2301 this_map_modes = calloc(
sizeof(
char*),
array_size(map_modes) );
2303 this_map_modes[i]=strdup(map_modes[i]);
2305 listMapModeVisible = 2;
2306 if (map_mode == MAPMODE_TRAVEL)
2308 else if (map_mode == MAPMODE_DISCOVER)
2311 defpos = cur_commod*2 + MAPMODE_TRADE - cur_commod_mode;
2313 window_addList( wid, -10, 60, 200, 200,
"lstMapMode",
2314 this_map_modes,
array_size(map_modes), defpos, map_modeUpdate, map_modeActivate );
2322static void map_onClose(
unsigned int wid,
const char *str )
2326 free( commod_known );
2327 commod_known = NULL;
2329 free( map_modes[i] );
2334void map_cleanup (
void)
2343void map_close (
void)
2353void map_clear (
void)
2360static void map_updateInternal(
CstMapWidget *cst,
double dt )
2363 double mapmin = 1.-map_minimal_mode;
2365#define AMAX(x) (x) = MIN( 1., (x) + dt )
2366#define AMIN(x) (x) = MAX( 0., (x) - dt )
2368if ((x) < y) (x) = MIN( y, (x) + dt ); \
2369else (x) = MAX( y, (x) - dt )
2370 switch (cst->
mode) {
2371 case MAPMODE_EDITOR:
2372 case MAPMODE_TRAVEL:
2382 case MAPMODE_DISCOVER:
2410 double angle = ANGLE(dx,dy);
2412 mod =
MIN( mod, dt*map_flyto_speed);
2413 cst->
xpos += mod * cos(angle);
2414 cst->
ypos += mod * sin(angle);
2421static void map_reset(
CstMapWidget* cst, MapMode mode )
2424 map_updateInternal( cst, 1000. );
2430static CstMapWidget* map_globalCustomData(
unsigned int wid )
2434 return (wid > 0) ? window_custGetData( wid,
"cstMap" ) : NULL;
2440static void map_selectCur (
void)
2455StarSystem* map_getDestination(
int *jumps )
2476 array_erase( &map_path, &map_path[0], &map_path[1] );
2483 if (map_path[0] ==
cur_system->jumps[j].target) {
2507void map_select(
const StarSystem *sys,
char shifted )
2510 unsigned int wid = 0;
2530 const vec2 *posstart = NULL;
2534 map_path = map_getJumpPath(
cur_system->name, posstart, sys->name, 0, 1, map_path, NULL );
2544 if (map_path[0] ==
cur_system->jumps[i].target) {
2561 window_enableButton( wid,
"btnAutonav" );
2563 window_disableButton( wid,
"btnAutonav" );
2575void map_cycleMissions(
int dir)
2578 StarSystem *dest = map_getDestination( NULL );
2580 int found_next_i = -1;
2581 int found_prev_i = -1;
2595 if (!sys_isFlag(&systems_stack[i], SYSTEM_MARKED | SYSTEM_PMARKED) || !
space_sysReachable(&systems_stack[i]) )
2609 if (&systems_stack[i]==dest)
2622 if (dir>0 && found_next_i>=0)
2624 else if (dir<0 && found_prev_i>=0)
2630 map_select( target, 0 );
2631 map_center(
window_get( MAP_WDWNAME ), target->name );
2641void map_toggleNotes()
2643 map_show_notes = !map_show_notes;
2656typedef struct SysNode_ {
2668static SysNode* A_newNode( StarSystem* sys );
2669static int A_g(
const SysNode* n );
2670static double A_d(
const SysNode* n );
2676static void A_freeList(
SysNode *first );
2677static int map_decorator_parse(
MapDecorator *temp,
const char *file );
2679static SysNode* A_newNode( StarSystem* sys )
2692static int A_g(
const SysNode* n )
2697static double A_d(
const SysNode* n )
2704 return (A_g(op1) < A_g(op2)) || (A_g(op1) == A_g(op2) && A_d(op1) < A_d(op2));
2715 while (n->next != NULL)
2726 if (first->sys == cur) {
2735 if (n->sys == cur) {
2741 }
while ((n=n->next) != NULL);
2757 }
while ((n=n->next) != NULL);
2771 if (A_less(n, lowest))
2773 }
while ((n=n->next) != NULL);
2777static void A_freeList(
SysNode *first )
2789 }
while ((n=n->gnext) != NULL);
2794void map_setZoom(
unsigned int wid,
double zoom )
2812StarSystem** map_getJumpPath(
const char* sysstart,
const vec2 *posstart,
const char* sysend,
2813 int ignore_known,
int show_hidden, StarSystem** old_data,
double *o_distance )
2816 StarSystem *ssys, *esys, **res;
2835 if (ssys==esys ||
array_size(ssys->jumps)==0) {
2848 const vec2 *p_pos_entry = (ojumps > 0) ? NULL : posstart;
2850 const char *prev_name = sysstart;
2852 prev_name = old_data[ojumps - 2]->name;
2854 const JumpPoint* jp =
jump_get(prev_name, ssys);
2856 p_pos_entry = &jp->pos;
2861 open = closed = NULL;
2862 cur = A_newNode( ssys );
2866 cur->
pos = p_pos_entry;
2867 open = A_add( open, cur );
2870 while ((cur = A_lowest(open))) {
2873 if (cur->
sys == esys)
2878 if (j > MAP_LOOP_PROT)
2882 open = A_rm( open, cur->
sys );
2883 closed = A_add( closed, cur );
2884 cost = A_g(cur) + 1;
2887 JumpPoint *jp = &cur->
sys->jumps[i];
2888 StarSystem *sys = jp->target;
2891 if (!ignore_known) {
2892 if (!jp_isKnown(jp))
2897 if (jp_isFlag( jp, JP_EXITONLY ))
2901 if (!show_hidden && jp_isFlag( jp, JP_HIDDEN ))
2907 .d = A_d(cur) + ((cur->
pos != NULL) ? vec2_dist(cur->
pos, &jp->pos) : 0.0)
2911 ccost = A_in(closed, sys);
2912 if ((ccost != NULL) && !A_less(&n_cost, ccost))
2917 ocost = A_in(open, sys);
2918 if (ocost != NULL) {
2919 if (A_less(&n_cost, ocost))
2920 open = A_rm( open, sys );
2927 neighbour = A_newNode( sys );
2929 neighbour->
g = n_cost.
g;
2930 neighbour->
d = n_cost.
d;
2931 neighbour->
pos = (jp_entry != NULL) ? &jp_entry->pos : NULL;
2932 open = A_add( open, neighbour );
2940 if (o_distance != NULL) {
2941 *o_distance = cur->
d;
2945 if (cur != NULL && esys == cur->
sys) {
2946 int njumps = A_g(cur) + ojumps;
2947 assert( njumps > ojumps );
2952 for (
int i=0; i<njumps-ojumps; i++) {
2953 res[njumps-i-1] = cur->
sys;
2974int map_map(
const Outfit *map )
2977 sys_setFlag(map->
u.
map->systems[i], SYSTEM_KNOWN);
2984 if (sysname == NULL)
2985 WARN(_(
"Map '%s' is trying to set spob '%s' as known when it has no system!"), map->
name, spb->
name );
2989 const StarSystem *ss = map->
u.
map->systems[j];
2990 if (strcmp( ss->name, sysname )==0) {
2996 WARN(_(
"Map '%s' is trying to set spob '%s' as known when it is not in the system list! '%s' is in the '%s' system!"),
3003 jp_setFlag(map->
u.
map->jumps[i], JP_KNOWN);
3015int map_isUseless(
const Outfit* map )
3018 if (!sys_isKnown(map->
u.
map->systems[i]))
3022 const Spob *p = map->
u.
map->spobs[i];
3025 if (!spob_isKnown(p))
3030 if (!jp_isKnown(map->
u.
map->jumps[i]))
3039int localmap_map(
const Outfit *lmap )
3051 if (jp_isFlag(jp, JP_EXITONLY) || jp_isFlag(jp, JP_HIDDEN))
3053 if (mod*jp->hide <= detect)
3054 jp_setFlag( jp, JP_KNOWN );
3062 if (mod*p->hide <= detect)
3072int localmap_isUseless(
const Outfit *lmap )
3084 if (jp_isFlag(jp, JP_EXITONLY) || jp_isFlag(jp, JP_HIDDEN))
3086 if ((mod*jp->hide <= detect) && !jp_isKnown( jp ))
3093 if ((mod*p->hide <= detect) && !spob_isKnown( p ))
3111void map_show(
int wid,
int x,
int y,
int w,
int h,
double zoom,
double xoff,
double yoff )
3116 window_addCust( wid, x, y, w, h,
3117 "cstMap", 1, map_render, map_mouse, NULL, map_focusLose, cst );
3118 window_custSetDynamic( wid,
"cstMap", 1 );
3119 window_custAutoFreeData( wid,
"cstMap" );
3133 map_setZoom( wid, zoom );
3135 map_reset( cst, MAPMODE_TRAVEL );
3145int map_center(
int wid,
const char *sys )
3161 map_flyto_speed =
MIN( 2000.,
d / 0.2 );
3174 Uint32 time = SDL_GetTicks();
3179 for (
int i=0; i<
array_size(decorator_files); i++) {
3181 int ret = map_decorator_parse( &temp, decorator_files[i] );
3184 free( decorator_files[i] );
3190 time = SDL_GetTicks() - time;
3191 DEBUG( n_(
"Loaded %d map decorator in %.3f s",
"Loaded %d map decorators in %.3f s",
array_size(decorator_stack) ),
array_size(decorator_stack), time/1000. );
3194 DEBUG( n_(
"Loaded %d map decorator",
"Loaded %d map decorators",
array_size(decorator_stack) ),
array_size(decorator_stack) );
3200static int map_decorator_parse(
MapDecorator *temp,
const char *file )
3203 xmlNodePtr node, parent;
3209 parent = doc->xmlChildrenNode;
3210 if (strcmp((
char*)parent->name,
"decorator")) {
3211 ERR(_(
"Malformed %s file: missing root element 'decorator'"), file );
3221 node = parent->xmlChildrenNode;
3223 xml_onlyNodes(node);
3224 xmlr_float(node,
"x", temp->x);
3225 xmlr_float(node,
"y", temp->
y);
3227 if (xml_isNode(node,
"image")) {
3229 MAP_DECORATOR_GFX_PATH
"%s", 1, 1, OPENGL_TEX_MIPMAPS );
3231 if (temp->
image == NULL)
3232 WARN(_(
"Could not load map decorator texture '%s'."), xml_get(node));
3236 WARN(_(
"Map decorator has unknown node '%s'."), node->name);
3237 }
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.
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?
char faction_getColourChar(int f)
Gets the faction character associated to its standing with the player.
const glTexture * faction_logo(int f)
Gets the faction's logo (ideally 256x256).
int areEnemies(int a, int b)
Checks whether two factions are enemies.
const char * faction_name(int f)
Gets a factions "real" (internal) name.
const char * faction_getStandingText(int f)
Gets the player's standing in human readable form.
const glColour * faction_colour(int f)
Gets the colour of the faction.
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 areAllies(int a, int b)
Checks whether two factions are allies or not.
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 mat4_translate(mat4 *m, double x, double y, double z)
Translates a homogenous transformation matrix.
void mat4_scale(mat4 *m, double x, double y, double z)
Scales a homogeneous transformation matrix.
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.
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.
const char * spob_getSystem(const char *spobname)
Get the name of a system from a spobname.
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.
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.
JumpPoint * jump_get(const char *jumpname, const StarSystem *sys)
Gets a jump point based on its target and system.
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.
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
CommodityPrice * commodityPrice
Node structure for A* pathfinding.
Represents a font in memory.
Abstraction for rendering sprite sheets.