diff --git a/stepmania/README-FIRST.TXT b/stepmania/README-FIRST.TXT index ab8a1e9b64..1a4ab28e54 100644 --- a/stepmania/README-FIRST.TXT +++ b/stepmania/README-FIRST.TXT @@ -1053,10 +1053,11 @@ options is sufficient. * Step 2: Install the Direct X 8.1 SDK -The DirectX 8.1 SDK is a free (but large) download from Microsoft (link here). -Install it using all the default settings. The SDK installer will configure -Visual C++ with the correct paths needed to find the DirectX 8.1 libraries and -headers. +The DirectX 8.1 SDK is a free (but large) download from Microsoft: +http://msdn.microsoft.com/downloads/?url=/downloads/sample.asp?url=/MSDN-FILES/ +027/001/771/msdncompositedoc.xml&frame=true. Install it using all the default +settings. The SDK installer will configure Visual C++ with the correct paths +needed to find the DirectX 8.1 libraries and headers. * Step 3: Create a SourceForge account diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index eee1716f36..ddc697c018 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -16,6 +16,7 @@ #include "PrefsManager.h" #include "InputMapper.h" #include "Song.h" +#include "RageLog.h" GameState* GAMESTATE = NULL; // global and accessable from anywhere in our program @@ -315,3 +316,33 @@ float GameState::GetPlayerSurviveTime( PlayerNumber pn ) else return m_fSecondsBeforeFail[pn]; } + +Grade GameState::GetCurrentGrade( PlayerNumber pn ) +{ + if( !GAMESTATE->IsPlayerEnabled(pn) || GAMESTATE->m_fSecondsBeforeFail[pn] != -1 ) + return GRADE_E; + + /* Based on the percentage of your total "Dance Points" to the maximum + * possible number, the following rank is assigned: + * + * 100% - AAA + * 93% - AA + * 80% - A + * 65% - B + * 45% - C + * Less - D + * Fail - E + */ + float fPercentDancePoints = m_iActualDancePoints[pn] / (float)m_iPossibleDancePoints[pn]; + fPercentDancePoints = max( fPercentDancePoints, 0 ); + LOG->Trace( "iActualDancePoints: %i", m_iActualDancePoints[pn] ); + LOG->Trace( "iPossibleDancePoints: %i", m_iPossibleDancePoints[pn] ); + LOG->Trace( "fPercentDancePoints: %f", fPercentDancePoints ); + + if ( fPercentDancePoints >= 1.00 ) return GRADE_AAA; + else if( fPercentDancePoints >= 0.93 ) return GRADE_AA; + else if( fPercentDancePoints >= 0.80 ) return GRADE_A; + else if( fPercentDancePoints >= 0.65 ) return GRADE_B; + else if( fPercentDancePoints >= 0.45 ) return GRADE_C; + else return GRADE_D; +} \ No newline at end of file diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index 5d78bf0dc9..08ce297e65 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -15,6 +15,7 @@ #include "SongOptions.h" #include "Game.h" #include "Style.h" +#include "Grade.h" class Song; @@ -96,6 +97,8 @@ public: float GetElapsedSeconds(); // Arcade: time into current song. Oni/Endless: time into current course + Grade GetCurrentGrade( PlayerNumber pn ); + int m_iSongsIntoCourse; // In Arcade, this value is meaningless. // In Oni and Endless, this is the number of songs played in the current course. int m_iSongsBeforeFail[NUM_PLAYERS]; // In Arcade, this value is meaningless. diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 5e8eedc179..2e55dea2db 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -73,7 +73,7 @@ const ScreenMessage SM_PlayToastySound = ScreenMessage(SM_User+105); // received while STATE_OUTRO const ScreenMessage SM_ShowCleared = ScreenMessage(SM_User+111); -const ScreenMessage SM_HideCleared = ScreenMessage(SM_User+112); +const ScreenMessage SM_ShowTryExtraStage = ScreenMessage(SM_User+112); const ScreenMessage SM_SaveChangedBeforeGoingBack = ScreenMessage(SM_User+113); const ScreenMessage SM_GoToScreenAfterBack = ScreenMessage(SM_User+114); const ScreenMessage SM_GoToStateAfterCleared= ScreenMessage(SM_User+115); @@ -81,7 +81,6 @@ const ScreenMessage SM_GoToStateAfterCleared= ScreenMessage(SM_User+115); const ScreenMessage SM_BeginFailed = ScreenMessage(SM_User+121); const ScreenMessage SM_ShowFailed = ScreenMessage(SM_User+122); const ScreenMessage SM_PlayFailComment = ScreenMessage(SM_User+123); -const ScreenMessage SM_HideFailed = ScreenMessage(SM_User+124); const ScreenMessage SM_GoToScreenAfterFail = ScreenMessage(SM_User+125); const ScreenMessage SM_GoToTitleMenu = ScreenMessage(SM_User+126); @@ -333,6 +332,14 @@ ScreenGameplay::ScreenGameplay() m_sprFailed.SetDiffuse( D3DXCOLOR(1,1,1,0) ); this->AddChild( &m_sprFailed ); + if( GAMESTATE->IsFinalStage() ) + m_sprTryExtraStage.Load( THEME->GetPathTo("Graphics","gameplay try extra stage1") ); + else if( GAMESTATE->IsExtraStage() ) + m_sprTryExtraStage.Load( THEME->GetPathTo("Graphics","gameplay try extra stage2") ); + m_sprTryExtraStage.SetXY( CENTER_X, CENTER_Y ); + m_sprTryExtraStage.SetDiffuse( D3DXCOLOR(1,1,1,0) ); + this->AddChild( &m_sprTryExtraStage ); + if( GAMESTATE->m_bDemonstration ) { m_quadDemonstrationBox.SetDiffuse( D3DXCOLOR(0,0,0,0.7f) ); @@ -369,6 +376,7 @@ ScreenGameplay::ScreenGameplay() if( !GAMESTATE->m_bDemonstration ) // don't load sounds if just playing demonstration { m_soundFail.Load( THEME->GetPathTo("Sounds","gameplay failed") ); + m_soundTryExtraStage.Load( THEME->GetPathTo("Sounds","gameplay try extra stage") ); m_soundOniDie.Load( THEME->GetPathTo("Sounds","gameplay oni die") ); m_announcerReady.Load( ANNOUNCER->GetPathTo("gameplay ready") ); if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() ) @@ -1081,8 +1089,34 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) else { m_StarWipe.CloseWipingRight( SM_None ); - this->SendScreenMessage( SM_ShowCleared, 1 ); - SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo("gameplay cleared") ); + + // do they deserve an extra stage? + + bool bTryExtraStage = false; + if( (GAMESTATE->IsFinalStage() || GAMESTATE->IsExtraStage()) ) + { + for( p=0; pIsPlayerEnabled( (PlayerNumber)p ) ) + continue; // skip + + if( GAMESTATE->m_pCurNotes[p]->m_DifficultyClass == CLASS_HARD && GAMESTATE->GetCurrentGrade((PlayerNumber)p) >= GRADE_AA ) + bTryExtraStage = true; + } + } + if( PREFSMAN->m_bEventMode ) + bTryExtraStage = false; + + + if( bTryExtraStage ) + { + this->SendScreenMessage( SM_ShowTryExtraStage, 1 ); + } + else + { + this->SendScreenMessage( SM_ShowCleared, 1 ); + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo("gameplay cleared") ); + } } } } @@ -1200,13 +1234,42 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) case SM_ShowCleared: m_sprCleared.BeginTweening(1.0f); m_sprCleared.SetTweenDiffuse( D3DXCOLOR(1,1,1,1) ); - SCREENMAN->SendMessageToTopScreen( SM_HideCleared, 1.5 ); - break; - case SM_HideCleared: + m_sprCleared.BeginTweening(1.5f); // sleep m_sprCleared.BeginTweening(0.7f); m_sprCleared.SetTweenDiffuse( D3DXCOLOR(1,1,1,0) ); - SCREENMAN->SendMessageToTopScreen( SM_GoToStateAfterCleared, 1 ); + SCREENMAN->SendMessageToTopScreen( SM_GoToStateAfterCleared, 3 ); break; + + case SM_ShowTryExtraStage: + { + m_soundTryExtraStage.PlayRandom(); + + // make the background invisible so we don't waste mem bandwidth drawing it + m_Background.BeginTweening( 1 ); + m_Background.SetTweenDiffuse( D3DXCOLOR(1,1,1,0) ); + + D3DXCOLOR colorStage = GAMESTATE->GetStageColor(); + colorStage.a *= 0.7f; + + m_sprTryExtraStage.SetZoom( 4 ); + m_sprTryExtraStage.BeginBlurredTweening( 0.8f, TWEEN_BIAS_END ); + m_sprTryExtraStage.SetTweenZoom( 0.5f ); // zoom out + m_sprTryExtraStage.SetTweenDiffuse( colorStage ); // and fade in + m_sprTryExtraStage.BeginTweening( 0.3f ); + m_sprTryExtraStage.SetTweenZoom( 1.1f ); // bounce + m_sprTryExtraStage.SetTweenDiffuse( colorStage ); // and fade in + m_sprTryExtraStage.BeginTweening( 0.2f ); + m_sprTryExtraStage.SetTweenZoom( 1.0f ); // come to rest + m_sprTryExtraStage.SetTweenDiffuse( colorStage ); // and fade in + + colorStage.a = 0; + + m_sprTryExtraStage.BeginTweening( 3 ); // sleep + m_sprTryExtraStage.SetTweenDiffuse( colorStage ); + SCREENMAN->SendMessageToTopScreen( SM_GoToStateAfterCleared, 5 ); + } + break; + case SM_SaveChangedBeforeGoingBack: if( m_bChangedOffsetOrBPM ) { @@ -1270,6 +1333,9 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) m_sprFailed.BeginTweening( 0.2f ); m_sprFailed.SetTweenZoom( 1.0f ); // come to rest m_sprFailed.SetTweenDiffuse( D3DXCOLOR(1,1,1,0.7f) ); // and fade in + m_sprFailed.BeginTweening( 2 ); // sleep + m_sprFailed.BeginTweening( 1 ); + m_sprFailed.SetTweenDiffuse( D3DXCOLOR(1,1,1,0) ); // show the survive time if extra stage if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() ) @@ -1283,25 +1349,18 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) m_textSurviveTime.BeginTweening( 0.3f ); // sleep m_textSurviveTime.BeginTweening( 0.3f ); // fade in m_textSurviveTime.SetTweenDiffuse( D3DXCOLOR(1,1,1,1) ); + m_textSurviveTime.BeginTweening( 3.5f ); // sleep + m_textSurviveTime.BeginTweening( 0.5f ); // fade out + m_textSurviveTime.SetTweenDiffuse( D3DXCOLOR(1,1,1,0) ); } SCREENMAN->SendMessageToTopScreen( SM_PlayFailComment, 1.0f ); - SCREENMAN->SendMessageToTopScreen( SM_HideFailed, 2.0f ); + SCREENMAN->SendMessageToTopScreen( SM_GoToScreenAfterFail, 5.0f ); break; case SM_PlayFailComment: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo("gameplay failed") ); break; - case SM_HideFailed: - m_sprFailed.StopTweening(); - m_sprFailed.BeginTweening(1.0f); - m_sprFailed.SetTweenDiffuse( D3DXCOLOR(1,1,1,0) ); - m_textSurviveTime.BeginTweening( 0.5f ); // sleep - m_textSurviveTime.BeginTweening( 0.5f ); // fade out - m_textSurviveTime.SetTweenDiffuse( D3DXCOLOR(1,1,1,0) ); - - SCREENMAN->SendMessageToTopScreen( SM_GoToScreenAfterFail, 1.5f ); - break; case SM_GoToScreenAfterFail: if( m_bChangedOffsetOrBPM ) { diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h index 483316f08a..f92ec52ab1 100644 --- a/stepmania/src/ScreenGameplay.h +++ b/stepmania/src/ScreenGameplay.h @@ -106,6 +106,7 @@ private: FocusingSprite m_sprHereWeGo; MotionBlurSprite m_sprCleared; MotionBlurSprite m_sprFailed; + MotionBlurSprite m_sprTryExtraStage; BitmapText m_textSurviveTime; // only shown in extra stage @@ -124,6 +125,7 @@ private: RandomSample m_soundFail; RandomSample m_soundOniDie; + RandomSample m_soundTryExtraStage; RandomSample m_announcerReady; RandomSample m_announcerHereWeGo; RandomSample m_announcerDanger;