/* * 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: * Fabian 'x3n' Landau * Co-authors: * ... * */ /** @file ParticleProjectile.h @brief Implementation of the ParticleProjectile class. */ #include "BallProjectile.h" #include "gametypes/Gametype.h" #include #include "core/CoreIncludes.h" #include "tools/ParticleInterface.h" #include "Scene.h" #include "core/command/Executor.h" #include "util/Convert.h" #include #include namespace orxonox { RegisterClass(BallProjectile); BallProjectile::BallProjectile(Context* context) : BillboardProjectile(context) { RegisterObject(BallProjectile); this->textureIndex_ = 1; this->setMass(0.1f); this->maxTextureIndex_ = 8; this->setDestroyAfterCollision(false); //I want the ball to bounce, not to be destroyed this->fieldWidth_ = 46; this->fieldHeight_ = 49; this->orxoblox_ = this->getOrxoBlox(); this->setCollisionShapeRadius(2.5); //setEffect("Orxonox/sparks2"); } void BallProjectile::registerVariables() { registerVariable(this->materialBase_); registerVariable( this->speed_ ); } /** @brief Set the material. @param material The name of the material. Material names with 1 to 8 appended must exist. */ void BallProjectile::setMaterial(const std::string& material) { this->materialBase_ = material; BillboardProjectile::setMaterial(material + multi_cast(this->textureIndex_)); } /** @brief Change the texture. */ void BallProjectile::changeTexture() { this->textureIndex_++; if (this->textureIndex_ > this->maxTextureIndex_) this->textureIndex_ = 1; this->setMaterial(this->materialBase_); } void BallProjectile::Bounce(WorldEntity* otherObject, btManifoldPoint& contactPoint, const btCollisionShape* cs) { Vector3 velocity = this->getVelocity(); Vector3 myPosition = otherObject->getPosition(); btVector3 positionOtherObject = contactPoint.getPositionWorldOnA(); int distance_X = positionOtherObject.getX() - myPosition.x; int distance_Z = positionOtherObject.getZ() - myPosition.z; if (distance_X < 0) distance_X = -distance_X; if (distance_Z < 0) distance_Z = -distance_Z; //orxout() << distance_X << endl; //orxout() << distance_Z << endl; if (distance_X < distance_Z) { velocity.z = -velocity.z; //orxout() << "z" << endl; } if (distance_Z < distance_X) { velocity.x = -velocity.x; //orxout() << "x" << endl; } else { velocity.x = -velocity.x; velocity.z = -velocity.z; //orxout() << "both" << endl; } this->setVelocity(velocity); //} } bool BallProjectile::processCollision(WorldEntity* otherObject, btManifoldPoint& contactPoint, const btCollisionShape* cs) { bool result = BasicProjectile::processCollision(otherObject, contactPoint, cs); if (result == true) { if (otherObject->isA(Class(OrxoBloxStones))) { Bounce(otherObject, contactPoint, cs); orxout() << "BOUNCED!" << endl; } } return result; } OrxoBlox* BallProjectile::getOrxoBlox() { if (this->getGametype() != nullptr && this->getGametype()->isA(Class(OrxoBlox))) { OrxoBlox* orxobloxGametype = orxonox_cast(this->getGametype()); return orxobloxGametype; } else orxout()<<"There is no Gametype for OrxoBlox! ask Anna"<< endl; return nullptr; } void BallProjectile::tick(float dt) { SUPER(BallProjectile, tick, dt); // Get the current position, velocity and acceleration of the ball. bool suicidal = false; Vector3 position = this->getPosition(); Vector3 velocity = this->getVelocity(); Vector3 acceleration = this->getAcceleration(); velocity.y = 0; position.y = 0; // If the ball has gone over the top or bottom boundary of the playing field (i.e. the ball has hit the top or bottom delimiters). if (position.z > this->fieldHeight_ || position.z < -this->fieldHeight_) { velocity.z = -velocity.z; // And its position is set as to not overstep the boundary it has just crossed. Remember z axis is reverted!!! if (position.z > this->fieldHeight_){ // Set the ball to be exactly at the boundary. position.z = this-> fieldHeight_; orxoblox_->LevelUp(); suicidal = true; } if (position.z < -this->fieldHeight_){ position.z = -this->fieldHeight_; } this->fireEvent(); } //Ball hits the right or left wall and should bounce back. // If the ball has crossed the left or right boundary of the playing field. if (position.x > this->fieldWidth_ || position.x < -this->fieldWidth_) { //Ball hits the right Wall if (position.x > this->fieldWidth_) { // Set the ball to be exactly at the boundary. position.x = this->fieldWidth_; // Invert its velocity in x-direction (i.e. it bounces off). velocity.x = -velocity.x; this->fireEvent(); } //Ball hits the left wall else if (position.x < -this->fieldWidth_) { // Set the ball to be exactly at the boundary. position.x = -this->fieldWidth_; // Invert its velocity in x-direction (i.e. it bounces off). velocity.x = -velocity.x; this->fireEvent(); } } // Set the position, velocity and acceleration of the ball, if they have changed. if (acceleration != this->getAcceleration()) this->setAcceleration(acceleration); if (velocity != this->getVelocity()) this->setVelocity(velocity); if (position != this->getPosition()) this->setPosition(position); //this->Collides((this->orxoblox_->CheckForCollision(this))); if (suicidal == true) { this->destroy(); } } void BallProjectile::setSpeed(float speed) { if (speed != this->speed_) // If the speed changes { this->speed_ = speed; // Set the speed in the direction of the balls current velocity. Vector3 velocity = this->getVelocity(); if (velocity.x != 0) velocity.x = sgn(velocity.x) * this->speed_; else // If the balls current velocity is zero, the speed is set in a random direction. velocity.x = this->speed_ * sgn(rnd(-1,1)); this->setVelocity(velocity); } } void BallProjectile::destroyObject(void) { if(GameMode::isMaster()) { } } }