[Add] Fleets. Not actually making use of them yet though.
[Add] More error checking for XML files
This commit is contained in:
parent
fd652a3642
commit
943cbecf70
@ -2,6 +2,8 @@
|
|||||||
<Factions>
|
<Factions>
|
||||||
<faction name = "Player">
|
<faction name = "Player">
|
||||||
</faction>
|
</faction>
|
||||||
|
<faction name = "Independent">
|
||||||
|
</faction>
|
||||||
<faction name = "Merchant">
|
<faction name = "Merchant">
|
||||||
</faction>
|
</faction>
|
||||||
<faction name = "Pirate">
|
<faction name = "Pirate">
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Fleets>
|
<Fleets>
|
||||||
<fleet name="Test">
|
<fleet name="Test">
|
||||||
<faction>2</faction>
|
<faction>Independent</faction>
|
||||||
<pilots>
|
<pilots>
|
||||||
<pilot chance='100'>Test</pilot>
|
<pilot chance='100'>Test</pilot>
|
||||||
</pilots>
|
</pilots>
|
||||||
</fleet>
|
</fleet>
|
||||||
<fleet name="Merchant Ship">
|
<fleet name="Merchant Ship">
|
||||||
<faction>2</faction>
|
<faction>Merchant</faction>
|
||||||
<pilots>
|
<pilots>
|
||||||
<pilot chance='100'>Ship</pilot>
|
<pilot chance='100'>Ship</pilot>
|
||||||
</pilots>
|
</pilots>
|
||||||
</fleet>
|
</fleet>
|
||||||
<fleet name="Sml Merchant Convoy">
|
<fleet name="Sml Merchant Convoy">
|
||||||
<faction>2</faction>
|
<faction>Merchant</faction>
|
||||||
<pilots>
|
<pilots>
|
||||||
<pilot chance='80'>Ship</pilot>
|
<pilot chance='80'>Ship</pilot>
|
||||||
<pilot chance='80'>Ship</pilot>
|
<pilot chance='80'>Ship</pilot>
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
<y>15</y>
|
<y>15</y>
|
||||||
</pos>
|
</pos>
|
||||||
<general>
|
<general>
|
||||||
<class>1</class>
|
<class>A</class>
|
||||||
|
<faction>Independent</faction>
|
||||||
<services>1</services>
|
<services>1</services>
|
||||||
<tech>0</tech>
|
<tech>0</tech>
|
||||||
<commodities>1</commodities>
|
<commodities>1</commodities>
|
||||||
@ -19,7 +20,8 @@
|
|||||||
<y>-345</y>
|
<y>-345</y>
|
||||||
</pos>
|
</pos>
|
||||||
<general>
|
<general>
|
||||||
<class>1</class>
|
<class>A</class>
|
||||||
|
<faction>Independent</faction>
|
||||||
<services>1</services>
|
<services>1</services>
|
||||||
<tech>0</tech>
|
<tech>0</tech>
|
||||||
<commodities>1</commodities>
|
<commodities>1</commodities>
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
<stars>500</stars>
|
<stars>500</stars>
|
||||||
<asteroids>0</asteroids>
|
<asteroids>0</asteroids>
|
||||||
<interference>0</interference>
|
<interference>0</interference>
|
||||||
<faction>2</faction>
|
|
||||||
</general>
|
</general>
|
||||||
<planets>
|
<planets>
|
||||||
<planet>KonoSphere</planet>
|
<planet>KonoSphere</planet>
|
||||||
@ -32,7 +31,6 @@
|
|||||||
<stars>27</stars>
|
<stars>27</stars>
|
||||||
<asteroids>0</asteroids>
|
<asteroids>0</asteroids>
|
||||||
<interference>0</interference>
|
<interference>0</interference>
|
||||||
<faction>2</faction>
|
|
||||||
</general>
|
</general>
|
||||||
<planets>
|
<planets>
|
||||||
<planet>SaraCraft</planet>
|
<planet>SaraCraft</planet>
|
||||||
|
4
src/ai.c
4
src/ai.c
@ -266,7 +266,7 @@ static int ai_getdistance(lua_State* L) {
|
|||||||
// Get the pilots position.
|
// Get the pilots position.
|
||||||
static int ai_getpos(lua_State* L) {
|
static int ai_getpos(lua_State* L) {
|
||||||
Pilot* p;
|
Pilot* p;
|
||||||
if(lua_isnumber(L, 1)) p = get_pilot((int)lua_tonumber(L,1)); // Pilot ID.
|
if(lua_isnumber(L, 1)) p = pilot_get((int)lua_tonumber(L,1)); // Pilot ID.
|
||||||
else if(lua_islightuserdata(L, 1)) p = (Pilot*)lua_topointer(L, 1); // Pilot pointer.
|
else if(lua_islightuserdata(L, 1)) p = (Pilot*)lua_topointer(L, 1); // Pilot pointer.
|
||||||
else p = cur_pilot; // Default to ones self.
|
else p = cur_pilot; // Default to ones self.
|
||||||
|
|
||||||
@ -324,7 +324,7 @@ static int ai_turn(lua_State* L) {
|
|||||||
static int ai_face(lua_State* L) {
|
static int ai_face(lua_State* L) {
|
||||||
MIN_ARGS(1);
|
MIN_ARGS(1);
|
||||||
Vec2* v; // Grab the position to face.
|
Vec2* v; // Grab the position to face.
|
||||||
if(lua_isnumber(L,1)) v = &get_pilot((unsigned int)lua_tonumber(L,1))->solid->pos;
|
if(lua_isnumber(L,1)) v = &pilot_get((unsigned int)lua_tonumber(L,1))->solid->pos;
|
||||||
else if(lua_islightuserdata(L,1)) v = (Vec2*)lua_topointer(L,1);
|
else if(lua_islightuserdata(L,1)) v = (Vec2*)lua_topointer(L,1);
|
||||||
|
|
||||||
double mod = -10;
|
double mod = -10;
|
||||||
|
@ -21,7 +21,7 @@ int nfactions = 0;
|
|||||||
static Faction* faction_parse(xmlNodePtr parent);
|
static Faction* faction_parse(xmlNodePtr parent);
|
||||||
|
|
||||||
// Return the faction of name "name".
|
// Return the faction of name "name".
|
||||||
Faction* get_faction(const char* name) {
|
Faction* faction_get(const char* name) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < nfactions; i++)
|
for(i = 0; i < nfactions; i++)
|
||||||
if(strcmp(faction_stack[i].name, name)==0)
|
if(strcmp(faction_stack[i].name, name)==0)
|
||||||
@ -54,6 +54,7 @@ int areAllies(Faction* a, Faction* b) {
|
|||||||
static Faction* faction_parse(xmlNodePtr parent) {
|
static Faction* faction_parse(xmlNodePtr parent) {
|
||||||
Faction* tmp = CALLOC_L(Faction);
|
Faction* tmp = CALLOC_L(Faction);
|
||||||
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
|
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
|
||||||
|
if(tmp->name == NULL) WARN("Faction from "FACTION_DATA" has invalid or no name");
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,13 +67,13 @@ int factions_load(void) {
|
|||||||
|
|
||||||
Faction* tmp = NULL;
|
Faction* tmp = NULL;
|
||||||
|
|
||||||
node = doc->xmlChildrenNode; // Ships node.
|
node = doc->xmlChildrenNode; // Faction node.
|
||||||
if(strcmp((char*)node->name, XML_FACTION_ID)) {
|
if(strcmp((char*)node->name, XML_FACTION_ID)) {
|
||||||
ERR("Malformed "FACTION_DATA" file: missing root element '"XML_FACTION_ID"'");
|
ERR("Malformed "FACTION_DATA" file: missing root element '"XML_FACTION_ID"'");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node->xmlChildrenNode; // First ship node.
|
node = node->xmlChildrenNode; // First faction node.
|
||||||
if(node == NULL) {
|
if(node == NULL) {
|
||||||
ERR("Malformed "FACTION_DATA" file: does not contain elements");
|
ERR("Malformed "FACTION_DATA" file: does not contain elements");
|
||||||
return -1;
|
return -1;
|
||||||
@ -97,6 +98,9 @@ int factions_load(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void factions_free(void) {
|
void factions_free(void) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < nfactions; i++)
|
||||||
|
free(faction_stack[i].name);
|
||||||
free(faction_stack);
|
free(faction_stack);
|
||||||
nfactions = 0;
|
nfactions = 0;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ typedef struct Faction {
|
|||||||
struct Faction** allies;
|
struct Faction** allies;
|
||||||
} Faction;
|
} Faction;
|
||||||
|
|
||||||
Faction* get_faction(const char* name);
|
Faction* faction_get(const char* name);
|
||||||
|
|
||||||
int areEnemies(Faction* a, Faction* b);
|
int areEnemies(Faction* a, Faction* b);
|
||||||
int areAllies(Faction* a, Faction* b);
|
int areAllies(Faction* a, Faction* b);
|
||||||
|
@ -249,14 +249,15 @@ int main(int argc, char** argv) {
|
|||||||
factions_load();
|
factions_load();
|
||||||
outfit_load();
|
outfit_load();
|
||||||
ships_load();
|
ships_load();
|
||||||
|
fleet_load();
|
||||||
space_load();
|
space_load();
|
||||||
|
|
||||||
// Testing.
|
// Testing.
|
||||||
pilot_create(get_ship("Ship"), "Player", 0., NULL, NULL, PILOT_PLAYER);
|
pilot_create(ship_get("Ship"), "Player", 0., NULL, NULL, PILOT_PLAYER);
|
||||||
gl_bindCamera(&player->solid->pos);
|
gl_bindCamera(&player->solid->pos);
|
||||||
space_init("SaraSys");
|
space_init("SaraSys");
|
||||||
|
|
||||||
pilot_create(get_ship("Test"), NULL, 2., NULL, NULL, 0);
|
pilot_create(ship_get("Test"), NULL, 2., NULL, NULL, 0);
|
||||||
|
|
||||||
player_message("Welcome to "APPNAME"!");
|
player_message("Welcome to "APPNAME"!");
|
||||||
player_message(" v%d.%d.%d", VMAJOR, VMINOR, VREV);
|
player_message(" v%d.%d.%d", VMAJOR, VMINOR, VREV);
|
||||||
@ -282,6 +283,7 @@ int main(int argc, char** argv) {
|
|||||||
space_exit(); // Clean up the universe!!!
|
space_exit(); // Clean up the universe!!!
|
||||||
pilots_free(); // Free the pilots, they where locked up D:
|
pilots_free(); // Free the pilots, they where locked up D:
|
||||||
gui_free(); // Free up the gui.
|
gui_free(); // Free up the gui.
|
||||||
|
fleet_free();
|
||||||
ships_free();
|
ships_free();
|
||||||
outfit_free();
|
outfit_free();
|
||||||
factions_free();
|
factions_free();
|
||||||
|
@ -125,6 +125,7 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
|||||||
xmlChar* prop;
|
xmlChar* prop;
|
||||||
|
|
||||||
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); // Already mallocs.
|
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); // Already mallocs.
|
||||||
|
if(tmp->name == NULL) WARN("Outfit in "OUTFIT_DATA" has invalid or no name");
|
||||||
|
|
||||||
node = parent->xmlChildrenNode;
|
node = parent->xmlChildrenNode;
|
||||||
|
|
||||||
|
145
src/pilot.c
145
src/pilot.c
@ -1,21 +1,36 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h> // We don't need this?
|
||||||
|
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "weapon.h"
|
#include "weapon.h"
|
||||||
|
#include "pack.h"
|
||||||
#include "pilot.h"
|
#include "pilot.h"
|
||||||
|
|
||||||
|
#define XML_NODE_START 1
|
||||||
|
#define XML_NODE_TEXT 3
|
||||||
|
|
||||||
|
#define XML_ID "Fleets" // XML section identifier.
|
||||||
|
#define XML_FLEET "fleet"
|
||||||
|
|
||||||
|
#define FLEET_DATA "../dat/fleet.xml"
|
||||||
|
|
||||||
// Stack of pilot id's to assure uniqueness.
|
// Stack of pilot id's to assure uniqueness.
|
||||||
static unsigned int pilot_id = 0;
|
static unsigned int pilot_id = 0;
|
||||||
|
|
||||||
// Stack of pilots - yes, they come in stacks now.
|
// Stack of pilots - yes, they come in stacks now.
|
||||||
Pilot** pilot_stack;
|
Pilot** pilot_stack = NULL; // Not static, it is used in player.c and weapon.c
|
||||||
int pilots = 0;
|
int pilots = 0;
|
||||||
extern Pilot* player;
|
extern Pilot* player;
|
||||||
|
|
||||||
|
// Stack of fleets.
|
||||||
|
static Fleet* fleet_stack = NULL;
|
||||||
|
static int nfleets = 0;
|
||||||
|
|
||||||
// External.
|
// External.
|
||||||
extern void ai_destroy(Pilot* p); // Ai.
|
extern void ai_destroy(Pilot* p); // Ai.
|
||||||
extern void player_think(Pilot* pilot); // Player.c
|
extern void player_think(Pilot* pilot); // Player.c
|
||||||
@ -24,9 +39,10 @@ extern void ai_think(Pilot* pilot); // Ai.c
|
|||||||
static void pilot_update(Pilot* pilot, const double dt);
|
static void pilot_update(Pilot* pilot, const double dt);
|
||||||
void pilot_render(Pilot* pilot);
|
void pilot_render(Pilot* pilot);
|
||||||
static void pilot_free(Pilot* p);
|
static void pilot_free(Pilot* p);
|
||||||
|
static Fleet* fleet_parse(const xmlNodePtr parent);
|
||||||
|
|
||||||
// Get the next pilot based on player_id.
|
// Get the next pilot based on player_id.
|
||||||
unsigned int pilot_getNext(unsigned int id) {
|
unsigned int pilot_getNext(const unsigned int id) {
|
||||||
int i, n;
|
int i, n;
|
||||||
for(i = 0, n = pilots/2; n > 0; n /= 2)
|
for(i = 0, n = pilots/2; n > 0; n /= 2)
|
||||||
i += (pilot_stack[i+n]->id > id) ? 0 : n;
|
i += (pilot_stack[i+n]->id > id) ? 0 : n;
|
||||||
@ -37,7 +53,7 @@ unsigned int pilot_getNext(unsigned int id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pull a pilot out of the pilot_stack based on id.
|
// Pull a pilot out of the pilot_stack based on id.
|
||||||
Pilot* get_pilot(unsigned int id) {
|
Pilot* pilot_get(const unsigned int id) {
|
||||||
// Regular search.
|
// Regular search.
|
||||||
#if 0
|
#if 0
|
||||||
for(int i = 0; i < pilots; i++)
|
for(int i = 0; i < pilots; i++)
|
||||||
@ -54,7 +70,7 @@ Pilot* get_pilot(unsigned int id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mkay, this is how we shoot. Listen up.
|
// Mkay, this is how we shoot. Listen up.
|
||||||
void pilot_shoot(Pilot* p, int secondary) {
|
void pilot_shoot(Pilot* p, const int secondary) {
|
||||||
int i;
|
int i;
|
||||||
if(!secondary) {
|
if(!secondary) {
|
||||||
// Primary weapons.
|
// Primary weapons.
|
||||||
@ -79,7 +95,7 @@ void pilot_shoot(Pilot* p, int secondary) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Damage the pilot.
|
// Damage the pilot.
|
||||||
void pilot_hit(Pilot* p, double damage_shield, double damage_armor) {
|
void pilot_hit(Pilot* p, const double damage_shield, const double damage_armor) {
|
||||||
if(p->shield - damage_shield > 0.)
|
if(p->shield - damage_shield > 0.)
|
||||||
p->shield -= damage_shield;
|
p->shield -= damage_shield;
|
||||||
else if(p->shield > 0.) {
|
else if(p->shield > 0.) {
|
||||||
@ -262,3 +278,120 @@ void pilots_update(double dt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the fleet based on 'name'
|
||||||
|
Fleet* fleet_get(const char* name) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < nfleets; i++)
|
||||||
|
if(strcmp(name, fleet_stack[i].name)==0)
|
||||||
|
return fleet_stack+i;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the fleet node.
|
||||||
|
static Fleet* fleet_parse(const xmlNodePtr parent) {
|
||||||
|
xmlNodePtr cur, node;
|
||||||
|
FleetPilot* pilot;
|
||||||
|
char* c;
|
||||||
|
node = parent->xmlChildrenNode;
|
||||||
|
|
||||||
|
Fleet* tmp = CALLOC_L(Fleet);
|
||||||
|
|
||||||
|
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); // Already mallocs.
|
||||||
|
if(tmp->name == NULL) WARN("Fleet in "FLEET_DATA" has invalid or no name");
|
||||||
|
|
||||||
|
while((node = node->next)) {
|
||||||
|
// Load all the data.
|
||||||
|
if(strcmp((char*)node->name, "faction")==0)
|
||||||
|
tmp->faction = faction_get((char*)node->children->content);
|
||||||
|
else if(strcmp((char*)node->name, "pilots")==0) {
|
||||||
|
cur = node->children;
|
||||||
|
while((cur = cur->next)) {
|
||||||
|
if(strcmp((char*)cur->name, "pilot")==0) {
|
||||||
|
tmp->npilots++; // Pilot count.
|
||||||
|
pilot = MALLOC_L(FleetPilot);
|
||||||
|
|
||||||
|
// Name is not obligatory. Will only override ship name.
|
||||||
|
c = (char*)xmlGetProp(cur, (xmlChar*)"name"); // Mallocs.
|
||||||
|
pilot->name = c; // No need to free here however.
|
||||||
|
|
||||||
|
pilot->ship = ship_get((char*)cur->children->content);
|
||||||
|
if(pilot->ship == NULL)
|
||||||
|
WARN("Pilot %s in Fleet %s has null ship", pilot->name, tmp->name);
|
||||||
|
|
||||||
|
c = (char*)xmlGetProp(cur, (xmlChar*)"chance"); // Mallocs.
|
||||||
|
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) free(c); // Free the external malloc.
|
||||||
|
|
||||||
|
tmp->pilots = realloc(tmp->pilots, sizeof(FleetPilot)*tmp->npilots);
|
||||||
|
memcpy(tmp->pilots+(tmp->npilots-1), pilot, sizeof(FleetPilot));
|
||||||
|
free(pilot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define MELEMENT(o,s) if((o) == NULL) WARN("Fleet '%s' missing '"s"' element", tmp->name)
|
||||||
|
MELEMENT(tmp->faction, "faction");
|
||||||
|
MELEMENT(tmp->pilots, "pilots");
|
||||||
|
#undef MELEMENT
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the fleets.
|
||||||
|
int fleet_load(void) {
|
||||||
|
uint32_t bufsize;
|
||||||
|
char* buf = pack_readfile(DATA, FLEET_DATA, &bufsize);
|
||||||
|
|
||||||
|
xmlNodePtr node;
|
||||||
|
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
|
||||||
|
|
||||||
|
Fleet* tmp = NULL;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_FLEET)==0) {
|
||||||
|
tmp = fleet_parse(node);
|
||||||
|
fleet_stack = realloc(fleet_stack, sizeof(Fleet)*(++nfleets));
|
||||||
|
memcpy(fleet_stack+nfleets-1, tmp, sizeof(Fleet));
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
} while((node = node->next));
|
||||||
|
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
free(buf);
|
||||||
|
xmlCleanupParser();
|
||||||
|
|
||||||
|
DEBUG("Loaded %d fleets", nfleets);
|
||||||
|
|
||||||
|
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);
|
||||||
|
free(fleet_stack[i].name);
|
||||||
|
free(fleet_stack[i].pilots);
|
||||||
|
}
|
||||||
|
free(fleet_stack);
|
||||||
|
}
|
||||||
|
nfleets = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
27
src/pilot.h
27
src/pilot.h
@ -3,6 +3,7 @@
|
|||||||
#include "physics.h"
|
#include "physics.h"
|
||||||
#include "ai.h"
|
#include "ai.h"
|
||||||
#include "outfit.h"
|
#include "outfit.h"
|
||||||
|
#include "faction.h"
|
||||||
#include "ship.h"
|
#include "ship.h"
|
||||||
|
|
||||||
// Aproximation for pilot size.
|
// Aproximation for pilot size.
|
||||||
@ -44,14 +45,30 @@ typedef struct Pilot {
|
|||||||
Task* task; // Current action.
|
Task* task; // Current action.
|
||||||
} Pilot;
|
} Pilot;
|
||||||
|
|
||||||
|
// Fleets.
|
||||||
|
typedef struct {
|
||||||
|
Ship* ship; // Ship that the pilot is flying.
|
||||||
|
char* name; // For special 'unique' names.
|
||||||
|
int chance; // Chance of this pilot appearing in the fleet.
|
||||||
|
} FleetPilot;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* name; // Fleet name, used as an identifier.
|
||||||
|
Faction* faction; // Faction of the fleet.
|
||||||
|
|
||||||
|
FleetPilot* pilots; // The pilots in the fleet.
|
||||||
|
int npilots; // Total number of pilots.
|
||||||
|
} Fleet;
|
||||||
|
|
||||||
// Grabing pilot crap.
|
// Grabing pilot crap.
|
||||||
extern Pilot* player; // The player.
|
extern Pilot* player; // The player.
|
||||||
Pilot* get_pilot(unsigned int id);
|
Pilot* pilot_get(unsigned int id);
|
||||||
unsigned int pilot_getNext(unsigned int id);
|
unsigned int pilot_getNext(unsigned int id);
|
||||||
|
Fleet* fleet_get(const char* name);
|
||||||
|
|
||||||
// MISC.
|
// MISC.
|
||||||
void pilot_shoot(Pilot* p, int secondary);
|
void pilot_shoot(Pilot* p, const int secondary);
|
||||||
void pilot_hit(Pilot* p, double damage_shield, double damage_armor);
|
void pilot_hit(Pilot* p, const double damage_shield, const double damage_armor);
|
||||||
|
|
||||||
// Creation.
|
// Creation.
|
||||||
void pilot_init(Pilot* dest, Ship* ship, char* name, const double dir,
|
void pilot_init(Pilot* dest, Ship* ship, char* name, const double dir,
|
||||||
@ -60,9 +77,11 @@ void pilot_init(Pilot* dest, Ship* ship, char* name, const double dir,
|
|||||||
unsigned int pilot_create(Ship* ship, char* name, const double dir,
|
unsigned int pilot_create(Ship* ship, char* name, const double dir,
|
||||||
const Vec2* pos, const Vec2* vel, const int flags);
|
const Vec2* pos, const Vec2* vel, const int flags);
|
||||||
|
|
||||||
// Cleanup.
|
// Init/Cleanup.
|
||||||
void pilot_destroy(Pilot* p);
|
void pilot_destroy(Pilot* p);
|
||||||
void pilots_free(void);
|
void pilots_free(void);
|
||||||
|
int fleet_load(void);
|
||||||
|
void fleet_free(void);
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
void pilots_update(double dt);
|
void pilots_update(double dt);
|
||||||
|
@ -136,7 +136,7 @@ void player_render(void) {
|
|||||||
|
|
||||||
// Render the player target graphics.
|
// Render the player target graphics.
|
||||||
if(player_target) {
|
if(player_target) {
|
||||||
p = get_pilot(player_target);
|
p = pilot_get(player_target);
|
||||||
|
|
||||||
vect_csetmin(&v, VX(p->solid->pos) - p->ship->gfx_space->sw * PILOT_SIZE_APROX/2.,
|
vect_csetmin(&v, VX(p->solid->pos) - p->ship->gfx_space->sw * PILOT_SIZE_APROX/2.,
|
||||||
VY(p->solid->pos) + p->ship->gfx_space->sh * PILOT_SIZE_APROX/2.);
|
VY(p->solid->pos) + p->ship->gfx_space->sh * PILOT_SIZE_APROX/2.);
|
||||||
|
@ -23,7 +23,7 @@ static int ships = 0;
|
|||||||
static Ship* ship_parse(xmlNodePtr parent);
|
static Ship* ship_parse(xmlNodePtr parent);
|
||||||
|
|
||||||
// Get a ship based on it's name.
|
// Get a ship based on it's name.
|
||||||
Ship* get_ship(const char* name) {
|
Ship* ship_get(const char* name) {
|
||||||
Ship* tmp = ship_stack;
|
Ship* tmp = ship_stack;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < ships; i++)
|
for(i = 0; i < ships; i++)
|
||||||
@ -44,6 +44,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
|||||||
xmlChar* xstr;
|
xmlChar* xstr;
|
||||||
|
|
||||||
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
|
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
|
||||||
|
if(tmp->name == NULL) WARN("Ship in "SHIP_DATA" has invalid or no name");
|
||||||
|
|
||||||
node = parent->xmlChildrenNode;
|
node = parent->xmlChildrenNode;
|
||||||
|
|
||||||
|
@ -53,5 +53,5 @@ typedef struct {
|
|||||||
int ships_load(void);
|
int ships_load(void);
|
||||||
void ships_free(void);
|
void ships_free(void);
|
||||||
|
|
||||||
Ship* get_ship(const char* name);
|
Ship* ship_get(const char* name);
|
||||||
|
|
||||||
|
93
src/space.c
93
src/space.c
@ -8,6 +8,7 @@
|
|||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
#include "pilot.h"
|
#include "pilot.h"
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
|
#include "faction.h"
|
||||||
#include "space.h"
|
#include "space.h"
|
||||||
|
|
||||||
#define XML_NODE_START 1
|
#define XML_NODE_START 1
|
||||||
@ -33,6 +34,7 @@
|
|||||||
|
|
||||||
// Planet types. I didn't take them from Star Trek, I promise.
|
// Planet types. I didn't take them from Star Trek, I promise.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
PLANET_CLASS_NULL = 0,
|
||||||
PLANET_CLASS_A, // Geothermal.
|
PLANET_CLASS_A, // Geothermal.
|
||||||
PLANET_CLASS_B, // Geomorteus.
|
PLANET_CLASS_B, // Geomorteus.
|
||||||
PLANET_CLASS_C, // Geoinactive.
|
PLANET_CLASS_C, // Geoinactive.
|
||||||
@ -55,34 +57,42 @@ typedef enum {
|
|||||||
PLANET_CLASS_T, // Ultragiant.
|
PLANET_CLASS_T, // Ultragiant.
|
||||||
PLANET_CLASS_X, // Demon.
|
PLANET_CLASS_X, // Demon.
|
||||||
PLANET_CLASS_Y, // Demon.
|
PLANET_CLASS_Y, // Demon.
|
||||||
PLANER_CLASS_Z // Demon.
|
PLANET_CLASS_Z // Demon.
|
||||||
} PlanetClass;
|
} PlanetClass;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* name;
|
char* name; // Planet name
|
||||||
Vec2 pos; // Position in star system.
|
Vec2 pos; // Position in star system.
|
||||||
PlanetClass class;
|
|
||||||
|
PlanetClass class; // Planet type.
|
||||||
|
Faction* faction; // Planet faction.
|
||||||
gl_texture* gfx_space; // Graphics in space.
|
gl_texture* gfx_space; // Graphics in space.
|
||||||
} Planet;
|
} Planet;
|
||||||
|
|
||||||
|
// Star systems.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* name;
|
Fleet* fleet; // Fleet to appear.
|
||||||
|
int chance; // Chance of fleet appearing in the system.
|
||||||
|
} SystemFleet;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* name; // Star system identifier.
|
||||||
Vec2 pos; // Position.
|
Vec2 pos; // Position.
|
||||||
int stars, asteroids; // Un numero!
|
int stars, asteroids; // Un numero!
|
||||||
double interference; // Un uh.. Percentage.
|
double interference; // Un uh.. Percentage.
|
||||||
|
|
||||||
// Factions.
|
|
||||||
Planet* planets; // Planets.
|
Planet* planets; // Planets.
|
||||||
int nplanets;
|
int nplanets; // Total number of planets.
|
||||||
|
|
||||||
// TODO: Throw some fleets here.
|
SystemFleet* fleets; // Fleets that can appear in the current system.
|
||||||
|
int nfleets; // Total number of fleets.
|
||||||
} StarSystem;
|
} StarSystem;
|
||||||
|
|
||||||
static StarSystem* systems = NULL;
|
static StarSystem* systems = NULL;
|
||||||
static int nsystems = 0;
|
static int nsystems = 0;
|
||||||
static StarSystem* cur_system = NULL; // Current star system.
|
static StarSystem* cur_system = NULL; // Current star system.
|
||||||
|
|
||||||
#define STAR_BUF 100 // Area to leave around screen.
|
#define STAR_BUF 100 // Area to leave around screen, more = less repitition.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
double x, y; // Position. It is simpler ligher to use two doubles than the physics.
|
double x, y; // Position. It is simpler ligher to use two doubles than the physics.
|
||||||
double brightness;
|
double brightness;
|
||||||
@ -93,8 +103,10 @@ static int nstars = 0; // Total stars.
|
|||||||
|
|
||||||
static Planet* planet_get(const char* name);
|
static Planet* planet_get(const char* name);
|
||||||
static StarSystem* system_parse(const xmlNodePtr parent);
|
static StarSystem* system_parse(const xmlNodePtr parent);
|
||||||
|
static PlanetClass planetclass_get(const char a);
|
||||||
|
|
||||||
// Draw the planet. Used in planet.c
|
// Draw the planet. Used in planet.c
|
||||||
|
// Matrix mode is already displaced to center of the minimap.
|
||||||
#define PIXEL(x,y) if(ABS(x)<w/2. && ABS(y)<h/2.) glVertex2i((x),(y))
|
#define PIXEL(x,y) if(ABS(x)<w/2. && ABS(y)<h/2.) glVertex2i((x),(y))
|
||||||
void planets_minimap(double res, double w, double h) {
|
void planets_minimap(double res, double w, double h) {
|
||||||
int i;
|
int i;
|
||||||
@ -151,6 +163,36 @@ void planets_minimap(double res, double w, double h) {
|
|||||||
}
|
}
|
||||||
#undef PIXEL
|
#undef PIXEL
|
||||||
|
|
||||||
|
static PlanetClass planetclass_get(const char a) {
|
||||||
|
switch(a) {
|
||||||
|
case 'A': return PLANET_CLASS_A;
|
||||||
|
case 'B': return PLANET_CLASS_B;
|
||||||
|
case 'C': return PLANET_CLASS_C;
|
||||||
|
case 'D': return PLANET_CLASS_D;
|
||||||
|
case 'E': return PLANET_CLASS_E;
|
||||||
|
case 'F': return PLANET_CLASS_F;
|
||||||
|
case 'G': return PLANET_CLASS_G;
|
||||||
|
case 'H': return PLANET_CLASS_H;
|
||||||
|
case 'I': return PLANET_CLASS_I;
|
||||||
|
case 'J': return PLANET_CLASS_J;
|
||||||
|
case 'K': return PLANET_CLASS_K;
|
||||||
|
case 'L': return PLANET_CLASS_L;
|
||||||
|
case 'M': return PLANET_CLASS_M;
|
||||||
|
case 'N': return PLANET_CLASS_N;
|
||||||
|
case 'O': return PLANET_CLASS_O;
|
||||||
|
case 'P': return PLANET_CLASS_P;
|
||||||
|
case 'Q': return PLANET_CLASS_Q;
|
||||||
|
case 'R': return PLANET_CLASS_R;
|
||||||
|
case 'S': return PLANET_CLASS_S;
|
||||||
|
case 'T': return PLANET_CLASS_T;
|
||||||
|
case 'X': return PLANET_CLASS_X;
|
||||||
|
case 'Y': return PLANET_CLASS_Y;
|
||||||
|
case 'Z': return PLANET_CLASS_Z;
|
||||||
|
|
||||||
|
default: return PLANET_CLASS_NULL;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Init the system.
|
// Init the system.
|
||||||
void space_init(const char* sysname) {
|
void space_init(const char* sysname) {
|
||||||
int i;
|
int i;
|
||||||
@ -231,7 +273,9 @@ static Planet* planet_get(const char* name) {
|
|||||||
cur = node->children;
|
cur = node->children;
|
||||||
while((cur = cur->next)) {
|
while((cur = cur->next)) {
|
||||||
if(strcmp((char*)cur->name, "class")==0)
|
if(strcmp((char*)cur->name, "class")==0)
|
||||||
tmp->class = atoi((char*)cur->children->content);
|
tmp->class = planetclass_get(cur->children->content[0]);
|
||||||
|
else if(strcmp((char*)cur->name, "faction")==0)
|
||||||
|
tmp->faction = faction_get((char*)cur->children->content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,6 +295,7 @@ static Planet* planet_get(const char* name) {
|
|||||||
MELEMENT(flags&FLAG_XSET, "x");
|
MELEMENT(flags&FLAG_XSET, "x");
|
||||||
MELEMENT(flags&FLAG_YSET, "y");
|
MELEMENT(flags&FLAG_YSET, "y");
|
||||||
MELEMENT(tmp->class, "class");
|
MELEMENT(tmp->class, "class");
|
||||||
|
MELEMENT(tmp->faction, "faction");
|
||||||
#undef MELEMENT
|
#undef MELEMENT
|
||||||
} else
|
} else
|
||||||
WARN("No planet found matching name '%s'", name);
|
WARN("No planet found matching name '%s'", name);
|
||||||
@ -262,7 +307,9 @@ static Planet* planet_get(const char* name) {
|
|||||||
// Return the StarSystem fully loaded.
|
// Return the StarSystem fully loaded.
|
||||||
static StarSystem* system_parse(const xmlNodePtr parent) {
|
static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||||
Planet* planet = NULL;
|
Planet* planet = NULL;
|
||||||
|
SystemFleet* fleet = NULL;
|
||||||
StarSystem* tmp = CALLOC_L(StarSystem);
|
StarSystem* tmp = CALLOC_L(StarSystem);
|
||||||
|
char* ptrc;
|
||||||
xmlNodePtr cur, node;
|
xmlNodePtr cur, node;
|
||||||
|
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
@ -301,17 +348,41 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Load all the planets.
|
||||||
else if(strcmp((char*)node->name, "planets")==0) {
|
else if(strcmp((char*)node->name, "planets")==0) {
|
||||||
cur = node->children;
|
cur = node->children;
|
||||||
while((cur = cur->next)) {
|
while((cur = cur->next)) {
|
||||||
if(strcmp((char*)cur->name, "planet")==0) {
|
if(strcmp((char*)cur->name, "planet")==0) {
|
||||||
planet = planet_get((const char*)cur->children->content);
|
planet = planet_get((const char*)cur->children->content);
|
||||||
tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets));
|
tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets));
|
||||||
memcpy(tmp->planets+tmp->nplanets-1, planet, sizeof(Planet));
|
memcpy(tmp->planets+(tmp->nplanets-1), planet, sizeof(Planet));
|
||||||
free(planet);
|
free(planet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Load all the fleets.
|
||||||
|
else if(strcmp((char*)node->name, "fleets")==0) {
|
||||||
|
cur = node->children;
|
||||||
|
while((cur = cur->next)) {
|
||||||
|
if(strcmp((char*)cur->name, "fleet")==0) {
|
||||||
|
fleet = CALLOC_L(SystemFleet);
|
||||||
|
fleet->fleet = fleet_get((const char*)cur->children->content);
|
||||||
|
if(fleet->fleet == NULL)
|
||||||
|
WARN("Fleet %s for Star System %s not found", (char*)cur->children->content, tmp->name);
|
||||||
|
|
||||||
|
ptrc = (char*)xmlGetProp(cur, (xmlChar*)"chance"); // Malloc ptrc.
|
||||||
|
fleet->chance = atoi(ptrc);
|
||||||
|
if(fleet->chance == 0)
|
||||||
|
WARN("Fleet %s for Star System %s has 0%% chance to appear",
|
||||||
|
fleet->fleet->name, tmp->name);
|
||||||
|
if(ptrc) free(ptrc); // Free the ptrc.
|
||||||
|
|
||||||
|
tmp->fleets = realloc(tmp->fleets, sizeof(SystemFleet)*(++tmp->nfleets));
|
||||||
|
memcpy(tmp->fleets+(tmp->nfleets-1), fleet, sizeof(SystemFleet));
|
||||||
|
free(fleet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Check elements.
|
// Check elements.
|
||||||
#define MELEMENT(o,s) if((o) == 0) WARN("Star System '%s' missing '"s"' element", tmp->name)
|
#define MELEMENT(o,s) if((o) == 0) WARN("Star System '%s' missing '"s"' element", tmp->name)
|
||||||
@ -402,6 +473,8 @@ void space_exit(void) {
|
|||||||
free(systems[i].planets[j].name);
|
free(systems[i].planets[j].name);
|
||||||
if(systems[i].planets[j].gfx_space)
|
if(systems[i].planets[j].gfx_space)
|
||||||
gl_freeTexture(systems[i].planets[j].gfx_space);
|
gl_freeTexture(systems[i].planets[j].gfx_space);
|
||||||
|
if(systems[i].fleets)
|
||||||
|
free(systems[i].fleets);
|
||||||
}
|
}
|
||||||
free(systems[i].planets);
|
free(systems[i].planets);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user