suicide key and respawning
authorterom
Mon, 08 Dec 2008 18:12:43 +0000
changeset 300 417183866f35
parent 299 e4dacf550ba1
child 301 02ad02d28245
suicide key and respawning
src/Config.hh
src/Input.cc
src/Input.hh
src/Network/Packet.hh
src/PhysicsWorld.cc
src/PhysicsWorld.hh
src/Player.cc
src/Player.hh
src/Timer.cc
src/Timer.hh
src/Types.hh
src/Vector.hh
--- a/src/Config.hh	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/Config.hh	Mon Dec 08 18:12:43 2008 +0000
@@ -4,6 +4,8 @@
 // XXX: merge this as Config.hh.in?
 #include "config.h"
 
+#include "Types.hh"
+
 #include <ClanLib/display.h>
 
 // This is a temporary way to declare different constants. Maybe we
@@ -49,6 +51,15 @@
                                         // objects
 const float PLAYER_RADIUS = 10;
 
+/** What size of hole to dig */
+const float PLAYER_DIG_RADIUS = 15;
+
+/** Player's initial health */
+const Health PLAYER_HEALTH = 100;
+
+/** How long to wait after dying to respawn */
+const TimeMS PLAYER_RESPAWN_DELAY = 2500;
+
 /*
  * Projectiles
  */
--- a/src/Input.cc	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/Input.cc	Mon Dec 08 18:12:43 2008 +0000
@@ -22,6 +22,7 @@
     {   INPUT_UNROPE,       -CL_KEY_ENTER,      CL_KEY_RSHIFT   },
     {   INPUT_ROPE_UP,      CL_KEY_ENTER,       CL_KEY_UP       },
     {   INPUT_ROPE_DOWN,    CL_KEY_ENTER,       CL_KEY_DOWN     },
+    {   INPUT_SUICIDE,      CL_KEY_LCONTROL,    CL_KEY_K        },
     {   INPUT_NONE,         0,                  0               }
 };
 
--- a/src/Input.hh	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/Input.hh	Mon Dec 08 18:12:43 2008 +0000
@@ -30,6 +30,8 @@
     INPUT_UNROPE        = 0x0400,
     INPUT_ROPE_UP       = 0x0800,
     INPUT_ROPE_DOWN     = 0x1000,
+
+    INPUT_SUICIDE       = 0x2000,
 };
 
 /**
--- a/src/Network/Packet.hh	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/Network/Packet.hh	Mon Dec 08 18:12:43 2008 +0000
@@ -2,7 +2,7 @@
 #define NETWORK_PACKET_HH
 
 #include "Config.hh"
-#include "../Vector.hh"
+#include "../Types.hh"
 #include "../Error.hh"
 
 /**
--- a/src/PhysicsWorld.cc	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/PhysicsWorld.cc	Mon Dec 08 18:12:43 2008 +0000
@@ -87,3 +87,7 @@
     objects.remove_if(std::mem_fun(&PhysicsObject::removeIfDestroyed));
 }
 
+TickCount PhysicsWorld::getTicks (void) {
+    return tick_timer.get_ticks();
+}
+
--- a/src/PhysicsWorld.hh	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/PhysicsWorld.hh	Mon Dec 08 18:12:43 2008 +0000
@@ -57,14 +57,14 @@
     /**
      * Advance one time step in physics simulation.
      */
-    void tick(TimeMS tick_length);
+    void tick (TimeMS tick_length);
 
     /**
      * Get current tick in physics simulation.
      *
      * @return tick Current simulation tick.
      */
-    uint32_t getTick();
+    TickCount getTicks (void);
 };
 
 #endif 
--- a/src/Player.cc	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/Player.cc	Mon Dec 08 18:12:43 2008 +0000
@@ -26,7 +26,8 @@
     weapons(buildWeaponsList()), 
     selectedWeapon(0), 
     rope(*this),
