/* base/spacemine.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 "base/spacemine.h" #include "base/game.h" #include "math/functions.h" namespace game { SpaceMine::SpaceMine() : EntityDynamic() { entity_moduletypeid = spacemine_enttype; set_name("Space mine"); set_label("spacemine"); set_flag(core::Entity::KeepAlive); /* // setting set_radius(0); // use template settings if available if (cargopod_template) { cargopod_template->apply(this); } // radius fallback if (!radius()) { if (model()->radius()) { set_radius(model()->radius()); } else { set_radius(0.1f); } } */ // FIXME should be loaded from the Weapon Info set_shape(core::Entity::Sphere); set_modelname("maps/static/cargopod001"); set_radius(0.10f); spacemine_detonated_timestamp = 0; // activate physics set_mass(radius()); reset(); const float damp = Game::g_damping->value(); body()->setDamping(damp, damp); } SpaceMine::~SpaceMine() { } void SpaceMine::upkeep(const unsigned long timestamp) { // space mines dissapear on upkeep die(); } void SpaceMine::collision(core::Entity *other) { if (state() == core::Entity::Destroyed) { return; } // mines explode on impact if ((other->type() == core::Entity::Dynamic) || (other->type() == core::Entity::Controlable)) { core::EntityDynamic *entity = static_cast(other); math::Vector3f explosion_direction(entity->location() - location()); explosion_direction.normalize(); math::Vector3f explosion_torque(math::randomf(2.0f) - 1.0f, math::randomf(2.0f) - 1.0f, math::randomf(2.0f) - 1.0f); explosion_torque.normalize(); const float force = math::max(entity->mass(), entity->radius() * 100.0f); entity->body()->applyCentralImpulse(math::to_btVector3(explosion_direction * force )); entity->body()->applyTorqueImpulse(math::to_btVector3(explosion_torque * force * 0.1f)); spacemine_detonated_timestamp = core::game()->time(); } set_state(core::Entity::Destroyed); // this method is a bullet callback, we can not reset() here } void SpaceMine::frame(const unsigned long elapsed) { EntityDynamic::frame(elapsed); if (state() == core::Entity::Destroyed) { if (body()) { reset(); } if (core::game()->time() - spacemine_detonated_timestamp > 5) { die(); } } } // main 'eject mine' function void SpaceMine::eject(core::EntityControlable *ejector) { if (!ejector->inventory()) { return; } if ((ejector->state() == core::Entity::Jump) || (ejector->state() == core::Entity::JumpInitiate)) { if (ejector->owner()) { ejector->owner()->send("^WCan not eject while hyperspace jump drive is active!"); } return; } else if ((ejector->state() == core::Entity::Impulse) || (ejector->state() == core::Entity::ImpulseInitiate)) { if (ejector->owner()) { ejector->owner()->send("^WCan not eject at impulse speed!"); } return; } else if (ejector->state() != core::Entity::Normal) { return; } // create space mine SpaceMine *spacemine = new SpaceMine(); spacemine->set_color(ejector->color()); spacemine->set_color_second(ejector->color_second()); spacemine->set_location(ejector->location() - ejector->axis().forward() * (ejector->radius() + spacemine->radius())); spacemine->set_axis(ejector->axis()); spacemine->set_zone(ejector->zone()); if (ejector->owner()) { ejector->owner()->send("Spacemine ejected"); ejector->owner()->sound("fx/eject"); } spacemine->reset(); } } // namespace game