25#define XML_TECH_ID "Techs"
26#define XML_TECH_TAG "tech"
31typedef enum tech_item_type_e {
42typedef struct tech_item_s {
66static tech_group_t *tech_groups = NULL;
79static int tech_addItemOutfit( tech_group_t *grp,
const char* name );
94 Uint32 time = SDL_GetTicks();
103 for (
int i=0; i<
array_size(tech_files); i++) {
112 tech.filename = strdup( tech_files[i] );
116 free( tech_files[i] );
123 for (
int i=0; i<s; i++)
129 DEBUG( n_(
"Loaded %d tech group in %.3f s",
"Loaded %d tech groups in %.3f s", s ), s, (SDL_GetTicks()-time)/1000. );
132 DEBUG( n_(
"Loaded %d tech group",
"Loaded %d tech groups", s ), s );
145 for (
int i=0; i<s; i++)
178 tech_group_t *tech = calloc(
sizeof(tech_group_t), 1 );
200 switch (item->
type) {
208 return tech_groups[ item->
u.
grp ].name;
228 xmlw_startElem( writer,
"tech" );
232 for (
int i=0; i<s; i++)
235 xmlw_endElem( writer );
250 parent = doc->xmlChildrenNode;
251 if (parent == NULL) {
252 ERR( _(
"Malformed '%s' file: does not contain elements"), file);
257 memset( tech, 0,
sizeof(tech_group_t) );
260 xmlr_attr_strd( parent,
"name", tech->name );
261 if (tech->name == NULL) {
262 WARN(_(
"tech node does not have 'name' attribute"));
277 xmlNodePtr node = parent->xmlChildrenNode;
280 if (xml_isNode(node,
"item")) {
284 name = xml_get( node );
286 WARN(_(
"Tech group '%s' has an item without a value."), tech->name);
291 xmlr_attr_strd( node,
"type", buf );
297 ret = tech_addItemOutfit( tech, name );
303 WARN(_(
"Generic item '%s' not found in tech group '%s'"),
306 else if (strcmp(buf,
"group")==0) {
308 WARN(_(
"Group item '%s' not found in tech group '%s'."),
311 else if (strcmp(buf,
"outfit")==0) {
313 WARN(_(
"Outfit item '%s' not found in tech group '%s'."),
316 else if (strcmp(buf,
"ship")==0) {
318 WARN(_(
"Ship item '%s' not found in tech group '%s'."),
321 else if (strcmp(buf,
"commodity")==0) {
323 WARN(_(
"Commodity item '%s' not found in tech group '%s'."),
329 WARN(_(
"Tech group '%s' has unknown node '%s'."), tech->name, node->name);
330 }
while (xml_nextNode( node ));
341 const char *file = tech->filename;
346 parent = doc->xmlChildrenNode;
347 if (parent == NULL) {
348 ERR( _(
"Malformed '%s' file: does not contain elements"), file);
365 if (grp->items == NULL)
370static int tech_addItemOutfit( tech_group_t *grp,
const char *name )
442 WARN(_(
"Trying to add item '%s' to non-existent tech '%s'."), value, name );
447 tech = &tech_groups[id];
452 ret = tech_addItemOutfit( tech, value );
458 WARN(_(
"Generic item '%s' not found in tech group '%s'"), value, name );
473 ret = tech_addItemOutfit( tech, value );
479 WARN(_(
"Generic item '%s' not found in tech group"), value );
492 for (
int i=0; i<s; i++) {
494 if (strcmp(buf, value)==0) {
495 array_erase( &tech->items, &tech->items[i], &tech->items[i+1] );
500 WARN(_(
"Item '%s' not found in tech group"), value );
515 WARN(_(
"Trying to remove item '%s' to non-existent tech '%s'."), value, name );
520 tech = &tech_groups[id];
524 for (
int i=0; i<s; i++) {
526 if (strcmp(buf, value)==0) {
527 array_erase( &tech->items, &tech->items[i], &tech->items[i+1] );
532 WARN(_(
"Item '%s' not found in tech group '%s'"), value, name );
542 for (
int i=0; i<s; i++) {
543 const tech_group_t *tech= &tech_groups[i];
544 if (tech->name == NULL)
546 if (strcmp(tech->name, name)==0)
596 memset( grp, 0,
sizeof(tech_group_t) );
599 for (
int i=0; i<num; i++)
612 for (
int i=0; i<size; i++) {
617 if (item->
type != type)
623 if (items[j] == item->
u.
ptr) {
638 for (
int i=0; i<size; i++) {
661 for (
int i=0; i<s; i++) {
663 if (strcmp(buf,item)==0)
692 names = malloc(
sizeof(
char*) * s );
694 for (
int i=0; i<s; i++)
712 names = malloc(
sizeof(
char*) * s );
714 for (
int i=0; i<s; i++)
715 names[i] = strdup( tech_groups[i].name );
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_shrink(ptr_array)
Shrinks memory to fit only ‘size’ elements.
#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’.
int commodity_compareTech(const void *commodity1, const void *commodity2)
Function meant for use with C89, C99 algorithm qsort().
Commodity * commodity_getW(const char *name)
Gets a commodity by name without warning.
Header file with generic functions and naev-specifics.
int ndata_matchExt(const char *path, const char *ext)
Sees if a file matches an extension.
char ** ndata_listRecursive(const char *path)
Lists all the visible files in a directory, at any depth.
xmlDocPtr xml_parsePhysFS(const char *filename)
Analogous to xmlParseMemory/xmlParseFile.
int outfit_compareTech(const void *outfit1, const void *outfit2)
Function meant for use with C89, C99 algorithm qsort().
const Outfit * outfit_getW(const char *name)
Gets an outfit by name without warning on no-find.
const Ship * ship_getW(const char *name)
Gets a ship based on its name without warning.
int ship_compareTech(const void *arg1, const void *arg2)
Comparison function for qsort().
A ship outfit, depends radically on the type.
Group of tech items, basic unit of the tech trees.
Item contained in a tech group.
const tech_group_t * grpptr
static char * tech_getItemName(tech_item_t *item)
Gets an item's name.
void tech_free(void)
Cleans up after the tech stuff.
Ship ** tech_getShipArray(tech_group_t **tech, int num)
Gets the ships from an array of techs.
int tech_load(void)
Loads the tech information.
Commodity ** tech_getCommodity(const tech_group_t *tech)
Gets all of the ships associated to a tech group.
int tech_checkOutfit(const tech_group_t *tech, const Outfit *o)
Checks to see if there is an outfit in the tech group.
int tech_groupWrite(xmlTextWriterPtr writer, tech_group_t *grp)
Writes a group in an xml node.
static int tech_parseFile(tech_group_t *tech, const char *file)
Parses an XML tech node.
static int tech_addItemCommodity(tech_group_t *grp, const char *name)
Loads a group item pertaining to a outfit.
static void tech_createMetaGroup(tech_group_t *grp, tech_group_t **tech, int num)
Creates a meta-tech group pointing only to other groups.
int tech_rmItemTech(tech_group_t *tech, const char *value)
Removes an item from a tech.
static int tech_addItemShip(tech_group_t *grp, const char *name)
Loads a group item pertaining to a outfit.
tech_group_t * tech_groupCreate(void)
Creates a tech group.
static int tech_addItemGroupPointer(tech_group_t *grp, const tech_group_t *ptr)
Adds a group pointer to a group.
int tech_getItemCount(const tech_group_t *tech)
Gets the number of techs within a given group.
int tech_rmItem(const char *name, const char *value)
Removes a tech item.
tech_item_type_t
Different tech types.
@ TECH_TYPE_GROUP_POINTER
static void tech_freeGroup(tech_group_t *grp)
Cleans up a tech group.
static int tech_parseXMLData(tech_group_t *tech, xmlNodePtr parent)
Parses an XML tech node.
int tech_hasItem(const tech_group_t *tech, const char *item)
Checks whether a given tech group has the specified item.
tech_group_t * tech_groupCreateXML(xmlNodePtr node)
Creates a tech group from an XML node.
static int tech_getID(const char *name)
Gets the ID of a tech.
void tech_groupDestroy(tech_group_t *grp)
Frees a tech group.
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.
static int tech_addItemGroup(tech_group_t *grp, const char *name)
Loads a group item pertaining to a group.
static tech_item_t * tech_itemGrow(tech_group_t *grp)
Adds an item to a tech.
Commodity ** tech_getCommodityArray(tech_group_t **tech, int num)
Gets the ships from an array of techs.
Ship ** tech_getShip(const tech_group_t *tech)
Gets all of the ships associated to a tech group.
int tech_addItemTech(tech_group_t *tech, const char *value)
Adds an item to a tech.
int tech_addItem(const char *name, const char *value)
Adds an item to a tech.
Outfit ** tech_getOutfitArray(tech_group_t **tech, int num)
Gets the outfits from an array of techs.
Outfit ** tech_getOutfit(const tech_group_t *tech)
Gets all of the outfits associated to a tech group.
static int tech_parseFileData(tech_group_t *tech)
Parses an XML tech node.
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.