diff --git a/dat/faction.xml b/dat/faction.xml
index 95ca975..1bf5e8d 100644
--- a/dat/faction.xml
+++ b/dat/faction.xml
@@ -8,8 +8,16 @@
-
-
-
-
+
+
+ Independent
+ Merchant
+
+
+
+
+ Neutral
+ Pirate
+
+
diff --git a/src/faction.c b/src/faction.c
index 0c7fdbe..28725bb 100644
--- a/src/faction.c
+++ b/src/faction.c
@@ -10,8 +10,12 @@
#define XML_NODE_START 1
#define XML_NODE_TEXT 3
-#define XML_FACTION_ID "Factions" // XML section id.
-#define XML_FACTION_TAG "faction"
+#define XML_FACTION_ID "Factions" // XML section id.
+#define XML_FACTION_TAG "faction"
+#define XML_ALLIANCE_ID "Alliances"
+#define XML_ALLIANCE_TAG "alliance"
+#define XML_ENEMIES_ID "Enemies"
+#define XML_ENEMIES_TAG "enemies"
#define FACTION_DATA "../dat/faction.xml"
@@ -19,6 +23,8 @@ Faction* faction_stack = NULL;
int nfactions = 0;
static Faction* faction_parse(xmlNodePtr parent);
+static void alliance_parse(xmlNodePtr parent);
+static void enemies_parse(xmlNodePtr parent);
// Return the faction of name "name".
Faction* faction_get(const char* name) {
@@ -36,21 +42,31 @@ Faction* faction_get(const char* name) {
// Return 1 if Faction a and b are enemies.
int areEnemies(Faction* a, Faction* b) {
int i = 0;
- while(a->enemies[i] != NULL && b != a->enemies[i]) i++;
+ for(i = 0; i < a->nenemies; i++)
+ if(a->enemies[i] == b)
+ return 1;
+ for(i = 0; i < b->nenemies; i++)
+ if(b->enemies[i] == a)
+ return 1;
- if(a->enemies[i] == NULL) return 0;
- return 1;
+ return 0;
}
// Return 1 if Faction a and b are allies.
int areAllies(Faction* a, Faction* b) {
int i = 0;
- while(a->allies[i] != NULL && b != a->allies[i]) i++;
+ for(i = 0; i < a->nallies; i++)
+ if(a->allies[i] == b)
+ return 1;
+ for(i = 0; i < b->nallies; i++)
+ if(b->allies[i] == a)
+ return 1;
+
+ return 0;
- if(a->allies[i] == NULL) return 0;
- return 1;
}
+// Parses a single faction, but does not set the allies/enemies.
static Faction* faction_parse(xmlNodePtr parent) {
Faction* tmp = CALLOC_L(Faction);
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
@@ -58,6 +74,70 @@ static Faction* faction_parse(xmlNodePtr parent) {
return tmp;
}
+// We set allies/enemies here, in the faction_stack.
+static void alliance_parse(xmlNodePtr parent) {
+ Faction** f = NULL;
+ int i, j, n, m;
+ i = 0;
+ char* name = NULL;
+ xmlNodePtr node, cur;
+
+ node = parent->xmlChildrenNode;
+
+ do {
+ if(node->type == XML_NODE_START) {
+ if(strcmp((char*)node->name, XML_ALLIANCE_TAG)==0) {
+ name = (char*)xmlGetProp(node, (xmlChar*)"name");
+
+ // Parse the current alliance's allies.
+ cur = node->xmlChildrenNode;
+ do {
+ if(strcmp((char*)cur->name, "ally")==0) {
+ f = realloc(f, (++i)*sizeof(Faction*));
+ f[i-1] = faction_get((char*)cur->children->content);
+ if(f[i-1] == NULL)
+ WARN("Faction %s in alliance %s does not exist in "FACTION_DATA,
+ (char*)cur->children->content, name);
+ }
+ }while((cur = cur->next));
+
+ // Set the crap needed by faction_stack.
+ for(j = 0; j < i; j++) {
+ f[j]->nallies += i-1;
+ f[j]->allies = realloc(f[j]->allies, f[j]->nallies*sizeof(Faction*));
+ for(n = 0, m = 0; n < i; n++, m++) {
+ // Add as ally for all factions exept self.
+ if(n == j) m--;
+ else if(n != j) f[j]->allies[f[j]->nallies-i+1+m] = f[n];
+ }
+ }
+ // Free up some memory.
+ if(f) {
+ free(f);
+ f = NULL;
+ i = 0;
+ }
+ if(name) free(name);
+ }
+ }
+ } while((node = node->next));
+}
+
+static void enemies_parse(xmlNodePtr parent) {
+ xmlNodePtr node;
+
+ node = parent->xmlChildrenNode;
+
+ do {
+ if(node->type == XML_NODE_START) {
+ if(strcmp((char*)node->name, XML_ENEMIES_TAG)==0) {
+
+ }
+ }
+ } while((node = node->next));
+}
+
+// Load all the factions.
int factions_load(void) {
uint32_t bufsize;
char* buf = pack_readfile(DATA, FACTION_DATA, &bufsize);
@@ -80,11 +160,17 @@ int factions_load(void) {
}
do {
- if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_FACTION_TAG) == 0) {
- tmp = faction_parse(node);
- faction_stack = realloc(faction_stack, sizeof(Faction)*(++nfactions));
- memcpy(faction_stack+nfactions-1, tmp, sizeof(Faction));
- free(tmp);
+ if(node->type == XML_NODE_START) {
+ if(strcmp((char*)node->name, XML_FACTION_TAG)==0) {
+ tmp = faction_parse(node);
+ faction_stack = realloc(faction_stack, sizeof(Faction)*(++nfactions));
+ memcpy(faction_stack+nfactions-1, tmp, sizeof(Faction));
+ free(tmp);
+ }
+ else if(strcmp((char*)node->name, XML_ALLIANCE_ID)==0)
+ alliance_parse(node);
+ else if(strcmp((char*)node->name, XML_ENEMIES_ID)==0)
+ enemies_parse(node);
}
} while((node = node->next));
@@ -99,8 +185,11 @@ int factions_load(void) {
void factions_free(void) {
int i;
- for(i = 0; i < nfactions; i++)
+ for(i = 0; i < nfactions; i++) {
free(faction_stack[i].name);
+ if(faction_stack[i].nallies > 0) free(faction_stack[i].allies);
+ if(faction_stack[i].nenemies > 0) free(faction_stack[i].enemies);
+ }
free(faction_stack);
nfactions = 0;
}
diff --git a/src/faction.h b/src/faction.h
index 55cdf40..c239fb9 100644
--- a/src/faction.h
+++ b/src/faction.h
@@ -4,7 +4,9 @@ typedef struct Faction {
char* name;
struct Faction** enemies;
+ int nenemies;
struct Faction** allies;
+ int nallies;
} Faction;
Faction* faction_get(const char* name);
diff --git a/src/main.c b/src/main.c
index 65a2d8e..5d66954 100644
--- a/src/main.c
+++ b/src/main.c
@@ -253,16 +253,15 @@ int main(int argc, char** argv) {
space_load();
// Testing.
- pilot_create(ship_get("Ship"), "Player", 0., NULL, NULL, PILOT_PLAYER);
+ pilot_create(ship_get("Ship"), "Player", faction_get("Player"), 0., NULL, NULL, PILOT_PLAYER);
gl_bindCamera(&player->solid->pos);
space_init("SaraSys");
- pilot_create(ship_get("Test"), NULL, 2., NULL, NULL, 0);
-
+ // Welcome message.
player_message("Welcome to "APPNAME"!");
player_message(" v%d.%d.%d", VMAJOR, VMINOR, VREV);
- time = SDL_GetTicks();
+ time = SDL_GetTicks(); // Init the time.
// Main looops.
SDL_Event event;
diff --git a/src/pilot.c b/src/pilot.c
index bccc2ce..8874eae 100644
--- a/src/pilot.c
+++ b/src/pilot.c
@@ -43,9 +43,15 @@ static Fleet* fleet_parse(const xmlNodePtr parent);
// Get the next pilot based on player_id.
unsigned int pilot_getNext(const unsigned int id) {
- int i, n;
- for(i = 0, n = pilots/2; n > 0; n /= 2)
- i += (pilot_stack[i+n]->id > id) ? 0 : n;
+ // Regular search.
+ int i;
+ for(i = 0; i < pilots; i++)
+ if(pilot_stack[i]->id == id)
+ break;
+ // Dichotomical search.
+ //int i, n;
+ //for(i = 0, n = pilots/2; n > 0; n /= 2)
+ //i += (pilot_stack[i+n]->id > id) ? 0 : n;
if(i == pilots-1) return 0;
@@ -55,18 +61,21 @@ unsigned int pilot_getNext(const unsigned int id) {
// Pull a pilot out of the pilot_stack based on id.
Pilot* pilot_get(const unsigned int id) {
// Regular search.
-#if 0
- for(int i = 0; i < pilots; i++)
+ int i;
+ for(i = 0; i < pilots; i++)
if(pilot_stack[i]->id == id)
return pilot_stack[i];
return NULL;
-#endif
+
if(id == 0) return player;
+ DEBUG("id = %d", id);
+#if 0
// Dichotomical search.
int i, n;
for(i = 0, n = pilots/2; n > 0; n /= 2)
i += (pilot_stack[i+n]->id > id) ? 0 : n;
return (pilot_stack[i]->id == id) ? pilot_stack[i] : NULL;
+#endif
}
// Mkay, this is how we shoot. Listen up.
@@ -153,7 +162,7 @@ static void pilot_update(Pilot* pilot, const double dt) {
// pos : Initial position.
// flags : Tweaking the pilot.
// ========================================================
-void pilot_init(Pilot* pilot, Ship* ship, char* name, const double dir, const Vec2* pos,
+void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction, const double dir, const Vec2* pos,
const Vec2* vel, const int flags) {
if(flags & PILOT_PLAYER) // Player is ID 0
@@ -164,6 +173,10 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, const double dir, const Ve
pilot->ship = ship;
pilot->name = strdup((name == NULL) ? ship->name : name);
+ // Faction.
+ pilot->faction = faction;
+
+ // Solid.
pilot->solid = solid_create(ship->mass, dir, pos, vel);
// Max shields armor.
@@ -211,14 +224,14 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, const double dir, const Ve
}
// Create a new pilot - Params are same as pilot_init. Return pilot's id.
-unsigned int pilot_create(Ship* ship, char* name, const double dir,
+unsigned int pilot_create(Ship* ship, char* name, Faction* faction, const double dir,
const Vec2* pos, const Vec2* vel, const int flags) {
Pilot* dyn = MALLOC_L(Pilot);
if(dyn == NULL) {
WARN("Unable to allocate memory.");
return 0;
}
- pilot_init(dyn, ship, name, dir, pos, vel, flags);
+ pilot_init(dyn, ship, name, faction, dir, pos, vel, flags);
if(flags & PILOT_PLAYER) {
// Player.
diff --git a/src/pilot.h b/src/pilot.h
index c8aa366..1f5a866 100644
--- a/src/pilot.h
+++ b/src/pilot.h
@@ -24,6 +24,8 @@ typedef struct Pilot {
unsigned int id; // Pilots id.
char* name; // Pilot's name (if unique).
+ Faction* faction;
+
// Object characteristics.
Ship* ship; // Pilots ship.
Solid* solid; // Associated solid (physics).
@@ -71,10 +73,10 @@ void pilot_shoot(Pilot* p, const int secondary);
void pilot_hit(Pilot* p, const double damage_shield, const double damage_armor);
// Creation.
-void pilot_init(Pilot* dest, Ship* ship, char* name, const double dir,
+void pilot_init(Pilot* dest, Ship* ship, char* name, Faction* faction, const double dir,
const Vec2* pos, const Vec2* vel, const int flags);
-unsigned int pilot_create(Ship* ship, char* name, const double dir,
+unsigned int pilot_create(Ship* ship, char* name, Faction* faction, const double dir,
const Vec2* pos, const Vec2* vel, const int flags);
// Init/Cleanup.
diff --git a/src/player.c b/src/player.c
index 69263d4..0fa0d44 100644
--- a/src/player.c
+++ b/src/player.c
@@ -262,6 +262,8 @@ void player_render(void) {
// Target.
if(player_target) {
+ p = pilot_get(player_target);
+
gl_blitStatic(p->ship->gfx_target, &gui.pos_target);
if(p->armor < p->armor_max * PILOT_DISABLED)
// Disable the pilot.
@@ -424,13 +426,16 @@ static void input_key(int keynum, double value, int abs) {
if(value == KEY_PRESS) player_primary = 1;
else if(value == KEY_RELEASE) player_primary = 0;
}
+ // Targetting.
else if(strcmp(player_input[keynum]->name, "target")==0) {
if(value == KEY_PRESS) player_target = pilot_getNext(player_target);
}
+ // Zoom in.
else if(strcmp(player_input[keynum]->name, "mapzoomin")==0) {
if(value == KEY_PRESS && gui.radar.res < RADAR_RES_MAX)
gui.radar.res += RADAR_RES_INTERVAL;
}
+ // Zoom out.
else if(strcmp(player_input[keynum]->name, "mapzoomout")==0) {
if(value == KEY_PRESS && gui.radar.res > RADAR_RES_MIN)
gui.radar.res -= RADAR_RES_INTERVAL;
diff --git a/src/space.c b/src/space.c
index e39c2bc..bf8077f 100644
--- a/src/space.c
+++ b/src/space.c
@@ -195,20 +195,33 @@ static PlanetClass planetclass_get(const char a) {
// Init the system.
void space_init(const char* sysname) {
- int i;
+ int i, j;
for(i = 0; i < nsystems; i++)
if(strcmp(sysname, systems[i].name)==0)
break;
if(i == nsystems) ERR("System %s not found in stack", sysname);
cur_system = systems+i;
+ // Set up stars.
nstars = (cur_system->stars*gl_screen.w*gl_screen.h+STAR_BUF*STAR_BUF)/(800*640);
- stars = malloc(sizeof(Star)*nstars);
+ stars = realloc(stars, sizeof(Star)*nstars); // Should realloc this, not malloc.
for(i = 0; i < nstars; i++) {
stars[i].brightness = (double)RNG(50, 200)/256.;
stars[i].x = (double)RNG(-STAR_BUF, gl_screen.w + STAR_BUF);
stars[i].y = (double)RNG(-STAR_BUF, gl_screen.h + STAR_BUF);
}
+ // Set up fleets -> pilots.
+ for(i = 0; i < cur_system->nfleets; i++)
+ if(RNG(0,100) <= cur_system->fleets[i].chance) // Check fleet.
+ for(j = 0; j < cur_system->fleets[i].fleet->npilots; j++)
+ if(RNG(0,100) <= cur_system->fleets[i].fleet->pilots[j].chance)
+ pilot_create(cur_system->fleets[i].fleet->pilots[j].ship,
+ cur_system->fleets[i].fleet->pilots[j].name,
+ cur_system->fleets[i].fleet->faction,
+ RNG(0,360),
+ NULL,
+ NULL,
+ 0);
}
// Load the planets of name 'name'.
diff --git a/src/weapon.c b/src/weapon.c
index 0a8885a..ed497d3 100644
--- a/src/weapon.c
+++ b/src/weapon.c
@@ -116,6 +116,7 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
int i;
for(i = 0; i < pilots; i++) {
if((w->parent != pilot_stack[i]->id) && // The pilot hasn't shoot it.
+ !areAllies(pilot_get(w->parent)->faction, pilot_stack[i]->faction) &&
(DIST(w->solid->pos, pilot_stack[i]->solid->pos) < (PILOT_SIZE_APROX *
w->outfit->gfx_space->sw/2. + pilot_stack[i]->ship->gfx_space->sw/2.))) {
pilot_hit(pilot_stack[i], w->outfit->damage_shield, w->outfit->damage_armor);