From 7dbe3d2598b94a79c9df8fafdd793592c183cb6b Mon Sep 17 00:00:00 2001 From: Allanis Date: Thu, 14 Feb 2013 17:55:31 +0000 Subject: [PATCH] [Add] It is now possible to disable ships - No death yet. [Add] Player start location. ship etc can now be defined in data file. --- dat/ship.xml | 2 +- dat/start.xml | 15 +++++++++ src/main.c | 10 ++---- src/physics.c | 4 +-- src/pilot.c | 39 +++++++++++------------ src/pilot.h | 6 ++-- src/player.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/player.h | 3 ++ 8 files changed, 127 insertions(+), 38 deletions(-) create mode 100644 dat/start.xml diff --git a/dat/ship.xml b/dat/ship.xml index 4db4fc6..89c490d 100644 --- a/dat/ship.xml +++ b/dat/ship.xml @@ -56,7 +56,7 @@ ship1 - simple + minimal 2 180 diff --git a/dat/start.xml b/dat/start.xml new file mode 100644 index 0000000..af6b2c2 --- /dev/null +++ b/dat/start.xml @@ -0,0 +1,15 @@ + + + Lancer + + 500 + 1500 + + + SaraSys + 100 + 75 + + + + diff --git a/src/main.c b/src/main.c index 04234fb..b7ef1a0 100644 --- a/src/main.c +++ b/src/main.c @@ -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. diff --git a/src/physics.c b/src/physics.c index 4354007..768664a 100644 --- a/src/physics.c +++ b/src/physics.c @@ -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. diff --git a/src/pilot.c b/src/pilot.c index a371f52..e7376c9 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -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); diff --git a/src/pilot.h b/src/pilot.h index f0b9ee6..ab80589 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -9,8 +9,8 @@ #define PLAYER_ID 1 // Aproximation for pilot size. -#define PILOT_SIZE_APROX 0.8 -#define PILOT_DISABLED 0.2 // Based on armor percentage. +#define PILOT_SIZE_APROX 0.8 +#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) diff --git a/src/player.c b/src/player.c index 30b5eb7..69cfd12 100644 --- a/src/player.c +++ b/src/player.c @@ -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); diff --git a/src/player.h b/src/player.h index 636df4e..90e445f 100644 --- a/src/player.h +++ b/src/player.h @@ -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);