17#include "dev_mapedit.h"
23#include "dev_sysedit.h"
24#include "dev_system.h"
25#include "dev_uniedit.h"
37#include "tk/toolkit_priv.h"
43#define BUTTON_WIDTH 80
44#define BUTTON_HEIGHT 30
46#define MAPEDIT_EDIT_WIDTH 400
47#define MAPEDIT_EDIT_HEIGHT 450
49#define MAPEDIT_DRAG_THRESHOLD 300
50#define MAPEDIT_MOVE_THRESHOLD 10
52#define MAPEDIT_ZOOM_STEP 1.2
53#define MAPEDIT_ZOOM_MAX 5
54#define MAPEDIT_ZOOM_MIN -5
56#define MAPEDIT_OPEN_WIDTH 800
57#define MAPEDIT_OPEN_HEIGHT 500
58#define MAPEDIT_OPEN_TXT_WIDTH 300
60#define MAPEDIT_SAVE_WIDTH 800
61#define MAPEDIT_SAVE_HEIGHT 500
62#define MAPEDIT_SAVE_TXT_WIDTH 300
64typedef struct mapOutfitsList_s {
106static void mapedit_render(
double bx,
double by,
double w,
double h,
109static int mapedit_mouse(
unsigned int wid,
const SDL_Event *event,
double mx,
110 double my,
double w,
double h,
double xr,
double yr,
113static void mapedit_close(
unsigned int wid,
const char *wgt );
114static void mapedit_btnOpen(
unsigned int wid_unused,
const char *unused );
116static void mapedit_clear(
unsigned int wid_unused,
const char *unused );
117static void mapedit_chkSpob(
unsigned int wid,
const char *wgtname );
118static void mapedit_chkHidden(
unsigned int wid,
const char *wgtname );
120static int mapedit_keys(
unsigned int wid, SDL_Keycode key, SDL_Keymod mod,
165 wid =
window_create(
"wdwMapOutfitEditor", _(
"Map Outfit Editor" ), -1, -1,
171 window_addCust( wid, 20, -40, SCREEN_W - 350, SCREEN_H - 100,
"cstSysEdit",
177 window_addButtonKey( wid, -20 - (
BUTTON_WIDTH + 20 ) * buttonHPos,
184 window_addButtonKey( wid, -20 - (
BUTTON_WIDTH + 20 ) * buttonHPos,
191 window_addButtonKey( wid, -20 - (
BUTTON_WIDTH + 20 ) * buttonHPos,
199 window_addButtonKey( wid, -20 - (
BUTTON_WIDTH + 20 ) * buttonHPos,
205 window_addText( wid, -200, -40 - textPos * parHeight - linesPos * lineHeight,
206 100, lineHeight, 0,
"txtSFileName", &
gl_smallFont, NULL,
208 window_addInput( wid, -30, -40 - textPos * parHeight - linesPos * lineHeight,
209 170, lineHeight,
"inpFileName", 1024, 1, &
gl_smallFont );
214 window_addText( wid, -200, -40 - textPos * parHeight - linesPos * lineHeight,
217 window_addInput( wid, -30, -40 - textPos * parHeight - linesPos * lineHeight,
218 170, lineHeight,
"inpMapName", 1024, 1, &
gl_smallFont );
224 window_addText( wid, -20, -40 - textPos * parHeight - linesPos * lineHeight,
225 300 - 20, lineHeight, 0,
"txtSDescription", &
gl_smallFont,
226 NULL, _(
"Description:" ) );
227 window_addInput( wid, -20,
228 -40 - textPos * parHeight - ( linesPos + 1 ) * lineHeight,
229 300 - 20, curLines * lineHeight,
"inpDescription", 32768, 0,
232 linesPos += ( curLines + 1 );
236 window_addText( wid, -20, -40 - textPos * parHeight - linesPos * lineHeight,
237 300 - 20, 20, 0,
"txtSCurrentNumSystems", &
gl_smallFont,
238 NULL, _(
"Number of Systems (up to 100):" ) );
239 window_addText( wid, -20, -40 - textPos * parHeight - linesPos * lineHeight,
240 60, curLines * lineHeight, 0,
"txtCurrentNumSystems",
247 window_addText( wid, -20, -40 - textPos * parHeight - linesPos * lineHeight,
250 window_addText( wid, -20,
251 -40 - textPos * parHeight - ( linesPos + 1 ) * lineHeight,
252 300 - 20, curLines * lineHeight, 0,
"txtPresence",
255 linesPos += curLines + 1;
259 window_addText( wid, -200, -40 - textPos * parHeight - linesPos * lineHeight,
262 window_addInput( wid, -30, -40 - textPos * parHeight - linesPos * lineHeight,
264 window_setInputFilter( wid,
"inpPrice", INPUT_FILTER_NUMBER );
266 linesPos += curLines;
269 window_addText( wid, -200, -40 - textPos * parHeight - linesPos * lineHeight,
272 window_addInput( wid, -30, -40 - textPos * parHeight - linesPos * lineHeight,
275 linesPos += curLines;
278 window_addText( wid, -200, -40 - textPos * parHeight - linesPos * lineHeight,
281 window_addInput( wid, -30, -40 - textPos * parHeight - linesPos * lineHeight,
283 window_setInputFilter( wid,
"inpRarity", INPUT_FILTER_NUMBER );
285 linesPos += curLines + 1;
289 window_addCheckbox( wid, -30,
290 -40 - textPos * parHeight - linesPos * lineHeight, 170,
291 lineHeight,
"chkSpob", _(
"Ignore Spobs" ),
294 linesPos += curLines + 1;
298 window_addCheckbox( wid, -30,
299 -40 - textPos * parHeight - linesPos * lineHeight, 170,
300 lineHeight,
"chkHidden", _(
"Set Hidden Jumps" ),
303 linesPos += curLines + 1;
307 wid, -20, -40 - textPos * parHeight - linesPos * lineHeight, 300 - 20,
308 curLines * lineHeight, 0,
"txtSWarning", &
gl_smallFont, NULL,
309 _(
"Warning: Editor can't (yet) manage which details are mapped within a "
310 "system. Review its changes before committing." ) );
312 linesPos += curLines + 1;
315 window_addButtonKey( wid, 40, 20, 30, 30,
"btnZoomIn",
"+",
317 window_addButtonKey( wid, 80, 20, 30, 30,
"btnZoomOut",
"-",
321 window_addText( wid, 140, 10, SCREEN_W - 350 - 30 - 30 -
BUTTON_WIDTH - 20,
331static int mapedit_keys(
unsigned int wid, SDL_Keycode key, SDL_Keymod mod,
379static void mapedit_chkSpob(
unsigned int wid,
const char *wgtname )
384static void mapedit_chkHidden(
unsigned int wid,
const char *wgtname )
413 uniedit_renderMap( bx, by, w, h, x, y,
mapedit_zoom, r );
449static int mapedit_mouse(
unsigned int wid,
const SDL_Event *event,
double mx,
450 double my,
double w,
double h,
double xr,
double yr,
454 const double t = 15. * 15.;
456 switch (event->type) {
459 if (( mx < 0. ) || ( mx > w ) || ( my < 0. ) || ( my > h ))
461 if (event->wheel.y > 0)
463 else if (event->wheel.y < 0)
467 case SDL_MOUSEBUTTONDOWN:
469 if (( mx < 0. ) || ( mx > w ) || ( my < 0. ) || ( my > h ))
474 if (event->button.button == SDL_BUTTON_X1) {
477 }
else if (event->button.button == SDL_BUTTON_X2) {
495 if ((
pow2( mx - x ) +
pow2( my - y ) ) < t) {
527 case SDL_MOUSEBUTTONUP:
532 case SDL_MOUSEMOTION:
564 window_modifyText(
mapedit_wid,
"txtSelected", _(
"No selection" ) );
565 window_modifyText(
mapedit_wid,
"txtCurrentNumSystems",
"0" );
616 char buf[STRMAX_SHORT];
630 window_modifyText(
mapedit_wid,
"txtSelected", buf );
634 window_modifyText(
mapedit_wid,
"txtCurrentNumSystems", buf );
639 map_updateFactionPresence(
mapedit_wid,
"txtPresence", sys, 1 );
640 snprintf( &buf[0],
sizeof( buf ), _(
"Presence (%s)" ), sys->name );
641 window_modifyText(
mapedit_wid,
"txtSPresence", buf );
643 window_modifyText(
mapedit_wid,
"txtSPresence", _(
"Presence" ) );
645 _(
"No system yet clicked" ) );
664 if (strcmp( str,
"btnZoomIn" ) == 0) {
668 }
else if (strcmp( str,
"btnZoomOut" ) == 0) {
689 wid =
window_create(
"wdwOpenMapOutfit", _(
"Open Map Outfit" ), -1, -1,
703 names = malloc(
sizeof(
char * ) * n );
704 for (
int i = 0; i < n; i++) {
706 names[i] = strdup( ns->mapName );
711 names = malloc(
sizeof(
char * ) );
712 names[0] = strdup(
"None" );
719 0,
"txtMapInfo", NULL, NULL, NULL );
747 char buf[STRMAX_SHORT];
750 save = toolkit_getList( wdw,
"lstMapOutfits" );
751 if (strcmp( save,
"None" ) == 0)
755 pos = toolkit_getListPos( wdw,
"lstMapOutfits" );
759 snprintf( buf,
sizeof( buf ),
768 ns->fileName, ns->mapName, ns->description, ns->numSystems );
770 window_modifyText( wdw,
"txtMapInfo", buf );
790 int pos, len, compareLimit, i, found;
793 char *file, *name, *systemName;
801 save = toolkit_getList( wdw,
"lstMapOutfits" );
802 if (strcmp( save,
"None" ) == 0)
810 pos = toolkit_getListPos( wdw,
"lstMapOutfits" );
814 len = strlen( MAP_DATA_PATH ) + strlen( ns->fileName ) + 2;
815 file = malloc( len );
816 snprintf( file, len,
"%s%s", MAP_DATA_PATH, ns->fileName );
821 node = doc->xmlChildrenNode;
828 if (!xml_isNode( node,
"outfit" )) {
835 xmlr_attr_strd( node,
"name", name );
836 if (strcmp( ns->mapName, name ) != 0) {
847 node = node->xmlChildrenNode;
849 xml_onlyNodes( node );
851 if (!xml_isNode( node,
"specific" ))
856 }
while (xml_nextNode( node ));
861 node = node->xmlChildrenNode;
863 xml_onlyNodes( node );
865 if (!xml_isNode( node,
"sys" ))
870 xmlr_attr_strd( node,
"name", systemName );
876 compareLimit = strlen( systemName );
877 if (strncmp( systemName, sys->name, compareLimit ) == 0) {
888 }
while (xml_nextNode( node ));
906 ns.fileName = strdup( window_getInput( wdw,
"inpFileName" ) );
907 ns.mapName = strdup( window_getInput( wdw,
"inpMapName" ) );
908 ns.description = strdup( window_getInput( wdw,
"inpDescription" ) );
909 ns.gfx_store = strdup( window_getInput( wdw,
"inpGFX" ) );
911 ns.price = atoll( window_getInput( wdw,
"inpPrice" ) );
912 ns.rarity = atoi( window_getInput( wdw,
"inpRarity" ) );
919 free( ns.description );
920 free( ns.gfx_store );
931 window_setInput(
mapedit_wid,
"inpFileName", ns->fileName );
932 window_setInput(
mapedit_wid,
"inpMapName", ns->mapName );
933 window_setInput(
mapedit_wid,
"inpDescription", ns->description );
934 window_setInput(
mapedit_wid,
"inpGFX", ns->gfx_store );
935 snprintf( buf,
sizeof( buf ),
"%i", ns->numSystems );
936 window_modifyText(
mapedit_wid,
"txtCurrentNumSystems", buf );
937 snprintf( buf,
sizeof( buf ),
"%" CREDITS_PRI, ns->price );
939 snprintf( buf,
sizeof( buf ),
"%i", ns->rarity );
954 int is_map, nSystems;
955 xmlNodePtr node, cur;
958 char *file, *name, *outfitType;
964 map_files = PHYSFS_enumerateFiles( MAP_DATA_PATH );
966 for (
size_t i = 0; map_files[i] != NULL; i++) {
967 char *description = NULL;
968 char *gfx_store = NULL;
969 credits_t price = 1000;
972 SDL_asprintf( &file,
"%s%s", MAP_DATA_PATH, map_files[i] );
981 node = doc->xmlChildrenNode;
988 if (!xml_isNode( node,
"outfit" )) {
995 xmlr_attr_strd( node,
"name", name );
998 node = node->xmlChildrenNode;
1001 xml_onlyNodes( node );
1003 if (!xml_isNode( node,
"specific" )) {
1004 if (xml_isNode( node,
"general" )) {
1005 cur = node->children;
1007 xml_onlyNodes( cur );
1008 xmlr_str( cur,
"description", description );
1009 xmlr_long( cur,
"price", price );
1010 xmlr_int( cur,
"rarity", rarity );
1011 xmlr_str( cur,
"gfx_store", gfx_store );
1012 }
while (xml_nextNode( cur ));
1018 xmlr_attr_strd( node,
"type", outfitType );
1019 is_map = outfitType == NULL ? 0 : !strncmp( outfitType,
"map", 3 );
1024 }
while (xml_nextNode( node ));
1036 node = node->xmlChildrenNode;
1038 xml_onlyNodes( node );
1039 if (!xml_isNode( node,
"sys" ))
1045 }
while (xml_nextNode( node ));
1050 newMapItem->numSystems = nSystems;
1051 newMapItem->fileName = strdup( map_files[i] );
1052 newMapItem->mapName = strdup( name );
1053 newMapItem->description =
1054 strdup( ( description != NULL ) ? description :
"" );
1055 newMapItem->gfx_store =
1056 strdup( ( gfx_store != NULL ) ? gfx_store :
"" );
1057 newMapItem->price = price;
1058 newMapItem->rarity = rarity;
1064 free( description );
1069 PHYSFS_freeList( map_files );
1080 for (
unsigned int i = 0; i < n; i++) {
1081 free( mapList[i].fileName );
1082 free( mapList[i].mapName );
1083 free( mapList[i].description );
1084 free( mapList[i].gfx_store );
1101 xmlTextWriterPtr writer;
1105 if (conf.dev_data_dir == NULL) {
1106 WARN( _(
"%s is not set!" ),
"conf.dev_data_dir" );
1111 writer = xmlNewTextWriterDoc( &doc, 0 );
1112 if (writer == NULL) {
1113 WARN( _(
"testXmlwriterDoc: Error creating the xml writer" ) );
1121 xmlw_start( writer );
1122 xmlw_startElem( writer,
"outfit" );
1125 xmlw_attr( writer,
"name",
"%s", ns->mapName );
1128 xmlw_startElem( writer,
"general" );
1129 xmlw_elem( writer,
"rarity",
"%d", ns->rarity );
1130 xmlw_elem( writer,
"mass",
"%d", 0 );
1131 xmlw_elem( writer,
"price",
"%" CREDITS_PRI, ns->price );
1132 xmlw_elem( writer,
"description",
"%s", ns->description );
1133 xmlw_elem( writer,
"gfx_store",
"%s", ns->gfx_store );
1134 xmlw_endElem( writer );
1136 xmlw_startElem( writer,
"specific" );
1137 xmlw_attr( writer,
"type",
"map" );
1141 for (
int i = 0; i < ns->numSystems; i++) {
1143 xmlw_startElem( writer,
"sys" );
1144 xmlw_attr( writer,
"name",
"%s", s->name );
1148 for (
int j = 0; j <
array_size( s->jumps ); j++) {
1150 if (jp_isFlag( &s->jumps[j], JP_EXITONLY ))
1155 for (
int k = 0; k < ns->numSystems; k++) {
1157 xmlw_elem( writer,
"jump",
"%s",
uniedit_sys[k]->name );
1165 for (
int j = 0; j <
array_size( s->spobs ); j++)
1166 xmlw_elem( writer,
"spob",
"%s", s->spobs[j]->name );
1168 xmlw_endElem( writer );
1171 xmlw_endElem( writer );
1172 xmlw_endElem( writer );
1173 xmlw_done( writer );
1176 xmlFreeTextWriter( writer );
1179 SDL_asprintf( &file,
"%s/outfits/maps/%s", conf.dev_data_dir, ns->fileName );
1180 if (xmlSaveFileEnc( file, doc,
"UTF-8" ) < 0) {
1181 WARN( _(
"Failed writing '%s'!" ), file );
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
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_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
static int mapedit_mapsList_refresh(void)
Gets the list of all the maps names. from outfit_mapParse()
static void mapedit_focusLose(unsigned int wid, const char *wgtname)
Called when it's de-focused.
static int mapedit_keys(unsigned int wid, SDL_Keycode key, SDL_Keymod mod, int isrepeat)
Handles keybindings.
static void mapedit_buttonZoom(unsigned int wid, const char *str)
Handles the button zoom clicks.
static void mapedit_selectRm(StarSystem *sys)
Removes a system from the selection.
static void mapedit_btnOpen(unsigned int wid_unused, const char *unused)
Opens up a map file.
void mapedit_open(unsigned int wid_unused, const char *unused)
Opens the system editor interface.
static unsigned int mapedit_wid
static char * mapedit_sLoadMapName
#define MAPEDIT_OPEN_WIDTH
static StarSystem ** mapedit_sys
static void mapedit_loadMapMenu_update(unsigned int wdw, const char *str)
Updates the load menu.
static int mapedit_nospob
static void mapedit_loadMapMenu_load(unsigned int wdw, const char *str)
Load the selected Map.
static int mapedit_hidden
static double mapedit_zoom
static int mapedit_mouse(unsigned int wid, const SDL_Event *event, double mx, double my, double w, double h, double xr, double yr, void *data)
System editor custom widget mouse handling.
static int mapedit_saveMap(StarSystem **uniedit_sys, mapOutfitsList_t *ns)
Saves selected systems as a map outfit file.
static unsigned int mapedit_widLoad
static void mapedit_btnSaveMapAs(unsigned int wid_unused, const char *unused)
Save the current Map to selected file.
#define MAPEDIT_OPEN_TXT_WIDTH
void mapedit_selectText(void)
Sets the selected system text.
static double mapedit_xpos
static void mapedit_loadMapMenu_close(unsigned int wdw, const char *str)
Closes the load map outfit menu.
StarSystem * systems_stack
static void mapedit_selectAdd(StarSystem *sys)
Adds a system to the selection.
static void mapsList_free(void)
Frees the loaded map.
void mapedit_setGlobalLoadedInfos(mapOutfitsList_t *ns)
Set and display the global variables describing last loaded/saved file.
static void mapedit_loadMapMenu_open(void)
Opens the load map outfit menu.
static unsigned int mapedit_dragTime
static int mapedit_iLastClickedSystem
static void mapedit_clear(unsigned int wid_unused, const char *unused)
Closes the system editor widget.
#define MAPEDIT_OPEN_HEIGHT
static void mapedit_deselect(void)
Deselects selected targets.
static double mapedit_ypos
static void mapedit_render(double bx, double by, double w, double h, void *data)
System editor custom widget rendering.
#define MAPEDIT_ZOOM_STEP
static void mapedit_close(unsigned int wid, const char *wgt)
Closes the system editor widget.
static StarSystem ** uniedit_sys
Header file with generic functions and naev-specifics.
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
void xmlw_setParams(xmlTextWriterPtr writer)
Sets up the standard xml write parameters.
xmlDocPtr xml_parsePhysFS(const char *filename)
Analogous to xmlParseMemory/xmlParseFile.
void gl_renderCircle(double cx, double cy, double r, const glColour *c, int filled)
Draws a circle.
void pause_game(void)
Pauses the game.
void unpause_game(void)
Unpauses the game.
void systems_reconstructJumps(void)
Reconstructs the jumps.
StarSystem * system_getIndex(int id)
Get the system by its index.
void diff_clear(void)
Removes all active diffs. (Call before economy_destroy().)