ScreenFPS.cpp

Go to the documentation of this file.
00001 #include "ScreenFPS.h"
00002 #include "MercuryDisplay.h"
00003 #include "MercuryTheme.h"
00004 #include "MercuryInput.h"
00005 #include "MercuryShapes.h"
00006 #include "MercuryLog.h"
00007 #include "MercuryTextureManager.h"
00008 #include "MercurySoundSourceWAV.h"
00009 
00010 KeyMappingWithCode( button_a, "0-97" );
00011 KeyMappingWithCode( button_b, "0-98" );
00012 KeyMappingWithCode( button_s, "0-115" );
00013 KeyMappingWithCode( button_d, "0-100" );
00014 KeyMappingWithCode( button_w, "0-119" );
00015 KeyMappingWithCode( button_mouse1, "0-1" );
00016 KeyMappingWithCode( button_mouse2, "0-2" );
00017 KeyMappingWithCode( button_u, "0-117" );
00018 KeyMappingWithCode( button_t, "0-116" );
00019 KeyMappingWithCode( button_space, "0-32" );
00020 
00021 REGISTER_SCREEN_CLASS( ScreenFPS );
00022 
00023 #define     MC_INPUTMAPPED      1       //convention: MESSAGE CODE
00024 #define     MC_EXPLOSION        2       //convention: MESSAGE CODE
00025 
00026 ScreenFPS::~ScreenFPS()
00027 {
00028     m_pCamera = NULL;
00029 }
00030 
00031 void ScreenFPS::Init()
00032 {
00033     ScreenOutdoors::Init();
00034 
00035     pTweenCommands.resize(4);
00036     pTweenCommands[0].sAnimationName = "run_lower";
00037     pTweenCommands[0].fPercent = .5;
00038     pTweenCommands[1].sAnimationName = "run_upper";
00039     pTweenCommands[1].fPercent = .25;
00040 
00041     pTweenCommands[2].sAnimationName = "shootright_upper";
00042     pTweenCommands[2].bLoop = pTweenCommands[2].bRunning = false;
00043     pTweenCommands[3].sAnimationName = "shootleft_upper";
00044     pTweenCommands[3].fRate = 2;
00045     pTweenCommands[3].bLoop = pTweenCommands[3].bRunning = false;
00046 
00047     m_pPlayer.SetName( "jupiter" );
00048     m_pPlayer.Init();
00049     m_pPlayer.SetRotX( 90 );
00050     m_pPlayer.SetScale( MercuryPoint( 0.1f,0.1f,0.1f ) );
00051     m_pPlayer.Load( GET_MODEL_BY_NAME( "jupiter" ) );
00052     m_pPlayer.SetAnimationState( pTweenCommands );
00053     AddPerspObject( &m_pPlayer );
00054 
00055     pBullet.SetName( "BULLET" );
00056     pBullet.Init();
00057     pBullet.NotifyClass( this, "rayhit" );
00058     pBullet.SetDrawOrder( 10000 );
00059     AddPerspObject( &pBullet, false );
00060 
00061     m_Aimer.SetName( "BULLET Aimer" );
00062     m_Aimer.Init();
00063     m_Aimer.NotifyClass( this, "aimhit" );
00064     m_oldInter = m_interactable = false;
00065     fClosestAimerObject = 100000;
00066 
00067     m_closestHitObjectDistance = 100000;
00068     m_runObjectHitCode = false;
00069 
00070     pPhysics.SetName( "PHYSGUN" );
00071     pPhysics.Init();
00072     pPhysics.NotifyClass( this, "physhit" );
00073     pPhysics.SetDrawOrder( 10000 );
00074     AddPerspObject( &pPhysics, false );
00075     iPhysicsObject = 0;
00076     fClosestPhysicsObject = 100000;
00077 
00078     m_pINI.Open( GET_FILE_BY_NAME( "IniFile" ) );
00079 
00080     m_pWorld.Init();
00081     m_pWorld.LoadFromINI( m_pINI, THEME.GetMetricS( m_name, "WorldName" ) );
00082     AddPerspObject( &m_pWorld );
00083 
00084     m_fCamera.SetName( "Camera" );
00085     m_fCamera.Init();
00086     m_fCamera.SetUp(MercuryPoint(0,0,1));
00087     m_pCamera = &m_fCamera;
00088     m_fCamera.Tweening.AddCommand( THEME.GetMetricS( m_name, "CamTween" ), MercuryTweenState::LOCAL, "CamTween" );
00089 
00090     m_fTimeSinceLastShot = 0;
00091     m_fForwardMovement = 0;
00092 
00093     m_bFPS = true;
00094     m_sprCrosshairs.SetName( "Crosshairs" );
00095     m_sprCrosshairs.Init();
00096     m_sprCrosshairs.LoadImage( "GRAPHIC:targetret2.png" );
00097     m_sprCrosshairs.SetPosition( MercuryPoint( 320,240, 0 ) );
00098     m_sprCrosshairs.SetDrawOrder( 10001 );
00099     m_sprCrosshairs.Tweening.AddCommand( THEME.GetMetricS( m_name, "CrosshairsOnTarget" ), MercuryTweenState::LOCAL, "OnTarget" );
00100     m_sprCrosshairs.Tweening.AddCommand( THEME.GetMetricS( m_name, "CrosshairsOffTarget" ), MercuryTweenState::LOCAL, "OffTarget" );
00101     m_sprCrosshairs.Tweening.ExecuteCommand("OffTarget", PStack());
00102     AddOrthoObject( &m_sprCrosshairs );
00103 
00104     m_sprCrosshairsCenter.SetName( "CrosshairsCenter" );
00105     m_sprCrosshairsCenter.Init();
00106     m_sprCrosshairsCenter.LoadImage( "GRAPHIC:targetret.png" );
00107     m_sprCrosshairsCenter.SetPosition( MercuryPoint( 320,240, 0 ) );
00108     m_sprCrosshairsCenter.SetDrawOrder( 10000 );
00109     AddOrthoObject( &m_sprCrosshairsCenter );
00110 
00111     RegisterMessage( MC_INPUTMAPPED, "mappedinput" );
00112     RegisterMessage( MC_EXPLOSION, "DoExplosion" );
00113     m_slowDown = false;
00114     m_fistExplosion = m_donefirst = false;
00115 
00116     Tweening.AddCommand(THEME.GetMetricS( GetName(), "BlastParticle" ) , MercuryTweenState::GLOBAL, "BlastParticle" ) ;
00117 
00118     MercuryObject* instructions = new MercuryObject;
00119     instructions->Init();
00120     instructions->SetName("Instructions");
00121     unsigned int num = THEME.GetMetricI( GetName(), "NumInstructions" );
00122     unsigned int space = 0;
00123     for (unsigned int i = 0; i < num; ++i)
00124     {
00125         MercuryText* t = new MercuryText;
00126 
00127 //      t->SetName(ssprintf("Instruction%d", i));
00128         t->Init();
00129         t->SetFont(THEME.GetMetricS( GetName(), "Font" ));
00130         t->SetSize(THEME.GetMetricI( GetName(), "FontSize" ));
00131         t->MoveY(space);
00132         t->SetText(THEME.GetMetricS( GetName(), ssprintf("Instruction%d", i)));
00133         instructions->AddObject(t, true);
00134         space += THEME.GetMetricI( GetName(), "InstructionSpace" );
00135     }
00136     instructions->Tweening.AddCommand(THEME.GetMetricS( GetName(), instructions->GetName() + "Tween" ));
00137     AddOrthoObject(instructions, true);
00138     
00139     MercurySoundSourceWAV* music = new MercurySoundSourceWAV;
00140     music->Open("FILE:test.wav");
00141     music->Play();
00142 }
00143 
00144 void ScreenFPS::CalculateMovement(MercuryODEObject* control)
00145 {
00146     int dx=0;
00147     int dy=0;
00148     if ( INPUTMAN->IsButtonDown( button_d ) )
00149         dy -= 5;
00150     if ( INPUTMAN->IsButtonDown( button_a ) )
00151         dy += 5;
00152     if ( INPUTMAN->IsButtonDown( button_w ) )
00153         dx += 5;
00154     if ( INPUTMAN->IsButtonDown( button_s ) )
00155         dx -= 5;
00156 
00157     float Amplitude = SQRT(float((dx*dx)+(dy*dy)));
00158     float AngleToGo=ATAN2(float(dx),float(-dy));
00159 
00160     MercuryPoint Target = m_pWorld.GetODEObjectByName( "Control" )->GetPosition();
00161     MercuryPoint From = Target - pTarget;
00162 
00163     float AngleDiff=ATAN2((From-Target).x,(From-Target).y);
00164     float RealAngle = AngleToGo - AngleDiff - 1.57f;
00165 
00166     dBodyEnable( control->m_oBody );
00167     dBodySetAngularVel( control->m_oBody, COS(RealAngle)*Amplitude,SIN(RealAngle)*Amplitude,0); 
00168     
00169     //Handle Jumping
00170     if( INPUTMAN->IsButtonDown( button_space ) )
00171     {
00172         dBodyAddForce( control->m_oBody, SIN(RealAngle)*Amplitude*800,-COS(RealAngle)*Amplitude*800,3900 );
00173     }
00174 
00175     //Now, Update the robot's animations
00176     PlayRobotAnimations(dx);
00177 }
00178 
00179 void ScreenFPS::PlayRobotAnimations(int dx)
00180 {
00181     if (m_fForwardMovement > 0 )
00182         m_fForwardMovement = (m_fForwardMovement + float(dx)/50) - 0.025f;
00183     else
00184         m_fForwardMovement = (m_fForwardMovement + float(dx)/50) + 0.025f;
00185 
00186     m_fForwardMovement = Clamp( m_fForwardMovement, -1.0f, 1.0f );
00187 
00188     if( m_fForwardMovement < 0.05 && m_fForwardMovement > -0.05f )
00189         m_fForwardMovement = 0;
00190 
00191     m_pPlayer.GetAllAnimationStates( pTweenCommands );
00192     pTweenCommands[0].fPercent = m_fForwardMovement;
00193     pTweenCommands[0].fRate = ABS(m_fForwardMovement)*1.5f;
00194     pTweenCommands[1].fPercent = m_fForwardMovement/2;
00195     pTweenCommands[1].fRate = ABS(m_fForwardMovement)*1.5f;
00196 
00197     if( m_fTimeSinceLastShot == 0 )
00198         pTweenCommands[3].Trigger();
00199 
00200     m_pPlayer.SetAnimationState( pTweenCommands );
00201 }
00202 
00203 void ScreenFPS::Update( const float dTime )
00204 {
00205     if (dTime == 0)
00206         return;
00207 
00208     if ( m_bFirstUpdate )
00209     {
00210         m_bFirstUpdate = false;
00211         return;
00212     }
00213 
00214     float adjTime = dTime;
00215     if (m_slowDown > 0)
00216     {
00217         m_slowDown -= dTime;
00218         adjTime /= 5;
00219     }
00220 
00221     if ((m_slowDown <= 0) && m_fistExplosion)
00222     {
00223         m_donefirst = true;
00224         m_slowDown = 0;
00225     }
00226 
00227     //hack to move water
00228     MercuryODEObjectLoadable* water = (MercuryODEObjectLoadable*)m_pWorld.GetODEObjectByName("Water");
00229     if (water)
00230     {
00231         water->GetGLState().Disable(MGLS_OPAQUE);
00232         MercuryShape* s = (MercuryShape*)water->m_vMercuryShapes[0];
00233         if (s)
00234         {
00235             MercuryMaterial* mw = s->GetMaterial(0);
00236             if (mw)
00237             {
00238                 mw->EditTexture(0)->MoveY( dTime/THEME.GetMetricF( m_name, "WaterPeriodSecY" ));
00239                 mw->EditTexture(0)->MoveX( dTime/THEME.GetMetricF( m_name, "WaterPeriodSecX" ));
00240             }
00241         }
00242     }
00243 
00244     int x, y;
00245     INPUTMAN->GetCursorPosition(x, y);
00246     MercuryODEObject* control = m_pWorld.GetODEObjectByName( "Control" );
00247 
00248     CalculateMovement(control);
00249 
00250     //Must happen before aim shot to keep targeting smooth
00251     CalculateLook(x, y, control);
00252 
00253     ScreenOutdoors::Update( adjTime );
00254 
00255     //Do before Physics Update to stay smooth
00256     m_Aimer.Disable();
00257     m_Aimer.EnableForShot( m_pWorld.GetWorldSpaceID(), 50000, m_pGun, pLookAt );
00258 
00259     //Must happen after physics update to stay smooth
00260     TweenCamera(x, y, control);
00261 
00262     m_pPlayer.SetPosition( control->GetPosition( ) );
00263 
00264     pPhysics.Disable();
00265     //do physics if necessiary
00266     if ( iPhysicsObject != 0 )
00267     {
00268         //Physics!
00269         MercuryPoint pNewPos = m_pGun + pLookAt.Normalize() * fClosestPhysicsObject;
00270         fClosestPhysicsObject = fClosestPhysicsObject * 0.95f + 2;
00271         MercuryPoint pCurrentPos( dBodyGetPosition( (dBodyID)iPhysicsObject ) );
00272         //dBodySetPosition( (dBodyID)iPhysicsObject, pPos.x, pPos.y, pPos.z );
00273 
00274         MercuryPoint pDir = pNewPos-pCurrentPos;
00275         pDir *= (0.4f/dTime);
00276         dBodySetLinearVel( (dBodyID)iPhysicsObject, pDir.x, pDir.y, pDir.z );
00277         dBodyEnable( (dBodyID)iPhysicsObject );
00278     }
00279 
00280 //      m_sprCrosshairs.SetHide( (m_slowDown > 0 && !m_donefirst) );
00281 
00282     m_fTimeSinceLastShot += dTime;
00283     pBullet.Disable();
00284     if( m_fTimeSinceLastShot > .25 && INPUTMAN->IsButtonDown( button_mouse1 ) )
00285     {
00286         m_fTimeSinceLastShot = 0;
00287         pBullet.EnableForShot( m_pWorld.GetWorldSpaceID(), 50000, 
00288             m_pGun, pLookAt );
00289     }
00290 
00291     //aimer result
00292     {
00293         if ( m_interactable )
00294         {
00295             if( m_interactable != m_oldInter )
00296             {
00297                 m_sprCrosshairs.Tweening.StopTweening();
00298                 m_sprCrosshairs.Tweening.ExecuteCommand("OnTarget", PStack());
00299             }
00300         }
00301         else
00302         {
00303             if( m_interactable != m_oldInter )
00304             {
00305                 m_sprCrosshairs.Tweening.StopTweening();
00306                 m_sprCrosshairs.Tweening.ExecuteCommand("OffTarget", PStack());
00307             }
00308         }
00309         m_oldInter = m_interactable;
00310         MercuryPoint xy = PointToScreenCoord(m_perspProjection.m_matrix, m_fCamera.GetFinalMatrix(), m_aimPos, DISPLAY->GetBasedDimensions());
00311         xy.z = 0;
00312         m_sprCrosshairs.SetPosition(xy);
00313         fClosestAimerObject = 10000;
00314     }
00315 
00316     if (m_runObjectHitCode)
00317         ObjectHit(m_closestHitPosition, m_closestHitObject, m_closestHitRay);
00318 
00319     m_pPlayer.SetRotY( -float(x)/300*RADDEG );
00320 
00321     //Tricky: find where the gun is shooting from, for this we can use some basic trigonometry.
00322     m_pGun = control->GetPosition();
00323     m_pGun.x += cos( -float(x)/300 + Q_PI/4)*7;
00324     m_pGun.y += sin( -float(x)/300 + Q_PI/4)*7;
00325 }
00326 
00327 void ScreenFPS::CalculateLook(int x, int y, MercuryODEObject* control)
00328 {
00329 
00330     if( ( y - m_iSlidingF ) > 470 )
00331         m_iSlidingF = y - 470;
00332     if( ( y - m_iSlidingF ) < -470 )
00333         m_iSlidingF = y + 470;
00334 
00335     pTarget.x = cos( -float(x)/300 );
00336     pTarget.y = sin( -float(x)/300 );
00337     pTarget.z = 0;
00338 
00339     pLookAt = pTarget;
00340 
00341     pLookAt.x *= cos( -float(y-m_iSlidingF)/300 );
00342     pLookAt.y *= cos( -float(y-m_iSlidingF)/300 );
00343     pLookAt.z = sin( -float(y-m_iSlidingF)/300 );
00344 }
00345 
00346 void ScreenFPS::TweenCamera(int x, int y, MercuryODEObject* control)
00347 {
00348     if ( !((m_slowDown > 0) && !m_donefirst))
00349         if( !m_bFPS )
00350         {
00351             m_fCamera.Tweening.StopTweening();
00352 
00353             m_fCamera.Tweening.ExecuteCommand( "CamTween", PStack( 
00354                     PSElement( control->GetX()-COS(-float(x)/300)*30 ),
00355                     PSElement( control->GetY()-SIN(-float(x)/300)*30 ),
00356                     PSElement( (control->GetZ())+25)));
00357 
00358             MercuryPoint pos = m_fCamera.GetPosition();
00359 
00360             m_pPlayer.SetHide( false );
00361             m_fCamera.SetTarget( pLookAt + pos );
00362 
00363             MercuryPoint pNewUp = pLookAt.CrossProduct( MercuryPoint( 0,0,1 ) );
00364             pNewUp = pNewUp.CrossProduct( pLookAt );
00365             m_fCamera.SetUp( pNewUp );
00366             m_fCamera.Prerender();
00367         } else {
00368             m_fCamera.SetPosition( control->GetPosition() );
00369             m_pPlayer.SetHide( true );
00370             m_fCamera.SetTarget( pLookAt + control->GetPosition() );
00371 
00372             MercuryPoint pNewUp = pLookAt.CrossProduct( MercuryPoint( 0,0,1 ) );
00373             pNewUp = pNewUp.CrossProduct( pLookAt );
00374             m_fCamera.SetUp( pNewUp );
00375         }
00376 }
00377 
00378 void ScreenFPS::Message( int Message, PStack & data, const MString &name )
00379 {
00380     switch ( Message ) 
00381     {
00382     case MC_INPUTMAPPED:
00383         {
00384             InputMessageStruct c(data);
00385             if ( c.code == button_u )
00386             {
00387                 if ( c.type == IET_DOWN )
00388                 {
00389                     m_bFPS = !m_bFPS;
00390                 }
00391             } else if ( c.code == button_b && c.type != IET_RELEASE ) {
00392                 m_pWorld.GenAndAddToWorld( m_pINI, "MyBall", "Ball", "MercuryODEObjectLoadable", 1, MercuryPoint(0,0,100));
00393             } else if ( c.code == button_t && c.type == IET_DOWN ) {
00394                 m_pWorld.GenAndAddToWorld( m_pINI, "MyBall", "coke", "ExplodingCokeCan", 1, MercuryPoint(0,0,100));
00395             } else if ( c.code == button_mouse2 )
00396             {
00397                 if ( c.type == IET_DOWN )
00398                 {
00399                     pPhysics.EnableForShot( m_pWorld.GetWorldSpaceID(), 50000, 
00400                         m_pGun, pLookAt );
00401                 }
00402                 else if( c.type == IET_RELEASE )
00403                 {
00404                     iPhysicsObject = 0;
00405                     fClosestPhysicsObject = 100000;
00406                 }
00407             }
00408         }
00409         break;
00410     case MC_EXPLOSION:
00411         {
00412             if (!m_fistExplosion)
00413             {
00414                 m_slowDown += 2;
00415 //              MercuryODEObject * c = m_pWorld.GetODEObjectByName( "Control" );
00416 
00417                 MercuryPoint coke;
00418                 coke.SetX(data.PeekItem(0).GetValueF());
00419                 coke.SetY(data.PeekItem(1).GetValueF());
00420                 coke.SetZ(data.PeekItem(2).GetValueF());
00421                 MercuryPoint a = (coke - m_fCamera.GetPosition()).CrossProduct( MercuryPoint(0,0,1));
00422                 a.NormalizeSelf();
00423                 m_fCamera.Tweening.StopTweening();
00424                 m_fCamera.Tweening.AddCommand( ssprintf( "linear,%f;x,%f;y,%f;z,%f", m_slowDown/5, coke.x-50, coke.y-50, coke.z+50));
00425 
00426     //          m_fCamera.Tweening.AddCommand( ssprintf( "linear,0.4;addx,%f;addy,%f;addz,%f", a.x*300, a.y*300, a.z*-600));
00427     //          m_fCamera.Tweening.AddCommand( ssprintf( "linear,0.2;movex,%f;y,%f;z,%f;",  
00428                 m_fCamera.SetTarget(coke);
00429     //          m_fCamera.SetTarget(c->GetPosition() + MercuryPoint( 0,0,15));
00430 
00431                 MercuryPoint pNewUp = pLookAt.CrossProduct( MercuryPoint( 0,0,1 ) );
00432                 pNewUp = pNewUp.CrossProduct( pLookAt );
00433                 m_fCamera.SetUp( pNewUp );
00434                 m_pPlayer.SetHide( false );
00435                 m_fistExplosion = true;
00436             }
00437         }
00438         break;
00439     };
00440 
00441     ScreenOutdoors::Message( Message, data, name );
00442 }
00443 
00444 bool ScreenFPS::Command( PStack & ret, const char * command, PStack & args )
00445 {
00446     if ( strcmp( command, "physhit" ) == 0 )
00447     {
00448         if( args.PeekItem( 0 ).GetValueS().compare( "EarthControl" ) == 0 )
00449             return true;
00450         MercuryODEObjectLoadable * L = (MercuryODEObjectLoadable*)args.PeekItem( 1 ).GetValueV();
00451         if( L->m_oBody )
00452         {
00453             MercuryPoint pPos = MercuryPoint(  args.PeekItem( 2 ).GetValueF(), 
00454                 args.PeekItem( 3 ).GetValueF(), 
00455                 args.PeekItem( 4 ).GetValueF() ) - m_pGun;
00456             
00457             float fDistance = pPos.Magnitude();
00458 
00459             if( fDistance < fClosestPhysicsObject )
00460             {
00461                 iPhysicsObject = (MVPtr)L->m_oBody;
00462                 fClosestPhysicsObject = fDistance;
00463             }
00464         }
00465         return true;
00466     }
00467     else if ( strcmp( command, "rayhit" ) == 0 )
00468     {
00469         if( args.PeekItem( 0 ).GetValueS().compare( "EarthControl" ) == 0 )
00470             return true;
00471         //Order of args: NameOfObject, (void*)ObjectHandle, fX, fY, fZ, fNX, fNY, fNZ
00472         MercuryODEObjectLoadable * L = (MercuryODEObjectLoadable*)args.PeekItem( 1 ).GetValueV();
00473 
00474         MercuryPoint position(MercuryPoint( args.PeekItem( 2 ).GetValueF(), args.PeekItem( 3 ).GetValueF(), args.PeekItem( 4 ).GetValueF() ));
00475         MercuryPoint ray(MercuryPoint( args.PeekItem( 5 ).GetValueF(), args.PeekItem( 6 ).GetValueF(), args.PeekItem( 7 ).GetValueF() ));
00476         ray.NormalizeSelf();
00477 
00478         float fDistance = (m_pPlayer.GetPosition()-position).Magnitude();
00479         if ( fDistance < m_closestHitObjectDistance )
00480         {
00481             m_closestHitObjectDistance = fDistance;
00482             m_runObjectHitCode = true;
00483             m_closestHitRay = ray;
00484             m_closestHitPosition = position;
00485             m_closestHitObject = L->m_oBody;
00486         }
00487         return true;
00488     }
00489     else if ( strcmp( command, "aimhit" ) == 0 )
00490     {
00491         if( args.PeekItem( 0 ).GetValueS().compare( "EarthControl" ) == 0 )
00492             return true;
00493         MercuryODEObjectLoadable * L = (MercuryODEObjectLoadable*)args.PeekItem( 1 ).GetValueV();
00494 
00495         MercuryPoint pPos = MercuryPoint(  args.PeekItem( 2 ).GetValueF(), 
00496             args.PeekItem( 3 ).GetValueF(), 
00497             args.PeekItem( 4 ).GetValueF() );
00498             
00499         float fDistance = (m_pPlayer.GetPosition()-pPos).Magnitude();
00500 
00501         if( fDistance < fClosestAimerObject )
00502         {
00503             if (L->m_oBody)
00504                 m_interactable = true;
00505             else
00506                 m_interactable = false;
00507 
00508             fClosestAimerObject = fDistance;
00509             m_aimPos = pPos;
00510         }
00511 
00512         return true;
00513     }
00514 
00515     return ScreenOutdoors::Command( ret, command, args );
00516 }
00517 
00518 void ScreenFPS::ObjectHit(const MercuryPoint& position, dBodyID id, const MercuryPoint& ray)
00519 {
00520     m_runObjectHitCode = false;
00521     m_closestHitObjectDistance = 100000;
00522 
00523     if( id )
00524     {
00525         dBodyEnable( id );
00526         dBodyAddForce( id, 70000*ray.x,
00527                     70000*ray.y,
00528                     70000*ray.z );
00529     }
00530     MercuryPoint p2(ray*0.01);
00531 
00532     MercuryLight* l = (MercuryLight*)Spawn("MercuryLight", "Explosion light");
00533     l->SetPosition(position-p2);
00534     l->SetStatic(true);
00535     l->SetLightType(LT_POINT);
00536     l->SetAttenuation(.001f,Attenuation::QUADRATIC);
00537     l->Tweening.AddCommand(THEME.GetMetricS( GetName(), "LightExplosion", "" ));
00538     DISPLAY->AddLight(l);
00539 
00540     MercuryColor color1, color2, color;
00541     float fRadius = ((rand()%1000)/100.0f) + 10.0f;
00542     float scale = THEME.GetMetricF( GetName(), "BlastParticleScale" );
00543     MercuryParticleField* pfield = (MercuryParticleField*)Spawn( "MercuryParticleField", "BlastParticles", PERSPECTIVE );
00544     pfield->LoadImage( THEME.GetMetricS( GetName(), "BlastParticleImage" ));
00545     pfield->Tweening.AddCommand( THEME.GetMetricS( GetName(), "BlastParticleField" ) );
00546     pfield->GetGLState().Disable(MGLS_OPAQUE);
00547     color1.FromString( THEME.GetMetricS( GetName(), "BlastParticleBaseColor1" ) );
00548     color2.FromString( THEME.GetMetricS( GetName(), "BlastParticleBaseColor2" ) );
00549 
00550     for (unsigned int i = 0; i < 25; ++i)
00551     {
00552         MercuryObject* particle = pfield->SpawnParticle();
00553         particle->SetPosition(position);
00554         particle->SetScale( MercuryPoint(scale, scale, 1) );
00555         particle->SetRotationMode(RM_BILLBOARD);
00556 
00557         float fLifetime = float( rand()%100 )/100.0f+0.3f;
00558         MercuryPoint newPos( ((rand()%200)/100.0f)-1.0f, ((rand()%200)/100.0f)-1.0f, ((rand()%200)/100.0f)-1.0f );
00559         newPos.NormalizeSelf();
00560         newPos *= fRadius*(rand()%90)/100.0f+0.1f;
00561         newPos += position;
00562         float brightness = ((rand()%50)+50)/100.0f;
00563 
00564         int percentColor1 = rand()%100;
00565         color = (color1*(percentColor1/100.0f));
00566         color += color2*((100-percentColor1)/100.0f);
00567 
00568         PStack KArgs;
00569         KArgs.PushItemBack( PSElement( color.GetR()*brightness ) );
00570         KArgs.PushItemBack( PSElement( color.GetG()*brightness ) );
00571         KArgs.PushItemBack( PSElement( color.GetB()*brightness ) );
00572         KArgs.PushItemBack( PSElement( fLifetime ) );
00573         KArgs.PushItemBack( PSElement( newPos.x ) );
00574         KArgs.PushItemBack( PSElement( newPos.y ) );
00575         KArgs.PushItemBack( PSElement( newPos.z ) );
00576         int rotz = (rand()%1000) - 500;
00577         KArgs.PushItemBack( PSElement( rotz ) );
00578         particle->Tweening.ExecuteCommand( "BlastParticle", KArgs );
00579     }
00580 }
00581 
00582 /* 
00583  * Copyright (c) 2006, Charles Lohr
00584  * All rights reserved.
00585  *
00586  * Redistribution and use in source and binary forms, with or
00587  * without modification, are permitted provided that the following
00588  * conditions are met:
00589  *  -   Redistributions of source code must retain the above
00590  *      copyright notice, this list of conditions and the following disclaimer.
00591  *  -   Redistributions in binary form must reproduce the above copyright
00592  *      notice, this list of conditions and the following disclaimer in
00593  *      the documentation and/or other materials provided with the distribution.
00594  *  -   Neither the name of the Mercury Engine nor the names of its
00595  *      contributors may be used to endorse or promote products derived from
00596  *      this software without specific prior written permission.
00597  *
00598  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00599  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00600  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00601  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00602  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00603  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00604  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00605  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00606  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00607  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00608  */

Hosted by SourceForge.net Logo