/* * ORXONOX - the hottest 3D action shooter ever to exist * > www.orxonox.net < * * * License notice: * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Author: * Vedat Aydin * Co-authors: * ... * */ #include "ExplosionPart.h" #include "core/XMLPort.h" namespace orxonox { RegisterClass(ExplosionPart); ExplosionPart::ExplosionPart(Context* context) : MovableEntity(context) { RegisterObject(ExplosionPart); this->bStop_ = false; this->LOD_ = LODParticle::Normal; this->mesh_ = ""; this->effect1_ = ""; this->effect2_ = ""; this->model_= new Model(this->getContext()); this->effect1Particle_= nullptr; this->effect2Particle_= nullptr; this->explosionEntity_ = new MovableEntity(this->getContext()); this->posOffset_ = Vector3::ZERO; } ExplosionPart::~ExplosionPart() { if (this->isInitialized()) { if (this->effect1Particle_) { this->model_->detachOgreObject(this->effect1Particle_->getParticleSystem()); delete this->effect1Particle_; } if (this->effect2Particle_) { this->model_->detachOgreObject(this->effect2Particle_->getParticleSystem()); delete this->effect2Particle_; } } } void ExplosionPart::XMLPort(Element& xmlelement, XMLPort::Mode mode) { SUPER(ExplosionPart, XMLPort, xmlelement, mode); XMLPortParam(ExplosionPart, "mesh", setMesh, getMesh, xmlelement, mode).defaultValues(""); //Define mesh file, that is going to fly out XMLPortParam(ExplosionPart, "minspeed", setMinSpeed, getMinSpeed, xmlelement, mode).defaultValues(50); //Minimum velocity at which parts fly out XMLPortParam(ExplosionPart, "maxspeed", setMaxSpeed, getMaxSpeed, xmlelement, mode).defaultValues(100); //Maximum velocity at which parts fly out, set both minspeed and maxspeed to 0 to have stationary effects XMLPortParam(ExplosionPart, "effect1", setEffect1, getEffect1, xmlelement, mode).defaultValues(""); //particle effect 1 XMLPortParam(ExplosionPart, "effect2", setEffect2, getEffect2, xmlelement, mode).defaultValues(""); //particle effect 2 XMLPortParam(ExplosionPart, "offset", setOffset, getOffset, xmlelement, mode).defaultValues(Vector3::ZERO); //Offset of the position if you need to have an explosion off-center XMLPortParam(ExplosionPart, "direction", setDirection, getDirection, xmlelement, mode).defaultValues(Vector3(1,1,1)); //general direction the parts fly in XMLPortParam(ExplosionPart, "angle", setAngle, getAngle, xmlelement, mode).defaultValues(180); //defines a cone shape with direction "direction" and angle "angle" inside which the parts fly out of XMLPortParam(ExplosionPart, "delay", setDelay, getDelay, xmlelement, mode).defaultValues(0); //delay to the explosion in seconds } void ExplosionPart::Explode() { this->destroyTimer_.setTimer(delay_, false, createExecutor(createFunctor(&ExplosionPart::ActuallyExplode, this))); } void ExplosionPart::stop() { if (this->effect1Particle_) this->effect1Particle_->setEnabled(false); if (this->effect2Particle_) this->effect2Particle_->setEnabled(false); if (this->model_) this->model_->setVisible(false); if (GameMode::isMaster()) { this->bStop_ = true; this->destroyTimer_.setTimer(1.0f, false, createExecutor(createFunctor(&ExplosionPart::destroy, this))); } } void ExplosionPart::ActuallyExplode() { this->model_->setVisible(true); //this->explosionEntity_->setSyncMode(0); //this->model_->setSyncMode(0); if(effect1_ != "") { this->effect1Particle_ = new ParticleInterface(this->getScene()->getSceneManager(), effect1_, this->LOD_); this->effect1Particle_->setDimensions(this->getScale()); this->model_->attachOgreObject(this->effect1Particle_->getParticleSystem()); } if(effect2_ != "") { this->effect2Particle_ = new ParticleInterface(this->getScene()->getSceneManager(), effect2_, this->LOD_); this->effect2Particle_->setDimensions(this->getScale()); this->model_->attachOgreObject(this->effect2Particle_->getParticleSystem()); } Vector3 velocityOffset = direction_.perpendicular(); velocityOffset.normalise(); Degree offsetDirection = Degree(rnd(0,360)); velocityOffset = Quaternion(offsetDirection, direction_.normalisedCopy()) * velocityOffset; velocityOffset.normalise(); direction_.normalise(); Vector3 finalDirection = direction_ + sin((rnd(0, angle_))*math::pi/180)*velocityOffset; this->explosionEntity_->setVelocity(finalDirection*rnd(minSpeed_,maxSpeed_)); this->explosionEntity_->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians()); this->explosionEntity_->setScale(this->getScale() * 4); this->explosionEntity_->attach(model_); this->attach(explosionEntity_); if (GameMode::isMaster()) { this->destroyTimer_.setTimer(rnd(2, 4), false, createExecutor(createFunctor(&ExplosionPart::stop, this))); } } void ExplosionPart::setMesh(const std::string& newString) { if(newString != "") { this->mesh_ = newString; this->model_->setMeshSource(mesh_); this->model_->setVisible(false); } } void ExplosionPart::setEffect1(const std::string& newString) { this->effect1_ = newString; } void ExplosionPart::setEffect2(const std::string& newString) { this->effect2_ = newString; } void ExplosionPart::setMinSpeed(float speed) { this->minSpeed_ = speed; } void ExplosionPart::setMaxSpeed(float speed) { this->maxSpeed_ = speed; } void ExplosionPart::setOffset(Vector3 newVector) { this->posOffset_ = newVector; this->explosionEntity_->setPosition(this->getPosition() + this->posOffset_ / this->getScale()); } void ExplosionPart::setDirection(Vector3 newDirection) { this->direction_ = newDirection; } void ExplosionPart::setAngle(float newAngle) { this->angle_ = newAngle; } void ExplosionPart::setDelay(float newDelay) { this->delay_ = newDelay; } std::string& ExplosionPart::getMesh() { return this->mesh_; } std::string& ExplosionPart::getEffect1() { return this->effect1_; } std::string& ExplosionPart::getEffect2() { return this->effect2_; } float ExplosionPart::getMinSpeed() { return this->minSpeed_; } float ExplosionPart::getMaxSpeed() { return this->maxSpeed_; } Vector3 ExplosionPart::getOffset() { return this->posOffset_; } Vector3 ExplosionPart::getDirection() { return direction_; } float ExplosionPart::getAngle() { return angle_; } float ExplosionPart::getDelay() { return delay_; } }