-    health(100),
+    health(PLAYER_HEALTH),
+    respawn_timer(PLAYER_RESPAWN_DELAY),
     animation_step(0)
 {
     // XXX: populate weapons from somewhere else
@@ -44,11 +45,46 @@
 
     // add to GameState players list
     state.addPlayer(this);
+
+    // connect respawn timer
+    respawn_slot = respawn_timer.sig_tick().connect(this, &Player::respawn);
+
+    // spawn
+    spawn(position);
 }
 
 Player::~Player (void) {
     state.removePlayer(this);
 }
+    
+void Player::spawn (Vector position) {
+    // dig hole
+    world.removeGround(position, PLAYER_DIG_RADIUS);
+
+    // update position
+    setPosition(position);
+
+    // enable
+    enable();
+}
+
+void Player::die (void) {
+    // disable our PhysicsObject
+    disable();
+    
+    // start respawn timer
+    respawn_timer.fire_once();
+}
+
+void Player::respawn (TimeMS dt) {
+    (void) dt;
+
+    // reset health
+    health = PLAYER_HEALTH;
+
+    // XXX: ...
+    spawn(Vector(PLAYER_INITIAL_X, PLAYER_INITIAL_Y));
+}
 
 void Player::handleDig (Vector pos, float radius) {
     // calculate new position and velocity
@@ -85,7 +121,7 @@
 void Player::tick (TimeMS dt) {
     // let PhysicsObject execute
     PhysicsObject::tick(dt);
-    
+
     // tick current weapon reload
     if (getCurrentWeapon())
         getCurrentWeapon()->tickReload(dt);
@@ -99,6 +135,9 @@
     (void) length;
 }
 
+/*
+ * LocalPlayer
+ */
 void LocalPlayer::fireWeapon (Weapon *weapon) {
     // calculate new position and velocity
     Vector shotPosition = position + getDirection() * PROJECTILE_START_DISTANCE;
@@ -164,7 +203,7 @@
     
     // outsource digging to Player::handleDig, since this modifies the Terrain and Network needs to know
     if (input & INPUT_DIG)
-        handleDig(position, 15);
+        handleDig(position, PLAYER_DIG_RADIUS);
     
     // change weapon back/forth
     if (input & INPUT_CHANGE_PREV)
@@ -201,6 +240,10 @@
     // apply force
     if (!move_force.zero())
         applyForce(move_force, dt);
+
+    // suicide?
+    if (input & INPUT_SUICIDE)
+        die();
 }
 
 Weapon* Player::getCurrentWeapon() {
@@ -237,7 +280,7 @@
     health -= damage;
 
     if (health <= 0)
-        disable();
+        die();
 
     Engine::log(DEBUG, "player.take_damage") << this << ": damage=" << damage << ", health=" << health;
 }
--- a/src/Player.hh	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/Player.hh	Mon Dec 08 18:12:43 2008 +0000
@@ -40,6 +40,10 @@
     /** Our current health */
     Health health;
 
+    /** Our respawn-timer */
+    Timer respawn_timer;
+    CL_Slot respawn_slot;
+
     // XXX: hmm... updated where?
     int animation_step;
 
@@ -57,6 +61,21 @@
      * Remove player from state players list
      */
     ~Player (void);
+    
+    /**
+     * Move the worm to the given position, removeGround to dig a hole there, and enable ourselves
+     */
+    virtual void spawn (Vector position);
+
+    /**
+     * We die. Disable and prepare respawn_timer
+     */
+    virtual void die (void);
+
+    /**
+     * Calculate a new position for the worm, and respawn there. Also set health back to 100%
+     */
+    void respawn (TimeMS dt);
 
     /**
      *  Used by the network code to execute various actions
--- a/src/Timer.cc	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/Timer.cc	Mon Dec 08 18:12:43 2008 +0000
@@ -18,6 +18,14 @@
     last_tick = CL_System::get_time();
 
     enabled = true;
+    single_shot = false;
+}
+        
+void Timer::fire_once (void) {
+    last_tick = CL_System::get_time();
+
+    enabled = true;
+    single_shot = true;
 }
 
 void Timer::keep_alive (void) {
@@ -43,6 +51,10 @@
         // update state
         last_tick = now;
         ticks += tick_length / interval;
+
+        // if it was single-shot, disable
+        if (single_shot)
+            enabled = false;
     }
 }
     
--- a/src/Timer.hh	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/Timer.hh	Mon Dec 08 18:12:43 2008 +0000
@@ -3,15 +3,7 @@
 
 #include <ClanLib/core.h>
 
-/**
- * A time interval, measured in real milliseconds
- */
-typedef unsigned long TimeMS;
-
-/**
- * Abstract tick count, defined as a number of Timer::interval's against real time
- */
-typedef uint32_t TickCount;
+#include "Types.hh"
 
 /**
  * Used to implement Physics ticks and Graphics frames. This will attempt to trigger sig_tick every <interval> ms,
@@ -19,22 +11,39 @@
  */
 class Timer : public CL_KeepAlive {
     protected:
-        // the target tick interval
+        /**
+         * The target tick interval
+         */
         TimeMS interval;
 
-        // number of ticks
+        /**
+         * Number of ticks so far, updated by keep_alive
+         */
         TickCount ticks;
-
+        
+        /**
+         * Is the timer running?
+         */
         bool enabled;
+        
+        /**
+         * Single-shot mode?
+         */
+        bool single_shot;
 
-        // time of last tick
+        /**
+         * Time of last tick, set to current time by start/fire_once/keep_alive
+         */
         TimeMS last_tick;
-
+        
+        /** The tick signal */
         CL_Signal_v1<TimeMS> _sig_tick;
         
     public:
-        /*
-         * Interval is in milliseconds
+        /**
+         * Prepare a timer, sig_tick will be fired every interval ms after the timer is started.
+         *
+         * @param interval interval in milliseconds
          */
         Timer (TimeMS interval);
         
@@ -43,15 +52,26 @@
          */
         TickCount get_ticks (void);
         
-        /*
-         * Start the timer, this should be called once keepalive starts getting called
+        /**
+         * Start the timer in continuous-call mode, this should be called once keepalive starts getting called.
          */
         void start (void);
+
+        /**
+         * Tick the timer, but only once
+         */
+        void fire_once (void);
         
     private:
+        /**
+         * If interval time has elapsed, fire sig_tick
+         */
         void keep_alive (void);
     
     public:
+        /**
+         * Triggered approximately every interval MS, but the given interval may also be longer if we've skipped ticks
+         */
         CL_Signal_v1<TimeMS>& sig_tick (void) { return _sig_tick; }
 };
 
--- a/src/Types.hh	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/Types.hh	Mon Dec 08 18:12:43 2008 +0000
@@ -5,8 +5,15 @@
  * Define various types
  */
 
+#include "Vector.hh"
+
 #include <stdint.h>
 
+/* 
+ * Standard vector used for Physics stuff
+ */
+typedef _Vector<float> Vector;
+
 /**
  * A player's health is measured in...
  */
@@ -22,5 +29,14 @@
  */
 typedef _Vector<PixelDimension> PixelCoordinate;
 
+/**
+ * A time interval, measured in real milliseconds
+ */
+typedef unsigned long TimeMS;
+
+/**
+ * Abstract tick count, defined as a number of Timer::interval's against real time
+ */
+typedef uint32_t TickCount;
 
 #endif
--- a/src/Vector.hh	Mon Dec 08 17:39:01 2008 +0000
+++ b/src/Vector.hh	Mon Dec 08 18:12:43 2008 +0000
@@ -109,7 +109,4 @@
     return s<<"("<<v.x<<", "<<v.y<<")";
 }
 
-// Standard vector
-typedef _Vector<float> Vector;
-
 #endif