From 1d53467491f7f172f7405ad00ed671c24f892fef Mon Sep 17 00:00:00 2001 From: Allanis Date: Sat, 18 Oct 2014 22:26:05 +0100 Subject: [PATCH] [Change] Modulised fleet stuff. --- src/fleet.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++++ src/fleet.h | 49 ++++++++++++ src/lephisto.c | 1 + src/pilot.c | 162 -------------------------------------- src/pilot.h | 38 --------- src/space.c | 1 + src/space.h | 1 + src/unidiff.c | 1 + 8 files changed, 260 insertions(+), 200 deletions(-) create mode 100644 src/fleet.c create mode 100644 src/fleet.h diff --git a/src/fleet.c b/src/fleet.c new file mode 100644 index 0000000..cd20e76 --- /dev/null +++ b/src/fleet.c @@ -0,0 +1,207 @@ +/** + * @file pilot.c + * + * @brief Handles the pilot stuff. + */ + +#include +#include +#include +#include + +#include "lxml.h" + +#include "lephisto.h" +#include "log.h" +#include "weapon.h" +#include "ldata.h" +#include "spfx.h" +#include "rng.h" +#include "hook.h" +#include "map.h" +#include "explosion.h" +#include "escort.h" +#include "music.h" +#include "pilot.h" + +#define XML_ID "Fleets" /**< XML document identifier. */ +#define XML_FLEET "fleet" /**< XML individual fleet identifier. */ + +#define FLEET_DATA "../dat/fleet.xml" /**< Where to find fleet data. */ + +#define CHUNK_SIZE 32 /**< Size to allocate memory by. */ + +/* Stack of fleets. */ +static Fleet* fleet_stack = NULL; /**< Fleet stack. */ +static int nfleets = 0; /**< Number of fleets. */ + +/** + * @brief Grabs a fleet out of the stack. + * @param name Name of the fleet to match. + * @return The fleet mactching name or NULL if not found. + */ +Fleet* fleet_get(const char* name) { + int i; + + for(i = 0; i < nfleets; i++) + if(strcmp(fleet_stack[i].name, name)==0) + return &fleet_stack[i]; + + WARN("Fleet '%s' not found in stack", name); + return NULL; +} + +/** + * @brief Parses the fleet node. + * @param tmp Fleet to load. + * @param parent Parent xml node of the fleet in question. + * @return A newly allocated fleet loaded with data in parent node. + */ +static int fleet_parse(Fleet* tmp, const xmlNodePtr parent) { + xmlNodePtr cur, node; + FleetPilot* pilot; + char* c; + int mem; + node = parent->xmlChildrenNode; + + /* Sane defaults and clean up. */ + memset(tmp, 0, sizeof(Fleet)); + tmp->faction = -1; + + tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); /* Already mallocs. */ + if(tmp->name == NULL) WARN("Fleet in "FLEET_DATA" has invalid or no name"); + + do { /* Load all the data. */ + if(xml_isNode(node, "faction")) + tmp->faction = faction_get(xml_get(node)); + else if(xml_isNode(node, "ai")) + tmp->ai = xml_getStrd(node); + else if(xml_isNode(node, "pilots")) { + cur = node->children; + mem = 0; + do { + if(xml_isNode(cur, "pilot")) { + /* See if must grow. */ + tmp->npilots++; + if(tmp->npilots > mem) { + mem += CHUNK_SIZE; + tmp->pilots = realloc(tmp->pilots, mem * sizeof(FleetPilot)); + } + pilot = &tmp->pilots[tmp->npilots-1]; + + /* Clear memory. */ + memset(pilot, 0, sizeof(FleetPilot)); + + /* Check for name override. */ + xmlr_attr(cur, "name", c); + pilot->name = c; /* No need to free since it will have later. */ + + /* Check for ai override. */ + xmlr_attr(cur, "ai", pilot->ai); + + /* Load pilots ship. */ + pilot->ship = ship_get(xml_get(cur)); + if(pilot->ship == NULL) + WARN("Pilot %s in Fleet %s has null ship", pilot->name, tmp->name); + + /* Load chance. */ + xmlr_attr(cur, "chance", c); + pilot->chance = atoi(c); + if(pilot->chance == 0) + WARN("Pilot %s in Fleet %s has 0%% chance of appearing", + pilot->name, tmp->name); + + if(c != NULL) + free(c); /* Free the external malloc. */ + } + } while(xml_nextNode(cur)); + + /* Resize to minimum. */ + tmp->pilots = realloc(tmp->pilots, sizeof(FleetPilot)*tmp->npilots); + } + } while(xml_nextNode(node)); + +#define MELEMENT(o,s) \ + if(o) WARN("Fleet '%s' missing '"s"' element", tmp->name) + /**< Hack to check for missing fields. */ + MELEMENT(tmp->ai == NULL, "ai"); + MELEMENT(tmp->faction == -1, "faction"); + MELEMENT(tmp->pilots == NULL, "pilots"); +#undef MELEMENT + + return 0; +} + +/** + * @brief Loads all the fleets. + * @return 0 on success. + */ +int fleet_load(void) { + int mem; + uint32_t bufsize; + char* buf = ldata_read(FLEET_DATA, &bufsize); + + xmlNodePtr node; + xmlDocPtr doc = xmlParseMemory(buf, bufsize); + + node = doc->xmlChildrenNode; /* Ships node. */ + if(strcmp((char*)node->name, XML_ID)) { + ERR("Malformed "FLEET_DATA" file: missing root element '"XML_ID"'"); + return -1; + } + + node = node->xmlChildrenNode; /* First ship node. */ + if(node == NULL) { + ERR("Malformed "FLEET_DATA" file: does not contain elements"); + return -1; + } + + mem = 0; + do { + if(xml_isNode(node, XML_FLEET)) { + /* See if memory must grow. */ + nfleets++; + if(nfleets > mem) { + mem += CHUNK_SIZE; + fleet_stack = realloc(fleet_stack, sizeof(Fleet) * mem); + } + + /* Load the fleet. */ + fleet_parse(&fleet_stack[nfleets-1], node); + } + } while(xml_nextNode(node)); + + /* Shrink to minimum. */ + fleet_stack = realloc(fleet_stack, sizeof(Fleet) * nfleets); + + xmlFreeDoc(doc); + free(buf); + + DEBUG("Loaded %d Fleets%s", nfleets, (nfleets == 1) ? "" : "s"); + + return 0; +} + +/** + * @brief Cleans up by freeing all the fleet data. + */ +void fleet_free(void) { + int i,j; + if(fleet_stack != NULL) { + for(i = 0; i < nfleets; i++) { + for(j = 0; j < fleet_stack[i].npilots; j++) { + if(fleet_stack[i].pilots[j].name) + free(fleet_stack[i].pilots[j].name); + if(fleet_stack[i].pilots[j].ai) + free(fleet_stack[i].pilots[j].ai); + } + free(fleet_stack[i].name); + free(fleet_stack[i].pilots); + free(fleet_stack[i].ai); + } + free(fleet_stack); + fleet_stack = NULL; + } + nfleets = 0; +} + diff --git a/src/fleet.h b/src/fleet.h new file mode 100644 index 0000000..834981a --- /dev/null +++ b/src/fleet.h @@ -0,0 +1,49 @@ +#pragma once +#include "pilot.h" + +/** + * @struct FleetPilot + * + * @brief Represents a pilot in a fleet. + * + * @sa Fleet + * @sa Pilot + */ +typedef struct FleetPilot_ { + Ship* ship; /**< Ship the pilot is flying. */ + char* name; /**< Used if they have a special name like uniques. */ + int chance; /**< Chance of this pilot appearing in the fleet. */ + char* ai; /**< ai different of fleets global ai. */ +} FleetPilot; + +/** + * @struct Fleet + * + * @brief Represenets a fleet. + * + * Fleets are used to create pilots, both from being in a system and from + * mission triggers. + * + * @sa FleetPilot + */ +typedef struct Fleet_ { + char* name; /**< Fleet name, used as the identifier. */ + int faction; /**< Faction of the fleet. */ + + char* ai; /**< faction of the fleet. */ + + FleetPilot* pilots; /**< The pilots in the fleet. */ + int npilots; /**< Total number of pilots. */ +} Fleet; + +/* + * Get fleet stuff. + */ +Fleet* fleet_get(const char* name); + +/* + * Load / cleanup. + */ +int fleet_load(void); +void fleet_free(void); + diff --git a/src/lephisto.c b/src/lephisto.c index b90a024..0d42234 100644 --- a/src/lephisto.c +++ b/src/lephisto.c @@ -31,6 +31,7 @@ #include "font.h" #include "ship.h" #include "pilot.h" +#include "fleet.h" #include "player.h" #include "input.h" #include "joystick.h" diff --git a/src/pilot.c b/src/pilot.c index 368a9a5..adbe553 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -23,11 +23,6 @@ #include "music.h" #include "pilot.h" -#define XML_ID "Fleets" /**< XML document identifier. */ -#define XML_FLEET "fleet" /**< XML individual fleet identifier. */ - -#define FLEET_DATA "../dat/fleet.xml" /**< Where to find fleet data. */ - #define PILOT_CHUNK 32 /**< Chunks to increment pilot_stack by. */ #define CHUNK_SIZE 32 /**< Size to allocate memory by. */ @@ -48,10 +43,6 @@ extern double player_crating; /**< Players combat rating. */ extern void player_abortAutonav(char* reason); extern int player_enemies; -/* Stack of fleets. */ -static Fleet* fleet_stack = NULL; /** Fleet stack. */ -static int nfleets = 0; /** Number of fleets. */ - /* External. */ /* AI. */ extern AI_Profile* ai_pinit(Pilot* p, char* ai); @@ -73,7 +64,6 @@ static void pilot_hyperspace(Pilot* pilot); void pilot_render(Pilot* pilot); static void pilot_calcCargo(Pilot* pilot); void pilot_free(Pilot* p); /* Externed in player.c */ -static int fleet_parse(Fleet* tmp, const xmlNodePtr parent); static void pilot_dead(Pilot* p); static int pilot_setOutfitMounts(Pilot* p, PilotOutfit* po, int o, int q); static void pilot_setSecondary(Pilot* p, Outfit* o); @@ -190,17 +180,6 @@ Pilot* pilot_get(const unsigned int id) { return pilot_stack[m]; } -/* Grab a fleet out of the stack. */ -Fleet* fleet_get(const char* name) { - int i; - for(i = 0; i < nfleets; i++) - if(strcmp(fleet_stack[i].name, name)==0) - return &fleet_stack[i]; - - WARN("Fleet '%s' not found in stack", name); - return NULL; -} - /** * @brief Check to see if pilot is hostile to the player. * @param p Player to see if is hostile. @@ -1987,144 +1966,3 @@ void pilots_render(void) { } } -/* Parse the fleet node. */ -static int fleet_parse(Fleet* tmp, const xmlNodePtr parent) { - xmlNodePtr cur, node; - FleetPilot* pilot; - char* c; - int mem; - node = parent->xmlChildrenNode; - - /* Sane defaults and clean up. */ - memset(tmp, 0, sizeof(Fleet)); - tmp->faction = -1; - - tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); /* Already mallocs. */ - if(tmp->name == NULL) WARN("Fleet in "FLEET_DATA" has invalid or no name"); - - do { - /* Load all the data. */ - if(xml_isNode(node, "faction")) - tmp->faction = faction_get(xml_get(node)); - else if(xml_isNode(node, "ai")) - tmp->ai = xml_getStrd(node); - else if(xml_isNode(node, "pilots")) { - cur = node->children; - mem = 0; - do { - if(xml_isNode(cur, "pilot")) { - /* See if we must grow. */ - tmp->npilots++; - if(tmp->npilots > mem) { - mem += CHUNK_SIZE; - tmp->pilots = realloc(tmp->pilots, mem * sizeof(FleetPilot)); - } - pilot = &tmp->pilots[tmp->npilots-1]; - - /* Clear memory. */ - memset(pilot, 0, sizeof(FleetPilot)); - - /* Check for name override. */ - xmlr_attr(cur, "name", c); - pilot->name = c; /* No need to free since it will have to later. */ - - /* Check for ai override. */ - xmlr_attr(cur, "ai", pilot->ai); - - /* Load pilots ship. */ - pilot->ship = ship_get(xml_get(cur)); - if(pilot->ship == NULL) - WARN("Pilot %s in Fleet %s has null ship", pilot->name, tmp->name); - - /* Load chance. */ - xmlr_attr(cur, "chance", c); - pilot->chance = atoi(c); - if(pilot->chance == 0) - WARN("Pilot %s in Fleet %s has 0%% chance of appearing", - pilot->name, tmp->name); - - if(c != NULL) - free(c); /* Free the external malloc. */ - } - } while(xml_nextNode(cur)); - - /* Resize to minimum. */ - tmp->pilots = realloc(tmp->pilots, sizeof(FleetPilot)*tmp->npilots); - } - } while(xml_nextNode(node)); -#define MELEMENT(o,s) if(o) WARN("Fleet '%s' missing '"s"' element", tmp->name) - MELEMENT(tmp->ai==NULL, "ai"); - MELEMENT(tmp->faction==-1, "faction"); - MELEMENT(tmp->pilots==NULL, "pilots"); -#undef MELEMENT - - return 0; -} - -/* Load the fleets. */ -int fleet_load(void) { - int mem; - uint32_t bufsize; - char* buf = ldata_read(FLEET_DATA, &bufsize); - - xmlNodePtr node; - xmlDocPtr doc = xmlParseMemory(buf, bufsize); - - node = doc->xmlChildrenNode; /* Ships node. */ - if(strcmp((char*)node->name, XML_ID)) { - ERR("Malformed "FLEET_DATA" file: missing root element '"XML_ID"'"); - return -1; - } - node = node->xmlChildrenNode; /* First ship node. */ - if(node == NULL) { - ERR("Malformed "FLEET_DATA" file: does not contain elements"); - return -1; - } - - mem = 0; - do { - if(xml_isNode(node, XML_FLEET)) { - /* See if memory must grow. */ - nfleets++; - if(nfleets > mem) { - mem += CHUNK_SIZE; - fleet_stack = realloc(fleet_stack, sizeof(Fleet)*mem); - } - - /* Load the fleet. */ - fleet_parse(&fleet_stack[nfleets-1], node); - } - } while(xml_nextNode(node)); - - /* Shrink to minimum. */ - fleet_stack = realloc(fleet_stack, sizeof(Fleet)*nfleets); - - xmlFreeDoc(doc); - free(buf); - - DEBUG("Loaded %d fleet%s", nfleets, (nfleets==1) ? "" : "s"); - - return 0; -} - -/* Free the fleets. */ -void fleet_free(void) { - int i, j; - if(fleet_stack != NULL) { - for(i = 0; i < nfleets; i++) { - for(j = 0; j < fleet_stack[i].npilots; j++) { - if(fleet_stack[i].pilots[j].name) - free(fleet_stack[i].pilots[j].name); - if(fleet_stack[i].pilots[j].ai) - free(fleet_stack[i].pilots[j].ai); - } - free(fleet_stack[i].name); - free(fleet_stack[i].pilots); - free(fleet_stack[i].ai); - } - free(fleet_stack); - fleet_stack = NULL; - } - nfleets = 0; -} - diff --git a/src/pilot.h b/src/pilot.h index 32fe443..f72468c 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -195,41 +195,6 @@ typedef struct Pilot_ { Task* task; /**< Current action. */ } Pilot; -/** - * @struct FleetPilot - * - * @brief Represents a pilot in a fleet. - * - * @sa Fleet - * @sa Pilot - */ -typedef struct FleetPilot_ { - Ship* ship; /**< Ship that the pilot is flying. */ - char* name; /**< For special 'unique' names. */ - int chance; /**< Chance of this pilot appearing in the fleet. */ - char* ai; /**< Ai difference of fleet's global ai. */ -} FleetPilot; - -/** - * @struct Fleet - * - * @brief Represents a fleet. - * - * Fleets are used to create pilots, both from being in a system and from - * mission triggers. - * - * @sa FleetPilot - */ -typedef struct Fleet_ { - char* name; /**< Fleet name, used as an identifier. */ - int faction; /**< Faction of the fleet. */ - - char* ai; /**< AI profile to use. */ - - FleetPilot* pilots; /**< The pilots in the fleet. */ - int npilots; /**< Total number of pilots. */ -} Fleet; - /* Grabing pilot crap. */ extern Pilot* player; /* The player. */ Pilot* pilot_get(unsigned int id); @@ -238,7 +203,6 @@ unsigned int pilot_getPrevID(const unsigned int id); unsigned int pilot_getNearestEnemy(const Pilot* p); unsigned int pilot_getNearestHostile(void); /* Only for the player. */ unsigned int pilot_getNearestPilot(const Pilot* p); -Fleet* fleet_get(const char* name); int pilot_getJumps(const Pilot* p); /* Misc. */ @@ -297,8 +261,6 @@ void pilots_free(void); void pilots_clean(void); void pilots_cleanAll(void); void pilot_free(Pilot* p); -int fleet_load(void); -void fleet_free(void); void pilot_setHostile(Pilot* p); void pilot_rmHostile(Pilot* p); diff --git a/src/space.c b/src/space.c index 2f7440c..5f18c53 100644 --- a/src/space.c +++ b/src/space.c @@ -17,6 +17,7 @@ #include "nebulae.h" #include "music.h" #include "gui.h" +#include "fleet.h" #include "space.h" #define XML_PLANET_ID "Planets" diff --git a/src/space.h b/src/space.h index af0f159..6d16622 100644 --- a/src/space.h +++ b/src/space.h @@ -3,6 +3,7 @@ #include "opengl.h" #include "economy.h" #include "pilot.h" +#include "fleet.h" #define MAX_HYPERSPACE_VEL 25 /**< Speed to brake to before jumping. */ diff --git a/src/unidiff.c b/src/unidiff.c index f79abfc..45dfcab 100644 --- a/src/unidiff.c +++ b/src/unidiff.c @@ -16,6 +16,7 @@ #include "lxml.h" #include "space.h" #include "ldata.h" +#include "fleet.h" #include "unidiff.h" #define CHUNK_SIZE 32 /**< Size of chunk to allocate. */