[Change] Improved outfit loading somewhat.

This commit is contained in:
Allanis 2014-01-21 20:07:29 +00:00
parent 20244a585d
commit 0c1f50a2ff
4 changed files with 62 additions and 37 deletions

View File

@ -18,6 +18,8 @@
#define OUTFIT_DATA "../dat/outfit.xml" #define OUTFIT_DATA "../dat/outfit.xml"
#define OUTFIT_GFX "../gfx/outfit/" #define OUTFIT_GFX "../gfx/outfit/"
#define CHUNK_SIZE 64 /** Size to reallocate by. */
/* The Stack. */ /* The Stack. */
static Outfit* outfit_stack = NULL; static Outfit* outfit_stack = NULL;
static int outfit_nstack = 0; static int outfit_nstack = 0;
@ -27,7 +29,7 @@ static DamageType outfit_strToDamageType(char* buf);
static OutfitType outfit_strToOutfitType(char* buf); static OutfitType outfit_strToOutfitType(char* buf);
/* Parsing. */ /* Parsing. */
static int outfit_parseDamage(DamageType* dtype, double* dmg, xmlNodePtr node); static int outfit_parseDamage(DamageType* dtype, double* dmg, xmlNodePtr node);
static Outfit* outfit_parse(const xmlNodePtr parent); static int outfit_parse(Outfit* tmp, const xmlNodePtr parent);
static void outfit_parseSBolt(Outfit* tmp, const xmlNodePtr parent); static void outfit_parseSBolt(Outfit* tmp, const xmlNodePtr parent);
static void outfit_parseSBeam(Outfit* tmp, const xmlNodePtr parent); static void outfit_parseSBeam(Outfit* tmp, const xmlNodePtr parent);
static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent); static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent);
@ -368,12 +370,10 @@ int outfit_delay(const Outfit* o) {
} }
/** /**
* @fn char* outfit_ammo(const Outfit* o)
*
* @brief Get the outfits ammo. * @brief Get the outfits ammo.
* @param o Outfit to get information from. * @param o Outfit to get information from.
*/ */
char* outfit_ammo(const Outfit* o) { Outfit* outfit_ammo(const Outfit* o) {
if(outfit_isLauncher(o)) return o->u.lau.ammo; if(outfit_isLauncher(o)) return o->u.lau.ammo;
else if(outfit_isFighterBay(o)) return o->u.bay.ammo; else if(outfit_isFighterBay(o)) return o->u.bay.ammo;
return NULL; return NULL;
@ -671,12 +671,12 @@ static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent) {
do { do {
/* Load the dataz. */ /* Load the dataz. */
xmlr_int(node, "delay", tmp->u.lau.delay); xmlr_int(node, "delay", tmp->u.lau.delay);
xmlr_strd(node, "ammo", tmp->u.lau.ammo); xmlr_strd(node, "ammo", tmp->u.lau.ammo_name);
} while((node = node->next)); } while((node = node->next));
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name) #define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
MELEMENT(tmp->u.lau.ammo == NULL, "ammo"); MELEMENT(tmp->u.lau.ammo_name == NULL, "ammo");
MELEMENT(tmp->u.lau.delay==0, "delay"); MELEMENT(tmp->u.lau.delay==0, "delay");
#undef MELEMENT #undef MELEMENT
} }
@ -792,13 +792,13 @@ static void outfit_parseSFighterBay(Outfit* tmp, const xmlNodePtr parent) {
do { do {
xmlr_int(node, "delay", tmp->u.bay.delay); xmlr_int(node, "delay", tmp->u.bay.delay);
xmlr_strd(node, "ammo", tmp->u.bay.ammo); xmlr_strd(node, "ammo", tmp->u.bay.ammo_name);
} while(xml_nextNode(node)); } while(xml_nextNode(node));
#define MELEMENT(o,s) \ #define MELEMENT(o,s) \
if(o) WARN("Outfit '%s' missing/invalid '"s"' element", tmp->name) if(o) WARN("Outfit '%s' missing/invalid '"s"' element", tmp->name)
MELEMENT(tmp->u.bay.delay==0, "delay"); MELEMENT(tmp->u.bay.delay==0, "delay");
MELEMENT(tmp->u.bay.ammo==NULL, "ammo"); MELEMENT(tmp->u.bay.ammo_name==NULL, "ammo");
#undef MELEMENT #undef MELEMENT
} }
@ -857,12 +857,14 @@ static void outfit_parseSJammer(Outfit* tmp, const xmlNodePtr parent) {
} }
/* Parse and return Outfits from parent node. */ /* Parse and return Outfits from parent node. */
static Outfit* outfit_parse(const xmlNodePtr parent) { static int outfit_parse(Outfit* tmp, const xmlNodePtr parent) {
Outfit* tmp = CALLOC_L(Outfit);
xmlNodePtr cur, node; xmlNodePtr cur, node;
char* prop; char* prop;
char str[PATH_MAX] = "\0"; char str[PATH_MAX] = "\0";
/* Clear data. */
memset(tmp, 0, sizeof(Outfit));
tmp->name = xml_nodeProp(parent, "name"); /* Already malloced. */ tmp->name = xml_nodeProp(parent, "name"); /* Already malloced. */
if(tmp->name == NULL) WARN("Outfit in "OUTFIT_DATA" has invalid or no name"); if(tmp->name == NULL) WARN("Outfit in "OUTFIT_DATA" has invalid or no name");
@ -934,16 +936,15 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
MELEMENT(tmp->description==NULL, "description"); MELEMENT(tmp->description==NULL, "description");
#undef MELEMENT #undef MELEMENT
return tmp; return 0;
} }
/* Load all the outfits into the outfit stack. */ /* Load all the outfits into the outfit stack. */
int outfit_load(void) { int outfit_load(void) {
int i, mem;
uint32_t bufsize; uint32_t bufsize;
char* buf = pack_readfile(DATA, OUTFIT_DATA, &bufsize); char* buf = pack_readfile(DATA, OUTFIT_DATA, &bufsize);
Outfit* tmp;
xmlNodePtr node; xmlNodePtr node;
xmlDocPtr doc = xmlParseMemory(buf, bufsize); xmlDocPtr doc = xmlParseMemory(buf, bufsize);
@ -959,15 +960,27 @@ int outfit_load(void) {
return -1; return -1;
} }
/* First pass, load up ammunition. */
mem = 0;
do { do {
if(xml_isNode(node, XML_OUTFIT_TAG)) { if(xml_isNode(node, XML_OUTFIT_TAG)) {
tmp = outfit_parse(node); outfit_nstack++;
outfit_stack = realloc(outfit_stack, sizeof(Outfit)*(++outfit_nstack)); if(outfit_nstack > mem) {
memmove(outfit_stack+outfit_nstack-1, tmp, sizeof(Outfit)); mem += CHUNK_SIZE;
free(tmp); outfit_stack = realloc(outfit_stack, sizeof(Outfit)*mem);
}
outfit_parse(&outfit_stack[outfit_nstack-1], node);
} }
} while((node = node->next)); } while((node = node->next));
/* Second pass, set up ammunition relationships. */
for(i = 0; i < outfit_nstack; i++) {
if(outfit_isLauncher(&outfit_stack[i]))
outfit_stack[i].u.lau.ammo = outfit_get(outfit_stack[i].u.lau.ammo_name);
else if(outfit_isFighterBay(&outfit_stack[i]))
outfit_stack[i].u.bay.ammo = outfit_get(outfit_stack[i].u.bay.ammo_name);
}
xmlFreeDoc(doc); xmlFreeDoc(doc);
free(buf); free(buf);
@ -988,10 +1001,10 @@ void outfit_free(void) {
gl_freeTexture(outfit_gfx(&outfit_stack[i])); gl_freeTexture(outfit_gfx(&outfit_stack[i]));
/* Type specification. */ /* Type specification. */
if(outfit_isLauncher(o) && o->u.lau.ammo) if(outfit_isLauncher(o) && o->u.lau.ammo_name)
free(o->u.lau.ammo); free(o->u.lau.ammo_name);
if(outfit_isFighterBay(o) && o->u.bay.ammo) if(outfit_isFighterBay(o) && o->u.bay.ammo_name)
free(o->u.bay.ammo); free(o->u.bay.ammo_name);
if(outfit_isFighter(o) && o->u.fig.ship) if(outfit_isFighter(o) && o->u.fig.ship)
free(o->u.fig.ship); free(o->u.fig.ship);

View File

@ -6,6 +6,8 @@
/* Property flags. */ /* Property flags. */
#define OUTFIT_PROP_WEAP_SECONDARY (1<<0) /**< Is a secondary weapon? */ #define OUTFIT_PROP_WEAP_SECONDARY (1<<0) /**< Is a secondary weapon? */
struct Outfit_;
/** /**
* @enum OutfitType * @enum OutfitType
* *
@ -107,7 +109,8 @@ typedef struct OutfitBeamData_ {
*/ */
typedef struct OutfitLauncherData_ { typedef struct OutfitLauncherData_ {
unsigned int delay; /**< Delay between shots. */ unsigned int delay; /**< Delay between shots. */
char* ammo; /**< The ammo to use. */ char* ammo_name; /**< The ammo to use. */
struct Outfit_* ammo; /**< Ammo to use. */
} OutfitLauncherData; } OutfitLauncherData;
/** /**
@ -179,8 +182,9 @@ typedef struct OutfitAfterburnerData_ {
* @brief Represents a fighter bay. * @brief Represents a fighter bay.
*/ */
typedef struct OutfitFighterBayData_ { typedef struct OutfitFighterBayData_ {
char* ammo; /**< Ships to use as ammo. */ char* ammo_name; /**< Ships to use as ammo. */
double delay; /**< Delay between launches. */ struct Outfit_* ammo; /**< Ships to use as ammo. */
double delay; /**< Delay between launches. */
} OutfitFighterBayData; } OutfitFighterBayData;
/** /**
@ -282,7 +286,7 @@ int outfit_spfx(const Outfit* o);
double outfit_damage(const Outfit* o); double outfit_damage(const Outfit* o);
DamageType outfit_damageType(const Outfit* o); DamageType outfit_damageType(const Outfit* o);
int outfit_delay(const Outfit* o); int outfit_delay(const Outfit* o);
char* outfit_ammo(const Outfit* o); Outfit* outfit_ammo(const Outfit* o);
double outfit_energy(const Outfit* o); double outfit_energy(const Outfit* o);
double outfit_range(const Outfit* o); double outfit_range(const Outfit* o);
double outfit_speed(const Outfit* o); double outfit_speed(const Outfit* o);

View File

@ -1,9 +1,17 @@
/**
* @file pause.c
*
* @brief Handles pausing and resuming the game.
*
* Main trick to pausing/unpausing is to allow things based on time
* to behave properly when the toolkit opens a window.
*
* @todo Should probably be eliminated by making everything use the dt system.
*/
#include "pilot.h" #include "pilot.h"
#include "pause.h" #include "pause.h"
/* Main thing with pausing is to allow things based on time to */
/* work properly when the toolkit opens a window. */
int paused = 0; /* Are we paused. */ int paused = 0; /* Are we paused. */
/* From pilot.c */ /* From pilot.c */

View File

@ -548,7 +548,7 @@ void pilot_setSecondary(Pilot* p, const char* secondary) {
*/ */
void pilot_setAmmo(Pilot* p) { void pilot_setAmmo(Pilot* p) {
int i; int i;
char* name; Outfit* ammo;
/* Weapon must use ammo. */ /* Weapon must use ammo. */
if((p->secondary == NULL) || (outfit_ammo(p->secondary->outfit)==NULL)) { if((p->secondary == NULL) || (outfit_ammo(p->secondary->outfit)==NULL)) {
@ -557,9 +557,9 @@ void pilot_setAmmo(Pilot* p) {
} }
/* Find the ammo and set it. */ /* Find the ammo and set it. */
name = outfit_ammo(p->secondary->outfit); ammo = outfit_ammo(p->secondary->outfit);
for(i = 0; i < p->noutfits; i++) for(i = 0; i < p->noutfits; i++)
if(strcmp(p->outfits[i].outfit->name, name)==0) { if(p->outfits[i].outfit == ammo) {
p->ammo = &p->outfits[i]; p->ammo = &p->outfits[i];
return; return;
} }
@ -576,16 +576,16 @@ void pilot_setAmmo(Pilot* p) {
*/ */
int pilot_getAmmo(Pilot* p, Outfit* o) { int pilot_getAmmo(Pilot* p, Outfit* o) {
int i; int i;
char* name; Outfit* ammo;
/* Must be a launcher. */ /* Must be a launcher. */
if(!outfit_isLauncher(o)) if(!outfit_isLauncher(o))
return 0; return 0;
/* Try to find the ammo. */ /* Try to find the ammo. */
name = o->u.lau.ammo; ammo = o->u.lau.ammo;
for(i = 0; i < p->noutfits; i++) for(i = 0; i < p->noutfits; i++)
if(strcmp(p->outfits[i].outfit->name, name)==0) if(p->outfits[i].outfit == ammo)
return p->outfits[i].quantity; return p->outfits[i].quantity;
/* Assume none. */ /* Assume none. */
@ -632,7 +632,7 @@ int pilot_dock(Pilot* p, Pilot* target) {
/* Check to see if target has an available bay. */ /* Check to see if target has an available bay. */
for(i = 0; i < target->noutfits; i++) { for(i = 0; i < target->noutfits; i++) {
if(outfit_isFighterBay(target->outfits[i].outfit)) { if(outfit_isFighterBay(target->outfits[i].outfit)) {
o = outfit_get(outfit_ammo(target->outfits[i].outfit)); o = outfit_ammo(target->outfits[i].outfit);
if(outfit_isFighter(o) && if(outfit_isFighter(o) &&
(strcmp(p->ship->name, o->u.fig.ship)==0)) (strcmp(p->ship->name, o->u.fig.ship)==0))
break; break;