Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/entity.cc7
-rw-r--r--src/core/gameserver.cc41
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;