diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/entity.cc | 7 | ||||
-rw-r--r-- | src/core/gameserver.cc | 41 |
2 files changed, 26 insertions, 22 deletions
diff --git a/src/core/entity.cc b/src/core/entity.cc index c76b23a..c99c186 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -14,6 +14,7 @@ #include "core/cvar.h" #include "core/application.h" #include "core/gameinterface.h" +#include "core/gameserver.h" #include "BulletCollision/CollisionShapes/btBoxShape.h" @@ -596,6 +597,12 @@ void EntityDynamic::frame(float seconds) return; } + if (flag_is_set(KeepAlive)) { + if ((keepalive_time() > 0.0f) && (keepalive_time() < server()->time())) { + die(); + } + } + // transfer bullet state to entity state if (entity_body) { // this makes sure an update is sent if speed goes to 0 in the next step diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index e6c44d0..344c069 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -588,38 +588,35 @@ void GameServer::frame(unsigned long timestamp) // send network updates server_network->frame(server_timestamp); } - - // mark all entities as updated + const float keepalive_distance_squared = range::fxdistance * range::fxdistance; + + // FIXME KeepAlive sweep has to be done in linear order, O(n^2) is extremely slow with a large number of entities - for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end();) { + for (Entity::Registry::const_iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) { - // perform a keep-alive pass - if ((*it).second->flag_is_set(Entity::KeepAlive) && ((*it).second->type() == Entity::Dynamic) && (*it).second->zone()) { + // set keepalive timeout + if ((*it).second->type() == Entity::Controlable) { + const EntityControlable *controlable = static_cast<const EntityControlable *>((*it).second); - bool keepalive = false; - EntityDynamic *entity = static_cast<EntityDynamic *>((*it).second); - - for (Zone::Content::const_iterator zit = entity->zone()->content().begin(); zit != entity->zone()->content().end(); zit++) { - - if (( (*zit)->type() == Entity::Controlable) && ( (*zit) != entity)) { + if ( (controlable->state() != Entity::Docked) && controlable->owner() && controlable->zone() ) { + for (Zone::Content::iterator zit = controlable->zone()->content().begin(); zit != controlable->zone()->content().end(); zit++) { - const EntityControlable *other = static_cast<const EntityControlable *>(*zit); - if (other->owner() && (other->state() != Entity::Docked) && (math::distancesquared(entity->location(), other->location()) < keepalive_distance_squared)) { - keepalive = true; + if ( ((*zit)->flag_is_set(Entity::KeepAlive)) && ((*zit)->type() == Entity::Dynamic) && ((*zit) != controlable) ) { + EntityDynamic *dynamic = static_cast<EntityDynamic *>(*zit); + if (math::distancesquared(controlable->location(), dynamic->location()) < keepalive_distance_squared) { + dynamic->set_keepalive_time(time() + dynamic->keepalive_timeout()); + } } } - } - if (keepalive) { - entity->set_keepalive_time(time() + entity->keepalive_timeout()); - } else if ((entity->keepalive_time() > 0.0f) && (entity->keepalive_time() < time())) { - entity->die(); - } } - - // delete the entity if necessary + } + + // remove deleted entities and mark remaining entities as updated + for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end();) { + // remove deleted entities if ((*it).second->entity_destroyed) { delete (*it).second; (*it).second = 0; |