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);