--- a/src/Network/Client.cc Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Network/Client.cc Sat Dec 06 18:49:51 2008 +0000
@@ -11,33 +11,15 @@
state(state), netsession(NETWORK_MAGIC_ID), server(netsession.connect(connect_to)), netobjs(netsession, NETCHAN_CORE, server) {
// connect slots
- slots.connect(netobjs.sig_create(), this, &NetworkClient::on_create);
+ slots.connect(netobjs.sig_create(NETMSG_SERVER_HELLO), this, &NetworkClient::on_server_hello);
+ slots.connect(netobjs.sig_create(NETMSG_PLAYER_INFO), this, &NetworkClient::on_player_info);
+ slots.connect(netobjs.sig_create(NETMSG_PLAYER_JOIN), this, &NetworkClient::on_player_join);
+ slots.connect(netobjs.sig_create(NETMSG_PROJECTILE_CREATE), this, &NetworkClient::on_projectile_create);
+
slots.connect(netsession.sig_chan_message(NETCHAN_TERRAIN_ARRAY), this, &NetworkClient::on_terrain_array);
// XXX: sig_disconnected
}
-
-void NetworkClient::on_create (NetworkObject_Client *obj, NetworkMessageID msg_id, NetworkPacketInput &pkt) {
- switch (msg_id) {
- case NETMSG_SERVER_HELLO:
- on_server_hello(obj, pkt);
-
- break;
-
- case NETMSG_PLAYER_INFO:
- on_player_info(obj, pkt);
-
- break;
-
- case NETMSG_PLAYER_JOIN:
- on_player_join(obj, pkt);
-
- break;
-
- default:
- Engine::log(WARN, "client.on_create_object") << "unknown msg_id=" << msg_id << " for obj=" << obj;
- }
-}
void NetworkClient::on_server_hello (NetworkObject_Client *obj, NetworkPacketInput &pkt) {
// read the packet
@@ -79,6 +61,18 @@
state.newPlayer(player);
}
+void NetworkClient::on_projectile_create (NetworkObject_Client *obj, NetworkPacketInput &pkt) {
+ // read the packet
+ Vector position = pkt.read_vector();
+ Vector velocity = pkt.read_vector();
+ float explosionRadius = pkt.read_float32();
+
+ Engine::log(INFO, "client.on_projectile_create") << "obj=" << obj << ", pos=" << position << ", velocity=" << velocity;
+
+ // create the NetworkClientPorjectile object
+ new NetworkClientProjectile(*this, obj, position, velocity, explosionRadius);
+}
+
void NetworkClient::on_terrain_array (NetworkPacketInput &pkt, NetworkNode *node) {
// ignore if not from server
if (node != server)
@@ -110,9 +104,21 @@
// delete player;
}
+/*
+ * NetworkClientObjectHelper
+ */
+NetworkClientObjectHelper::NetworkClientObjectHelper (NetworkClient &client, NetworkObject_Client *obj) :
+ client(client), obj(obj)
+{
+
+}
+
+/*
+ * NetworkClientPlayerHelper
+ */
NetworkClientPlayerHelper::NetworkClientPlayerHelper (NetworkClient &client, Vector position, NetworkObject_Client *obj) :
- Player(client.state, position, true), client(client), obj(obj) {
-
+ NetworkClientObjectHelper(client, obj), Player(client.state, position, true)
+{
// receive position updates
slots.connect(obj->sig_message(NETMSG_PLAYER_POSITION), this, &NetworkClientPlayerHelper::on_position);
slots.connect(obj->sig_message(NETMSG_PLAYER_DIG), this, &NetworkClientPlayerHelper::on_dig);
@@ -150,7 +156,7 @@
NetworkPacket pkt;
pkt.write_uint16(input);
- obj->send(NETMSG_CLIENT_MOVE, pkt, false);
+ obj->send(NETMSG_CLIENT_INPUT, pkt, false);
// do not handle locally
}
@@ -171,4 +177,10 @@
client.player_quit(this);
}
+NetworkClientProjectile::NetworkClientProjectile (NetworkClient &client, NetworkObject_Client *obj, Vector position,
+ Vector velocity, float explosionRadius) :
+ NetworkClientObjectHelper(client, obj), Projectile(client.state, position, velocity, true, explosionRadius)
+{
+ // XXX: register messages
+}
--- a/src/Network/Client.hh Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Network/Client.hh Sat Dec 06 18:49:51 2008 +0000
@@ -13,6 +13,7 @@
friend class NetworkClientPlayerHelper;
friend class NetworkClientLocalPlayer;
friend class NetworkClientRemotePlayer;
+ friend class NetworkClientProjectile;
protected:
GameState &state;
@@ -32,6 +33,7 @@
void on_server_hello (NetworkObject_Client *obj, NetworkPacketInput &pkt);
void on_player_info (NetworkObject_Client *obj, NetworkPacketInput &pkt);
void on_player_join (NetworkObject_Client *obj, NetworkPacketInput &pkt);
+ void on_projectile_create (NetworkObject_Client *obj, NetworkPacketInput &pkt);
void on_terrain_array (NetworkPacketInput &pkt, NetworkNode *node);
@@ -39,7 +41,7 @@
void player_quit (NetworkClientRemotePlayer *player);
};
-class NetworkClientPlayerHelper : public virtual Player {
+class NetworkClientObjectHelper {
protected:
NetworkClient &client;
@@ -47,6 +49,10 @@
NetworkObject_Client *obj;
+ NetworkClientObjectHelper (NetworkClient &client, NetworkObject_Client *obj);
+};
+
+class NetworkClientPlayerHelper : public NetworkClientObjectHelper, public virtual Player {
protected:
NetworkClientPlayerHelper (NetworkClient &client, Vector position, NetworkObject_Client *obj);
@@ -71,4 +77,10 @@
};
+class NetworkClientProjectile : public NetworkClientObjectHelper, public Projectile {
+ public:
+ NetworkClientProjectile (NetworkClient &client, NetworkObject_Client *obj, Vector position, Vector velocity,
+ float explosionRadius);
+};
+
#endif
--- a/src/Network/Object.cc Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Network/Object.cc Sat Dec 06 18:49:51 2008 +0000
@@ -67,7 +67,8 @@
NetworkObject_Client *obj = new NetworkObject_Client(*this, obj_id);
// signal
- _sig_create(obj, msg_id, pkt);
+ // XXX: this leaks if it's not handled
+ _map_sig_create[msg_id](obj, pkt);
}
/*
--- a/src/Network/Object.hh Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Network/Object.hh Sat Dec 06 18:49:51 2008 +0000
@@ -59,7 +59,7 @@
private:
NetworkNode *server;
- CL_Signal_v3<NetworkObject_Client*, NetworkMessageID, NetworkPacketInput&> _sig_create;
+ std::map<NetworkMessageID, CL_Signal_v2<NetworkObject_Client*, NetworkPacketInput&> > _map_sig_create;
public:
NetworkObject_ClientController (NetworkSession &session, NetworkChannelID channel_id, NetworkNode *server);
@@ -68,7 +68,7 @@
virtual void handle_create (NetworkObjectID obj_id, NetworkMessageID msg_id, NetworkPacketInput &pkt, NetworkNode *node);
public:
- CL_Signal_v3<NetworkObject_Client*, NetworkMessageID, NetworkPacketInput&>& sig_create (void) { return _sig_create; }
+ CL_Signal_v2<NetworkObject_Client*, NetworkPacketInput&>& sig_create (NetworkMessageID msg_id) { return _map_sig_create[msg_id]; }
};
class NetworkObject {
--- a/src/Network/Protocol.hh Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Network/Protocol.hh Sat Dec 06 18:49:51 2008 +0000
@@ -27,41 +27,41 @@
};
enum NetworkMessage {
- NETMSG_PACKET_INVALID = 0x0000,
+ NETMSG_PACKET_INVALID = 0x0000,
/*
* You have joined the game:
*
* Vector initial_position
*/
- NETMSG_SERVER_HELLO = 0x0100,
+ NETMSG_SERVER_HELLO = 0x0100,
/*
* New client has connected to server:
*
* Vector initial_position
*/
- NETMSG_PLAYER_JOIN = 0x0101,
+ NETMSG_PLAYER_JOIN = 0x0101,
/*
* Client has left server:
*
*/
- NETMSG_PLAYER_QUIT = 0x0102,
+ NETMSG_PLAYER_QUIT = 0x0102,
/*
- * Client has moved
+ * Client has input to process
*
- * uint16_t PlayerInput_Move
+ * uint16_t PlayerInput
*/
- NETMSG_CLIENT_MOVE = 0x0201,
+ NETMSG_CLIENT_INPUT = 0x0201,
/*
* Initial player info
*
* Vector initial_position
*/
- NETMSG_PLAYER_INFO = 0x0300,
+ NETMSG_PLAYER_INFO = 0x0300,
/*
* Player position update
@@ -71,7 +71,7 @@
* uint8_t NetworkPhysicsFlags
* float32 aim
*/
- NETMSG_PLAYER_POSITION = 0x0301,
+ NETMSG_PLAYER_POSITION = 0x0301,
/*
* Terrain update, removeGround
@@ -79,7 +79,16 @@
* Vector position
* float32 radius
*/
- NETMSG_PLAYER_DIG = 0x0302,
+ NETMSG_PLAYER_DIG = 0x0302,
+
+ /*
+ * New projectile spawned
+ *
+ * Vector position
+ * Vector velocity
+ * float explosionRadius
+ */
+ NETMSG_PROJECTILE_CREATE = 0x0401,
};
#endif
--- a/src/Network/Server.cc Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Network/Server.cc Sat Dec 06 18:49:51 2008 +0000
@@ -46,7 +46,7 @@
// messages
slots.connect(node->sig_disconnected(), this, &NetworkServerPlayer::on_disconnected);
- slots.connect(obj.sig_message(NETMSG_CLIENT_MOVE), this, &NetworkServerPlayer::on_move);
+ slots.connect(obj.sig_message(NETMSG_CLIENT_INPUT), this, &NetworkServerPlayer::on_input);
// the initial NETMSG_PLAYER_HELLO
NetworkPacket hello_pkt;
@@ -89,6 +89,13 @@
Player::handleDig(position, radius);
}
+void NetworkServerPlayer::handleCreateProjectile (Weapon &weapon, Vector position, Vector velocity) {
+ Engine::log(INFO, "server_player.create_projectile") << /* "weapon=" << weapon << ", */ "position=" << position << ", velocity=" << velocity;
+
+ // create new NetworkServerProjectile object
+ new NetworkServerProjectile(server, position, velocity, weapon.getExplosionRadius(), weapon.getExpireTicks());
+}
+
void NetworkServerPlayer::on_disconnected (void) {
NetworkPacket pkt;
@@ -104,16 +111,16 @@
// delete this;
}
-void NetworkServerPlayer::on_move (NetworkNode *src, NetworkPacketInput &pkt) {
+void NetworkServerPlayer::on_input (NetworkNode *src, NetworkPacketInput &pkt) {
// sanity-check, other players shouldn't move
if (src != node) {
- Engine::log(WARN, "server_player.on_move") << "packet from wrong src=" << src << ", node=" << node;
+ Engine::log(WARN, "server_player.on_input") << "packet from wrong src=" << src << ", node=" << node;
return;
}
PlayerInput input = pkt.read_uint16();
- Engine::log(INFO, "server_player.on_move") << "player=" << obj << ", old_pos=" << position << ", input=" << input;
+ Engine::log(INFO, "server_player.on_input") << "player=" << obj << ", old_pos=" << position << ", input=" << input;
// apply input
handleInput(input);
@@ -164,3 +171,19 @@
obj.send_all(NETMSG_PLAYER_POSITION, pkt, false);
}
+/*
+ * NetworkServerProjectile
+ */
+NetworkServerProjectile::NetworkServerProjectile (NetworkServer &server, Vector position, Vector velocity,
+ float explosionRadius, TickCount age) :
+ Projectile(server.state, position, velocity, true, explosionRadius, age), server(server), obj(server.netobjs)
+{
+ NetworkPacket pkt;
+
+ pkt.write_vector(position);
+ pkt.write_vector(velocity);
+ pkt.write_float32(explosionRadius);
+
+ obj.send_all(NETMSG_PROJECTILE_CREATE, pkt, true);
+}
+
--- a/src/Network/Server.hh Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Network/Server.hh Sat Dec 06 18:49:51 2008 +0000
@@ -14,6 +14,7 @@
class NetworkServer {
friend class NetworkServerPlayer;
+ friend class NetworkServerProjectile;
protected:
GameState &state;
@@ -43,15 +44,26 @@
public:
NetworkServerPlayer (NetworkServer &server, NetworkNode *node);
-
+
+ // 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);
private:
void on_disconnected (void);
- void on_move (NetworkNode *node, NetworkPacketInput &pkt);
+ void on_input (NetworkNode *node, NetworkPacketInput &pkt);
void send_terrain_data (void);
void send_position_update (void);
};
+class NetworkServerProjectile : public Projectile {
+ private:
+ NetworkServer &server;
+ NetworkObject_Server obj;
+
+ public:
+ NetworkServerProjectile (NetworkServer &server, Vector position, Vector velocity, float explosionRadius, TickCount age);
+};
+
#endif
--- a/src/PhysicsObject.cc Sat Dec 06 17:51:19 2008 +0000
+++ b/src/PhysicsObject.cc Sat Dec 06 18:49:51 2008 +0000
@@ -11,11 +11,7 @@
}
PhysicsObject::~PhysicsObject (void) {
- Engine::log(DEBUG, "PhysicsObject.destructor") << this /* << ": objects.size=" << ((int) world.objects.size()) */;
-
- // world.objects.remove(this);
-
- Engine::log(DEBUG, "PhysicsObject.destructor") << this /* << ": objects.size=" << ((int) world.objects.size()) */;
+ // Engine::log(DEBUG, "PhysicsObject.destructor") << this /* << ": objects.size=" << ((int) world.objects.size()) */;
}
/**
@@ -146,10 +142,8 @@
// If the worm is not in the air make it walk,
// otherwise integrate the new position and velocity
if (!this->inAir) {
- //std::cout << "Tryin to walk" << std::endl;
// It walks only if there's some vertical force
if (total.x != 0) {
- std::cout << "Succeeding to walk" << std::endl;
walk(dt, total.x > 0);
this->velocity = Vector(0,0);
}
--- a/src/Player.cc Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Player.cc Sat Dec 06 18:49:51 2008 +0000
@@ -51,20 +51,8 @@
}
-void Player::handleShoot (Weapon &weapon) {
- Vector unitVectorAim = (facingRight ?
- Vector(std::cos(aim), -std::sin(aim)) :
- Vector(-std::cos(aim), -std::sin(aim))
- );
-
- // XXX: what does the PHYSICS_TICK_MS stuff mean?
- float shotspeed = weapon.getVelocity() * PHYSICS_TICK_MS / 2;
-
- Vector shotRelativeVelocity = unitVectorAim * shotspeed;
- Vector shotVelocity = this->velocity + shotRelativeVelocity;
- Vector shotPosition = this->position + unitVectorAim * 10;
-
- weapon.shoot(shotPosition, shotVelocity);
+void Player::handleCreateProjectile (Weapon &weapon, Vector position, Vector velocity) {
+ new Projectile(state, position, velocity, true, weapon.getExplosionRadius());
}
void Player::printDebugInfo (void) {
@@ -79,6 +67,27 @@
getWeapon().tickReload(dt);
}
+void LocalPlayer::fireWeapon (Weapon &weapon) {
+ // update reload timer
+ weapon.reload();
+
+ // calculate unit vector
+ Vector unitVectorAim = (facingRight ?
+ Vector(std::cos(aim), -std::sin(aim)) :
+ Vector(-std::cos(aim), -std::sin(aim))
+ );
+
+ // XXX: what does the PHYSICS_TICK_MS stuff mean?
+ float shotspeed = weapon.getVelocity() * PHYSICS_TICK_MS / 2;
+
+ Vector shotRelativeVelocity = unitVectorAim * shotspeed;
+ Vector shotVelocity = this->velocity + shotRelativeVelocity;
+ Vector shotPosition = this->position + unitVectorAim * 10;
+
+ // execute
+ handleCreateProjectile(weapon, shotPosition, shotVelocity);
+}
+
void LocalPlayer::handleInput (PlayerInput input) {
// Movement force, vertical is always zero
Vector move_force = Vector(0, 0);
@@ -142,9 +151,8 @@
}
// validate shoot events, and then outsource to handleShoot so Network can intercept it
- if (input & INPUT_SHOOT && getWeapon().canShoot()) {
- this->handleShoot(getWeapon());
- }
+ if (input & INPUT_SHOOT && getWeapon().canShoot())
+ fireWeapon(getWeapon());
// XXX: how should this be written?
if (move_force.x != 0)
--- a/src/Player.hh Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Player.hh Sat Dec 06 18:49:51 2008 +0000
@@ -31,10 +31,10 @@
// used by the network code to execute actions for players
virtual void handleDig (Vector position, float radius);
- virtual void handleShoot (Weapon &weapon);
+ virtual void handleCreateProjectile (Weapon &weapon, Vector position, Vector velocity);
/*
- *
+ * The currently selected weapon
*/
Weapon& getWeapon();
@@ -58,6 +58,9 @@
};
class LocalPlayer : public virtual Player {
+ private:
+ void fireWeapon (Weapon &weapon);
+
public:
/*
* Called to invoke some action on this player that we control, either by Graphics or NetworkServer.
--- a/src/Projectile.hh Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Projectile.hh Sat Dec 06 18:49:51 2008 +0000
@@ -13,12 +13,12 @@
bool visible;
bool target_visible;
float radius;
+
public:
-
TickCount birth_tick;
TickCount age;
- Projectile(GameState &state, Vector position, Vector velocity, bool visible, float radius, TickCount age=1000000000);
+ Projectile (GameState &state, Vector position, Vector velocity, bool visible, float radius, TickCount age=1000000000);
virtual ~Projectile (void);
virtual void draw (CL_GraphicContext *gc) const;
--- a/src/Terrain.cc Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Terrain.cc Sat Dec 06 18:49:51 2008 +0000
@@ -171,23 +171,19 @@
int dirIdx = getDirectionIndex(prevPoint.roundToInt() - point.roundToInt());
// dirIdx = (dirIdx+4)%8;
- std::cout << (prevPoint.roundToInt()) - (point.roundToInt()) << prevPoint-point << std::endl;
-
normal += DIRECTIONS[dirIdx];
- for(int i = 1; i <= 2; i++) {
+ for (int i = 1; i <= 2; i++) {
if(getType(point + DIRECTIONS[(dirIdx+i+8)%8]) == EMPTY) {
normal += DIRECTIONS[(dirIdx+i+8)%8];
}
}
- for(int i = 1; i <= 2; i++) {
+ for (int i = 1; i <= 2; i++) {
if(getType(point + DIRECTIONS[(dirIdx-i+8)%8]) == EMPTY) {
normal += DIRECTIONS[(dirIdx-i+8)%8];
}
}
- Engine::log(DEBUG, "Physics.getNormal ") << "normal: " << normal << " dirIdx: " << dirIdx;
-
- if(getType(point) == EMPTY || getType(prevPoint) != EMPTY) {
+ if (getType(point) == EMPTY || getType(prevPoint) != EMPTY) {
Engine::log(DEBUG, "Physics.getNormal ") << "logic ground error";
}
--- a/src/Weapon.cc Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Weapon.cc Sat Dec 06 18:49:51 2008 +0000
@@ -31,10 +31,8 @@
return (reloadTimer == 0);
}
-Projectile* Weapon::shoot (Vector position, Vector velocity) {
+void Weapon::reload (void) {
// set the reload timer
reloadTimer = reloadTime;
-
- return new Projectile(st, position, velocity, true, explosionRadius);
}
--- a/src/Weapon.hh Sat Dec 06 17:51:19 2008 +0000
+++ b/src/Weapon.hh Sat Dec 06 18:49:51 2008 +0000
@@ -34,13 +34,13 @@
// can the weapon be fired (not reloading, have a clip, etc)
bool canShoot (void);
- // get the weapon projectile velocity
+ // get weapon parameters
float getVelocity (void) { return velocity; }
-
- /*
- * Fire the Weapon! Position and velocity are the initial position and velocity for the resulting projectile
- */
- Projectile* shoot (Vector position, Vector velocity);
+ float getExplosionRadius (void) { return explosionRadius; }
+ TickCount getExpireTicks (void) { return age; }
+
+ // start reloading
+ void reload (void);
};
#endif