[Add] Faction system almost done.

[Add] Fleets almost complete, just need to randomize start location.
This commit is contained in:
Allanis 2013-02-08 16:04:24 +00:00
parent 6dad718ef2
commit d46f509ee5
9 changed files with 167 additions and 35 deletions

View File

@ -8,8 +8,16 @@
</faction>
<faction name = "Pirate">
</faction>
<alliances>
</alliances>
<Alliances>
<alliance name = "Neutral">
<ally>Independent</ally>
<ally>Merchant</ally>
</alliance>
</Alliances>
<Enemies>
<enemies>
<enemy type = "alliance">Neutral</enemy>
<enemy type = "faction">Pirate</enemy>
</enemies>
</Enemies>
</Factions>

View File

@ -12,6 +12,10 @@
#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++;
if(a->enemies[i] == NULL) return 0;
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;
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++;
if(a->allies[i] == NULL) return 0;
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;
}
// 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,12 +160,18 @@ int factions_load(void) {
}
do {
if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_FACTION_TAG) == 0) {
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));
xmlFreeDoc(doc);
@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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.

View File

@ -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.

View File

@ -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;

View File

@ -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'.

View File

@ -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);