diff --git a/src/faction.c b/src/faction.c index 1b6dc80..554f6c2 100644 --- a/src/faction.c +++ b/src/faction.c @@ -16,6 +16,8 @@ #define FACTION_DATA "../dat/faction.xml" +#define ALLIANCE_OFFSET 27182 // Special offset for alliances. + typedef struct Faction_ { char* name; @@ -58,6 +60,19 @@ int faction_get(const char* name) { return -1; } +// Return the id of an alliance. +int faction_getAlliance(char* name) { + int i; + for(i = 0; i < nalliances; i++) + if(strcmp(faction_stack[i].name, name)==0) + break; + + if(i != nalliances) + return ALLIANCE_OFFSET + i; + DEBUG("Alliance '%s' not found in stack.", name); + return -1; +} + char* faction_name(int f) { return faction_stack[f].name; } @@ -79,20 +94,34 @@ static Alliance* alliance_get(char* name) { int areEnemies(int a, int b) { Faction* fa, *fb; int i = 0; + + if(a == b) return 0; // Luckily our factions aren't masochistic. - if((a == b) || (a >= nfactions) || (b > nfactions) || - (a < 0) || (b < 0)) return 0; + // Handle a. + if(faction_isFaction(a)) fa = &faction_stack[a]; + else { + // a isn't valid. + DEBUG("areEnemies: %d is an invalid faction/alliance", a); + return 0; + } - 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 < fb->nenemies; i++) - if(fb->enemies[i] == a) - return 1; + // Handle b. + if(faction_isFaction(b)) fb = &faction_stack[b]; + else { + // b isn't valid. + DEBUG("areEnemies: %d is an invalid faction/alliance", b); + return 0; + } + if(fa && fb) { + // Both are factions. + for(i = 0; i < fa->nenemies; i++) + if(fa->enemies[i] == b) + return 1; + for(i = 0; i < fb->nenemies; i++) + if(fb->enemies[i] == a) + return 1; + } return 0; } @@ -101,24 +130,74 @@ int areAllies(int a, int b) { Faction* fa, *fb; int i = 0; - if((a >= nfactions) || (b >= nfactions) || - (a < 0) || (b < 0)) return 0; + // Handle a. + if(faction_isFaction(a)) fa = &faction_stack[a]; + else { + // b isn't valid. + DEBUG("areEnemies: %d is an invalid faction/alliance", a); + return 0; + } + + // Handle b. + if(faction_isFaction(b)) fb = &faction_stack[b]; + else { + // b isn't valid. + DEBUG("areEnemies: %d is an invalid faction/alliance", b); + return 0; + } if(a == b) return 0; - fa = &faction_stack[a]; - fb = &faction_stack[b]; + if(fa && fb) { + // Both are factions. + for(i = 0; i < fa->nallies; i++) + if(fa->allies[i] == b) + return 1; - for(i = 0; i < fa->nallies; i++) - if(fa->allies[i] == b) - return 1; + for(i = 0; i < fb->nallies; i++) + if(fb->allies[i] == a) + return 1; + } + return 0; +} - for(i = 0; i < fb->nallies; i++) - if(fb->allies[i] == a) +// Is faction f part of alliance a? +int faction_ofAlliance(int f, int a) { + int i; + Alliance* aa; + + if(!faction_isFaction(f)) { + DEBUG("faction_ofAlliance: invalid alliance '%d'", f); + return 0; + } + + if(!faction_isAlliance(a)) { + DEBUG("faction_ofAlliance: invalid alliance '%d'", a); + return 0; + } + + aa = &alliances[a]; + + for(i = 0; i < aa->nfactions; i++) + if(aa->factions[i] == f) return 1; return 0; +} +// Return true if a s an alliance. +int faction_isAlliance(int a) { + if((a < ALLIANCE_OFFSET) || (a >= ALLIANCE_OFFSET + nalliances)) + return 0; + + return 1; +} + +// Return true if f is a faction. +int faction_isFaction(int f) { + if((f < 0) || (f >= nfactions)) + return 0; + return 1; } // Parses a single faction, but does not set the allies/enemies. diff --git a/src/faction.h b/src/faction.h index 353217f..7496cfe 100644 --- a/src/faction.h +++ b/src/faction.h @@ -1,11 +1,22 @@ #pragma once +// Get stuff. int faction_get(const char* name); +int faction_getAlliance(char* name); char* faction_name(int f); +// Works with only factions. int areEnemies(int a, int b); int areAllies(int a, int b); +// Faction + Alliance. +int faction_ofAlliance(int f, int a); + +// Check. +int faction_isAlliance(int a); +int faction_isFaction(int f); + +// Load/Free. int factions_load(void); void factions_free(void);