From 37d132313dbed8007ee6e5cb3c61d59548fb3d4b Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Tue, 5 Aug 2008 13:31:12 +0000 Subject: server-side detection of entity zone changes, netserver ent/die responses, removed zone from sup messages --- src/core/entity.cc | 35 +++++++++++++++++++---------------- src/core/entity.h | 13 +++++++++++-- src/core/gameserver.cc | 6 ++---- src/core/net.h | 2 +- src/core/netserver.cc | 32 +++++++++++++++++++++----------- 5 files changed, 54 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/core/entity.cc b/src/core/entity.cc index 060ceab..483f58c 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -14,17 +14,22 @@ namespace core { +// maximal number of entities +const size_t MAX_ENTITY = 1048574; + using math::Color; using math::Vector3f; /* ---- Static functions for the Entity registry ------------------- */ Entity::Registry Entity::entity_registry; +size_t Entity::entity_nextid = 0; void Entity::add(Entity *ent) { Registry::iterator it; - unsigned int id = 1; + entity_nextid = (entity_nextid % MAX_ENTITY) + 1; // lowest entity-id is 1 + unsigned int id = entity_nextid; for (it = entity_registry.begin(); it != entity_registry.end() && id == (*it).second->id(); it++) { id++; } @@ -103,6 +108,7 @@ Entity::Entity(unsigned int flags) : entity_clientstate = 0; entity_zone = 0; + entity_oldzone = 0; add(this); } @@ -111,6 +117,8 @@ Entity::Entity(std::istream & is) { entity_id = 0; entity_zone = 0; + entity_oldzone = 0; + entity_model = 0; entity_clientstate = 0; @@ -134,6 +142,13 @@ void Entity::die() entity_destroyed = true; } +void Entity::clear_updates() +{ + entity_created = false; + entity_dirty = false; + entity_oldzone = 0; +} + void Entity::set_zone(Zone *zone) { if (entity_zone == zone) @@ -142,6 +157,9 @@ void Entity::set_zone(Zone *zone) if (entity_zone) entity_zone->remove(this); + if (!entity_oldzone) + entity_oldzone = entity_zone; + entity_zone = zone; entity_dirty = true; @@ -292,7 +310,6 @@ void EntityDynamic::receive_client_update(std::istream &is) void EntityDynamic::serialize_server_update(std::ostream & os) const { - os << (entity_zone ? entity_zone->id() : 0) << " "; os << entity_location << " "; os << entity_axis.forward() << " "; os << entity_axis.left() << " "; @@ -301,26 +318,12 @@ void EntityDynamic::serialize_server_update(std::ostream & os) const void EntityDynamic::receive_server_update(std::istream &is) { - unsigned int zone_id; - is >> zone_id; is >> entity_location; // axis up vector is the crossproduct of forward and left is >> entity_axis[0]; is >> entity_axis[1]; entity_axis[2] = math::crossproduct(entity_axis.forward(), entity_axis.left()); is >> entity_speed; - - - if (!zone_id) { - if (entity_zone) { - entity_zone->remove(this); - entity_zone = 0; - } - } else { - if (zone_id != entity_zone->id()) { - set_zone(Zone::find(zone_id)); - } - } } /*----- EntityControlable ------------------------------------------ */ diff --git a/src/core/entity.h b/src/core/entity.h index feb99f7..40d1ffa 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -87,6 +87,9 @@ public: /// pointer to the zone the entity belongs to inline Zone *zone() const { return entity_zone; } + /// the zone the entity left in case of a zone change + inline Zone *oldzone() const { return entity_oldzone; } + /// dirty flag inline bool dirty() const { return entity_dirty; } @@ -145,6 +148,9 @@ public: */ virtual void set_zone(Zone *zone); + /// clear all update flags + virtual void clear_updates(); + /*----- static ---------------------------------------------------- */ /// type definition for the entity registry @@ -192,6 +198,8 @@ public: protected: // the zone the entity belongs to Zone *entity_zone; + // the previous zone the entity belonged too + Zone *entity_oldzone; private: // add an entity to the registry @@ -200,9 +208,10 @@ private: // the id is set by add() unsigned int entity_id; - // the entity registry - static Registry entity_registry; + static Registry entity_registry; + + static size_t entity_nextid; }; diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 717ce87..81df14b 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -552,15 +552,14 @@ void GameServer::frame(float seconds) return; } } - if (server_network) { - // send network updates server_network->frame(server_time, server_previoustime); } + // mark all entities as udpated for (Entity::Registry::iterator it=Entity::registry().begin(); it != Entity::registry().end(); ) { Entity *entity = (*it).second; @@ -569,8 +568,7 @@ void GameServer::frame(float seconds) (*it).second = entity = 0; Entity::registry().erase(it++); } else { - entity->entity_created = false; - entity->entity_dirty = false; + entity->clear_updates(); ++it; } } diff --git a/src/core/net.h b/src/core/net.h index 6f4a280..0c2b5a6 100644 --- a/src/core/net.h +++ b/src/core/net.h @@ -11,7 +11,7 @@ namespace core { /// network protocol version -const unsigned int PROTOCOLVERSION = 5; +const unsigned int PROTOCOLVERSION = 6; /// maximum lenght of a (compressed) network message block const unsigned int FRAMESIZE = 1152; diff --git a/src/core/netserver.cc b/src/core/netserver.cc index b674dbd..dd70bcf 100644 --- a/src/core/netserver.cc +++ b/src/core/netserver.cc @@ -330,19 +330,29 @@ void NetServer::client_frame(NetClient *client, float timestamp, float previoust send_frame_marker(client, timestamp, previoustimestamp); // send updates for entities in the zone - for (Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { - Entity *entity = (*it); + for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) { + Entity *entity = (*it).second; + + if (entity->zone() == zone) { + if (entity->entity_destroyed) { + if (!entity->entity_created) { + send_entity_delete(client, entity); + } + } else if (entity->entity_created) { + send_entity_create(client, entity); - if (entity->entity_destroyed) { - if (!entity->entity_created) { - send_entity_delete(client, entity); - } - } else if (entity->entity_created) { - send_entity_create(client, entity); - } else if (entity->dirty() && !(entity->flags() & Entity::Static) ) { + } else if (entity->oldzone()) { + // this entity has entered the zone + send_entity_create(client, entity); - // FIXME only within visual range - send_entity_update(client, entity); + } else if (entity->dirty() && !(entity->flags() & Entity::Static) ) { + + // FIXME only within visual range + send_entity_update(client, entity); + } + } else if (entity->oldzone() == zone) { + // the entity has left the zone + send_entity_delete(client, entity); } } } -- cgit v1.2.3