[Add] Faction system almost done.
[Add] Fleets almost complete, just need to randomize start location.
This commit is contained in:
parent
6dad718ef2
commit
d46f509ee5
@ -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>
|
||||
|
105
src/faction.c
105
src/faction.c
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
31
src/pilot.c
31
src/pilot.c
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
17
src/space.c
17
src/space.c
@ -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'.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user