naev 0.11.5
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"
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#if DEBUGGING
94 Uint32 time = SDL_GetTicks();
95#endif /* DEBUGGING */
96 int s;
97 char **tech_files = ndata_listRecursive( TECH_DATA_PATH );
98
99 /* Create the array. */
100 tech_groups = array_create( tech_group_t );
101
102 /* First pass create the groups - needed to reference them later. */
103 for (int i=0; i<array_size(tech_files); i++) {
104 tech_group_t tech;
105 int ret;
106
107 if (!ndata_matchExt( tech_files[i], "xml" ))
108 continue;
109
110 ret = tech_parseFile( &tech, tech_files[i] );
111 if (ret==0) {
112 tech.filename = strdup( tech_files[i] );
113 array_push_back( &tech_groups, tech );
114 }
115
116 free( tech_files[i] );
117 }
118 array_free( tech_files );
119 array_shrink( &tech_groups );
120
121 /* Now we load the data. */
122 s = array_size( tech_groups );
123 for (int i=0; i<s; i++)
124 tech_parseFileData( &tech_groups[i] );
125
126 /* Info. */
127#if DEBUGGING
128 if (conf.devmode) {
129 DEBUG( n_( "Loaded %d tech group in %.3f s", "Loaded %d tech groups in %.3f s", s ), s, (SDL_GetTicks()-time)/1000. );
130 }
131 else
132 DEBUG( n_( "Loaded %d tech group", "Loaded %d tech groups", s ), s );
133#endif /* DEBUGGING */
134
135 return 0;
136}
137
141void tech_free (void)
142{
143 /* Free all individual techs. */
144 int s = array_size( tech_groups );
145 for (int i=0; i<s; i++)
146 tech_freeGroup( &tech_groups[i] );
147
148 /* Free the tech array. */
149 array_free( tech_groups );
150}
151
155static void tech_freeGroup( tech_group_t *grp )
156{
157 free(grp->name);
158 free(grp->filename);
159 array_free( grp->items );
160}
161
165tech_group_t *tech_groupCreateXML( xmlNodePtr node )
166{
167 /* Load data. */
168 tech_group_t *tech = tech_groupCreate();
169 tech_parseXMLData( tech, node );
170 return tech;
171}
172
176tech_group_t *tech_groupCreate( void )
177{
178 tech_group_t *tech = calloc( sizeof(tech_group_t), 1 );
179 return tech;
180}
181
185void tech_groupDestroy( tech_group_t *grp )
186{
187 if (grp == NULL)
188 return;
189
190 tech_freeGroup( grp );
191 free(grp);
192}
193
197static char* tech_getItemName( tech_item_t *item )
198{
199 /* Handle type. */
200 switch (item->type) {
201 case TECH_TYPE_OUTFIT:
202 return item->u.outfit->name;
203 case TECH_TYPE_SHIP:
204 return item->u.ship->name;
206 return item->u.comm->name;
207 case TECH_TYPE_GROUP:
208 return tech_groups[ item->u.grp ].name;
210 return item->u.grpptr->name;
211 }
212
213 return NULL;
214}
215
219int tech_groupWrite( xmlTextWriterPtr writer, tech_group_t *grp )
220{
221 int s;
222
223 /* Handle empty groups. */
224 if (grp == NULL)
225 return 0;
226
227 /* Node header. */
228 xmlw_startElem( writer, "tech" );
229
230 /* Save items. */
231 s = array_size( grp->items );
232 for (int i=0; i<s; i++)
233 xmlw_elem( writer, "item", "%s", tech_getItemName( &grp->items[i] ) );
234
235 xmlw_endElem( writer ); /* "tech" */
236
237 return 0;
238}
239
243static int tech_parseFile( tech_group_t *tech, const char *file )
244{
245 xmlNodePtr parent;
246 xmlDocPtr doc = xml_parsePhysFS( file );
247 if (doc == NULL)
248 return -1;
249
250 parent = doc->xmlChildrenNode; /* first faction node */
251 if (parent == NULL) {
252 ERR( _("Malformed '%s' file: does not contain elements"), file);
253 return -1;
254 }
255
256 /* Just in case. */
257 memset( tech, 0, sizeof(tech_group_t) );
258
259 /* Get name. */
260 xmlr_attr_strd( parent, "name", tech->name );
261 if (tech->name == NULL) {
262 WARN(_("tech node does not have 'name' attribute"));
263 return 1;
264 }
265
266 xmlFreeDoc(doc);
267
268 return 0;
269}
270
274static int tech_parseXMLData( tech_group_t *tech, xmlNodePtr parent )
275{
276 /* Parse the data. */
277 xmlNodePtr node = parent->xmlChildrenNode;
278 do {
279 xml_onlyNodes(node);
280 if (xml_isNode(node,"item")) {
281 char *buf, *name;
282
283 /* Must have name. */
284 name = xml_get( node );
285 if (name == NULL) {
286 WARN(_("Tech group '%s' has an item without a value."), tech->name);
287 continue;
288 }
289
290 /* Try to find hard-coded type. */
291 xmlr_attr_strd( node, "type", buf );
292 if (buf == NULL) {
293 int ret = 1;
294 //if (ret)
295 ret = tech_addItemGroup( tech, name );
296 if (ret)
297 ret = tech_addItemOutfit( tech, name );
298 if (ret)
299 ret = tech_addItemShip( tech, name );
300 if (ret)
301 ret = tech_addItemCommodity( tech, name );
302 if (ret)
303 WARN(_("Generic item '%s' not found in tech group '%s'"),
304 name, tech->name );
305 }
306 else if (strcmp(buf,"group")==0) {
307 if (!tech_addItemGroup( tech, name ))
308 WARN(_("Group item '%s' not found in tech group '%s'."),
309 name, tech->name );
310 }
311 else if (strcmp(buf,"outfit")==0) {
312 if (!tech_addItemGroup( tech, name ))
313 WARN(_("Outfit item '%s' not found in tech group '%s'."),
314 name, tech->name );
315 }
316 else if (strcmp(buf,"ship")==0) {
317 if (!tech_addItemGroup( tech, name ))
318 WARN(_("Ship item '%s' not found in tech group '%s'."),
319 name, tech->name );
320 }
321 else if (strcmp(buf,"commodity")==0) {
322 if (!tech_addItemGroup( tech, name ))
323 WARN(_("Commodity item '%s' not found in tech group '%s'."),
324 name, tech->name );
325 }
326 free( buf );
327 continue;
328 }
329 WARN(_("Tech group '%s' has unknown node '%s'."), tech->name, node->name);
330 } while (xml_nextNode( node ));
331
332 return 0;
333}
334
338static int tech_parseFileData( tech_group_t *tech )
339{
340 xmlNodePtr parent;
341 const char *file = tech->filename;
342 xmlDocPtr doc = xml_parsePhysFS( file );
343 if (doc == NULL)
344 return -1;
345
346 parent = doc->xmlChildrenNode; /* first faction node */
347 if (parent == NULL) {
348 ERR( _("Malformed '%s' file: does not contain elements"), file);
349 return -1;
350 }
351
352 /* Parse the data. */
353 tech_parseXMLData( tech, parent );
354
355 xmlFreeDoc(doc);
356
357 return 0;
358}
359
363static tech_item_t *tech_itemGrow( tech_group_t *grp )
364{
365 if (grp->items == NULL)
366 grp->items = array_create( tech_item_t );
367 return &array_grow( &grp->items );
368}
369
370static int tech_addItemOutfit( tech_group_t *grp, const char *name )
371{
372 tech_item_t *item;
373 const Outfit *o;
374
375 /* Get the outfit. */
376 o = outfit_getW( name );
377 if (o==NULL)
378 return 1;
379
380 /* Load the new item. */
381 item = tech_itemGrow( grp );
382 item->type = TECH_TYPE_OUTFIT;
383 item->u.outfit = o;
384 return 0;
385}
386
392static int tech_addItemShip( tech_group_t *grp, const char* name )
393{
394 tech_item_t *item;
395 const Ship *s;
396
397 /* Get the outfit. */
398 s = ship_getW( name );
399 if (s==NULL)
400 return 1;
401
402 /* Load the new item. */
403 item = tech_itemGrow( grp );
404 item->type = TECH_TYPE_SHIP;
405 item->u.ship = s;
406 return 0;
407}
408
414static int tech_addItemCommodity( tech_group_t *grp, const char* name )
415{
416 tech_item_t *item;
417 Commodity *c;
418
419 /* Get the outfit. */
420 c = commodity_getW( name );
421 if (c==NULL)
422 return 1;
423
424 /* Load the new item. */
425 item = tech_itemGrow( grp );
427 item->u.comm = c;
428 return 0;
429}
430
434int tech_addItem( const char *name, const char *value )
435{
436 int id, ret;
437 tech_group_t *tech;
438
439 /* Get ID. */
440 id = tech_getID( name );
441 if (id < 0) {
442 WARN(_("Trying to add item '%s' to non-existent tech '%s'."), value, name );
443 return -1;
444 }
445
446 /* Comfort. */
447 tech = &tech_groups[id];
448
449 /* Try to add the tech. */
450 ret = tech_addItemGroup( tech, value );
451 if (ret)
452 ret = tech_addItemOutfit( tech, value );
453 if (ret)
454 ret = tech_addItemShip( tech, value );
455 if (ret)
456 ret = tech_addItemCommodity( tech, value );
457 if (ret) {
458 WARN(_("Generic item '%s' not found in tech group '%s'"), value, name );
459 return -1;
460 }
461
462 return 0;
463}
464
468int tech_addItemTech( tech_group_t *tech, const char *value )
469{
470 /* Try to add the tech. */
471 int ret = tech_addItemGroup( tech, value );
472 if (ret)
473 ret = tech_addItemOutfit( tech, value );
474 if (ret)
475 ret = tech_addItemShip( tech, value );
476 if (ret)
477 ret = tech_addItemCommodity( tech, value );
478 if (ret) {
479 WARN(_("Generic item '%s' not found in tech group"), value );
480 return -1;
481 }
482 return 0;
483}
484
488int tech_rmItemTech( tech_group_t *tech, const char *value )
489{
490 /* Iterate over to find it. */
491 int s = array_size( tech->items );
492 for (int i=0; i<s; i++) {
493 const char *buf = tech_getItemName( &tech->items[i] );
494 if (strcmp(buf, value)==0) {
495 array_erase( &tech->items, &tech->items[i], &tech->items[i+1] );
496 return 0;
497 }
498 }
499
500 WARN(_("Item '%s' not found in tech group"), value );
501 return -1;
502}
503
507int tech_rmItem( const char *name, const char *value )
508{
509 int id, s;
510 tech_group_t *tech;
511
512 /* Get ID. */
513 id = tech_getID( name);
514 if (id < 0) {
515 WARN(_("Trying to remove item '%s' to non-existent tech '%s'."), value, name );
516 return -1;
517 }
518
519 /* Comfort. */
520 tech = &tech_groups[id];
521
522 /* Iterate over to find it. */
523 s = array_size( tech->items );
524 for (int i=0; i<s; i++) {
525 const char *buf = tech_getItemName( &tech->items[i] );
526 if (strcmp(buf, value)==0) {
527 array_erase( &tech->items, &tech->items[i], &tech->items[i+1] );
528 return 0;
529 }
530 }
531
532 WARN(_("Item '%s' not found in tech group '%s'"), value, name );
533 return -1;
534}
535
539static int tech_getID( const char *name )
540{
541 int s = array_size( tech_groups );
542 for (int i=0; i<s; i++) {
543 const tech_group_t *tech= &tech_groups[i];
544 if (tech->name == NULL)
545 continue;
546 if (strcmp(tech->name, name)==0)
547 return i;
548 }
549 return -1L;
550}
551
555static int tech_addItemGroupPointer( tech_group_t *grp, const tech_group_t *ptr )
556{
557 /* Load the new item. */
558 tech_item_t *item = tech_itemGrow( grp );
560 item->u.grpptr = ptr;
561 return 0;
562}
563
569static int tech_addItemGroup( tech_group_t *grp, const char *name )
570{
571 tech_item_t *item;
572 int tech;
573
574 /* Try to find the tech. */
575 tech = tech_getID( name );
576 if (tech < 0)
577 return 1;
578
579 /* Load the new item. */
580 item = tech_itemGrow( grp );
581 item->type = TECH_TYPE_GROUP;
582 item->u.grp = tech;
583 return 0;
584}
585
593static void tech_createMetaGroup( tech_group_t *grp, tech_group_t **tech, int num )
594{
595 /* Create meta group. */
596 memset( grp, 0, sizeof(tech_group_t) );
597
598 /* Create a meta-group. */
599 for (int i=0; i<num; i++)
600 tech_addItemGroupPointer( grp, tech[i] );
601}
602
606static void** tech_addGroupItem( void **items, tech_item_type_t type, const tech_group_t *tech )
607{
608 /* Set up. */
609 int size = array_size( tech->items );
610
611 /* Load commodities first, then we handle groups. */
612 for (int i=0; i<size; i++) {
613 int f;
614 tech_item_t *item = &tech->items[i];
615
616 /* Only handle commodities for now. */
617 if (item->type != type)
618 continue;
619
620 /* Skip if already in list. */
621 f = 0;
622 for (int j=0; j<array_size(items); j++) {
623 if (items[j] == item->u.ptr) {
624 f = 1;
625 break;
626 }
627 }
628 if (f == 1)
629 continue;
630
631 /* Add. */
632 if (items == NULL)
633 items = array_create( void* );
634 array_push_back( &items, item->u.ptr );
635 }
636
637 /* Now handle other groups. */
638 for (int i=0; i<size; i++) {
639 tech_item_t *item = &tech->items[i];
640
641 /* Only handle commodities for now. */
642 if (item->type == TECH_TYPE_GROUP)
643 items = tech_addGroupItem( items, type, &tech_groups[ item->u.grp ] );
644 else if (item->type == TECH_TYPE_GROUP_POINTER)
645 items = tech_addGroupItem( items, type, item->u.grpptr );
646 }
647
648 return items;
649}
650
658int tech_hasItem( const tech_group_t *tech, const char *item )
659{
660 int s = array_size( tech->items );
661 for (int i=0; i<s; i++) {
662 const char *buf = tech_getItemName( &tech->items[i] );
663 if (strcmp(buf,item)==0)
664 return 1;
665 }
666 return 0;
667}
668
674int tech_getItemCount( const tech_group_t *tech )
675{
676 return array_size( tech->items );
677}
678
686char** tech_getItemNames( const tech_group_t *tech, int *n )
687{
688 int s;
689 char **names;
690
691 *n = s = array_size( tech->items );
692 names = malloc( sizeof(char*) * s );
693
694 for (int i=0; i<s; i++)
695 names[i] = strdup( tech_getItemName( &tech->items[i] ) );
696
697 return names;
698}
699
706char** tech_getAllItemNames( int *n )
707{
708 int s;
709 char **names;
710
711 *n = s = array_size( tech_groups );
712 names = malloc( sizeof(char*) * s );
713
714 for (int i=0; i<s; i++)
715 names[i] = strdup( tech_groups[i].name );
716
717 return names;
718}
719
728Outfit** tech_getOutfit( const tech_group_t *tech )
729{
730 Outfit **o;
731
732 if (tech==NULL)
733 return NULL;
734
735 o = (Outfit**)tech_addGroupItem( NULL, TECH_TYPE_OUTFIT, tech );
736
737 /* Sort. */
738 if (o != NULL)
739 qsort( o, array_size(o), sizeof(Outfit*), outfit_compareTech );
740
741 return o;
742}
743
753Outfit** tech_getOutfitArray( tech_group_t **tech, int num )
754{
755 tech_group_t grp;
756 Outfit **o;
757
758 if (tech==NULL)
759 return NULL;
760
761 tech_createMetaGroup( &grp, tech, num );
762 o = tech_getOutfit( &grp );
763 tech_freeGroup( &grp );
764
765 return o;
766}
767
776Ship** tech_getShip( const tech_group_t *tech )
777{
778 Ship **s;
779
780 if (tech==NULL)
781 return NULL;
782
783 /* Get the outfits. */
784 s = (Ship**) tech_addGroupItem( NULL, TECH_TYPE_SHIP, tech );
785
786 /* Sort. */
787 if (s != NULL)
788 qsort( s, array_size(s), sizeof(Ship*), ship_compareTech );
789
790 return s;
791}
792
802Ship** tech_getShipArray( tech_group_t **tech, int num )
803{
804 tech_group_t grp;
805 Ship **s;
806
807 if (tech==NULL)
808 return NULL;
809
810 tech_createMetaGroup( &grp, tech, num );
811 s = tech_getShip( &grp );
812 tech_freeGroup( &grp );
813
814 return s;
815}
816
826Commodity** tech_getCommodityArray( tech_group_t **tech, int num )
827{
828 tech_group_t grp;
829 Commodity **c;
830
831 if (tech==NULL)
832 return NULL;
833
834 tech_createMetaGroup( &grp, tech, num );
835 c = tech_getCommodity( &grp );
836 tech_freeGroup( &grp );
837
838 return c;
839}
840
849Commodity** tech_getCommodity( const tech_group_t *tech )
850{
851 Commodity **c;
852
853 if (tech==NULL)
854 return NULL;
855
856 /* Get the commodities. */
858
859 /* Sort. */
860 if (c != NULL)
861 qsort( c, array_size(c), sizeof(Commodity*), commodity_compareTech );
862
863 return c;
864}
865
869int tech_checkOutfit( const tech_group_t *tech, const Outfit *o )
870{
871 Outfit **to = tech_getOutfit( tech );
872 for (int i=0; i<array_size(to); i++) {
873 if (to[i]==o) {
874 array_free(to);
875 return 1;
876 }
877 }
878 array_free(to);
879 return 0;
880}
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
int commodity_compareTech(const void *commodity1, const void *commodity2)
Function meant for use with C89, C99 algorithm qsort().
Definition commodity.c:219
Commodity * commodity_getW(const char *name)
Gets a commodity by name without warning.
Definition commodity.c:142
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:365
char ** ndata_listRecursive(const char *path)
Lists all the visible files in a directory, at any depth.
Definition ndata.c:231
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:243
const Outfit * outfit_getW(const char *name)
Gets an outfit by name without warning on no-find.
Definition outfit.c:180
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:101
int ship_compareTech(const void *arg1, const void *arg2)
Comparison function for qsort().
Definition ship.c:129
Represents a commodity.
Definition commodity.h:43
char * name
Definition commodity.h:44
A ship outfit, depends radically on the type.
Definition outfit.h:328
char * name
Definition outfit.h:329
int devmode
Definition conf.h:157
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
union tech_item_t::@37 u
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
const Ship * ship
Definition tech.c:47
static char * tech_getItemName(tech_item_t *item)
Gets an item's name.
Definition tech.c:197
void tech_free(void)
Cleans up after the tech stuff.
Definition tech.c:141
Ship ** tech_getShipArray(tech_group_t **tech, int num)
Gets the ships from an array of techs.
Definition tech.c:802
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:849
int tech_checkOutfit(const tech_group_t *tech, const Outfit *o)
Checks to see if there is an outfit in the tech group.
Definition tech.c:869
int tech_groupWrite(xmlTextWriterPtr writer, tech_group_t *grp)
Writes a group in an xml node.
Definition tech.c:219
static int tech_parseFile(tech_group_t *tech, const char *file)
Parses an XML tech node.
Definition tech.c:243
static int tech_addItemCommodity(tech_group_t *grp, const char *name)
Loads a group item pertaining to a outfit.
Definition tech.c:414
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:593
int tech_rmItemTech(tech_group_t *tech, const char *value)
Removes an item from a tech.
Definition tech.c:488
static int tech_addItemShip(tech_group_t *grp, const char *name)
Loads a group item pertaining to a outfit.
Definition tech.c:392
tech_group_t * tech_groupCreate(void)
Creates a tech group.
Definition tech.c:176
static int tech_addItemGroupPointer(tech_group_t *grp, const tech_group_t *ptr)
Adds a group pointer to a group.
Definition tech.c:555
int tech_getItemCount(const tech_group_t *tech)
Gets the number of techs within a given group.
Definition tech.c:674
int tech_rmItem(const char *name, const char *value)
Removes a tech item.
Definition tech.c:507
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:155
static int tech_parseXMLData(tech_group_t *tech, xmlNodePtr parent)
Parses an XML tech node.
Definition tech.c:274
int tech_hasItem(const tech_group_t *tech, const char *item)
Checks whether a given tech group has the specified item.
Definition tech.c:658
tech_group_t * tech_groupCreateXML(xmlNodePtr node)
Creates a tech group from an XML node.
Definition tech.c:165
static int tech_getID(const char *name)
Gets the ID of a tech.
Definition tech.c:539
void tech_groupDestroy(tech_group_t *grp)
Frees a tech group.
Definition tech.c:185
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:606
static int tech_addItemGroup(tech_group_t *grp, const char *name)
Loads a group item pertaining to a group.
Definition tech.c:569
static tech_item_t * tech_itemGrow(tech_group_t *grp)
Adds an item to a tech.
Definition tech.c:363
Commodity ** tech_getCommodityArray(tech_group_t **tech, int num)
Gets the ships from an array of techs.
Definition tech.c:826
Ship ** tech_getShip(const tech_group_t *tech)
Gets all of the ships associated to a tech group.
Definition tech.c:776
int tech_addItemTech(tech_group_t *tech, const char *value)
Adds an item to a tech.
Definition tech.c:468
int tech_addItem(const char *name, const char *value)
Adds an item to a tech.
Definition tech.c:434
Outfit ** tech_getOutfitArray(tech_group_t **tech, int num)
Gets the outfits from an array of techs.
Definition tech.c:753
Outfit ** tech_getOutfit(const tech_group_t *tech)
Gets all of the outfits associated to a tech group.
Definition tech.c:728
static int tech_parseFileData(tech_group_t *tech)
Parses an XML tech node.
Definition tech.c:338
char ** tech_getItemNames(const tech_group_t *tech, int *n)
Gets the names of all techs within a given group.
Definition tech.c:686
char ** tech_getAllItemNames(int *n)
Gets the names of all techs.
Definition tech.c:706