naev 0.10.4
dev_sysedit.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include "physfs.h"
11#include "SDL.h"
12
13#include "naev.h"
16#include "dev_sysedit.h"
17
18#include "array.h"
19#include "conf.h"
20#include "dev_spob.h"
21#include "dev_system.h"
22#include "dev_uniedit.h"
23#include "dialogue.h"
24#include "economy.h"
25#include "map.h"
26#include "ndata.h"
27#include "nstring.h"
28#include "opengl.h"
29#include "opengl_render.h"
30#include "safelanes.h"
31#include "space.h"
32#include "tk/toolkit_priv.h"
33#include "toolkit.h"
34#include "unidiff.h"
35
36#define BUTTON_WIDTH 100
37#define BUTTON_HEIGHT 30
39#define SYSEDIT_EDIT_WIDTH 500
40#define SYSEDIT_EDIT_HEIGHT 400
42#define SYSEDIT_DRAG_THRESHOLD 300
43#define SYSEDIT_MOVE_THRESHOLD 10
45#define SYSEDIT_ZOOM_STEP 1.2
46#define SYSEDIT_ZOOM_MAX 1
47#define SYSEDIT_ZOOM_MIN -23
49/*
50 * Selection types.
51 */
52enum {
58};
59
63typedef struct Select_s {
64 int type;
65 union {
66 int spob;
67 int jump;
68 int asteroid;
69 int astexclude;
70 } u;
71} Select_t;
72static Select_t *sysedit_select = NULL;
73static int sysedit_nselect = 0;
74static int sysedit_mselect = 0;
76static int sysedit_tadd = 0;
78/*
79 * System editor stuff.
80 */
81static StarSystem *sysedit_sys = NULL;
82static unsigned int sysedit_wid = 0;
83static unsigned int sysedit_widEdit = 0;
84static int sysedit_grid = 1;
85static double sysedit_xpos = 0.;
86static double sysedit_ypos = 0.;
87static double sysedit_zoom = 1.;
88static int sysedit_moved = 0;
89static unsigned int sysedit_dragTime = 0;
90static int sysedit_drag = 0;
91static int sysedit_dragSel = 0;
92static double sysedit_mx = 0.;
93static double sysedit_my = 0.;
95/* Stored checkbox values. */
96static int jp_hidden = 0;
97static int jp_exit = 0;
99/*
100 * System editor Prototypes.
101 */
102/* Custom system editor widget. */
103static void sysedit_buttonZoom( unsigned int wid, const char* str );
104static void sysedit_render( double bx, double by, double w, double h, void *data );
105static void sysedit_renderAsteroidsField( double bx, double by, const AsteroidAnchor *ast, int selected );
106static void sysedit_renderAsteroidExclusion( double bx, double by, const AsteroidExclusion *aexcl, int selected );
107static void sysedit_renderBG( double bx, double bw, double w, double h, double x, double y );
108static void sysedit_renderSprite( glTexture *gfx, double bx, double by, double x, double y,
109 int sx, int sy, const glColour *c, int selected, const char *caption );
110static void sysedit_focusLose( unsigned int wid, const char* wgtname );
111static int sysedit_mouseTrySelect( const Select_t *sel, double x, double y, double t, double mx, double my, SDL_Keymod mod, void (*func)(void) );
112static int sysedit_mouse( unsigned int wid, SDL_Event* event, double mx, double my,
113 double w, double h, double xr, double yr, void *data );
114/* Button functions. */
115static void sysedit_close( unsigned int wid, const char *wgt );
116static void sysedit_btnNewSpob( unsigned int wid_unused, const char *unused );
117static void sysedit_btnNewAsteroids( unsigned int wid_unused, const char *unused );
118static void sysedit_btnRename( unsigned int wid_unused, const char *unused );
119static void sysedit_btnRemove( unsigned int wid_unused, const char *unused );
120static void sysedit_btnReset( unsigned int wid_unused, const char *unused );
121static void sysedit_btnScale( unsigned int wid_unused, const char *unused );
122static void sysedit_btnGrid( unsigned int wid_unused, const char *unused );
123static void sysedit_btnEdit( unsigned int wid_unused, const char *unused );
124/* Spob editing. */
125static void sysedit_editPnt (void);
126static void sysedit_editPntClose( unsigned int wid, const char *unused );
127static void sysedit_spobDesc( unsigned int wid, const char *unused );
128static void sysedit_spobDescReturn( unsigned int wid, const char *unused );
129static void sysedit_spobDescClose( unsigned int wid, const char *unused );
130static void sysedit_genServicesList( unsigned int wid );
131static void sysedit_btnTechEdit( unsigned int wid, const char *unused );
132static void sysedit_genTechList( unsigned int wid );
133static void sysedit_btnAddTech( unsigned int wid, const char *unused );
134static void sysedit_btnRmTech( unsigned int wid, const char *unused );
135static void sysedit_btnAddService( unsigned int wid, const char *unused );
136static void sysedit_btnRmService( unsigned int wid, const char *unused );
137static void sysedit_spobGFX( unsigned int wid_unused, const char *wgt );
138static void sysedit_btnGFXClose( unsigned int wid, const char *wgt );
139static void sysedit_btnGFXApply( unsigned int wid, const char *wgt );
140static void sysedit_btnFaction( unsigned int wid_unused, const char *unused );
141static void sysedit_btnFactionSet( unsigned int wid, const char *unused );
142/* Jump editing */
143static void sysedit_editJump (void);
144static void sysedit_editJumpClose( unsigned int wid, const char *unused );
145/* Asteroid editing. */
146static void sysedit_editAsteroids (void);
147static void sysedit_editAsteroidsClose( unsigned int wid, const char *unused );
148static void sysedit_genAsteroidsList( unsigned int wid );
149static void sysedit_btnAsteroidsDelete( unsigned int wid, const char *unused );
150static void sysedit_btnRmAsteroid( unsigned int wid, const char *unused );
151static void sysedit_btnAddAsteroid( unsigned int wid, const char *unused );
152/* Exclusion zone editing. */
153static void sysedit_editExclusion (void);
154static void sysedit_editExclusionClose( unsigned int wid, const char *unused );
155static void sysedit_btnExclusionDelete( unsigned int wid, const char *unused );
156/* Keybindings handling. */
157static int sysedit_keys( unsigned int wid, SDL_Keycode key, SDL_Keymod mod );
158/* Selection. */
159static int sysedit_selectCmp( const Select_t *a, const Select_t *b );
160static int sysedit_isSelected( const Select_t *s );
161static void sysedit_checkButtons (void);
162static void sysedit_deselect (void);
163static void sysedit_selectAdd( const Select_t *sel );
164static void sysedit_selectRm( Select_t *sel );
165
169void sysedit_open( StarSystem *sys )
170{
171 unsigned int wid;
172 char buf[128];
173 int i;
174 const glColour cBG = { 0., 0., 0., 0.95 };
175
176 /* Reconstructs the jumps - just in case. */
178
179 /* Reset some variables. */
180 sysedit_sys = sys;
181 sysedit_drag = 0;
183 sysedit_xpos = 0.;
184 sysedit_ypos = 0.;
185
186 /* Load graphics. */
188
189 /* Create the window. */
190 snprintf( buf, sizeof(buf), _("%s - Star System Editor"), sys->name );
191 wid = window_create( "wdwSysEdit", buf, -1, -1, -1, -1 );
193 window_setBorder( wid, 0 );
194 sysedit_wid = wid;
195
197
198 /* Actual viewport, at the bottom. */
199 window_addCust( wid, 0, 0, SCREEN_W, SCREEN_H,
200 "cstSysEdit", 1, sysedit_render, sysedit_mouse, NULL, sysedit_focusLose, NULL );
201
202 /* Overlay background. */
203 window_addRect( wid, SCREEN_W-130, 0, 130, SCREEN_H, "rctRCol", &cBG, 0 );
204 window_addRect( wid, 0, 0, SCREEN_W, 60, "rctBBar", &cBG, 0 );
205
206 /* Close button. */
207 window_addButtonKey( wid, -15, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
208 "btnClose", _("Exit"), sysedit_close, SDLK_x );
209 i = 1;
210
211 /* Autosave toggle. */
212 window_addCheckbox( wid, -150, 25, SCREEN_W/2 - 150, 20,
213 "chkEditAutoSave", _("Automatically save changes"), uniedit_autosave, conf.devautosave );
214
215 /* Scale. */
216 window_addButton( wid, -15, 20+(BUTTON_HEIGHT+20)*i, BUTTON_WIDTH, BUTTON_HEIGHT,
217 "btnScale", _("Scale"), sysedit_btnScale );
218 i += 1;
219
220 /* Reset. */
221 window_addButtonKey( wid, -15, 20+(BUTTON_HEIGHT+20)*i, BUTTON_WIDTH, BUTTON_HEIGHT,
222 "btnReset", _("Reset Jumps"), sysedit_btnReset, SDLK_r );
223 i += 1;
224
225 /* Editing. */
226 window_addButtonKey( wid, -15, 20+(BUTTON_HEIGHT+20)*i, BUTTON_WIDTH, BUTTON_HEIGHT,
227 "btnEdit", _("Edit"), sysedit_btnEdit, SDLK_e );
228 i += 1;
229
230 /* Remove. */
231 window_addButton( wid, -15, 20+(BUTTON_HEIGHT+20)*i, BUTTON_WIDTH, BUTTON_HEIGHT,
232 "btnRemove", _("Remove"), sysedit_btnRemove );
233 i += 1;
234
235 /* Rename. */
236 window_addButton( wid, -15, 20+(BUTTON_HEIGHT+20)*i, BUTTON_WIDTH, BUTTON_HEIGHT,
237 "btnRename", _("Rename"), sysedit_btnRename );
238 i += 1;
239
240 /* New spob. */
241 window_addButtonKey( wid, -15, 20+(BUTTON_HEIGHT+20)*i, BUTTON_WIDTH, BUTTON_HEIGHT,
242 "btnNewSpob", _("New Spob"), sysedit_btnNewSpob, SDLK_n );
243 i += 1;
244
245 /* New asteroids. */
246 window_addButtonKey( wid, -15, 20+(BUTTON_HEIGHT+20)*i, BUTTON_WIDTH, BUTTON_HEIGHT,
247 "btnNewAsteroids", _("New Asteroids"), sysedit_btnNewAsteroids, SDLK_a );
248 i += 1;
249
250 /* Toggle Grid. */
251 window_addButtonKey( wid, -15, 20+(BUTTON_HEIGHT+20)*i, BUTTON_WIDTH, BUTTON_HEIGHT,
252 "btnGrid", _("Grid"), sysedit_btnGrid, SDLK_g );
253
254 /* Zoom buttons */
255 window_addButton( wid, 40, 20, 30, 30, "btnZoomIn", "+", sysedit_buttonZoom );
256 window_addButton( wid, 80, 20, 30, 30, "btnZoomOut", "-", sysedit_buttonZoom );
257
258 /* Selected text. */
259 snprintf( buf, sizeof(buf), _("Radius: %.0f"), sys->radius );
260 window_addText( wid, 140, 10, SCREEN_W/2-140, 30, 0,
261 "txtSelected", &gl_smallFont, NULL, buf );
262
263 /* Deselect everything. */
265}
266
270static int sysedit_keys( unsigned int wid, SDL_Keycode key, SDL_Keymod mod )
271{
272 (void) wid;
273 (void) mod;
274
275 switch (key) {
276
277 default:
278 return 0;
279 }
280}
281
285static void sysedit_close( unsigned int wid, const char *wgt )
286{
287 /* Unload graphics. */
289
290 /* Remove selection. */
292
293 /* Set the dominant faction. */
295
296 /* Update asteroid info. */
298
299 /* Save the system */
300 if (conf.devautosave)
302
303 /* Reconstruct universe presences. */
306
307 /* Close the window. */
308 window_close( wid, wgt );
309
310 /* Update the universe editor's sidebar text. */
312
313 /* Propagate autosave checkbox state */
314 uniedit_updateAutosave();
315
316 /* Unset. */
317 sysedit_wid = 0;
318}
319
323static void sysedit_editPntClose( unsigned int wid, const char *unused )
324{
325 (void) unused;
326 const char *inp;
327 Spob *p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
328
329 p->population = (uint64_t)strtoull( window_getInput( sysedit_widEdit, "inpPop" ), 0, 10);
330
331 inp = window_getInput( sysedit_widEdit, "inpClass" );
332 free( p->class );
333
334 if (inp[0] == '\0')
335 p->class = NULL;
336 else
337 p->class = strdup( inp );
338
339 inp = window_getInput( sysedit_widEdit, "inpLua" );
340 free( p->lua_file );
341
342 if ((inp == NULL) || (strlen(inp) == 0))
343 p->lua_file = NULL;
344 else
345 p->lua_file = strdup( inp );
346
347 p->presence.base = atof(window_getInput( sysedit_widEdit, "inpPresenceBase" ));
348 p->presence.bonus = atof(window_getInput( sysedit_widEdit, "inpPresenceBonus" ));
349 p->presence.range = atoi(window_getInput( sysedit_widEdit, "inpPresenceRange" ));
350 p->hide = atof(window_getInput( sysedit_widEdit, "inpHide" ));
351
352 /* Have to recompute presences if stuff changed. */
354
355 if (conf.devautosave)
356 dpl_saveSpob( p );
357
358 /* Clean up presences. */
361
362 window_close( wid, unused );
363}
364
368static void sysedit_btnNewSpob( unsigned int wid_unused, const char *unused )
369{
370 (void) wid_unused;
371 (void) unused;
372 Spob *p, *b;
373 char *name;
374
375 /* Get new name. */
376 name = dialogue_inputRaw( _("New Spob Creation"), 1, 32, _("What do you want to name the new spob?") );
377 if (name == NULL)
378 return;
379
380 /* Check for collision. */
381 if (spob_exists( name )) {
382 dialogue_alert( _("Spob by the name of #r'%s'#0 already exists in the #r'%s'#0 system"),
383 name, spob_getSystem( name ) );
384 free(name);
385 sysedit_btnNewSpob( 0, NULL );
386 return;
387 }
388
389 /* Create the new spob. */
390 p = spob_new();
391 p->name = name;
392
393 /* Base spob data off another. */
394 b = spob_get( space_getRndSpob(0, 0, NULL) );
395 p->class = strdup( b->class );
396 p->gfx_spacePath = strdup( b->gfx_spacePath );
397 p->gfx_spaceName = strdup( b->gfx_spaceName );
398 p->gfx_exterior = strdup( b->gfx_exterior );
399 p->gfx_exteriorPath = strdup( b->gfx_exteriorPath );
400 p->pos.x = sysedit_xpos / sysedit_zoom;
401 p->pos.y = sysedit_ypos / sysedit_zoom;
402 p->hide = HIDE_DEFAULT_SPOB;
403 p->radius = b->radius;
404
405 /* Add new spob. */
407
408 /* Update economy due to galaxy modification. */
410
411 if (conf.devautosave)
412 dpl_saveSpob( p );
413
414 /* Reload graphics. */
416}
417
418
422static void sysedit_btnNewAsteroids( unsigned int wid_unused, const char *unused )
423{
424 (void) wid_unused;
425 (void) unused;
426 const char *title, *caption, *ret;
427 const char *opts[] = {
428 _("Asteroid Field"),
429 _("Exclusion Zone"),
430 };
431
432 /* See if we want to make a field or exclusion zone. */
433 title = _("Add asteriod field or exclusion zone?");
434 caption = _("Do you wish to add an asteroid field or an asteroid exclusion zone that will remove all asteroids that will appear in it?");
435 dialogue_makeChoice( title, caption, 2 );
436 dialogue_addChoice( title, caption, opts[0] );
437 dialogue_addChoice( title, caption, opts[1] );
438 ret = dialogue_runChoice();
439 if (ret==NULL)
440 ret = opts[0];
441
442 if (strcmp(ret, opts[0])==0) {
443 AsteroidAnchor *ast = &array_grow( &sysedit_sys->asteroids );
444 memset( ast, 0, sizeof(AsteroidAnchor) );
445 ast->density = ASTEROID_DEFAULT_DENSITY;
447 ast->groupsw = array_create( double );
448 ast->radius = 2500.;
449 ast->maxspeed = ASTEROID_DEFAULT_MAXSPEED;
450 ast->thrust = ASTEROID_DEFAULT_THRUST;
454 }
455 else {
456 AsteroidExclusion *exc = &array_grow( &sysedit_sys->astexclude );
457 memset( exc, 0, sizeof(AsteroidExclusion) );
458 exc->radius = 1000.;
461 }
462
463 if (conf.devautosave)
465}
466
467static void sysedit_btnRename( unsigned int wid_unused, const char *unused )
468{
469 (void) wid_unused;
470 (void) unused;
471 for (int i=0; i<sysedit_nselect; i++) {
472 Select_t *sel = &sysedit_select[i];
473 if (sel->type == SELECT_SPOB) {
474 char *name, *oldName, *newName, *filtered;
475 Spob *p = sysedit_sys[i].spobs[ sel->u.spob ];
476
477 /* Get new name. */
478 name = dialogue_input( _("New Spob Creation"), 1, 32,
479 _("What do you want to rename the spob #r%s#0?"), p->name );
480 if (name == NULL)
481 continue;
482
483 /* Check for collision. */
484 if (spob_exists( name )) {
485 dialogue_alert( _("Spob by the name of #r'%s'#0 already exists in the #r'%s'#0 system"),
486 name, spob_getSystem( name ) );
487 free(name);
488 continue;
489 }
490
491 /* Rename. */
492 filtered = uniedit_nameFilter(p->name);
493 asprintf(&oldName, "dat/spob/%s.xml", filtered);
494 free(filtered);
495
496 filtered = uniedit_nameFilter(name);
497 asprintf(&newName, "dat/spob/%s.xml", filtered);
498 free(filtered);
499
500 rename(oldName, newName);
501
502 free(oldName);
503 free(newName);
504 free(p->name);
505
506 p->name = name;
507 window_modifyText( sysedit_widEdit, "txtName", p->name );
508 dpl_saveSpob( p );
509 }
510 }
511}
512
516static void sysedit_btnRemove( unsigned int wid_unused, const char *unused )
517{
518 (void) wid_unused;
519 (void) unused;
520 char *file, *filtered;
521
522 if (dialogue_YesNo( _("Remove selected objects (excluding jumps)?"), _("This can not be undone.") )) {
523 for (int i=0; i<sysedit_nselect; i++) {
524 Select_t *sel = &sysedit_select[i];
525 if (sel->type == SELECT_SPOB) {
526 Spob *sp = sysedit_sys->spobs[ sel->u.spob ];
527 filtered = uniedit_nameFilter( sp->name );
528 asprintf(&file, "dat/spob/%s.xml", filtered);
529 remove(file);
530
531 free(filtered);
532 free(file);
533
535 }
536 else if (sel->type == SELECT_ASTEROID) {
537 AsteroidAnchor *ast = &sysedit_sys->asteroids[ sel->u.asteroid ];
538 asteroid_free( ast );
539 array_erase( &sysedit_sys->asteroids, ast, ast+1 );
540 }
541 else if (sel->type == SELECT_ASTEXCLUDE ){
542 AsteroidExclusion *exc = &sysedit_sys->astexclude[ sel->u.astexclude ];
543
544 array_erase( &sysedit_sys->astexclude, exc, exc+1 );
545 }
546 }
547
548 /* Update economy due to galaxy modification. */
550 }
551}
552
556static void sysedit_btnReset( unsigned int wid_unused, const char *unused )
557{
558 (void) wid_unused;
559 (void) unused;
560 for (int i=0; i<sysedit_nselect; i++) {
561 Select_t *sel = &sysedit_select[i];
562 if (sel->type == SELECT_JUMPPOINT)
563 sysedit_sys[i].jumps[ sel->u.jump ].flags |= JP_AUTOPOS;
564 }
565
566 /* Must reconstruct jumps. */
568}
569
573static void sysedit_btnScale( unsigned int wid_unused, const char *unused )
574{
575 (void) wid_unused;
576 (void) unused;
577 char *str;
578 double s;
579 StarSystem *sys;
580
581 /* Prompt scale amount. */
582 str = dialogue_inputRaw( _("Scale Star System"), 1, 32, _("By how much do you want to scale the star system?") );
583 if (str == NULL)
584 return;
585
586 sys = sysedit_sys; /* Comfort. */
587 s = atof(str);
588 free(str);
589
590 /* In case screwed up. */
591 if ((s < 0.1) || (s > 10.)) {
592 int i = dialogue_YesNo( _("Scale Star System"), _("Are you sure you want to scale the star system by %.2f (from %.2f to %.2f)?"),
593 s, sys->radius, sys->radius*s );
594 if (i==0)
595 return;
596 }
597
598 sysedit_sysScale(sys, s);
599}
600
604void sysedit_sysScale( StarSystem *sys, double factor )
605{
606 char buf[STRMAX];
607
608 /* Scale radius. */
609 sys->radius *= factor;
610 snprintf( buf, sizeof(buf), _("Radius: %.0f"), sys->radius );
611 if (sysedit_wid > 0)
612 window_modifyText( sysedit_wid, "txtSelected", buf );
613
614 /* Scale spobs. */
615 for (int i=0; i<array_size(sys->spobs); i++) {
616 Spob *p = sys->spobs[i];
617 vec2_cset( &p->pos, p->pos.x*factor, p->pos.y*factor );
618 }
619
620 /* Scale jumps. */
621 for (int i=0; i<array_size(sys->jumps); i++) {
622 JumpPoint *jp = &sys->jumps[i];
623 vec2_cset( &jp->pos, jp->pos.x*factor, jp->pos.y*factor );
624 }
625
626 /* Scale asteroids. */
627 for (int i=0; i<array_size(sys->asteroids); i++) {
628 AsteroidAnchor *ast = &sys->asteroids[i];
629 vec2_cset( &ast->pos, ast->pos.x*factor, ast->pos.y*factor );
630 ast->radius *= factor;
631 }
632 for (int i=0; i<array_size(sys->astexclude); i++) {
633 AsteroidExclusion *exc = &sys->astexclude[i];
634 vec2_cset( &exc->pos, exc->pos.x*factor, exc->pos.y*factor );
635 exc->radius *= factor;
636 }
637
638 /* Must reconstruct jumps. */
640}
641
645static void sysedit_btnGrid( unsigned int wid_unused, const char *unused )
646{
647 (void) wid_unused;
648 (void) unused;
649
651}
652
656static void sysedit_render( double bx, double by, double w, double h, void *data )
657{
658 (void) data;
659 StarSystem *sys;
660 double x,y, z;
661
662 /* Comfort++. */
663 sys = sysedit_sys;
664 z = sysedit_zoom;
665
666 /* Coordinate translation. */
667 x = bx - sysedit_xpos + w/2;
668 y = by - sysedit_ypos + h/2;
669
670 /* First render background with lines. */
671 sysedit_renderBG( bx, by, w, h, x, y );
672
673 /* Render spobs. */
674 for (int i=0; i<array_size(sys->spobs); i++) {
675 Spob *p = sys->spobs[i];
676 const Select_t sel = {
677 .type = SELECT_SPOB,
678 .u.spob = i,
679 };
680 int selected = sysedit_isSelected( &sel );
681 sysedit_renderSprite( p->gfx_space, x, y, p->pos.x, p->pos.y, 0, 0, NULL, selected, p->name );
682 }
683
684 /* Render jump points. */
685 for (int i=0; i<array_size(sys->jumps); i++) {
686 const glColour *c;
687 JumpPoint *jp = &sys->jumps[i];
688 const Select_t sel = {
690 .u.jump = i,
691 };
692 int selected = sysedit_isSelected( &sel );
693
694 /* Choose colour. */
695 c = (jp->flags & JP_AUTOPOS) ? &cGreen : NULL;
696
697 /* Render. */
698 sysedit_renderSprite( jumppoint_gfx, x, y, jp->pos.x, jp->pos.y,
699 jp->sx, jp->sy, c, selected, jp->target->name );
700 }
701
702 /* Render asteroids */
703 for (int i=0; i<array_size(sys->asteroids); i++) {
704 AsteroidAnchor *ast = &sys->asteroids[i];
705 const Select_t sel = {
707 .u.asteroid = i,
708 };
709 int selected = sysedit_isSelected( &sel );
710 sysedit_renderAsteroidsField( x, y, ast, selected );
711 }
712
713 /* Render asteroid exclusions */
714 for (int i=0; i<array_size(sys->astexclude); i++) {
715 AsteroidExclusion *aexcl = &sys->astexclude[i];
716 const Select_t sel = {
718 .u.astexclude = i,
719 };
720 int selected = sysedit_isSelected( &sel );
721 sysedit_renderAsteroidExclusion( x, y, aexcl, selected );
722 }
723
724 /* Render safe lanes. */
725 SafeLane* safelanes = safelanes_get( -1, 0, sys );
726 for (int i=0; i<array_size(safelanes); i++) {
727 vec2 *posns[2];
728 Spob *pnt;
729 JumpPoint *njp;
730 glColour col;
731 SafeLane *sf = &safelanes[i];
732
733 for (int j=0; j<2; j++) {
734 switch(sf->point_type[j]) {
735 case SAFELANE_LOC_SPOB:
736 pnt = spob_getIndex( sf->point_id[j] );
737 posns[j] = &pnt->pos;
738 break;
739 case SAFELANE_LOC_DEST_SYS:
740 njp = jump_getTarget( system_getIndex( sf->point_id[j] ), sys );
741 posns[j] = &njp->pos;
742 break;
743 default:
744 ERR( _("Invalid vertex type.") );
745 }
746 }
747
748 col = *faction_colour( sf->faction );
749 col.a = 0.3;
750
751 /* Get positions and stuff. */
752 double x1, y1, x2, y2, ry, rx, r, rw, rh;
753 x1 = x + posns[0]->x * z;
754 y1 = y + posns[0]->y * z;
755 x2 = x + posns[1]->x * z;
756 y2 = y + posns[1]->y * z;
757 rx = x2-x1;
758 ry = y2-y1;
759 r = atan2( ry, rx );
760 rw = MOD(rx,ry)/2.;
761 rh = 9.;
762
763 /* Render. */
764 glUseProgram(shaders.safelane.program);
765 gl_renderShader( (x1+x2)/2., (y1+y2)/2., rw, rh, r, &shaders.safelane, &col, 1 );
766 }
767 array_free( safelanes );
768
769 /* Render cursor position. */
770 gl_print( &gl_defFontMono, bx + 5., by + 65.,
771 &cWhite, "% 9.2f x % 9.2f",
772 (bx + sysedit_mx - x)/z,
773 (by + sysedit_my - y)/z );
774}
775
780static void sysedit_renderAsteroidsField( double bx, double by, const AsteroidAnchor *ast, int selected )
781{
782 double tx, ty, z;
783
784 /* Inits. */
785 z = sysedit_zoom;
786
787 /* Translate asteroid field center's coords. */
788 tx = bx + ast->pos.x*z;
789 ty = by + ast->pos.y*z;
790
791 if (selected) {
792 const glColour csel = COL_ALPHA( cFontBlue, 0.5 );
793 gl_renderCircle( tx, ty, ast->radius * sysedit_zoom, &csel, 1 );
794 }
795
796 gl_renderCircle( tx, ty, ast->radius * sysedit_zoom, &cOrange, 0 );
798 tx - 100, ty - gl_smallFont.h/2.,
799 (selected) ? &cRed : NULL, -1., _("Asteroid Field") );
800}
801
806static void sysedit_renderAsteroidExclusion( double bx, double by, const AsteroidExclusion *aexcl, int selected )
807{
808 double tx, ty, z, r, rr;
809 const glColour *col;
810
811 /* Inits. */
812 z = sysedit_zoom;
813
814 /* Translate asteroid field center's coords. */
815 tx = bx + aexcl->pos.x*z;
816 ty = by + aexcl->pos.y*z;
817 r = aexcl->radius * sysedit_zoom;
818 rr = r * sin(M_PI / 4.);
819
820 if (selected) {
821 const glColour csel = COL_ALPHA( cFontBlue, 0.5 );
822 gl_renderCircle( tx, ty, aexcl->radius * sysedit_zoom, &csel, 1 );
823 }
824
825 col = (selected) ? &cWhite : &cRed;
826
827 gl_renderCircle( tx, ty, r, col, 0 );
828 gl_renderCross( tx, ty, r, col );
829 gl_renderRectEmpty( tx - rr, ty - rr, rr * 2, rr * 2, col );
830}
831
835static void sysedit_renderBG( double bx, double by, double w, double h, double x, double y )
836{
837 /* Comfort. */
838 const double z = sysedit_zoom;
839 const double s = 1000.;
840
841 /* Vars */
842 double startx, starty, spacing;
843 int nx, ny;
844
845 /* Render blackness. */
846 gl_renderRect( bx, by, w, h, &cBlack );
847
848 /* Must have grid activated. */
849 if (!sysedit_grid)
850 return;
851
852 /* Draw lines that go through 0,0 */
853 gl_renderRect( x - 1., by, 3., h, &cLightBlue );
854 gl_renderRect( bx, y - 1., w, 3., &cLightBlue );
855
856 /* Render lines. */
857 spacing = s * z;
858 startx = bx + fmod( x - bx, spacing );
859 starty = by + fmod( y - by, spacing );
860
861 nx = lround( w / spacing );
862 ny = lround( h / spacing );
863
864 /* Vertical. */
865 for (int i=0; i<nx; i++) {
866 double d = startx + (i * spacing);
867 gl_renderLine( d, by, d, by + h, &cBlue );
868 }
869 /* Horizontal. */
870 for (int i=0; i<ny; i++) {
871 double d = starty + (i * spacing);
872 gl_renderLine( bx, d, bx + w, d, &cBlue );
873 }
874
875 gl_renderCircle( x, y, sysedit_sys->radius * z, &cLightBlue, 0 );
876}
877
881static void sysedit_renderSprite( glTexture *gfx, double bx, double by, double x, double y,
882 int sx, int sy, const glColour *c, int selected, const char *caption )
883{
884 double tx, ty, z;
885 const glColour *col;
886
887 /* Comfort. */
888 z = sysedit_zoom;
889
890 /* Selection graphic. */
891 if (selected) {
892 const glColour csel = COL_ALPHA( cFontBlue, 0.5 );
893 gl_renderCircle( bx + x*z, by + y*z, gfx->sw*z*1.1, &csel, 1 );
894 }
895
896 /* Translate coords. */
897 tx = bx + (x - gfx->sw/2.)*z;
898 ty = by + (y - gfx->sh/2.)*z;
899 /* Blit the spob. */
900 gl_renderScaleSprite( gfx, tx, ty, sx, sy, gfx->sw*z, gfx->sh*z, c );
901
902 /* Display caption. */
903 if (caption != NULL) {
904 if (selected)
905 col = &cRed;
906 else
907 col = c;
908 gl_printMidRaw( &gl_smallFont, gfx->sw*z+100,
909 tx - 50, ty - gl_smallFont.h - 5, col, -1., caption );
910 }
911}
912
916static void sysedit_focusLose( unsigned int wid, const char* wgtname )
917{
918 (void) wid;
919 (void) wgtname;
921}
922
923static int sysedit_mouseTrySelect( const Select_t *sel, double x, double y, double t, double mx, double my, SDL_Keymod mod, void (*func)(void) )
924{
925 x *= sysedit_zoom;
926 y *= sysedit_zoom;
927
928 if ((pow2(mx-x)+pow2(my-y)) > t)
929 return 0;
930
931 /* Check if already selected. */
932 for (int j=0; j<sysedit_nselect; j++) {
933 if (!sysedit_selectCmp( sel, &sysedit_select[j] ))
934 continue;
935
936 sysedit_dragSel = 1;
937 sysedit_tsel = *sel;
938
939 /* Check modifier. */
940 if (mod & (KMOD_LCTRL | KMOD_RCTRL))
941 sysedit_tadd = 0;
942 else {
943 /* Detect double click to open spob editor. */
944 if ((SDL_GetTicks() - sysedit_dragTime < SYSEDIT_DRAG_THRESHOLD*2)
946 if (func != NULL)
947 func();
948 sysedit_dragSel = 0;
949 return 1;
950 }
951 sysedit_tadd = -1;
952 }
953 sysedit_dragTime = SDL_GetTicks();
954 sysedit_moved = 0;
955 return 1;
956 }
957
958 /* Add the system if not selected. */
959 if (mod & (KMOD_LCTRL | KMOD_RCTRL))
960 sysedit_selectAdd( sel );
961 else {
963 sysedit_selectAdd( sel );
964 }
966
967 /* Start dragging anyway. */
968 sysedit_dragSel = 1;
969 sysedit_dragTime = SDL_GetTicks();
970 sysedit_moved = 0;
971 return 1;
972}
973
977static int sysedit_mouse( unsigned int wid, SDL_Event* event, double mx, double my,
978 double w, double h, double xr, double yr, void *data )
979{
980 (void) data;
981 StarSystem *sys = sysedit_sys;
982 SDL_Keymod mod = SDL_GetModState();
983
984 switch (event->type) {
985
986 case SDL_MOUSEWHEEL:
987 /* Must be in bounds. */
988 if ((mx < 0.) || (mx > w) || (my < 0.) || (my > h))
989 return 0;
990
991 if (event->wheel.y > 0)
992 sysedit_buttonZoom( 0, "btnZoomIn" );
993 else if (event->wheel.y < 0)
994 sysedit_buttonZoom( 0, "btnZoomOut" );
995
996 return 1;
997
998 case SDL_MOUSEBUTTONDOWN:
999 /* Must be in bounds. */
1000 if ((mx < 0.) || (mx > w) || (my < 0.) || (my > h))
1001 return 0;
1002 window_setFocus( wid, "cstSysEdit" );
1003
1004 /* selecting star system */
1005 mx -= w/2 - sysedit_xpos;
1006 my -= h/2 - sysedit_ypos;
1007
1008 /* Check spobs. */
1009 for (int i=0; i<array_size(sys->spobs); i++) {
1010 Spob *p = sys->spobs[i];
1011 const Select_t sel = {
1012 .type = SELECT_SPOB,
1013 .u.spob = i,
1014 };
1015
1016 /* Threshold. */
1017 double t = p->gfx_space->sw * p->gfx_space->sh / 4.; /* Radius^2 */
1018 t *= pow2(2.*sysedit_zoom);
1019
1020 /* Try to select. */
1021 if (sysedit_mouseTrySelect( &sel, p->pos.x, p->pos.y, t, mx, my, mod, sysedit_editPnt ))
1022 return 1;
1023 }
1024
1025 /* Check jump points. */
1026 for (int i=0; i<array_size(sys->jumps); i++) {
1027 JumpPoint *jp = &sys->jumps[i];
1028 const Select_t sel = {
1030 .u.jump = i,
1031 };
1032
1033 /* Threshold. */
1034 double t = jumppoint_gfx->sw * jumppoint_gfx->sh / 4.; /* Radius^2 */
1035 t *= pow2(2.*sysedit_zoom);
1036
1037 /* Try to select. */
1038 if (sysedit_mouseTrySelect( &sel, jp->pos.x, jp->pos.y, t, mx, my, mod, sysedit_editJump ))
1039 return 1;
1040 }
1041
1042 /* Check asteroids exclusions. */
1043 for (int i=0; i<array_size(sys->astexclude); i++) {
1044 AsteroidExclusion *exc = &sys->astexclude[i];
1045 const Select_t sel = {
1047 .u.astexclude = i,
1048 };
1049 double t = pow2(exc->radius*sysedit_zoom);
1050
1051 /* Try to select. */
1052 if (sysedit_mouseTrySelect( &sel, exc->pos.x, exc->pos.y, t, mx, my, mod, sysedit_editExclusion ))
1053 return 1;
1054 }
1055
1056 /* Check asteroids. */
1057 for (int i=0; i<array_size(sys->asteroids); i++) {
1058 AsteroidAnchor *ast = &sys->asteroids[i];
1059 const Select_t sel = {
1061 .u.asteroid = i,
1062 };
1063 double t = pow2(ast->radius*sysedit_zoom);
1064
1065 /* Try to select. */
1066 if (sysedit_mouseTrySelect( &sel, ast->pos.x, ast->pos.y, t, mx, my, mod, sysedit_editAsteroids ))
1067 return 1;
1068 }
1069
1070 /* Start dragging. */
1071 if (!(mod & (KMOD_LCTRL | KMOD_RCTRL))) {
1072 sysedit_drag = 1;
1073 sysedit_dragTime = SDL_GetTicks();
1074 sysedit_moved = 0;
1076 }
1077 return 1;
1078
1079 case SDL_MOUSEBUTTONUP:
1080 if (sysedit_drag) {
1084 else
1086 }
1087 sysedit_drag = 0;
1088
1089 if (conf.devautosave)
1090 for (int i=0; i<sysedit_nselect; i++)
1091 dpl_saveSpob(sysedit_sys->spobs[ sysedit_select[i].u.spob ]);
1092 }
1093 if (sysedit_dragSel) {
1094 if ((SDL_GetTicks() - sysedit_dragTime < SYSEDIT_DRAG_THRESHOLD) &&
1096 if (sysedit_tadd == 0)
1098 else {
1101 }
1102 }
1103 sysedit_dragSel = 0;
1104
1105 /* Save all spobs in our selection - their positions might have changed. */
1106 if (conf.devautosave)
1107 for (int i=0; i<sysedit_nselect; i++)
1108 if (sysedit_select[i].type == SELECT_SPOB)
1109 dpl_saveSpob( sys->spobs[ sysedit_select[i].u.spob ] );
1110 }
1111 break;
1112
1113 case SDL_MOUSEMOTION:
1114 /* Update mouse positions. */
1115 sysedit_mx = mx;
1116 sysedit_my = my;
1117
1118 /* Handle dragging. */
1119 if (sysedit_drag) {
1120 /* axis is inverted */
1121 sysedit_xpos -= xr;
1122 sysedit_ypos += yr;
1123
1124 /* Update mouse movement. */
1125 sysedit_moved += ABS(xr) + ABS(yr);
1126 }
1127 /* Dragging selection around. */
1128 else if (sysedit_dragSel && (sysedit_nselect > 0)) {
1130 double xmove = xr / sysedit_zoom;
1131 double ymove = -yr / sysedit_zoom;
1132 for (int i=0; i<sysedit_nselect; i++) {
1133 Spob *p;
1134 JumpPoint *jp;
1135 AsteroidAnchor *ast;
1136 AsteroidExclusion *exc;
1137 Select_t *sel = &sysedit_select[i];
1138
1139 switch (sel->type) {
1140 case SELECT_SPOB:
1141 p = sys->spobs[ sel->u.spob ];
1142 p->pos.x += xmove;
1143 p->pos.y += ymove;
1144 break;
1145
1146 case SELECT_JUMPPOINT:
1147 jp = &sys->jumps[ sel->u.jump ];
1148 jp->flags &= ~(JP_AUTOPOS);
1149 jp->pos.x += xmove;
1150 jp->pos.y += ymove;
1151 break;
1152
1153 case SELECT_ASTEROID:
1154 ast = &sys->asteroids[ sel->u.asteroid ];
1155 ast->pos.x += xmove;
1156 ast->pos.y += ymove;
1157 break;
1158
1159 case SELECT_ASTEXCLUDE:
1160 exc = &sys->astexclude[ sel->u.astexclude ];
1161 exc->pos.x += xmove;
1162 exc->pos.y += ymove;
1163 break;
1164 }
1165 }
1166 }
1167
1168 /* Update mouse movement. */
1169 sysedit_moved += ABS(xr) + ABS(yr);
1170 }
1171 break;
1172 }
1173
1174 return 0;
1175}
1176
1183static void sysedit_buttonZoom( unsigned int wid, const char* str )
1184{
1185 (void) wid;
1186
1187 /* Transform coords to normal. */
1190
1191 /* Apply zoom. */
1192 if (strcmp(str,"btnZoomIn")==0) {
1195 }
1196 else if (strcmp(str,"btnZoomOut")==0) {
1199 }
1200
1201 /* Transform coords back. */
1204}
1205
1209static void sysedit_deselect (void)
1210{
1211 if (sysedit_nselect > 0)
1212 free( sysedit_select );
1213 sysedit_select = NULL;
1214 sysedit_nselect = 0;
1215 sysedit_mselect = 0;
1216
1217 /* Button check. */
1219}
1220
1224static void sysedit_checkButtons (void)
1225{
1226 int sel_spob, sel_jump, sel_asteroid, sel_exclusion;
1227
1228 /* See if a spob or jump is selected. */
1229 sel_spob = 0;
1230 sel_jump = 0;
1231 sel_asteroid = 0;
1232 sel_exclusion = 0;
1233 for (int i=0; i<sysedit_nselect; i++) {
1234 Select_t *sel = &sysedit_select[i];
1235 switch (sel->type) {
1236 case SELECT_SPOB:
1237 sel_spob++;
1238 break;
1239 case SELECT_JUMPPOINT:
1240 sel_spob++;
1241 break;
1242 case SELECT_ASTEROID:
1243 sel_asteroid++;
1244 break;
1245 case SELECT_ASTEXCLUDE:
1246 sel_exclusion++;
1247 break;
1248 }
1249 }
1250
1251 /* Spob dependent. */
1252 if (sel_spob || sel_asteroid || sel_exclusion)
1253 window_enableButton( sysedit_wid, "btnRemove" );
1254 else
1255 window_disableButton( sysedit_wid, "btnRemove" );
1256 if (sel_spob && (sysedit_nselect==1))
1257 window_enableButton( sysedit_wid, "btnRename" );
1258 else
1259 window_disableButton( sysedit_wid, "btnRename" );
1260
1261 /* Jump dependent. */
1262 if (sel_jump)
1263 window_enableButton( sysedit_wid, "btnReset" );
1264 else
1265 window_disableButton( sysedit_wid, "btnReset" );
1266
1267 /* Editor - just one spob. */
1268 if (sysedit_nselect==1)
1269 window_enableButton( sysedit_wid, "btnEdit" );
1270 else
1271 window_disableButton( sysedit_wid, "btnEdit" );
1272}
1273
1277static void sysedit_selectAdd( const Select_t *sel )
1278{
1279 /* Allocate if needed. */
1281 if (sysedit_mselect == 0)
1282 sysedit_mselect = 1;
1283 sysedit_mselect *= 2;
1284 sysedit_select = realloc( sysedit_select,
1285 sizeof(Select_t) * sysedit_mselect );
1286 }
1287
1288 /* Add system. */
1291
1292 /* Button check. */
1294}
1295
1299static void sysedit_selectRm( Select_t *sel )
1300{
1301 for (int i=0; i<sysedit_nselect; i++) {
1302 if (sysedit_selectCmp( &sysedit_select[i], sel )) {
1304 memmove( &sysedit_select[i], &sysedit_select[i+1],
1305 sizeof(Select_t) * (sysedit_nselect - i) );
1306 /* Button check. */
1308 return;
1309 }
1310 }
1311 WARN(_("Trying to deselect item that is not in selection!"));
1312}
1313
1319static int sysedit_selectCmp( const Select_t *a, const Select_t *b )
1320{
1321 return (memcmp(a, b, sizeof(Select_t)) == 0);
1322}
1323
1327static int sysedit_isSelected( const Select_t *sel )
1328{
1329 for (int i=0; i<sysedit_nselect; i++)
1330 if (sysedit_selectCmp( sel, &sysedit_select[i] ))
1331 return 1;
1332 return 0;
1333}
1334
1338static void sysedit_editPnt (void)
1339{
1340 unsigned int wid;
1341 int x, y, w, l, bw;
1342 char buf[STRMAX_SHORT], title[128];
1343 const char *s;
1344 Spob *p;
1345
1346 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
1347
1348 /* Create the window. */
1349 snprintf(title, sizeof(title), _("Spob Property Editor - %s"), p->name);
1350 wid = window_create( "wdwSysEditPnt", title, -1, -1, SYSEDIT_EDIT_WIDTH, SYSEDIT_EDIT_HEIGHT );
1351 sysedit_widEdit = wid;
1352
1354
1355 bw = (SYSEDIT_EDIT_WIDTH - 40 - 15 * 3) / 4.;
1356
1357 /* Rename button. */
1358 y = -40;
1359 snprintf( buf, sizeof(buf), "%s ", _("Name:") );
1360 w = gl_printWidthRaw( NULL, buf );
1361 window_addText( wid, 20, y, 180, 15, 0, "txtNameLabel", &gl_smallFont, NULL, buf );
1362 snprintf( buf, sizeof(buf), "%s", p->name );
1363 window_addText( wid, 20 + w, y, 180, 15, 0, "txtName", &gl_smallFont, NULL, buf );
1364 window_addButton( wid, -20, y - gl_defFont.h/2. + BUTTON_HEIGHT/2., bw, BUTTON_HEIGHT, "btnRename",
1365 _("Rename"), sysedit_btnRename );
1366 window_addButton( wid, -20 - 15 - bw, y - gl_defFont.h/2. + BUTTON_HEIGHT/2., bw, BUTTON_HEIGHT, "btnFaction",
1367 _("Faction"), sysedit_btnFaction );
1368
1369 y -= gl_defFont.h + 5;
1370
1371 snprintf( buf, sizeof(buf), "%s ", _("Faction:") );
1372 w = gl_printWidthRaw( NULL, buf );
1373 window_addText( wid, 20, y, 180, 15, 0, "txtFactionLabel", &gl_smallFont, NULL, buf );
1374 snprintf( buf, sizeof(buf), "%s", p->presence.faction >= 0 ? faction_name( p->presence.faction ) : _("None") );
1375 window_addText( wid, 20 + w, y, 180, 15, 0, "txtFaction", &gl_smallFont, NULL, buf );
1376 y -= gl_defFont.h + 5;
1377
1378 /* Input widgets and labels. */
1379 x = 20;
1380 s = _("Population");
1381 l = gl_printWidthRaw( NULL, s );
1382 window_addText( wid, x, y, l, 20, 1, "txtPop",
1383 NULL, NULL, s );
1384 window_addInput( wid, x += l + 5, y, 80, 20, "inpPop", 12, 1, NULL );
1385 window_setInputFilter( wid, "inpPop", INPUT_FILTER_NUMBER );
1386 x += 80 + 10;
1387
1388 s = _("Class");
1389 l = gl_printWidthRaw( NULL, s );
1390 window_addText( wid, x, y, l, 20, 1, "txtClass",
1391 NULL, NULL, s );
1392 window_addInput( wid, x += l + 5, y, 30, 20, "inpClass", 1, 1, NULL );
1393 x += 30 + 10;
1394
1395 s = _("Lua");
1396 l = gl_printWidthRaw( NULL, s );
1397 window_addText( wid, x, y, l, 20, 1, "txtLua",
1398 NULL, NULL, s );
1399 window_addInput( wid, x += l + 5, y, 150, 20, "inpLua", 20, 1, NULL );
1400 y -= gl_defFont.h + 15;
1401
1402 /* Second row. */
1403 x = 20;
1404 s = _("Base Presence");
1405 l = gl_printWidthRaw( NULL, s );
1406 window_addText( wid, x, y, l, 20, 1, "txtPresenceBase",
1407 NULL, NULL, s );
1408 window_addInput( wid, x += l + 5, y, 50, 20, "inpPresenceBase", 5, 1, NULL );
1409 window_setInputFilter( wid, "inpPresenceBase", INPUT_FILTER_NUMBER );
1410 x += 50 + 10;
1411
1412 s = _("Bonus Presence");
1413 l = gl_printWidthRaw( NULL, s );
1414 window_addText( wid, x, y, l, 20, 1, "txtPresenceBonus",
1415 NULL, NULL, s );
1416 window_addInput( wid, x += l + 5, y, 50, 20, "inpPresenceBonus", 5, 1, NULL );
1417 window_setInputFilter( wid, "inpPresenceBonus", INPUT_FILTER_NUMBER );
1418 x += 50 + 10;
1419
1420 s = _("Range");
1421 l = gl_printWidthRaw( NULL, s );
1422 window_addText( wid, x, y, l, 20, 1, "txtPresenceRange",
1423 NULL, NULL, s );
1424 window_addInput( wid, x += l + 5, y, 30, 20, "inpPresenceRange", 1, 1, NULL );
1425 window_setInputFilter( wid, "inpPresenceRange", INPUT_FILTER_NUMBER );
1426 //x += 30 + 10;
1427
1428 x = 250;
1429 y -= gl_defFont.h + 15;
1430 s = _("hide");
1431 l = gl_printWidthRaw( NULL, s );
1432 window_addText( wid, x, y, l, 20, 1, "txtHide",
1433 NULL, NULL, s );
1434 window_addInput( wid, x += l + 5, y, 50, 20, "inpHide", 4, 1, NULL );
1435 window_setInputFilter( wid, "inpHide", INPUT_FILTER_NUMBER );
1436 x += 50 + 10;
1437
1438 /* Tags. */
1439 x = 250;
1440 y -= gl_defFont.h + 20;
1441 l = scnprintf( buf, sizeof(buf), "#n%s#0", _("Tags:") );
1442 for (int i=0; i<array_size(p->tags); i++)
1443 l += scnprintf( &buf[l], sizeof(buf)-l, "%s %s", ((i>0) ? "," : ""), p->tags[i] );
1444 window_addText( wid, x, y, 300, 20, 0, "txtTags", NULL, NULL, buf );
1445
1446 /* Bottom buttons. */
1447 window_addButton( wid, -20 - bw*3 - 15*3, 35 + BUTTON_HEIGHT, bw, BUTTON_HEIGHT,
1448 "btnRmService", _("Rm Service"), sysedit_btnRmService );
1449 window_addButton( wid, -20 - bw*2 - 15*2, 35 + BUTTON_HEIGHT, bw, BUTTON_HEIGHT,
1450 "btnAddService", _("Add Service"), sysedit_btnAddService );
1451 window_addButton( wid, -20 - bw - 15, 35 + BUTTON_HEIGHT, bw, BUTTON_HEIGHT,
1452 "btnEditTech", _("Edit Tech"), sysedit_btnTechEdit );
1453 window_addButton( wid, -20 - bw*3 - 15*3, 20, bw, BUTTON_HEIGHT,
1454 "btnDesc", _("Description"), sysedit_spobDesc );
1455 window_addButton( wid, -20 - bw*2 - 15*2, 20, bw, BUTTON_HEIGHT,
1456 "btnLandGFX", _("Land GFX"), sysedit_spobGFX );
1457 window_addButton( wid, -20 - bw - 15, 20, bw, BUTTON_HEIGHT,
1458 "btnSpaceGFX", _("Space GFX"), sysedit_spobGFX );
1459 window_addButton( wid, -20, 20, bw, BUTTON_HEIGHT,
1460 "btnClose", _("Close"), sysedit_editPntClose );
1461
1462 /* Load current values. */
1463 snprintf( buf, sizeof(buf), "%"PRIu64, p->population );
1464 window_setInput( wid, "inpPop", buf );
1465 snprintf( buf, sizeof(buf), "%s", p->class );
1466 window_setInput( wid, "inpClass", buf );
1467 window_setInput( wid, "inpLua", p->lua_file );
1468 snprintf( buf, sizeof(buf), "%g", p->presence.base );
1469 window_setInput( wid, "inpPresenceBase", buf );
1470 snprintf( buf, sizeof(buf), "%g", p->presence.bonus );
1471 window_setInput( wid, "inpPresenceBonus", buf );
1472 snprintf( buf, sizeof(buf), "%d", p->presence.range );
1473 window_setInput( wid, "inpPresenceRange", buf );
1474 snprintf( buf, sizeof(buf), "%g", p->hide );
1475 window_setInput( wid, "inpHide", buf );
1476
1477 /* Generate the list. */
1479}
1480
1484static void jp_type_check_hidden_update( unsigned int wid, const char* str )
1485{
1486 (void) str;
1487 if (jp_hidden == 0) {
1488 jp_hidden = 1;
1489 jp_exit = 0;
1490 }
1491 else
1492 jp_hidden = 0;
1493 window_checkboxSet( wid, "chkHidden", jp_hidden );
1494 window_checkboxSet( wid, "chkExit", jp_exit );
1495}
1496
1500static void jp_type_check_exit_update( unsigned int wid, const char* str )
1501{
1502 (void) str;
1503 if (jp_exit == 0) {
1504 jp_exit = 1;
1505 jp_hidden = 0;
1506 }
1507 else
1508 jp_exit = 0;
1509 window_checkboxSet( wid, "chkHidden", jp_hidden );
1510 window_checkboxSet( wid, "chkExit", jp_exit );
1511}
1512
1516static void sysedit_editJump (void)
1517{
1518 unsigned int wid;
1519 int x, y, w, l, bw;
1520 char buf[STRMAX_SHORT];
1521 const char *s;
1522 JumpPoint *j = &sysedit_sys->jumps[ sysedit_select[0].u.jump ];
1523
1524 /* Create the window. */
1525 wid = window_create( "wdwJumpPointEditor", _("Jump Point Editor"), -1, -1, SYSEDIT_EDIT_WIDTH, SYSEDIT_EDIT_HEIGHT );
1526 sysedit_widEdit = wid;
1527
1528 bw = (SYSEDIT_EDIT_WIDTH - 40 - 15 * 3) / 4.;
1529
1530 /* Target lable. */
1531 y = -40;
1532 snprintf( buf, sizeof(buf), _("Target: ") );
1533 w = gl_printWidthRaw( NULL, buf );
1534 window_addText( wid, 20, y, 180, 15, 0, "txtTargetLabel", &gl_smallFont, NULL, buf );
1535 snprintf( buf, sizeof(buf), "%s", j->target->name );
1536 window_addText( wid, 20 + w, y, 180, 15, 0, "txtName", &gl_smallFont, NULL, buf );
1537
1538 y -= gl_defFont.h + 10;
1539
1540 /* Input widgets and labels. */
1541 x = 20;
1542
1543 /* Initial checkbox state */
1544 jp_hidden = 0;
1545 jp_exit = 0;
1546 if (jp_isFlag( j, JP_HIDDEN ))
1547 jp_hidden = 1;
1548 else if (jp_isFlag( j, JP_EXITONLY ))
1549 jp_exit = 1;
1550 /* Create check boxes. */
1551 window_addCheckbox( wid, x, y, 100, 20,
1552 "chkHidden", _("Hidden"), jp_type_check_hidden_update, jp_hidden );
1553 y -= 20;
1554 window_addCheckbox( wid, x, y, 100, 20,
1555 "chkExit", _("Exit only"), jp_type_check_exit_update, jp_exit );
1556 y -= 30;
1557
1558 s = _("Hide"); /* TODO: if inpType == 0 disable hide box */
1559 l = gl_printWidthRaw( NULL, s );
1560 window_addText( wid, x, y, l, 20, 1, "txtHide",
1561 NULL, NULL, s );
1562 window_addInput( wid, x + l + 8, y, 50, 20, "inpHide", 4, 1, NULL );
1563 window_setInputFilter( wid, "inpHide", INPUT_FILTER_NUMBER );
1564 x += 50 + 10;
1565
1566 /* Bottom buttons. */
1567 window_addButton( wid, -20, 20, bw, BUTTON_HEIGHT,
1568 "btnClose", _("Close"), sysedit_editJumpClose );
1569
1570 /* Load current values. */
1571 snprintf( buf, sizeof(buf), "%g", j->hide );
1572 window_setInput( wid, "inpHide", buf );
1573}
1574
1578static void sysedit_editJumpClose( unsigned int wid, const char *unused )
1579{
1580 (void) unused;
1581 JumpPoint *j = &sysedit_sys->jumps[ sysedit_select[0].u.jump ];
1582 if (jp_hidden == 1) {
1583 jp_setFlag( j, JP_HIDDEN );
1584 jp_rmFlag( j, JP_EXITONLY );
1585 }
1586 else if (jp_exit == 1) {
1587 jp_setFlag( j, JP_EXITONLY );
1588 jp_rmFlag( j, JP_HIDDEN );
1589 }
1590 else {
1591 jp_rmFlag( j, JP_HIDDEN );
1592 jp_rmFlag( j, JP_EXITONLY );
1593 }
1594 j->hide = atof(window_getInput( sysedit_widEdit, "inpHide" ));
1595
1596 window_close( wid, unused );
1597}
1598
1602static void sysedit_editAsteroids (void)
1603{
1604 unsigned int wid;
1605 int x, y, l, bw;
1606 char buf[STRMAX_SHORT];
1607 const char *s;
1608 AsteroidAnchor *ast = &sysedit_sys->asteroids[ sysedit_select[0].u.asteroid ];
1609
1610 /* Create the window. */
1611 wid = window_create( "wdwAsteroidsEditor", _("Asteroid Field Editor"), -1, -1, SYSEDIT_EDIT_WIDTH, SYSEDIT_EDIT_HEIGHT );
1612 sysedit_widEdit = wid;
1613 window_setCancel( wid, sysedit_editAsteroidsClose );
1614
1615 /* Input widgets and labels. */
1616 x = 20;
1617
1618 /* Add some inputs. */
1619 y = -40;
1620 s = _("Density: ");
1621 l = gl_printWidthRaw( NULL, s );
1622 window_addText( wid, x, y, l, 20, 1, "txtDensity", NULL, NULL, s );
1623 window_addInput( wid, x + l + 8, y, 80, 20, "inpDensity", 10, 1, NULL );
1624 window_setInputFilter( wid, "inpDensity", INPUT_FILTER_NUMBER );
1625 y -= 30;
1626 s = _("Radius: ");
1627 l = gl_printWidthRaw( NULL, s );
1628 window_addText( wid, x, y, l, 20, 1, "txtInput", NULL, NULL, s );
1629 window_addInput( wid, x + l + 8, y, 80, 20, "inpRadius", 10, 1, NULL );
1630 window_setInputFilter( wid, "inpRadius", INPUT_FILTER_NUMBER );
1631 x = 200;
1632 y = -40;
1633 s = _("Max Speed: ");
1634 l = gl_printWidthRaw( NULL, s );
1635 window_addText( wid, x, y, l, 20, 1, "txtMaxspeed", NULL, NULL, s );
1636 window_addInput( wid, x + l + 8, y, 80, 20, "inpMaxspeed", 10, 1, NULL );
1637 window_setInputFilter( wid, "inpMaxspeed", INPUT_FILTER_NUMBER );
1638 y -= 30;
1639 s = _("Thrust: ");
1640 l = gl_printWidthRaw( NULL, s );
1641 window_addText( wid, x, y, l, 20, 1, "txtThrust", NULL, NULL, s );
1642 window_addInput( wid, x + l + 8, y, 80, 20, "inpThrust", 10, 1, NULL );
1643 window_setInputFilter( wid, "inpThrust", INPUT_FILTER_NUMBER );
1644
1645 /* List to choose the different asteroids that appear. */
1646 sysedit_genAsteroidsList( wid );
1647
1648 /* Button width. */
1649 bw = (SYSEDIT_EDIT_WIDTH - 40 - 15 * 3) / 4.;
1650
1651 /* List Captions. */
1652 window_addText( wid, 20, 20+BUTTON_HEIGHT+15+200+5, bw, gl_smallFont.h,
1653 1, "txtAsteroidsHave", NULL, NULL, _("Asteroids") );
1654 window_addText( wid, 20+bw+15, 20+BUTTON_HEIGHT+15+200+5, bw, gl_smallFont.h,
1655 1, "txtAsteroidsAvailable", NULL, NULL, _("Available") );
1656
1657 /* Bottom buttons. */
1658 window_addButton( wid, 20, 20, bw, BUTTON_HEIGHT,
1659 "btnRmAsteroid", _("Rm Asteroid"), sysedit_btnRmAsteroid );
1660 window_addButton( wid, 20 + bw + 15, 20, bw, BUTTON_HEIGHT,
1661 "btnAddAsteroid", _("Add Asteroid"), sysedit_btnAddAsteroid );
1662 window_addButton( wid, 20 + 2*(bw + 15), 20, bw, BUTTON_HEIGHT,
1663 "btnDelete", _("Delete"), sysedit_btnAsteroidsDelete );
1664 window_addButton( wid, -20, 20, bw, BUTTON_HEIGHT,
1665 "btnClose", _("Close"), sysedit_editAsteroidsClose );
1666
1667 /* Load current values. */
1668 snprintf( buf, sizeof(buf), "%g", ast->density );
1669 window_setInput( wid, "inpDensity", buf );
1670 snprintf( buf, sizeof(buf), "%g", ast->radius );
1671 window_setInput( wid, "inpRadius", buf );
1672 snprintf( buf, sizeof(buf), "%g", ast->maxspeed );
1673 window_setInput( wid, "inpMaxspeed", buf );
1674 snprintf( buf, sizeof(buf), "%g", ast->thrust );
1675 window_setInput( wid, "inpThrust", buf );
1676}
1677
1678static void sysedit_genAsteroidsList( unsigned int wid )
1679{
1680 int hpos, apos;
1681 int x, y, w, h;
1682 AsteroidAnchor *ast = &sysedit_sys->asteroids[ sysedit_select[0].u.asteroid ];
1683 const AsteroidTypeGroup *astgroups;
1684 char **have, **available;
1685
1686 hpos = apos = -1;
1687 if (widget_exists( wid, "lstAsteroidsHave" ) &&
1688 widget_exists( wid, "lstAsteroidsAvailable" )) {
1689 hpos = toolkit_getListPos( wid, "lstAsteroidsHave" );
1690 apos = toolkit_getListPos( wid, "lstAsteroidsAvailable" );
1691 window_destroyWidget( wid, "lstAsteroidsHave" );
1692 window_destroyWidget( wid, "lstAsteroidsAvailable" );
1693 }
1694
1695 /* Set up positions. */
1696 x = 20;
1697 y = 20 + BUTTON_HEIGHT + 15;
1698 w = (SYSEDIT_EDIT_WIDTH - 40 - 15 * 3) / 4;
1699 h = 200;
1700
1701 /* Find and add used asteroids. */
1702 have = malloc( sizeof(char*) * array_size(ast->groups) );
1703 for (int i=0; i<array_size(ast->groups); i++)
1704 have[i] = strdup( ast->groups[i]->name );
1705 window_addList( wid, x, y, w, h, "lstAsteroidsHave", have, array_size(ast->groups), 0, NULL, sysedit_btnRmAsteroid );
1706 x += w + 15;
1707
1708 /* Load all asteroid types. */
1709 astgroups = astgroup_getAll();
1710 available = malloc( sizeof(char*) * array_size(astgroups) );
1711 for (int i=0; i<array_size(astgroups); i++)
1712 available[i] = strdup( astgroups[i].name );
1713 qsort( available, array_size(astgroups), sizeof(char*), strsort );
1714 window_addList( wid, x, y, w, h, "lstAsteroidsAvailable", available, array_size(astgroups), 0, NULL, sysedit_btnAddAsteroid );
1715
1716 /* Restore positions. */
1717 if (hpos != -1 && apos != -1) {
1718 toolkit_setListPos( wid, "lstAsteroidsHave", hpos );
1719 toolkit_setListPos( wid, "lstAsteroidsAvailable", apos );
1720 }
1721}
1722
1723static void sysedit_btnRmAsteroid( unsigned int wid, const char *unused )
1724{
1725 (void) unused;
1726 int pos = toolkit_getListPos( wid, "lstAsteroidsHave" );
1727 AsteroidAnchor *ast = &sysedit_sys->asteroids[ sysedit_select[0].u.asteroid ];
1728
1729 if (array_size(ast->groups) > 0)
1730 array_erase( &ast->groups, &ast->groups[pos], &ast->groups[pos+1] );
1731
1732 sysedit_genAsteroidsList( wid );
1733}
1734
1735static void sysedit_btnAddAsteroid( unsigned int wid, const char *unused )
1736{
1737 (void) unused;
1738 const char *selected = toolkit_getList( wid, "lstAsteroidsAvailable" );
1739 AsteroidAnchor *ast = &sysedit_sys->asteroids[ sysedit_select[0].u.asteroid ];
1740
1741 array_push_back( &ast->groups, astgroup_getName( selected ) );
1742
1743 sysedit_genAsteroidsList( wid );
1744}
1745
1746static void sysedit_btnAsteroidsDelete( unsigned int wid, const char *unused )
1747{
1748 int i = dialogue_YesNo( _("Remove Asteroid Field"), _("Are you sure you want to remove this asteroid field?") );
1749 if (i==0)
1750 return;
1751
1752 AsteroidAnchor *ast = &sysedit_sys->asteroids[ sysedit_select[0].u.asteroid ];
1753
1754 asteroid_free( ast );
1755 array_erase( &sysedit_sys->asteroids, ast, ast+1 );
1756
1757 if (conf.devautosave)
1759
1760 window_close( wid, unused );
1761}
1762
1763static void sysedit_editAsteroidsClose( unsigned int wid, const char *unused )
1764{
1765 AsteroidAnchor *ast = &sysedit_sys->asteroids[ sysedit_select[0].u.asteroid ];
1766
1767 ast->density = atof(window_getInput( sysedit_widEdit, "inpDensity" ));
1768 ast->radius = atof(window_getInput( sysedit_widEdit, "inpRadius" ));
1769 ast->maxspeed = atof(window_getInput( sysedit_widEdit, "inpMaxspeed" ));
1770 ast->thrust = atof(window_getInput( sysedit_widEdit, "inpThrust" ));
1771
1772 /* Need to update some internals based on new values. */
1774
1775 if (conf.devautosave)
1777
1778 window_close( wid, unused );
1779}
1780
1781static void sysedit_editExclusion (void)
1782{
1783 unsigned int wid;
1784 int x, y, l, bw;
1785 char buf[STRMAX_SHORT];
1786 const char *s;
1787 AsteroidExclusion *exc = &sysedit_sys->astexclude[ sysedit_select[0].u.astexclude ];
1788
1789 /* Create the window. */
1790 wid = window_create( "wdwExclusionEditor", _("Asteroid Exclusion Zone Editor"), -1, -1, SYSEDIT_EDIT_WIDTH, SYSEDIT_EDIT_HEIGHT );
1791 sysedit_widEdit = wid;
1792 window_setCancel( wid, sysedit_editExclusionClose );
1793
1794 /* Add some inputs. */
1795 x = 20;
1796 y = -40;
1797 s = _("Radius: ");
1798 l = gl_printWidthRaw( NULL, s );
1799 window_addText( wid, x, y, l, 20, 1, "txtInput", NULL, NULL, s );
1800 window_addInput( wid, x + l + 8, y, 80, 20, "inpRadius", 10, 1, NULL );
1801 window_setInputFilter( wid, "inpRadius", INPUT_FILTER_NUMBER );
1802
1803 /* Bottom buttons. */
1804 bw = (SYSEDIT_EDIT_WIDTH - 40 - 15 * 3) / 4.;
1805 window_addButton( wid, -20 - 15 - bw, 20, bw, BUTTON_HEIGHT,
1806 "btnDelete", _("Delete"), sysedit_btnExclusionDelete );
1807 window_addButton( wid, -20, 20, bw, BUTTON_HEIGHT,
1808 "btnClose", _("Close"), sysedit_editExclusionClose );
1809
1810 /* Load current values. */
1811 snprintf( buf, sizeof(buf), "%g", exc->radius );
1812 window_setInput( wid, "inpRadius", buf );
1813}
1814
1815static void sysedit_btnExclusionDelete( unsigned int wid, const char *unused )
1816{
1817 int i = dialogue_YesNo( _("Remove Asteroid Exclusion Zone"), _("Are you sure you want to remove this asteroid exclusion zone?") );
1818 if (i==0)
1819 return;
1820
1821 AsteroidExclusion *exc = &sysedit_sys->astexclude[ sysedit_select[0].u.astexclude ];
1822
1823 array_erase( &sysedit_sys->astexclude, exc, exc+1 );
1824
1825 if (conf.devautosave)
1827
1828 window_close( wid, unused );
1829}
1830
1831static void sysedit_editExclusionClose( unsigned int wid, const char *unused )
1832{
1833 AsteroidExclusion *exc = &sysedit_sys->astexclude[ sysedit_select[0].u.astexclude ];
1834
1835 exc->radius = atof(window_getInput( sysedit_widEdit, "inpRadius" ));
1836
1837 if (conf.devautosave)
1839
1840 window_close( wid, unused );
1841}
1842
1846static void sysedit_spobDesc( unsigned int wid, const char *unused )
1847{
1848 (void) unused;
1849 int x, y, h, w, bw;
1850 Spob *p;
1851 const char *desc, *bardesc;
1852 char title[128];
1853
1854 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
1855
1856 /* Create the window. */
1857 snprintf(title, sizeof(title), _("Spob Information - %s"), p->name);
1858 wid = window_create( "wdwSpobDesc", title, -1, -1, SYSEDIT_EDIT_WIDTH, SYSEDIT_EDIT_HEIGHT );
1860
1861 x = 20;
1862 y = -40;
1863 w = SYSEDIT_EDIT_WIDTH - 40;
1864 h = (SYSEDIT_EDIT_HEIGHT - gl_defFont.h * 2 - 30 - 60 - BUTTON_HEIGHT - 10) / 2.;
1865 desc = p->description ? p->description : _("None");
1866 bardesc = p->bar_description ? p->bar_description : _("None");
1867 bw = (SYSEDIT_EDIT_WIDTH - 40 - 15 * 3) / 4.;
1868
1869 window_addButton( wid, -20 - bw*3 - 15*3, 20, bw, BUTTON_HEIGHT,
1870 "btnProperties", _("Properties"), sysedit_spobDescReturn );
1871
1872 window_addButton( wid, -20, 20, bw, BUTTON_HEIGHT,
1873 "btnClose", _("Close"), sysedit_spobDescClose );
1874
1875 /* Description label and text. */
1876 window_addText( wid, x, y, w, gl_defFont.h, 0, "txtDescriptionLabel", &gl_defFont, NULL,
1877 _("Landing Description") );
1878 y -= gl_defFont.h + 10;
1879 window_addInput( wid, x, y, w, h, "txtDescription", 1024, 0,
1880 NULL );
1881 window_setInputFilter( wid, "txtDescription",
1882 "[]{}~<>@#$^|_" );
1883 y -= h + 10;
1884 /* Load current values. */
1885 window_setInput( wid, "txtDescription", desc );
1886
1887 /* Bar description label and text. */
1888 window_addText( wid, x, y, w, gl_defFont.h, 0, "txtBarDescriptionLabel", &gl_defFont, NULL,
1889 _("Bar Description") );
1890 y -= gl_defFont.h + 10;
1891 window_addInput( wid, x, y, w, h, "txtBarDescription", 1024, 0,
1892 NULL );
1893 window_setInputFilter( wid, "txtBarDescription",
1894 "[]{}~<>@#$^|_" );
1895 /* Load current values. */
1896 window_setInput( wid, "txtBarDescription", bardesc );
1897}
1898
1902static void sysedit_spobDescReturn( unsigned int wid, const char *unused )
1903{
1904 Spob *p;
1905 const char *mydesc, *mybardesc;
1906
1907 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
1908
1909 mydesc = window_getInput( wid, "txtDescription" );
1910 mybardesc = window_getInput( wid, "txtBarDescription" );
1911
1912 free(p->description);
1913 free(p->bar_description);
1914 p->description = NULL;
1915 p->bar_description = NULL;
1916
1917 if (mydesc != NULL)
1918 p->description = strdup( mydesc );
1919 if (mybardesc != NULL)
1920 p->bar_description = strdup( mybardesc );
1921
1922 window_close( wid, unused );
1923}
1924
1928static void sysedit_spobDescClose( unsigned int wid, const char *unused )
1929{
1930 sysedit_spobDescReturn( wid, unused );
1932}
1933
1937static void sysedit_genServicesList( unsigned int wid )
1938{
1939 int j, n, nservices;
1940 Spob *p;
1941 char **have, **lack;
1942 int x, y, w, h, hpos, lpos;
1943
1944 hpos = lpos = -1;
1945
1946 /* Destroy if exists. */
1947 if (widget_exists( wid, "lstServicesHave" ) &&
1948 widget_exists( wid, "lstServicesLacked" )) {
1949 hpos = toolkit_getListPos( wid, "lstServicesHave" );
1950 lpos = toolkit_getListPos( wid, "lstServicesLacked" );
1951 window_destroyWidget( wid, "lstServicesHave" );
1952 window_destroyWidget( wid, "lstServicesLacked" );
1953 }
1954
1955 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
1956 x = 20;
1957 y = 20 + BUTTON_HEIGHT * 2 + 30;
1958 w = (SYSEDIT_EDIT_WIDTH - 40 - 15 * 3) / 4.;
1959 h = SYSEDIT_EDIT_HEIGHT - y - 130;
1960
1961 /* Get all missing services. */
1962 n = nservices = 0;
1963 for (int i=1; i<SPOB_SERVICES_MAX; i<<=1) {
1964 if (!spob_hasService(p, i) && (i != SPOB_SERVICE_INHABITED))
1965 n++;
1966 nservices++; /* Cheaply track all service types. */
1967 }
1968
1969 /* Get all the services the spob has. */
1970 j = 0;
1971 have = malloc( sizeof(char*) * MAX(nservices - n, 1) );
1972 if (nservices == n)
1973 have[j++] = strdup(_("None"));
1974 else
1975 for (int i=1; i<SPOB_SERVICES_MAX; i<<=1)
1976 if (spob_hasService(p, i) && (i != SPOB_SERVICE_INHABITED))
1977 have[j++] = strdup( spob_getServiceName( i ) );
1978
1979 /* Add list. */
1980 window_addList( wid, x, y, w, h, "lstServicesHave", have, j, 0, NULL, sysedit_btnRmService );
1981 x += w + 15;
1982
1983 /* Add list of services the spob lacks. */
1984 j = 0;
1985 lack = malloc( sizeof(char*) * MAX(1, n) );
1986 if (!n)
1987 lack[j++] = strdup( _("None") );
1988 else
1989 for (int i=1; i<SPOB_SERVICES_MAX; i<<=1)
1990 if (!spob_hasService(p, i) && (i != SPOB_SERVICE_INHABITED))
1991 lack[j++] = strdup( spob_getServiceName(i) );
1992
1993 /* Add list. */
1994 window_addList( wid, x, y, w, h, "lstServicesLacked", lack, j, 0, NULL, sysedit_btnAddService );
1995
1996 /* Restore positions. */
1997 if (hpos != -1 && lpos != -1) {
1998 toolkit_setListPos( wid, "lstServicesHave", hpos );
1999 toolkit_setListPos( wid, "lstServicesLacked", lpos );
2000 }
2001}
2002
2006static void sysedit_btnAddService( unsigned int wid, const char *unused )
2007{
2008 (void) unused;
2009 const char *selected;
2010 Spob *p;
2011
2012 selected = toolkit_getList( wid, "lstServicesLacked" );
2013 if ((selected == NULL) || (strcmp(selected,_("None"))==0))
2014 return;
2015
2016 /* Enable the service. All services imply landability. */
2017 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
2018 p->services |= spob_getService(selected) | SPOB_SERVICE_INHABITED | SPOB_SERVICE_LAND;
2019
2020 /* Regenerate the list. */
2022}
2023
2027static void sysedit_btnRmService( unsigned int wid, const char *unused )
2028{
2029 (void) unused;
2030 const char *selected;
2031 Spob *p;
2032
2033 selected = toolkit_getList( wid, "lstServicesHave" );
2034 if ((selected==NULL) || (strcmp(selected,_("None"))==0))
2035 return;
2036
2037 /* Flip the bit. Safe enough, as it's always 1 to start with. */
2038 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
2039 p->services ^= spob_getService(selected);
2040
2041 /* If landability was removed, the rest must go, too. */
2042 if (strcmp(selected,"Land")==0)
2043 p->services = 0;
2044
2046}
2047
2051static void sysedit_btnTechEdit( unsigned int wid, const char *unused )
2052{
2053 (void) unused;
2054 int y, w, bw;
2055
2056 /* Create the window. */
2057 wid = window_create( "wdwSpobTechEditor", _("Spob Tech Editor"), -1, -1, SYSEDIT_EDIT_WIDTH, SYSEDIT_EDIT_HEIGHT );
2059
2060 w = (SYSEDIT_EDIT_WIDTH - 40 - 15) / 2.;
2061 bw = (SYSEDIT_EDIT_WIDTH - 40 - 15 * 3) / 4.;
2062
2063 /* Close button. */
2064 window_addButton( wid, -20, 20, bw, BUTTON_HEIGHT,
2065 "btnClose", _("Close"), window_close );
2066 y = 20 + BUTTON_HEIGHT + 15;
2067
2068 /* Remove button. */
2069 window_addButton( wid, -20-(w+15), y, w, BUTTON_HEIGHT,
2070 "btnRm", _("Rm Tech"), sysedit_btnRmTech );
2071
2072 /* Add button. */
2073 window_addButton( wid, -20, y, w, BUTTON_HEIGHT,
2074 "btnAdd", _("Add Tech"), sysedit_btnAddTech );
2075
2076 sysedit_genTechList( wid );
2077}
2078
2082static void sysedit_genTechList( unsigned int wid )
2083{
2084 Spob *p;
2085 char **have, **lack;
2086 int j, n, x, y, w, h, hpos, lpos;
2087
2088 hpos = lpos = -1;
2089
2090 /* Destroy if exists. */
2091 if (widget_exists( wid, "lstTechsHave" ) &&
2092 widget_exists( wid, "lstTechsLacked" )) {
2093 hpos = toolkit_getListPos( wid, "lstTechsHave" );
2094 lpos = toolkit_getListPos( wid, "lstTechsLacked" );
2095 window_destroyWidget( wid, "lstTechsHave" );
2096 window_destroyWidget( wid, "lstTechsLacked" );
2097 }
2098
2099 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
2100 w = (SYSEDIT_EDIT_WIDTH - 40 - 15) / 2.;
2101 x = -20 - w - 15;
2102 y = 20 + BUTTON_HEIGHT * 2 + 30;
2103 h = SYSEDIT_EDIT_HEIGHT - y - 30;
2104
2105 /* Get all the techs the spob has. */
2106 n = 0;
2107 if (p->tech != NULL)
2108 have = tech_getItemNames( p->tech, &n );
2109 else {
2110 have = malloc( sizeof(char*) );
2111 have[n++] = strdup(_("None"));
2112 }
2113
2114 /* Add list. */
2115 window_addList( wid, x, y, w, h, "lstTechsHave", have, n, 0, NULL, sysedit_btnRmTech );
2116 x += w + 15;
2117
2118 /* Omit the techs that the spob already has from the list. */
2119 n = 0;
2120 if (p->tech != NULL) {
2121 char **tmp = tech_getAllItemNames( &j );
2122 for (int i=0; i<j; i++)
2123 if (!tech_hasItem( p->tech, tmp[i] ))
2124 n++;
2125
2126 if (!n) {
2127 lack = malloc( sizeof(char*) );
2128 lack[n++] = strdup(_("None"));
2129 }
2130 else {
2131 lack = malloc( sizeof(char*) * j );
2132 n = 0;
2133 for (int i=0; i<j; i++)
2134 if (!tech_hasItem( p->tech, tmp[i] ))
2135 lack[n++] = strdup( tmp[i] );
2136 }
2137
2138 /* Clean up. */
2139 for (int i=0; i<j; i++)
2140 free(tmp[i]);
2141
2142 free(tmp);
2143 }
2144 else
2145 lack = tech_getAllItemNames( &n );
2146
2147 /* Add list. */
2148 window_addList( wid, x, y, w, h, "lstTechsLacked", lack, n, 0, NULL, sysedit_btnAddTech );
2149
2150 /* Restore positions. */
2151 if (hpos != -1 && lpos != -1) {
2152 toolkit_setListPos( wid, "lstTechsHave", hpos );
2153 toolkit_setListPos( wid, "lstTechsLacked", lpos );
2154 }
2155}
2156
2160static void sysedit_btnAddTech( unsigned int wid, const char *unused )
2161{
2162 (void) unused;
2163 const char *selected;
2164 Spob *p;
2165
2166 selected = toolkit_getList( wid, "lstTechsLacked" );
2167 if ((selected == NULL) || (strcmp(selected,_("None"))==0))
2168 return;
2169
2170 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
2171 if (p->tech == NULL)
2172 p->tech = tech_groupCreate();
2173 tech_addItemTech( p->tech, selected );
2174
2175 /* Regenerate the list. */
2176 sysedit_genTechList( wid );
2177}
2178
2182static void sysedit_btnRmTech( unsigned int wid, const char *unused )
2183{
2184 (void) unused;
2185 const char *selected;
2186 Spob *p;
2187 int n;
2188
2189 selected = toolkit_getList( wid, "lstTechsHave" );
2190 if ((selected == NULL) || (strcmp(selected,_("None"))==0))
2191 return;
2192
2193 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
2194 if (tech_hasItem( p->tech, selected ))
2195 tech_rmItemTech( p->tech, selected );
2196
2197 n = tech_getItemCount( p->tech );
2198 if (!n)
2199 p->tech = NULL;
2200
2201 /* Regenerate the list. */
2202 sysedit_genTechList( wid );
2203}
2204
2208static void sysedit_btnFaction( unsigned int wid_unused, const char *unused )
2209{
2210 (void) wid_unused;
2211 (void) unused;
2212 unsigned int wid;
2213 int pos, j, y, h, bw, *factions;
2214 char **str;
2215 const char *s;
2216 Spob *p;
2217
2218 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
2219
2220 /* Create the window. */
2221 wid = window_create( "wdwModifyFaction", _("Modify Faction"), -1, -1, SYSEDIT_EDIT_WIDTH, SYSEDIT_EDIT_HEIGHT );
2223
2224 /* Generate factions list. */
2225 factions = faction_getAll();
2226 str = malloc( sizeof(char*) * (array_size(factions) + 1) );
2227 str[0] = strdup(_("None"));
2228 j = 1;
2229 for (int i=0; i<array_size(factions); i++)
2230 str[j++] = strdup( faction_name( factions[i] ) ); /* Not translating so we can use faction_get */
2231 qsort( &str[1], j-1, sizeof(char*), strsort );
2232
2233 /* Get current faction. */
2234 if (p->presence.faction >= 0) {
2235 pos = 0;
2236 s = faction_name(p->presence.faction);
2237 for (int i=0; i<j; i++)
2238 if (strcmp(s,str[i])==0)
2239 pos = i;
2240 }
2241 else
2242 pos = -1;
2243
2244 bw = (SYSEDIT_EDIT_WIDTH - 40 - 15 * 3) / 4.;
2245 y = 20 + BUTTON_HEIGHT + 15;
2246 h = SYSEDIT_EDIT_HEIGHT - y - 30;
2247 window_addList( wid, 20, -40, SYSEDIT_EDIT_WIDTH-40, h,
2248 "lstFactions", str, j, pos, NULL, sysedit_btnFactionSet );
2249
2250 /* Close button. */
2251 window_addButton( wid, -20, 20, bw, BUTTON_HEIGHT,
2252 "btnClose", _("Close"), window_close );
2253
2254 /* Add button. */
2255 window_addButton( wid, -20-(bw+15), 20, bw, BUTTON_HEIGHT,
2256 "btnAdd", _("Set"), sysedit_btnFactionSet );
2257
2258 array_free( factions );
2259}
2260
2264static void sysedit_btnFactionSet( unsigned int wid, const char *unused )
2265{
2266 (void) unused;
2267 const char *selected;
2268 Spob *p;
2269
2270 selected = toolkit_getList( wid, "lstFactions" );
2271 if (selected == NULL)
2272 return;
2273 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
2274
2275 /* "None" case. */
2276 if (toolkit_getListPos( wid, "lstFactions")==0) {
2277 p->presence.faction = -1;
2278 }
2279 else {
2280 /* Set the faction. */
2281 p->presence.faction = faction_get( selected );
2282 }
2283
2284 /* Update the editor window. */
2285 window_modifyText( sysedit_widEdit, "txtFaction", p->presence.faction >= 0 ? faction_name( p->presence.faction ) : _("None") );
2286
2287 window_close( wid, unused );
2288}
2289
2293static void sysedit_btnEdit( unsigned int wid_unused, const char *unused )
2294{
2295 (void) wid_unused;
2296 (void) unused;
2297 Select_t *sel = &sysedit_select[0];
2298 if (sel->type==SELECT_SPOB)
2300 else if (sel->type==SELECT_JUMPPOINT)
2302 else if (sel->type==SELECT_ASTEROID)
2304 else if (sel->type==SELECT_ASTEXCLUDE)
2305 sysedit_editExclusion();
2306}
2307
2311static void sysedit_spobGFX( unsigned int wid_unused, const char *wgt )
2312{
2313 (void) wid_unused;
2314 unsigned int wid;
2315 size_t nfiles, j;
2316 char *path, buf[STRMAX_SHORT];
2317 char **files;
2318 glTexture *t;
2319 ImageArrayCell *cells;
2320 int w, h, land;
2321 Spob *p;
2322 glColour c;
2323
2324 land = (strcmp(wgt,"btnLandGFX") == 0);
2325
2326 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
2327 /* Create the window. */
2328 snprintf( buf, sizeof(buf), _("%s - Spob Properties"), p->name );
2329 wid = window_create( "wdwSpobGFX", buf, -1, -1, -1, -1 );
2330 window_dimWindow( wid, &w, &h );
2331
2334
2335 /* Close button. */
2336 window_addButton( wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
2337 "btnClose", _("Close"), sysedit_btnGFXClose );
2338
2339 /* Apply button. */
2340 window_addButton( wid, -20, 20+(20+BUTTON_HEIGHT), BUTTON_WIDTH, BUTTON_HEIGHT,
2341 land ? "btnApplyLand" : "btnApplySpace", _("Apply"), sysedit_btnGFXApply );
2342
2343 /* Find images first. */
2344 path = land ? SPOB_GFX_EXTERIOR_PATH : SPOB_GFX_SPACE_PATH;
2345 files = PHYSFS_enumerateFiles( path );
2346 for (nfiles=0; files[nfiles]; nfiles++) {}
2347 cells = calloc( nfiles, sizeof(ImageArrayCell) );
2348
2349 j = 0;
2350 for (size_t i=0; i<nfiles; i++) {
2351 PHYSFS_Stat path_stat;
2352 snprintf( buf, sizeof(buf), "%s/%s", path, files[i] );
2353 /* Ignore directories. */
2354 if (!PHYSFS_stat( buf, &path_stat )) {
2355 WARN(_("Unable to check file type for '%s'!"), buf);
2356 continue;
2357 }
2358 if (path_stat.filetype != PHYSFS_FILETYPE_REGULAR)
2359 continue;
2360
2361 t = gl_newImage( buf, OPENGL_TEX_MIPMAPS );
2362 if (t == NULL)
2363 continue;
2364 cells[j].image = t;
2365 cells[j].caption = strdup( files[i] );
2366 c = strcmp(files[i], land ? p->gfx_exteriorPath : p->gfx_spacePath)==0 ? cOrange : cBlack;
2367 memcpy( &cells[j].bg, &c, sizeof(glColour) );
2368 j++;
2369 }
2370 PHYSFS_freeList( files );
2371
2372 /* Add image array. */
2373 window_addImageArray( wid, 20, 20, w-60-BUTTON_WIDTH, h-60, "iarGFX", 128, 128, cells, j, NULL, NULL, NULL );
2374 toolkit_setImageArray( wid, "iarGFX", path );
2375}
2376
2380static void sysedit_btnGFXClose( unsigned int wid, const char *wgt )
2381{
2382 window_close( wid, wgt );
2383}
2384
2388static void sysedit_btnGFXApply( unsigned int wid, const char *wgt )
2389{
2390 Spob *p;
2391 const char *str;
2392 char *path, buf[PATH_MAX];
2393 int land;
2394
2395 land = (strcmp(wgt,"btnApplyLand") == 0);
2396 p = sysedit_sys->spobs[ sysedit_select[0].u.spob ];
2397
2398 /* Get output. */
2399 str = toolkit_getImageArray( wid, "iarGFX" );
2400 if (str == NULL)
2401 return;
2402
2403 /* New path. */
2404 path = land ? SPOB_GFX_EXTERIOR_PATH : SPOB_GFX_SPACE_PATH;
2405 snprintf( buf, sizeof(buf), "%s/%s", path, str );
2406
2407 if (land) {
2408 free( p->gfx_exteriorPath );
2409 free( p->gfx_exterior );
2410 snprintf( buf, sizeof(buf), SPOB_GFX_EXTERIOR_PATH"%s", str );
2411 p->gfx_exteriorPath = strdup( str );
2412 p->gfx_exterior = strdup( buf );
2413 }
2414 else { /* Free old texture, load new. */
2415 free( p->gfx_spaceName );
2416 free( p->gfx_spacePath );
2417 p->gfx_spaceName = strdup( buf );
2418 p->gfx_spacePath = strdup( str );
2419 gl_freeTexture( p->gfx_space );
2420 p->gfx_space = NULL;
2421 p->radius = -1.; /* Reset radius. */
2422 spob_gfxLoad( p );
2423 }
2424
2425 /* For now we close. */
2426 sysedit_btnGFXClose( wid, wgt );
2427}
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition: array.h:158
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
Definition: array.h:140
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition: array.h:168
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
Definition: array.h:119
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
Definition: array.h:129
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Definition: array.h:93
void asteroids_computeInternals(AsteroidAnchor *a)
Updates internal alues of an asteroid field.
Definition: asteroid.c:407
const AsteroidTypeGroup * astgroup_getAll(void)
Gets all the asteroid type groups.
Definition: asteroid.c:1003
void asteroid_free(AsteroidAnchor *ast)
Frees an asteroid anchor.
Definition: asteroid.c:891
AsteroidTypeGroup * astgroup_getName(const char *name)
Gets an asteroid type group by name.
Definition: asteroid.c:1014
int dpl_saveSpob(const Spob *p)
Saves a spob.
Definition: dev_spob.c:31
static Select_t sysedit_tsel
Definition: dev_sysedit.c:75
#define SYSEDIT_ZOOM_STEP
Definition: dev_sysedit.c:45
static void sysedit_btnGFXApply(unsigned int wid, const char *wgt)
Apply new graphics.
Definition: dev_sysedit.c:2388
static double sysedit_xpos
Definition: dev_sysedit.c:85
static int sysedit_nselect
Definition: dev_sysedit.c:73
static int jp_hidden
Definition: dev_sysedit.c:96
static int sysedit_grid
Definition: dev_sysedit.c:84
static unsigned int sysedit_wid
Definition: dev_sysedit.c:82
static void jp_type_check_exit_update(unsigned int wid, const char *str)
Updates the jump point checkboxes.
Definition: dev_sysedit.c:1500
static void sysedit_close(unsigned int wid, const char *wgt)
Closes the system editor widget.
Definition: dev_sysedit.c:285
static void sysedit_editPntClose(unsigned int wid, const char *unused)
Closes the spob editor, saving the changes made.
Definition: dev_sysedit.c:323
static int sysedit_drag
Definition: dev_sysedit.c:90
static void sysedit_buttonZoom(unsigned int wid, const char *str)
Handles the button zoom clicks.
Definition: dev_sysedit.c:1183
static int sysedit_tadd
Definition: dev_sysedit.c:76
static void sysedit_selectAdd(const Select_t *sel)
Adds a system to the selection.
Definition: dev_sysedit.c:1277
static void sysedit_focusLose(unsigned int wid, const char *wgtname)
Called when it's de-focused.
Definition: dev_sysedit.c:916
static void sysedit_btnGrid(unsigned int wid_unused, const char *unused)
Toggles the grid.
Definition: dev_sysedit.c:645
static void sysedit_btnNewSpob(unsigned int wid_unused, const char *unused)
Enters the editor in new spob mode.
Definition: dev_sysedit.c:368
static int sysedit_selectCmp(const Select_t *a, const Select_t *b)
Compares two selections to see if they are the same.
Definition: dev_sysedit.c:1319
#define SYSEDIT_EDIT_WIDTH
Definition: dev_sysedit.c:39
static void sysedit_btnReset(unsigned int wid_unused, const char *unused)
Resets jump points.
Definition: dev_sysedit.c:556
static void sysedit_render(double bx, double by, double w, double h, void *data)
System editor custom widget rendering.
Definition: dev_sysedit.c:656
static double sysedit_ypos
Definition: dev_sysedit.c:86
static int sysedit_isSelected(const Select_t *s)
Check to see if something is selected.
Definition: dev_sysedit.c:1327
static void sysedit_renderAsteroidsField(double bx, double by, const AsteroidAnchor *ast, int selected)
Draws an asteroid field on the map.
Definition: dev_sysedit.c:780
static int sysedit_keys(unsigned int wid, SDL_Keycode key, SDL_Keymod mod)
Handles keybindings.
Definition: dev_sysedit.c:270
@ SELECT_ASTEROID
Definition: dev_sysedit.c:56
@ SELECT_ASTEXCLUDE
Definition: dev_sysedit.c:57
@ SELECT_JUMPPOINT
Definition: dev_sysedit.c:55
@ SELECT_NONE
Definition: dev_sysedit.c:53
@ SELECT_SPOB
Definition: dev_sysedit.c:54
static unsigned int sysedit_widEdit
Definition: dev_sysedit.c:83
static void sysedit_renderSprite(glTexture *gfx, double bx, double by, double x, double y, int sx, int sy, const glColour *c, int selected, const char *caption)
Renders a sprite for the custom widget.
Definition: dev_sysedit.c:881
static int sysedit_mouse(unsigned int wid, SDL_Event *event, double mx, double my, double w, double h, double xr, double yr, void *data)
System editor custom widget mouse handling.
Definition: dev_sysedit.c:977
static int jp_exit
Definition: dev_sysedit.c:97
static void sysedit_btnAddService(unsigned int wid, const char *unused)
Adds a service to a spob.
Definition: dev_sysedit.c:2006
static void sysedit_genTechList(unsigned int wid)
Generates the spob tech list.
Definition: dev_sysedit.c:2082
static void sysedit_btnGFXClose(unsigned int wid, const char *wgt)
Closes the spob graphic editor.
Definition: dev_sysedit.c:2380
static void sysedit_deselect(void)
Deselects everything.
Definition: dev_sysedit.c:1209
static void sysedit_checkButtons(void)
Checks to see which buttons should be active and the likes.
Definition: dev_sysedit.c:1224
static void sysedit_btnRmTech(unsigned int wid, const char *unused)
Removes a tech from a spob.
Definition: dev_sysedit.c:2182
static double sysedit_zoom
Definition: dev_sysedit.c:87
static void sysedit_btnFaction(unsigned int wid_unused, const char *unused)
Edits a spob's faction.
Definition: dev_sysedit.c:2208
static void sysedit_spobGFX(unsigned int wid_unused, const char *wgt)
Opens the spob landing or space graphic editor.
Definition: dev_sysedit.c:2311
static void sysedit_editAsteroids(void)
Opens the asteroid editor.
Definition: dev_sysedit.c:1602
static void sysedit_selectRm(Select_t *sel)
Removes a system from the selection.
Definition: dev_sysedit.c:1299
static StarSystem * sysedit_sys
Definition: dev_sysedit.c:81
#define SYSEDIT_DRAG_THRESHOLD
Definition: dev_sysedit.c:42
static void sysedit_btnEdit(unsigned int wid_unused, const char *unused)
Opens the system property editor.
Definition: dev_sysedit.c:2293
#define SYSEDIT_ZOOM_MIN
Definition: dev_sysedit.c:47
#define SYSEDIT_MOVE_THRESHOLD
Definition: dev_sysedit.c:43
static void sysedit_renderAsteroidExclusion(double bx, double by, const AsteroidExclusion *aexcl, int selected)
Draws an asteroid exclusion zone on the map.
Definition: dev_sysedit.c:806
#define BUTTON_HEIGHT
Definition: dev_sysedit.c:37
static void sysedit_spobDescClose(unsigned int wid, const char *unused)
Closes both the spob description window and the properties window.
Definition: dev_sysedit.c:1928
static void sysedit_btnFactionSet(unsigned int wid, const char *unused)
Actually modifies the faction.
Definition: dev_sysedit.c:2264
static unsigned int sysedit_dragTime
Definition: dev_sysedit.c:89
#define SYSEDIT_EDIT_HEIGHT
Definition: dev_sysedit.c:40
static void sysedit_spobDesc(unsigned int wid, const char *unused)
Displays the spob landing description and bar description in a separate window.
Definition: dev_sysedit.c:1846
static void sysedit_editJumpClose(unsigned int wid, const char *unused)
Closes the jump editor, saving the changes made.
Definition: dev_sysedit.c:1578
static void sysedit_btnScale(unsigned int wid_unused, const char *unused)
Interface for scaling a system from the system view.
Definition: dev_sysedit.c:573
static int sysedit_mselect
Definition: dev_sysedit.c:74
static void sysedit_genServicesList(unsigned int wid)
Generates the spob services list.
Definition: dev_sysedit.c:1937
static double sysedit_my
Definition: dev_sysedit.c:93
static void sysedit_btnRemove(unsigned int wid_unused, const char *unused)
Removes spobs.
Definition: dev_sysedit.c:516
void sysedit_open(StarSystem *sys)
Opens the system editor interface.
Definition: dev_sysedit.c:169
static void sysedit_btnRmService(unsigned int wid, const char *unused)
Removes a service from a spob.
Definition: dev_sysedit.c:2027
static void sysedit_renderBG(double bx, double bw, double w, double h, double x, double y)
Renders the custom widget background.
Definition: dev_sysedit.c:835
static void sysedit_editPnt(void)
Edits a spob.
Definition: dev_sysedit.c:1338
static int sysedit_moved
Definition: dev_sysedit.c:88
static void sysedit_spobDescReturn(unsigned int wid, const char *unused)
Closes the spob description window and returns to the properties window.
Definition: dev_sysedit.c:1902
static void sysedit_btnAddTech(unsigned int wid, const char *unused)
Adds a tech to a spob.
Definition: dev_sysedit.c:2160
void sysedit_sysScale(StarSystem *sys, double factor)
Scales a system.
Definition: dev_sysedit.c:604
#define BUTTON_WIDTH
Definition: dev_sysedit.c:36
static void jp_type_check_hidden_update(unsigned int wid, const char *str)
Updates the jump point checkboxes.
Definition: dev_sysedit.c:1484
static double sysedit_mx
Definition: dev_sysedit.c:92
static void sysedit_btnTechEdit(unsigned int wid, const char *unused)
Edits a spob's tech.
Definition: dev_sysedit.c:2051
static int sysedit_dragSel
Definition: dev_sysedit.c:91
static void sysedit_btnNewAsteroids(unsigned int wid_unused, const char *unused)
Enters the editor in new spob mode.
Definition: dev_sysedit.c:422
#define SYSEDIT_ZOOM_MAX
Definition: dev_sysedit.c:46
static void sysedit_editJump(void)
Edits a jump.
Definition: dev_sysedit.c:1516
static Select_t * sysedit_select
Definition: dev_sysedit.c:72
int dsys_saveSystem(StarSystem *sys)
Saves a star system.
Definition: dev_system.c:83
void uniedit_selectText(void)
Sets the selected system text.
Definition: dev_uniedit.c:1492
char * dialogue_runChoice(void)
Run the dialog and return the clicked string.
Definition: dialogue.c:792
char * dialogue_inputRaw(const char *title, int min, int max, const char *msg)
Creates a dialogue that allows the player to write a message.
Definition: dialogue.c:465
void dialogue_alert(const char *fmt,...)
Displays an alert popup with only an ok button and a message.
Definition: dialogue.c:132
char * dialogue_input(const char *title, int min, int max, const char *fmt,...)
Creates a dialogue that allows the player to write a message.
Definition: dialogue.c:436
void dialogue_addChoice(const char *caption, const char *msg, const char *opt)
Add a choice to the dialog.
Definition: dialogue.c:770
void dialogue_makeChoice(const char *caption, const char *msg, int opts)
Create the choice dialog. Need to add choices with below method.
Definition: dialogue.c:748
int dialogue_YesNo(const char *caption, const char *fmt,...)
Runs a dialogue with both yes and no options.
Definition: dialogue.c:344
int economy_execQueued(void)
Calls economy_refresh if an economy update is queued.
Definition: economy.c:483
const char * faction_name(int f)
Gets a factions "real" (internal) name.
Definition: faction.c:304
const glColour * faction_colour(int f)
Gets the colour of the faction.
Definition: faction.c:467
int * faction_getAll(void)
Returns all faction IDs in an array (array.h).
Definition: faction.c:193
int faction_get(const char *name)
Gets a faction ID by name.
Definition: faction.c:182
glFont gl_smallFont
Definition: font.c:154
int gl_printWidthRaw(const glFont *ft_font, const char *text)
Gets the width that it would take to print some text.
Definition: font.c:960
glFont gl_defFont
Definition: font.c:153
int gl_printMidRaw(const glFont *ft_font, int width, double x, double y, const glColour *c, double outlineR, const char *text)
Displays text centered in position and width.
Definition: font.c:787
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.
Definition: font.c:690
glFont gl_defFontMono
Definition: font.c:155
void land(Spob *p, int load)
Opens up all the land dialogue stuff.
Definition: land.c:1201
Header file with generic functions and naev-specifics.
#define MIN(x, y)
Definition: naev.h:40
#define ABS(x)
Definition: naev.h:36
#define pow2(x)
Definition: naev.h:46
#define MAX(x, y)
Definition: naev.h:39
#define PATH_MAX
Definition: naev.h:50
int asprintf(char **strp, const char *fmt,...)
Like sprintf(), but it allocates a large-enough string and returns the pointer in the first argument....
Definition: nstring.c:161
int strsort(const void *p1, const void *p2)
Sort function for sorting strings with qsort().
Definition: nstring.c:108
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
Definition: nstring.c:178
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.
Definition: opengl_render.c:90
void gl_renderLine(double x1, double y1, double x2, double y2, const glColour *c)
Draws a line.
void gl_renderScaleSprite(const glTexture *sprite, double bx, double by, int sx, int sy, double bw, double bh, const glColour *c)
Blits a scaled sprite, position is in absolute screen coordinates.
void gl_renderRectEmpty(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
void gl_renderCross(double x, double y, double r, const glColour *c)
Renders a cross at a given position.
void gl_renderCircle(double cx, double cy, double r, const glColour *c, int filled)
Draws a circle.
glTexture * gl_newImage(const char *path, const unsigned int flags)
Loads an image as a texture.
Definition: opengl_tex.c:570
void gl_freeTexture(glTexture *texture)
Frees a texture.
Definition: opengl_tex.c:755
static const double c[]
Definition: rng.c:264
static const double d[]
Definition: rng.c:273
static const double b[]
Definition: rng.c:256
void safelanes_recalculate(void)
Update the safe lane locations in response to the universe changing (e.g., diff applied).
Definition: safelanes.c:249
SafeLane * safelanes_get(int faction, int standing, const StarSystem *system)
Gets a set of safelanes for a faction and system.
Definition: safelanes.c:187
void space_reconstructPresences(void)
Reset the presence of all systems.
Definition: space.c:4220
int spob_exists(const char *spobname)
Check to see if a spob exists.
Definition: space.c:1082
void systems_reconstructJumps(void)
Reconstructs the jumps.
Definition: space.c:2671
int spob_getService(const char *name)
Converts name to spob service flag.
Definition: space.c:184
void system_setFaction(StarSystem *sys)
Sets the system faction based on the spobs it has.
Definition: space.c:3017
Spob * spob_get(const char *spobname)
Gets a spob based on its name.
Definition: space.c:1006
const char * space_getRndSpob(int landable, unsigned int services, int(*filter)(Spob *p))
Gets the name of a random spob.
Definition: space.c:601
StarSystem * system_getIndex(int id)
Get the system by its index.
Definition: space.c:944
JumpPoint * jump_getTarget(const StarSystem *target, const StarSystem *sys)
Less safe version of jump_get that works with pointers.
Definition: space.c:1198
char * spob_getSystem(const char *spobname)
Get the name of a system from a spobname.
Definition: space.c:980
void system_updateAsteroids(StarSystem *sys)
Updates some internal calculations about asteroids in a system.
Definition: space.c:322
int system_addSpob(StarSystem *sys, const char *spobname)
Adds a spob to a star system.
Definition: space.c:2372
void spob_gfxLoad(Spob *spob)
Loads a spob's graphics (and radius).
Definition: space.c:2019
Spob * spob_getIndex(int ind)
Gets spob by index.
Definition: space.c:1038
const char * spob_getServiceName(int service)
Gets the (English) name for a service code.
Definition: space.c:165
Spob * spob_new(void)
Creates a new spob.
Definition: space.c:1659
glTexture * jumppoint_gfx
Definition: space.c:106
void space_gfxLoad(StarSystem *sys)
Loads all the graphics for a star system.
Definition: space.c:2057
int system_rmSpob(StarSystem *sys, const char *spobname)
Removes a spob from a star system.
Definition: space.c:2411
Represents an asteroid field anchor.
Definition: asteroid.h:100
double radius
Definition: asteroid.h:107
double density
Definition: asteroid.h:104
double * groupsw
Definition: asteroid.h:110
double thrust
Definition: asteroid.h:114
double maxspeed
Definition: asteroid.h:112
Asteroid * asteroids
Definition: asteroid.h:105
AsteroidTypeGroup ** groups
Definition: asteroid.h:109
Represents an asteroid exclusion zone.
Definition: asteroid.h:121
Represents a group of asteroids.
Definition: asteroid.h:66
int devautosave
Definition: conf.h:159
Describes a safe lane, patrolled by a faction, within a system.
Definition: safelanes.h:24
int point_id[2]
Definition: safelanes.h:27
int faction
Definition: safelanes.h:25
SafeLaneLocType point_type[2]
Definition: safelanes.h:26
Selection generic for stuff in a system.
Definition: dev_sysedit.c:63
union Select_t::@6 u
int type
Definition: dev_sysedit.c:64
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Definition: space.h:88
char * name
Definition: space.h:90
vec2 pos
Definition: space.h:93
int h
Definition: font.h:18
Abstraction for rendering sprite sheets.
Definition: opengl_tex.h:34
double sw
Definition: opengl_tex.h:44
double sh
Definition: opengl_tex.h:45
double sx
Definition: opengl_tex.h:42
Represents a 2d vector.
Definition: vec2.h:32
double y
Definition: vec2.h:34
double x
Definition: vec2.h:33
int tech_rmItemTech(tech_group_t *tech, const char *value)
Removes an item from a tech.
Definition: tech.c:485
tech_group_t * tech_groupCreate(void)
Creates a tech group.
Definition: tech.c:173
int tech_getItemCount(const tech_group_t *tech)
Gets the number of techs within a given group.
Definition: tech.c:671
int tech_hasItem(const tech_group_t *tech, const char *item)
Checks whether a given tech group has the specified item.
Definition: tech.c:655
int tech_addItemTech(tech_group_t *tech, const char *value)
Adds an item to a tech.
Definition: tech.c:465
char ** tech_getItemNames(const tech_group_t *tech, int *n)
Gets the names of all techs within a given group.
Definition: tech.c:683
char ** tech_getAllItemNames(int *n)
Gets the names of all techs.
Definition: tech.c:703
unsigned int window_create(const char *name, const char *displayname, const int x, const int y, const int w, const int h)
Creates a window.
Definition: toolkit.c:696
void window_setFocus(unsigned int wid, const char *wgtname)
Sets the focused widget in a window.
Definition: toolkit.c:2460
void window_setAccept(unsigned int wid, void(*accept)(unsigned int, const char *))
Sets the default accept function of the window.
Definition: toolkit.c:879
void window_dimWindow(unsigned int wid, int *w, int *h)
Gets the dimensions of a window.
Definition: toolkit.c:371
void window_setCancel(unsigned int wid, void(*cancel)(unsigned int, const char *))
Sets the default cancel function of the window.
Definition: toolkit.c:900
void window_handleKeys(unsigned int wid, int(*keyhandler)(unsigned int, SDL_Keycode, SDL_Keymod))
Sets the key handler for the window.
Definition: toolkit.c:972
void window_destroyWidget(unsigned int wid, const char *wgtname)
Destroys a widget in a window.
Definition: toolkit.c:1162
void window_setBorder(unsigned int wid, int enable)
Sets or removes the border of a window.
Definition: toolkit.c:953
int widget_exists(unsigned int wid, const char *wgtname)
Checks to see if a widget exists.
Definition: toolkit.c:1139
void window_close(unsigned int wid, const char *str)
Helper function to automatically close the window calling it.
Definition: toolkit.c:1031