16#include "dev_sysedit.h"
21#include "dev_system.h"
22#include "dev_uniedit.h"
29#include "opengl_render.h"
32#include "tk/toolkit_priv.h"
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
63typedef struct Select_s {
105static void sysedit_render(
double bx,
double by,
double w,
double h,
void *data );
108static void sysedit_renderBG(
double bx,
double bw,
double w,
double h,
double x,
double y );
110 int sx,
int sy,
const glColour *
c,
int selected,
const char *caption );
112static int sysedit_mouseTrySelect(
const Select_t *sel,
double x,
double y,
double t,
double mx,
double my, SDL_Keymod mod,
void (*func)(
void) );
113static int sysedit_mouse(
unsigned int wid,
const SDL_Event* event,
double mx,
double my,
114 double w,
double h,
double xr,
double yr,
void *data );
116static void sysedit_close(
unsigned int wid,
const char *wgt );
119static void sysedit_btnRename(
unsigned int wid_unused,
const char *unused );
123static void sysedit_btnGrid(
unsigned int wid_unused,
const char *unused );
124static void sysedit_btnEdit(
unsigned int wid_unused,
const char *unused );
141static void sysedit_btnTagsClose(
unsigned int wid,
const char *unused );
144static void sysedit_spobGFX(
unsigned int wid_unused,
const char *wgt );
154static void sysedit_editAsteroidsClose(
unsigned int wid,
const char *unused );
155static void sysedit_genAsteroidsList(
unsigned int wid );
156static void sysedit_btnAsteroidsDelete(
unsigned int wid,
const char *unused );
157static void sysedit_btnRmAsteroid(
unsigned int wid,
const char *unused );
158static void sysedit_btnAddAsteroid(
unsigned int wid,
const char *unused );
160static void sysedit_editExclusion (
void);
161static void sysedit_editExclusionClose(
unsigned int wid,
const char *unused );
162static void sysedit_btnExclusionDelete(
unsigned int wid,
const char *unused );
164static int sysedit_keys(
unsigned int wid, SDL_Keycode key, SDL_Keymod mod,
int isrepeat );
181 const glColour cBG = { 0., 0., 0., 0.95 };
197 snprintf( buf,
sizeof(buf), _(
"%s - Star System Editor"), sys->name );
207 window_addCust( wid, 0, 0, SCREEN_W, SCREEN_H,
211 window_addRect( wid, SCREEN_W-130, 0, 130, SCREEN_H,
"rctRCol", &cBG, 0 );
212 window_addRect( wid, 0, 0, SCREEN_W, 60,
"rctBBar", &cBG, 0 );
220 window_addCheckbox( wid, -150, 25, SCREEN_W/2 - 150, 20,
221 "chkEditAutoSave", _(
"Automatically save changes"), uniedit_autosave, conf.
devautosave );
245 "btnRename", _(
"Rename"), sysedit_btnRename );
267 snprintf( buf,
sizeof(buf), _(
"Radius: %.0f"), sys->radius );
268 window_addText( wid, 140, 10, SCREEN_W/2-140, 30, 0,
278static int sysedit_keys(
unsigned int wid, SDL_Keycode key, SDL_Keymod mod,
int isrepeat )
323 uniedit_updateAutosave();
338 p->population = (uint64_t)strtoull( window_getInput(
sysedit_widEdit,
"inpPop" ), 0, 10);
346 p->class = strdup( inp );
351 if ((inp == NULL) || (strlen(inp) == 0))
354 p->lua_file = strdup( inp );
356 p->presence.base = atof(window_getInput(
sysedit_widEdit,
"inpPresenceBase" ));
357 p->presence.bonus = atof(window_getInput(
sysedit_widEdit,
"inpPresenceBonus" ));
358 p->presence.range = atoi(window_getInput(
sysedit_widEdit,
"inpPresenceRange" ));
391 name =
dialogue_inputRaw( _(
"New Spob Creation"), 1, 32, _(
"What do you want to name the new spob?") );
397 dialogue_alert( _(
"Space object by the name of #r'%s'#0 already exists in the #r'%s'#0 system"),
412 good = !((b->class==NULL) ||
413 (b->gfx_spacePath==NULL) || (b->gfx_spaceName==NULL) ||
414 (b->gfx_exterior==NULL) || (b->gfx_exteriorPath==NULL));
417 p->class = strdup( b->class );
418 p->gfx_spacePath = strdup( b->gfx_spacePath );
419 p->gfx_spaceName = strdup( b->gfx_spaceName );
420 p->gfx_exterior = strdup( b->gfx_exterior );
421 p->gfx_exteriorPath = strdup( b->gfx_exteriorPath );
424 p->hide = HIDE_DEFAULT_SPOB;
425 p->radius = b->radius;
451 const char *title, *caption;
453 const char *opts[] = {
459 title = _(
"Add asteriod field or exclusion zone?");
460 caption = _(
"Do you wish to add an asteroid field or an asteroid exclusion zone that will remove all asteroids that will appear in it?");
466 ret = strdup(opts[0]);
468 if (strcmp(ret, opts[0])==0) {
471 ast->
density = ASTEROID_DEFAULT_DENSITY;
475 ast->
maxspeed = ASTEROID_DEFAULT_MAXSPEED;
476 ast->
accel = ASTEROID_DEFAULT_ACCEL;
496static void sysedit_btnRename(
unsigned int wid_unused,
const char *unused )
505 char *name, *oldName, *newName, *filtered;
510 _(
"What do you want to rename the spob #r%s#0?"), p->name );
516 dialogue_alert( _(
"Space object by the name of #r'%s'#0 already exists in the #r'%s'#0 system"),
523 filtered = uniedit_nameFilter(p->name);
524 SDL_asprintf(&oldName,
"%s/%s.xml", conf.
dev_save_spob, filtered);
527 filtered = uniedit_nameFilter(name);
528 SDL_asprintf(&newName,
"%s/%s.xml", conf.
dev_save_spob, filtered);
531 if (rename(oldName, newName))
532 WARN(_(
"Failed to rename '%s' to '%s'!"),oldName,newName);
557 char *file, *filtered;
559 if (
dialogue_YesNo( _(
"Remove selected objects (excluding jumps)?"), _(
"This can not be undone.") )) {
564 filtered = uniedit_nameFilter( sp->
name );
565 SDL_asprintf(&file,
"%s/%s.xml", conf.
dev_save_spob, filtered);
601 sysedit_sys[i].jumps[ sel->
u.jump ].flags |= JP_AUTOPOS;
620 str =
dialogue_inputRaw( _(
"Scale Star System"), 1, 32, _(
"By how much do you want to scale the star system?") );
629 if ((s < 0.1) || (s > 10.)) {
630 int i =
dialogue_YesNo( _(
"Scale Star System"), _(
"Are you sure you want to scale the star system by %.2f (from %.2f to %.2f)?"),
631 s, sys->radius, sys->radius*s );
647 sys->radius *= factor;
648 snprintf( buf,
sizeof(buf), _(
"Radius: %.0f"), sys->radius );
650 window_modifyText(
sysedit_wid,
"txtSelected", buf );
653 for (
int i=0; i<
array_size(sys->spobs); i++) {
654 Spob *p = sys->spobs[i];
655 vec2_cset( &p->pos, p->pos.x*factor, p->pos.y*factor );
659 for (
int i=0; i<
array_size(sys->jumps); i++) {
660 JumpPoint *jp = &sys->jumps[i];
661 vec2_cset( &jp->pos, jp->pos.x*factor, jp->pos.y*factor );
665 for (
int i=0; i<
array_size(sys->asteroids); i++) {
667 vec2_cset( &ast->
pos, ast->
pos.
x*factor, ast->
pos.
y*factor );
670 for (
int i=0; i<
array_size(sys->astexclude); i++) {
672 vec2_cset( &exc->
pos, exc->
pos.
x*factor, exc->
pos.
y*factor );
694static void sysedit_render(
double bx,
double by,
double w,
double h,
void *data )
712 for (
int i=0; i<
array_size(sys->spobs); i++) {
713 Spob *p = sys->spobs[i];
720 if (p->gfx_space != NULL)
725 for (
int i=0; i<
array_size(sys->jumps); i++) {
727 JumpPoint *jp = &sys->jumps[i];
735 c = (jp->flags & JP_AUTOPOS) ? &cGreen : NULL;
739 jp->
sx, jp->sy,
c, selected, jp->target->name );
743 for (
int i=0; i<
array_size(sys->asteroids); i++) {
754 for (
int i=0; i<
array_size(sys->astexclude); i++) {
773 for (
int j=0; j<2; j++) {
775 case SAFELANE_LOC_SPOB:
777 posns[j] = &pnt->
pos;
779 case SAFELANE_LOC_DEST_SYS:
781 posns[j] = &njp->pos;
784 ERR( _(
"Invalid vertex type.") );
792 double x1, y1, x2, y2, ry, rx, r, rw, rh;
793 x1 = x + posns[0]->
x * z;
794 y1 = y + posns[0]->
y * z;
795 x2 = x + posns[1]->
x * z;
796 y2 = y + posns[1]->
y * z;
804 glUseProgram(shaders.safelane.program);
805 gl_renderShader( (x1+x2)/2., (y1+y2)/2., rw, rh, r, &shaders.safelane, &col, 1 );
811 &cWhite,
"% 9.2f x % 9.2f",
828 tx = bx + ast->
pos.
x*z;
829 ty = by + ast->
pos.
y*z;
832 const glColour csel = COL_ALPHA( cFontBlue, 0.5 );
839 (selected) ? &cRed : NULL, -1., _(
"Asteroid Field") );
848 double tx, ty, z, r, rr;
855 tx = bx + aexcl->
pos.
x*z;
856 ty = by + aexcl->
pos.
y*z;
858 rr = r * sin(M_PI / 4.);
861 const glColour csel = COL_ALPHA( cFontBlue, 0.5 );
865 col = (selected) ? &cWhite : &cRed;
875static void sysedit_renderBG(
double bx,
double by,
double w,
double h,
double x,
double y )
879 const double s = 1000.;
882 double startx, starty, spacing;
898 startx = bx + fmod( x - bx, spacing );
899 starty = by + fmod( y - by, spacing );
901 nx = lround( w / spacing );
902 ny = lround( h / spacing );
905 for (
int i=0; i<nx; i++) {
906 double d = startx + (i * spacing);
910 for (
int i=0; i<ny; i++) {
911 double d = starty + (i * spacing);
922 int sx,
int sy,
const glColour *
c,
int selected,
const char *caption )
932 const glColour csel = COL_ALPHA( cFontBlue, 0.5 );
937 tx = bx + (x - gfx->
sw/2.)*z;
938 ty = by + (y - gfx->
sh/2.)*z;
943 if (caption != NULL) {
963static int sysedit_mouseTrySelect(
const Select_t *sel,
double x,
double y,
double t,
double mx,
double my, SDL_Keymod mod,
void (*func)(
void) )
980 if (mod & (KMOD_LCTRL | KMOD_RCTRL))
999 if (mod & (KMOD_LCTRL | KMOD_RCTRL))
1017static int sysedit_mouse(
unsigned int wid,
const SDL_Event* event,
double mx,
double my,
1018 double w,
double h,
double xr,
double yr,
void *data )
1022 SDL_Keymod mod = SDL_GetModState();
1024 switch (event->type) {
1026 case SDL_MOUSEWHEEL:
1028 if ((mx < 0.) || (mx > w) || (my < 0.) || (my > h))
1031 if (event->wheel.y > 0)
1033 else if (event->wheel.y < 0)
1038 case SDL_MOUSEBUTTONDOWN:
1040 if ((mx < 0.) || (mx > w) || (my < 0.) || (my > h))
1049 for (
int i=0; i<
array_size(sys->spobs); i++) {
1050 Spob *p = sys->spobs[i];
1057 double t =
pow2(p->radius);
1061 if (sysedit_mouseTrySelect( &sel, p->pos.x, p->pos.y, t, mx, my, mod,
sysedit_editPnt ))
1066 for (
int i=0; i<
array_size(sys->jumps); i++) {
1067 JumpPoint *jp = &sys->jumps[i];
1078 if (sysedit_mouseTrySelect( &sel, jp->pos.x, jp->pos.y, t, mx, my, mod,
sysedit_editJump ))
1083 for (
int i=0; i<
array_size(sys->astexclude); i++) {
1092 if (sysedit_mouseTrySelect( &sel, exc->
pos.
x, exc->
pos.
y, t, mx, my, mod, sysedit_editExclusion ))
1097 for (
int i=0; i<
array_size(sys->asteroids); i++) {
1111 if (!(mod & (KMOD_LCTRL | KMOD_RCTRL))) {
1119 case SDL_MOUSEBUTTONUP:
1158 case SDL_MOUSEMOTION:
1184 switch (sel->
type) {
1186 p = sys->spobs[ sel->
u.spob ];
1192 jp = &sys->jumps[ sel->
u.jump ];
1193 jp->flags &= ~(JP_AUTOPOS);
1200 ast->
pos.
x += xmove;
1201 ast->
pos.
y += ymove;
1205 exc = &sys->astexclude[ sel->
u.astexclude ];
1206 exc->
pos.
x += xmove;
1207 exc->
pos.
y += ymove;
1237 if (strcmp(str,
"btnZoomIn")==0) {
1241 else if (strcmp(str,
"btnZoomOut")==0) {
1271 int sel_spob, sel_jump, sel_asteroid, sel_exclusion;
1280 switch (sel->
type) {
1297 if (sel_spob || sel_asteroid || sel_exclusion)
1356 WARN(_(
"Trying to deselect item that is not in selection!"));
1366 return (memcmp(a, b,
sizeof(
Select_t)) == 0);
1387 char buf[STRMAX_SHORT], title[128];
1394 snprintf(title,
sizeof(title), _(
"Space Object Property Editor - %s"), p->name);
1404 snprintf( buf,
sizeof(buf),
"%s ", _(
"Name:") );
1406 window_addText( wid, 20, y, 180, 15, 0,
"txtNameLabel", &
gl_smallFont, NULL, buf );
1407 snprintf( buf,
sizeof(buf),
"%s", p->name );
1408 window_addText( wid, 20 + w, y, 180, 15, 0,
"txtName", &
gl_smallFont, NULL, buf );
1410 _(
"Rename"), sysedit_btnRename );
1416 snprintf( buf,
sizeof(buf),
"%s ", _(
"Faction:") );
1418 window_addText( wid, 20, y, 180, 15, 0,
"txtFactionLabel", &
gl_smallFont, NULL, buf );
1419 snprintf( buf,
sizeof(buf),
"%s", p->presence.faction >= 0 ?
faction_name( p->presence.faction ) : _(
"None") );
1420 window_addText( wid, 20 + w, y, 180, 15, 0,
"txtFaction", &
gl_smallFont, NULL, buf );
1425 s = _(
"Population");
1427 window_addText( wid, x, y, l, 20, 1,
"txtPop",
1429 window_addInput( wid, x += l + 5, y, 80, 20,
"inpPop", 12, 1, NULL );
1430 window_setInputFilter( wid,
"inpPop", INPUT_FILTER_NUMBER );
1435 window_addText( wid, x, y, l, 20, 1,
"txtClass",
1437 window_addInput( wid, x += l + 5, y, 30, 20,
"inpClass", 1, 1, NULL );
1442 window_addText( wid, x, y, l, 20, 1,
"txtLua",
1444 window_addInput( wid, x += l + 5, y, 150, 20,
"inpLua", 20, 1, NULL );
1449 s = _(
"Base Presence");
1451 window_addText( wid, x, y, l, 20, 1,
"txtPresenceBase",
1453 window_addInput( wid, x += l + 5, y, 50, 20,
"inpPresenceBase", 5, 1, NULL );
1454 window_setInputFilter( wid,
"inpPresenceBase", INPUT_FILTER_NUMBER );
1457 s = _(
"Bonus Presence");
1459 window_addText( wid, x, y, l, 20, 1,
"txtPresenceBonus",
1461 window_addInput( wid, x += l + 5, y, 50, 20,
"inpPresenceBonus", 5, 1, NULL );
1462 window_setInputFilter( wid,
"inpPresenceBonus", INPUT_FILTER_NUMBER );
1465 s = p_(
"sysedit",
"Range");
1467 window_addText( wid, x, y, l, 20, 1,
"txtPresenceRange",
1469 window_addInput( wid, x += l + 5, y, 30, 20,
"inpPresenceRange", 1, 1, NULL );
1470 window_setInputFilter( wid,
"inpPresenceRange", INPUT_FILTER_NUMBER );
1477 window_addText( wid, x, y, l, 20, 1,
"txtHide",
1479 window_addInput( wid, x += l + 5, y, 50, 20,
"inpHide", 4, 1, NULL );
1480 window_setInputFilter( wid,
"inpHide", INPUT_FILTER_NUMBER );
1486 l =
scnprintf( buf,
sizeof(buf),
"#n%s#0", _(
"Tags:") );
1488 l +=
scnprintf( &buf[l],
sizeof(buf)-l,
"%s %s", ((i>0) ?
"," :
""), p->tags[i] );
1489 window_addText( wid, x, y, 300, 20, 0,
"txtTags", NULL, NULL, buf );
1500 window_addButton( wid, -20 - bw*3 - 15*3, 20, bw,
BUTTON_HEIGHT,
1502 window_addButton( wid, -20 - bw*2 - 15*2, 20, bw,
BUTTON_HEIGHT,
1504 window_addButton( wid, -20 - bw - 15, 20, bw,
BUTTON_HEIGHT,
1510 snprintf( buf,
sizeof(buf),
"%"PRIu64, p->population );
1511 window_setInput( wid,
"inpPop", buf );
1512 snprintf( buf,
sizeof(buf),
"%s", p->class );
1513 window_setInput( wid,
"inpClass", buf );
1514 window_setInput( wid,
"inpLua", p->lua_file );
1515 snprintf( buf,
sizeof(buf),
"%g", p->presence.base );
1516 window_setInput( wid,
"inpPresenceBase", buf );
1517 snprintf( buf,
sizeof(buf),
"%g", p->presence.bonus );
1518 window_setInput( wid,
"inpPresenceBonus", buf );
1519 snprintf( buf,
sizeof(buf),
"%d", p->presence.range );
1520 window_setInput( wid,
"inpPresenceRange", buf );
1521 snprintf( buf,
sizeof(buf),
"%g", p->hide );
1522 window_setInput( wid,
"inpHide", buf );
1540 window_checkboxSet( wid,
"chkHidden",
jp_hidden );
1541 window_checkboxSet( wid,
"chkExit",
jp_exit );
1556 window_checkboxSet( wid,
"chkHidden",
jp_hidden );
1557 window_checkboxSet( wid,
"chkExit",
jp_exit );
1565 int s = window_checkboxState( wid, str );
1568 jp_setFlag( j, JP_NOLANES );
1570 jp_rmFlag( j, JP_NOLANES );
1580 char buf[STRMAX_SHORT];
1592 snprintf( buf,
sizeof(buf), _(
"Target: ") );
1594 window_addText( wid, 20, y, 180, 15, 0,
"txtTargetLabel", &
gl_smallFont, NULL, buf );
1595 snprintf( buf,
sizeof(buf),
"%s", j->target->name );
1596 window_addText( wid, 20 + w, y, 180, 15, 0,
"txtName", &
gl_smallFont, NULL, buf );
1606 if (jp_isFlag( j, JP_HIDDEN ))
1608 else if (jp_isFlag( j, JP_EXITONLY ))
1611 window_addCheckbox( wid, x, y, 100, 20,
1614 window_addCheckbox( wid, x, y, 100, 20,
1617 window_addCheckbox( wid, x, y, 100, 20,
1623 window_addText( wid, x, y, l, 20, 1,
"txtHide",
1625 window_addInput( wid, x + l + 8, y, 50, 20,
"inpHide", 4, 1, NULL );
1626 window_setInputFilter( wid,
"inpHide", INPUT_FILTER_NUMBER );
1634 snprintf( buf,
sizeof(buf),
"%g", j->hide );
1635 window_setInput( wid,
"inpHide", buf );
1646 jp_setFlag( j, JP_HIDDEN );
1647 jp_rmFlag( j, JP_EXITONLY );
1650 jp_setFlag( j, JP_EXITONLY );
1651 jp_rmFlag( j, JP_HIDDEN );
1654 jp_rmFlag( j, JP_HIDDEN );
1655 jp_rmFlag( j, JP_EXITONLY );
1669 char buf[STRMAX_SHORT];
1685 window_addText( wid, x, y, l, 20, 1,
"txtDensity", NULL, NULL, s );
1686 window_addInput( wid, x + l + 8, y, 80, 20,
"inpDensity", 10, 1, NULL );
1687 window_setInputFilter( wid,
"inpDensity", INPUT_FILTER_NUMBER );
1691 window_addText( wid, x, y, l, 20, 1,
"txtInput", NULL, NULL, s );
1692 window_addInput( wid, x + l + 8, y, 80, 20,
"inpRadius", 10, 1, NULL );
1693 window_setInputFilter( wid,
"inpRadius", INPUT_FILTER_NUMBER );
1696 s = _(
"Max Speed: ");
1698 window_addText( wid, x, y, l, 20, 1,
"txtMaxspeed", NULL, NULL, s );
1699 window_addInput( wid, x + l + 8, y, 80, 20,
"inpMaxspeed", 10, 1, NULL );
1700 window_setInputFilter( wid,
"inpMaxspeed", INPUT_FILTER_NUMBER );
1704 window_addText( wid, x, y, l, 20, 1,
"txtAccel", NULL, NULL, s );
1705 window_addInput( wid, x + l + 8, y, 80, 20,
"inpAccel", 10, 1, NULL );
1706 window_setInputFilter( wid,
"inpAccel", INPUT_FILTER_NUMBER );
1709 sysedit_genAsteroidsList( wid );
1716 1,
"txtAsteroidsHave", NULL, NULL, _(
"Asteroids") );
1718 1,
"txtAsteroidsAvailable", NULL, NULL, _(
"Available") );
1722 "btnRmAsteroid", _(
"Rm Asteroid"), sysedit_btnRmAsteroid );
1724 "btnAddAsteroid", _(
"Add Asteroid"), sysedit_btnAddAsteroid );
1725 window_addButton( wid, 20 + 2*(bw + 15), 20, bw,
BUTTON_HEIGHT,
1726 "btnDelete", _(
"Delete"), sysedit_btnAsteroidsDelete );
1728 "btnClose", _(
"Close"), sysedit_editAsteroidsClose );
1731 snprintf( buf,
sizeof(buf),
"%g", ast->
density );
1732 window_setInput( wid,
"inpDensity", buf );
1733 snprintf( buf,
sizeof(buf),
"%g", ast->
radius );
1734 window_setInput( wid,
"inpRadius", buf );
1735 snprintf( buf,
sizeof(buf),
"%g", ast->
maxspeed );
1736 window_setInput( wid,
"inpMaxspeed", buf );
1737 snprintf( buf,
sizeof(buf),
"%g", ast->
accel );
1738 window_setInput( wid,
"inpAccel", buf );
1741static void sysedit_genAsteroidsList(
unsigned int wid )
1743 int hpos, apos, nhave, navail;
1747 char **have, **available;
1752 hpos = toolkit_getListPos( wid,
"lstAsteroidsHave" );
1753 apos = toolkit_getListPos( wid,
"lstAsteroidsAvailable" );
1767 have = malloc(
sizeof(
char*) * nhave );
1768 for (
int i=0; i<nhave; i++)
1773 window_addList( wid, x, y, w, h,
"lstAsteroidsHave", have, nhave, 0, NULL, sysedit_btnRmAsteroid );
1780 available = malloc(
sizeof(
char*) * navail );
1781 for (
int i=0; i<navail; i++)
1782 available[i] = strdup( astgroups[i].name );
1783 qsort( available, navail,
sizeof(
char*),
strsort );
1787 window_addList( wid, x, y, w, h,
"lstAsteroidsAvailable", available, navail, 0, NULL, sysedit_btnAddAsteroid );
1790 if (hpos != -1 && apos != -1) {
1791 toolkit_setListPos( wid,
"lstAsteroidsHave", hpos );
1792 toolkit_setListPos( wid,
"lstAsteroidsAvailable", apos );
1796static void sysedit_btnRmAsteroid(
unsigned int wid,
const char *unused )
1799 int pos = toolkit_getListPos( wid,
"lstAsteroidsHave" );
1805 sysedit_genAsteroidsList( wid );
1808static void sysedit_btnAddAsteroid(
unsigned int wid,
const char *unused )
1811 const char *selected = toolkit_getList( wid,
"lstAsteroidsAvailable" );
1816 sysedit_genAsteroidsList( wid );
1819static void sysedit_btnAsteroidsDelete(
unsigned int wid,
const char *unused )
1821 int i =
dialogue_YesNo( _(
"Remove Asteroid Field"), _(
"Are you sure you want to remove this asteroid field?") );
1836static void sysedit_editAsteroidsClose(
unsigned int wid,
const char *unused )
1854static void sysedit_editExclusion (
void)
1858 char buf[STRMAX_SHORT];
1872 window_addText( wid, x, y, l, 20, 1,
"txtInput", NULL, NULL, s );
1873 window_addInput( wid, x + l + 8, y, 80, 20,
"inpRadius", 10, 1, NULL );
1874 window_setInputFilter( wid,
"inpRadius", INPUT_FILTER_NUMBER );
1878 window_addButton( wid, -20 - 15 - bw, 20, bw,
BUTTON_HEIGHT,
1879 "btnDelete", _(
"Delete"), sysedit_btnExclusionDelete );
1881 "btnClose", _(
"Close"), sysedit_editExclusionClose );
1884 snprintf( buf,
sizeof(buf),
"%g", exc->
radius );
1885 window_setInput( wid,
"inpRadius", buf );
1888static void sysedit_btnExclusionDelete(
unsigned int wid,
const char *unused )
1890 int i =
dialogue_YesNo( _(
"Remove Asteroid Exclusion Zone"), _(
"Are you sure you want to remove this asteroid exclusion zone?") );
1904static void sysedit_editExclusionClose(
unsigned int wid,
const char *unused )
1924 const char *desc, *bardesc;
1930 snprintf(title,
sizeof(title), _(
"Space Object Information - %s"), p->name);
1938 desc = p->description ? p->description : _(
"None");
1939 bardesc = p->bar_description ? p->bar_description : _(
"None");
1942 window_addButton( wid, -20 - bw*3 - 15*3, 20, bw,
BUTTON_HEIGHT,
1950 _(
"Landing Description") );
1952 window_addInput( wid, x, y, w, h,
"txtDescription", 1024, 0,
1954 window_setInputFilter( wid,
"txtDescription",
1958 window_setInput( wid,
"txtDescription", desc );
1962 _(
"Bar Description") );
1964 window_addInput( wid, x, y, w, h,
"txtBarDescription", 1024, 0,
1966 window_setInputFilter( wid,
"txtBarDescription",
1969 window_setInput( wid,
"txtBarDescription", bardesc );
1978 const char *mydesc, *mybardesc;
1982 mydesc = window_getInput( wid,
"txtDescription" );
1983 mybardesc = window_getInput( wid,
"txtBarDescription" );
1985 free(p->description);
1986 free(p->bar_description);
1987 p->description = NULL;
1988 p->bar_description = NULL;
1991 p->description = strdup( mydesc );
1992 if (mybardesc != NULL)
1993 p->bar_description = strdup( mybardesc );
2012 int j, n, nservices;
2014 char **have, **lack;
2015 int x, y, w, h, hpos, lpos;
2022 hpos = toolkit_getListPos( wid,
"lstServicesHave" );
2023 lpos = toolkit_getListPos( wid,
"lstServicesLacked" );
2036 for (
int i=1; i<SPOB_SERVICES_MAX; i<<=1) {
2037 if (!spob_hasService(p, i) && (i != SPOB_SERVICE_INHABITED))
2044 have = malloc(
sizeof(
char*) *
MAX(nservices - n, 1) );
2046 have[j++] = strdup(_(
"None"));
2048 for (
int i=1; i<SPOB_SERVICES_MAX; i<<=1)
2049 if (spob_hasService(p, i) && (i != SPOB_SERVICE_INHABITED))
2053 window_addList( wid, x, y, w, h,
"lstServicesHave", have, j, 0, NULL,
sysedit_btnRmService );
2058 lack = malloc(
sizeof(
char*) *
MAX(1, n) );
2060 lack[j++] = strdup( _(
"None") );
2062 for (
int i=1; i<SPOB_SERVICES_MAX; i<<=1)
2063 if (!spob_hasService(p, i) && (i != SPOB_SERVICE_INHABITED))
2067 window_addList( wid, x, y, w, h,
"lstServicesLacked", lack, j, 0, NULL,
sysedit_btnAddService );
2070 if (hpos != -1 && lpos != -1) {
2071 toolkit_setListPos( wid,
"lstServicesHave", hpos );
2072 toolkit_setListPos( wid,
"lstServicesLacked", lpos );
2082 const char *selected;
2085 selected = toolkit_getList( wid,
"lstServicesLacked" );
2086 if ((selected == NULL) || (strcmp(selected,_(
"None"))==0))
2091 p->services |=
spob_getService(selected) | SPOB_SERVICE_INHABITED | SPOB_SERVICE_LAND;
2103 const char *selected;
2106 selected = toolkit_getList( wid,
"lstServicesHave" );
2107 if ((selected==NULL) || (strcmp(selected,_(
"None"))==0))
2115 if (strcmp(selected,
"Land")==0)
2158 char **have, **lack;
2159 int j, n, x, y, w, h, hpos, lpos;
2166 hpos = toolkit_getListPos( wid,
"lstTechsHave" );
2167 lpos = toolkit_getListPos( wid,
"lstTechsLacked" );
2180 if (p->tech != NULL)
2183 have = malloc(
sizeof(
char*) );
2184 have[n++] = strdup(_(
"None"));
2188 window_addList( wid, x, y, w, h,
"lstTechsHave", have, n, 0, NULL,
sysedit_btnRmTech );
2193 if (p->tech != NULL) {
2195 for (
int i=0; i<j; i++)
2200 lack = malloc(
sizeof(
char*) );
2201 lack[n++] = strdup(_(
"None"));
2204 lack = malloc(
sizeof(
char*) * j );
2206 for (
int i=0; i<j; i++)
2208 lack[n++] = strdup( tmp[i] );
2212 for (
int i=0; i<j; i++)
2221 window_addList( wid, x, y, w, h,
"lstTechsLacked", lack, n, 0, NULL,
sysedit_btnAddTech );
2224 if (hpos != -1 && lpos != -1) {
2225 toolkit_setListPos( wid,
"lstTechsHave", hpos );
2226 toolkit_setListPos( wid,
"lstTechsLacked", lpos );
2236 const char *selected;
2239 selected = toolkit_getList( wid,
"lstTechsLacked" );
2240 if ((selected == NULL) || (strcmp(selected,_(
"None"))==0))
2244 if (p->tech == NULL)
2258 const char *selected;
2262 selected = toolkit_getList( wid,
"lstTechsHave" );
2263 if ((selected == NULL) || (strcmp(selected,_(
"None"))==0))
2296 "btnClose", _(
"Close"), sysedit_btnTagsClose );
2316 Spob *s = &spob_all[i];
2318 char *t = s->
tags[j];
2338static void sysedit_btnTagsClose(
unsigned int wid,
const char *unused )
2340 char buf[STRMAX_SHORT];
2342 int l =
scnprintf( buf,
sizeof(buf),
"#n%s#0", _(
"Tags:") );
2344 l +=
scnprintf( &buf[l],
sizeof(buf)-l,
"%s %s", ((i>0) ?
"," :
""), p->tags[i] );
2356 char **have, **lack;
2357 int n, x, y, w, h, hpos, lpos, empty;
2364 hpos = toolkit_getListPos( wid,
"lstTagsHave" );
2365 lpos = toolkit_getListPos( wid,
"lstTagsLacked" );
2379 have = malloc( n *
sizeof(
char*) );
2380 for (
int i=0; i<n; i++)
2381 have[i] = strdup(p->tags[i]);
2385 have = malloc(
sizeof(
char*) );
2386 have[n++] = strdup(_(
"None"));
2391 window_addList( wid, x, y, w, h,
"lstTagsHave", have, n, 0, NULL,
sysedit_btnRmTag );
2400 lack[n++] = strdup(t);
2404 if (strcmp( p->tags[j], t )==0) {
2409 lack[n++] = strdup( t );
2414 window_addList( wid, x, y, w, h,
"lstTagsLacked", lack, n, 0, NULL,
sysedit_btnAddTag );
2417 if (hpos != -1 && lpos != -1) {
2418 toolkit_setListPos( wid,
"lstTagsHave", hpos );
2419 toolkit_setListPos( wid,
"lstTagsLacked", lpos );
2429 const char *selected;
2432 selected = toolkit_getList( wid,
"lstTagsLacked" );
2433 if ((selected == NULL) || (strcmp(selected,_(
"None"))==0))
2437 if (p->tags == NULL)
2451 const char *selected;
2455 selected = toolkit_getList( wid,
"lstTagsHave" );
2456 if ((selected == NULL) || (strcmp(selected,_(
"None"))==0))
2462 if (strcmp( selected, p->tags[i] )==0)
2467 array_erase( &p->tags, &p->tags[i], &p->tags[i+1] );
2481 char *tag =
dialogue_input( _(
"Add New Spob Tag"), 1, 128, _(
"Please write the new tag to add to the spob.") );
2486 if (s->
tags == NULL)
2505 int pos, j, y, h, bw, *factions;
2518 str = malloc(
sizeof(
char*) * (
array_size(factions) + 1) );
2519 str[0] = strdup(_(
"None"));
2523 qsort( &str[1], j-1,
sizeof(
char*),
strsort );
2526 if (p->presence.faction >= 0) {
2529 for (
int i=0; i<j; i++)
2530 if (strcmp(s,str[i])==0)
2559 const char *selected;
2562 selected = toolkit_getList( wid,
"lstFactions" );
2563 if (selected == NULL)
2568 if (toolkit_getListPos( wid,
"lstFactions")==0) {
2569 p->presence.faction = -1;
2597 sysedit_editExclusion();
2608 char *path, buf[STRMAX_SHORT];
2611 ImageArrayCell *cells;
2616 land = (strcmp(wgt,
"btnLandGFX") == 0);
2620 snprintf( buf,
sizeof(buf), _(
"%s - Space Object Properties"), p->name );
2636 path =
land ? SPOB_GFX_EXTERIOR_PATH : SPOB_GFX_SPACE_PATH;
2637 files = PHYSFS_enumerateFiles( path );
2638 for (nfiles=0; files[nfiles]; nfiles++) {}
2639 cells = calloc( nfiles,
sizeof(ImageArrayCell) );
2642 for (
size_t i=0; i<nfiles; i++) {
2643 PHYSFS_Stat path_stat;
2644 const char *filepath;
2645 snprintf( buf,
sizeof(buf),
"%s/%s", path, files[i] );
2647 if (!PHYSFS_stat( buf, &path_stat )) {
2648 WARN(_(
"Unable to check file type for '%s'!"), buf);
2651 if (path_stat.filetype != PHYSFS_FILETYPE_REGULAR)
2658 cells[j].caption = strdup( files[i] );
2659 filepath = (
land ? p->gfx_exteriorPath : p->gfx_spacePath);
2660 c = ((filepath==NULL) || strcmp(files[i], filepath)!=0) ? cBlack : cOrange;
2661 memcpy( &cells[j].bg, &
c,
sizeof(glColour) );
2664 PHYSFS_freeList( files );
2667 window_addImageArray( wid, 20, 20, w-60-
BUTTON_WIDTH, h-60,
"iarGFX", 128, 128, cells, j, NULL, NULL, NULL );
2668 toolkit_setImageArray( wid,
"iarGFX", path );
2689 land = (strcmp(wgt,
"btnApplyLand") == 0);
2693 str = toolkit_getImageArray( wid,
"iarGFX" );
2698 path =
land ? SPOB_GFX_EXTERIOR_PATH : SPOB_GFX_SPACE_PATH;
2699 snprintf( buf,
sizeof(buf),
"%s/%s", path, str );
2702 free( p->gfx_exteriorPath );
2703 free( p->gfx_exterior );
2704 snprintf( buf,
sizeof(buf), SPOB_GFX_EXTERIOR_PATH
"%s", str );
2705 p->gfx_exteriorPath = strdup( str );
2706 p->gfx_exterior = strdup( buf );
2709 free( p->gfx_spaceName );
2710 free( p->gfx_spacePath );
2711 p->gfx_spaceName = strdup( buf );
2712 p->gfx_spacePath = strdup( str );
2714 p->gfx_space = NULL;
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
void asteroids_computeInternals(AsteroidAnchor *a)
Updates internal alues of an asteroid field.
const AsteroidTypeGroup * astgroup_getAll(void)
Gets all the asteroid type groups.
void asteroid_free(AsteroidAnchor *ast)
Frees an asteroid anchor.
AsteroidTypeGroup * astgroup_getName(const char *name)
Gets an asteroid type group by name.
int dpl_saveSpob(const Spob *p)
Saves a spob.
static Select_t sysedit_tsel
static void jp_type_check_nolanes_update(unsigned int wid, const char *str)
Updates the jump point checkboxes.
#define SYSEDIT_ZOOM_STEP
static void sysedit_btnGFXApply(unsigned int wid, const char *wgt)
Apply new graphics.
static double sysedit_xpos
static int sysedit_nselect
static unsigned int sysedit_wid
static void jp_type_check_exit_update(unsigned int wid, const char *str)
Updates the jump point checkboxes.
static void sysedit_close(unsigned int wid, const char *wgt)
Closes the system editor widget.
static void sysedit_editPntClose(unsigned int wid, const char *unused)
Closes the spob editor, saving the changes made.
static void sysedit_buttonZoom(unsigned int wid, const char *str)
Handles the button zoom clicks.
static void sysedit_selectAdd(const Select_t *sel)
Adds a system to the selection.
static void sysedit_focusLose(unsigned int wid, const char *wgtname)
Called when it's de-focused.
static void sysedit_btnGrid(unsigned int wid_unused, const char *unused)
Toggles the grid.
static void sysedit_btnNewSpob(unsigned int wid_unused, const char *unused)
Enters the editor in new spob mode.
static int sysedit_selectCmp(const Select_t *a, const Select_t *b)
Compares two selections to see if they are the same.
#define SYSEDIT_EDIT_WIDTH
static void sysedit_btnReset(unsigned int wid_unused, const char *unused)
Resets jump points.
static int sysedit_keys(unsigned int wid, SDL_Keycode key, SDL_Keymod mod, int isrepeat)
Handles keybindings.
static void sysedit_render(double bx, double by, double w, double h, void *data)
System editor custom widget rendering.
static double sysedit_ypos
static int sysedit_isSelected(const Select_t *s)
Check to see if something is selected.
static void sysedit_renderAsteroidsField(double bx, double by, const AsteroidAnchor *ast, int selected)
Draws an asteroid field on the map.
static void sysedit_btnRmTag(unsigned int wid, const char *unused)
Removes a tech from a spob.
static unsigned int sysedit_widEdit
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.
static void sysedit_genTagsList(unsigned int wid)
Generates the spob tech list.
static void sysedit_btnAddService(unsigned int wid, const char *unused)
Adds a service to a spob.
static void sysedit_genTechList(unsigned int wid)
Generates the spob tech list.
static void sysedit_btnGFXClose(unsigned int wid, const char *wgt)
Closes the spob graphic editor.
static void sysedit_deselect(void)
Deselects everything.
static void sysedit_checkButtons(void)
Checks to see which buttons should be active and the likes.
static void sysedit_btnRmTech(unsigned int wid, const char *unused)
Removes a tech from a spob.
static double sysedit_zoom
static void sysedit_btnFaction(unsigned int wid_unused, const char *unused)
Edits a spob's faction.
static void sysedit_spobGFX(unsigned int wid_unused, const char *wgt)
Opens the spob landing or space graphic editor.
static void sysedit_editAsteroids(void)
Opens the asteroid editor.
static void sysedit_selectRm(Select_t *sel)
Removes a system from the selection.
static char ** sysedit_tagslist
static StarSystem * sysedit_sys
#define SYSEDIT_DRAG_THRESHOLD
static void sysedit_btnEdit(unsigned int wid_unused, const char *unused)
Opens the system property editor.
static void sysedit_btnNewTag(unsigned int wid, const char *unused)
Adds a tech to a spob.
#define SYSEDIT_MOVE_THRESHOLD
static void sysedit_renderAsteroidExclusion(double bx, double by, const AsteroidExclusion *aexcl, int selected)
Draws an asteroid exclusion zone on the map.
static void sysedit_spobDescClose(unsigned int wid, const char *unused)
Closes both the spob description window and the properties window.
static void sysedit_btnFactionSet(unsigned int wid, const char *unused)
Actually modifies the faction.
static unsigned int sysedit_dragTime
#define SYSEDIT_EDIT_HEIGHT
static void sysedit_spobDesc(unsigned int wid, const char *unused)
Displays the spob landing description and bar description in a separate window.
static void sysedit_editJumpClose(unsigned int wid, const char *unused)
Closes the jump editor, saving the changes made.
static void sysedit_btnScale(unsigned int wid_unused, const char *unused)
Interface for scaling a system from the system view.
static int sysedit_mselect
static void sysedit_genServicesList(unsigned int wid)
Generates the spob services list.
static void sysedit_btnRemove(unsigned int wid_unused, const char *unused)
Removes spobs.
void sysedit_open(StarSystem *sys)
Opens the system editor interface.
static void sysedit_btnRmService(unsigned int wid, const char *unused)
Removes a service from a spob.
static void sysedit_renderBG(double bx, double bw, double w, double h, double x, double y)
Renders the custom widget background.
static void sysedit_btnAddTag(unsigned int wid, const char *unused)
Adds a tech to a spob.
static void sysedit_btnTagsEdit(unsigned int wid, const char *unused)
Edits a spob's tags.
static void sysedit_editPnt(void)
Edits a spob.
static void sysedit_spobDescReturn(unsigned int wid, const char *unused)
Closes the spob description window and returns to the properties window.
static void sysedit_btnAddTech(unsigned int wid, const char *unused)
Adds a tech to a spob.
void sysedit_sysScale(StarSystem *sys, double factor)
Scales a system.
static int sysedit_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 void jp_type_check_hidden_update(unsigned int wid, const char *str)
Updates the jump point checkboxes.
static void sysedit_btnTechEdit(unsigned int wid, const char *unused)
Edits a spob's tech.
static int sysedit_dragSel
static void sysedit_btnNewAsteroids(unsigned int wid_unused, const char *unused)
Enters the editor in new spob mode.
static void sysedit_editJump(void)
Edits a jump.
static Select_t * sysedit_select
int dsys_saveSystem(StarSystem *sys)
Saves a star system.
void uniedit_selectText(void)
Sets the selected system text.
char * dialogue_runChoice(void)
Run the dialog and return the clicked string.
char * dialogue_inputRaw(const char *title, int min, int max, const char *msg)
Creates a dialogue that allows the player to write a message.
void dialogue_alert(const char *fmt,...)
Displays an alert popup with only an ok button and a message.
char * dialogue_input(const char *title, int min, int max, const char *fmt,...)
Creates a dialogue that allows the player to write a message.
void dialogue_addChoice(const char *caption, const char *msg, const char *opt)
Add a choice to the dialog.
void dialogue_makeChoice(const char *caption, const char *msg, int opts)
Create the choice dialog. Need to add choices with below method.
int dialogue_YesNo(const char *caption, const char *fmt,...)
Runs a dialogue with both yes and no options.
int economy_execQueued(void)
Calls economy_refresh if an economy update is queued.
const char * faction_name(int f)
Gets a factions "real" (internal) name.
const glColour * faction_colour(int f)
Gets the colour of the faction.
int * faction_getAll(void)
Returns all faction IDs in an array (array.h).
int faction_get(const char *name)
Gets a faction ID by name.
int gl_printWidthRaw(const glFont *ft_font, const char *text)
Gets the width that it would take to print some text.
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.
void gl_print(const glFont *ft_font, const double x, const double y, const glColour *c, const char *fmt,...)
Prints text on screen like printf.
void land(Spob *p, int load)
Opens up all the land dialogue stuff.
Header file with generic functions and naev-specifics.
int strsort(const void *p1, const void *p2)
Sort function for sorting strings with qsort().
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
void gl_renderShader(double x, double y, double w, double h, double r, const SimpleShader *shd, const glColour *c, int center)
Renders a simple shader.
void gl_renderRect(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
void gl_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.
void gl_freeTexture(glTexture *texture)
Frees a texture.
void safelanes_recalculate(void)
Update the safe lane locations in response to the universe changing (e.g., diff applied).
SafeLane * safelanes_get(int faction, int standing, const StarSystem *system)
Gets a set of safelanes for a faction and system.
void space_reconstructPresences(void)
Reset the presence of all systems.
int spob_exists(const char *spobname)
Check to see if a spob exists.
void systems_reconstructJumps(void)
Reconstructs the jumps.
Spob * spob_getAll(void)
Gets an array (array.h) of all spobs.
int spob_rename(Spob *p, char *newname)
Renames a spob.
int spob_getService(const char *name)
Converts name to spob service flag.
void system_setFaction(StarSystem *sys)
Sets the system faction based on the spobs it has.
Spob * spob_get(const char *spobname)
Gets a spob based on its name.
const char * space_getRndSpob(int landable, unsigned int services, int(*filter)(Spob *p))
Gets the name of a random spob.
StarSystem * system_getIndex(int id)
Get the system by its index.
JumpPoint * jump_getTarget(const StarSystem *target, const StarSystem *sys)
Less safe version of jump_get that works with pointers.
const char * spob_getSystem(const char *spobname)
Get the name of a system from a spobname.
void system_updateAsteroids(StarSystem *sys)
Updates some internal calculations about asteroids in a system.
int system_addSpob(StarSystem *sys, const char *spobname)
Adds a spob to a star system.
void spob_gfxLoad(Spob *spob)
Loads a spob's graphics (and radius).
Spob * spob_getIndex(int ind)
Gets spob by index.
const char * spob_getServiceName(int service)
Gets the (English) name for a service code.
Spob * spob_new(void)
Creates a new spob.
glTexture * jumppoint_gfx
void space_gfxLoad(StarSystem *sys)
Loads all the graphics for a star system.
int system_rmSpob(StarSystem *sys, const char *spobname)
Removes a spob from a star system.
Represents an asteroid field anchor.
AsteroidTypeGroup ** groups
Represents an asteroid exclusion zone.
Represents a group of asteroids.
Describes a safe lane, patrolled by a faction, within a system.
SafeLaneLocType point_type[2]
Selection generic for stuff in a system.
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Abstraction for rendering sprite sheets.
int tech_rmItemTech(tech_group_t *tech, const char *value)
Removes an item from a tech.
tech_group_t * tech_groupCreate(void)
Creates a tech group.
int tech_getItemCount(const tech_group_t *tech)
Gets the number of techs within a given group.
int tech_hasItem(const tech_group_t *tech, const char *item)
Checks whether a given tech group has the specified item.
int tech_addItemTech(tech_group_t *tech, const char *value)
Adds an item to a tech.
char ** tech_getItemNames(const tech_group_t *tech, int *n)
Gets the names of all techs within a given group.
char ** tech_getAllItemNames(int *n)
Gets the names of all techs.