diff options
Diffstat (limited to 'src/game/base/projectile.cc')
-rw-r--r-- | src/game/base/projectile.cc | 115 |
1 files changed, 108 insertions, 7 deletions
diff --git a/src/game/base/projectile.cc b/src/game/base/projectile.cc index 6bcbad9..4dd483d 100644 --- a/src/game/base/projectile.cc +++ b/src/game/base/projectile.cc @@ -13,16 +13,16 @@ namespace game { -Projectile::Projectile(unsigned long lifespan) : EntityDynamic() +EntityProjectile::EntityProjectile(unsigned long lifespan) : EntityDynamic() { entity_moduletypeid = projectile_enttype; //set_name(""); - //set_label(""); + set_label("projectile"); //set_serverside(true); set_flag(core::Entity::KeepAlive); set_shape(core::Entity::Sphere); - set_radius(0.02f); + set_radius(0.01f); set_mass(radius()); //reset(); @@ -36,17 +36,17 @@ Projectile::Projectile(unsigned long lifespan) : EntityDynamic() projectile_ownerid = 0; } -Projectile::~Projectile() +EntityProjectile::~EntityProjectile() { } -void Projectile::upkeep(const unsigned long timestamp) +void EntityProjectile::upkeep(const unsigned long timestamp) { die(); } -void Projectile::collision(core::Entity *other) +void EntityProjectile::collision(core::Entity *other) { if (state() == core::Entity::Destroyed) { return; @@ -56,7 +56,7 @@ void Projectile::collision(core::Entity *other) // this method is a bullet callback, we can not reset() here } -void Projectile::frame(const unsigned long elapsed) +void EntityProjectile::frame(const unsigned long elapsed) { EntityDynamic::frame(elapsed); @@ -69,5 +69,106 @@ void Projectile::frame(const unsigned long elapsed) } } +void EntityProjectile::reset() +{ + // no bullet physics on NonSolid entities + if (!radius() || has_flag(NonSolid)) { + return; + } + + // remove Docked and Destroyed entities from the physics simulation + if (destroyed() || (state() == core::Entity::Docked) || (state() == core::Entity::Destroyed)) { + + if (entity_body) { + + if (entity_motionstate) { + delete entity_motionstate; + entity_motionstate = 0; + } + + if (zone() && zone()->physics()) { + entity_zone->physics()->removeRigidBody(body()); + } + + if (entity_collision_shape) { + delete entity_collision_shape; + entity_collision_shape = 0; + } + + for (CollisionShapes::iterator sit = entity_collision_child_shapes.begin(); sit != entity_collision_child_shapes.end(); sit++) { + delete (*sit); + (*sit) = 0; + } + entity_collision_child_shapes.clear(); + + if (entity_body) { + delete entity_body; + entity_body = 0; + } + + if (entity_body_info) { + delete entity_body_info; + entity_body_info = 0; + } + } + + return; + } + + // location and orientation + btTransform t; + t.setIdentity(); + t.setOrigin(to_btVector3(location())); + t.setBasis(to_btMatrix3x3(axis())); + + // construct physics body if necessary + if (!entity_body) { + // use a sphere with a radius matching the entity + btSphereShape *sphereshape = new btSphereShape(radius()); + entity_collision_shape = sphereshape; + + // set margin + //entity_collision_shape->setMargin(core::Cvar::sv_collisionmargin->value()); + + // calculate inertia + btVector3 inertia(0, 0, 0); + if (entity_mass) + entity_collision_shape->calculateLocalInertia(entity_mass, inertia); + + // create motion state + entity_motionstate = new btDefaultMotionState(t); + + // create physics body + entity_body_info = new btRigidBody::btRigidBodyConstructionInfo(entity_mass, entity_motionstate, entity_collision_shape, inertia); + entity_body = new btRigidBody(*entity_body_info); + // point the bullet user pointer to the entity + entity_body->setUserPointer((void *) this); + // enable custom collision callback + entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + //entity_body->setCollisionFlags(entity_body->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); + + if (entity_mass) { + entity_body->setActivationState(DISABLE_DEACTIVATION); + } else { + entity_body->setActivationState(ISLAND_SLEEPING); + } + + if (zone()) + zone()->physics()->addRigidBody(entity_body); + } + + // transfer entity location to motion state + body()->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); + body()->setAngularVelocity(btVector3(0.0f, 0.0f, 0.0f)); + body()->setWorldTransform(t); + body()->clearForces(); + + if (motionstate()) { + motionstate()->setWorldTransform(t); + } + + set_dirty(); +} + } // namespace game |