[Add] It is now possible to disable ships - No death yet.

[Add] Player start location. ship etc can now be defined in data file.
This commit is contained in:
Allanis 2013-02-14 17:55:31 +00:00
parent e269911055
commit 7dbe3d2598
8 changed files with 127 additions and 38 deletions

View File

@ -56,7 +56,7 @@
</ship>
<ship name="Lancer">
<GFX>ship1</GFX>
<GUI>simple</GUI>
<GUI>minimal</GUI>
<class>2</class>
<movement>
<thrust>180</thrust>

15
dat/start.xml Normal file
View File

@ -0,0 +1,15 @@
<Start>
<player>
<ship>Lancer</ship>
<credits>
<low>500</low>
<high>1500</high>
</credits>
<system>
<name>SaraSys</name>
<x>100</x>
<y>75</y>
</system>
</player>
</Start>

View File

@ -251,14 +251,8 @@ int main(int argc, char** argv) {
fleet_load();
space_load();
// Testing.
pilot_create(ship_get("Merchant Ship"), "Player", faction_get("Player"), NULL, 0., NULL, NULL, PILOT_PLAYER);
gl_bindCamera(&player->solid->pos);
space_init("SaraSys");
// Welcome message.
player_message("Welcome to "APPNAME"!");
player_message(" v%d.%d.%d", VMAJOR, VMINOR, VREV);
// Create new player. TODO: Start menu.
player_new();
time = SDL_GetTicks(); // Init the time.

View File

@ -134,8 +134,8 @@ static void simple_update(Solid* obj, const double dt) {
static void rk4_update(Solid* obj, const double dt) {
// Make sure angle doesn't flip.
obj->dir += M_PI/180.*obj->dir_vel*dt;
if(obj->dir >= 2*M_PI) obj->dir -= 2*M_PI;
if(obj->dir < 0.) obj->dir += 2*M_PI;
if(obj->dir >= 2.*M_PI) obj->dir -= 2*M_PI;
else if(obj->dir < 0.) obj->dir += 2*M_PI;
int N = (dt > RK4_MIN_H) ? (int)(dt/RK4_MIN_H) : 1;
double h = dt / (double)N; // Step.

View File

@ -40,7 +40,7 @@ static Fleet* fleet_parse(const xmlNodePtr parent);
// Get the next pilot based on id.
unsigned int pilot_getNext(const unsigned int id) {
// Dichotmical search.
// Binary search.
int l, m, h;
l = 0;
h = pilots-1;
@ -90,19 +90,9 @@ unsigned pilot_getHostile(void) {
// Pull a pilot out of the pilot_stack based on id.
Pilot* pilot_get(const unsigned int id) {
// Regular search.
#if 0
int i;
for(i = 0; i < pilots; i++)
if(pilot_stack[i]->id == id)
return pilot_stack[i];
return NULL;
if(id == 0) return player;
#endif
if(id == PLAYER_ID) return player; // Special case player.
// Dichotomical search.
// Binary search.
int l, m, h;
l = 0;
h = pilots-1;
@ -167,8 +157,20 @@ void pilot_render(Pilot* p) {
// Update the pilot.
static void pilot_update(Pilot* pilot, const double dt) {
// Regeneration.
if(pilot->armor < pilot->armor_max)
if(pilot != player && pilot->armor < PILOT_DISABLED_ARMOR * pilot->armor_max) {
// We are disabled.
pilot_setFlag(pilot, PILOT_DISABLED);
// Come to a halt slowly.
vect_pset(&pilot->solid->vel, VMOD(pilot->solid->vel) * (1. - dt*0.10), VANGLE(pilot->solid->vel));
vectnull(&pilot->solid->force);
pilot->solid->dir_vel = 0.; // Stop it from turning.
// Update the solid.
pilot->solid->update(pilot->solid, dt);
return;
}
// We are still alive.
else if(pilot->armor < pilot->armor_max)
pilot->armor += pilot->ship->armor_regen*dt;
else
pilot->shield += pilot->ship->shield_regen*dt;
@ -176,18 +178,13 @@ static void pilot_update(Pilot* pilot, const double dt) {
if(pilot->armor > pilot->armor_max) pilot->armor = pilot->armor_max;
if(pilot->shield > pilot->shield_max) pilot->shield = pilot->shield_max;
if((pilot->solid->dir > 2.*M_PI) || (pilot->solid->dir < 0.0))
pilot->solid->dir = fmod(pilot->solid->dir, 2.*M_PI);
// Update the solid.
pilot->solid->update(pilot->solid, dt);
(*pilot->solid->update)(pilot->solid, dt);
if(VMOD(pilot->solid->vel) > pilot->ship->speed) {
// Should not go faster.
vect_pset(&pilot->solid->vel, pilot->ship->speed, VANGLE(pilot->solid->vel));
}
pilot_render(pilot);
}
// ==Init pilot.===========================================
@ -319,7 +316,7 @@ void pilots_free(void) {
void pilots_update(double dt) {
int i;
for(i = 0; i < pilots; i++) {
if(pilot_stack[i]->think)
if(pilot_stack[i]->think && !pilot_isFlag(pilot_stack[i], PILOT_DISABLED))
pilot_stack[i]->think(pilot_stack[i]);
if(pilot_stack[i]->update)
pilot_stack[i]->update(pilot_stack[i], dt);

View File

@ -10,7 +10,7 @@
// Aproximation for pilot size.
#define PILOT_SIZE_APROX 0.8
#define PILOT_DISABLED 0.2 // Based on armor percentage.
#define PILOT_DISABLED_ARMOR 0.2 // Based on armor percentage.
// Flags.
#define pilot_isFlag(p,f) (p->flags & f)
@ -22,7 +22,7 @@
#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player.
#define PILOT_COMBAT (1<<2) // Pilot is engaged in combat.
#define PILOT_HYPERSPACE (1<<3) // Pilot is in hyperspace.
#define PILOT_DISABLED (1<<4) // Pilot is disabled.
// Just makes life simpler.
#define pilot_isPlayer(p) ((p)->flags & PILOT_PLAYER)

View File

@ -6,14 +6,20 @@
#include "opengl.h"
#include "pack.h"
#include "xml.h"
#include "space.h"
#include "rng.h"
#include "player.h"
#define XML_GUI_ID "GUIs" // XML section identifier.
#define XML_GUI_TAG "gui"
#define XML_START_ID "Start"
#define GUI_DATA "../dat/gui.xml"
#define GUI_GFX "../gfx/gui/"
#define START_DATA "../dat/start.xml"
#define POW2(x) ((x)*(x))
#define GFX_GUI_FRAME "../gfx/gui/frame.png"
@ -41,7 +47,7 @@ unsigned int credits = 0;
static double player_turn = 0.; // Turn velocity from input.
static double player_acc = 0.; // Accel velocity from input.
static int player_primary = 0; // Player is shooting primary weapon.
static int player_secondary = 0; // layer is shooting secondary weapon.
//static int player_secondary = 0; // layer is shooting secondary weapon.
static unsigned int player_target = PLAYER_ID; // Targetted pilot.
static int planet_target = -1; // Targetted planet.
static int weapon = -1; // Secondary weapon is in use.
@ -132,6 +138,78 @@ static int gui_parse(const xmlNodePtr parent, const char* name);
static void gui_renderPilot(const Pilot* p);
static void gui_renderBar(const glColor* c, const Vec2* p, const Rect* r, const double w);
// Create a new player.
void player_new(void) {
Ship* ship;
char system[20];
uint32_t bufsize;
char* buf = pack_readfile(DATA, START_DATA, &bufsize);
int l, h;
double x, y, d;
Vec2 v;
xmlNodePtr node, cur, tmp;
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
node = doc->xmlChildrenNode;
if(!xml_isNode(node, XML_START_ID)) {
ERR("Malformed '"START_DATA"' file: missing root element '"XML_START_ID"'");
return;
}
node = node->xmlChildrenNode; // First system node.
if(node == NULL) {
ERR("Malformed '"START_DATA"' file: does not contain elements");
return;
}
do {
// We are interested in the player.
if(xml_isNode(node, "player")) {
cur = node->children;
do {
if(xml_isNode(cur, "ship")) ship = ship_get(xml_get(cur));
else if(xml_isNode(cur, "credits")) {
// MONIEZZ!!!! -- We call these SCred AKA SaraCred. Lame right?
tmp = cur->children;
do {
if(xml_isNode(tmp, "low")) l = xml_getInt(tmp);
else if(xml_isNode(tmp, "high")) h = xml_getInt(tmp);
} while((tmp = tmp->next));
}
else if(xml_isNode(cur, "system")) {
tmp = cur->children;
do {
// System name. TODO: Chance based on percentage.
if(xml_isNode(tmp, "name")) snprintf(system, 20, xml_get(tmp));
// Position.
else if(xml_isNode(tmp, "x")) x = xml_getFloat(tmp);
else if(xml_isNode(tmp, "y")) y = xml_getFloat(tmp);
} while((tmp = tmp->next));
}
} while((cur = cur->next));
}
}while((node = node->next));
xmlFreeDoc(doc);
free(buf);
xmlCleanupParser();
// Money.
credits = RNG(l, h);
// Position and direction.
vect_cset(&v, x, y);
d = RNG(0, 359)/180.*M_PI;
pilot_create(ship, "Player", faction_get("Player"), NULL, d, &v, NULL, PILOT_PLAYER);
gl_bindCamera(&player->solid->pos);
space_init(system);
// Welcome message.
player_message("Welcome to "APPNAME"!");
player_message("v%d.%d.%d", VMAJOR, VMINOR, VREV);
}
void player_message(const char* fmt, ...) {
va_list ap;
int i;
@ -164,7 +242,8 @@ void player_render(void) {
if(player_target != PLAYER_ID) {
p = pilot_get(player_target);
if(pilot_isFlag(p, PILOT_HOSTILE)) c = &cHostile;
if(pilot_isFlag(p, PILOT_DISABLED)) c = &cInert;
else if(pilot_isFlag(p, PILOT_HOSTILE)) c = &cHostile;
else c = &cNeutral;
vect_csetmin(&v, VX(p->solid->pos) - p->ship->gfx_space->sw * PILOT_SIZE_APROX/2.,
@ -271,7 +350,7 @@ void player_render(void) {
gl_print(&gui.smallFont, &gui.pos_target_faction, NULL, "%s", p->faction->name);
// Target status.
if(p->armor < p->armor_max * PILOT_DISABLED)
if(pilot_isFlag(p, PILOT_DISABLED))
// Disable the pilot.
gl_print(&gui.smallFont, &gui.pos_target_health, NULL, "Disabled");
else if(p->shield > p->shield_max / 100.)
@ -342,6 +421,7 @@ static void gui_renderPilot(const Pilot* p) {
glBegin(GL_QUADS);
// Colors.
if(p->id == player_target) COLOR(cRadar_targ);
else if(pilot_isFlag(p, PILOT_DISABLED)) COLOR(cInert);
else if(pilot_isFlag(p, PILOT_HOSTILE)) COLOR(cHostile);
else COLOR(cNeutral);

View File

@ -9,6 +9,9 @@ extern unsigned int credits;
typedef enum { RADAR_RECT, RADAR_CIRCLE } RadarShape; // For render functions.
typedef enum { KEYBIND_NULL, KEYBIND_KEYBOARD, KEYBIND_JAXIS, KEYBIND_JBUTTON } KeybindType;
// Creation.
void player_new(void);
// Render.
int gui_init(void);
void gui_free(void);