/* 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 "math/functions.h" #include "core/entityprojectile.h" #include "core/gameserver.h" #include "base/spacemine.h" #include "base/game.h" namespace game { const Template *SpaceMine::spacemine_template = 0; SpaceMine::SpaceMine(const Weapon *weapon) : EntityDynamic() { entity_moduletypeid = spacemine_enttype; set_name("Space mine"); set_label("spacemine"); set_flag(core::Entity::KeepAlive); set_shape(core::Entity::Sphere); // setting set_radius(0); set_damage(0.0f); // use template settings if available if (spacemine_template) { spacemine_template->apply(this); } // item type model overrides template if (weapon) { set_info(weapon); if (weapon->modelname().size()) { set_modelname(weapon->modelname()); } set_name(weapon->name()); set_label(weapon->label()); set_damage(weapon->damage()); } // radius fallback if (!radius()) { if (model()->radius()) { set_radius(model()->radius()); } else { set_radius(0.1f); } } 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)); entity->hit(this); } else if (other->type() == core::Entity::Projectile) { // hit by projectile core::EntityProjectile *projectile = static_cast(other); core::Player *assassin = 0; if (projectile->owner_id()) { assassin = core::server()->find_player(projectile->owner_id()); } // send hit sound to assassin if (assassin) { assassin->sound("game/target_hit"); } } 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(); } // stay alive for 10 more seconds while explosion particles are drawn if (spacemine_detonated_timestamp + 10.0f < core::game()->time()) { die(); } } } } // namespace game