ability to send NetworkObjectID's via packets, modify Network Projectiles to use this and fix recoil/reloading
--- 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; }