Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2012-11-25 12:06:13 +0000
committerStijn Buys <ingar@osirion.org>2012-11-25 12:06:13 +0000
commitd8be908233fd7b85492d7a9e87f07bb207173990 (patch)
tree70d9103a867688838fc517290bb370366c69fedb /src/game
parentedc5ddce817244111b302e449c28a052f2746cc4 (diff)
Moved core::EntityGlobe into a separate file,
added various methods to core::Item and core::Slot, added r_slots cvar to draw entity slots and docks, added game methods for mounting and umounting of weapons, added playerlist to chat window.
Diffstat (limited to 'src/game')
-rw-r--r--src/game/base/game.cc155
-rw-r--r--src/game/base/game.h2
-rw-r--r--src/game/base/planet.h2
-rw-r--r--src/game/base/projectile.cc115
-rw-r--r--src/game/base/projectile.h13
-rw-r--r--src/game/base/ship.cc17
-rw-r--r--src/game/base/shipmodel.cc7
-rw-r--r--src/game/base/star.h2
-rw-r--r--src/game/base/weapon.h8
-rw-r--r--src/game/intro/intro.cc2
10 files changed, 295 insertions, 28 deletions
diff --git a/src/game/base/game.cc b/src/game/base/game.cc
index 2355a9e..1020fa8 100644
--- a/src/game/base/game.cc
+++ b/src/game/base/game.cc
@@ -340,9 +340,10 @@ void Game::func_give(core::Player *player, const std::string &args)
}
// transfer inventory
- for (core::Inventory::Items::iterator it = player->control()->inventory()->items().begin();
- it != player->control()->inventory()->items().end(); it++) {
- ship->inventory()->add(new core::Item(*(*it)));
+ for (core::Inventory::Items::iterator it = player->control()->inventory()->items().begin(); it != player->control()->inventory()->items().end(); it++) {
+ core::Item *item = new core::Item(*(*it));
+ item->unset_flag(core::Item::Mounted);
+ ship->inventory()->add(item);
}
ship->inventory()->set_dirty();
@@ -973,7 +974,7 @@ void Game::func_drop(core::Player *player, const std::string &args)
// cannot drop items while jumping
if ((ship->state() == core::Entity::Jump) || (ship->state() == core::Entity::JumpInitiate)) {
- player->send("^WCan not eject while hyperspace jump drive is active");
+ player->send("^WCan not drop items while hyperspace jump drive is active");
return;
}
@@ -1112,9 +1113,10 @@ void Game::func_eject(core::Player *player, const std::string &args)
pod->add_inventory();
pod->inventory()->set_capacity(item->info()->volume() * amount);
- core::Item *loot = new core::Item(item->info());
+ core::Item *loot = new core::Item(item->info());
loot->set_amount(amount);
loot->set_flags(item->flags());
+ loot->unset_flag(core::Item::Mounted);
pod->inventory()->add(loot);
pod->inventory()->set_dirty();
@@ -1134,11 +1136,147 @@ void Game::func_eject(core::Player *player, const std::string &args)
}
if (item->amount() == 0) {
+ if (item->has_flag(core::Item::Mounted)) {
+ // unmount
+ core::Slot *slot = 0;
+
+ for(core::Slots::iterator it = ejector->slots()->begin(); (!slot) && (it != ejector->slots()->end()); ++it) {
+ if ((*it)->item() == item) {
+ slot = (*it);
+ }
+ }
+
+ if (slot) {
+ slot->set_item(0);
+ slot->unset_flag(core::Slot::Active);
+ slot->unset_flag(core::Slot::Mounted);
+ item->unset_flag(core::Item::Mounted);
+ }
+
+ }
ejector->inventory()->erase(item->id());
}
ejector->inventory()->set_dirty();
}
+// mount weapons into slots
+void Game::func_mount(core::Player *player, const std::string &args)
+{
+ if (!player->control()) {
+ return;
+ }
+
+ Ship *ship = static_cast<Ship *>(player->control());
+
+ if (!ship->slots()) {
+ return;
+ }
+
+ std::istringstream is(args);
+ unsigned int id = 0;
+
+ if (!(is >> id)) {
+ ship->owner()->send("Usage: mount [id] mount weapon with id into the first available slot");
+ return;
+ }
+
+ // find item to be mounted
+ core::Item *item = ship->inventory()->find(id);
+ if (!item) {
+ if (ship->owner()) {
+ std::stringstream msgstr;
+ msgstr << "^WItem " << id << " not in inventory";
+ ship->owner()->send(msgstr.str());
+ }
+ return;
+ }
+
+ // verify item is mountable
+ if (item->info()->type() != Weapon::infotype()) {
+ if (ship->owner()) {
+ std::stringstream msgstr;
+ msgstr << "^WItem " << id << " can not be mounted";
+ ship->owner()->send(msgstr.str());
+ }
+ return;
+ }
+ const Weapon *weapon = static_cast<const Weapon *>(item->info());
+
+ if (!item->unique() || (weapon->subtype() != Weapon::Cannon)) {
+ if (ship->owner()) {
+ std::stringstream msgstr;
+ msgstr << "^WItem " << id << " can not be mounted";
+ ship->owner()->send(msgstr.str());
+ }
+ return;
+ }
+
+ if (item->has_flag(core::Item::Mounted)) {
+ // unmount
+ core::Slot *slot = 0;
+
+ for(core::Slots::iterator it = ship->slots()->begin(); (!slot) && (it != ship->slots()->end()); ++it) {
+ if ((*it)->item() == item) {
+ slot = (*it);
+ }
+ }
+
+ if (slot) {
+ slot->set_item(0);
+ slot->unset_flag(core::Slot::Active);
+ slot->unset_flag(core::Slot::Mounted);
+ item->unset_flag(core::Item::Mounted);
+
+ if (ship->owner()) {
+ std::stringstream msgstr;
+ msgstr << "^BUnmounted " << weapon->name();
+ ship->owner()->send(msgstr.str());
+ }
+ }
+
+ } else {
+ // mount
+ core::Slot *slot = 0;
+
+ for(core::Slots::iterator it = ship->slots()->begin(); (!slot) && (it != ship->slots()->end()); ++it) {
+ if (!(*it)->has_flag(core::Slot::Mounted)) {
+ slot = (*it);
+ }
+ }
+
+ if (!slot) {
+ if (ship->owner()) {
+ std::stringstream msgstr;
+ msgstr << "^WNo slot available to mount item " << id;
+ ship->owner()->send(msgstr.str());
+ }
+ return;
+ } else {
+ slot->set_item(item);
+ slot->set_flag(core::Slot::Active);
+ slot->set_flag(core::Slot::Mounted);
+ item->set_flag(core::Item::Mounted);
+
+ slot->set_projectile_damage(weapon->damage());
+ slot->set_projectile_speed(weapon->projectile_speed());
+ slot->set_projectile_lifespan(weapon->projectile_lifespan());
+ slot->set_projectile_interval(weapon->projectile_interval());
+ slot->set_projectile_modelname(weapon->projectile_modelname());
+
+ if (ship->owner()) {
+ std::stringstream msgstr;
+ msgstr << "^BMounted " << weapon->name();
+ ship->owner()->send(msgstr.str());
+ }
+ }
+ }
+}
+
+// unmount weapons from slots
+void Game::func_unmount(core::Player *player, const std::string &args)
+{
+}
+
// beam in nearby cargo pods
void Game::func_beam(core::Player *player, const std::string &args)
{
@@ -1180,6 +1318,8 @@ void Game::func_beam(core::Player *player, const std::string &args)
}
if (!iteminv) {
iteminv = new core::Item(item->info());
+ iteminv->set_flags(item->flags());
+ iteminv->unset_flag(core::Item::Mounted);
inventory->add(iteminv);
}
item->dec_amount(negotiated_amount);
@@ -1424,7 +1564,10 @@ Game::Game() : core::Module("Project::OSiRiON", true)
func->set_info("[label] drop an item and activate it");
func = core::Func::add("eject", Game::func_eject);
- func->set_info("[string] [string] [int] eject an item from inventory: specify type, label and amount");
+ func->set_info("[int] eject item with id from inventory");
+
+ func = core::Func::add("mount", Game::func_mount);
+ func->set_info("[int] mount a weapon into the first available slot");
func = core::Func::add("beam", Game::func_beam);
func->set_info("beam nearby cargo pods in");
diff --git a/src/game/base/game.h b/src/game/base/game.h
index d030367..f535ec9 100644
--- a/src/game/base/game.h
+++ b/src/game/base/game.h
@@ -133,6 +133,8 @@ private:
static void func_specs(core::Player *player, const std::string &args);
static void func_eject(core::Player *player, const std::string &args);
static void func_drop(core::Player *player, std::string const &args);
+ static void func_mount(core::Player *player, const std::string &args);
+ static void func_unmount(core::Player *player, const std::string &args);
static void func_beam(core::Player *player, const std::string &args);
/* ---- target functions ----------------------------------- */
diff --git a/src/game/base/planet.h b/src/game/base/planet.h
index 337bab2..6b97d40 100644
--- a/src/game/base/planet.h
+++ b/src/game/base/planet.h
@@ -7,7 +7,7 @@
#ifndef __INCLUDED_BASE_PLANET_H__
#define __INCLUDED_BASE_PLANET_H__
-#include "core/entity.h"
+#include "core/entityglobe.h"
#include "math/mathlib.h"
#include <string>
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
diff --git a/src/game/base/projectile.h b/src/game/base/projectile.h
index f9cda64..2513901 100644
--- a/src/game/base/projectile.h
+++ b/src/game/base/projectile.h
@@ -1,5 +1,5 @@
/*
- base/spacemine.h
+ base/projectile.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
*/
@@ -12,11 +12,11 @@
namespace game
{
-class Projectile : public core::EntityDynamic
+class EntityProjectile : public core::EntityDynamic
{
public:
- Projectile(unsigned long lifespan);
- virtual ~Projectile();
+ EntityProjectile(unsigned long lifespan);
+ virtual ~EntityProjectile();
virtual void upkeep(const unsigned long timestamp);
@@ -58,6 +58,11 @@ public:
/* --- mutators -------------------------------------------- */
/**
+ * @brief reset physics state
+ * */
+ virtual void reset();
+
+ /**
* @brief set the amount of damage this projectile inflicts
* */
inline void set_damage(const float damage)
diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc
index 7282fe1..fc01b5c 100644
--- a/src/game/base/ship.cc
+++ b/src/game/base/ship.cc
@@ -9,13 +9,15 @@
#include <iostream>
#include "auxiliary/functions.h"
+#include "math/functions.h"
+
#include "core/gameserver.h"
#include "core/entity.h"
+
#include "base/game.h"
#include "base/ship.h"
#include "base/projectile.h"
#include "base/spacemine.h"
-#include "math/functions.h"
using math::degrees360f;
using math::degrees180f;
@@ -85,14 +87,16 @@ Ship::Ship(core::Player *owner, const ShipModel *shipmodel) : core::EntityContro
if (model()) {
add_slots();
slots()->load(model());
-
+/*
for (core::Slots::iterator it = slots()->begin(); it != slots()->end(); it++) {
// default fire rate: 1 projectile / second
(*it)->set_projectile_interval(1000);
(*it)->set_projectile_lifespan(5000);
(*it)->set_projectile_speed(5.0f);
(*it)->set_projectile_damage(10.0f);
+ (*it)->set_projectile_modelname("laser1");
}
+*/
}
// menus for docked players
@@ -529,7 +533,7 @@ void Ship::collision(core::Entity *other)
} else if (other->moduletype() == projectile_enttype) {
// hit by projectile
- Projectile * projectile = static_cast<Projectile *>(other);
+ game::EntityProjectile *projectile = static_cast<EntityProjectile *>(other);
if (projectile->state() != core::Entity::Destroyed) {
ship_armor -= projectile->damage();
}
@@ -877,10 +881,10 @@ void Ship::frame(const unsigned long elapsed)
for (core::Slots::iterator it = slots()->begin(); it != slots()->end(); it++) {
// create projectiles
- if ((*it)->projectile_interval() > 0) {
+ if ( ((*it)->projectile_interval() > 0) && ((*it)->has_flag(core::Slot::Mounted)) && ((*it)->has_flag(core::Slot::Active))) {
if ((*it)->last_fired() + (*it)->projectile_interval() <= core::server()->timestamp()) {
(*it)->set_last_fired(core::server()->timestamp());
- Projectile * projectile = new Projectile((*it)->projectile_lifespan());
+ EntityProjectile * projectile = new EntityProjectile((*it)->projectile_lifespan());
projectile->set_damage((*it)->projectile_damage());
projectile->set_color(color());
if (owner()) {
@@ -889,7 +893,8 @@ void Ship::frame(const unsigned long elapsed)
projectile->set_zone(zone());
projectile->set_axis(axis() * (*it)->axis());
projectile->set_location(location() + (axis() * (*it)->location() * modelscale) + projectile->axis().forward() * projectile->radius());
-
+ projectile->set_modelname("maps/projectiles/" + (*it)->projectile_modelname());
+
projectile->reset();
projectile->body()->setDamping(0.0f, 0.0f);
projectile->body()->setLinearVelocity(math::to_btVector3(projectile->axis().forward() * (*it)->projectile_speed()));
diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc
index fe8889d..ba01765 100644
--- a/src/game/base/shipmodel.cc
+++ b/src/game/base/shipmodel.cc
@@ -337,9 +337,10 @@ void ShipModel::buy(core::EntityControlable *buyer, core::Entity *seller)
//ship->reset(); // reset() is done by set_dock()
// transfer inventory
- for (core::Inventory::Items::iterator it = player->control()->inventory()->items().begin();
- it != player->control()->inventory()->items().end(); it++) {
- ship->inventory()->add(new core::Item(*(*it)));
+ for (core::Inventory::Items::iterator it = player->control()->inventory()->items().begin(); it != player->control()->inventory()->items().end(); it++) {
+ core::Item *item = new core::Item(*(*it));
+ item->unset_flag(core::Item::Mounted);
+ ship->inventory()->add(item);
}
ship->inventory()->set_dirty();
diff --git a/src/game/base/star.h b/src/game/base/star.h
index 12bec07..1e45dbb 100644
--- a/src/game/base/star.h
+++ b/src/game/base/star.h
@@ -8,7 +8,7 @@
#define __INCLUDED_BASE_STAR_H__
// project headers
-#include "core/entity.h"
+#include "core/entityglobe.h"
#include "math/mathlib.h"
// C++ headers
diff --git a/src/game/base/weapon.h b/src/game/base/weapon.h
index 94fdce6..b4a790c 100644
--- a/src/game/base/weapon.h
+++ b/src/game/base/weapon.h
@@ -45,6 +45,14 @@ public:
}
/**
+ * @brief lifespan of projectiles generated by this weapon, in milliseconds
+ * */
+ inline const unsigned long projectile_lifespan() const
+ {
+ return weapon_projectile_lifespan;
+ }
+
+ /**
* @brief speed of projectiles generated by this weapon
* */
inline const float projectile_speed() const
diff --git a/src/game/intro/intro.cc b/src/game/intro/intro.cc
index f5f7ab2..028a134 100644
--- a/src/game/intro/intro.cc
+++ b/src/game/intro/intro.cc
@@ -6,6 +6,8 @@
#include "intro/intro.h"
#include "core/core.h"
+#include "core/entity.h"
+#include "core/entityglobe.h"
#include "core/parser.h"
#include "filesystem/filesystem.h"
#include "filesystem/inifile.h"