diff options
author | Stijn Buys <ingar@osirion.org> | 2010-10-26 21:08:12 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2010-10-26 21:08:12 +0000 |
commit | 75c6db097b990e58b4b2585580a89561c838d923 (patch) | |
tree | 8c913bdc531ea9a76dcaa9e10a65763f95fa55e4 /src/core/gameserver.cc | |
parent | 23c7d2c11170ee8736673e82a88e87a3d2e538f7 (diff) |
updated network protocol version to 20, implemented invemtory depletion, unified depletion with keepalive
Diffstat (limited to 'src/core/gameserver.cc')
-rw-r--r-- | src/core/gameserver.cc | 107 |
1 files changed, 70 insertions, 37 deletions
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 344c069..f84e228 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -509,19 +509,77 @@ void GameServer::frame(unsigned long timestamp) server_previoustime = server_timestamp; server_timestamp = timestamp - server_startup; - float elapsed = (float)(server_timestamp - server_previoustime) / 1000.0f; + const float elapsed = (float)(server_timestamp - server_previoustime) / 1000.0f; + const unsigned long keepalive_timeout = (Cvar::sv_keepalive ? 1000 * (unsigned long) Cvar::sv_keepalive->value() : (unsigned long) 0 ); - // copy the previous entity state to the client state - /*if (!Cvar::sv_dedicated->value()) { - reset_clientstate(); - }*/ - - // run a time frame on each entity - for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) { - Entity *entity = (*it).second; + for (Zone::Registry::iterator zit = Zone::registry().begin(); zit != Zone::registry().end(); zit++) { + Zone *zone= (*zit).second; + + bool keepalive_run = false; + math::Vector3f keepalive_maxbox; + math::Vector3f keepalive_minbox; - if ((entity->type() == Entity::Controlable) || (entity->type() == Entity::Dynamic)) { - entity->frame(elapsed); + // run a game frame on all dynamic and controlable entities + for (Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { + Entity *entity = (*it); + + if (entity->type() == Entity::Dynamic) { + entity->frame(elapsed); + + } else if (entity->type() == Entity::Controlable) { + EntityControlable *controlable = static_cast<EntityControlable *>(entity); + controlable->frame(elapsed); + + if (controlable->owner() && (controlable->owner()->control() == controlable)) { + // add player controlable to keepalive bounding box + if (!keepalive_run) { + keepalive_maxbox.assign(controlable->location()); + keepalive_minbox.assign(controlable->location()); + keepalive_run = true; + } else { + for (size_t i = 0; i < 3; i++) { + if (keepalive_maxbox[i] < controlable->location()[i]) + keepalive_maxbox[i] = controlable->location()[i]; + if (keepalive_minbox[i] > controlable->location()[i]) + keepalive_minbox[i] = controlable->location()[i]; + } + } + } + } + } + + // expand keepalive bounding box + for (size_t i = 0; i < 3; i++) { + keepalive_maxbox[i] += range::fxdistance * 0.5f; + keepalive_minbox[i] -= range::fxdistance * 0.5f; + } + + // run an upkeep frame on entities that require it + for (Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { + Entity *entity = (*it); + + // if entity is inside the keepalive bounding box, the keepalive timestamp will be set to the current game timestamp + if (entity->flag_is_set(Entity::KeepAlive)) { + if (keepalive_run) { + bool alive = true; + + // bounding box test + for (size_t i = 0; alive && (i < 3); i++) { + if ((entity->location()[i] > keepalive_maxbox[i]) || (entity->location()[i] < keepalive_minbox[i])) { + alive = false; + } + } + + if (alive) { + entity->set_keepalive(server_timestamp); + } + } + + // run upkeep if the keepalive timeout has elapsed + if (entity->keepalive() + keepalive_timeout < server_timestamp) { + entity->upkeep(server_timestamp); + } + } } } @@ -543,7 +601,7 @@ void GameServer::frame(unsigned long timestamp) EntityControlable *control = player->control(); // the player is viewing an entity - if (view) { + if (view) { // the view has changed zone if (view->zone() != player->zone()) { if (control) { @@ -589,31 +647,6 @@ void GameServer::frame(unsigned long timestamp) server_network->frame(server_timestamp); } - 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::const_iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) { - - // set keepalive timeout - if ((*it).second->type() == Entity::Controlable) { - const EntityControlable *controlable = static_cast<const EntityControlable *>((*it).second); - - if ( (controlable->state() != Entity::Docked) && controlable->owner() && controlable->zone() ) { - for (Zone::Content::iterator zit = controlable->zone()->content().begin(); zit != controlable->zone()->content().end(); zit++) { - - 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()); - } - } - } - } - - } - } - // remove deleted entities and mark remaining entities as updated for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end();) { // remove deleted entities |