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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<FleetGroups> + <fleetgroup name="Goddard Prescence"> + <fleet chance="50">Goddard Goddard</fleet> + <fleet chance="50">Goddard Goddard</fleet> + </fleetgroup> + <fleetgroup name="Trader Light Prescence"> + <fleet chance="50">Trader Llama</fleet> + <fleet chance="40">Trader Llama</fleet> + <fleet chance="40">Trader Koala</fleet> + <fleet chance="30">Trader Koala</fleet> + <fleet chance="30">Trader Mule</fleet> + </fleetgroup> + <fleetgroup name="Trader Medium Prescence"> + <fleet chance="70">Trader Llama</fleet> + <fleet chance="60">Trader Llama</fleet> + <fleet chance="60">Trader Koala</fleet> + <fleet chance="50">Trader Koala</fleet> + <fleet chance="50">Trader Mule</fleet> + <fleet chance="40">Trader Mule</fleet> + <fleet chance="30">Sml Trader Convoy</fleet> + </fleetgroup> + <fleetgroup name="Trader Heavy Prescence"> + <fleet chance="80">Trader Llama</fleet> + <fleet chance="70">Trader Llama</fleet> + <fleet chance="60">Trader Llama</fleet> + <fleet chance="70">Trader Koala</fleet> + <fleet chance="60">Trader Koala</fleet> + <fleet chance="50">Trader Koala</fleet> + <fleet chance="60">Trader Mule</fleet> + <fleet chance="50">Trader Mule</fleet> + <fleet chance="40">Trader Mule</fleet> + <fleet chance="40">Sml Trader Convoy</fleet> + <fleet chance="30">Sml Trader Convoy</fleet> + </fleetgroup> + <fleetgroup name="Pirate Light Prescence"> + <fleet chance="50">Pirate Hyena</fleet> + <fleet chance="40">Pirate Vendetta</fleet> + <fleet chance="30">Pirate Ancestor</fleet> + <fleet chance="20">Pirate Hyena Pack</fleet> + <fleet chance="5" >Pirate Admonisher</fleet> + </fleetgroup> + <fleetgroup name="Pirate Medium Prescence"> + <fleet chance="50">Pirate Hyena</fleet> + <fleet chance="60">Pirate Vendetta</fleet> + <fleet chance="50">Pirate Ancestor</fleet> + <fleet chance="30">Pirate Hyena Pack</fleet> + <fleet chance="20">Pirate Admonisher</fleet> + </fleetgroup> + <fleetgroup name="Pirate Heavy Prescence"> + <fleet chance="80">Pirate Hyena</fleet> + <fleet chance="50">Pirate Hyena</fleet> + <fleet chance="80">Pirate Vendetta</fleet> + <fleet chance="60">Pirate Vendetta</fleet> + <fleet chance="70">Pirate Ancestor</fleet> + <fleet chance="50">Pirate Ancestor</fleet> + <fleet chance="50">Pirate Hyena Pack</fleet> + <fleet chance="40">Pirate Admonisher</fleet> + </fleetgroup> + <fleetgroup name="Empire Patrol Prescence"> + <fleet chance="70">Empire Pacifier</fleet> + <fleet chance="20">Empire Pacifier</fleet> + </fleetgroup> + <fleetgroup name="Empire Light Prescence"> + <fleet chance="50">Empire Lancelot</fleet> + <fleet chance="30">Empire Admonisher</fleet> + <fleet chance="10">Empire Pacifier</fleet> + </fleetgroup> + <fleetgroup name="Empire Medium Prescence"> + <fleet chance="60">Empire Lancelot</fleet> + <fleet chance="30">Empire Lancelot</fleet> + <fleet chance="45">Empire Admonisher</fleet> + <fleet chance="25">Empire Pacifier</fleet> + </fleetgroup> + <fleetgroup name="Empire Heavy Prescence"> + <fleet chance="80">Empire Lancelot</fleet> + <fleet chance="70">Empire Lancelot</fleet> + <fleet chance="60">Empire Admonisher</fleet> + <fleet chance="50">Empire Admonisher</fleet> + <fleet chance="40">Empire Pacifier</fleet> + <fleet chance="30">Empire Pacifier</fleet> + <fleet chance="50">Empire Sml Defense</fleet> + </fleetgroup> + <fleetgroup name="Collective Light Prescence"> + <fleet chance="80">Collective Drone</fleet> + <fleet chance="40">Collective Drone</fleet> + <fleet chance="20">Collective Sml Swarm</fleet> + </fleetgroup> + <fleetgroup name="Collective Medium Prescence"> + <fleet chance="80">Collective Drone</fleet> + <fleet chance="60">Collective Drone</fleet> + <fleet chance="40">Collective Drone</fleet> + <fleet chance="40">Collective Sml Swarm</fleet> + <fleet chance="20">Collective Sml Swarm</fleet> + </fleetgroup> + <fleetgroup name="Dvaered Light Prescence"> + <fleet chance="70">Dvaered Vendetta</fleet> + <fleet chance="20">Dvaered Vendetta</fleet> + <fleet chance="40">Dvaered Ancestor</fleet> + </fleetgroup> + <fleetgroup name="Dvaered Medium Prescence"> + <fleet chance="70">Dvaered Vendetta</fleet> + <fleet chance="50">Dvaered Vendetta</fleet> + <fleet chance="60">Dvaered Ancestor</fleet> + <fleet chance="40">Dvaered Ancestor</fleet> + <fleet chance="5" >Dvaered Goddard</fleet> + </fleetgroup> + <fleetgroup name="Dvaered Heavy Prescence"> + <fleet chance="80">Dvaered Vendetta</fleet> + <fleet chance="60">Dvaered Vendetta</fleet> + <fleet chance="40">Dvaered Vendetta</fleet> + <fleet chance="60">Dvaered Ancestor</fleet> + <fleet chance="40">Dvaered Ancestor</fleet> + <fleet chance="15">Dvaered Goddard</fleet> + <fleet chance="30">Dvaered Sml Force</fleet> + </fleetgroup> + <fleetgroup name="FLF Light Guerrilla"> + <fleet chance="20">FLF Vendetta</fleet> + <fleet chance="10">FLF Pacifier</fleet> + <fleet chance="5" >FLF Sml Force</fleet> + </fleetgroup> + <fleetgroup name="FLF Medium Guerrilla"> + <fleet chance="30">FLF Vendetta</fleet> + <fleet chance="20">FLF Pacifier</fleet> + <fleet chance="15">FLF Sml Force</fleet> + <fleet chance="5" >FLF Med Force</fleet> + </fleetgroup> +</FleetGroups> 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 <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> #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.