[Change] Use ids for factions instead of pointers.

This commit is contained in:
Allanis 2013-03-31 16:12:33 +01:00
parent bcdce29654
commit a66a9ea264
10 changed files with 94 additions and 72 deletions

View File

@ -16,13 +16,22 @@
#define FACTION_DATA "../dat/faction.xml"
Faction* faction_stack = NULL;
int nfactions = 0;
typedef struct Faction_ {
char* name;
int* enemies;
int nenemies;
int* allies;
int nallies;
} Faction;
static Faction* faction_stack = NULL;
static int nfactions = 0;
// Save alliance.
typedef struct Alliance_ {
char* name;
Faction** factions;
int* factions;
int nfactions;
} Alliance;
@ -36,16 +45,21 @@ static void enemies_parse(xmlNodePtr parent);
static Alliance* alliance_get(char* name);
// Return the faction of name "name".
Faction* faction_get(const char* name) {
int faction_get(const char* name) {
int i;
for(i = 0; i < nfactions; i++)
if(strcmp(faction_stack[i].name, name)==0)
break;
if(i != nfactions)
return faction_stack+i;
return i;
return NULL;
DEBUG("Faction '%s' not found in stack.", name);
return -1;
}
char* faction_name(int f) {
return faction_stack[f].name;
}
// Return the alliance of name 'name'.
@ -62,34 +76,45 @@ static Alliance* alliance_get(char* name) {
}
// Return 1 if Faction a and b are enemies.
int areEnemies(Faction* a, Faction* b) {
int areEnemies(int a, int b) {
Faction* fa, *fb;
int i = 0;
if(a == b) return 0;
else if((a == NULL) || (b == NULL)) return 0;
if((a == b) || (a >= nfactions) || (b > nfactions) ||
(a < 0) || (b < 0)) return 0;
for(i = 0; i < a->nenemies; i++)
if(a->enemies[i] == b)
fa = &faction_stack[a];
fb = &faction_stack[b];
for(i = 0; i < fa->nenemies; i++)
if(fa->enemies[i] == b)
return 1;
for(i = 0; i < b->nenemies; i++)
if(b->enemies[i] == a)
for(i = 0; i < fb->nenemies; i++)
if(fb->enemies[i] == a)
return 1;
return 0;
}
// Return 1 if Faction a and b are allies.
int areAllies(Faction* a, Faction* b) {
int areAllies(int a, int b) {
Faction* fa, *fb;
int i = 0;
if(a == b) return 0;
else if((a == NULL) || (b == NULL)) return 0;
if((a >= nfactions) || (b >= nfactions) ||
(a < 0) || (b < 0)) return 0;
for(i = 0; i < a->nallies; i++)
if(a->allies[i] == b)
if(a == b) return 0;
fa = &faction_stack[a];
fb = &faction_stack[b];
for(i = 0; i < fa->nallies; i++)
if(fa->allies[i] == b)
return 1;
for(i = 0; i < b->nallies; i++)
if(b->allies[i] == a)
for(i = 0; i < fb->nallies; i++)
if(fb->allies[i] == a)
return 1;
return 0;
@ -109,6 +134,7 @@ static Faction* faction_parse(xmlNodePtr parent) {
static void alliance_parse(xmlNodePtr parent) {
Alliance* a;
int* i, j, n, m;
Faction* ft;
xmlNodePtr node, cur;
node = parent->xmlChildrenNode;
@ -132,26 +158,25 @@ static void alliance_parse(xmlNodePtr parent) {
(*i)++;
// Load the faction.
a->factions = realloc(a->factions, (*i)*sizeof(Faction*));
a->factions = realloc(a->factions, (*i)*sizeof(int));
a->factions[(*i)-1] = faction_get((char*)cur->children->content);
if(a->factions[(*i)-1] == NULL)
WARN("Faction %s in alliance %s does not exist in "FACTION_DATA,
if(a->factions[(*i)-1] == -1)
WARN("Faction '%s' in alliance '%s' does not exist in "FACTION_DATA,
(char*)cur->children->content, a->name);
}
} while((cur = cur->next));
// Set the crap needed by faction_stack.
for(j = 0; j < (*i); j++) {
a->factions[j]->nallies += (*i)-1;
a->factions[j]->allies = realloc(a->factions[j]->allies,
a->factions[j]->nallies*sizeof(Faction*));
ft = &faction_stack[a->factions[j]];
ft->nallies += (*i)-1;
ft->allies = realloc(ft->allies, (ft->nallies)*sizeof(int));
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)
a->factions[j]->allies[a->factions[j]->nallies-(*i)+1+m] =
a->factions[n];
ft->allies[ft->nallies-(*i)+1+m] = a->factions[n];
}
}
}
@ -160,7 +185,8 @@ static void alliance_parse(xmlNodePtr parent) {
static void enemies_parse(xmlNodePtr parent) {
xmlNodePtr node, cur;
Faction*** f;
int** f;
Faction* ft;
Alliance* a;
int i, *j, n, m, x, y, z, e;
char* type;
@ -181,7 +207,7 @@ static void enemies_parse(xmlNodePtr parent) {
i++;
j = realloc(j, sizeof(int)*i);
f = realloc(f, sizeof(Faction**)*i);
f = realloc(f, sizeof(int*)*i);
if(strcmp(type, "alliance")==0) {
// Enemy thing is an alliance.
@ -195,9 +221,9 @@ static void enemies_parse(xmlNodePtr parent) {
else if(strcmp(type,"faction")==0) {
// Enemy thing is only a faction.
j[i-1] = 1;
f[i-1] = malloc(sizeof(Faction*));
f[i-1] = malloc(sizeof(int));
f[i-1][0] = faction_get((char*)cur->children->content);
if(f[i-1][0] == NULL)
if(f[i-1][0] == -1)
WARN("Faction %s not found in stack",
(char*)cur->children->content);
}
@ -205,16 +231,16 @@ static void enemies_parse(xmlNodePtr parent) {
}
} while((cur = cur->next));
// Now actually parse and load up the enemies.
for(n = 0; n < i; n++) {
for(m = 0; m < j[n]; m++) {
for(n = 0; n < i; n++) { // Unsinged int.
for(m = 0; m < j[n]; m++) { // Unsigned int.
// Faction.
// Add all the faction enemies to nenemies and alloc.
for(e = 0, x = 0; x < i; x++)
if(x != n) e += j[x]; // Store the total enemies.
// Now allocate the memory.
f[n][m]->nenemies += e;
f[n][m]->enemies = realloc(f[n][m]->enemies,
sizeof(Faction*)*f[n][m]->nenemies);
ft = &faction_stack[f[n][m]];
ft->nenemies += e;
ft->enemies = realloc(ft->enemies, sizeof(int)*ft->nenemies);
// Add the actualy enemies.
for(x = 0, z = 0; x < i; x++)
@ -222,7 +248,7 @@ static void enemies_parse(xmlNodePtr parent) {
// Make sure it's not from the same group.
if(x != n)
for(y = 0; y < j[x]; y++, z++)
f[n][m]->enemies[f[n][m]->nenemies-e+z]=f[x][y];
ft->enemies[ft->nenemies-e+z] = f[x][y];
}
}
// Free al the temp memory.

View File

@ -1,18 +1,10 @@
#pragma once
typedef struct Faction_ {
char* name;
int faction_get(const char* name);
char* faction_name(int f);
struct Factiona_** enemies;
int nenemies;
struct Faction_** allies;
int nallies;
} Faction;
Faction* faction_get(const char* name);
int areEnemies(Faction* a, Faction* b);
int areAllies(Faction* a, Faction* b);
int areEnemies(int a, int b);
int areAllies(int a, int b);
int factions_load(void);
void factions_free(void);

View File

@ -87,7 +87,7 @@ static void map_close(char* str) {
static void map_update(void) {
int i;
StarSystem* sys;
Faction* f;
int f;
char buf[100];
sys = &systems_stack[map_selected];
@ -98,9 +98,9 @@ static void map_update(void) {
// No planets -> no factions.
snprintf(buf, 100, "NA");
else {
f = NULL;
f = -1;
for(i = 0; i < sys->nplanets; i++) {
if(f == NULL)
if(f == -1)
f = sys->planets[i].faction;
else if(f != sys->planets[i].faction) {
// TODO: more verbosity.
@ -110,7 +110,7 @@ static void map_update(void) {
}
if(i == sys->nplanets)
// Saw them all, and all the same.
snprintf(buf, 100, "%s", f->name);
snprintf(buf, 100, "%s", faction_name(f));
}
window_modifyText(map_wid, "txtFaction", buf);

View File

@ -141,17 +141,17 @@ static rnd_int(lua_State* L) {
// -- HOOK --
static int hook_land(lua_State* L) {
char* parent, *func;
char* func;
MIN_ARGS(1);
parent = cur_mission->data->name;
if(lua_isstring(L, -1)) func = (char*)lua_tostring(L, -1);
else {
WARN("Mission %s: trying to push non-valid function hook", parent);
WARN("Mission '%s': trying to push non-valid function hook",
cur_mission->data->name);
return 0;
}
hook_add(L, parent, func, "land");
hook_add(L, cur_mission->id, func, "land");
return 0;
}

View File

@ -1,5 +1,4 @@
#pragma once
#include "faction.h"
#include "misn_lua.h"
// Availability by location.
@ -29,7 +28,7 @@ typedef struct MissionData_ {
char* system;
// For generic cases.
Faction* factions;
int* factions;
int nfactions;
} avail;

View File

@ -665,7 +665,7 @@ int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) {
// pos : Initial position.
// flags : Tweaking the pilot.
// ========================================================
void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction,
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags) {
@ -740,7 +740,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
}
// Create a new pilot - Params are same as pilot_init. Return pilot's id.
unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
unsigned int pilot_create(Ship* ship, char* name, int faction,
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags) {
@ -905,6 +905,7 @@ static Fleet* fleet_parse(const xmlNodePtr parent) {
node = parent->xmlChildrenNode;
Fleet* tmp = CALLOC_L(Fleet);
tmp->faction = -1;
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); // Already mallocs.
if(tmp->name == NULL) WARN("Fleet in "FLEET_DATA" has invalid or no name");
@ -946,6 +947,7 @@ static Fleet* fleet_parse(const xmlNodePtr parent) {
} while((node = node->next));
#define MELEMENT(o,s) if(o) WARN("Fleet '%s' missing '"s"' element", tmp->name)
MELEMENT(tmp->ai==NULL, "ai");
MELEMENT(tmp->faction==-1, "faction");
MELEMENT(tmp->faction==NULL, "faction");
MELEMENT(tmp->pilots==NULL, "pilots");
#undef MELEMENT

View File

@ -60,7 +60,7 @@ typedef struct Pilot_ {
unsigned int id; // Pilots id.
char* name; // Pilot's name (if unique).
Faction* faction;
int faction;
// Object characteristics.
Ship* ship; // Pilots ship.
@ -112,7 +112,7 @@ typedef struct FleetPilot_ {
typedef struct Fleet_ {
char* name; // Fleet name, used as an identifier.
Faction* faction; // Faction of the fleet.
int faction; // Faction of the fleet.
AI_Profile* ai; // A useable profile.
@ -143,11 +143,11 @@ int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity);
int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity);
// Creation.
void pilot_init(Pilot* dest, Ship* ship, char* name, Faction* faction,
void pilot_init(Pilot* dest, Ship* ship, char* name, int faction,
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags);
unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
unsigned int pilot_create(Ship* ship, char* name, int faction,
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags);

View File

@ -611,7 +611,7 @@ void player_render(void) {
gl_print(NULL, gui.target_name.x, gui.target_name.y,
NULL, "%s", p->name);
gl_print(&gl_smallFont, gui.target_faction.x, gui.target_faction.y,
NULL, "%s", p->faction->name);
NULL, "%s", faction_name(p->faction));
// Target status.
if(pilot_isDisabled(p))

View File

@ -37,6 +37,7 @@
#define FLAG_INTEFERENCESET (1<<3)
#define FLAG_SERVICESET (1<<4)
#define FLAG_TECHSET (1<<5)
#define FLAG_FACTIONSET (1<<6)
// Star system stack and co.
StarSystem* systems_stack = NULL; // Star system stack.
@ -367,8 +368,10 @@ static Planet* planet_get(const char* name) {
do {
if(xml_isNode(cur, "class"))
tmp->class = planetclass_get(cur->children->content[0]);
else if(xml_isNode(cur, "faction"))
else if(xml_isNode(cur, "faction")) {
flags |= FLAG_FACTIONSET;
tmp->faction = faction_get(xml_get(cur));
}
else if(xml_isNode(cur, "description"))
tmp->description = strdup(xml_get(cur));
else if(xml_isNode(cur, "bar"))
@ -434,7 +437,7 @@ static Planet* planet_get(const char* name) {
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
tmp->bar_description==NULL, "bar");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
tmp->faction==NULL, "faction");
(flags & FLAG_FACTIONSET)==0, "faction");
MELEMENT((flags&FLAG_SERVICESET)==0, "services");
MELEMENT((planet_hasService(tmp, PLANET_SERVICE_OUTFITS) ||

View File

@ -51,7 +51,7 @@ typedef struct Planet_ {
Vec2 pos; // Position in star system.
PlanetClass class; // Planet type.
Faction* faction; // Planet faction.
int faction; // Planet faction.
char* description; // Planet description.
char* bar_description; // Spaceport bar description.
@ -79,7 +79,7 @@ typedef struct StarSystem_ {
int stars, asteroids; // Un numero!
double interference; // Un uh.. Percentage.
Faction* faction; // Overall faction.
int faction; // Overall faction.
Planet* planets; // Planets.
int nplanets; // Total number of planets.