[Add] Rudementory Hyperspace travel. Still a work in progress. ;)

This commit is contained in:
Allanis 2013-02-20 19:34:30 +00:00
parent a417d59492
commit 44c6ea6ed6
14 changed files with 292 additions and 72 deletions

View File

@ -21,8 +21,8 @@
</planet> </planet>
<planet name="SaraCraft"> <planet name="SaraCraft">
<pos> <pos>
<x>125</x> <x>0</x>
<y>-345</y> <y>0</y>
</pos> </pos>
<general> <general>
<class>A</class> <class>A</class>

View File

@ -12,7 +12,6 @@
</general> </general>
<planets> <planets>
<planet>KonoSphere</planet> <planet>KonoSphere</planet>
<planet>SaraCraft</planet>
</planets> </planets>
<fleets> <fleets>
<fleet chance="100">Enemy Test</fleet> <fleet chance="100">Enemy Test</fleet>
@ -23,6 +22,9 @@
<fleet chance="50">Sml Merchant Convoy</fleet> <fleet chance="50">Sml Merchant Convoy</fleet>
<fleet chance="40">Sml Merchant Convoy</fleet> <fleet chance="40">Sml Merchant Convoy</fleet>
</fleets> </fleets>
<jumps>
<jump>KonoSys</jump>
</jumps>
</ssys> </ssys>
<ssys name="KonoSys"> <ssys name="KonoSys">
<pos> <pos>
@ -41,5 +43,9 @@
<fleet chance="80">Merchant Ship</fleet> <fleet chance="80">Merchant Ship</fleet>
<fleet chance="60">Merchant Ship</fleet> <fleet chance="60">Merchant Ship</fleet>
</fleets> </fleets>
<jumps>
<jump>SaraSys</jump>
</jumps>
</ssys> </ssys>
</Systems> </Systems>

View File

@ -58,10 +58,6 @@
// Don't run the function if (n) params aren't passed. // Don't run the function if (n) params aren't passed.
#define MIN_ARGS(n) if(lua_gettop(L) < n) return 0 #define MIN_ARGS(n) if(lua_gettop(L) < n) return 0
#define MIN_DIR_ERR 1.0*M_PI/180.
#define MAX_DIR_ERR 0.1*M_PI/180.
#define MIN_VEL_ERR 0.5
// Ai flags. // Ai flags.
#define ai_setFlag(f) (pilot_flags |= f) #define ai_setFlag(f) (pilot_flags |= f)
#define ai_isFlag(f) (pilot_flags & f) #define ai_isFlag(f) (pilot_flags & f)

View File

@ -1,6 +1,11 @@
#pragma once #pragma once
#include "lua.h" #include "lua.h"
#define MIN_DIR_ERR 1.0*M_PI/180.
#define MAX_DIR_ERR 0.1*M_PI/180.
#define MIN_VEL_ERR 0.5
// Max number of AI timers. // Max number of AI timers.
#define MAX_AI_TIMERS 2 #define MAX_AI_TIMERS 2

View File

