/* * 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: * Florian Zinggeler * Co-authors: * ... * */ /** @file Invader.cc @brief Implementation of the Invader class. */ #include "Invader.h" #include "Highscore.h" #include "core/CoreIncludes.h" #include "core/EventIncludes.h" #include "core/command/Executor.h" #include "core/config/ConfigValueIncludes.h" #include "gamestates/GSLevel.h" #include "chat/ChatManager.h" // ! HACK #include "infos/PlayerInfo.h" #include "InvaderCenterPoint.h" #include "InvaderShip.h" #include "InvaderEnemy.h" #include "InvaderEnemyShooter.h" #include "core/command/ConsoleCommand.h" #include "worldentities/ExplosionPart.h" namespace orxonox { RegisterUnloadableClass(Invader); Invader::Invader(Context* context) : Deathmatch(context) { RegisterObject(Invader); this->numberOfBots_ = 0; //sets number of default bots temporarly to 0 this->center_ = nullptr; bEndGame = false; lives = 3; level = 1; point = 0; bShowLevel = false; multiplier = 1; b_combo = false; // spawn enemy every 3.5 seconds enemySpawnTimer.setTimer(3.5f, true, createExecutor(createFunctor(&Invader::spawnEnemy, this))); comboTimer.setTimer(3.0f, true, createExecutor(createFunctor(&Invader::comboControll, this))); this->setHUDTemplate("InvaderHUD"); } void Invader::levelUp() { level++; if (getPlayer() != nullptr) { for (int i = 0; i < 7; i++) { WeakPtr chunk5 = new ExplosionPart(this->center_->getContext()); chunk5->setPosition(this->center_->getPosition()); chunk5->setVelocity(Vector3(1000, 0, 0)); //player->getVelocity() chunk5->setScale(10); chunk5->setEffect1("Orxonox/explosion2b"); chunk5->setEffect2("Orxonox/smoke6"); chunk5->setMinSpeed(0); chunk5->setMaxSpeed(0); chunk5->Explode(); } } addPoints(multiplier * 42); multiplier *= 2; toggleShowLevel(); showLevelTimer.setTimer(1.0f, false, createExecutor(createFunctor(&Invader::toggleShowLevel, this))); } InvaderShip* Invader::getPlayer() { if (player == nullptr) { for (InvaderShip* ship : ObjectList()) player = ship; } return player; } void Invader::spawnEnemy() { if (getPlayer() == nullptr) return; for (int i = 0; i < (3*log10(static_cast(level)) + 1); i++) { InvaderEnemy* newPawn; if (rand() % 42/(1 + level*level) == 0) { newPawn = new InvaderEnemyShooter(this->center_->getContext()); newPawn->addTemplate("enemyinvadershooter"); } else { newPawn = new InvaderEnemy(this->center_->getContext()); newPawn->addTemplate("enemyinvader"); } newPawn->setInvaderPlayer(player); newPawn->level = level; // spawn enemy at random points in front of player. newPawn->setPosition(player->getPosition() + Vector3(500.f + 100 * i, 0, float(rand())/RAND_MAX * 400 - 200)); } } void Invader::setCenterpoint(InvaderCenterPoint* center) { this->center_ = center; } void Invader::costLife() { lives--; multiplier = 1; // end the game in 30 seconds. if (lives <= 0) enemySpawnTimer.setTimer(30.0f, false, createExecutor(createFunctor(&Invader::end, this))); }; void Invader::comboControll() { if (b_combo) multiplier++; // if no combo was performed before, reset multiplier else multiplier = 1; b_combo = false; } void Invader::start() { // Set variable to temporarily force the player to spawn. this->bForceSpawn_ = true; if (this->center_ == nullptr) // abandon mission! { orxout(internal_error) << "Invader: No Centerpoint specified." << endl; GSLevel::startMainMenu(); return; } // Call start for the parent class. Deathmatch::start(); } void Invader::addPoints(int numPoints) { if (!bEndGame) { point += numPoints * multiplier; b_combo = true; } } void Invader::end() { // DON'T CALL THIS! // Deathmatch::end(); // It will misteriously crash the game! // Instead startMainMenu, this won't crash. if (Highscore::exists()){ int score = this->getPoints(); if(score > Highscore::getInstance().getHighestScoreOfGame("Orxonox Arcade")) Highscore::getInstance().storeHighscore("Orxonox Arcade",score); } GSLevel::startMainMenu(); } }