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

View File

@ -1,18 +1,10 @@
#pragma once #pragma once
typedef struct Faction_ { int faction_get(const char* name);
char* name; char* faction_name(int f);
struct Factiona_** enemies; int areEnemies(int a, int b);
int nenemies; int areAllies(int a, int b);
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 factions_load(void); int factions_load(void);
void factions_free(void); void factions_free(void);

View File

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

View File

@ -141,17 +141,17 @@ static rnd_int(lua_State* L) {
// -- HOOK -- // -- HOOK --
static int hook_land(lua_State* L) { static int hook_land(lua_State* L) {
char* parent, *func; char* func;
MIN_ARGS(1); MIN_ARGS(1);
parent = cur_mission->data->name;
if(lua_isstring(L, -1)) func = (char*)lua_tostring(L, -1); if(lua_isstring(L, -1)) func = (char*)lua_tostring(L, -1);
else { 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; return 0;
} }
hook_add(L, parent, func, "land"); hook_add(L, cur_mission->id, func, "land");
return 0; return 0;
} }

View File

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

View File

@ -665,7 +665,7 @@ int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) {
// pos : Initial position. // pos : Initial position.
// flags : Tweaking the pilot. // 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, AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags) { 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. // 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, AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags) { const Vec2* vel, const int flags) {
@ -905,6 +905,7 @@ static Fleet* fleet_parse(const xmlNodePtr parent) {
node = parent->xmlChildrenNode; node = parent->xmlChildrenNode;
Fleet* tmp = CALLOC_L(Fleet); Fleet* tmp = CALLOC_L(Fleet);
tmp->faction = -1;
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); // Already mallocs. tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); // Already mallocs.
if(tmp->name == NULL) WARN("Fleet in "FLEET_DATA" has invalid or no name"); 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)); } while((node = node->next));
#define MELEMENT(o,s) if(o) WARN("Fleet '%s' missing '"s"' element", tmp->name) #define MELEMENT(o,s) if(o) WARN("Fleet '%s' missing '"s"' element", tmp->name)
MELEMENT(tmp->ai==NULL, "ai"); MELEMENT(tmp->ai==NULL, "ai");
MELEMENT(tmp->faction==-1, "faction");
MELEMENT(tmp->faction==NULL, "faction"); MELEMENT(tmp->faction==NULL, "faction");
MELEMENT(tmp->pilots==NULL, "pilots"); MELEMENT(tmp->pilots==NULL, "pilots");
#undef MELEMENT #undef MELEMENT

View File

@ -60,7 +60,7 @@ typedef struct Pilot_ {
unsigned int id; // Pilots id. unsigned int id; // Pilots id.
char* name; // Pilot's name (if unique). char* name; // Pilot's name (if unique).
Faction* faction; int faction;
// Object characteristics. // Object characteristics.
Ship* ship; // Pilots ship. Ship* ship; // Pilots ship.
@ -111,8 +111,8 @@ typedef struct FleetPilot_ {
} FleetPilot; } FleetPilot;
typedef struct Fleet_ { typedef struct Fleet_ {
char* name; // Fleet name, used as an identifier. 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. 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); int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity);
// Creation. // 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, AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags); 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, AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags); 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, gl_print(NULL, gui.target_name.x, gui.target_name.y,
NULL, "%s", p->name); NULL, "%s", p->name);
gl_print(&gl_smallFont, gui.target_faction.x, gui.target_faction.y, 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. // Target status.
if(pilot_isDisabled(p)) if(pilot_isDisabled(p))

View File

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

View File

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