diff --git a/dat/fleetgroup.xml b/dat/fleetgroup.xml
new file mode 100644
index 0000000..541efc7
--- /dev/null
+++ b/dat/fleetgroup.xml
@@ -0,0 +1,128 @@
+
+
+
+ Goddard Goddard
+ Goddard Goddard
+
+
+ Trader Llama
+ Trader Llama
+ Trader Koala
+ Trader Koala
+ Trader Mule
+
+
+ Trader Llama
+ Trader Llama
+ Trader Koala
+ Trader Koala
+ Trader Mule
+ Trader Mule
+ Sml Trader Convoy
+
+
+ Trader Llama
+ Trader Llama
+ Trader Llama
+ Trader Koala
+ Trader Koala
+ Trader Koala
+ Trader Mule
+ Trader Mule
+ Trader Mule
+ Sml Trader Convoy
+ Sml Trader Convoy
+
+
+ Pirate Hyena
+ Pirate Vendetta
+ Pirate Ancestor
+ Pirate Hyena Pack
+ Pirate Admonisher
+
+
+ Pirate Hyena
+ Pirate Vendetta
+ Pirate Ancestor
+ Pirate Hyena Pack
+ Pirate Admonisher
+
+
+ Pirate Hyena
+ Pirate Hyena
+ Pirate Vendetta
+ Pirate Vendetta
+ Pirate Ancestor
+ Pirate Ancestor
+ Pirate Hyena Pack
+ Pirate Admonisher
+
+
+ Empire Pacifier
+ Empire Pacifier
+
+
+ Empire Lancelot
+ Empire Admonisher
+ Empire Pacifier
+
+
+ Empire Lancelot
+ Empire Lancelot
+ Empire Admonisher
+ Empire Pacifier
+
+
+ Empire Lancelot
+ Empire Lancelot
+ Empire Admonisher
+ Empire Admonisher
+ Empire Pacifier
+ Empire Pacifier
+ Empire Sml Defense
+
+
+ Collective Drone
+ Collective Drone
+ Collective Sml Swarm
+
+
+ Collective Drone
+ Collective Drone
+ Collective Drone
+ Collective Sml Swarm
+ Collective Sml Swarm
+
+
+ Dvaered Vendetta
+ Dvaered Vendetta
+ Dvaered Ancestor
+
+
+ Dvaered Vendetta
+ Dvaered Vendetta
+ Dvaered Ancestor
+ Dvaered Ancestor
+ Dvaered Goddard
+
+
+ Dvaered Vendetta
+ Dvaered Vendetta
+ Dvaered Vendetta
+ Dvaered Ancestor
+ Dvaered Ancestor
+ Dvaered Goddard
+ Dvaered Sml Force
+
+
+ FLF Vendetta
+ FLF Pacifier
+ FLF Sml Force
+
+
+ FLF Vendetta
+ FLF Pacifier
+ FLF Sml Force
+ FLF Med Force
+
+
diff --git a/src/fleet.c b/src/fleet.c
index cd20e76..575bfd0 100644
--- a/src/fleet.c
+++ b/src/fleet.c
@@ -1,33 +1,24 @@
/**
- * @file pilot.c
+ * @file fleet.c
*
- * @brief Handles the pilot stuff.
+ * @brief Handles the fleet stuff.
*/
+#include "fleet.h"
+
#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"
+#include "ldata.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 FLEET_DATA "../dat/fleet.xml" /**< Where to find fleet data. */
+#define FLEETGROUP_DATA "../dat/fleetgroup.xml" /**< Where to find fleetgroup. */
#define CHUNK_SIZE 32 /**< Size to allocate memory by. */
@@ -35,6 +26,13 @@
static Fleet* fleet_stack = NULL; /**< Fleet stack. */
static int nfleets = 0; /**< Number of fleets. */
+/* Stack of fleetgroups. */
+static FleetGroup* fleetgroup_stack = NULL; /**< FleetGroup stack. */
+static int nfleetgroups = 0; /**< Number of fleetgroups. */
+
+static int fleet_parse(Fleet* tmp, const xmlNodePtr parent);
+static int fleet_parseGroup(FleetGroup* fltgrp, xmlNodePtr parent);
+
/**
* @brief Grabs a fleet out of the stack.
* @param name Name of the fleet to match.
@@ -47,7 +45,21 @@ Fleet* fleet_get(const char* name) {
if(strcmp(fleet_stack[i].name, name)==0)
return &fleet_stack[i];
- WARN("Fleet '%s' not found in stack", name);
+ return NULL;
+}
+
+/**
+ * @brief Grab a fleetgroup out of the stack.
+ * @param name Name of the fleetgroup to match.
+ * @return The fleetgroup matching name or NULL if not found.
+ */
+FleetGroup* fleet_getGroup(const char* name) {
+ int i;
+
+ for(i = 0; i < nfleetgroups; i++)
+ if(strcmp(fleetgroup_stack[i].name, name)==0)
+ return &fleetgroup_stack[i];
+
return NULL;
}
@@ -136,29 +148,34 @@ static int fleet_parse(Fleet* tmp, const xmlNodePtr parent) {
* @brief Loads all the fleets.
* @return 0 on success.
*/
-int fleet_load(void) {
+static int fleet_loadFleets(void) {
int mem;
uint32_t bufsize;
- char* buf = ldata_read(FLEET_DATA, &bufsize);
+ char* buf;
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"'");
+ xmlDocPtr doc;
+
+ /* Load the data. */
+ buf = ldata_read(FLEET_DATA, &bufsize);
+ doc = xmlParseMemory(buf, bufsize);
+
+ node = doc->xmlChildrenNode; /* Fleets node. */
+ if(strcmp((char*)node->name, "Fleets")) {
+ ERR("Malformed "FLEET_DATA" file: missing root element 'Fleets'.");
return -1;
}
- node = node->xmlChildrenNode; /* First ship node. */
+ node = node->xmlChildrenNode; /* First fleet node. */
if(node == NULL) {
- ERR("Malformed "FLEET_DATA" file: does not contain elements");
+ ERR("Malformed "FLEET_DATA" file: does not contain elements.");
return -1;
}
mem = 0;
do {
- if(xml_isNode(node, XML_FLEET)) {
+ if(xml_isNode(node, "fleet")) {
/* See if memory must grow. */
nfleets++;
if(nfleets > mem) {
@@ -177,7 +194,127 @@ int fleet_load(void) {
xmlFreeDoc(doc);
free(buf);
- DEBUG("Loaded %d Fleets%s", nfleets, (nfleets == 1) ? "" : "s");
+ return 0;
+}
+
+/**
+ * @brief Parses a fleetgroup from an xml node.
+ * @param fltgrp FleetGroup to fill with data from the xml node.
+ * @param parent Node containing fleetgroup data.
+ * @return 0 on success.
+ */
+static int fleet_parseGroup(FleetGroup* fltgrp, xmlNodePtr parent) {
+ int mem;
+ xmlNodePtr node;
+ Fleet* f;
+ char* buf;
+
+ /* Clear memory. */
+ memset(fltgrp, 0, sizeof(FleetGroup));
+
+ /* Get the name. */
+ xmlr_attr(parent, "name", fltgrp->name);
+
+ /* Load the fleetgroup data. */
+ node = parent->children;
+ mem = 0;
+ do {
+ if(xml_isNode(node, "fleet")) {
+ /* See if memory must grow. */
+ fltgrp->nfleets++;
+ if(fltgrp->nfleets > mem) {
+ mem += CHUNK_SIZE;
+ fltgrp->fleets = realloc(fltgrp->fleets, sizeof(Fleet*) * mem);
+ fltgrp->chance = realloc(fltgrp->chance, sizeof(int) * mem);
+ }
+
+ /* Add the fleet. */
+ f = fleet_get(xml_get(node));
+ if(f == NULL) {
+ WARN("Fleet '%s' in FleetGroup '%s' not found in stack.",
+ xml_get(node), fltgrp->name);
+ fltgrp->nfleets--;
+ continue;
+ }
+ fltgrp->fleets[fltgrp->nfleets-1] = f;
+
+ /* Get the chance. */
+ xmlr_attr(node, "chance", buf);
+ if(buf == NULL) {
+ WARN("Fleet '%s' in FleetGroup '%s' missing 'chance' attribute.",
+ xml_get(node), fltgrp->name);
+ fltgrp->chance[fltgrp->nfleets-1] = 0;
+ continue;
+ }
+ fltgrp->chance[fltgrp->nfleets-1] = CLAMP(0, 100, atoi(buf));
+ }
+ } while(xml_nextNode(node));
+
+ return 0;
+}
+
+/**
+ * @brief Load all the fleetgroups.
+ * @return 0 on success.
+ */
+static int fleet_loadFleetGroups(void) {
+ int mem;
+ uint32_t bufsize;
+ char* buf;
+ xmlNodePtr node;
+ xmlDocPtr doc;
+
+ /* Create the document. */
+ buf = ldata_read(FLEETGROUP_DATA, &bufsize);
+ doc = xmlParseMemory(buf, bufsize);
+
+ node = doc->xmlChildrenNode; /* Fleetgroups node. */
+ if(strcmp((char*)node->name, "FleetGroups")) {
+ ERR("Malformed "FLEETGROUP_DATA" file: missing root element 'FleetGroups'");
+ return -1;
+ }
+
+ node = node->xmlChildrenNode; /* First fleetgroup node. */
+ if(node == NULL) {
+ ERR("Malformed "FLEETGROUP_DATA" file: does not contain elements");
+ return -1;
+ }
+
+ mem = 0;
+ do {
+ if(xml_isNode(node, "fleetgroup")) {
+ /* See if memory must grow. */
+ nfleetgroups++;
+ if(nfleets > mem) {
+ mem += CHUNK_SIZE;
+ fleetgroup_stack = realloc(fleetgroup_stack, sizeof(FleetGroup) * mem);
+ }
+
+ /* Load the fleetgroup. */
+ fleet_parseGroup(&fleetgroup_stack[nfleetgroups-1], node);
+ }
+ } while(xml_nextNode(node));
+
+ /* Shrink to minimum. */
+ fleet_stack = realloc(fleet_stack, sizeof(Fleet) * nfleets);
+
+ xmlFreeDoc(doc);
+ free(buf);
+
+ return 0;
+}
+
+/**
+ * @brief Load all the fleets and fleetgroups.
+ * @return 0 on success.
+ */
+int fleet_load(void) {
+ if(fleet_loadFleets())
+ return -1;
+ if(fleet_loadFleetGroups())
+ return -1;
+
+ DEBUG("Loaded %d Fleet%s", nfleets, (nfleets==1) ? "" : "s");
return 0;
}
@@ -200,8 +337,20 @@ void fleet_free(void) {
free(fleet_stack[i].ai);
}
free(fleet_stack);
- fleet_stack = NULL;
}
+ fleet_stack = NULL;
nfleets = 0;
+
+ /* Free the fleetgroup stack. */
+ if(fleetgroup_stack != NULL) {
+ for(i = 0; i < nfleetgroups; i++) {
+ free(fleetgroup_stack[i].name);
+ free(fleetgroup_stack[i].fleets);
+ free(fleetgroup_stack[i].chance);
+ }
+ free(fleetgroup_stack);
+ }
+ fleetgroup_stack = NULL;
+ nfleetgroups = 0;
}
diff --git a/src/fleet.h b/src/fleet.h
index 834981a..8da1b74 100644
--- a/src/fleet.h
+++ b/src/fleet.h
@@ -25,21 +25,36 @@ typedef struct FleetPilot_ {
* mission triggers.
*
* @sa FleetPilot
+ * @sa FleetGroup
*/
typedef struct Fleet_ {
- char* name; /**< Fleet name, used as the identifier. */
- int faction; /**< Faction of the fleet. */
-
- char* ai; /**< faction of the 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. */
+ int npilots; /**< Total number of pilots. */
} Fleet;
+/**
+ * @brief Represents a group of fleets.
+ *
+ * Used to simplify creation of star systems and easily synchonize all systems.
+ * with new ship additions.
+ *
+ * @sa Fleet
+ */
+typedef struct FleetGroup_ {
+ char* name; /** Name of the fleetgroup, used as the identifier. */
+ Fleet** fleets; /**< List of fleets in the group. */
+ int* chance; /**< Chance of each fleet in the group. */
+ int nfleets; /**< Number of fleets in the group. */
+} FleetGroup;
+
/*
* Get fleet stuff.
*/
Fleet* fleet_get(const char* name);
+FleetGroup* fleet_getGroup(const char* name);
/*
* Load / cleanup.
diff --git a/src/lephisto.h b/src/lephisto.h
index 92c778d..e8f5597 100644
--- a/src/lephisto.h
+++ b/src/lephisto.h
@@ -8,11 +8,12 @@
#define APPNAME "Lephisto" /**< Application name. */
-#define ABS(x) (((x)<0)?-(x):(x)) /**< Return absulute value. */
-#define FABS(x) (((x)<0.)?-(x):(x)) /**< Return float absolute value. */
+#define ABS(x) (((x)<0)?-(x):(x)) /**< Return absulute value. */
+#define FABS(x) (((x)<0.)?-(x):(x)) /**< Return float absolute value. */
-#define MAX(x,y) (((x)>(y))?(x):(y)) /**< Return maximum. */
-#define MIN(x,y) (((x)>(y))?(y):(x)) /**< Return minumum. */
+#define MAX(x,y) (((x)>(y))?(x):(y)) /**< Return maximum. */
+#define MIN(x,y) (((x)>(y))?(y):(x)) /**< Return minumum. */
+#define CLAMP(a, b, x) ((x)<(a)?(a):((x)>(b)?(b):(x))) /**< Clamps x between a and b: a <= x <= b */
#define pow2(x) ((x)*(x)) /**< ^2 */
diff --git a/src/perlin.c b/src/perlin.c
index 5bd74c0..9de13bb 100644
--- a/src/perlin.c
+++ b/src/perlin.c
@@ -34,10 +34,6 @@
* @brief Ponderates x between a and b.
*/
#define LERP(a, b, x) (a + x * (b - a))
-/**
- * @brief Clamps x between a and b: a <= x <= b.
- */
-#define CLAMP(a, b, x) ((x) < (a) ? (a) : ((x) > (b) ? (b) : (x)))
/**
* @brief Structure used for generating noise.