diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/entity.cc | 92 | ||||
-rw-r--r-- | src/core/entity.h | 53 | ||||
-rw-r--r-- | src/core/gameserver.cc | 45 | ||||
-rw-r--r-- | src/core/physics.h | 2 |
4 files changed, 143 insertions, 49 deletions
diff --git a/src/core/entity.cc b/src/core/entity.cc index a1db040..1438466 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -520,7 +520,7 @@ void Entity::reset() entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(entity_mass, entity_motionstate, entity_collision_shape, inertia); entity_body = new btRigidBody(*entity_body_info); - //entity_body->setActivationState(ISLAND_SLEEPING); + entity_body->setActivationState(ISLAND_SLEEPING); if (zone()) zone()->physics()->addRigidBody(entity_body); @@ -540,12 +540,16 @@ EntityDynamic::EntityDynamic() : Entity() { entity_state = Normal; entity_timer = 0; + entity_keepalive_time = 0.0f; + entity_keepalive_timeout = 0.0f; } EntityDynamic::EntityDynamic(std::istream & is) : Entity(is) { entity_state = Normal; entity_timer = 0; + entity_keepalive_time = 0.0f; + entity_keepalive_timeout = 0.0f; } EntityDynamic::~EntityDynamic() @@ -560,6 +564,16 @@ void EntityDynamic::set_state(int state) } } +void EntityDynamic::set_keepalive_time(float time) +{ + entity_keepalive_time = time; +} + +void EntityDynamic::set_keepalive_timeout(float timeout) +{ + entity_keepalive_timeout = timeout; +} + void EntityDynamic::reset() { Entity::reset(); @@ -577,7 +591,6 @@ void EntityDynamic::frame(float seconds) return; // transfer bullet state to entity state - // FIXME disable physics when docked if (entity_body) { // this makes sure an update is sent if speed goes to 0 in the next step if (entity_speed > 0) { @@ -672,6 +685,27 @@ void EntityDynamic::receive_server_update(std::istream &is) } } +/*----- EntityControlable::ActionInterface ------------------------- */ + +EntityControlable::ActionInterface::ActionInterface(EntityControlable *entity) +{ + actioninterface_entity = entity; +} + +EntityControlable::ActionInterface::~ActionInterface() +{ + actioninterface_entity = 0; +} + +void EntityControlable::ActionInterface::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) +{ + actioninterface_entity->action(deltaTimeStep); +} + +void EntityControlable::ActionInterface::debugDraw(btIDebugDraw* debugDrawer) +{ +} + /*----- EntityControlable ------------------------------------------ */ EntityControlable::EntityControlable() : EntityDynamic() @@ -688,7 +722,7 @@ EntityControlable::EntityControlable() : EntityDynamic() entity_owner = 0; - entity_vehicle = 0; + entity_actioninterface = 0; } EntityControlable::EntityControlable(std::istream & is) : @@ -706,7 +740,7 @@ EntityControlable::EntityControlable(std::istream & is) : entity_owner = 0; - entity_vehicle = 0; + entity_actioninterface = 0; } @@ -800,14 +834,6 @@ void EntityControlable::receive_server_update(std::istream &is) entity_movement /= 100.0f; } -void EntityControlable::frame(float seconds) -{ - //entity_direction = target_direction; - //entity_thrust = target_thrust; - //entity_dirty = true; - EntityDynamic::frame(seconds); -} - void EntityControlable::set_thrust(float thrust) { if ((flags() & Static) == Static) @@ -892,11 +918,9 @@ void EntityControlable::set_zone(Zone *zone) if (entity_zone) { entity_zone->remove(this); - if (vehicle() && entity_zone->physics()) { - entity_zone->physics()->removeAction(entity_vehicle); + if (body() && entity_zone->physics()) { + entity_zone->physics()->removeAction(entity_actioninterface); entity_zone->physics()->removeRigidBody(body()); - delete entity_vehicle; - entity_vehicle = 0; } } @@ -909,10 +933,9 @@ void EntityControlable::set_zone(Zone *zone) if (entity_zone) { entity_zone->add(this); - if (body() && entity_zone->physics()) { - entity_vehicle = new btRaycastVehicle(entity_vehicletuning, body(), entity_zone->raycaster()); + if (body() && entity_zone->physics()) { entity_zone->physics()->addRigidBody(body()); - entity_zone->physics()->addAction(entity_vehicle); + entity_zone->physics()->addAction(entity_actioninterface); reset(); } } @@ -945,20 +968,19 @@ void EntityControlable::reset() entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(entity_mass, entity_motionstate, entity_collision_shape, inertia); entity_body = new btRigidBody(*entity_body_info); entity_body->setActivationState(DISABLE_DEACTIVATION); - } - - entity_body->setWorldTransform(t); - if (zone()) { - if (!entity_vehicle) { - entity_vehicle = new btRaycastVehicle(entity_vehicletuning, body(), entity_zone->raycaster()); + + entity_actioninterface = new ActionInterface(this); + + if (zone()) { entity_zone->physics()->addRigidBody(body()); - entity_zone->physics()->addAction(entity_vehicle); - } + entity_zone->physics()->addAction(entity_actioninterface); - // transfer entity location to motion state - zone()->physics()->synchronizeSingleMotionState(entity_body); + // transfer entity location to motion state + zone()->physics()->synchronizeSingleMotionState(entity_body); + } } + entity_body->setWorldTransform(t); if ((entity_state == Docked) || (entity_state == Destroyed) || (!visible())){ entity_body->activate(false); } else { @@ -968,6 +990,18 @@ void EntityControlable::reset() set_dirty(); } +// bullet physics frame (runs at bullet framerate) +void EntityControlable::action(btScalar seconds) +{ +} + +// osirion game frame (runs at osirion server framerate) +void EntityControlable::frame(float seconds) +{ + EntityDynamic::frame(seconds); +} + + /*----- EntityGlobe ------------------------------------------------ */ EntityGlobe::EntityGlobe() : Entity() diff --git a/src/core/entity.h b/src/core/entity.h index 057ffb2..f6ee1d7 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -41,8 +41,10 @@ class Entity : public Label friend class Extension; public: - /// Entity flags - enum Flags {Static = 1, Solid = 2, Bright = 4, Dockable = 8, ShowOnMap = 16}; + /** + * @brief entity flags + */ + enum Flags {Static = 1, Solid = 2, Bright = 4, Dockable = 8, ShowOnMap = 16, KeepAlive = 32}; /// Entity type constants enum Type {Default = 0, Dynamic = 1, Controlable = 2, Globe = 3}; @@ -492,7 +494,17 @@ public: return entity_timer; } -/*----- mutators -------------------------------------------------- */ + /// time when the entity was last alive + inline const float keepalive_time() const { + return entity_keepalive_time; + } + + /// keepalive timeout + inline const float keepalive_timeout() const { + return entity_keepalive_timeout; + } + + /*----- mutators -------------------------------------------------- */ /// mass of the entity inline void set_mass(const float mass) { @@ -528,6 +540,12 @@ public: /// set event state virtual void set_state(int state); + + /// set the time when the entity was last alive, in game time seconds + void set_keepalive_time(float time); + + /// set the timeout after which the entitie is deleted, in seconds + void set_keepalive_timeout(float timeout); /// runs one game frame for the entity /** @@ -542,6 +560,8 @@ public: virtual void reset(); protected: + float entity_keepalive_time; + float entity_keepalive_timeout; float entity_timer; int entity_state; }; @@ -551,6 +571,20 @@ class EntityControlable : public EntityDynamic { friend class Player; public: + /// bullet action interface class + class ActionInterface: public btActionInterface { + public: + ActionInterface(EntityControlable *entity); + virtual ~ActionInterface(); + + virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTimeStep); + + virtual void debugDraw(btIDebugDraw* debugDrawer); + + private: + EntityControlable *actioninterface_entity; + }; + /// server-side constructor, create a controlable entity EntityControlable(); @@ -581,9 +615,9 @@ public: return entity_movement; } - /// physics vehicle container - inline btRaycastVehicle *vehicle() { - return entity_vehicle; + /// physics action + inline ActionInterface *actioninterface() { + return entity_actioninterface; } /*----- serializers ----------------------------------------------- */ @@ -655,6 +689,10 @@ public: float entity_thrust; protected: + + /// physics action interface callback + virtual void action (btScalar seconds); + /* target_ variables can be set by the client */ /** @@ -688,8 +726,7 @@ protected: float entity_movement; - btRaycastVehicle::btVehicleTuning entity_vehicletuning; - btRaycastVehicle *entity_vehicle; + ActionInterface *entity_actioninterface; private: // owner of the entity diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 597de33..e6c44d0 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -15,6 +15,7 @@ #include "core/loader.h" #include "core/parser.h" #include "core/physics.h" +#include "core/range.h" #include "core/netserver.h" #include "filesystem/filesystem.h" #include "sys/sys.h" @@ -564,8 +565,7 @@ void GameServer::frame(unsigned long timestamp) } // view is to be deleted - if (view->destroyed()) - { + if (view->destroyed()) { if (control) { // player is docked at deleted entity if (control->state() == Entity::Docked) { @@ -590,15 +590,42 @@ void GameServer::frame(unsigned long timestamp) } // mark all entities as updated + const float keepalive_distance_squared = range::fxdistance * range::fxdistance; + for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end();) { - Entity *entity = (*it).second; + + // perform a keep-alive pass + if ((*it).second->flag_is_set(Entity::KeepAlive) && ((*it).second->type() == Entity::Dynamic) && (*it).second->zone()) { + + 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)) { + + 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 (keepalive) { + entity->set_keepalive_time(time() + entity->keepalive_timeout()); + } else if ((entity->keepalive_time() > 0.0f) && (entity->keepalive_time() < time())) { + entity->die(); + } + } - if (entity->entity_destroyed) { - delete entity; - (*it).second = entity = 0; + // delete the entity if necessary + if ((*it).second->entity_destroyed) { + delete (*it).second; + (*it).second = 0; Entity::registry().erase(it++); } else { - entity->clear_updates(); + (*it).second->clear_updates(); ++it; } } @@ -607,10 +634,6 @@ void GameServer::frame(unsigned long timestamp) application()->notify_zonechange(); localplayer()->set_zonechange(false); } - - /*if (!Cvar::sv_dedicated->value()) { - update_clientstate(); - }*/ } void GameServer::save_config() diff --git a/src/core/physics.h b/src/core/physics.h index 071ad33..ecceb67 100644 --- a/src/core/physics.h +++ b/src/core/physics.h @@ -15,7 +15,7 @@ #include "BulletCollision/CollisionShapes/btTriangleMesh.h" #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" #include "BulletCollision/Gimpact/btGImpactShape.h" -#include "BulletDynamics/Vehicle/btRaycastVehicle.h" +#include "BulletDynamics/Dynamics/btActionInterface.h" namespace core { |