ability to send NetworkObjectID's via packets, modify Network Projectiles to use this and fix recoil/reloading
authorterom
Mon, 08 Dec 2008 01:08:00 +0000
changeset 276 87434abc1ba1
parent 275 fa44b905bc2e
child 277 40f4a03917e2
ability to send NetworkObjectID's via packets, modify Network Projectiles to use this and fix recoil/reloading
src/Config.hh
src/Network/Client.cc
src/Network/Client.hh
src/Network/Object.cc
src/Network/Object.hh
src/Network/Protocol.hh
src/Network/Server.cc
src/Network/Server.hh
src/Player.cc
src/Player.hh
src/Projectile.cc
src/Projectile.hh
src/Vector.hh
src/Weapon.hh
--- a/src/Config.hh	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Config.hh	Mon Dec 08 01:08:00 2008 +0000
@@ -44,14 +44,33 @@
                                         // different for different
                                         // objects
 
+/*
+ * Projectiles
+ */
+
+// object mass...
+const float PROJECTILE_MASS = 10.0;
+
 // how far away from the player the projectile spawns
 const float PROJECTILE_START_DISTANCE = 10.0;
 
-// rope
+/*
+ * Rope
+ */
+
+// how much to grow the rope length by on every ROPE_UP/DOWN
 const float ROPE_GROWTH_RATE = 5;
+
+// the force that the rope exerts on the player when the length is too long
 const float ROPE_FORCE = 3500;
-const float ROPE_MASS = 10.0;   // same as player mass...?
+
+// same as player mass...?
+const float ROPE_MASS = 10.0;
+
+// initial length... this should probably be a bit more dynamic?
 const float ROPE_LENGTH = 100.0;
+
+// initial velocity of the rope when thrown
 const float ROPE_VELOCITY = 500;
 
 // Graphical properties
--- a/src/Network/Client.cc	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Network/Client.cc	Mon Dec 08 01:08:00 2008 +0000
@@ -70,8 +70,8 @@
             on_player_join(obj_id, pkt);
             break;
 
-        case NETMSG_PROJECTILE_CREATE:
-            on_projectile_create(obj_id, pkt);
+        case NETMSG_PROJECTILE_PLAYER_FIRED:
+            on_projectile_player_fired(obj_id, pkt);
             break;
 
         default:
@@ -109,17 +109,32 @@
     new NetworkClientRemotePlayer(client, obj_id, position);
 }
         
