//============================================================================== // 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //============================================================================== //============================================================================== // File: cGameMode.cpp // Project: Shooting Star // Author: Jarmo Hekkanen // Copyrights (c) 2003 2ndPoint ry (www.2ndpoint.fi) //------------------------------------------------------------------------------ // Revision history //============================================================================== //============================================================================== // Includes #include "cGameMode.hpp" #include #include #include #include #include "Debug.hpp" #include "cTextureManager.hpp" #include "cWorld.hpp" #include "cMap.hpp" #include "cWeapon.hpp" #include "cGameCore.hpp" #include "cMedPack.hpp" #include "cWeaponBox.hpp" #include "cAnimationManager.hpp" #include "cHud.hpp" #include "cMixer.hpp" #include "cPistol.hpp" #include "cShotgun.hpp" #include "cFlamer.hpp" #include "cRocketLauncher.hpp" #include "cDisplayManager.hpp" #include "Actions.hpp" #include "cOptions.hpp" //------------------------------------------------------------------------------ // Namespaces using namespace ShootingStar; //------------------------------------------------------------------------------ // Constants const int PistolEnemy_MaxHealth = 25; const int ShotgunEnemy_MaxHealth = 40; const int FlamerEnemy_MaxHealth = 50; const int RocketEnemy_MaxHealth = 50; //============================================================================== //! Constructor cGameMode::cGameMode (cGameCore &core): mCore (core), mGameView (*this), mTexManager (cTextureManager::GetInstance ()), mAnimManager (cAnimationManager::GetInstance ()), mWorld (cWorld::GetInstance ()), mMixer (cMixer::GetInstance ()), mDisplayManager (cDisplayManager::GetInstance ()), mOptions (cOptions::GetInstance ()), mHud (mPlayer1, mPlayer2), mFPS (0), mGameType (GameType_Single) { dbg::enable (dbg::all, "cWorld", true); }; //! Destructor cGameMode::~cGameMode (void) { // Empty }; void cGameMode::Run (GameType type) { mGameType = type; mCameraLock = false; mActionMapper.ClearBindings (); // Game actions mActionMapper.RegisterKeyboardAction (SDLK_ESCAPE, SDL_PRESSED, cAction (ActionType_Game, GameAction_Quit)); mActionMapper.RegisterKeyboardAction (SDLK_PAGEUP, SDL_PRESSED, cAction (ActionType_Game, GameAction_MusicUp)); mActionMapper.RegisterKeyboardAction (SDLK_PAGEDOWN, SDL_PRESSED, cAction (ActionType_Game, GameAction_MusicDown)); mActionMapper.RegisterKeyboardAction (SDLK_HOME, SDL_PRESSED, cAction (ActionType_Game, GameAction_SoundsUp)); mActionMapper.RegisterKeyboardAction (SDLK_END, SDL_PRESSED, cAction (ActionType_Game, GameAction_SoundsDown)); // Player 1 actions mActionMapper.RegisterKeyboardAction (mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_Fire], SDL_PRESSED, cAction (ActionType_Player1, PlayerAction_PullTrigger)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_Fire], SDL_RELEASED, cAction (ActionType_Player1, PlayerAction_ReleaseTrigger)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_NextWeapon], SDL_PRESSED, cAction (ActionType_Player1, PlayerAction_NextWeapon)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_PreviousWeapon], SDL_PRESSED, cAction (ActionType_Player1, PlayerAction_PreviousWeapon)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_AimMode], SDL_PRESSED, cAction (ActionType_Player1, PlayerAction_EnableFineAim)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_AimMode], SDL_RELEASED, cAction (ActionType_Player1, PlayerAction_DisableFineAim)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_StrafeMode], SDL_PRESSED, cAction (ActionType_Player1, PlayerAction_EnableStrafe)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_StrafeMode], SDL_RELEASED, cAction (ActionType_Player1, PlayerAction_DisableStrafe)); mActionMapper.RegisterMouseAction (mOptions.mPlayer1Keys.buttons[tPlayerKeys::Key_Fire], SDL_PRESSED, cAction (ActionType_Player1, PlayerAction_PullTrigger)); mActionMapper.RegisterMouseAction (mOptions.mPlayer1Keys.buttons[tPlayerKeys::Key_Fire], SDL_RELEASED, cAction (ActionType_Player1, PlayerAction_ReleaseTrigger)); mActionMapper.RegisterMouseAction (mOptions.mPlayer1Keys.buttons[tPlayerKeys::Key_NextWeapon], SDL_PRESSED, cAction (ActionType_Player1, PlayerAction_NextWeapon)); mActionMapper.RegisterMouseAction (mOptions.mPlayer1Keys.buttons[tPlayerKeys::Key_PreviousWeapon], SDL_PRESSED, cAction (ActionType_Player1, PlayerAction_PreviousWeapon)); mActionMapper.RegisterMouseAction (mOptions.mPlayer1Keys.buttons[tPlayerKeys::Key_AimMode], SDL_PRESSED, cAction (ActionType_Player1, PlayerAction_EnableFineAim)); mActionMapper.RegisterMouseAction (mOptions.mPlayer1Keys.buttons[tPlayerKeys::Key_AimMode], SDL_RELEASED, cAction (ActionType_Player1, PlayerAction_DisableFineAim)); mActionMapper.RegisterMouseAction (mOptions.mPlayer1Keys.buttons[tPlayerKeys::Key_StrafeMode], SDL_PRESSED, cAction (ActionType_Player1, PlayerAction_EnableStrafe)); mActionMapper.RegisterMouseAction (mOptions.mPlayer1Keys.buttons[tPlayerKeys::Key_StrafeMode], SDL_RELEASED, cAction (ActionType_Player1, PlayerAction_DisableStrafe)); // Player 2 actions mActionMapper.RegisterKeyboardAction (mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_Fire], SDL_PRESSED, cAction (ActionType_Player2, PlayerAction_PullTrigger)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_Fire], SDL_RELEASED, cAction (ActionType_Player2, PlayerAction_ReleaseTrigger)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_NextWeapon], SDL_PRESSED, cAction (ActionType_Player2, PlayerAction_NextWeapon)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_PreviousWeapon], SDL_PRESSED, cAction (ActionType_Player2, PlayerAction_PreviousWeapon)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_AimMode], SDL_PRESSED, cAction (ActionType_Player2, PlayerAction_EnableFineAim)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_AimMode], SDL_RELEASED, cAction (ActionType_Player2, PlayerAction_DisableFineAim)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_StrafeMode], SDL_PRESSED, cAction (ActionType_Player2, PlayerAction_EnableStrafe)); mActionMapper.RegisterKeyboardAction (mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_StrafeMode], SDL_RELEASED, cAction (ActionType_Player2, PlayerAction_DisableStrafe)); mFont.Initialize ("font_11x20.png", 11, 20); mHud.LoadTextures(); LoadLevelList (); bool forceFrame = false; int skipCount = 0; // Create player object(s) mPlayer1 = new cPlayer ("player1"); if ( mGameType == GameType_Split ) mPlayer2 = new cPlayer ("player2"); // Timing Uint32 now, deltaTime, lastTime = SDL_GetTicks (); // Fps Uint32 frames = 0, fpsStart = SDL_GetTicks (); NextLevel (); // Main loop mRunning = true; while ( mRunning ) { // Calculate delta time now = SDL_GetTicks (); deltaTime = now - lastTime; lastTime = now; if ( deltaTime > 1000 ) // This happens when level changes or restarts continue; // Could also happen on _very_ slow machine??? if ( mOptions.mDelay ) SDL_Delay (SDL_TIMESLICE); // Collect garbage static Uint32 garbageTime = now + 5000; if ( garbageTime < now ) { garbageTime = now + 5000; cObject::CollectGarbage (); } if ( fpsStart + 1000 < now ) { mFPS = frames; frames = 0; fpsStart = now; } EventHandler (deltaTime); ActionHandler (); UpdateGame (deltaTime); if ( deltaTime < 30 || forceFrame ) { RenderGame (deltaTime); forceFrame = false; skipCount = 0; } else if ( mOptions.mFrameSkip ) { skipCount++; if ( skipCount > 5 ) forceFrame = true; } frames++; } mPlayer1 = NULL; mPlayer2 = NULL; // Clean up mEnemies.clear (); mWorld.RemoveAllObjects (); mAnimManager.FreeAllAnimations (); mMixer.StopAllSounds (); mMixer.FreeAllSounds (); cObject::CollectGarbage (); if ( mGameCompleted ) GameCompleted (); cMixer::GetInstance ().FadeMusic (); cMixer::GetInstance ().PlayMusic ("menu.ogg"); mTexManager.FreeAllTextures (); } void cGameMode::LoadLevel (string map) { mDisplayManager.BeginFrame (); glPushMatrix (); string dataDir = mCore.GetDataDir (); glColor4f (1.0f, 0.5f, 0.0f, 1.0f); glTranslatef (280.0f, 300.0f, 0.0f); mFont.Print ("Loading %s", map.c_str ()); glPopMatrix (); mDisplayManager.EndFrame (); mActionList.clear (); mEnemies.clear (); mWorld.RemoveAllObjects (); mMixer.StopAllSounds (); cObject::CollectGarbage (); try { mWorld.LoadMap (string (dataDir + string ("maps/") + map + string (".map"))); mWorld.GetMapSize (mMapWidth, mMapHeight); LoadObjects (string (dataDir + string ("maps/") + map + string (".obj"))); } catch ( runtime_error &x ) { dbgError () << "Unable to load level: " << x.what () << '\n'; } InitializeLevel (); // Damn it takes long to load these huge data files =) SDL_Delay (1000); mDisplayManager.BeginFrame (); glPushMatrix (); glColor4f (1.0f, 0.5f, 0.0f, 1.0f); glTranslatef (280.0f, 300.0f, 0.0f); mFont.Print ("Entering %s", map.c_str ()); glTranslatef (0.0f, 25.0f, 0.0f); mFont.PrintString ("Press any key to continue"); glPopMatrix (); mDisplayManager.EndFrame (); bool running = true; SDL_Event event; while ( running ) { SDL_WaitEvent (&event); switch ( event.type ) { case SDL_QUIT: running = false; break; case SDL_KEYDOWN: running = false; break; default: break; } } } void cGameMode::LoadObjects (string map) { int numberOfObjects[10]; ifstream fin; try { // Open file fin.open (map.c_str ()); if ( !fin ) { dbgError () << "Unable to open file " << map << " for reading\n"; throw runtime_error ("Unable to load objects"); } char buffer[80]; for ( int i = 0; i < 10; i++ ) { // Skip the description fin.getline (buffer, 80, ':'); // Read the first number fin.getline (buffer, 80, ','); if ( mGameType == GameType_Single ) numberOfObjects[i] = atoi (buffer); // Read the second number fin.getline (buffer, 80); if ( mGameType == GameType_Split ) numberOfObjects[i] = atoi (buffer); } if ( !fin ) { dbgError () << "Unable to read objects from file " << map << '\n'; throw runtime_error ("Unable to load objects"); } // Close the file fin.close (); } catch ( ... ) { fin.close (); throw; } mEnemies.clear (); // Spawn pistol enemies for ( int i = 0; i < numberOfObjects[0]; i++ ) { cComputerSoldier *pBot = new cComputerSoldier (mPlayer1, mPlayer2); pBot->SetMaxHealth (PistolEnemy_MaxHealth); mWorld.RandomPlace (pBot, 550.0f); mWorld.SpawnObject (pBot); mEnemies.push_back (cPointer (pBot)); cWeapon *pWeapon = new cPistol; mWorld.SpawnObject (pWeapon); pBot->AddWeapon (pWeapon); } // Spawn shotgun enemies for ( int i = 0; i < numberOfObjects[1]; i++ ) { cComputerSoldier *pBot = new cComputerSoldier (mPlayer1, mPlayer2); pBot->SetMaxHealth (ShotgunEnemy_MaxHealth); mWorld.RandomPlace (pBot, 550.0f); mWorld.SpawnObject (pBot); mEnemies.push_back (cPointer (pBot)); cWeapon *pWeapon = new cShotgun; mWorld.SpawnObject (pWeapon); pBot->AddWeapon (pWeapon); } // Spawn flamer enemies for ( int i = 0; i < numberOfObjects[2]; i++ ) { cComputerSoldier *pBot = new cComputerSoldier (mPlayer1, mPlayer2); pBot->SetMaxHealth (FlamerEnemy_MaxHealth); mWorld.RandomPlace (pBot, 550.0f); mWorld.SpawnObject (pBot); mEnemies.push_back (cPointer (pBot)); cWeapon *pWeapon = new cFlamer; mWorld.SpawnObject (pWeapon); pBot->AddWeapon (pWeapon); } // Spawn rocket enemies for ( int i = 0; i < numberOfObjects[3]; i++ ) { cComputerSoldier *pBot = new cComputerSoldier (mPlayer1, mPlayer2); pBot->SetMaxHealth (RocketEnemy_MaxHealth); mWorld.RandomPlace (pBot, 550.0f); mWorld.SpawnObject (pBot); mEnemies.push_back (cPointer (pBot)); cWeapon *pWeapon = new cRocketLauncher; mWorld.SpawnObject (pWeapon); pBot->AddWeapon (pWeapon); } // Spawn medpacks for ( int i = 0; i < numberOfObjects[4]; i++ ) { cMedPack *pPack = new cMedPack; mWorld.RandomPlace (pPack, 100); mWorld.SpawnObject (pPack); } // Spawn pistol boxes for ( int i = 0; i < numberOfObjects[5]; i++ ) { cWeaponBox *pBox = new cWeaponBox; pBox->SetBoxType (cWeaponBox::BoxType_Pistol); mWorld.RandomPlace (pBox, 100); mWorld.SpawnObject (pBox); } // Spawn shotgun boxes for ( int i = 0; i < numberOfObjects[6]; i++ ) { cWeaponBox *pBox = new cWeaponBox; pBox->SetBoxType (cWeaponBox::BoxType_Shotgun); mWorld.RandomPlace (pBox, 100); mWorld.SpawnObject (pBox); } // Spawn flamer boxes for ( int i = 0; i < numberOfObjects[7]; i++ ) { cWeaponBox *pBox = new cWeaponBox; pBox->SetBoxType (cWeaponBox::BoxType_Flamer); mWorld.RandomPlace (pBox, 100); mWorld.SpawnObject (pBox); } // Spawn rocket laucher boxes for ( int i = 0; i < numberOfObjects[8]; i++ ) { cWeaponBox *pBox = new cWeaponBox; pBox->SetBoxType (cWeaponBox::BoxType_RocketLauncher); mWorld.RandomPlace (pBox, 100); mWorld.SpawnObject (pBox); } // Spawn rocket laucher boxes for ( int i = 0; i < numberOfObjects[9]; i++ ) { cWeaponBox *pBox = new cWeaponBox; pBox->SetBoxType (cWeaponBox::BoxType_MachineGun); mWorld.RandomPlace (pBox, 100); mWorld.SpawnObject (pBox); } } void cGameMode::EventHandler (Uint32 deltaTime) { SDL_Event event; cAction action; Uint8 *pKeys = SDL_GetKeyState (NULL); bool skipMouseEvent = false; float angle = 0.0f; // Poll the event queue while ( SDL_PollEvent (&event) != 0 ) { switch ( event.type ) { case SDL_QUIT: mRunning = false; break; case SDL_KEYDOWN: // Same as SDL_KEYUP case SDL_KEYUP: action = mActionMapper.MapKeyboardEvent (&event.key); if ( action.IsValid () ) mActionList.push_back (action); break; case SDL_MOUSEMOTION: if ( skipMouseEvent ) { skipMouseEvent = false; break; } angle += (event.motion.x - 320) * 0.0002f * deltaTime * mOptions.mMouseSensitivity; SDL_WarpMouse (320, 240); skipMouseEvent = true; // Skip the warp event break; case SDL_MOUSEBUTTONDOWN: // Same as SDL_MOUSEBUTTONUP case SDL_MOUSEBUTTONUP: action = mActionMapper.MapMouseEvent (&event.button); if ( action.IsValid () ) mActionList.push_back (action); break; default: break; } } if ( mPlayer1.IsValid () && mPlayer1->IsAlive () ) { if ( mOptions.mMouseTurning && mOptions.mMousePlayer1 ) mPlayer1->Rotate (angle); // Turning if ( pKeys[mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_TurnLeft]] == SDL_PRESSED ) mPlayer1->TurnLeft (); else if ( pKeys[mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_TurnRight]] == SDL_PRESSED ) mPlayer1->TurnRight (); else mPlayer1->StopTurning (); // Walking mPlayer1->StopWalking (); if ( pKeys[mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_WalkForward]] == SDL_PRESSED ) mPlayer1->WalkForward (); else if ( pKeys[mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_WalkBackward]] == SDL_PRESSED ) mPlayer1->WalkBackward (); if ( pKeys[mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_WalkLeft]] == SDL_PRESSED ) mPlayer1->WalkLeft (); else if ( pKeys[mOptions.mPlayer1Keys.keys[tPlayerKeys::Key_WalkRight]] == SDL_PRESSED ) mPlayer1->WalkRight (); } if ( mPlayer2.IsValid () && mPlayer2->IsAlive () ) { if ( mOptions.mMouseTurning && !mOptions.mMousePlayer1 ) mPlayer2->Rotate (angle); // Turning if ( pKeys[mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_TurnLeft]] == SDL_PRESSED ) mPlayer2->TurnLeft (); else if ( pKeys[mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_TurnRight]] == SDL_PRESSED ) mPlayer2->TurnRight (); else mPlayer2->StopTurning (); // Walking mPlayer2->StopWalking (); if ( pKeys[mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_WalkForward]] == SDL_PRESSED ) mPlayer2->WalkForward (); else if ( pKeys[mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_WalkBackward]] == SDL_PRESSED ) mPlayer2->WalkBackward (); if ( pKeys[mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_WalkLeft]] == SDL_PRESSED ) mPlayer2->WalkLeft (); else if ( pKeys[mOptions.mPlayer2Keys.keys[tPlayerKeys::Key_WalkRight]] == SDL_PRESSED ) mPlayer2->WalkRight (); } } void cGameMode::ActionHandler (void) { // Handle actions for ( unsigned int i = 0; i < mActionList.size (); i++ ) { switch ( mActionList[i].GetType () ) { case ActionType_Game: switch ( mActionList[i].GetAction () ) { case GameAction_Quit: mRunning = false; break; case GameAction_ToggleCameraLock: mCameraLock = !mCameraLock; break; case GameAction_NextLevel: NextLevel (); break; case GameAction_RestartLevel: RestartLevel (); break; case GameAction_MusicUp: mMixer.SetMusicVolume (mMixer.GetMusicVolume () + 10); break; case GameAction_MusicDown: mMixer.SetMusicVolume (mMixer.GetMusicVolume () - 10); break; case GameAction_SoundsUp: mMixer.SetSoundsVolume (mMixer.GetSoundsVolume () + 10); break; case GameAction_SoundsDown: mMixer.SetSoundsVolume (mMixer.GetSoundsVolume () - 10); break; default: break; } break; case ActionType_Player1: if ( mPlayer1.IsValid () && mPlayer1->IsAlive () ) mPlayer1->HandleAction (mActionList[i].GetAction ()); break; case ActionType_Player2: if ( mPlayer2.IsValid () && mPlayer2->IsAlive () ) mPlayer2->HandleAction (mActionList[i].GetAction ()); break; default: break; } } // Clear the action list mActionList.clear (); } void cGameMode::UpdateGame (Uint32 deltaTime) { mWorld.Update (deltaTime); mGameView.Update (deltaTime); if ( !mGameOver && mPlayer1.IsValid () && !mPlayer1->IsAlive () ) { if ( mGameType == GameType_Single ) mGameOver = true; else if ( mPlayer2.IsValid () && !mPlayer2->IsAlive () ) mGameOver = true; if ( mGameOver ) mLevelEndDelay = 5000; } if ( !mLevelCleared ) { bool allDead = true; // TODO remove dead objects from the list for ( unsigned int i = 0; i < mEnemies.size (); i++ ) { if ( mEnemies[i]->IsAlive () ) { allDead = false; break; } } if ( allDead && !mGameOver ) { mLevelCleared = true; mLevelEndDelay = 10000; } } if ( mGameOver && mLevelCleared ) mLevelCleared = false; if ( mGameOver || mLevelCleared ) { if ( deltaTime >= mLevelEndDelay ) { mLevelEndDelay = 0; if ( mGameOver ) mActionList.push_back (cAction (ActionType_Game, GameAction_RestartLevel)); else if ( mLevelCleared ) mActionList.push_back (cAction (ActionType_Game, GameAction_NextLevel)); } else mLevelEndDelay -= deltaTime; } mTextWave += 0.008f * deltaTime; } void cGameMode::RenderGame (Uint32 deltaTime) { mDisplayManager.BeginFrame (false); GLenum error = glGetError (); while ( error != GL_NO_ERROR ) { dbgError () << "OpenGL error before rendering: " << gluErrorString (error) << '\n'; error = glGetError (); } mGameView.Render (deltaTime); // Render HUD mHud.Render (); // Render stats /* glPushMatrix (); glTranslatef (0.0f, 20.0f, 0.0f); glColor4f (1.0f, 1.0f, 0.0f, 1.0f); mFont.Print ("FPS: %6.2f WORLD OBJECTS: %i, OBJECTS: %i, GARBAGE OBJECTS %i)", mFPS, mWorld.GetObjectCount (), cObject::GetObjectCount (), cObject::GetGarbageCount ()); glPopMatrix (); */ // Render wave text if ( mGameOver || mLevelCleared ) { glTranslatef ((800.0f - 10 * 11) * 0.5f, 600.0f * 0.5f, 0.0f); glColor4f (1.0f, 1.0f, 0.0f, 1.0f); string text = "LEVEL CLEARED"; if ( mGameOver ) text = "GAME OVER"; mFont.PrintStringW (text, mTextWave); /*if ( mGameOver ) { glTranslatef (-44.0f, 60.0f, 0.0f); glColor4f (1.0f, 1.0f, 1.0f, 0.5f); mFont.Print ("Restarting in %i", mLevelEndDelay); }*/ } mDisplayManager.EndFrame (); error = glGetError (); while ( error != GL_NO_ERROR ) { dbgError () << "OpenGL error post rendering: " << gluErrorString (error) << '\n'; error = glGetError (); } } void cGameMode::InitializeLevel (void) { mGameView.Reset (); mGameOver = false; mLevelCleared = false; mGameCompleted = false; if ( mPlayer1.IsValid () ) { mPlayer1->SetPosition (cVector2f (100.0f, 100.0f)); mWorld.SpawnObject (mPlayer1); mPlayer1->OnLevelChanged (); } else dbg::sentinel (DBG_HERE); if ( mPlayer2.IsValid () ) { mPlayer2->SetPosition (cVector2f (150.0f, 100.0f)); mWorld.SpawnObject (mPlayer2); mPlayer2->OnLevelChanged (); } } void cGameMode::LoadLevelList (void) { // Clear the old list mLevelList.clear (); string filename = mCore.GetDataDir () + string ("maps/levels"); dbgInfo () << "Loading level list from file " << filename << '\n'; ifstream fin; try { // Open file for reading fin.open (filename.c_str ()); if ( !fin ) { dbgError () << "Unable to open file " << filename << " for reading\n"; throw runtime_error ("Unable to load level list"); } // Read level names char buffer[80]; while ( 1 ) { fin.getline (buffer, 80); if ( fin ) mLevelList.push_back (buffer); else break; } // Close the file fin.close (); } catch ( ... ) { fin.close (); throw; } mNextLevel = 0; if ( mLevelList.empty () ) throw runtime_error ("Unable to load level list"); } void cGameMode::NextLevel (void) { if ( mNextLevel >= mLevelList.size () ) { mGameCompleted = true; mRunning = false; } else { if ( mPlayer1.IsValid () ) mPlayer1->SaveWeapons (); if ( mPlayer2.IsValid () ) mPlayer2->SaveWeapons (); LoadLevel (mLevelList[mNextLevel++]); } } void cGameMode::RestartLevel (void) { if ( mPlayer1.IsValid () ) mPlayer1->RestoreWeapons (); if ( mPlayer2.IsValid () ) mPlayer2->RestoreWeapons (); LoadLevel (mLevelList[mNextLevel - 1]); } void cGameMode::GameCompleted (void) { mDisplayManager.BeginFrame (); glColor4f (1.0f, 0.5f, 0.0f, 1.0f); glTranslatef (59.0f, 200.0f, 0.0f); mFont.Print (" The End"); glColor4f (1.0f, 1.0f, 1.0f, 1.0f); glTranslatef (0.0f, 25.0f, 0.0f); mFont.Print (" Thanks for playing 2ndPoint's Shooting Star"); glTranslatef (0.0f, 40.0f, 0.0f); mFont.Print (" Get Shooting Star map editor and other cool stuff"); glTranslatef (0.0f, 20.0f, 0.0f); mFont.Print (" from www.2ndpoint.fi/ss"); glTranslatef (0.0f, 40.0f, 0.0f); mFont.Print ("Send comments, contributions, patches etc. to ss@2ndpoint.fi"); mDisplayManager.EndFrame (); SDL_Delay (2000); bool running = true; SDL_Event event; // Empty the event queue while ( SDL_PollEvent (&event) != 0 ) { if ( event.type == SDL_QUIT ) running = false; } while ( running ) { SDL_WaitEvent (&event); switch ( event.type ) { case SDL_QUIT: running = false; break; case SDL_KEYDOWN: running = false; break; default: break; } } } //============================================================================== // EOF //==============================================================================