diff --git a/src/faction.c b/src/faction.c index f430569..1b6dc80 100644 --- a/src/faction.c +++ b/src/faction.c @@ -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. diff --git a/src/faction.h b/src/faction.h index a55f8d0..353217f 100644 --- a/src/faction.h +++ b/src/faction.h @@ -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); diff --git a/src/map.c b/src/map.c index 508410f..d368ad8 100644 --- a/src/map.c +++ b/src/map.c @@ -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); diff --git a/src/misn_lua.c b/src/misn_lua.c index a1f5ece..bbf2091 100644 --- a/src/misn_lua.c +++ b/src/misn_lua.c @@ -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; } diff --git a/src/mission.h b/src/mission.h index 606c3e1..091ec6d 100644 --- a/src/mission.h +++ b/src/mission.h @@ -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; diff --git a/src/pilot.c b/src/pilot.c index d32aadf..e74f39a 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -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 diff --git a/src/pilot.h b/src/pilot.h index 349a28c..2aa8365 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -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. @@ -111,8 +111,8 @@ typedef struct FleetPilot_ { } FleetPilot; typedef struct Fleet_ { - char* name; // Fleet name, used as an identifier. - Faction* faction; // Faction of the fleet. + char* name; // Fleet name, used as an identifier. + 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); diff --git a/src/player.c b/src/player.c index bc5f5ae..d80fa4e 100644 --- a/src/player.c +++ b/src/player.c @@ -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)) diff --git a/src/space.c b/src/space.c index 3420ab0..f64b2ed 100644 --- a/src/space.c +++ b/src/space.c @@ -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) || diff --git a/src/space.h b/src/space.h index cac3692..6d77eba 100644 --- a/src/space.h +++ b/src/space.h @@ -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.