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();
101 for (
int i=0; i<
array_size(tech_files); i++) {
110 tech.filename = strdup( tech_files[i] );
114 free( tech_files[i] );
121 for (
int i=0; i<s; i++)
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. );
130 DEBUG( n_(
"Loaded %d tech group",
"Loaded %d tech groups", s ), s );
142 for (
int i=0; i<s; i++)
175 tech_group_t *tech = calloc(
sizeof(tech_group_t), 1 );
197 switch (item->
type) {
205 return tech_groups[ item->
u.
grp ].name;
225 xmlw_startElem( writer,
"tech" );
229 for (
int i=0; i<s; i++)
232 xmlw_endElem( writer );
247 parent = doc->xmlChildrenNode;
248 if (parent == NULL) {
249 ERR( _(
"Malformed '%s' file: does not contain elements"), file);
254 memset( tech, 0,
sizeof(tech_group_t) );
257 xmlr_attr_strd( parent,
"name", tech->name );
258 if (tech->name == NULL) {
259 WARN(_(
"tech node does not have 'name' attribute"));
274 xmlNodePtr node = parent->xmlChildrenNode;
277 if (xml_isNode(node,
"item")) {
281 name = xml_get( node );
283 WARN(_(
"Tech group '%s' has an item without a value."), tech->name);
288 xmlr_attr_strd( node,
"type", buf );
294 ret = tech_addItemOutfit( tech, name );
300 WARN(_(
"Generic item '%s' not found in tech group '%s'"),
303 else if (strcmp(buf,
"group")==0) {
305 WARN(_(
"Group item '%s' not found in tech group '%s'."),
308 else if (strcmp(buf,
"outfit")==0) {
310 WARN(_(
"Outfit item '%s' not found in tech group '%s'."),
313 else if (strcmp(buf,
"ship")==0) {
315 WARN(_(
"Ship item '%s' not found in tech group '%s'."),
318 else if (strcmp(buf,
"commodity")==0) {
320 WARN(_(
"Commodity item '%s' not found in tech group '%s'."),
326 WARN(_(
"Tech group '%s' has unknown node '%s'."), tech->name, node->name);
327 }
while (xml_nextNode( node ));
338 const char *file = tech->filename;
343 parent = doc->xmlChildrenNode;
344 if (parent == NULL) {
345 ERR( _(
"Malformed '%s' file: does not contain elements"), file);
362 if (grp->items == NULL)
367static int tech_addItemOutfit( tech_group_t *grp,
const char *name )
417 c = commodity_getW( name );
439 WARN(_(
"Trying to add item '%s' to non-existent tech '%s'."), value, name );
444 tech = &tech_groups[id];
449 ret = tech_addItemOutfit( tech, value );
455 WARN(_(
"Generic item '%s' not found in tech group '%s'"), value, name );
470 ret = tech_addItemOutfit( tech, value );
476 WARN(_(
"Generic item '%s' not found in tech group"), value );
489 for (
int i=0; i<s; i++) {
491 if (strcmp(buf, value)==0) {
492 array_erase( &tech->items, &tech->items[i], &tech->items[i+1] );
497 WARN(_(
"Item '%s' not found in tech group"), value );
512 WARN(_(
"Trying to remove item '%s' to non-existent tech '%s'."), value, name );
517 tech = &tech_groups[id];
521 for (
int i=0; i<s; i++) {
523 if (strcmp(buf, value)==0) {
524 array_erase( &tech->items, &tech->items[i], &tech->items[i+1] );
529 WARN(_(
"Item '%s' not found in tech group '%s'"), value, name );
539 for (
int i=0; i<s; i++) {
540 tech_group_t *tech= &tech_groups[i];
541 if (tech->name == NULL)
543 if (strcmp(tech->name, name)==0)
593 memset( grp, 0,
sizeof(tech_group_t) );
596 for (
int i=0; i<num; i++)
609 for (
int i=0; i<size; i++) {
614 if (item->
type != type)
620 if (items[j] == item->
u.
ptr) {
635 for (
int i=0; i<size; i++) {
658 for (
int i=0; i<s; i++) {
660 if (strcmp(buf,item)==0)
689 names = malloc(
sizeof(
char*) * s );
691 for (
int i=0; i<s; i++)
709 names = malloc(
sizeof(
char*) * s );
711 for (
int i=0; i<s; i++)
712 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’.
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.
static char buf[NEWS_MAX_LENGTH]
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_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.