[Add] Rudementory Hyperspace travel. Still a work in progress. ;)
This commit is contained in:
parent
a417d59492
commit
44c6ea6ed6
@ -21,8 +21,8 @@
|
||||
</planet>
|
||||
<planet name="SaraCraft">
|
||||
<pos>
|
||||
<x>125</x>
|
||||
<y>-345</y>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
</pos>
|
||||
<general>
|
||||
<class>A</class>
|
||||
|
@ -12,7 +12,6 @@
|
||||
</general>
|
||||
<planets>
|
||||
<planet>KonoSphere</planet>
|
||||
<planet>SaraCraft</planet>
|
||||
</planets>
|
||||
<fleets>
|
||||
<fleet chance="100">Enemy Test</fleet>
|
||||
@ -23,6 +22,9 @@
|
||||
<fleet chance="50">Sml Merchant Convoy</fleet>
|
||||
<fleet chance="40">Sml Merchant Convoy</fleet>
|
||||
</fleets>
|
||||
<jumps>
|
||||
<jump>KonoSys</jump>
|
||||
</jumps>
|
||||
</ssys>
|
||||
<ssys name="KonoSys">
|
||||
<pos>
|
||||
@ -41,5 +43,9 @@
|
||||
<fleet chance="80">Merchant Ship</fleet>
|
||||
<fleet chance="60">Merchant Ship</fleet>
|
||||
</fleets>
|
||||
<jumps>
|
||||
<jump>SaraSys</jump>
|
||||
</jumps>
|
||||
</ssys>
|
||||
</Systems>
|
||||
|
||||
|
4
src/ai.c
4
src/ai.c
@ -58,10 +58,6 @@
|
||||
// Don't run the function if (n) params aren't passed.
|
||||
#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.
|
||||
#define ai_setFlag(f) (pilot_flags |= f)
|
||||
#define ai_isFlag(f) (pilot_flags & f)
|
||||
|
5
src/ai.h
5
src/ai.h
@ -1,6 +1,11 @@
|
||||
#pragma once
|
||||
#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.
|
||||
#define MAX_AI_TIMERS 2
|
||||
|
||||
|
23
src/input.c
23
src/input.c
@ -24,14 +24,13 @@ static Keybind** input_keybinds; // Contains the players keybindings.
|
||||
const char* keybindNames[] = { "accel", "left", "right", "reverse", // Movement.
|
||||
"primary", "target", "target_nearest", "face", "board", // Combat.
|
||||
"secondary", "secondary_next", // Secondary weapons.
|
||||
"target_planet", "land", // Navigation.
|
||||
"target_planet", "land", "thyperspace", "jump", // Navigation.
|
||||
"mapzoomin", "mapzoomout", "screenshot", "pause", "menu", // Misc.
|
||||
"end" }; // Must terminate at the end.
|
||||
// From player.c
|
||||
extern double player_turn;
|
||||
extern double player_acc;
|
||||
extern unsigned int player_target;
|
||||
extern int planet_target;
|
||||
// Grabbed from main.c
|
||||
extern int show_fps;
|
||||
|
||||
@ -56,6 +55,9 @@ void input_setDefault(void) {
|
||||
// Space
|
||||
input_setKeybind("target_planet", KEYBIND_KEYBOARD, SDLK_p, 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.
|
||||
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_UP, 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) {
|
||||
if(value == KEY_PRESS) player_board();
|
||||
}
|
||||
// Selecting secondary weapon.
|
||||
// Shooting secondary weapon.
|
||||
else if(KEY("secondary") && !paused) {
|
||||
if(value == KEY_PRESS) player_setFlag(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) {
|
||||
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.
|
||||
// Target planet (cycles just like target).
|
||||
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) {
|
||||
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.
|
||||
else if(KEY("mapzoomin")) {
|
||||
if(value == KEY_PRESS) player_setRadarRel(1);
|
||||
|
@ -144,8 +144,7 @@ void takeoff(void) {
|
||||
sh = planet->gfx_space->h;
|
||||
|
||||
// Set player to another position with random facing direction and no velocity.
|
||||
vect_cset(&player->solid->pos,
|
||||
planet->pos.x + RNG(-sw/2, sw/2), planet->pos.y + RNG(-sh/2, sh/2));
|
||||
player_warp(planet->pos.x + RNG(-sw/2, sw/2), planet->pos.y + RNG(-sh/2, sh/2));
|
||||
vect_pset(&player->solid->vel, 0., 0.);
|
||||
player->solid->dir = RNG(0, 359) * M_PI/180.;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#pragma one
|
||||
#pragma once
|
||||
|
||||
void menu_small(void);
|
||||
|
||||
|
69
src/pilot.c
69
src/pilot.c
@ -32,10 +32,12 @@ static int nfleets = 0;
|
||||
extern void ai_destroy(Pilot* p); // Ai.
|
||||
extern void ai_think(Pilot* pilot); // Ai.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
|
||||
// Internal.
|
||||
static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t);
|
||||
static void pilot_update(Pilot* pilot, const double dt);
|
||||
static void pilot_hyperspace(Pilot* pilot);
|
||||
void pilot_render(Pilot* pilot);
|
||||
static void pilot_free(Pilot* p);
|
||||
static Fleet* fleet_parse(const xmlNodePtr parent);
|
||||
@ -107,6 +109,23 @@ Pilot* pilot_get(const unsigned int id) {
|
||||
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.
|
||||
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) {
|
||||
int i;
|
||||
@ -230,9 +249,40 @@ static void pilot_update(Pilot* pilot, const double dt) {
|
||||
// Update the solid.
|
||||
(*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.
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,7 +346,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction, AI_Profi
|
||||
|
||||
if(flags & PILOT_PLAYER) {
|
||||
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!
|
||||
player = pilot;
|
||||
gui_load(pilot->ship->gui); // Load the GUI.
|
||||
@ -382,12 +432,19 @@ void pilots_clean(void) {
|
||||
void pilots_update(double dt) {
|
||||
int 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]);
|
||||
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);
|
||||
if(pilot_stack[i]->render)
|
||||
pilot_stack[i]->render(pilot_stack[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
13
src/pilot.h
13
src/pilot.h
@ -8,6 +8,9 @@
|
||||
|
||||
#define PLAYER_ID 1
|
||||
|
||||
#define HYPERSPACE_FLY_DELAY 5000
|
||||
#define HYPERSPACE_ENGINE_DELAY 3000
|
||||
|
||||
// Aproximation for pilot size.
|
||||
#define PILOT_SIZE_APROX 0.8
|
||||
#define PILOT_DISABLED_ARMOUR 0.2 // Based on armour percentage.
|
||||
@ -21,8 +24,12 @@
|
||||
// Dynamic.
|
||||
#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.
|
||||
#define PILOT_HYP_PREP (1<<5) // Pilot is getting ready for hyperspace.
|
||||
#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.
|
||||
#define pilot_isPlayer(p) ((p)->flags & PILOT_PLAYER)
|
||||
#define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED)
|
||||
@ -60,6 +67,7 @@ typedef struct Pilot {
|
||||
PilotOutfit* ammo; // Secondary ammo (if needed).
|
||||
|
||||
unsigned int flags; // Used for AI etc.
|
||||
unsigned int ptimer; // Generic timer for internal pilot use.
|
||||
|
||||
// AI.
|
||||
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_hit(Pilot* p, const double damage_shield, const double damage_armour);
|
||||
void pilot_setAmmo(Pilot* p);
|
||||
double pilot_face(Pilot* p, const float dir);
|
||||
|
||||
// Creation.
|
||||
void pilot_init(Pilot* dest, Ship* ship, char* name, Faction* faction, AI_Profile* ai,
|
||||
|
87
src/player.c
87
src/player.c
@ -35,12 +35,16 @@ unsigned int player_flags = 0; // Player flags.
|
||||
double player_turn = 0.; // Turn velocity from input.
|
||||
double player_acc = 0.; // Accel velocity from input.
|
||||
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.
|
||||
extern Pilot** pilot_stack;
|
||||
extern int pilots;
|
||||
|
||||
// Space stuff for GUI.
|
||||
extern StarSystem* systems;
|
||||
|
||||
// GUI crap.
|
||||
typedef struct {
|
||||
double x,y; // Position.
|
||||
@ -196,10 +200,15 @@ void player_message(const char* fmt, ...) {
|
||||
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.
|
||||
void player_clear(void) {
|
||||
player_target = PLAYER_ID;
|
||||
planet_target = -1;
|
||||
hyperspace_target = -1;
|
||||
}
|
||||
|
||||
// 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,
|
||||
NULL, "%s", cur_system->planets[planet_target].name);
|
||||
}
|
||||
else if(planet_target == -1) {
|
||||
// No planet target.
|
||||
else if(hyperspace_target >= 0) {
|
||||
// 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,
|
||||
gui.nav.y - 5, &cConsole, "Navigation");
|
||||
gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x,
|
||||
@ -744,23 +762,21 @@ void gui_free(void) {
|
||||
// Used in pilot.c
|
||||
// Basically uses keyboard input instead of AI input.
|
||||
void player_think(Pilot* player) {
|
||||
double diff;
|
||||
if(player_isFlag(PLAYER_FACE) && (player_target != PLAYER_ID)) {
|
||||
diff = angle_diff(player->solid->dir,
|
||||
// PLAYER_FACE will take over navigation.
|
||||
if(player_isFlag(PLAYER_FACE) && (player_target != PLAYER_ID))
|
||||
pilot_face(player,
|
||||
vect_angle(&player->solid->pos, &pilot_get(player_target)->solid->pos));
|
||||
player_turn = -10.*diff;
|
||||
if(player_turn > 1.) player_turn = 1.;
|
||||
else if(player_turn < -1.) player_turn = -1.;
|
||||
}
|
||||
else if(player_isFlag(PLAYER_REVERSE) && (VMOD(player->solid->vel) > 0.)) {
|
||||
diff = angle_diff(player->solid->dir, VANGLE(player->solid->vel));
|
||||
player_turn = 10.*diff;
|
||||
if(player_turn >= 0.) player_turn = 1.;
|
||||
else if(player_turn < 0.) player_turn = -1;
|
||||
}
|
||||
|
||||
// PLAYER_REVERSE will take over navigation.
|
||||
else if(player_isFlag(PLAYER_REVERSE) && (VMOD(player->solid->vel) > 0.))
|
||||
pilot_face(player, VANGLE(player->solid->vel) + M_PI);
|
||||
|
||||
// Normal navigation sheme.
|
||||
else {
|
||||
player->solid->dir_vel = 0.;
|
||||
if(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_SECONDARY)) // Needs a target.
|
||||
@ -801,7 +817,7 @@ void player_board(void) {
|
||||
if((pow2(VX(player->solid->vel)-VX(p->solid->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;
|
||||
}
|
||||
player_message("Boarding ship %s", p->name);
|
||||
@ -844,6 +860,8 @@ void player_secondaryNext(void) {
|
||||
|
||||
// Cycle through planet targets.
|
||||
void player_targetPlanet(void) {
|
||||
hyperspace_target = -1;
|
||||
|
||||
if((planet_target == -1) && (cur_system->nplanets > 0)) {
|
||||
// No target.
|
||||
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.
|
||||
void player_screenshot(void) {
|
||||
char filename[20];
|
||||
|
@ -4,7 +4,7 @@
|
||||
// Flag definitions.
|
||||
#define PLAYER_TURN_LEFT (1<<0) // Player is turning left.
|
||||
#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_PRIMARY (1<<11) // Player is shooting primary weapon.
|
||||
#define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon.
|
||||
@ -33,6 +33,7 @@ void player_renderBG(void); // Render BG layer.
|
||||
// Misc.
|
||||
void player_message(const char* fmt, ...);
|
||||
void player_clear(void);
|
||||
void player_warp(const double x, const double y);
|
||||
|
||||
// Keybind actions.
|
||||
void player_setRadarRel(int mod);
|
||||
@ -40,5 +41,7 @@ void player_board(void);
|
||||
void player_secondaryNext(void);
|
||||
void player_targetPlanet(void);
|
||||
void player_land(void);
|
||||
void player_targetHyperspace(void);
|
||||
void player_jump(void);
|
||||
void player_screenshot(void);
|
||||
|
||||
|
81
src/space.c
81
src/space.c
@ -35,7 +35,7 @@
|
||||
#define FLAG_ASTEROIDSSET (1<<2)
|
||||
#define FLAG_INTEFERENCESET (1<<3)
|
||||
|
||||
static StarSystem* systems = NULL;
|
||||
StarSystem* systems = NULL;
|
||||
static int nsystems = 0;
|
||||
StarSystem* cur_system = NULL; // Current star system.
|
||||
|
||||
@ -56,6 +56,7 @@ static int mstars = 0;
|
||||
// Intern
|
||||
static Planet* planet_get(const char* name);
|
||||
static StarSystem* system_parse(const xmlNodePtr parent);
|
||||
static void system_parseJumps(const xmlNodePtr parent);
|
||||
static PlanetClass planetclass_get(const char a);
|
||||
// Extern.
|
||||
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.
|
||||
int space_hyperspace(Pilot* p) {
|
||||
// Check distance to ensure we can go into hyperspace.
|
||||
int space_canHyperspace(Pilot* p) {
|
||||
int i;
|
||||
double d;
|
||||
for(i = 0; i < cur_system->nplanets; i++) {
|
||||
d = vect_dist(&p->solid->pos, &cur_system->planets[i].pos);
|
||||
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.
|
||||
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.
|
||||
if(p == player) {
|
||||
// Player crap.
|
||||
} else {
|
||||
|
||||
}
|
||||
// Pilot is now going to get automatically ready for hyperspace.
|
||||
pilot_setFlag(p, PILOT_HYP_PREP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -432,7 +435,47 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
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
|
||||
// -- Used a two system pass to first load the star systems and then set jump routes.
|
||||
int space_load(void) {
|
||||
uint32_t 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");
|
||||
return -1;
|
||||
}
|
||||
// Fist pass - Load all the star systems.
|
||||
do {
|
||||
if(xml_isNode(node, XML_SYSTEM_TAG)) {
|
||||
tmp = system_parse(node);
|
||||
@ -461,6 +505,14 @@ int space_load(void) {
|
||||
}
|
||||
} 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);
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
@ -506,10 +558,17 @@ void space_exit(void) {
|
||||
free(systems[i].name);
|
||||
if(systems[i].fleets)
|
||||
free(systems[i].fleets);
|
||||
if(systems[i].jumps)
|
||||
free(systems[i].jumps);
|
||||
|
||||
for(j = 0; j < systems[i].nplanets; j++) {
|
||||
free(systems[i].planets[j].name);
|
||||
if(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)
|
||||
gl_freeTexture(systems[i].planets[j].gfx_space);
|
||||
if(systems[i].planets[j].gfx_exterior)
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "pilot.h"
|
||||
|
||||
#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.
|
||||
typedef enum {
|
||||
@ -72,6 +72,9 @@ typedef struct {
|
||||
|
||||
SystemFleet* fleets; // Fleets that can appear in the current system.
|
||||
int nfleets; // Total number of fleets.
|
||||
|
||||
int* jumps; // Adjacent star system index number.
|
||||
int njumps; // Number of adjacent jumps.
|
||||
} StarSystem;
|
||||
|
||||
extern StarSystem* cur_system; // Current star system.
|
||||
@ -86,6 +89,7 @@ void space_render(double dt);
|
||||
void planets_render(void);
|
||||
|
||||
// Misc.
|
||||
int space_canHyperspace(Pilot* p);
|
||||
int space_hyperspace(Pilot* p);
|
||||
extern char* stardate;
|
||||
|
||||
|
@ -7,7 +7,8 @@ typedef enum {
|
||||
WIDGET_NULL,
|
||||
WIDGET_BUTTON,
|
||||
WIDGET_TEXT,
|
||||
WIDGET_IMAGE
|
||||
WIDGET_IMAGE,
|
||||
WIDGET_LIST
|
||||
} WidgetType;
|
||||
|
||||
typedef enum {
|
||||
@ -33,7 +34,7 @@ typedef struct {
|
||||
};
|
||||
// Widget text.
|
||||
struct {
|
||||
char* text;
|
||||
char* text; // Use printMid for centered printText if not.
|
||||
glFont* font;
|
||||
glColour* colour;
|
||||
int centered;
|
||||
@ -42,6 +43,12 @@ typedef struct {
|
||||
// Widget image.
|
||||
glTexture* image;
|
||||
};
|
||||
struct {
|
||||
// Widget list.
|
||||
char** options; // Pointer to the options.
|
||||
int noptions; // total number of options.
|
||||
int selected; // Currently selected option.
|
||||
};
|
||||
};
|
||||
} Widget;
|
||||
|
||||
@ -139,6 +146,26 @@ void window_addImage(const unsigned int wid, const int x, const int 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.
|
||||
static Widget* window_newWidget(Window* w) {
|
||||
Widget* wgt = NULL;
|
||||
@ -458,6 +485,9 @@ static void window_render(Window* w) {
|
||||
case WIDGET_IMAGE:
|
||||
toolkit_renderImage(&w->widgets[i], x, y);
|
||||
break;
|
||||
case WIDGET_LIST:
|
||||
// TODO widget list rendering.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user