#include #include #include #include "lephisto.h" #include "xml.h" #include "pack.h" #include "log.h" #include "economy.h" #define XML_COMMODITY_ID "Commodities" // XML section identifier. #define XML_COMMODITY_TAG "commodity" #define COMMODITY_DATA "../dat/commodity.xml" // Commodity stack. static Commodity* commodity_stack = NULL; static int commodity_nstack = 0; static void commodity_freeOne(Commodity* com); static Commodity* commodity_parse(xmlNodePtr parent); // Convert credits to a usable string for displaying. // str must have 10 characters allocated. void credits2str(char* str, unsigned int credits, int decimals) { if(decimals < 0) snprintf(str, 32, "%d", credits); else if(credits >= 1000000000) snprintf(str, 16, "%.*fB", decimals, (double)credits / 1000000000.); else if(credits >= 1000000) snprintf(str, 16, "%*fM", decimals, (double)credits / 1000000.); else if(credits >= 1000) snprintf(str, 16, "%.*fK", decimals, (double)credits / 1000.); else snprintf(str, 16, "%d", credits); } // Get a commodity. Commodity* commodity_get(const char* name) { int i; for(i = 0; i < commodity_nstack; i++) if(strcmp(commodity_stack[i].name, name)==0) return &commodity_stack[i]; WARN("Commodity '%s' not found in stack", name); return NULL; } // Free a commodity. static void commodity_freeOne(Commodity* com) { if(com->name) free(com->name); } static Commodity* commodity_parse(xmlNodePtr parent) { xmlNodePtr node; Commodity* tmp = CALLOC_L(Commodity); tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); if(tmp->name == NULL) WARN("Commodity from "COMMODITY_DATA" has invalid or noname"); node = parent->xmlChildrenNode; do { if(xml_isNode(node, "high")) tmp->high = xml_getInt(node); else if(xml_isNode(node, "medium")) tmp->medium = xml_getInt(node); else if(xml_isNode(node, "low")) tmp->low = xml_getInt(node); } while((node = node->next)); #define MELEMENT(o,s)if(o)WARN("Commodity '%s' missing '"s"' element",tmp->name) MELEMENT(tmp->high==0, "high"); MELEMENT(tmp->medium==0, "medium"); MELEMENT(tmp->low==0, "low"); #undef MELEMENT return tmp; } int commodity_load(void) { uint32_t bufsize; char* buf = pack_readfile(DATA, COMMODITY_DATA, &bufsize); xmlNodePtr node; xmlDocPtr doc = xmlParseMemory(buf, bufsize); Commodity* tmp = NULL; node = doc->xmlChildrenNode; // Commoditys node. if(strcmp((char*)node->name, XML_COMMODITY_ID)) { ERR("Malformed "COMMODITY_DATA " file: Missing root element '"XML_COMMODITY_ID"'"); return -1; } node = node->xmlChildrenNode; // First faction node. if(node == NULL) { ERR("Malformed "COMMODITY_DATA" file: does not contain elements"); return -1; } do { if(node->type == XML_NODE_START) { if(strcmp((char*)node->name, XML_COMMODITY_TAG)==0) { tmp = commodity_parse(node); commodity_stack = realloc(commodity_stack, sizeof(Commodity)*(++commodity_nstack)); memcpy(commodity_stack+commodity_nstack-1, tmp, sizeof(Commodity)); free(tmp); } } } while((node = node->next)); xmlFreeDoc(doc); free(buf); xmlCleanupParser(); DEBUG("Loaded %d commodit%s", commodity_nstack, (commodity_nstack==1) ? "y" : "ies"); return 0; } void commodity_free(void) { int i; for(i = 0; i < commodity_nstack; i++) commodity_freeOne(&commodity_stack[i]); free(commodity_stack); commodity_stack = NULL; commodity_nstack = 0; }