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
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
00170 if( INPUTMAN->IsButtonDown( button_space ) )
00171 {
00172 dBodyAddForce( control->m_oBody, SIN(RealAngle)*Amplitude*800,-COS(RealAngle)*Amplitude*800,3900 );
00173 }
00174
00175
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
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
00251 CalculateLook(x, y, control);
00252
00253 ScreenOutdoors::Update( adjTime );
00254
00255
00256 m_Aimer.Disable();
00257 m_Aimer.EnableForShot( m_pWorld.GetWorldSpaceID(), 50000, m_pGun, pLookAt );
00258
00259
00260 TweenCamera(x, y, control);
00261
00262 m_pPlayer.SetPosition( control->GetPosition( ) );
00263
00264 pPhysics.Disable();
00265
00266 if ( iPhysicsObject != 0 )
00267 {
00268
00269 MercuryPoint pNewPos = m_pGun + pLookAt.Normalize() * fClosestPhysicsObject;
00270 fClosestPhysicsObject = fClosestPhysicsObject * 0.95f + 2;
00271 MercuryPoint pCurrentPos( dBodyGetPosition( (dBodyID)iPhysicsObject ) );
00272
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
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
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
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
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
00427
00428 m_fCamera.SetTarget(coke);
00429
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
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
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608