-void NetworkClientController::on_projectile_create (NetworkObjectID obj_id, NetworkPacketInput &pkt) {
+void NetworkClientController::on_projectile_player_fired (NetworkObjectID obj_id, NetworkPacketInput &pkt) {
     // read the packet
+    NetworkObject *player_obj = client.controller.read_object(pkt);
     Vector position = pkt.read_vector();
     Vector velocity = pkt.read_vector();
-    float explosionRadius = pkt.read_float32();
-    float radius = pkt.read_float32();
+    WeaponID weapon_id = pkt.read_uint8();
+    
+    NetworkClientPlayerBase *player;
 
-    Engine::log(INFO, "client.on_projectile_create") << this << ": pos=" << position << ", velocity=" << velocity;
+    // ignore for invalid players
+    if ((player = dynamic_cast<NetworkClientPlayerBase*>(player_obj)) == NULL) {
+        Engine::log(ERROR, "client.on_projectile_player_fired") << this << ": Unknown player object";
+        return;
+    }
+
+    Weapon *weapon;
+
+    // try and get the weapon
+    if ((weapon = player->getWeapon(weapon_id)) == NULL) {
+        Engine::log(ERROR, "client.on_projectile_player_fired") << this << ": Unknown weapon id: player=" << player << ", weapon_id=" << weapon_id;
+    }
+
+    Engine::log(INFO, "client.on_projectile_create") << this << ": player=" << player << ", pos=" << position << ", velocity=" << velocity << ", weapon=" << weapon;
 
     // create the NetworkClientPorjectile object
-    new NetworkClientProjectile(client, obj_id, position, velocity, explosionRadius, radius);
+    new NetworkClientProjectile(client, obj_id, player, position, velocity, weapon);
 }
 
 /*
@@ -253,12 +268,15 @@
     client.player_quit(this);
 }
 
-NetworkClientProjectile::NetworkClientProjectile (NetworkClient &client, NetworkObjectID obj_id, Vector position,
-        Vector velocity, float explosionRadius, float radius) :
-    NetworkClientObject(client, obj_id), Projectile(client.state, position, velocity, explosionRadius, radius, 100 /* XXX */)
+NetworkClientProjectile::NetworkClientProjectile (NetworkClient &client, NetworkObjectID obj_id, Player *player,
+        Vector position, Vector velocity, Weapon *weapon) :
+    NetworkClientObject(client, obj_id), Projectile(player, position, velocity, weapon)
 {
     // hook up signals
     slots.connect(sig_message(NETMSG_PROJECTILE_DESTROY), this, &NetworkClientProjectile::on_destroy);
+    
+    // tell Player
+    player->weaponFired(weapon);
 }
 
 void NetworkClientProjectile::onDestroy (Vector position, bool removeGround) {
--- a/src/Network/Client.hh	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Network/Client.hh	Mon Dec 08 01:08:00 2008 +0000
@@ -27,7 +27,7 @@
         void on_server_hello (NetworkObjectID obj_id, NetworkPacketInput &pkt);
         void on_player_info (NetworkObjectID obj_id, NetworkPacketInput &pkt);
         void on_player_join (NetworkObjectID obj_id, NetworkPacketInput &pkt);
-        void on_projectile_create (NetworkObjectID obj_id, NetworkPacketInput &pkt);
+        void on_projectile_player_fired (NetworkObjectID obj_id, NetworkPacketInput &pkt);
 };
 
 class NetworkClient {
@@ -101,8 +101,8 @@
 
 class NetworkClientProjectile : public NetworkClientObject, public Projectile {
     public:
-        NetworkClientProjectile (NetworkClient &client, NetworkObjectID obj_id, Vector position, Vector velocity,
-                float explosionRadius, float radius);
+        NetworkClientProjectile (NetworkClient &client, NetworkObjectID obj_id, Player *player, Vector position, 
+                Vector velocity, Weapon *weapon);
     
     protected:
         virtual void onDestroy (Vector position, bool removeGround);
--- a/src/Network/Object.cc	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Network/Object.cc	Mon Dec 08 01:08:00 2008 +0000
@@ -16,10 +16,10 @@
 void NetworkObjectController::on_message (NetworkPacketInput &pkt, NetworkNode *node) {
     uint32_t obj_id = pkt.read_uint32();
     uint16_t msg_id = pkt.read_uint16();
-    
+
     // lookup object
     NetworkObject *obj = objects[obj_id];
-
+    
     if (obj) {
         obj->handle_packet(node, msg_id, pkt);
 
@@ -27,6 +27,20 @@
         handle_create(obj_id, msg_id, pkt, node);
     }
 }
+        
+NetworkObject* NetworkObjectController::read_object (NetworkPacketInput &pkt) {
+    uint32_t obj_id = pkt.read_uint32();
+
+    // lookup object
+    NetworkObject *obj = objects[obj_id];
+    
+    // return
+    return obj;
+}
+        
+void NetworkObjectController::write_object (NetworkPacketOutput &pkt, NetworkObject *obj) {
+    pkt.write_uint32(obj->obj_id);
+}
 
 /* 
  * NetworkObject_ServerController 
--- a/src/Network/Object.hh	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Network/Object.hh	Mon Dec 08 01:08:00 2008 +0000
@@ -36,6 +36,18 @@
 
     protected:
         virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacketInput &pkt, NetworkNode *node) = 0; 
+
+    public:
+        /**
+         * Read an NetworkObjectID from the given packet, and return the corresponding NetworkObject, or NULL if we
+         * don't know it
+         */
+        NetworkObject* read_object (NetworkPacketInput &pkt);
+
+        /**
+         * Write the given Object's NetworkObjectID to the given packet
+         */
+        void write_object (NetworkPacketOutput &pkt, NetworkObject *obj);
 };
 
 class NetworkObject_ServerController : public NetworkObjectController {
--- a/src/Network/Protocol.hh	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Network/Protocol.hh	Mon Dec 08 01:08:00 2008 +0000
@@ -88,10 +88,10 @@
     /*
      * Player changed weapon
      *
-     * uint8_t  weapon_index
+     * uint8_t  weapon_id
      */
     NETMSG_PLAYER_WEAPON_CHANGE = 0x0321,
-    
+
     /*
      * Player threw the rope
      *
@@ -121,16 +121,16 @@
      * float length
      */
     NETMSG_PLAYER_ROPE_LENGTH   = 0x0334,
-
+    
     /*
-     * New projectile spawned
+     * Player has fired a weapon, creating this projectile
      *
+     * Object   player
      * Vector   position
      * Vector   velocity
-     * float    explosionRadius
-     * float    radius
+     * uint8_t  weapon_id
      */
-    NETMSG_PROJECTILE_CREATE    = 0x0401,
+    NETMSG_PROJECTILE_PLAYER_FIRED  = 0x0411,
 
     /*
      * Projectile has gone away
@@ -138,7 +138,7 @@
      * Vector   position
      * uint8_t  NetworkProjectileFlags (REMOVE_GROUND)
      */
-    NETMSG_PROJECTILE_DESTROY   = 0x0402,
+    NETMSG_PROJECTILE_DESTROY       = 0x040F,
 };
 
 #endif
--- a/src/Network/Server.cc	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Network/Server.cc	Mon Dec 08 01:08:00 2008 +0000
@@ -8,7 +8,7 @@
 #include <cassert>
 
 NetworkServer::NetworkServer (GameState &state, const NetworkAddress &listen_addr) : 
-    state(state), netsession(NETWORK_MAGIC_ID), netobjs(netsession, NETCHAN_CORE) {
+    state(state), netsession(NETWORK_MAGIC_ID), controller(netsession, NETCHAN_CORE) {
     
     // connect slots
     slots.connect(netsession.sig_node_connected(), this, &NetworkServer::on_node_connected);
@@ -39,7 +39,7 @@
  * NetworkServerObject
  */
 NetworkServerObject::NetworkServerObject (NetworkServer &server) :
-    NetworkObject_Server(server.netobjs), server(server)
+    NetworkObject_Server(server.controller), server(server)
 {
 
 }
@@ -98,11 +98,14 @@
     Player::handleDig(position, radius);
 }
 
-void NetworkServerPlayer::handleCreateProjectile (Weapon *weapon, Vector position, Vector velocity) {
-    Engine::log(INFO, "server_player.create_projectile") << "weapon='" << weapon->getName() << "', position=" << position << ", velocity=" << velocity;
+void NetworkServerPlayer::handleFireWeapon (Weapon *weapon, Vector position, Vector velocity) {
+    Engine::log(INFO, "server_player.fire_weapon") << "weapon='" << weapon->getName() << "', position=" << position << ", velocity=" << velocity;
 
     // create new NetworkServerProjectile object
     new NetworkServerProjectile(server, this, position, velocity, weapon);
+
+    // as handleFireWeapon does
+    weaponFired(weapon);
 }
 
 void NetworkServerPlayer::handleChangeWeapon (unsigned int weaponIndex) {
@@ -241,23 +244,23 @@
  */
 NetworkServerProjectile::NetworkServerProjectile (NetworkServer &server, NetworkServerPlayer *player, Vector position,
         Vector velocity, Weapon *weapon) :
-    Projectile(server.state, position, velocity, weapon, true), NetworkServerObject(server)
+    Projectile(player, position, velocity, weapon, true), NetworkServerObject(server)
 {
     NetworkPacket pkt;
-
+    
+    server.controller.write_object(pkt, player);
     pkt.write_vector(position);
     pkt.write_vector(velocity);
-    pkt.write_float32(explosionRadius);
-    pkt.write_float32(radius);
+    pkt.write_uint8(weapon->getID());
 
-    send_all(NETMSG_PROJECTILE_CREATE, pkt, true);
+    send_all(NETMSG_PROJECTILE_PLAYER_FIRED, pkt, true);
 }
 
 void NetworkServerProjectile::onDestroy (Vector position, bool removeGround) {
     NetworkPacket pkt;
 
     Engine::log(INFO, "server_projectile.destroy") << "position=" << position << ", removeGround=" << removeGround;
-
+    
     pkt.write_vector(position);
     pkt.write_uint8(removeGround ? NETWORK_PROJECTILE_REMOVE_GROUND : 0);
 
--- a/src/Network/Server.hh	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Network/Server.hh	Mon Dec 08 01:08:00 2008 +0000
@@ -22,7 +22,7 @@
         CL_SlotContainer slots;
 
         NetworkSession netsession;
-        NetworkObject_ServerController netobjs;
+        NetworkObject_ServerController controller;
         std::list<NetworkServerPlayer *> players;
 
     public:
@@ -53,7 +53,7 @@
     protected:    
         // override from Player to replicate side effects of events to clients
         virtual void handleDig (Vector position, float radius);
-        virtual void handleCreateProjectile (Weapon *weapon, Vector position, Vector velocity);
+        virtual void handleFireWeapon (Weapon *weapon, Vector position, Vector velocity);
         virtual void handleChangeWeapon (unsigned int weaponIndex);
         virtual void handleRopeState (RopeState state);
         virtual void handleRopeLength (float length);
--- a/src/Player.cc	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Player.cc	Mon Dec 08 01:08:00 2008 +0000
@@ -55,8 +55,10 @@
     world.removeGround(digPosition, radius);
 }
 
-void Player::handleCreateProjectile (Weapon *weapon, Vector position, Vector velocity) {
-    new Projectile(state, position, velocity, weapon);
+void Player::handleFireWeapon (Weapon *weapon, Vector position, Vector velocity) {
+    weaponFired(weapon);
+
+    new Projectile(this, position, velocity, weapon);
 }
         
 void Player::handleChangeWeapon (unsigned int weaponIndex) {
@@ -64,6 +66,14 @@
 
     selectedWeapon = weaponIndex;
 }
+    
+void Player::weaponFired (Weapon *weapon) {
+    // apply recoil
+    applyForce(-getDirection() * weapon->getRecoil());
+    
+    // reload weapon
+    weapon->reload();
+}
 
 void Player::printDebugInfo (void) {
     Engine::log(DEBUG, "layer.debug") << "In air: " << this->inAir;
@@ -87,19 +97,12 @@
 }
 
 void LocalPlayer::fireWeapon (Weapon *weapon) {
-    // update reload timer
-    weapon->reload();
-    
     // calculate new position and velocity
     Vector shotPosition = position + getDirection() * PROJECTILE_START_DISTANCE;
     Vector shotVelocity = velocity + getDirection() * weapon->getSpeed();
     
-    // Recoil
-    Vector recoilForce =  (getDirection() * weapon->getRecoil())*(-1);
-    applyForce(recoilForce);
-
     // execute
-    handleCreateProjectile(weapon, shotPosition, shotVelocity);
+    handleFireWeapon(weapon, shotPosition, shotVelocity);
 }
         
 void LocalPlayer::changeWeapon (int delta) {
@@ -197,6 +200,13 @@
     return weapons[selectedWeapon % weapons.size()];
 }
 
+Weapon* Player::getWeapon (WeaponID id) {
+    if (id < weapons.size())
+        return weapons[id];
+    else
+        return NULL;
+}
+
 void Player::draw (Graphics *g, PixelCoordinate camera) {
     CL_GraphicContext *gc = g->get_gc();
     
--- a/src/Player.hh	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Player.hh	Mon Dec 08 01:08:00 2008 +0000
@@ -35,38 +35,52 @@
     // XXX: hmm... updated where?
     int animation_step;
 
-         /**
-         * Default constructor for use with virtual inheritance... it's not defined, and must not be called
-         */
-        Player (void);
+    /**
+     * Default constructor for use with virtual inheritance... it's not defined, and must not be called
+     */
+    Player (void);
 
-        /**
-         * Initialize params, and add ourselves to GameState
-         */
-        Player (GameState &state, Vector position, bool visible); 
+    /**
+     * Initialize params, and add ourselves to GameState
+     */
+    Player (GameState &state, Vector position, bool visible); 
 
-        /**
-         * Remove player from state players list
-         */
-        ~Player (void);
+    /**
+     * Remove player from state players list
+     */
+    ~Player (void);
 
     /*
      *  Used by the network code to execute various actions
      */
     virtual void handleDig (Vector position, float radius);
-    virtual void handleCreateProjectile (Weapon *weapon, Vector position, Vector velocity);
+    virtual void handleFireWeapon (Weapon *weapon, Vector position, Vector velocity);
     virtual void handleChangeWeapon (unsigned int weaponIndex);
 
     // Called by rope to handle state changes, these don't do anything by default
     virtual void handleRopeState (RopeState state);
     virtual void handleRopeLength (float length);
+
+public:
+    /**
+     * Called when a weapon is fired, this should apply recoil and reload the weapon
+     */
+    void weaponFired (Weapon *weapon);
         
-    /*
-     * The currently selected weapon
+    /**
+     * Get the currently selected weapon
+     *
+     * @return A pointer to the Weapon object
      */
     Weapon* getCurrentWeapon();
 
-public:
+    /**
+     * Get the weapon with the given index
+     *
+     * @return A pointer to a Weapon object if found, NULL otherwise
+     */
+    Weapon* getWeapon (WeaponID id);
+
     /*
      * Prints random things via Engine::log
      */
--- a/src/Projectile.cc	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Projectile.cc	Mon Dec 08 01:08:00 2008 +0000
@@ -2,22 +2,12 @@
 #include "Graphics.hh"
 #include "Timer.hh"
 
-Projectile::Projectile (GameState &state, Vector position, Vector velocity, float explosionRadius, float radius, 
-        TickCount expire, bool visible) :
-    PhysicsObject(state.world, PLAYER_MASS, position, velocity, PROJECTILE), state(state), visible(visible),
-    explosionRadius(explosionRadius), radius(radius), expire(expire)
+   
+Projectile::Projectile (Player *player, Vector position, Vector velocity, Weapon *weapon, bool visible) :
+    PhysicsObject(player->state.world, PROJECTILE_MASS, position, velocity, PROJECTILE), player(player),
+    visible(visible), explosionRadius(weapon->getExplosionRadius()), radius(weapon->getRadius()),
+    expire(weapon->getExpire())
 {
-    initialize();
-}
-    
-Projectile::Projectile (GameState &state, Vector position, Vector velocity, Weapon *weapon, bool visible) :
-    PhysicsObject(state.world, PLAYER_MASS, position, velocity, PROJECTILE), state(state), visible(visible),
-    explosionRadius(weapon->getExplosionRadius()), radius(weapon->getRadius()), expire(weapon->getExpire())
-{
-    initialize();
-}
-    
-void Projectile::initialize (void) {
     // set birth tick
     birth_tick = world.tick_timer.get_ticks();
 
@@ -35,11 +25,11 @@
     collision_elasticity = 0.9;
 
     // add to state
-    state.addProjectile(this);
+    player->state.addProjectile(this);
 }
 
 Projectile::~Projectile (void) {
-    state.projectiles.remove(this);
+    player->state.projectiles.remove(this);
 }
  
 void Projectile::onDestroy (Vector position, bool removeGround) {
--- a/src/Projectile.hh	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Projectile.hh	Mon Dec 08 01:08:00 2008 +0000
@@ -11,9 +11,9 @@
 class Projectile : public PhysicsObject {
 protected:
     /**
-     * Reference to the world that we live in
+     * Which player fired this projectile?
      */
-    GameState &state;
+    Player *player;
 
     /**
      * Projectiles can be inivisble, e.g. for digging
@@ -42,17 +42,10 @@
 
 public:
     /**
-     * Construct a Projectile using the given parameters and add it to the world's list of projectiles
+     * Constructs this projectile using the given position/velocity, pulling the rest of the parameter values from the
+     * given weapon. The given player is assigned to this projectile. 
      */
-    Projectile (GameState &state, Vector position, Vector velocity, float explosionRadius, float radius,
-            TickCount expire, bool visible = true);
-
-    /**
-     * Like above, but using the parameters of the given weapon
-     *
-     * @see Projectile
-     */
-    Projectile (GameState &state, Vector position, Vector velocity, Weapon *weapon, bool visible = true);
+    Projectile (Player *player, Vector position, Vector velocity, Weapon *weapon, bool visible = true);
 
     /**
      * Removes this from the world's list of projectiles
@@ -66,11 +59,6 @@
 
 protected:
     /**
-     * Initialize shape and add to world projectiles list
-     */
-    void initialize (void);
-
-    /**
      * Removes ground at given position if applicable, and destroys this PhysicsObject.
      *
      * This is overriden by Network.
--- a/src/Vector.hh	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Vector.hh	Mon Dec 08 01:08:00 2008 +0000
@@ -44,6 +44,9 @@
     _Vector operator-(const _Vector &v) const {
         return _Vector(this->x-v.x, this->y-v.y);
     }
+    _Vector operator- (void) const {
+        return _Vector(-this->x, -this->y);
+    }
     _Vector operator*(const T &scalar) const {
         return _Vector(this->x*scalar, this->y*scalar);
     }
--- a/src/Weapon.hh	Mon Dec 08 00:36:24 2008 +0000
+++ b/src/Weapon.hh	Mon Dec 08 01:08:00 2008 +0000
@@ -81,6 +81,7 @@
     /*
      * Get weapon parameters
      */
+    WeaponID getID (void) const { return id; }
     std::string getName (void) const { return name; }
     float getSpeed (void) const { return velocity; }
     float getRecoil (void) const { return recoil; }