Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2012-11-25 21:25:40 +0000
committerStijn Buys <ingar@osirion.org>2012-11-25 21:25:40 +0000
commit3318b29475ffc5f462e2926f9b1141beca8305ae (patch)
tree15558ef704cf0aa8951618e52f7cd01769258bcc
parent438283d0029a6d82e1669b218a2481c5c4ea2dbd (diff)
Added core::Entity::Projectile.
-rw-r--r--src/core/Makefile.am2
-rw-r--r--src/core/entityprojectile.cc264
-rw-r--r--src/core/entityprojectile.h146
3 files changed, 412 insertions, 0 deletions
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 6f2a505..1a7c0ac 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -11,6 +11,7 @@ noinst_HEADERS = \
descriptions.h \
entity.h \
entityglobe.h \
+ entityprojectile.h \
extension.h \
func.h \
gameconnection.h \
@@ -46,6 +47,7 @@ libcore_la_SOURCES = \
descriptions.cc \
entity.cc \
entityglobe.cc \
+ entityprojectile.cc \
extension.cc \
func.cc \
gameconnection.cc \
diff --git a/src/core/entityprojectile.cc b/src/core/entityprojectile.cc
new file mode 100644
index 0000000..8c6c57b
--- /dev/null
+++ b/src/core/entityprojectile.cc
@@ -0,0 +1,264 @@
+/*
+ core/entityprojectile.cc
+ This file is part of the Osirion project and is distributed under
+ the terms and conditions of the GNU General Public License version 2
+*/
+
+#include "core/entityprojectile.h"
+#include "core/application.h"
+#include "math/functions.h"
+#include "sys/sys.h"
+
+#include <iomanip>
+
+namespace core
+{
+
+EntityProjectile::EntityProjectile() : EntityDynamic()
+{
+ set_label("projectile");
+ set_flag(Entity::KeepAlive);
+ set_shape(Entity::Sphere);
+ set_radius(0.01f);
+ set_mass(radius());
+
+ projectile_damage = 0.0f;
+ projectile_lifespan = 0.0f;
+ projectile_ownerid = 0;
+ projectile_timestamp = game()->timestamp();
+}
+
+EntityProjectile::EntityProjectile(std::istream & is) : EntityDynamic(is)
+{
+ set_label("projectile");
+ set_flag(Entity::KeepAlive);
+ set_shape(Entity::Sphere);
+ set_radius(0.01f);
+ set_mass(radius());
+
+ projectile_damage = 0.0f;
+ projectile_lifespan = 0.0f;
+ projectile_ownerid = 0;
+ projectile_timestamp = game()->timestamp();
+}
+
+EntityProjectile::~EntityProjectile()
+{
+
+}
+
+void EntityProjectile::upkeep(const unsigned long timestamp)
+{
+ die();
+}
+
+void EntityProjectile::collision(Entity *other)
+{
+ if (state() == Entity::Destroyed) {
+ return;
+ }
+
+ set_state(Entity::Destroyed);
+ // this method is a bullet callback, we can not reset() here
+}
+
+void EntityProjectile::frame(const unsigned long elapsed)
+{
+ // transfer bullet state to entity state
+ // do not set_dirty() as movement will be handled client-side
+ if (entity_body) {
+ body()->setLinearVelocity(math::to_btVector3(axis().forward() * speed()));
+
+ btTransform t;
+ entity_motionstate->getWorldTransform(t);
+ get_location().assign(t.getOrigin());
+ get_axis().assign(t.getBasis());
+ //entity_speed = (float) entity_body->getLinearVelocity().length();
+
+ }
+
+ if (projectile_timestamp + projectile_lifespan < game()->timestamp()) {
+ set_state(Entity::Destroyed);
+ set_speed(0.0f);
+ set_dirty();
+ }
+
+ if (state() == Entity::Destroyed) {
+ die();
+ }
+}
+
+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() == Entity::Docked) || (state() == 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()->setDamping(0.0f, 0.0f);
+ body()->setLinearVelocity(math::to_btVector3(axis().forward() * speed()));
+ body()->setAngularVelocity(btVector3(0.0f, 0.0f, 0.0f));
+ body()->setWorldTransform(t);
+ body()->clearForces();
+
+ if (motionstate()) {
+ motionstate()->setWorldTransform(t);
+ }
+
+ set_dirty();
+}
+
+void EntityProjectile::set_projectile_modelname(const std::string modelname)
+{
+ projectile_modelname_str.assign(modelname);
+ set_modelname("maps/projectiles/" + modelname);
+}
+
+void EntityProjectile::serialize_server_create(std::ostream & os) const
+{
+ os << moduletype() << " ";
+ os << flags() << " ";
+ os << (zone() ? zone()->id() : 0) << " ";
+ os << std::setprecision(8) << location() << " ";
+ os << color() << " ";
+ os << color_second() << " ";
+ os << radius() << " ";
+ os << std::setprecision(8) << axis().forward() << " ";
+ os << std::setprecision(8) << axis().left() << " ";
+ os << "\"" << projectile_modelname() << "\" ";
+ os << roundf(speed() * 100.0f) << " ";
+ os << state() << " ";;
+ os << lifespan() << " ";
+ os << ownerid() << " ";
+}
+
+void EntityProjectile::receive_server_create(std::istream &is)
+{
+ is >> entity_moduletypeid;
+
+ unsigned int f;
+ is >> f;
+ set_flags(f);
+
+ unsigned int zo;
+ is >> zo;
+ set_zone(Zone::find(zo));
+ if (entity_zone && !zo) {
+ con_warn << "Received entity " << id() << " for unknown zone " << zo << "!" << std::endl;
+ }
+
+ is >> get_location();
+ is >> get_color();
+ is >> get_color_second();
+
+ float r;
+ is >> r;
+ set_radius(r)
+ ;
+ is >> get_axis()[0];
+ is >> get_axis()[1];
+ get_axis()[2].assign(math::crossproduct(axis().forward(), axis().left()));
+
+ // read projectile modelname
+ std::string n;
+ char c;
+ n.clear();
+ while ((is.get(c)) && (c != '"'));
+ while ((is.get(c)) && (c != '"'))
+ n += c;
+ set_projectile_modelname(n);
+
+ is >> entity_speed;
+ entity_speed /= 100.0f;
+
+ is >> entity_state;
+ is >> projectile_lifespan;
+ is >> projectile_ownerid;
+
+ set_dirty(false);
+}
+
+} // namespace core
+
diff --git a/src/core/entityprojectile.h b/src/core/entityprojectile.h
new file mode 100644
index 0000000..04070ff
--- /dev/null
+++ b/src/core/entityprojectile.h
@@ -0,0 +1,146 @@
+/*
+ core/entityprojectile.h
+ This file is part of the Osirion project and is distributed under
+ the terms and conditions of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_CORE_PROJECTILE_H__
+#define __INCLUDED_CORE_PROJECTILE_H__
+
+#include "core/entity.h"
+
+namespace core
+{
+
+class EntityProjectile : public core::EntityDynamic
+{
+public:
+ EntityProjectile();
+ EntityProjectile(std::istream & is);
+
+ virtual ~EntityProjectile();
+
+ virtual void upkeep(const unsigned long timestamp);
+
+ virtual void collision(Entity *other);
+
+ virtual void frame(const unsigned long elapsed);
+
+ /* --- inspectors ------------------------------------------ */
+
+ /**
+ * @brief core type id
+ * */
+ virtual inline const unsigned int type() const {
+ return Projectile;
+ }
+
+ inline const unsigned long timestamp() const
+ {
+ return projectile_timestamp;
+ }
+
+ /**
+ * @brief the lifespan of this projectile, in milliseconds
+ * */
+ inline const unsigned long lifespan() const
+ {
+ return projectile_lifespan;
+ }
+
+ /**
+ * @brief the amount of damage this projectile inflicts
+ * */
+ inline const float damage() const
+ {
+ return projectile_damage;
+ }
+
+ /**
+ * @brief id of the player who fired the projectile
+ * */
+ inline const int ownerid() const
+ {
+ return projectile_ownerid;
+ }
+
+ /**
+ * @brief return the projectile modelname
+ * */
+ inline const std::string & projectile_modelname() const
+ {
+ return projectile_modelname_str;
+ }
+
+ /*----- serializers ----------------------------------------------- */
+
+ /**
+ * @brief serialize the entity to a stream
+ * */
+ virtual void serialize_server_create(std::ostream & os) const;
+
+ /*----- mutators -------------------------------------------------- */
+
+ /**
+ * @brief receive a server-to-client create from a stream
+ * */
+ virtual void receive_server_create(std::istream &is);
+
+ /**
+ * @brief reset physics state
+ * */
+ virtual void reset();
+
+ /**
+ * @brief set the amount of damage this projectile inflicts
+ * */
+ inline void set_damage(const float damage)
+ {
+ projectile_damage = damage;
+ }
+
+ /**
+ * @brief set the lifespan of the projectile
+ * */
+ inline void set_lifespan(const unsigned long lifespan)
+ {
+ projectile_lifespan = lifespan;
+ }
+
+ /**
+ * @brief set the id of the player who fired the projectile
+ * */
+ inline void set_ownerid(const int ownerid)
+ {
+ projectile_ownerid = ownerid;
+ }
+
+ /**
+ * @brief set the projectile timestamp
+ * */
+ inline void set_timestamp(const unsigned int timestamp)
+ {
+ projectile_timestamp = timestamp;
+ }
+
+ /**
+ * @brief set the projectile modelname
+ * */
+ void set_projectile_modelname(const std::string modelname);
+
+private:
+ unsigned long projectile_timestamp;
+
+ unsigned long projectile_lifespan;
+
+ std::string projectile_modelname_str;
+
+ float projectile_damage;
+
+ int projectile_ownerid;
+};
+
+} // namespace game
+
+#endif // __INCLUDED_CORE_PROJECTILE_H__
+