From 218be328796e1c311c9b90a8faae712290efe910 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Tue, 5 Apr 2005 08:30:57 +0000 Subject: [PATCH] separate fail types per player. Now FailType adjustments based on Difficulty only affect the relevant players. --- stepmania/src/Background.cpp | 30 ++---- stepmania/src/Background.h | 2 - stepmania/src/GameState.cpp | 103 +++++++++++------- stepmania/src/GameState.h | 10 +- stepmania/src/LifeMeterBar.cpp | 15 +-- stepmania/src/MusicWheel.cpp | 4 +- stepmania/src/PrefsManager.cpp | 10 +- stepmania/src/PrefsManager.h | 2 + stepmania/src/ProfileManager.cpp | 4 +- stepmania/src/ScreenEvaluation.cpp | 4 +- stepmania/src/ScreenGameplay.cpp | 112 ++++++++++---------- stepmania/src/ScreenGameplayMultiplayer.cpp | 4 - stepmania/src/ScreenOptionsMasterPrefs.cpp | 4 +- stepmania/src/ScreenPlayerOptions.cpp | 2 - stepmania/src/ScreenSelectMusic.cpp | 3 +- stepmania/src/ScreenSongOptions.cpp | 10 ++ stepmania/src/ScreenSongOptions.h | 2 + stepmania/src/ScreenTitleMenu.cpp | 2 +- stepmania/src/StepMania.cpp | 2 +- 19 files changed, 175 insertions(+), 150 deletions(-) diff --git a/stepmania/src/Background.cpp b/stepmania/src/Background.cpp index 6d2fe7c6c0..d119790acc 100644 --- a/stepmania/src/Background.cpp +++ b/stepmania/src/Background.cpp @@ -597,10 +597,10 @@ void Background::Update( float fDeltaTime ) FOREACH_PlayerNumber( p ) { - if( IsDangerPlayerVisible(p) ) + if( GAMESTATE->IsPlayerInDanger(p) ) m_DangerPlayer[p].Update( fDeltaTime ); - if( IsDeadPlayerVisible(p) ) + if( GAMESTATE->IsPlayerDead(p) ) m_DeadPlayer[p].Update( fDeltaTime ); } @@ -652,9 +652,9 @@ void Background::DrawPrimitives() FOREACH_PlayerNumber( p ) { - if( IsDangerPlayerVisible(p) ) + if( GAMESTATE->IsPlayerInDanger(p) ) m_DangerPlayer[p].Draw(); - if( IsDeadPlayerVisible(p) ) + if( GAMESTATE->IsPlayerDead(p) ) m_DeadPlayer[p].Draw(); } } @@ -667,8 +667,9 @@ void Background::DrawPrimitives() bool Background::IsDangerAllVisible() { - if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_OFF ) - return false; + FOREACH_PlayerNumber( p ) + if( GAMESTATE->GetPlayerFailType(p) == SongOptions::FAIL_OFF ) + return false; if( !PREFSMAN->m_bShowDanger ) return false; @@ -686,23 +687,6 @@ bool Background::IsDangerAllVisible() return true; } -bool Background::IsDangerPlayerVisible( PlayerNumber pn ) -{ - if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_OFF ) - return false; - if( !PREFSMAN->m_bShowDanger ) - return false; - return GAMESTATE->m_pPlayerState[pn]->m_HealthState == PlayerState::DANGER; -} - -bool Background::IsDeadPlayerVisible( PlayerNumber pn ) -{ - if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_OFF ) - return false; - return GAMESTATE->m_pPlayerState[pn]->m_HealthState == PlayerState::DEAD; -} - - BrightnessOverlay::BrightnessOverlay() { float fQuadWidth = (RIGHT_EDGE-LEFT_EDGE)/2; diff --git a/stepmania/src/Background.h b/stepmania/src/Background.h index 73c724706a..226532d35e 100644 --- a/stepmania/src/Background.h +++ b/stepmania/src/Background.h @@ -51,9 +51,7 @@ protected: void LoadFromRandom( float fFirstBeat, float fLastBeat, const TimingData &timing, CString sPreferredSubDir ); int FindBGSegmentForBeat( float fBeat ) const; - bool IsDangerPlayerVisible( PlayerNumber pn ); bool IsDangerAllVisible(); - bool IsDeadPlayerVisible( PlayerNumber pn ); void UpdateCurBGChange( float fCurrentTime ); bool m_bInitted; diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index a303ec180c..5da7e37a64 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -145,7 +145,7 @@ void GameState::Reset() m_MasterPlayerNumber = PLAYER_INVALID; m_mapEnv.clear(); m_sPreferredSongGroup = GROUP_ALL_MUSIC; - m_bChangedFailType = false; + m_bChangedFailTypeOnScreenSongOptions = false; FOREACH_PlayerNumber( p ) { m_PreferredDifficulty[p].Set( DIFFICULTY_INVALID ); @@ -475,7 +475,7 @@ void GameState::FinishStage() if( m_bDemonstrationOrJukebox ) return; - if( GAMESTATE->GetEventMode() ) + if( GAMESTATE->IsEventMode() ) { const int iSaveProfileEvery = 3; if( iOldStageIndex/iSaveProfileEvery < m_iCurrentStageIndex/iSaveProfileEvery ) @@ -688,14 +688,14 @@ int GameState::GetNumStagesLeft() const { if( IsExtraStage() || IsExtraStage2() ) return 1; - if( GAMESTATE->GetEventMode() ) + if( GAMESTATE->IsEventMode() ) return 999; return PREFSMAN->m_iNumArcadeStages - m_iCurrentStageIndex; } bool GameState::IsFinalStage() const { - if( GAMESTATE->GetEventMode() ) + if( GAMESTATE->IsEventMode() ) return false; if( this->IsCourseMode() ) @@ -710,14 +710,14 @@ bool GameState::IsFinalStage() const bool GameState::IsExtraStage() const { - if( GAMESTATE->GetEventMode() ) + if( GAMESTATE->IsEventMode() ) return false; return m_iCurrentStageIndex == PREFSMAN->m_iNumArcadeStages; } bool GameState::IsExtraStage2() const { - if( GAMESTATE->GetEventMode() ) + if( GAMESTATE->IsEventMode() ) return false; return m_iCurrentStageIndex == PREFSMAN->m_iNumArcadeStages+1; } @@ -726,7 +726,7 @@ CString GameState::GetStageText() const { if( m_bDemonstrationOrJukebox ) return "demo"; // "event" has precedence - else if( GAMESTATE->GetEventMode() ) return "event"; + else if( GAMESTATE->IsEventMode() ) return "event"; else if( m_PlayMode == PLAY_MODE_ONI ) return "oni"; else if( m_PlayMode == PLAY_MODE_NONSTOP ) return "nonstop"; else if( m_PlayMode == PLAY_MODE_ENDLESS ) return "endless"; @@ -931,7 +931,7 @@ bool GameState::IsBattleMode() const bool GameState::HasEarnedExtraStage() const { - if( GAMESTATE->GetEventMode() ) + if( GAMESTATE->IsEventMode() ) return false; if( !PREFSMAN->m_bAllowExtraStage ) @@ -1005,13 +1005,8 @@ StageResult GameState::GetStageResult( PlayerNumber pn ) const void GameState::ApplyModifiers( PlayerNumber pn, CString sModifiers ) { - const SongOptions::FailType ft = this->m_SongOptions.m_FailType; - m_pPlayerState[pn]->m_PlayerOptions.FromString( sModifiers ); m_SongOptions.FromString( sModifiers ); - - if( ft != this->m_SongOptions.m_FailType ) - this->m_bChangedFailType = true; } /* Store the player's preferred options. This is called at the very beginning @@ -1277,38 +1272,44 @@ void setmax( T &a, const T &b ) a = max(a, b); } -/* Adjust the fail mode based on the chosen difficulty. This must be called - * after the difficulty has been finalized (usually in ScreenSelectMusic or - * ScreenPlayerOptions), and before the fail mode is displayed or used (usually - * in ScreenSongOptions). */ -void GameState::AdjustFailType() +SongOptions::FailType GameState::GetPlayerFailType( PlayerNumber pn ) const { - /* Single song mode only. */ - if( this->IsCourseMode() ) - return; + SongOptions::FailType ft = m_SongOptions.m_FailType; /* If the player changed the fail mode explicitly, leave it alone. */ - if( this->m_bChangedFailType ) - return; + if( this->m_bChangedFailTypeOnScreenSongOptions ) + return ft; - /* Find the easiest difficulty notes selected by either player. */ - const Difficulty dc = GetEasiestNotesDifficulty(); + if( this->IsCourseMode() ) + { + if( PREFSMAN->m_bMinimum1FullSongInCourses && GAMESTATE->IsCourseMode() && GAMESTATE->GetCourseSongIndex()==0 ) + ft = max( ft, SongOptions::FAIL_COMBO_OF_30_MISSES ); // take the least harsh of the two FailTypes + } + else + { + Difficulty dc = DIFFICULTY_INVALID; + if( m_pCurSteps[pn] ) + dc = m_pCurSteps[pn]->GetDifficulty(); - /* Reset the fail type to the default. */ - SongOptions so; - so.FromString( PREFSMAN->m_sDefaultModifiers ); - this->m_SongOptions.m_FailType = so.m_FailType; + bool bFirstStage = !GAMESTATE->IsEventMode() && m_iCurrentStageIndex == 0; - /* Easy and beginner are never harder than FAIL_END_OF_SONG. */ - if(dc <= DIFFICULTY_EASY) - setmax(this->m_SongOptions.m_FailType, SongOptions::FAIL_END_OF_SONG); + /* Easy and beginner are never harder than FAIL_END_OF_SONG. */ + if( dc <= DIFFICULTY_EASY ) + setmax( ft, SongOptions::FAIL_END_OF_SONG ); - /* If beginner's steps were chosen, and this is the first stage, - * turn off failure completely--always give a second try. */ - if(dc == DIFFICULTY_BEGINNER && - GAMESTATE->GetEventMode() && /* stage index is meaningless in event mode */ - this->m_iCurrentStageIndex == 0) - setmax(this->m_SongOptions.m_FailType, SongOptions::FAIL_OFF); + if( dc <= DIFFICULTY_EASY && bFirstStage && PREFSMAN->m_bFailOffForFirstStageEasy ) + setmax( ft, SongOptions::FAIL_OFF ); + + /* If beginner's steps were chosen, and this is the first stage, + * turn off failure completely. */ + if( dc == DIFFICULTY_BEGINNER && bFirstStage ) + setmax( ft, SongOptions::FAIL_OFF ); + + if( dc == DIFFICULTY_BEGINNER && PREFSMAN->m_bFailOffInBeginner ) + setmax( ft, SongOptions::FAIL_OFF ); + } + + return ft; } bool GameState::ShowMarvelous() const @@ -1788,14 +1789,14 @@ Difficulty GameState::GetEasiestNotesDifficulty() const return dc; } -bool GameState::GetEventMode() +bool GameState::IsEventMode() const { return m_bTemporaryEventMode || PREFSMAN->m_bEventMode; } CoinMode GameState::GetCoinMode() { - if( GetEventMode() && PREFSMAN->m_CoinMode == COIN_PAY ) + if( IsEventMode() && PREFSMAN->m_CoinMode == COIN_PAY ) return COIN_FREE; else return PREFSMAN->m_CoinMode; @@ -1803,12 +1804,32 @@ CoinMode GameState::GetCoinMode() Premium GameState::GetPremium() { - if( GetEventMode() ) + if( IsEventMode() ) return PREMIUM_NONE; else return PREFSMAN->m_Premium; } +bool GameState::IsPlayerHot( PlayerNumber pn ) const +{ + return GAMESTATE->m_pPlayerState[pn]->m_HealthState == PlayerState::HOT; +} + +bool GameState::IsPlayerInDanger( PlayerNumber pn ) const +{ + if( GAMESTATE->GetPlayerFailType(pn) == SongOptions::FAIL_OFF ) + return false; + if( !PREFSMAN->m_bShowDanger ) + return false; + return GAMESTATE->m_pPlayerState[pn]->m_HealthState == PlayerState::DANGER; +} + +bool GameState::IsPlayerDead( PlayerNumber pn ) const +{ + if( GAMESTATE->GetPlayerFailType(pn) == SongOptions::FAIL_OFF ) + return false; + return GAMESTATE->m_pPlayerState[pn]->m_HealthState == PlayerState::DEAD; +} diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index 396bcf5667..760159506b 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -10,6 +10,7 @@ #include "RageTimer.h" #include "Difficulty.h" #include "MessageManager.h" +#include "SongOptions.h" #include #include @@ -101,7 +102,7 @@ public: CString m_sLoadingMessage; // used in loading screen CString m_sPreferredSongGroup; // GROUP_ALL_MUSIC denotes no preferred group - bool m_bChangedFailType; // true if FailType was changed in the song options screen + bool m_bChangedFailTypeOnScreenSongOptions; // true if FailType was changed in the song options screen BroadcastOnChange1D m_PreferredDifficulty; SortOrder m_PreferredSortOrder; // used by MusicWheel bool m_bEditing; // NoteField does special stuff when this is true @@ -165,6 +166,9 @@ public: void UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp = RageZeroTimer ); float GetSongPercent( float beat ) const; + bool IsPlayerHot( PlayerNumber pn ) const; + bool IsPlayerInDanger( PlayerNumber pn ) const; + bool IsPlayerDead( PlayerNumber pn ) const; bool AllAreInDangerOrWorse() const; bool AllAreDead() const; bool AllHaveComboOf30OrMoreMisses() const; @@ -209,7 +213,7 @@ public: bool IsDisqualified( PlayerNumber pn ); - void AdjustFailType(); + SongOptions::FailType GetPlayerFailType( PlayerNumber pn ) const; // character stuff private: @@ -275,7 +279,7 @@ public: // These options have weird interactions depending on m_bEventMode, // so wrap them bool m_bTemporaryEventMode; - bool GetEventMode(); + bool IsEventMode() const; CoinMode GetCoinMode(); Premium GetPremium(); diff --git a/stepmania/src/LifeMeterBar.cpp b/stepmania/src/LifeMeterBar.cpp index 381b677c54..853006bddd 100644 --- a/stepmania/src/LifeMeterBar.cpp +++ b/stepmania/src/LifeMeterBar.cpp @@ -291,7 +291,7 @@ void LifeMeterBar::ChangeLife( TapNoteScore score ) default: ASSERT(0); } - if( IsHot() && score < TNS_GOOD ) + if( GAMESTATE->IsPlayerHot(m_PlayerNumber) && score < TNS_GOOD ) fDeltaLife = -0.10f; // make it take a while to get back to "doing great" break; case SongOptions::DRAIN_NO_RECOVER: @@ -347,7 +347,7 @@ void LifeMeterBar::ChangeLife( HoldNoteScore score, TapNoteScore tscore ) default: ASSERT(0); } - if( IsHot() && score == HNS_NG ) + if( GAMESTATE->IsPlayerHot(m_PlayerNumber) && score == HNS_NG ) fDeltaLife = -0.10f; // make it take a while to get back to "doing great" break; case SongOptions::DRAIN_NO_RECOVER: @@ -477,13 +477,16 @@ void LifeMeterBar::Update( float fDeltaTime ) // HACK: Tweaking these values is very difficulty. Update the // "physics" many times so that the spring motion appears faster + bool bIsDead = GAMESTATE->IsPlayerDead(m_PlayerNumber); + bool bIsHot = GAMESTATE->IsPlayerHot(m_PlayerNumber); + for( int i=0; i<10; i++ ) { const float fDelta = m_fLifePercentage - m_fTrailingLifePercentage; // Don't apply spring and viscous forces if we're full or empty. // Just move straight to either full or empty. - if( IsFailing() || IsHot() ) + if( bIsDead || bIsHot ) { m_fLifeVelocity = (fDelta / fabsf(fDelta)) * 4; } @@ -508,10 +511,10 @@ void LifeMeterBar::Update( float fDeltaTime ) m_fPassingAlpha += IsPastPassmark() ? +fDeltaTime*2 : -fDeltaTime*2; CLAMP( m_fPassingAlpha, 0, 1 ); - m_fHotAlpha += IsHot() ? + fDeltaTime*2 : -fDeltaTime*2; + m_fHotAlpha += bIsHot ? + fDeltaTime*2 : -fDeltaTime*2; CLAMP( m_fHotAlpha, 0, 1 ); - if( IsHot() ) + if( bIsHot ) m_fLifeVelocity = max( 0, m_fLifeVelocity ); } @@ -523,7 +526,7 @@ void LifeMeterBar::DrawPrimitives() m_pStream->m_fHotAlpha = m_fHotAlpha; float fPercentRed = 0; - if( IsFailing() ) + if( GAMESTATE->IsPlayerDead(m_PlayerNumber) ) fPercentRed = 0; else if( m_fTrailingLifePercentagem_pCurSong != NULL && SongManager::GetNumStagesForSong( GAMESTATE->m_pCurSong ) + GAMESTATE->m_iCurrentStageIndex > PREFSMAN->m_iNumArcadeStages - && !GAMESTATE->GetEventMode() + && !GAMESTATE->IsEventMode() && !GAMESTATE->IsExtraStage() && !GAMESTATE->IsExtraStage2() ) { GAMESTATE->m_pCurSong.Set( NULL ); @@ -498,7 +498,7 @@ void MusicWheel::BuildWheelItemDatas( vector &arrayWheelItemDatas case SORT_ONI_COURSES: case SORT_ENDLESS_COURSES: /* Don't display course modes after the first stage. */ - if( !GAMESTATE->GetEventMode() && GAMESTATE->m_iCurrentStageIndex ) + if( !GAMESTATE->IsEventMode() && GAMESTATE->m_iCurrentStageIndex ) continue; } diff --git a/stepmania/src/PrefsManager.cpp b/stepmania/src/PrefsManager.cpp index f023e88bf4..d1426d68c3 100644 --- a/stepmania/src/PrefsManager.cpp +++ b/stepmania/src/PrefsManager.cpp @@ -150,6 +150,8 @@ void PrefsManager::Init() m_bTwoPlayerRecovery = true; m_bMercifulDrain = true; m_bMinimum1FullSongInCourses = false; + m_bFailOffInBeginner = false; + m_bFailOffForFirstStageEasy = false; m_iPercentScoreWeightMarvelous = 3; m_iPercentScoreWeightPerfect = 2; @@ -382,7 +384,9 @@ void PrefsManager::ReadGlobalPrefsFromIni( const IniFile &ini ) ini.GetValue( "Options", "MaxRegenComboAfterMiss", m_iMaxRegenComboAfterMiss ); ini.GetValue( "Options", "TwoPlayerRecovery", m_bTwoPlayerRecovery ); ini.GetValue( "Options", "MercifulDrain", m_bMercifulDrain ); - ini.GetValue( "Options", "Minimum1FullSongInCourses", m_bMinimum1FullSongInCourses ); + ini.GetValue( "Options", "Minimum1FullSongInCourses", m_bMinimum1FullSongInCourses ); + ini.GetValue( "Options", "FailOffInBeginner", m_bFailOffInBeginner ); + ini.GetValue( "Options", "FailOffForFirstStageEasy", m_bFailOffForFirstStageEasy ); ini.GetValue( "Options", "PercentScoreWeightMarvelous", m_iPercentScoreWeightMarvelous ); ini.GetValue( "Options", "PercentScoreWeightPerfect", m_iPercentScoreWeightPerfect ); @@ -599,7 +603,9 @@ void PrefsManager::SaveGlobalPrefsToIni( IniFile &ini ) const ini.SetValue( "Options", "MaxRegenComboAfterMiss", m_iMaxRegenComboAfterMiss ); ini.SetValue( "Options", "TwoPlayerRecovery", m_bTwoPlayerRecovery ); ini.SetValue( "Options", "MercifulDrain", m_bMercifulDrain ); - ini.SetValue( "Options", "Minimum1FullSongInCourses", m_bMinimum1FullSongInCourses ); + ini.SetValue( "Options", "Minimum1FullSongInCourses", m_bMinimum1FullSongInCourses ); + ini.SetValue( "Options", "FailOffInBeginner", m_bFailOffInBeginner ); + ini.SetValue( "Options", "FailOffForFirstStageEasy", m_bFailOffForFirstStageEasy ); ini.SetValue( "Options", "PercentScoreWeightMarvelous", m_iPercentScoreWeightMarvelous ); ini.SetValue( "Options", "PercentScoreWeightPerfect", m_iPercentScoreWeightPerfect ); diff --git a/stepmania/src/PrefsManager.h b/stepmania/src/PrefsManager.h index 50bd99267e..32154a9b9a 100644 --- a/stepmania/src/PrefsManager.h +++ b/stepmania/src/PrefsManager.h @@ -96,6 +96,8 @@ public: bool m_bTwoPlayerRecovery; bool m_bMercifulDrain; // negative life deltas are scaled by the players life percentage bool m_bMinimum1FullSongInCourses; // FEoS for 1st song, FailImmediate thereafter + bool m_bFailOffInBeginner; + bool m_bFailOffForFirstStageEasy; // percent score (the number that is shown on the screen and saved to memory card) int m_iPercentScoreWeightMarvelous; diff --git a/stepmania/src/ProfileManager.cpp b/stepmania/src/ProfileManager.cpp index 5eb509b464..b583506936 100644 --- a/stepmania/src/ProfileManager.cpp +++ b/stepmania/src/ProfileManager.cpp @@ -379,7 +379,7 @@ void ProfileManager::AddStepsScore( const Song* pSong, const Steps* pSteps, Play // In event mode, set the score's name immediately to the Profile's last // used name. If no profile last used name exists, use "EVNT". - if( GAMESTATE->GetEventMode() ) + if( GAMESTATE->IsEventMode() ) { Profile* pProfile = PROFILEMAN->GetProfile(pn); if( pProfile && !pProfile->m_sLastUsedHighScoreName.empty() ) @@ -448,7 +448,7 @@ void ProfileManager::AddCourseScore( const Course* pCourse, const Trail* pTrail, // In event mode, set the score's name immediately to the Profile's last // used name. If no profile last used name exists, use "EVNT". - if( GAMESTATE->GetEventMode() ) + if( GAMESTATE->IsEventMode() ) { Profile* pProfile = PROFILEMAN->GetProfile(pn); if( pProfile && !pProfile->m_sLastUsedHighScoreName.empty() ) diff --git a/stepmania/src/ScreenEvaluation.cpp b/stepmania/src/ScreenEvaluation.cpp index 55affa9b38..4e18d8cb41 100644 --- a/stepmania/src/ScreenEvaluation.cpp +++ b/stepmania/src/ScreenEvaluation.cpp @@ -1355,7 +1355,7 @@ void ScreenEvaluation::HandleScreenMessage( const ScreenMessage SM ) } else if( SM == SM_GoToNextScreen ) { - if( GAMESTATE->GetEventMode() ) + if( GAMESTATE->IsEventMode() ) { SCREENMAN->SetNewScreen( NEXT_SCREEN ); } @@ -1460,7 +1460,7 @@ void ScreenEvaluation::EndScreen() FOREACH_PlayerNumber( p ) m_Grades[p].SettleImmediately(); - if( !GAMESTATE->GetEventMode() ) + if( !GAMESTATE->IsEventMode() ) { switch( m_Type ) { diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 7ed9a5f354..d7793156ee 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -133,10 +133,6 @@ void ScreenGameplay::Init() if( GAMESTATE->m_pCurSong == NULL && GAMESTATE->m_pCurCourse == NULL ) return; // ScreenDemonstration will move us to the next screen. We just need to survive for one update without crashing. - /* This is usually done already, but we might have come here without going through - * ScreenSelectMusic or the options menus at all. */ - GAMESTATE->AdjustFailType(); - /* Save selected options before we change them. */ GAMESTATE->StoreSelectedOptions(); @@ -905,7 +901,10 @@ void ScreenGameplay::LoadNextSong() if( GAMESTATE->m_SongOptions.m_LifeType==SongOptions::LIFE_BATTERY && STATSMAN->m_CurStageStats.m_player[p].bFailed ) // already failed ShowOniGameOver(p); - if( GAMESTATE->m_SongOptions.m_LifeType==SongOptions::LIFE_BAR && GAMESTATE->m_PlayMode == PLAY_MODE_REGULAR && !GAMESTATE->GetEventMode() && !GAMESTATE->m_bDemonstrationOrJukebox) + if( GAMESTATE->m_SongOptions.m_LifeType==SongOptions::LIFE_BAR && + GAMESTATE->m_PlayMode == PLAY_MODE_REGULAR && + !GAMESTATE->IsEventMode() && + !GAMESTATE->m_bDemonstrationOrJukebox ) { m_pLifeMeter[p]->UpdateNonstopLifebar( GAMESTATE->GetStageIndex(), @@ -1333,67 +1332,68 @@ void ScreenGameplay::Update( float fDeltaTime ) case STATE_DANCING: /* Set STATSMAN->m_CurStageStats.bFailed for failed players. In, FAIL_IMMEDIATE, send * SM_BeginFailed if all players failed, and kill dead Oni players. */ - switch( GAMESTATE->m_SongOptions.m_FailType ) + FOREACH_EnabledPlayer( pn ) { - case SongOptions::FAIL_OFF: - // don't allow fail - break; - default: - // check for individual fail - FOREACH_EnabledPlayer( pn ) - { - if( (m_pLifeMeter[pn] && !m_pLifeMeter[pn]->IsFailing()) || - (m_pCombinedLifeMeter && !m_pCombinedLifeMeter->IsFailing(pn)) ) - continue; /* isn't failing */ - if( STATSMAN->m_CurStageStats.m_player[pn].bFailed ) - continue; /* failed and is already dead */ + SongOptions::FailType ft = GAMESTATE->GetPlayerFailType(pn); + if( ft == SongOptions::FAIL_OFF ) + continue; - /* If recovery is enabled, only set fail if both are failing. - * There's no way to recover mid-song in battery mode. */ - if( GAMESTATE->m_SongOptions.m_LifeType != SongOptions::LIFE_BATTERY && - PREFSMAN->m_bTwoPlayerRecovery && !GAMESTATE->AllAreDead() ) - continue; + // check for individual fail + if( (m_pLifeMeter[pn] && !m_pLifeMeter[pn]->IsFailing()) || + (m_pCombinedLifeMeter && !m_pCombinedLifeMeter->IsFailing(pn)) ) + continue; /* isn't failing */ + if( STATSMAN->m_CurStageStats.m_player[pn].bFailed ) + continue; /* failed and is already dead */ + + /* If recovery is enabled, only set fail if both are failing. + * There's no way to recover mid-song in battery mode. */ + if( GAMESTATE->m_SongOptions.m_LifeType != SongOptions::LIFE_BATTERY && + PREFSMAN->m_bTwoPlayerRecovery && !GAMESTATE->AllAreDead() ) + continue; - LOG->Trace("Player %d failed", (int)pn); - STATSMAN->m_CurStageStats.m_player[pn].bFailed = true; // fail + LOG->Trace("Player %d failed", (int)pn); + STATSMAN->m_CurStageStats.m_player[pn].bFailed = true; // fail - if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && - GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_IMMEDIATE ) + if( ft == SongOptions::LIFE_BATTERY && + ft == SongOptions::FAIL_IMMEDIATE ) + { + if( !STATSMAN->m_CurStageStats.AllFailedEarlier() ) // if not the last one to fail { - if( !STATSMAN->m_CurStageStats.AllFailedEarlier() ) // if not the last one to fail - { - // kill them! - SOUND->PlayOnceFromDir( THEME->GetPathS(m_sName,"oni die") ); - ShowOniGameOver(pn); - m_Player[pn].m_NoteData.Init(); // remove all notes and scoring - m_Player[pn].FadeToFail(); // tell the NoteField to fade to white - } + // kill them! + SOUND->PlayOnceFromDir( THEME->GetPathS(m_sName,"oni die") ); + ShowOniGameOver(pn); + m_Player[pn].m_NoteData.Init(); // remove all notes and scoring + m_Player[pn].FadeToFail(); // tell the NoteField to fade to white } } - break; } - /* If FAIL_IMMEDIATE and everyone is failing, start SM_BeginFailed. */ - bool bBeginFailed = false; - SongOptions::FailType ft = GAMESTATE->m_SongOptions.m_FailType; - if( PREFSMAN->m_bMinimum1FullSongInCourses && GAMESTATE->IsCourseMode() && GAMESTATE->GetCourseSongIndex()==0 ) + bool bAllFailed = true; + FOREACH_EnabledPlayer( pn ) { - // take the least harsh of the two FailTypes - ft = max( ft, SongOptions::FAIL_COMBO_OF_30_MISSES ); + SongOptions::FailType ft = GAMESTATE->GetPlayerFailType(pn); + switch( ft ) + { + case SongOptions::FAIL_IMMEDIATE: + if( GAMESTATE->m_pPlayerState[pn]->m_HealthState < PlayerState::DEAD ) + bAllFailed = false; + break; + case SongOptions::FAIL_COMBO_OF_30_MISSES: + if( STATSMAN->m_CurStageStats.m_player[pn].iCurMissCombo < 30 ) + bAllFailed = false; + break; + case SongOptions::FAIL_END_OF_SONG: + bAllFailed = false; // wait until the end of the song to fail. + break; + case SongOptions::FAIL_OFF: + bAllFailed = false; // never fail. + break; + default: + ASSERT(0); + } } - switch( ft ) - { - case SongOptions::FAIL_IMMEDIATE: - if( GAMESTATE->AllAreDead() ) - bBeginFailed = true; - break; - case SongOptions::FAIL_COMBO_OF_30_MISSES: - if( GAMESTATE->AllHaveComboOf30OrMoreMisses() ) - bBeginFailed = true; - break; - } - - if( bBeginFailed ) + + if( bAllFailed ) SCREENMAN->PostMessageToTopScreen( SM_BeginFailed, 0 ); // @@ -2106,7 +2106,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) } /* Mark failure. This hasn't been done yet if m_bTwoPlayerRecovery is set. */ - if( GAMESTATE->m_SongOptions.m_FailType != SongOptions::FAIL_OFF && + if( GAMESTATE->GetPlayerFailType(p) != SongOptions::FAIL_OFF && (m_pLifeMeter[p] && m_pLifeMeter[p]->IsFailing()) || (m_pCombinedLifeMeter && m_pCombinedLifeMeter->IsFailing(p)) ) STATSMAN->m_CurStageStats.m_player[p].bFailed = true; diff --git a/stepmania/src/ScreenGameplayMultiplayer.cpp b/stepmania/src/ScreenGameplayMultiplayer.cpp index 395dd4aa7a..14064b1210 100644 --- a/stepmania/src/ScreenGameplayMultiplayer.cpp +++ b/stepmania/src/ScreenGameplayMultiplayer.cpp @@ -64,10 +64,6 @@ void ScreenGameplayMultiplayer::Init() if( GAMESTATE->m_pCurSong == NULL && GAMESTATE->m_pCurCourse == NULL ) return; // ScreenDemonstration will move us to the next scren. We just need to survive for one update without crashing. - /* This is usually done already, but we might have come here without going through - * ScreenSelectMusic or the options menus at all. */ - GAMESTATE->AdjustFailType(); - /* Save selected options before we change them. */ GAMESTATE->StoreSelectedOptions(); diff --git a/stepmania/src/ScreenOptionsMasterPrefs.cpp b/stepmania/src/ScreenOptionsMasterPrefs.cpp index 85dbccdd05..f2ce4f86de 100644 --- a/stepmania/src/ScreenOptionsMasterPrefs.cpp +++ b/stepmania/src/ScreenOptionsMasterPrefs.cpp @@ -398,7 +398,9 @@ static void DefaultFailType( int &sel, bool ToSel, const ConfOption *pConfOption SongOptions so; so.FromString( PREFSMAN->m_sDefaultModifiers ); sel = so.m_FailType; - } else { + } + else + { PlayerOptions po; SongOptions so; GetDefaultModifiers( po, so ); diff --git a/stepmania/src/ScreenPlayerOptions.cpp b/stepmania/src/ScreenPlayerOptions.cpp index 70a9ed000f..6cc230cd4b 100644 --- a/stepmania/src/ScreenPlayerOptions.cpp +++ b/stepmania/src/ScreenPlayerOptions.cpp @@ -95,8 +95,6 @@ void ScreenPlayerOptions::GoToNextScreen() } else { - GAMESTATE->AdjustFailType(); - if( m_bGoToOptions ) SCREENMAN->SetNewScreen( NEXT_SCREEN ); else diff --git a/stepmania/src/ScreenSelectMusic.cpp b/stepmania/src/ScreenSelectMusic.cpp index 3732f0d088..07d7adb034 100644 --- a/stepmania/src/ScreenSelectMusic.cpp +++ b/stepmania/src/ScreenSelectMusic.cpp @@ -1113,7 +1113,6 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM ) } else { - GAMESTATE->AdjustFailType(); SOUND->StopMusic(); SCREENMAN->SetNewScreen( NEXT_SCREEN ); } @@ -1170,7 +1169,7 @@ void ScreenSelectMusic::MenuStart( PlayerNumber pn ) /* See if this song is a repeat. If we're in event mode, only check the last five songs. */ bool bIsRepeat = false; int i = 0; - if( GAMESTATE->GetEventMode() ) + if( GAMESTATE->IsEventMode() ) i = max( 0, int(STATSMAN->m_vPlayedStageStats.size())-5 ); for( ; i < (int)STATSMAN->m_vPlayedStageStats.size(); ++i ) if( STATSMAN->m_vPlayedStageStats[i].vpSongs.back() == m_MusicWheel.GetSelectedSong() ) diff --git a/stepmania/src/ScreenSongOptions.cpp b/stepmania/src/ScreenSongOptions.cpp index 0baf7293c1..5de1847ceb 100644 --- a/stepmania/src/ScreenSongOptions.cpp +++ b/stepmania/src/ScreenSongOptions.cpp @@ -36,6 +36,16 @@ void ScreenSongOptions::Init() } } +void ScreenSongOptions::ExportOptions( int row, const vector &vpns ) +{ + const SongOptions::FailType ft = GAMESTATE->m_SongOptions.m_FailType; + + ScreenOptionsMaster::ExportOptions( row, vpns ); + + if( ft != GAMESTATE->m_SongOptions.m_FailType ) + GAMESTATE->m_bChangedFailTypeOnScreenSongOptions = true; +} + void ScreenSongOptions::GoToPrevScreen() { if( GAMESTATE->m_bEditing ) diff --git a/stepmania/src/ScreenSongOptions.h b/stepmania/src/ScreenSongOptions.h index 8ee03f10d9..8eec873549 100644 --- a/stepmania/src/ScreenSongOptions.h +++ b/stepmania/src/ScreenSongOptions.h @@ -13,6 +13,8 @@ public: static CString GetNextScreen(); private: + virtual void ExportOptions( int row, const vector &vpns ); + void GoToNextScreen(); void GoToPrevScreen(); }; diff --git a/stepmania/src/ScreenTitleMenu.cpp b/stepmania/src/ScreenTitleMenu.cpp index 04d0a19fbc..b01ac4a6e7 100644 --- a/stepmania/src/ScreenTitleMenu.cpp +++ b/stepmania/src/ScreenTitleMenu.cpp @@ -82,7 +82,7 @@ void ScreenTitleMenu::Init() m_textMaxStages.LoadFromFont( THEME->GetPathF(m_sName,"MaxStages") ); m_textMaxStages.SetName( "MaxStages" ); CString sText = - GAMESTATE->GetEventMode() ? + GAMESTATE->IsEventMode() ? CString("event mode") : ssprintf( "%d %s%s max", PREFSMAN->m_iNumArcadeStages.Value(), MAX_STAGES_TEXT.c_str(), (PREFSMAN->m_iNumArcadeStages>1)?"s":"" ); m_textMaxStages.SetText( sText ); diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index e140db04ee..efbc38d963 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -1453,7 +1453,7 @@ static void HandleInputEvents(float fDeltaTime) continue; // skip // check back in event mode - if( GAMESTATE->GetEventMode() && + if( GAMESTATE->IsEventMode() && CodeDetector::EnteredCode(GameI.controller,CodeDetector::CODE_BACK_IN_EVENT_MODE) ) { MenuI.player = PLAYER_1;