Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2010-10-18 23:41:41 +0000
committerStijn Buys <ingar@osirion.org>2010-10-18 23:41:41 +0000
commit7a373c3f1fb8ea9dbef7690154bbe332fc386eca (patch)
treee56652c9b6197017d7eb8e86e5cd431bf9861d57 /src/core
parent4c5b00221c9405c5af06143974fbc6296ebe46b5 (diff)
bullet ActionInterface for controlable entities, KeepAlive flag and g_keepalive
Diffstat (limited to 'src/core')
-rw-r--r--src/core/entity.cc92
-rw-r--r--src/core/entity.h53
-rw-r--r--src/core/gameserver.cc45
-rw-r--r--src/core/physics.h2
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
{