/* * 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: * Manuel Meier * Co-authors: * Cyrill Muskelprotz * */ /** @file Hover.cc @brief Implementation of the Hover class. Sets up the whole Minigame */ //#include "orxonox/worldentities/pawns/SpaceShip.h" #include "Hover.h" #include "HoverWall.h" #include "HoverFlag.h" #include "core/CoreIncludes.h" #include #include #include #include #include #include #include #include namespace orxonox { bool firstTick = true; //Levelcode represents the pitch: It's a 10x10 field. // 1 represents a Wall on the right side of this square // 2 represents a Wall on the top of this square // 3 represents 2 and 1 at the same time // Note: the levelcode is generated from the Maze-Generator functions at the beginning of the game int levelcode[10][10] = { { 0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0,0,0 } }; const int NumCells = 10; unsigned char* g_Maze = new unsigned char[ NumCells* NumCells ]; // current traversing position int g_PtX; int g_PtY; // return the current index in g_Maze int Hover::CellIdx() { return g_PtX + NumCells * g_PtY; } int Hover::RandomInt() { return (rand() % NumCells); } int Hover::RandomInt4() { return (rand() % 4); } RegisterUnloadableClass(Hover); Hover::Hover(Context* context) : Gametype(context) { RegisterObject(Hover); this->setHUDTemplate("HoverHUD"); } void Hover::tick(float dt) { SUPER(Hover, tick, dt); if(firstTick) { std::fill( g_Maze, g_Maze + NumCells * NumCells, 0 ); g_PtX=0; g_PtY=0; GenerateMaze(); RenderMaze(); firstTick = false; //Outer Walls for(int i = 0; i<10; i++){ new HoverWall(origin_->getContext(), 0, i+1, 1); new HoverWall(origin_->getContext(), 10, i+1, 1); new HoverWall(origin_->getContext(), i+1, 0, 2); new HoverWall(origin_->getContext(), i+1, 10, 2); } //Generate inner Walls according to levelcode for(int y=0; y<10; y++){ for(int x=0; x<10; x++){ switch(levelcode[y][x]){ case 1: new HoverWall(origin_->getContext(), x+1, 10-y, 1); break; case 3: new HoverWall(origin_->getContext(), x+1, 10-y, 1); case 2: new HoverWall(origin_->getContext(), x+1, 10-y, 0); default: break; } } } //Generate 5 flags randomly for ( int i = 0; i < 5; i++ ) flagVector.push_back(new HoverFlag(origin_->getContext(), rand()%10, rand()%10)); Flags_ = flagVector.size(); }//firsttick end // Check if ship collided with one of the flags for ( unsigned int i = 0; i < flagVector.size(); i++ ){ if(flagVector[i]->getCollided()){ flagVector[i]->destroyLater(); flagVector.erase (flagVector.begin()+i); } } Flags_ = flagVector.size(); } int Hover::getFlags() { // Call start for the parent class. return Flags_; } void Hover::start() { // Call start for the parent class. Gametype::start(); } void Hover::end() { // DON'T CALL THIS! // Deathmatch::end(); // It will misteriously crash the game! // Instead startMainMenu, this won't crash. GSLevel::startMainMenu(); } // Some definitions for the Maze-Generator // 0 1 2 3 4 5 6 7 8 // U R D L int Heading_X[9] = { 0, 0,+1, 0, 0, 0, 0, 0,-1 }; int Heading_Y[9] = { 0,-1, 0, 0,+1, 0, 0, 0, 0 }; int Mask[9] = { 0, eDirection_Down | eDirection_Down << 4, eDirection_Left | eDirection_Left << 4, 0, eDirection_Up | eDirection_Up << 4, 0, 0, 0, eDirection_Right | eDirection_Right << 4 }; /** @brief Checks if Direction is valid (for Maze-Generator) */ bool Hover::IsDirValid( eDirection Dir ) { int NewX = g_PtX + Heading_X[ Dir ]; int NewY = g_PtY + Heading_Y[ Dir ]; if ( !Dir || NewX < 0 || NewY < 0 || NewX >= NumCells || NewY >= NumCells ) return false; return !g_Maze[ NewX + NumCells * NewY ]; } /** @brief Generates new Direction (for Maze-Generator) */ eDirection Hover::GetDirection() { eDirection Dir = eDirection( 1 << RandomInt4() ); while ( true ) { for ( int x = 0; x < 4; x++ ) { if ( IsDirValid( Dir ) ) { return eDirection( Dir ); } Dir = eDirection( Dir << 1 ); if ( Dir > eDirection_Left ) { Dir = eDirection_Up; } } Dir = eDirection( ( g_Maze[ CellIdx() ] & 0xf0 ) >> 4 ); // nowhere to go if ( !Dir ) return eDirection_Invalid; g_PtX += Heading_X[ Dir ]; g_PtY += Heading_Y[ Dir ]; Dir = eDirection( 1 << RandomInt4() ); } } /** @brief Generates a Maze (for Maze-Generator) */ void Hover::GenerateMaze() { for ( eDirection Dir = GetDirection(); Dir != eDirection_Invalid; Dir = GetDirection() ) { g_Maze[ CellIdx() ] |= Dir; g_PtX += Heading_X[ Dir ]; g_PtY += Heading_Y[ Dir ]; g_Maze[ CellIdx() ] = Mask[ Dir ]; } } /** @brief Print Maze (for Debugging only) */ void Hover::MazeOut(){ for ( int y = 0; y < NumCells; y++ ) { for ( int x = 0; x < NumCells; x++ ) { char v = g_Maze[ y * NumCells + x ]; orxout()<<"["; if ( ( v & eDirection_Up ) ) orxout()<<"U"; else orxout()<<" "; if ( ( v & eDirection_Right ) ) orxout()<<"R"; else orxout()<<" "; if ( ( v & eDirection_Down ) ) orxout()<<" "; else orxout()<<" "; if ( ( v & eDirection_Left ) ) orxout()<<" "; else orxout()<<" "; orxout()<<"]"; } orxout()<0) levelcode[y][x] |= 2; if ( !( v & eDirection_Right ) && x <9) levelcode[y][x] |= 1; } } for ( int y = 3; y < 7; y++ ) { for ( int x = 3; x < 7; x++ ) { if(y == 3 && x != 7) levelcode[y][x] &= 2; else if (x == 7 && y != 3) levelcode[y][x] &= 1; else if(x != 7) levelcode[y][x] = 0; } } } }