00001
00002
00003 #include "irrlicht.h"
00004 #include "irrConsole/console.h"
00005 using namespace irr;
00006
00007 #include "cerberus.h"
00008 #include "game.h"
00009 #include "landscape.h"
00010
00014 cGame::cGame( IrrlichtDevice* device, cConfiguration* configuration, cAudioDevice* audioDevice,
00015 IC_Console* console, unsigned int level ) :
00016 mDevice( device ), mConfiguration( configuration ), mAudioDevice( audioDevice ),
00017 mConsole(console), mLevel( level )
00018 {
00019
00020 mDriver = mDevice->getVideoDriver();
00021 mSmgr = mDevice->getSceneManager();
00022 mEnv = mDevice->getGUIEnvironment();
00023 mLogger = mDevice->getLogger();
00024
00025
00026 mDriver->setTextureCreationFlag( video::ETCF_ALWAYS_32_BIT, true );
00027 tIrrlichtLogo = mDriver->getTexture( "media/irrlichtlogo2.png" );
00028 tNrgTree = mDriver->getTexture( "media/tree_energy.png" );
00029 tNrgBoulder = mDriver->getTexture( "media/boulder_energy.png" );
00030 tNrgRobot = mDriver->getTexture( "media/robot_energy.png" );
00031 tNrgRobot5 = mDriver->getTexture( "media/robot_energy5.png" );
00032
00033
00034
00035 mRNG = new mt19937( 0 );
00036
00037
00038 mEnv->addImage( tIrrlichtLogo, core::position2d<s32>(10, mConfiguration->height-92) );
00039
00040
00041 mDevice->getCursorControl()->setPosition( 0.5f, 0.5f );
00042 mDevice->getCursorControl()->setVisible( false );
00043
00044
00045 mWorld = new cWorld( mDevice, mLevel, 33, 15, 4, 0.9 );
00046 mWorld->create();
00047 if( mWorld->getNode() ) {
00048 mWorld->getNode()->setPosition( core::vector3df(0, 0, 0) );
00049 mWorld->getNode()->setRotation( core::vector3df(0, 0, 0) );
00050 }
00051
00052
00053 mSmgr->addSkyDomeSceneNode( mDriver->getTexture("media/alien_world.jpg"), 16, 16, 1.0, 2.0 );
00054
00055
00056 mDevice->setEventReceiver( this );
00057
00058
00059 mGameStatus=eGameStart;
00060 mWorld->showStartScreen();
00061 }
00062
00063
00067 cGame::~cGame( void )
00068 {
00069
00070 if( mWorld )
00071 delete mWorld;
00072 delete mRNG;
00073
00074
00075 mDevice->setEventReceiver( NULL );
00076
00077
00078 mSmgr->clear();
00079 }
00080
00081
00085 bool cGame::OnEvent( const SEvent& event )
00086 {
00087 switch( mGameStatus ) {
00088 case eGameStart:
00089
00090 if( event.EventType == EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown ) {
00091 switch (event.KeyInput.Key) {
00092 case KEY_ESCAPE:
00093 mGameStatus=eGameQuit;
00094 return true;
00095 case KEY_KEY_S:
00096 mDriver->writeImageToFile( mDriver->createScreenShot(), "screenshot.png" );
00097 return true;
00098 default:
00099 mWorld->getSoul()->updateView();
00100 mGameStatus=eGameRuns;
00101 return true;
00102 }
00103 }
00104
00105
00106 if( event.EventType == EET_MOUSE_INPUT_EVENT ) {
00107 switch( event.MouseInput.Event ) {
00108 case EMIE_LMOUSE_PRESSED_DOWN:
00109 mWorld->getSoul()->updateView();
00110 mGameStatus=eGameRuns;
00111 return true;
00112 default:
00113 return true;
00114 }
00115 }
00116 break;
00117 case eGameRuns:
00118
00119 if( event.EventType == EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown ) {
00120 if( event.KeyInput.Key==KEY_TAB ) {
00121 if( !mConsole->isVisible() )
00122 mConsole->setVisible( true );
00123 else if( !event.KeyInput.Control )
00124 mConsole->setVisible( false );
00125 return true;
00126 } else if( event.KeyInput.Key==KEY_ESCAPE ) {
00127 if( mConsole->isVisible() )
00128 mConsole->setVisible( false );
00129 else
00130 mGameStatus=eGameQuit;
00131 return true;
00132 }
00133
00134 if( mConsole->isVisible() ) {
00135 mConsole->handleKeyPress( event.KeyInput.Char, event.KeyInput.Key, event.KeyInput.Shift, event.KeyInput.Control );
00136 return true;
00137 }
00138
00139 cEntityBase* entityBelow;
00140 switch( event.KeyInput.Key ) {
00141 case KEY_KEY_S:
00142 mDriver->writeImageToFile( mDriver->createScreenShot(), "screenshot.png" );
00143 return true;
00144 case KEY_KEY_T:
00145 entityBelow = mWorld->findEntity();
00146 if( entityBelow )
00147 if( mWorld->createEntity( eTree, entityBelow ) )
00148 mLogger->log( "Planted a tree", ELL_INFORMATION );
00149 return true;
00150 case KEY_KEY_B:
00151 entityBelow = mWorld->findEntity();
00152 if( entityBelow )
00153 if( mWorld->createEntity( eBoulder, entityBelow ) )
00154 mLogger->log( "Planted a boulder", ELL_INFORMATION );
00155 return true;
00156 case KEY_KEY_R:
00157 entityBelow = mWorld->findEntity();
00158 if( entityBelow )
00159 if( mWorld->createEntity( eRobot, entityBelow ) )
00160 mLogger->log( "Planted a robot", ELL_INFORMATION );
00161 return true;
00162 case KEY_KEY_H:
00163 mWorld->hyperjump();
00164 return true;
00165 case KEY_KEY_A:
00166 entityBelow = mWorld->findEntity();
00167 if( entityBelow )
00168 mWorld->absorbEntity( entityBelow );
00169 return true;
00170 case KEY_KEY_O:
00171 mLogger->log( "Options", ELL_INFORMATION );
00172 return true;
00173 case KEY_KEY_Q:
00174 entityBelow = mWorld->findEntity();
00175 if( entityBelow )
00176 mWorld->transferSoul( entityBelow );
00177 return true;
00178 case KEY_KEY_U:
00179 mWorld->getSoul()->turnAround();
00180 return true;
00181 default:
00182 return true;
00183 }
00184 }
00185
00186
00187 if( event.EventType == EET_MOUSE_INPUT_EVENT ) {
00188 cEntityBase* entityBelow;
00189 switch( event.MouseInput.Event ) {
00190 case EMIE_MOUSE_MOVED: {
00191 gui::ICursorControl* cursorcontrol = mDevice->getCursorControl();
00192 core::position2d<f32> pos = cursorcontrol->getRelativePosition();
00193
00194 if( (pos.X!=0.5f) || (pos.Y!=0.5f) ) {
00195 mWorld->getSoul()->changeView( pos.X-0.5f, pos.Y-0.5f );
00196
00197 cursorcontrol->setPosition( 0.5f, 0.5f );
00198 }
00199 return true;
00200 }
00201 case EMIE_LMOUSE_PRESSED_DOWN:
00202 entityBelow = mWorld->findEntity();
00203 if( entityBelow )
00204 mWorld->absorbEntity( entityBelow );
00205 return true;
00206 case EMIE_RMOUSE_PRESSED_DOWN:
00207 entityBelow = mWorld->findEntity();
00208 if( entityBelow )
00209 mWorld->transferSoul( entityBelow );
00210 return true;
00211 default:
00212 return true;
00213 }
00214
00215 }
00216
00217 if( event.EventType == EET_LOG_TEXT_EVENT ) {
00218 mConsole->logMessage( event.LogEvent.Level, event.LogEvent.Text );
00219 return true;
00220 }
00221 break;
00222 case ePlayerIsDead:
00223 break;
00224 case ePlayerHasWon:
00225 break;
00226 case( eGameQuit ):
00227
00228 break;
00229 }
00230
00231 return false;
00232 }
00233
00234
00238 void cGame::drawInterface( void )
00239 {
00240
00241 mDriver->draw2DRectangle( video::SColor(80,255,255,255),
00242 core::rect<s32>(mConfiguration->width/2-20,mConfiguration->height/2-1,
00243 mConfiguration->width/2-5,mConfiguration->height/2+1) );
00244 mDriver->draw2DRectangle( video::SColor(80,255,255,255),
00245 core::rect<s32>(mConfiguration->width/2+5,mConfiguration->height/2-1,
00246 mConfiguration->width/2+20,mConfiguration->height/2+1) );
00247 mDriver->draw2DRectangle( video::SColor(80,255,255,255),
00248 core::rect<s32>(mConfiguration->width/2-1,mConfiguration->height/2-20,
00249 mConfiguration->width/2+1,mConfiguration->height/2-5) );
00250 mDriver->draw2DRectangle( video::SColor(80,255,255,255),
00251 core::rect<s32>(mConfiguration->width/2-1,mConfiguration->height/2+5,
00252 mConfiguration->width/2+1,mConfiguration->height/2+20) );
00253
00254
00255 int energy=mWorld->getSoul()->getEnergy();
00256 int xPos=10;
00257 int nrIcons;
00258
00259
00260 mDriver->draw2DRectangle( video::SColor(255,0,0,0), core::rect<s32>(0,0,mConfiguration->width,17) );
00261
00262
00263 nrIcons = (int)floor(energy/15.0);
00264 energy -= nrIcons*15;
00265 for( int i=0; i<nrIcons; i++ ) {
00266 mDriver->draw2DImage( tNrgRobot5, core::position2d<s32>(xPos, 2) );
00267 xPos+=32;
00268 }
00269
00270
00271 nrIcons = (int)floor(energy/3.0);
00272 energy -= nrIcons*3;
00273 for( int i=0; i<nrIcons; i++ ) {
00274 mDriver->draw2DImage( tNrgRobot, core::position2d<s32>(xPos, 2) );
00275 xPos+=32;
00276 }
00277
00278
00279 nrIcons = (int)floor(energy/2.0);
00280 energy -= nrIcons*2;
00281 for( int i=0; i<nrIcons; i++ ) {
00282 mDriver->draw2DImage( tNrgBoulder, core::position2d<s32>(xPos, 2) );
00283 xPos+=32;
00284 }
00285
00286
00287 nrIcons = energy;
00288 for( int i=0; i<nrIcons; i++ ) {
00289 mDriver->draw2DImage( tNrgTree, core::position2d<s32>(xPos, 2) );
00290 xPos+=32;
00291 }
00292
00293
00294 const int barWidth=128;
00295 const int barHeight=8;
00296 mDriver->draw2DRectangle( video::SColor(255,252,0,0),
00297 core::rect<s32>(mConfiguration->width-32-barWidth-3,0,
00298 mConfiguration->width-32+3,barHeight+4) );
00299 mDriver->draw2DRectangle( video::SColor(255,0,0,0),
00300 core::rect<s32>(mConfiguration->width-32-barWidth,2,
00301 mConfiguration->width-32,barHeight+2) );
00302
00303
00304
00305 if( 1 ) {
00306 unsigned long mask;
00307 for( int i=0; i<barHeight; i+=2 ) {
00308 mask = mRNG->genrand_int32();
00309 for( int j=0; j<barWidth/2; j+=2 ) {
00310 if( mask & (1<<j) )
00311 mDriver->draw2DRectangle( video::SColor(255,0,180,0),
00312 core::rect<s32>(mConfiguration->width-32-barWidth+j,2+i,
00313 mConfiguration->width-32-barWidth+j+2,4+i) );
00314 }
00315 if( 1 )
00316 for( int j=barWidth/2; j<barWidth; j+=2 ) {
00317 if( mask & (1<<j) )
00318 mDriver->draw2DRectangle( video::SColor(255,0,180,0),
00319 core::rect<s32>(mConfiguration->width-32-barWidth+j,2+i,
00320 mConfiguration->width-32-barWidth+j+2,4+i) );
00321 }
00322 }
00323 }
00324 }
00325
00326
00330 void cGame::run( void )
00331 {
00332 int lastFPS = -1, fps;
00333 double oldtime=0, period=0, timeset=0;
00334 core::stringw title = L"The Sentinel [";
00335 title += mDriver->getName();
00336 title += "] FPS: ";
00337 core::stringw fulltitle;
00338
00339 gui::IGUIFont* font=mEnv->getFont("media/zeroes.xml");
00340
00341 timeset=(double)(mDevice->getTimer()->getRealTime());
00342 while( mDevice->run() && mGameStatus!=eGameQuit ) {
00343 if( mDevice->isWindowActive() ) {
00344
00345 period = mConfiguration->fps_period-((double)(mDevice->getTimer()->getRealTime())-oldtime);
00346 if( period>0 )
00347 mDevice->sleep( (u32)period, false );
00348 oldtime=(double)(mDevice->getTimer()->getRealTime());
00349
00350 switch( mGameStatus ) {
00351 case( eGameStart ):
00352
00353 mDriver->beginScene( true, true, video::SColor(255, 0, 0, 0) );
00354 mSmgr->drawAll();
00355 mEnv->drawAll();
00356 font->draw( mWorld->GetName().c_str(), core::rect<s32>(mConfiguration->width/2, 50, mConfiguration->width/2, 50),
00357 video::SColor(255,255,255,255), true, false, NULL );
00358 mDriver->endScene();
00359 break;
00360 case( eGameRuns ):
00361 mDriver->beginScene( true, true, video::SColor(255, 0, 60, 156) );
00362
00363 mSmgr->drawAll();
00364 mEnv->drawAll();
00365
00366
00367 drawInterface();
00368 mConsole->renderConsole( mEnv, mDriver, 1000 );
00369
00370 mDriver->endScene();
00371
00372
00373 #ifdef USE_IRRKLANG
00374 {
00375 scene::ICameraSceneNode* cam = mSmgr->getActiveCamera();
00376 mAudioDevice->setListenerPosition( cam->getAbsolutePosition(), cam->getTarget() );
00377 }
00378 #endif
00379
00380
00381 if( isPlayerDead() ) {
00382
00383 delete mWorld;
00384 mWorld=NULL;
00385 mSmgr->clear();
00386
00387 mGameStatus=ePlayerIsDead;
00388 timeset=(double)(mDevice->getTimer()->getRealTime());
00389 }
00390 break;
00391 case( ePlayerIsDead ):
00392 mDriver->beginScene( true, true, video::SColor(255, 0, 0, 0) );
00393
00394 mSmgr->drawAll();
00395 mEnv->drawAll();
00396
00397 mDriver->endScene();
00398 if( (double)(mDevice->getTimer()->getRealTime())-timeset>3000 )
00399 mGameStatus=eGameQuit;
00400 break;
00401 case( ePlayerHasWon ):
00402 mDriver->beginScene( true, true, video::SColor(255, 0, 60, 156) );
00403 mDriver->endScene();
00404 mGameStatus=eGameQuit;
00405 break;
00406 case( eGameQuit ):
00407
00408 break;
00409 }
00410
00411
00412 fps = mDriver->getFPS();
00413 if( lastFPS!=fps ) {
00414 fulltitle = title;
00415 fulltitle += fps;
00416
00417 mDevice->setWindowCaption( fulltitle.c_str() );
00418 lastFPS = fps;
00419 }
00420 }
00421 }
00422
00423
00424 }