diff options
Diffstat (limited to 'src/game')
| -rw-r--r-- | src/game/base/game.cc | 155 | ||||
| -rw-r--r-- | src/game/base/game.h | 2 | ||||
| -rw-r--r-- | src/game/base/planet.h | 2 | ||||
| -rw-r--r-- | src/game/base/projectile.cc | 115 | ||||
| -rw-r--r-- | src/game/base/projectile.h | 13 | ||||
| -rw-r--r-- | src/game/base/ship.cc | 17 | ||||
| -rw-r--r-- | src/game/base/shipmodel.cc | 7 | ||||
| -rw-r--r-- | src/game/base/star.h | 2 | ||||
| -rw-r--r-- | src/game/base/weapon.h | 8 | ||||
| -rw-r--r-- | src/game/intro/intro.cc | 2 | 
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" | 
