From 106d0cb0cf884dd7a2920564852c001e13af1568 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Mon, 8 Nov 2010 15:24:41 +0000 Subject: fixes crash on jumpgate usage, streamlined keepalive/upkeep frame cycle --- src/core/entity.cc | 12 ++++++ src/core/gameserver.cc | 100 +++++++++++++++---------------------------------- src/core/zone.h | 15 ++++++++ 3 files changed, 58 insertions(+), 69 deletions(-) (limited to 'src/core') diff --git a/src/core/entity.cc b/src/core/entity.cc index af100a9..8fde03a 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -990,6 +990,18 @@ void EntityControlable::action(btScalar seconds) void EntityControlable::frame(float seconds) { EntityDynamic::frame(seconds); + + // update zone keepalive bounding box + if (owner() && (owner()->control() == this) && zone()) { + + // add player controlable to keepalive bounding box + if (!zone()->keepalive_run()) { + zone()->keepalive_box().assign(location()); + zone()->set_keepalive_run(true); + } else { + zone()->keepalive_box().expand(location()); + } + } } diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 412c554..5ea6206 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -515,81 +515,43 @@ void GameServer::frame(unsigned long timestamp) 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 ); + // reset zone keepalive state 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; - - // 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); - - // FIXME - // if a controlable changes zone during the entity frame (like when using jumpgates) - // the zone content iterator will become invalid + zone->set_keepalive_run(false); + } + + // run entity game frames + for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) { + Entity *entity = (*it).second; + + if ((entity->type() == Entity::Dynamic) || (entity->type() == Entity::Controlable)) { + entity->frame(elapsed); - // possible solutions - // 1) move the actual zone change into the entity_destroyed sequence (renamed entity.oldzone to newzone and track changes) - // 2) revert to using the entity iterator and add the keep_alive min- and maxbox to the zone class - - if (entity->type() == Entity::Dynamic) { - entity->frame(elapsed); - - } else if (entity->type() == Entity::Controlable) { - EntityControlable *controlable = static_cast(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; + } + } + + // expand zone keepalive bounding box + for (Zone::Registry::iterator zit = Zone::registry().begin(); zit != Zone::registry().end(); zit++) { + Zone *zone= (*zit).second; + if (zone->keepalive_run()) { + zone->keepalive_box().expand(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); + } + + // run upkeep frames + for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) { + Entity *entity = (*it).second; + Zone *zone = entity->zone(); + if (zone && entity->flag_is_set(Entity::KeepAlive)) { + if (zone->keepalive_run() && zone->keepalive_box().inside(entity->location())) { + entity->set_keepalive(server_timestamp); + } - // 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); - } + // run upkeep if the keepalive timeout has elapsed + if (entity->keepalive() + keepalive_timeout < server_timestamp) { + entity->upkeep(server_timestamp); } } } diff --git a/src/core/zone.h b/src/core/zone.h index d4b08bf..d2cdf2c 100644 --- a/src/core/zone.h +++ b/src/core/zone.h @@ -150,7 +150,19 @@ public: inline btVehicleRaycaster *raycaster() { return zone_bullet_raycaster; } + + math::BoundingBox3f & keepalive_box() { + return zone_keepalive_box; + } + + const bool keepalive_run() const { + return zone_keepalive_run; + } + void set_keepalive_run(const bool keepalive_run) { + zone_keepalive_run = keepalive_run; + } + private: unsigned int zone_id; @@ -164,6 +176,9 @@ private: btAxisSweep3 *zone_bullet_cache; btDiscreteDynamicsWorld *zone_bullet_world; btVehicleRaycaster *zone_bullet_raycaster; + + math::BoundingBox3f zone_keepalive_box; + bool zone_keepalive_run; }; } -- cgit v1.2.3