naev 0.10.4
tech.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
11#include "naev.h"
14#include "tech.h"
15
16#include "conf.h"
17#include "array.h"
18#include "economy.h"
19#include "log.h"
20#include "ndata.h"
21#include "nxml.h"
22#include "outfit.h"
23#include "ship.h"
24
25#define XML_TECH_ID "Techs"
26#define XML_TECH_TAG "tech"
31typedef enum tech_item_type_e {
38
42typedef struct tech_item_s {
44 union {
45 void *ptr;
46 const Outfit *outfit;
47 const Ship *ship;
49 int grp;
50 const tech_group_t *grpptr;
51 } u;
53
58 char *name;
59 char *filename;
61};
62
63/*
64 * Group list.
65 */
66static tech_group_t *tech_groups = NULL;
67
68/*
69 * Prototypes.
70 */
71static void tech_createMetaGroup( tech_group_t *grp, tech_group_t **tech, int num );
72static void tech_freeGroup( tech_group_t *grp );
73static char* tech_getItemName( tech_item_t *item );
74/* Loading. */
75static tech_item_t *tech_itemGrow( tech_group_t *grp );
76static int tech_parseFile( tech_group_t *tech, const char *file );
77static int tech_parseFileData( tech_group_t *tech );
78static int tech_parseXMLData( tech_group_t *tech, xmlNodePtr parent );
79static int tech_addItemOutfit( tech_group_t *grp, const char* name );
80static int tech_addItemShip( tech_group_t *grp, const char* name );
81static int tech_addItemCommodity( tech_group_t *grp, const char* name );
82static int tech_getID( const char *name );
83static int tech_addItemGroupPointer( tech_group_t *grp, const tech_group_t *ptr );
84static int tech_addItemGroup( tech_group_t *grp, const char* name );
85/* Getting by tech. */
86static void** tech_addGroupItem( void **items, tech_item_type_t type, const tech_group_t *tech );
87
91int tech_load (void)
92{
93 int s;
94 Uint32 time = SDL_GetTicks();
95 char **tech_files = ndata_listRecursive( TECH_DATA_PATH );
96
97 /* Create the array. */
98 tech_groups = array_create( tech_group_t );
99
100 /* First pass create the groups - needed to reference them later. */
101 for (int i=0; i<array_size(tech_files); i++) {
102 tech_group_t tech;
103 int ret;
104
105 if (!ndata_matchExt( tech_files[i], "xml" ))
106 continue;
107
108 ret = tech_parseFile( &tech, tech_files[i] );
109 if (ret==0) {
110 tech.filename = strdup( tech_files[i] );
111 array_push_back( &tech_groups, tech );
112 }
113
114 free( tech_files[i] );
115 }
116 array_free( tech_files );
117 array_shrink( &tech_groups );
118
119 /* Now we load the data. */
120 s = array_size( tech_groups );
121 for (int i=0; i<s; i++)
122 tech_parseFileData( &tech_groups[i] );
123
124 /* Info. */
125 if (conf.devmode) {
126 time = SDL_GetTicks() - time;
127 DEBUG( n_( "Loaded %d tech group in %.3f s", "Loaded %d tech groups in %.3f s", s ), s, time/1000. );
128 }
129 else
130 DEBUG( n_( "Loaded %d tech group", "Loaded %d tech groups", s ), s );
131
132 return 0;
133}
134
138void tech_free (void)
139{
140 /* Free all individual techs. */
141 int s = array_size( tech_groups );
142 for (int i=0; i<s; i++)
143 tech_freeGroup( &tech_groups[i] );
144
145 /* Free the tech array. */
146 array_free( tech_groups );
147}
148
152static void tech_freeGroup( tech_group_t *grp )
153{
154 free(grp->name);
155 free(grp->filename);
156 array_free( grp->items );
157}
158
162tech_group_t *tech_groupCreateXML( xmlNodePtr node )
163{
164 /* Load data. */
165 tech_group_t *tech = tech_groupCreate();
166 tech_parseXMLData( tech, node );
167 return tech;
168}
169
173tech_group_t *tech_groupCreate( void )
174{
175 tech_group_t *tech = calloc( sizeof(tech_group_t), 1 );
176 return tech;
177}
178
182void tech_groupDestroy( tech_group_t *grp )
183{
184 if (grp == NULL)
185 return;
186
187 tech_freeGroup( grp );
188 free(grp);
189}
190
194static char* tech_getItemName( tech_item_t *item )
195{
196 /* Handle type. */
197 switch (item->type) {
198 case TECH_TYPE_OUTFIT:
199 return item->u.outfit->name;
200 case TECH_TYPE_SHIP:
201 return item->u.ship->name;
203 return item->u.comm->name;
204 case TECH_TYPE_GROUP:
205 return tech_groups[ item->u.grp ].name;
207 return item->u.grpptr->name;
208 }
209
210 return NULL;
211}
212
216int tech_groupWrite( xmlTextWriterPtr writer, tech_group_t *grp )
217{
218 int s;
219
220 /* Handle empty groups. */
221 if (grp == NULL)
222 return 0;
223
224 /* Node header. */
225 xmlw_startElem( writer, "tech" );
226
227 /* Save items. */
228 s = array_size( grp->items );
229 for (int i=0; i<s; i++)
230 xmlw_elem( writer, "item", "%s", tech_getItemName( &grp->items[i] ) );
231
232 xmlw_endElem( writer ); /* "tech" */
233
234 return 0;
235}
236
240static int tech_parseFile( tech_group_t *tech, const char *file )
241{
242 xmlNodePtr parent;
243 xmlDocPtr doc = xml_parsePhysFS( file );
244 if (doc == NULL)
245 return -1;
246
247 parent = doc->xmlChildrenNode; /* first faction node */
248 if (parent == NULL) {
249 ERR( _("Malformed '%s' file: does not contain elements"), file);
250 return -1;
251 }
252
253 /* Just in case. */
254 memset( tech, 0, sizeof(tech_group_t) );
255
256 /* Get name. */
257 xmlr_attr_strd( parent, "name", tech->name );
258 if (tech->name == NULL) {
259 WARN(_("tech node does not have 'name' attribute"));
260 return 1;
261 }
262
263 xmlFreeDoc(doc);
264
265 return 0;
266}
267
271static int tech_parseXMLData( tech_group_t *tech, xmlNodePtr parent )
272{
273 /* Parse the data. */
274 xmlNodePtr node = parent->xmlChildrenNode;
275 do {
276 xml_onlyNodes(node);
277 if (xml_isNode(node,"item")) {
278 char *buf, *name;
279
280 /* Must have name. */
281 name = xml_get( node );
282 if (name == NULL) {
283 WARN(_("Tech group '%s' has an item without a value."), tech->name);
284 continue;
285 }
286
287 /* Try to find hard-coded type. */
288 xmlr_attr_strd( node, "type", buf );
289 if (buf == NULL) {
290 int ret = 1;
291 if (ret)
292 ret = tech_addItemGroup( tech, name );
293 if (ret)
294 ret = tech_addItemOutfit( tech, name );
295 if (ret)
296 ret = tech_addItemShip( tech, name );
297 if (ret)
298 ret = tech_addItemCommodity( tech, name );
299 if (ret)
300 WARN(_("Generic item '%s' not found in tech group '%s'"),
301 name, tech->name );
302 }
303 else if (strcmp(buf,"group")==0) {
304 if (!tech_addItemGroup( tech, name ))
305 WARN(_("Group item '%s' not found in tech group '%s'."),
306 name, tech->name );
307 }
308 else if (strcmp(buf,"outfit")==0) {
309 if (!tech_addItemGroup( tech, name ))
310 WARN(_("Outfit item '%s' not found in tech group '%s'."),
311 name, tech->name );
312 }
313 else if (strcmp(buf,"ship")==0) {
314 if (!tech_addItemGroup( tech, name ))
315 WARN(_("Ship item '%s' not found in tech group '%s'."),
316 name, tech->name );
317 }
318 else if (strcmp(buf,"commodity")==0) {
319 if (!tech_addItemGroup( tech, name ))
320 WARN(_("Commodity item '%s' not found in tech group '%s'."),
321 name, tech->name );
322 }
323 free( buf );
324 continue;
325 }
326 WARN(_("Tech group '%s' has unknown node '%s'."), tech->name, node->name);
327 } while (xml_nextNode( node ));
328
329 return 0;
330}
331
335static int tech_parseFileData( tech_group_t *tech )
336{
337 xmlNodePtr parent;
338 const char *file = tech->filename;
339 xmlDocPtr doc = xml_parsePhysFS( file );
340 if (doc == NULL)
341 return -1;
342
343 parent = doc->xmlChildrenNode; /* first faction node */
344 if (parent == NULL) {
345 ERR( _("Malformed '%s' file: does not contain elements"), file);
346 return -1;
347 }
348
349 /* Parse the data. */
350 tech_parseXMLData( tech, parent );
351
352 xmlFreeDoc(doc);
353
354 return 0;
355}
356
360static tech_item_t *tech_itemGrow( tech_group_t *grp )
361{
362 if (grp->items == NULL)
363 grp->items = array_create( tech_item_t );
364 return &array_grow( &grp->items );
365}
366
367static int tech_addItemOutfit( tech_group_t *grp, const char *name )
368{
369 tech_item_t *item;
370 const Outfit *o;
371
372 /* Get the outfit. */
373 o = outfit_getW( name );
374 if (o==NULL)
375 return 1;
376
377 /* Load the new item. */
378 item = tech_itemGrow( grp );
379 item->type = TECH_TYPE_OUTFIT;
380 item->u.outfit = o;
381 return 0;
382}
383
389static int tech_addItemShip( tech_group_t *grp, const char* name )
390{
391 tech_item_t *item;
392 const Ship *s;
393
394 /* Get the outfit. */
395 s = ship_getW( name );
396 if (s==NULL)
397 return 1;
398
399 /* Load the new item. */
400 item = tech_itemGrow( grp );
401 item->type = TECH_TYPE_SHIP;
402 item->u.ship = s;
403 return 0;
404}
405
411static int tech_addItemCommodity( tech_group_t *grp, const char* name )
412{
413 tech_item_t *item;
414 Commodity *c;
415
416 /* Get the outfit. */
417 c = commodity_getW( name );
418 if (c==NULL)
419 return 1;
420
421 /* Load the new item. */
422 item = tech_itemGrow( grp );
424 item->u.comm = c;
425 return 0;
426}
427
431int tech_addItem( const char *name, const char *value )
432{
433 int id, ret;
434 tech_group_t *tech;
435
436 /* Get ID. */
437 id = tech_getID( name );
438 if (id < 0) {
439 WARN(_("Trying to add item '%s' to non-existent tech '%s'."), value, name );
440 return -1;
441 }
442
443 /* Comfort. */
444 tech = &tech_groups[id];
445
446 /* Try to add the tech. */
447 ret = tech_addItemGroup( tech, value );
448 if (ret)
449 ret = tech_addItemOutfit( tech, value );
450 if (ret)
451 ret = tech_addItemShip( tech, value );
452 if (ret)
453 ret = tech_addItemCommodity( tech, value );
454 if (ret) {
455 WARN(_("Generic item '%s' not found in tech group '%s'"), value, name );
456 return -1;
457 }
458
459 return 0;
460}
461
465int tech_addItemTech( tech_group_t *tech, const char *value )
466{
467 /* Try to add the tech. */
468 int ret = tech_addItemGroup( tech, value );
469 if (ret)
470 ret = tech_addItemOutfit( tech, value );
471 if (ret)
472 ret = tech_addItemShip( tech, value );
473 if (ret)
474 ret = tech_addItemCommodity( tech, value );
475 if (ret) {
476 WARN(_("Generic item '%s' not found in tech group"), value );
477 return -1;
478 }
479 return 0;
480}
481
485int tech_rmItemTech( tech_group_t *tech, const char *value )
486{
487 /* Iterate over to find it. */
488 int s = array_size( tech->items );
489 for (int i=0; i<s; i++) {
490 char *buf = tech_getItemName( &tech->items[i] );
491 if (strcmp(buf, value)==0) {
492 array_erase( &tech->items, &tech->items[i], &tech->items[i+1] );
493 return 0;
494 }
495 }
496
497 WARN(_("Item '%s' not found in tech group"), value );
498 return -1;
499}
500
504int tech_rmItem( const char *name, const char *value )
505{
506 int id, s;
507 tech_group_t *tech;
508
509 /* Get ID. */
510 id = tech_getID( name);
511 if (id < 0) {
512 WARN(_("Trying to remove item '%s' to non-existent tech '%s'."), value, name );
513 return -1;
514 }
515
516 /* Comfort. */
517 tech = &tech_groups[id];
518
519 /* Iterate over to find it. */
520 s = array_size( tech->items );
521 for (int i=0; i<s; i++) {
522 char *buf = tech_getItemName( &tech->items[i] );
523 if (strcmp(buf, value)==0) {
524 array_erase( &tech->items, &tech->items[i], &tech->items[i+1] );
525 return 0;
526 }
527 }
528
529 WARN(_("Item '%s' not found in tech group '%s'"), value, name );
530 return -1;
531}
532
536static int tech_getID( const char *name )
537{
538 int s = array_size( tech_groups );
539 for (int i=0; i<s; i++) {
540 tech_group_t *tech= &tech_groups[i];
541 if (tech->name == NULL)
542 continue;
543 if (strcmp(tech->name, name)==0)
544 return i;
545 }
546 return -1L;
547}
548
552static int tech_addItemGroupPointer( tech_group_t *grp, const tech_group_t *ptr )
553{
554 /* Load the new item. */
555 tech_item_t *item = tech_itemGrow( grp );
557 item->u.grpptr = ptr;
558 return 0;
559}
560
566static int tech_addItemGroup( tech_group_t *grp, const char *name )
567{
568 tech_item_t *item;
569 int tech;
570
571 /* Try to find the tech. */
572 tech = tech_getID( name );
573 if (tech < 0)
574 return 1;
575
576 /* Load the new item. */
577 item = tech_itemGrow( grp );
578 item->type = TECH_TYPE_GROUP;
579 item->u.grp = tech;
580 return 0;
581}
582
590static void tech_createMetaGroup( tech_group_t *grp, tech_group_t **tech, int num )
591{
592 /* Create meta group. */
593 memset( grp, 0, sizeof(tech_group_t) );
594
595 /* Create a meta-group. */
596 for (int i=0; i<num; i++)
597 tech_addItemGroupPointer( grp, tech[i] );
598}
599
603static void** tech_addGroupItem( void **items, tech_item_type_t type, const tech_group_t *tech )
604{
605 /* Set up. */
606 int size = array_size( tech->items );
607
608 /* Load commodities first, then we handle groups. */
609 for (int i=0; i<size; i++) {
610 int f;
611 tech_item_t *item = &tech->items[i];
612
613 /* Only handle commodities for now. */
614 if (item->type != type)
615 continue;
616
617 /* Skip if already in list. */
618 f = 0;
619 for (int j=0; j<array_size(items); j++) {
620 if (items[j] == item->u.ptr) {
621 f = 1;
622 break;
623 }
624 }
625 if (f == 1)
626 continue;
627
628 /* Add. */
629 if (items == NULL)
630 items = array_create( void* );
631 array_push_back( &items, item->u.ptr );
632 }
633
634 /* Now handle other groups. */
635 for (int i=0; i<size; i++) {
636 tech_item_t *item = &tech->items[i];
637
638 /* Only handle commodities for now. */
639 if (item->type == TECH_TYPE_GROUP)
640 items = tech_addGroupItem( items, type, &tech_groups[ item->u.grp ] );
641 else if (item->type == TECH_TYPE_GROUP_POINTER)
642 items = tech_addGroupItem( items, type, item->u.grpptr );
643 }
644
645 return items;
646}
647
655int tech_hasItem( const tech_group_t *tech, const char *item )
656{
657 int s = array_size( tech->items );
658 for (int i=0; i<s; i++) {
659 char *buf = tech_getItemName( &tech->items[i] );
660 if (strcmp(buf,item)==0)
661 return 1;
662 }
663 return 0;
664}
665
671int tech_getItemCount( const tech_group_t *tech )
672{
673 return array_size( tech->items );
674}
675
683char** tech_getItemNames( const tech_group_t *tech, int *n )
684{
685 int s;
686 char **names;
687
688 *n = s = array_size( tech->items );
689 names = malloc( sizeof(char*) * s );
690
691 for (int i=0; i<s; i++)
692 names[i] = strdup( tech_getItemName( &tech->items[i] ) );
693
694 return names;
695}
696
703char** tech_getAllItemNames( int *n )
704{
705 int s;
706 char **names;
707
708 *n = s = array_size( tech_groups );
709 names = malloc( sizeof(char*) * s );
710
711 for (int i=0; i<s; i++)
712 names[i] = strdup( tech_groups[i].name );
713
714 return names;
715}
716
725Outfit** tech_getOutfit( const tech_group_t *tech )
726{
727 Outfit **o;
728
729 if (tech==NULL)
730 return NULL;
731
732 o = (Outfit**)tech_addGroupItem( NULL, TECH_TYPE_OUTFIT, tech );
733
734 /* Sort. */
735 if (o != NULL)
736 qsort( o, array_size(o), sizeof(Outfit*), outfit_compareTech );
737
738 return o;
739}
740
750Outfit** tech_getOutfitArray( tech_group_t **tech, int num )
751{
752 tech_group_t grp;
753 Outfit **o;
754
755 if (tech==NULL)
756 return NULL;
757
758 tech_createMetaGroup( &grp, tech, num );
759 o = tech_getOutfit( &grp );
760 tech_freeGroup( &grp );
761
762 return o;
763}
764
773Ship** tech_getShip( const tech_group_t *tech )
774{
775 Ship **s;
776
777 if (tech==NULL)
778 return NULL;
779
780 /* Get the outfits. */
781 s = (Ship**) tech_addGroupItem( NULL, TECH_TYPE_SHIP, tech );
782
783 /* Sort. */
784 if (s != NULL)
785 qsort( s, array_size(s), sizeof(Ship*), ship_compareTech );
786
787 return s;
788}
789
799Ship** tech_getShipArray( tech_group_t **tech, int num )
800{
801 tech_group_t grp;
802 Ship **s;
803
804 if (tech==NULL)
805 return NULL;
806
807 tech_createMetaGroup( &grp, tech, num );
808 s = tech_getShip( &grp );
809 tech_freeGroup( &grp );
810
811 return s;
812}
813
823Commodity** tech_getCommodityArray( tech_group_t **tech, int num )
824{
825 tech_group_t grp;
826 Commodity **c;
827
828 if (tech==NULL)
829 return NULL;
830
831 tech_createMetaGroup( &grp, tech, num );
832 c = tech_getCommodity( &grp );
833 tech_freeGroup( &grp );
834
835 return c;
836}
837
846Commodity** tech_getCommodity( const tech_group_t *tech )
847{
848 Commodity **c;
849
850 if (tech==NULL)
851 return NULL;
852
853 /* Get the commodities. */
855
856 /* Sort. */
857 if (c != NULL)
858 qsort( c, array_size(c), sizeof(Commodity*), commodity_compareTech );
859
860 return c;
861}
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_shrink(ptr_array)
Shrinks memory to fit only ‘size’ elements.
Definition: array.h:149
#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
Header file with generic functions and naev-specifics.
int ndata_matchExt(const char *path, const char *ext)
Sees if a file matches an extension.
Definition: ndata.c:366
char ** ndata_listRecursive(const char *path)
Lists all the visible files in a directory, at any depth.
Definition: ndata.c:232
static char buf[NEWS_MAX_LENGTH]
Definition: news.c:45
xmlDocPtr xml_parsePhysFS(const char *filename)
Analogous to xmlParseMemory/xmlParseFile.
Definition: nxml.c:75
int outfit_compareTech(const void *outfit1, const void *outfit2)
Function meant for use with C89, C99 algorithm qsort().
Definition: outfit.c:195
const Outfit * outfit_getW(const char *name)
Gets an outfit by name without warning on no-find.
Definition: outfit.c:132
static const double c[]
Definition: rng.c:264
const Ship * ship_getW(const char *name)
Gets a ship based on its name without warning.
Definition: ship.c:87
int ship_compareTech(const void *arg1, const void *arg2)
Comparison function for qsort().
Definition: ship.c:115
Represents a commodity.
Definition: commodity.h:43
char * name
Definition: commodity.h:44
A ship outfit, depends radically on the type.
Definition: outfit.h:304
char * name
Definition: outfit.h:305
int devmode
Definition: conf.h:158
Represents a space ship.
Definition: ship.h:94
char * name
Definition: ship.h:95
Group of tech items, basic unit of the tech trees.
Definition: tech.c:57
char * name
Definition: tech.c:58
char * filename
Definition: tech.c:59
tech_item_t * items
Definition: tech.c:60
Item contained in a tech group.
Definition: tech.c:42
const Outfit * outfit
Definition: tech.c:46
const Commodity * comm
Definition: tech.c:48
tech_item_type_t type
Definition: tech.c:43
const tech_group_t * grpptr
Definition: tech.c:50
void * ptr
Definition: tech.c:45
int grp
Definition: tech.c:49
union tech_item_t::@31 u
const Ship * ship
Definition: tech.c:47
static char * tech_getItemName(tech_item_t *item)
Gets an item's name.
Definition: tech.c:194
void tech_free(void)
Cleans up after the tech stuff.
Definition: tech.c:138
Ship ** tech_getShipArray(tech_group_t **tech, int num)
Gets the ships from an array of techs.
Definition: tech.c:799
int tech_load(void)
Loads the tech information.
Definition: tech.c:91
Commodity ** tech_getCommodity(const tech_group_t *tech)
Gets all of the ships associated to a tech group.
Definition: tech.c:846
int tech_groupWrite(xmlTextWriterPtr writer, tech_group_t *grp)
Writes a group in an xml node.
Definition: tech.c:216
static int tech_parseFile(tech_group_t *tech, const char *file)
Parses an XML tech node.
Definition: tech.c:240
static int tech_addItemCommodity(tech_group_t *grp, const char *name)
Loads a group item pertaining to a outfit.
Definition: tech.c:411
static void tech_createMetaGroup(tech_group_t *grp, tech_group_t **tech, int num)
Creates a meta-tech group pointing only to other groups.
Definition: tech.c:590
int tech_rmItemTech(tech_group_t *tech, const char *value)
Removes an item from a tech.
Definition: tech.c:485
static int tech_addItemShip(tech_group_t *grp, const char *name)
Loads a group item pertaining to a outfit.
Definition: tech.c:389
tech_group_t * tech_groupCreate(void)
Creates a tech group.
Definition: tech.c:173
static int tech_addItemGroupPointer(tech_group_t *grp, const tech_group_t *ptr)
Adds a group pointer to a group.
Definition: tech.c:552
int tech_getItemCount(const tech_group_t *tech)
Gets the number of techs within a given group.
Definition: tech.c:671
int tech_rmItem(const char *name, const char *value)
Removes a tech item.
Definition: tech.c:504
tech_item_type_t
Different tech types.
Definition: tech.c:31
@ TECH_TYPE_COMMODITY
Definition: tech.c:34
@ TECH_TYPE_OUTFIT
Definition: tech.c:32
@ TECH_TYPE_GROUP
Definition: tech.c:35
@ TECH_TYPE_GROUP_POINTER
Definition: tech.c:36
@ TECH_TYPE_SHIP
Definition: tech.c:33
static void tech_freeGroup(tech_group_t *grp)
Cleans up a tech group.
Definition: tech.c:152
static int tech_parseXMLData(tech_group_t *tech, xmlNodePtr parent)
Parses an XML tech node.
Definition: tech.c:271
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
tech_group_t * tech_groupCreateXML(xmlNodePtr node)
Creates a tech group from an XML node.
Definition: tech.c:162
static int tech_getID(const char *name)
Gets the ID of a tech.
Definition: tech.c:536
void tech_groupDestroy(tech_group_t *grp)
Frees a tech group.
Definition: tech.c:182
static void ** tech_addGroupItem(void **items, tech_item_type_t type, const tech_group_t *tech)
Recursive function for creating an array of commodities from a tech group.
Definition: tech.c:603
static int tech_addItemGroup(tech_group_t *grp, const char *name)
Loads a group item pertaining to a group.
Definition: tech.c:566
static tech_item_t * tech_itemGrow(tech_group_t *grp)
Adds an item to a tech.
Definition: tech.c:360
Commodity ** tech_getCommodityArray(tech_group_t **tech, int num)
Gets the ships from an array of techs.
Definition: tech.c:823
Ship ** tech_getShip(const tech_group_t *tech)
Gets all of the ships associated to a tech group.
Definition: tech.c:773
int tech_addItemTech(tech_group_t *tech, const char *value)
Adds an item to a tech.
Definition: tech.c:465
int tech_addItem(const char *name, const char *value)
Adds an item to a tech.
Definition: tech.c:431
Outfit ** tech_getOutfitArray(tech_group_t **tech, int num)
Gets the outfits from an array of techs.
Definition: tech.c:750
Outfit ** tech_getOutfit(const tech_group_t *tech)
Gets all of the outfits associated to a tech group.
Definition: tech.c:725
static int tech_parseFileData(tech_group_t *tech)
Parses an XML tech node.
Definition: tech.c:335
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