00001 #include "ExplodingCokeCan.h"
00002 #include "MercuryLog.h"
00003 #include "MercuryTheme.h"
00004 #include "MercuryShapes.h"
00005 #include "MercuryDisplay.h"
00006 #include "MercuryScreenManager.h"
00007 #include "MercurySoundSourceWAV.h"
00008
00009 REGISTER_ODE_OBJECT_CLASS( ExplodingCokeCan )
00010
00011 ExplodingCokeCan::~ExplodingCokeCan()
00012 {
00013 if( m_pSph )
00014 dGeomDestroy( m_pSph );
00015 }
00016
00017 void ExplodingCokeCan::Init()
00018 {
00019 MercuryODEObjectLoadable::Init();
00020 m_bDestroyed = false;
00021 m_fHealth = THEME.GetMetricF( "FPSStuff", "CokeHealth", 10 );
00022
00023 m_pSph = dCreateSphere( m_oWorldSpace, THEME.GetMetricF( "FPSStuff", "CokeExplosionRadius" ) );
00024 dGeomSetData( m_pSph, this );
00025
00026 RegisterMessage( 1, "DoExplosion" );
00027 Tweening.AddCommand(THEME.GetMetricS( "FPSStuff", "CokeBlastParticle" ) , MercuryTweenState::GLOBAL, "CokeBlastParticle" ) ;
00028
00029 }
00030
00031 void ExplodingCokeCan::Update( const float dTime )
00032 {
00033 dGeomSetPosition( m_pSph, GetX(), GetY(), GetZ() );
00034 MercuryODEObjectLoadable::Update( dTime );
00035 }
00036
00037 bool ExplodingCokeCan::Collide( MercuryODEObject * pHit, dContact & pContact, MercuryODEWorld * pWorld )
00038 {
00039 if( !m_bDestroyed && ( pContact.geom.g1 == m_pSph || pContact.geom.g2 == m_pSph ) )
00040 return false;
00041
00042 if( m_bDestroyed )
00043 {
00044 if ( pHit->m_oBody )
00045 {
00046 MercuryPoint AntiDirection = pHit->GetPosition() - GetPosition();
00047 float fForce = THEME.GetMetricF( "FPSStuff", "CokeExplosionForce" ) * (THEME.GetMetricF( "FPSStuff", "CokeExplosionRadius" )-AntiDirection.Magnitude()+5);
00048 if ( fForce < 0 )
00049 return false;
00050 dBodyEnable( pHit->m_oBody );
00051 dBodyAddForce( pHit->m_oBody, AntiDirection.x*fForce, AntiDirection.y*fForce, AntiDirection.z*fForce );
00052 }
00053 return false;
00054 }
00055
00056 if( pHit->GetName().compare( "BULLET" ) == 0 )
00057 {
00058 m_fHealth -= THEME.GetMetricF( "FPSStuff", "CokeBulletDamage", 100 );
00059 if( m_fHealth <= 0 )
00060 {
00061
00062 Tweening.AddCommand( THEME.GetMetricS( "FPSStuff", "CokeExplosionSelf", "" ) );
00063
00064 MercurySoundSourceWAV* sound = new MercurySoundSourceWAV;
00065 sound->Open( "FILE:explosion.wav");
00066 sound->SetDestroyOnStop(true);
00067 sound->Play();
00068
00069 MercuryColor color1, color2, color;
00070 color1.FromString( THEME.GetMetricS( "FPSStuff", "CokeBlastParticleBaseColor1" ) );
00071 color2.FromString( THEME.GetMetricS( "FPSStuff", "CokeBlastParticleBaseColor2" ) );
00072 MercuryPoint mp( GetPosition() );
00073 float fRadius = ((rand()%2000)/100.0f) + 50.0f;
00074 float scale = THEME.GetMetricF( "FPSStuff", "CokeBlastParticleScale" );
00075 MercuryParticleField* pfield = (MercuryParticleField*)SCREENMAN->GetCurrentScreen()->Spawn( "MercuryParticleField", "CokeBlastParticles", PERSPECTIVE );
00076 pfield->LoadImage( THEME.GetMetricS( "FPSStuff", "CokeBlastParticleImage" ));
00077 pfield->Tweening.AddCommand( THEME.GetMetricS( "FPSStuff", "CokeBlastParticleField" ) );
00078 pfield->GetGLState().Disable(MGLS_OPAQUE);
00079
00080 for (unsigned int i = 0; i < 100; ++i)
00081 {
00082 MercuryObject* particle = pfield->SpawnParticle();
00083 particle->SetPosition(mp);
00084 particle->SetScale( MercuryPoint(scale, scale, 1) );
00085 particle->SetRotationMode(RM_BILLBOARD);
00086
00087 float fLifetime = float( rand()%1000 )/1000.0f+1.0f;
00088 MercuryPoint newPos( ((rand()%200)/100.0f)-1.0f, ((rand()%200)/100.0f)-1.0f, ((rand()%200)/100.0f)-1.0f );
00089 newPos.NormalizeSelf();
00090 newPos *= fRadius*(rand()%90)/100.0f+0.1f;
00091 newPos += mp;
00092 float brightness = ((rand()%50)+50)/100.0f;
00093
00094 int percentColor1 = rand()%100;
00095 color = (color1*(percentColor1/100.0f));
00096 color += color2*((100-percentColor1)/100.0f);
00097
00098 PStack KArgs;
00099 KArgs.PushItemBack( PSElement( color.GetR()*brightness ) );
00100 KArgs.PushItemBack( PSElement( color.GetG()*brightness ) );
00101 KArgs.PushItemBack( PSElement( color.GetB()*brightness ) );
00102 KArgs.PushItemBack( PSElement( fLifetime ) );
00103 KArgs.PushItemBack( PSElement( newPos.x ) );
00104 KArgs.PushItemBack( PSElement( newPos.y ) );
00105 KArgs.PushItemBack( PSElement( newPos.z ) );
00106 int rotz = (rand()%1000) - 500;
00107 KArgs.PushItemBack( PSElement( rotz ) );
00108 particle->Tweening.ExecuteCommand( "BlastParticle", KArgs );
00109 }
00110
00111
00112 MercuryLight* l = (MercuryLight*)((MercuryObject*)pWorld->GetParentObject())->Spawn("MercuryLight", "Can Explosion light");
00113 l->SetPosition(this->GetGlobalPosition());
00114 l->SetStatic(true);
00115 l->SetLightType(LT_POINT);
00116 l->SetAttenuation(.1,Attenuation::CONSTANT);
00117
00118 l->SetAttenuation(.0001f,Attenuation::QUADRATIC);
00119 l->Tweening.AddCommand(THEME.GetMetricS( "FPSStuff", "LightExplosion", "" ));
00120 DISPLAY->AddLight(l);
00121
00122 m_bDestroyed = true;
00123 PStack p;
00124
00125 p.PushItemBack(GetPosition().x);
00126 p.PushItemBack(GetPosition().y);
00127 p.PushItemBack(GetPosition().z);
00128 MESSAGEMAN->PostSystemMessage( "DoExplosion", p, 0 );
00129 return false;
00130 }
00131 }
00132 return MercuryODEObjectLoadable::Collide( pHit, pContact, pWorld );
00133 }
00134
00135 void ExplodingCokeCan::Message( int Message, PStack & data, const MString & name )
00136 {
00137 MercuryODEObjectLoadable::Message( Message, data, name );
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166