@ -24,14 +24,13 @@ static Keybind** input_keybinds; // Contains the players keybindings.
const char* keybindNames[] = { "accel", "left", "right", "reverse", // Movement. const char* keybindNames[] = { "accel", "left", "right", "reverse", // Movement.
"primary", "target", "target_nearest", "face", "board", // Combat. "primary", "target", "target_nearest", "face", "board", // Combat.
"secondary", "secondary_next", // Secondary weapons. "secondary", "secondary_next", // Secondary weapons.
"target_planet", "land", // Navigation. "target_planet", "land", "thyperspace", "jump", // Navigation.
"mapzoomin", "mapzoomout", "screenshot", "pause", "menu", // Misc. "mapzoomin", "mapzoomout", "screenshot", "pause", "menu", // Misc.
"end" }; // Must terminate at the end. "end" }; // Must terminate at the end.
// From player.c // From player.c
extern double player_turn; extern double player_turn;
extern double player_acc; extern double player_acc;
extern unsigned int player_target; extern unsigned int player_target;
extern int planet_target;
// Grabbed from main.c // Grabbed from main.c
extern int show_fps; extern int show_fps;
@ -56,6 +55,9 @@ void input_setDefault(void) {
// Space // Space
input_setKeybind("target_planet", KEYBIND_KEYBOARD, SDLK_p, 0); input_setKeybind("target_planet", KEYBIND_KEYBOARD, SDLK_p, 0);
input_setKeybind("land", KEYBIND_KEYBOARD, SDLK_l, 0); input_setKeybind("land", KEYBIND_KEYBOARD, SDLK_l, 0);
input_setKeybind("thyperspace", KEYBIND_KEYBOARD, SDLK_h, 0);
input_setKeybind("jump", KEYBIND_KEYBOARD, SDLK_j, 0);
// Misc. // Misc.
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_UP, 0); input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_UP, 0);
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_DOWN, 0); input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_DOWN, 0);
@ -175,7 +177,7 @@ static void input_key(int keynum, double value, int abs) {
else if(KEY("board") && !paused) { else if(KEY("board") && !paused) {
if(value == KEY_PRESS) player_board(); if(value == KEY_PRESS) player_board();
} }
// Selecting secondary weapon. // Shooting secondary weapon.
else if(KEY("secondary") && !paused) { else if(KEY("secondary") && !paused) {
if(value == KEY_PRESS) player_setFlag(PLAYER_SECONDARY); if(value == KEY_PRESS) player_setFlag(PLAYER_SECONDARY);
else if(value == KEY_RELEASE) player_rmFlag(PLAYER_SECONDARY); else if(value == KEY_RELEASE) player_rmFlag(PLAYER_SECONDARY);
@ -184,15 +186,6 @@ static void input_key(int keynum, double value, int abs) {
else if(KEY("secondary_next") && !paused) { else if(KEY("secondary_next") && !paused) {
if(value == KEY_PRESS) player_secondaryNext(); if(value == KEY_PRESS) player_secondaryNext();
} }
// Selecting secondary weapon.
else if(KEY("secondary")) {
if(value == KEY_PRESS) player_setFlag(PLAYER_SECONDARY);
else if(value == KEY_RELEASE) player_rmFlag(PLAYER_SECONDARY);
}
// Selecting secondary weapon.
else if(KEY("secondary_next") && !paused) {
if(value == KEY_PRESS) player_secondaryNext();
}
// Space. // Space.
// Target planet (cycles just like target). // Target planet (cycles just like target).
else if(KEY("target_planet") && !paused) { else if(KEY("target_planet") && !paused) {
@ -202,6 +195,12 @@ static void input_key(int keynum, double value, int abs) {
else if(KEY("land") && !paused) { else if(KEY("land") && !paused) {
if(value == KEY_PRESS) player_land(); if(value == KEY_PRESS) player_land();
} }
else if(KEY("thyperspace") && !paused) {
if(value == KEY_PRESS) player_targetHyperspace();
}
else if(KEY("jump") && !paused) {
if(value == KEY_PRESS) player_jump();
}
// Zoom in. // Zoom in.
else if(KEY("mapzoomin")) { else if(KEY("mapzoomin")) {
if(value == KEY_PRESS) player_setRadarRel(1); if(value == KEY_PRESS) player_setRadarRel(1);

View File

@ -144,8 +144,7 @@ void takeoff(void) {
sh = planet->gfx_space->h; sh = planet->gfx_space->h;
// Set player to another position with random facing direction and no velocity. // Set player to another position with random facing direction and no velocity.
vect_cset(&player->solid->pos, player_warp(planet->pos.x + RNG(-sw/2, sw/2), planet->pos.y + RNG(-sh/2, sh/2));
planet->pos.x + RNG(-sw/2, sw/2), planet->pos.y + RNG(-sh/2, sh/2));
vect_pset(&player->solid->vel, 0., 0.); vect_pset(&player->solid->vel, 0., 0.);
player->solid->dir = RNG(0, 359) * M_PI/180.; player->solid->dir = RNG(0, 359) * M_PI/180.;

View File

@ -1,4 +1,4 @@
#pragma one #pragma once
void menu_small(void); void menu_small(void);

View File

@ -32,10 +32,12 @@ static int nfleets = 0;
extern void ai_destroy(Pilot* p); // Ai. extern void ai_destroy(Pilot* p); // Ai.
extern void ai_think(Pilot* pilot); // Ai.c extern void ai_think(Pilot* pilot); // Ai.c
extern void player_think(Pilot* pilot); // Player.c extern void player_think(Pilot* pilot); // Player.c
extern void player_brokeHyperspace(void); // Player.c
extern int gui_load(const char* name); // Player.c extern int gui_load(const char* name); // Player.c
// Internal. // Internal.
static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t); static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t);
static void pilot_update(Pilot* pilot, const double dt); static void pilot_update(Pilot* pilot, const double dt);
static void pilot_hyperspace(Pilot* pilot);
void pilot_render(Pilot* pilot); void pilot_render(Pilot* pilot);
static void pilot_free(Pilot* p); static void pilot_free(Pilot* p);
static Fleet* fleet_parse(const xmlNodePtr parent); static Fleet* fleet_parse(const xmlNodePtr parent);
@ -107,6 +109,23 @@ Pilot* pilot_get(const unsigned int id) {
return NULL; return NULL;
} }
// Attempt to turn the pilot to face dir.
double pilot_face(Pilot* p, const float dir) {
double diff, turn;
diff = angle_diff(p->solid->dir, dir);
turn = -10.*diff;
if(turn > 1.) turn = 1.;
else if(turn < -1.) turn = -1.;
p->solid->dir_vel = 0.;
if(turn)
p->solid->dir_vel -= p->ship->turn * turn;
return diff;
}
// Mkay, this is how we shoot. Listen up. // Mkay, this is how we shoot. Listen up.
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) { void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) {
int i; int i;
@ -230,10 +249,41 @@ static void pilot_update(Pilot* pilot, const double dt) {
// Update the solid. // Update the solid.
(*pilot->solid->update)(pilot->solid, dt); (*pilot->solid->update)(pilot->solid, dt);
if(VMOD(pilot->solid->vel) > pilot->ship->speed) { if(!pilot_isFlag(pilot, PILOT_HYPERSPACE) && VMOD(pilot->solid->vel) >
pilot->ship->speed)
// Should not go faster. // Should not go faster.
vect_pset(&pilot->solid->vel, pilot->ship->speed, VANGLE(pilot->solid->vel)); vect_pset(&pilot->solid->vel, pilot->ship->speed, VANGLE(pilot->solid->vel));
} }
// Pilot is getting ready or is in, hyperspace.
static void pilot_hyperspace(Pilot* p) {
if(pilot_isFlag(p, PILOT_HYPERSPACE)) {
// Pilot is actually in hyperspace.
if(SDL_GetTicks() > p->ptimer) {
if(p == player) {
player_brokeHyperspace();
} else
pilot_setFlag(p, PILOT_DELETE); // Set flag to delete pilot.
return;
}
vect_pset(&p->solid->force, p->ship->thrust * 3., p->solid->dir);
}
else if(pilot_isFlag(p, PILOT_HYP_BEGIN)) {
if(SDL_GetTicks() > p->ptimer) {
// Engines are ready.
p->ptimer = SDL_GetTicks() + HYPERSPACE_FLY_DELAY;
pilot_setFlag(p, PILOT_HYPERSPACE);
}
} else {
double diff = pilot_face(p, VANGLE(player->solid->pos));
if(diff < MAX_DIR_ERR) {
// We can now prepare the jump.
p->solid->dir_vel = 0.;
p->ptimer = SDL_GetTicks() + HYPERSPACE_ENGINE_DELAY;
pilot_setFlag(p, PILOT_HYP_BEGIN);
}
}
} }
// ==Init pilot.=========================================== // ==Init pilot.===========================================
@ -296,7 +346,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction, AI_Profi
if(flags & PILOT_PLAYER) { if(flags & PILOT_PLAYER) {
pilot->think = player_think; // Players don't need to thing! :P pilot->think = player_think; // Players don't need to thing! :P
pilot->render = NULL; pilot->render = NULL; // Render will be called from player_think
pilot_setFlag(pilot, PILOT_PLAYER); // It's a player! pilot_setFlag(pilot, PILOT_PLAYER); // It's a player!
player = pilot; player = pilot;
gui_load(pilot->ship->gui); // Load the GUI. gui_load(pilot->ship->gui); // Load the GUI.
@ -382,12 +432,19 @@ void pilots_clean(void) {
void pilots_update(double dt) { void pilots_update(double dt) {
int i; int i;
for(i = 0; i < pilots; i++) { for(i = 0; i < pilots; i++) {
if(pilot_stack[i]->think && !pilot_isDisabled(pilot_stack[i])) if(pilot_stack[i]->think && !pilot_isDisabled(pilot_stack[i])) {
// Hyperspace gets special treatment.
if(pilot_isFlag(pilot_stack[i], PILOT_HYP_PREP))
pilot_hyperspace(pilot_stack[i]);
else
pilot_stack[i]->think(pilot_stack[i]); pilot_stack[i]->think(pilot_stack[i]);
if(pilot_stack[i]->update) }
if(pilot_stack[i]->update) {
if(pilot_isFlag(pilot_stack[i], PILOT_DELETE))
pilot_destroy(pilot_stack[i]);
else
pilot_stack[i]->update(pilot_stack[i], dt); pilot_stack[i]->update(pilot_stack[i], dt);
if(pilot_stack[i]->render) }
pilot_stack[i]->render(pilot_stack[i]);
} }
} }

View File

@ -8,6 +8,9 @@
#define PLAYER_ID 1 #define PLAYER_ID 1
#define HYPERSPACE_FLY_DELAY 5000
#define HYPERSPACE_ENGINE_DELAY 3000
// Aproximation for pilot size. // Aproximation for pilot size.
#define PILOT_SIZE_APROX 0.8 #define PILOT_SIZE_APROX 0.8
#define PILOT_DISABLED_ARMOUR 0.2 // Based on armour percentage. #define PILOT_DISABLED_ARMOUR 0.2 // Based on armour percentage.
@ -21,8 +24,12 @@
// Dynamic. // Dynamic.
#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player. #define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player.
#define PILOT_COMBAT (1<<2) // Pilot is engaged in combat. #define PILOT_COMBAT (1<<2) // Pilot is engaged in combat.
#define PILOT_HYPERSPACE (1<<3) // Pilot is in hyperspace. #define PILOT_HYP_PREP (1<<5) // Pilot is getting ready for hyperspace.
#define PILOT_DISABLED (1<<4) // Pilot is disabled. #define PILOT_HYP_BEGIN (1<<6) // Pilot is starting engines.
#define PILOT_HYPERSPACE (1<<7) // Pilot is in hyperspace.
#define PILOT_DISABLED (1<<9) // Pilot is disabled.
#define PILOT_DELETE (1<<10) // Pilot will get delete asap.
// Just makes life simpler. // Just makes life simpler.
#define pilot_isPlayer(p) ((p)->flags & PILOT_PLAYER) #define pilot_isPlayer(p) ((p)->flags & PILOT_PLAYER)
#define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED) #define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED)
@ -60,6 +67,7 @@ typedef struct Pilot {
PilotOutfit* ammo; // Secondary ammo (if needed). PilotOutfit* ammo; // Secondary ammo (if needed).
unsigned int flags; // Used for AI etc. unsigned int flags; // Used for AI etc.
unsigned int ptimer; // Generic timer for internal pilot use.
// AI. // AI.
AI_Profile* ai; // Ai personality profile. AI_Profile* ai; // Ai personality profile.
@ -97,6 +105,7 @@ Fleet* fleet_get(const char* name);
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary); void pilot_shoot(Pilot* p, const unsigned int target, const int secondary);
void pilot_hit(Pilot* p, const double damage_shield, const double damage_armour); void pilot_hit(Pilot* p, const double damage_shield, const double damage_armour);
void pilot_setAmmo(Pilot* p); void pilot_setAmmo(Pilot* p);
double pilot_face(Pilot* p, const float dir);
// Creation. // Creation.
void pilot_init(Pilot* dest, Ship* ship, char* name, Faction* faction, AI_Profile* ai, void pilot_init(Pilot* dest, Ship* ship, char* name, Faction* faction, AI_Profile* ai,

View File

@ -35,12 +35,16 @@ unsigned int player_flags = 0; // Player flags.
double player_turn = 0.; // Turn velocity from input. double player_turn = 0.; // Turn velocity from input.
double player_acc = 0.; // Accel velocity from input. double player_acc = 0.; // Accel velocity from input.
unsigned int player_target = PLAYER_ID; // Targetted pilot. unsigned int player_target = PLAYER_ID; // Targetted pilot.
int planet_target = -1; // Targetted planet. static int planet_target = -1; // Targetted planet.
static int hyperspace_target = -1; // Target hyperspace route.
// Pilot stuff for GUI. // Pilot stuff for GUI.
extern Pilot** pilot_stack; extern Pilot** pilot_stack;
extern int pilots; extern int pilots;
// Space stuff for GUI.
extern StarSystem* systems;
// GUI crap. // GUI crap.
typedef struct { typedef struct {
double x,y; // Position. double x,y; // Position.
@ -196,10 +200,15 @@ void player_message(const char* fmt, ...) {
msg_stack[0].t = SDL_GetTicks() + msg_timeout; msg_stack[0].t = SDL_GetTicks() + msg_timeout;
} }
void player_warp(const double x, const double y) {
vect_cset(&player->solid->pos, x, y);
}
// Clear the targets. // Clear the targets.
void player_clear(void) { void player_clear(void) {
player_target = PLAYER_ID; player_target = PLAYER_ID;
planet_target = -1; planet_target = -1;
hyperspace_target = -1;
} }
// Render the background player stuff, namely planet target // Render the background player stuff, namely planet target
@ -320,8 +329,17 @@ void player_render(void) {
gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x, gui.nav.y - 10 - gl_smallFont.h, gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x, gui.nav.y - 10 - gl_smallFont.h,
NULL, "%s", cur_system->planets[planet_target].name); NULL, "%s", cur_system->planets[planet_target].name);
} }
else if(planet_target == -1) { else if(hyperspace_target >= 0) {
// No planet target. // Hyperspace target.
c = space_canHyperspace(player) ? &cConsole : NULL;
gl_printMid(NULL, (int)gui.nav.w, gui.nav.x, gui.nav.y - 5,
c, "Hyperspace");
gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x, gui.nav.y - 10 - gl_smallFont.h,
NULL, "%s", systems[cur_system->jumps[hyperspace_target]].name);
}
else {
// No NAV target.
gl_printMid(NULL, (int)gui.nav.w, gui.nav.x, gl_printMid(NULL, (int)gui.nav.w, gui.nav.x,
gui.nav.y - 5, &cConsole, "Navigation"); gui.nav.y - 5, &cConsole, "Navigation");
gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x, gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x,
@ -744,23 +762,21 @@ void gui_free(void) {
// Used in pilot.c // Used in pilot.c
// Basically uses keyboard input instead of AI input. // Basically uses keyboard input instead of AI input.
void player_think(Pilot* player) { void player_think(Pilot* player) {
double diff; // PLAYER_FACE will take over navigation.
if(player_isFlag(PLAYER_FACE) && (player_target != PLAYER_ID)) { if(player_isFlag(PLAYER_FACE) && (player_target != PLAYER_ID))
diff = angle_diff(player->solid->dir, pilot_face(player,
vect_angle(&player->solid->pos, &pilot_get(player_target)->solid->pos)); vect_angle(&player->solid->pos, &pilot_get(player_target)->solid->pos));
player_turn = -10.*diff;
if(player_turn > 1.) player_turn = 1.; // PLAYER_REVERSE will take over navigation.
else if(player_turn < -1.) player_turn = -1.; else if(player_isFlag(PLAYER_REVERSE) && (VMOD(player->solid->vel) > 0.))
} pilot_face(player, VANGLE(player->solid->vel) + M_PI);
else if(player_isFlag(PLAYER_REVERSE) && (VMOD(player->solid->vel) > 0.)) {
diff = angle_diff(player->solid->dir, VANGLE(player->solid->vel)); // Normal navigation sheme.
player_turn = 10.*diff; else {
if(player_turn >= 0.) player_turn = 1.;
else if(player_turn < 0.) player_turn = -1;
}
player->solid->dir_vel = 0.; player->solid->dir_vel = 0.;
if(player_turn) if(player_turn)
player->solid->dir_vel -= player->ship->turn * player_turn; player->solid->dir_vel -= player->ship->turn * player_turn;
}
if(player_isFlag(PLAYER_PRIMARY)) pilot_shoot(player, 0, 0); if(player_isFlag(PLAYER_PRIMARY)) pilot_shoot(player, 0, 0);
if(player_isFlag(PLAYER_SECONDARY)) // Needs a target. if(player_isFlag(PLAYER_SECONDARY)) // Needs a target.
@ -801,7 +817,7 @@ void player_board(void) {
if((pow2(VX(player->solid->vel)-VX(p->solid->vel)) + if((pow2(VX(player->solid->vel)-VX(p->solid->vel)) +
pow2(VY(player->solid->vel)-VY(p->solid->vel))) > (double)pow2(MAX_HYPERSPACE_VEL)) { pow2(VY(player->solid->vel)-VY(p->solid->vel))) > (double)pow2(MAX_HYPERSPACE_VEL)) {
player_message("You are going too fact to board the ship"); player_message("You are going too fast to board the ship");
return; return;
} }
player_message("Boarding ship %s", p->name); player_message("Boarding ship %s", p->name);
@ -844,6 +860,8 @@ void player_secondaryNext(void) {
// Cycle through planet targets. // Cycle through planet targets.
void player_targetPlanet(void) { void player_targetPlanet(void) {
hyperspace_target = -1;
if((planet_target == -1) && (cur_system->nplanets > 0)) { if((planet_target == -1) && (cur_system->nplanets > 0)) {
// No target. // No target.
planet_target = 0; planet_target = 0;
@ -894,6 +912,41 @@ void player_land(void) {
} }
} }
void player_targetHyperspace(void) {
planet_target = -1; // Remove planet target.
hyperspace_target++;
if(hyperspace_target >= cur_system->njumps)
hyperspace_target = -1;
}
// Actually attempt to jump into hyperspace.
void player_jump(void) {
if(hyperspace_target == -1) return;
int i = space_hyperspace(player);
if(i == -1)
player_message("You are too close to gravity centers to initiate hyperspace.");
else if(i == -2)
player_message("You are moving too fast to enter hyperspace.");
else
player_message("Preparing for hyperspace");
}
// Player actually broke hyperspace (Let's enter a new system).
void player_brokeHyperspace(void) {
// Enter the new system.
space_init(systems[cur_system->jumps[hyperspace_target]].name);
// Set position, pilot_update will handle the lowering of velocity.
player_warp(-cos(player->solid->dir) * MIN_HYPERSPACE_DIST * 1.2,
-sin(player->solid->dir) * MIN_HYPERSPACE_DIST * 1.2);
// Stop hyperspace.
pilot_rmFlag(player, PILOT_HYPERSPACE | PILOT_HYP_BEGIN | PILOT_HYP_PREP);
}
// Take a screenshot. // Take a screenshot.
void player_screenshot(void) { void player_screenshot(void) {
char filename[20]; char filename[20];

View File

@ -4,7 +4,7 @@
// Flag definitions. // Flag definitions.
#define PLAYER_TURN_LEFT (1<<0) // Player is turning left. #define PLAYER_TURN_LEFT (1<<0) // Player is turning left.
#define PLAYER_TURN_RIGHT (1<<1) // Player is turning right. #define PLAYER_TURN_RIGHT (1<<1) // Player is turning right.
#define PLAYER_REVERSE (1<<2) #define PLAYER_REVERSE (1<<2) // Player is facint opposite vel.
#define PLAYER_FACE (1<<10) // Player is facing target. #define PLAYER_FACE (1<<10) // Player is facing target.
#define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon. #define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon.
#define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon. #define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon.
@ -33,6 +33,7 @@ void player_renderBG(void); // Render BG layer.
// Misc. // Misc.
void player_message(const char* fmt, ...); void player_message(const char* fmt, ...);
void player_clear(void); void player_clear(void);
void player_warp(const double x, const double y);
// Keybind actions. // Keybind actions.
void player_setRadarRel(int mod); void player_setRadarRel(int mod);
@ -40,5 +41,7 @@ void player_board(void);
void player_secondaryNext(void); void player_secondaryNext(void);
void player_targetPlanet(void); void player_targetPlanet(void);
void player_land(void); void player_land(void);
void player_targetHyperspace(void);
void player_jump(void);
void player_screenshot(void); void player_screenshot(void);

View File

@ -35,7 +35,7 @@
#define FLAG_ASTEROIDSSET (1<<2) #define FLAG_ASTEROIDSSET (1<<2)
#define FLAG_INTEFERENCESET (1<<3) #define FLAG_INTEFERENCESET (1<<3)
static StarSystem* systems = NULL; StarSystem* systems = NULL;
static int nsystems = 0; static int nsystems = 0;
StarSystem* cur_system = NULL; // Current star system. StarSystem* cur_system = NULL; // Current star system.
@ -56,6 +56,7 @@ static int mstars = 0;
// Intern // Intern
static Planet* planet_get(const char* name); static Planet* planet_get(const char* name);
static StarSystem* system_parse(const xmlNodePtr parent); static StarSystem* system_parse(const xmlNodePtr parent);
static void system_parseJumps(const xmlNodePtr parent);
static PlanetClass planetclass_get(const char a); static PlanetClass planetclass_get(const char a);
// Extern. // Extern.
extern void player_message(const char* fmt, ...); extern void player_message(const char* fmt, ...);
@ -151,24 +152,26 @@ static PlanetClass planetclass_get(const char a) {
}; };
} }
// Hyperspaces, return 0 if entering hyperspace, or distance otherwise. // Check distance to ensure we can go into hyperspace.
int space_hyperspace(Pilot* p) { int space_canHyperspace(Pilot* p) {
int i; int i;
double d; double d;
for(i = 0; i < cur_system->nplanets; i++) { for(i = 0; i < cur_system->nplanets; i++) {
d = vect_dist(&p->solid->pos, &cur_system->planets[i].pos); d = vect_dist(&p->solid->pos, &cur_system->planets[i].pos);
if(d < MIN_HYPERSPACE_DIST) if(d < MIN_HYPERSPACE_DIST)
return (int)(MIN_HYPERSPACE_DIST - d); return 0;
} }
return 1;
}
// Hyperspace, returns 0 if entering hyperspace, or the distance if not.
int space_hyperspace(Pilot* p) {
if(!space_canHyperspace(p)) return -1;
// Too fast. // Too fast.
if(VMOD(p->solid->vel) > MAX_HYPERSPACE_VEL) return -1; if(VMOD(p->solid->vel) > MAX_HYPERSPACE_VEL) return -2;
// TODO: All hyperspace worky work. // Pilot is now going to get automatically ready for hyperspace.
if(p == player) { pilot_setFlag(p, PILOT_HYP_PREP);
// Player crap.
} else {
}
return 0; return 0;
} }
@ -432,7 +435,47 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
return tmp; return tmp;
} }
// Load the jumps into a system.
static void system_parseJumps(const xmlNodePtr parent) {
int i;
StarSystem* system;
char* name;
xmlNodePtr cur, node;
name = xml_nodeProp(parent, "name"); // Already mallocs.
for(i = 0; i < nsystems; i++)
if(strcmp(systems[i].name, name)==0) {
system = &systems[i];
break;
}
if(i == nsystems) WARN("System '%s' was not found in the stack for some reason", name);
free(name); // No need for it now.
node = parent->xmlChildrenNode;
do {
// Load the data.
if(xml_isNode(node, "jumps")) {
cur = node->children;
do {
if(xml_isNode(cur, "jump")) {
for(i = 0; i < nsystems; i++)
if(strcmp(systems[i].name, xml_get(cur))==0) {
system->njumps++;
system->jumps = realloc(system->jumps, system->njumps*sizeof(int));
system->jumps[system->njumps-1] = i;
break;
}
if(i == nsystems)
WARN("System '%s' not found for jump linking", xml_get(cur));
}
} while((cur = cur->next));
}
} while((node = node->next));
}
// Load the ENTIRE universe into RAM. -- WOAH! -- Wasn't that bad. :P // Load the ENTIRE universe into RAM. -- WOAH! -- Wasn't that bad. :P
// -- Used a two system pass to first load the star systems and then set jump routes.
int space_load(void) { int space_load(void) {
uint32_t bufsize; uint32_t bufsize;
char* buf = pack_readfile(DATA, SYSTEM_DATA, &bufsize); char* buf = pack_readfile(DATA, SYSTEM_DATA, &bufsize);
@ -452,6 +495,7 @@ int space_load(void) {
ERR("Malformed "SYSTEM_DATA" file: does not contain elements"); ERR("Malformed "SYSTEM_DATA" file: does not contain elements");
return -1; return -1;
} }
// Fist pass - Load all the star systems.
do { do {
if(xml_isNode(node, XML_SYSTEM_TAG)) { if(xml_isNode(node, XML_SYSTEM_TAG)) {
tmp = system_parse(node); tmp = system_parse(node);
@ -461,6 +505,14 @@ int space_load(void) {
} }
} while((node = node->next)); } while((node = node->next));
// Second pass - Load all the jump routes.
node = doc->xmlChildrenNode->xmlChildrenNode;
do {
if(xml_isNode(node, XML_SYSTEM_TAG))
system_parseJumps(node); // Automatically load the jumps into the system.
} while((node = node->next));
// Cleanup.
xmlFreeDoc(doc); xmlFreeDoc(doc);
free(buf); free(buf);
xmlCleanupParser(); xmlCleanupParser();
@ -506,10 +558,17 @@ void space_exit(void) {
free(systems[i].name); free(systems[i].name);
if(systems[i].fleets) if(systems[i].fleets)
free(systems[i].fleets); free(systems[i].fleets);
if(systems[i].jumps)
free(systems[i].jumps);
for(j = 0; j < systems[i].nplanets; j++) { for(j = 0; j < systems[i].nplanets; j++) {
free(systems[i].planets[j].name); free(systems[i].planets[j].name);
if(systems[i].planets[j].description) if(systems[i].planets[j].description)
free(systems[i].planets[j].description); free(systems[i].planets[j].description);
if(systems[i].planets[j].bar_description)
free(systems[i].planets[j].bar_description);
// Graphics.
if(systems[i].planets[j].gfx_space) if(systems[i].planets[j].gfx_space)
gl_freeTexture(systems[i].planets[j].gfx_space); gl_freeTexture(systems[i].planets[j].gfx_space);
if(systems[i].planets[j].gfx_exterior) if(systems[i].planets[j].gfx_exterior)

View File

@ -4,7 +4,7 @@
#include "pilot.h" #include "pilot.h"
#define MIN_HYPERSPACE_DIST 1500 #define MIN_HYPERSPACE_DIST 1500
#define MAX_HYPERSPACE_VEL 15 #define MAX_HYPERSPACE_VEL 25
// Planet types. I didn't take them from Star Trek, I promise. // Planet types. I didn't take them from Star Trek, I promise.
typedef enum { typedef enum {
@ -72,6 +72,9 @@ typedef struct {
SystemFleet* fleets; // Fleets that can appear in the current system. SystemFleet* fleets; // Fleets that can appear in the current system.
int nfleets; // Total number of fleets. int nfleets; // Total number of fleets.
int* jumps; // Adjacent star system index number.
int njumps; // Number of adjacent jumps.
} StarSystem; } StarSystem;
extern StarSystem* cur_system; // Current star system. extern StarSystem* cur_system; // Current star system.
@ -86,6 +89,7 @@ void space_render(double dt);
void planets_render(void); void planets_render(void);
// Misc. // Misc.
int space_canHyperspace(Pilot* p);
int space_hyperspace(Pilot* p); int space_hyperspace(Pilot* p);
extern char* stardate; extern char* stardate;

View File

@ -7,7 +7,8 @@ typedef enum {
WIDGET_NULL, WIDGET_NULL,
WIDGET_BUTTON, WIDGET_BUTTON,
WIDGET_TEXT, WIDGET_TEXT,
WIDGET_IMAGE WIDGET_IMAGE,
WIDGET_LIST
} WidgetType; } WidgetType;
typedef enum { typedef enum {
@ -33,7 +34,7 @@ typedef struct {
}; };
// Widget text. // Widget text.
struct { struct {
char* text; char* text; // Use printMid for centered printText if not.
glFont* font; glFont* font;
glColour* colour; glColour* colour;
int centered; int centered;
@ -42,6 +43,12 @@ typedef struct {
// Widget image. // Widget image.
glTexture* image; glTexture* image;
}; };
struct {
// Widget list.
char** options; // Pointer to the options.
int noptions; // total number of options.
int selected; // Currently selected option.
};
}; };
} Widget; } Widget;
@ -139,6 +146,26 @@ void window_addImage(const unsigned int wid, const int x, const int y,
else wgt->y = (double)y; else wgt->y = (double)y;
} }
void window_addList(const unsigned int wid, const int x, const int y,
const int w, const int h, char* name, char** items, int nitems, int defitem) {
Window *wdw = window_wget(wid);
Widget* wgt = window_newWidget(wdw);
wgt->type = WIDGET_LIST;
wgt->name = strdup(name);
wgt->options = items;
wgt->noptions = nitems;
wgt->selected = defitem; // -1 would be none.
wgt->w = (double) w;
wgt->h = (double) h;
if(x < 0) wgt->x = wdw->w - wgt->w + x;
else wgt->x = (double) x;
if(y < 0) wgt->y = wdw->h - wgt->h + y;
else wgt->y = (double) y;
}
// Return pointer to newly allocated widget. // Return pointer to newly allocated widget.
static Widget* window_newWidget(Window* w) { static Widget* window_newWidget(Window* w) {
Widget* wgt = NULL; Widget* wgt = NULL;
@ -458,6 +485,9 @@ static void window_render(Window* w) {
case WIDGET_IMAGE: case WIDGET_IMAGE:
toolkit_renderImage(&w->widgets[i], x, y); toolkit_renderImage(&w->widgets[i], x, y);
break; break;
case WIDGET_LIST:
// TODO widget list rendering.
break;
} }
} }
} }