/* * 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: * Fabien Vultier * Co-authors: * ... * */ /** @file SOBFigure.cc @brief This class represents your figure when you play the minigame. Here the movement of the figure, activating items, ... are handled. */ #include "SOBFigure.h" #include "core/CoreIncludes.h" #include "core/XMLPort.h" #include "graphics/Model.h" #include "graphics/Camera.h" #include "graphics/ParticleSpawner.h" #include "SOBMushroom.h" #include "SOBGumba.h" #include "SOB.h" #include "SOBFlagstone.h" namespace orxonox { RegisterClass(SOBFigure); SOBFigure::SOBFigure(Context* context) : ControllableEntity(context) { RegisterObject(SOBFigure); // initialize variables moveUpPressed_ = false; moveDownPressed_ = false; moveLeftPressed_ = false; moveDownPressed_ = false; firePressed_ = false; timeSinceLastFire_ = 0.0; lastSpeed_z = 0.0; isColliding_ = true; particlespawner_ = NULL; gravityAcceleration_ = 350.0; pitch_ = 0.0; predead_ = false; dead_ = false; gotPowerUp_ = false; setAngularFactor(0.0); this->enableCollisionCallback(); } bool SOBFigure::collidesAgainst(WorldEntity* otherObject, const btCollisionShape* ownCollisionShape, btManifoldPoint& contactPoint) { isColliding_ = true; SOBMushroom* mush = orxonox_cast(otherObject); SOBGumba* gumba = orxonox_cast(otherObject); SOBFlagstone* flagstone = orxonox_cast(otherObject); if (mush != nullptr && !(mush->hasCollided_)) { otherObject->destroyLater(); gotPowerUp_ = true; SOB* SOBGame = orxonox_cast(getGametype()); SOBGame->addMushroom(); mush->hasCollided_ = true; } else if (gumba != nullptr && !(gumba->hasCollided_)) { if (getVelocity().z >= -20) { Vector3 vel = getVelocity(); vel.y = -80; vel.z = 200; setVelocity(vel); predead_=true; } else { gumba->destroyLater(); gumba->hasCollided_ = true; SOB* SOBGame = orxonox_cast(getGametype()); SOBGame->addGumba(); } } if (flagstone != nullptr && !(flagstone->hasCollided_)) { flagstone->hasCollided_ = true; } return true; } void SOBFigure::XMLPort(Element& xmlelement, XMLPort::Mode mode) { SUPER(SOBFigure, XMLPort, xmlelement, mode); } int SOBFigure::sgn(float x) { if (x < 0.0) return -1; return 1; } void SOBFigure::tick(float dt) { SUPER(SOBFigure, tick, dt); if (particlespawner_ == NULL) { for (WorldEntity* object : this->getAttachedObjects()) { if (object->isA(Class(ParticleSpawner))) particlespawner_ = object; } } if (firePressed_ == false) { gravityAcceleration_ = 350.0; } if (hasLocalController()) { Vector3 velocity = getVelocity(); Vector3 position = getPosition(); if (!predead_) velocity.y = 0; if (position.z < -100) { dead_ = true; } if (dead_) { velocity.x = 0; velocity.z = 0; setVelocity(velocity); SOB* SOBGame = orxonox_cast(getGametype()); if (firePressed_) SOBGame->restart(); return; } int maxvelocity_x = 100; int speedAddedPerTick = 5; int camMaxOffset = 25; timeSinceLastFire_ += dt; lastSpeed_z = velocity.z; //Handle the rocket fire from the jetpack if (velocity.z > 40) particlespawner_->setVisible(true); else particlespawner_->setVisible(false); //If player hits space and does not move in z-dir if (firePressed_ && isColliding_ && std::abs(velocity.z) < 0.1 && std::abs(lastSpeed_z) < 0.1) { gravityAcceleration_ = 100.0; velocity.z = 110; //150 } // rotate(1,getOrientation()* WorldEntity::FRONT) //Left-right movement with acceleration float rot = getOrientation().getRoll().valueDegrees(); orxout() << rot << endl; if (moveRightPressed_) { if (!(rot < 5.0 && -5.0 < rot)) setOrientation(Vector3::UNIT_Z, getOrientation().getRoll() - sgn(rot)*dt*Radian(6)); if (std::abs(velocity.x) < maxvelocity_x) { velocity.x += speedAddedPerTick; } } else if (moveLeftPressed_) { if (!(abs(rot) > 175.0 )) setOrientation(Vector3::UNIT_Z, getOrientation().getRoll() + sgn(rot)*dt*Radian(6)); if (std::abs(velocity.x) < maxvelocity_x) { velocity.x -= speedAddedPerTick; } } else { velocity.x /= 1.1; } velocity.z -= gravityAcceleration_*dt; setVelocity(velocity); //Camera operation Camera* cam = getCamera(); Vector3 campos = cam->getPosition(); if (campos.x + camMaxOffset < position.x) { campos.x = position.x - camMaxOffset; cam->setPosition(campos); } if (campos.x - camMaxOffset > position.x) { campos.x = position.x + camMaxOffset; cam->setPosition(campos); } } // Move through the left and right screen boundaries //setPosition(position); // Reset key variables moveUpPressed_ = false; moveDownPressed_ = false; moveLeftPressed_ = false; moveRightPressed_ = false; moveDownPressed_ = false; isColliding_ = false; } void SOBFigure::moveFrontBack(const Vector2& value) { if (value.x > 0) { moveUpPressed_ = true; moveDownPressed_ = false; } else { moveUpPressed_ = false; moveDownPressed_ = true; } } void SOBFigure::moveRightLeft(const Vector2& value) { if (value.x > 0) { moveLeftPressed_ = false; moveRightPressed_ = true; } else { moveLeftPressed_ = true; moveRightPressed_ = false; } } void SOBFigure::boost(bool boost) { firePressed_ = boost; } }