[Change] Improved outfit loading somewhat.
This commit is contained in:
parent
20244a585d
commit
0c1f50a2ff
59
src/outfit.c
59
src/outfit.c
@ -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);
|
||||||
|
|
||||||
|
12
src/outfit.h
12
src/outfit.h
@ -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);
|
||||||
|
14
src/pause.c
14
src/pause.c
@ -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 */
|
||||||
|
14
src/pilot.c
14
src/pilot.c
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user