From e3c2ca72acce1d1cce79e95a7dfb4bed919dbffd Mon Sep 17 00:00:00 2001 From: Allanis <allanis@saracraft.net> Date: Fri, 15 Feb 2013 18:15:06 +0000 Subject: [PATCH] [Add] Planet targeting/landing framework. [Change] Seperated update/render as it should be. --- gfx/gui/minimal_planet.png | Bin 326 -> 328 bytes src/main.c | 50 ++++++++++-------- src/pilot.c | 9 ++++ src/pilot.h | 1 + src/player.c | 104 ++++++++++++++++++++++++++++++++++--- src/space.h | 2 +- src/weapon.c | 33 ++++++++++-- src/weapon.h | 7 ++- 8 files changed, 170 insertions(+), 36 deletions(-) diff --git a/gfx/gui/minimal_planet.png b/gfx/gui/minimal_planet.png index e2b41d3768c7bbd20ef013b08eaa1b1bdc532441..9a6450a52619377917f5f4d6ddc52fe7ae335136 100644 GIT binary patch delta 295 zcmX@cbb@JuRy_j<{B+(8VsI9CL>4nJa0`PlBg3pY5<o%r5>H=O_Ujxh0%jb~Wgbie z3SISdaSVw#e0PR7UxNaV%iOp-6-6;GosM46U%aMg+1tZTGdJlxVLtAhoogG<bem^} zI$MnWnWi^}9mf_3y^}~XUDNP--N98Q{YP4^)dNM?B3M^;GOlm-*`b#pw&bY#B3ZZJ zPSYN1$e-YQFjv7SSmfjPiCg;?UDG!zOM3FmsbpsbZ<>a`ngjQet!1+qO()E|e4N!n zW%?ZV#Wl;+f5vvLH0Laxxlr%Q6?fUK5eue8Uul{e^(olg_e!pM>0`gzua32qCd_#v rK}JW@S`->4%q&=Cb)u@%&%Vqw@{i7`ma0!cFEV(#`njxgN@xNAJ&t)$ delta 293 zcmV+=0owk^0>%Q6Du4d~{{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G` z2i6J$5G@z)X`Y1u007fTL_t(o!`+xm4uBvGM4evTcye91&;*0@%P1?Op?wH#rz{Kk z!1cJVx7XVooR$IYhgp!%45FJ*33m>$POO0IoWZK?e)kFOgnvr72f!-GaUbv+$b{<v zW<lz0BHCcIEo2#vvVm*|-UT9ei~N5ddFLqR{30h3<AMwE>7wgSot}(<7D!v}bO34~ z?bXK#I0ES_jq;(M<ab+49VFCghB{GGmpW>(KrOeZ1uM1Wr*4|4+fM4no%-s7`toQ7 r+!&-}ip>ZCAs%z#RC$o|5}ke=Q(k^7p6=u}00000NkvXXu0mjfK)-=I diff --git a/src/main.c b/src/main.c index 7b2a732..99749d5 100644 --- a/src/main.c +++ b/src/main.c @@ -53,6 +53,7 @@ static void window_caption(void); static void data_name(void); // Update. static void update_all(void); +static void render_all(void); // Usage. static void print_usage(char** argv) { @@ -276,7 +277,7 @@ int main(int argc, char** argv) { time = SDL_GetTicks(); // Init the time. - // Main looops. + // Main loop. SDL_Event event; // flushes the event loop, since I notices that when the joystick is loaded, it // creates button events that results in the player starting out accelerating. @@ -288,6 +289,7 @@ int main(int argc, char** argv) { input_handle(&event); // handles all the events the player keybinds. } update_all(); + render_all(); } // Unload data. @@ -310,25 +312,12 @@ int main(int argc, char** argv) { exit(EXIT_SUCCESS); } -// == Update everything. ================================== -// Blitting order. (layers) -// -// BG | Stars and planets. -// | Background particles. -// | Back layer weapons. -// X -// N | NPC ships. -// | Normal layer particles (above ships). -// | Front layer weapons. -// X -// FG | Player. -// | Foreground particles. -// | Text and GUI. -// ======================================================== +// Updates everything. static double fps_dt = 1.; +static double dt = 0.; static void update_all(void) { // dt in ms/1000. - double dt = (double)(SDL_GetTicks() - time) / 1000.; + dt = (double)(SDL_GetTicks() - time) / 1000.; time = SDL_GetTicks(); // TODO: This could use some work. @@ -344,21 +333,38 @@ static void update_all(void) { SDL_Delay(delay); fps_dt += delay; // Make sure it displays the propper FPS. } + weapons_update(dt); + pilots_update(dt); +} +// == Renders everything. ================================== +// Blitting order. (layers) +// +// BG | Stars and planets. +// | Background particles. +// | Back layer weapons. +// X +// N | NPC ships. +// | Normal layer particles (above ships). +// | Front layer weapons. +// X +// FG | Player. +// | Foreground particles. +// | Text and GUI. +// ======================================================== +static void render_all(void) { glClear(GL_COLOR_BUFFER_BIT); -// -- // BG. space_render(dt); planets_render(); - weapons_update(dt, WEAPON_LAYER_BG); + weapons_render(WEAPON_LAYER_BG); // N. - pilots_update(dt); - weapons_update(dt, WEAPON_LAYER_FG); + pilots_render(); + weapons_render(WEAPON_LAYER_FG); // FG. player_render(); display_fps(dt); -// -- SDL_GL_SwapBuffers(); } diff --git a/src/pilot.c b/src/pilot.c index 15553ff..4ff118e 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -361,6 +361,15 @@ void pilots_update(double dt) { } } +// Render all the pilots. +void pilots_render(void) { + int i; + for(i = 1; i < pilots; i++) + // Skip the player. + if(pilot_stack[i]->render) + pilot_stack[i]->render(pilot_stack[i]); +} + // Return the fleet based on 'name' Fleet* fleet_get(const char* name) { int i; diff --git a/src/pilot.h b/src/pilot.h index dc3407d..2e75bf1 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -112,4 +112,5 @@ void fleet_free(void); // Update. void pilots_update(double dt); +void pilots_render(void); diff --git a/src/player.c b/src/player.c index bfa7d65..9f47c39 100644 --- a/src/player.c +++ b/src/player.c @@ -49,6 +49,7 @@ static Keybind** player_input; // Contains the players keybindings. const char* keybindNames[] = { "accel", "left", "right", // Movement. "primary", "target", "target_nearest", "face", "board", // Combat. "secondary", "secondary_next", // Secondary weapons. + "target_planet", "land", // Navigation. "mapzoomin", "mapzoomout", "screenshot", "end" }; // Misc. // Player stuff. @@ -149,6 +150,8 @@ static void gui_renderBar(const glColour* c, const Vec2* p, const Rect* r, const // Keybinds. static void player_board(void); static void player_secondaryNext(void); +static void player_targetPlanet(void); +static void player_land(void); static void player_screenshot(void); // Create a new player. @@ -248,6 +251,7 @@ void player_render(void) { int i, j; char str[10]; Pilot* p; + Planet* planet; Vec2 v; glColour* c; gl_font* f; @@ -270,7 +274,23 @@ void player_render(void) { VX(v) -= p->ship->gfx_space->sw * PILOT_SIZE_APROX; gl_blitSprite(gui.gfx_targetPilot, &v, 0, 1, c); // Bottom left. } + // Render the planet target graphics. + if(planet_target >= 0) { + planet = &cur_system->planets[planet_target]; + if(areEnemies(player->faction, planet->faction)) c = &cHostile; + else c = &cNeutral; + + vect_csetmin(&v, VX(planet->pos) - planet->gfx_space->sw/2., + VY(planet->pos) + planet->gfx_space->sh/2.); + gl_blitSprite(gui.gfx_targetPlanet, &v, 0, 0, c); // Top left. + VX(v) += planet->gfx_space->sw; + gl_blitSprite(gui.gfx_targetPlanet, &v, 1, 0, c); // Top right. + VY(v) -= planet->gfx_space->sh; + gl_blitSprite(gui.gfx_targetPlanet, &v, 1, 1, c); // Bottom right. + VX(v) -= planet->gfx_space->sw; + gl_blitSprite(gui.gfx_targetPlanet, &v, 0, 1, c); // Bottom left. + } // Render the player. pilot_render(player); @@ -325,15 +345,23 @@ void player_render(void) { glPopMatrix(); // GL_PROJECTION. // Nav. - if(planet_target != -1) { - - } else { - i = gl_printWidth(NULL, "NAV"); + if(planet_target >= 0) { + // Planet landing target. + i = gl_printWidth(NULL, "Land"); vect_csetmin(&v, VX(gui.pos_nav) + (gui.nav.w - i)/2., VY(gui.pos_nav) - 5); - gl_print(NULL, &v, &cConsole, "NAV"); - i = gl_printWidth(&gui.smallFont, "No Target"); + gl_print(NULL, &v, &cConsole, "Land"); + i = gl_printWidth(&gui.smallFont, "%s", cur_system->planets[planet_target].name); vect_csetmin(&v, VX(gui.pos_nav) + (gui.nav.w - i)/2., VY(gui.pos_nav) - 10 - gui.smallFont.h); - gl_print(&gui.smallFont, &v, &cGrey, "No Target"); + gl_print(&gui.smallFont, &v, NULL, "%s", cur_system->planets[planet_target].name); + } + else if(planet_target == -1) { + // No planet target. + i = gl_printWidth(NULL, "Navigation"); + vect_csetmin(&v, VX(gui.pos_nav) + (gui.nav.w - i)/2., VY(gui.pos_nav) - 5); + gl_print(NULL, &v, &cConsole, "Navigation"); + i = gl_printWidth(&gui.smallFont, "Off"); + vect_csetmin(&v, VX(gui.pos_nav) + (gui.nav.w - i)/2., VY(gui.pos_nav) - 10 - gui.smallFont.h); + gl_print(&gui.smallFont, &v, &cGrey, "Off"); } // Health @@ -810,6 +838,7 @@ void player_board(void) { player_message("You are going too fact to board the ship"); return; } + // TODO: player_message("It's a shame Allanis hasn't added boarding yet, right?!"); } @@ -838,6 +867,52 @@ static void player_secondaryNext(void) { pilot_setAmmo(player); } +// Cycle through planet targets. +static void player_targetPlanet(void) { + if((planet_target == -1) && (cur_system->nplanets > 0)) { + // No target. + planet_target = 0; + return; + } + + planet_target++; + + if(planet_target >= cur_system->nplanets) + // Last system. + planet_target = -1; +} + +// Attempt to land or target closest planet if no land target. +static void player_land(void) { + Planet* planet = &cur_system->planets[planet_target]; + if(planet_target >= 0) { + if(vect_dist(&player->solid->vel, &planet->pos) > planet->gfx_space->sw) { + player_message("You are too far away to land on %s", planet->name); + return; + } + else if((pow2(VX(player->solid->vel)) + pow2(VY(player->solid->vel))) > (double)pow2(MAX_HYPERSPACE_VEL)) { + player_message("You are going too fast to land on %s", planet->name); + return; + } + // TODO: Landing. + player_message("D'aww.. Allanis was too lazy to do it properly."); + } else { + // Get nearest planet target. + int i; + int tp; + double td, d; + + for(i = 0, tp = -1; i < cur_system->nplanets; i++) { + d = vect_dist(&player->solid->vel, &planet->pos); + if((tp == -1) || (td > d)) { + tp = i; + td = d; + } + } + planet_target = tp; + } +} + // Take a screenshot. static void player_screenshot(void) { char filename[20]; @@ -852,16 +927,23 @@ static void player_screenshot(void) { // Set the default input keys. void input_setDefault(void) { + // Movement. input_setKeybind("accel", KEYBIND_KEYBOARD, SDLK_w, 0); input_setKeybind("left", KEYBIND_KEYBOARD, SDLK_a, 0); input_setKeybind("right", KEYBIND_KEYBOARD, SDLK_d, 0); + // Combat. input_setKeybind("primary", KEYBIND_KEYBOARD, SDLK_SPACE, 0); input_setKeybind("target", KEYBIND_KEYBOARD, SDLK_TAB, 0); input_setKeybind("target_nearest", KEYBIND_KEYBOARD, SDLK_r, 0); input_setKeybind("face", KEYBIND_KEYBOARD, SDLK_f, 0); input_setKeybind("board", KEYBIND_KEYBOARD, SDLK_b, 0); + // Secondary weapon. input_setKeybind("secondary", KEYBIND_KEYBOARD, SDLK_LSHIFT, 0); input_setKeybind("secondary_next", KEYBIND_KEYBOARD, SDLK_q, 0); + // Space + input_setKeybind("target_planet", KEYBIND_KEYBOARD, SDLK_p, 0); + input_setKeybind("land", KEYBIND_KEYBOARD, SDLK_l, 0); + // Misc. input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_UP, 0); input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_DOWN, 0); input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0); @@ -975,6 +1057,14 @@ static void input_key(int keynum, double value, int abs) { else if(strcmp(player_input[keynum]->name, "secondary_next")==0) { if(value == KEY_PRESS) player_secondaryNext(); } + // Target planet (cycles just like target). + else if(strcmp(player_input[keynum]->name, "target_planet")==0) { + if(value == KEY_PRESS) player_targetPlanet(); + } + // Target nearest planet or attempt to land. + else if(strcmp(player_input[keynum]->name, "land")==0) { + if(value == KEY_PRESS) player_land(); + } // Zoom in. else if(strcmp(player_input[keynum]->name, "mapzoomin")==0) { if((value == KEY_PRESS) && (gui.radar.res < RADAR_RES_MAX)) diff --git a/src/space.h b/src/space.h index f7d2d89..ad7c814 100644 --- a/src/space.h +++ b/src/space.h @@ -4,7 +4,7 @@ #include "pilot.h" #define MIN_HYPERSPACE_DIST 1500 -#define MAX_HYPERSPACE_VEL 10 +#define MAX_HYPERSPACE_VEL 15 // Planet types. I didn't take them from Star Trek, I promise. typedef enum { diff --git a/src/weapon.c b/src/weapon.c index 2520fa0..9ead979 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -49,6 +49,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const unsigned int target); static void weapon_render(const Weapon* w); +static void weapons_updateLayer(const double dt, const WeaponLayer layer); static void weapon_update(Weapon* w, const double dt, WeaponLayer layer); static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer); static void weapon_destroy(Weapon* w, WeaponLayer layer); @@ -98,8 +99,14 @@ static void think_seeker(Weapon* w) { vect_pset(&w->solid->vel, w->outfit->speed, VANGLE(w->solid->vel)); } +// Update all the weapon layers. +void weapons_update(const double dt) { + weapons_updateLayer(dt, WEAPON_LAYER_BG); + weapons_updateLayer(dt, WEAPON_LAYER_FG); +} + // Update all weapons in the layer. -void weapons_update(const double dt, WeaponLayer layer) { +static void weapons_updateLayer(const double dt, const WeaponLayer layer) { Weapon** wlayer; int* nlayer; @@ -139,6 +146,26 @@ void weapons_update(const double dt, WeaponLayer layer) { } } +// Render all the weapons. +void weapons_render(const WeaponLayer layer) { + Weapon** wlayer; + int* nlayer; + int i; + + switch(layer) { + case WEAPON_LAYER_BG: + wlayer = wbackLayer; + nlayer = &nwbackLayer; + break; + case WEAPON_LAYER_FG: + wlayer = wfrontLayer; + nlayer = &nwfrontLayer; + break; + } + for(i = 0; i < (*nlayer); i++) + weapon_render(wlayer[i]); +} + // Render the weapons. static void weapon_render(const Weapon* w) { int sx, sy; @@ -175,8 +202,6 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) { } if(weapon_isSmart(w)) (*w->think)(w); (*w->solid->update)(w->solid, dt); - - weapon_render(w); } // Good shot. @@ -231,7 +256,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* // Add a new weapon. void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, const Vec2* vel, - unsigned int parent, unsigned int target, WeaponLayer layer) { + unsigned int parent, unsigned int target, const WeaponLayer layer) { if(!outfit_isWeapon(outfit) && !outfit_isAmmo(outfit)) { ERR("Trying to create a weapon from a non-Weapon type Outfit"); diff --git a/src/weapon.h b/src/weapon.h index f13c16f..0fe147d 100644 --- a/src/weapon.h +++ b/src/weapon.h @@ -6,10 +6,13 @@ typedef enum { WEAPON_LAYER_BG, WEAPON_LAYER_FG } WeaponLayer; void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, const Vec2* vel, unsigned int parent, - const unsigned int target, WeaponLayer layer); + const unsigned int target, const WeaponLayer layer); -void weapons_update(const double dt, WeaponLayer layer); +// Update. +void weapons_update(const double dt); +void weapons_render(const WeaponLayer layer); +// Clean. void weapon_clear(void); void weapon_exit(void);