diff --git a/stepmania/src/Background.cpp b/stepmania/src/Background.cpp index 7f06a25681..67e51649bf 100644 --- a/stepmania/src/Background.cpp +++ b/stepmania/src/Background.cpp @@ -866,7 +866,7 @@ bool BackgroundImpl::IsDangerAllVisible() { /* The players are never in danger in FAIL_OFF. */ FOREACH_PlayerNumber( p ) - if( GAMESTATE->GetPlayerFailType(GAMESTATE->m_pPlayerState[p]) == SongOptions::FAIL_OFF ) + if( GAMESTATE->GetPlayerFailType(GAMESTATE->m_pPlayerState[p]) == PlayerOptions::FAIL_OFF ) return false; if( !g_bShowDanger ) return false; diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index dc37899262..77bdb4436a 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -1294,10 +1294,10 @@ void setmax( T &a, const T &b ) a = max(a, b); } -SongOptions::FailType GameState::GetPlayerFailType( const PlayerState *pPlayerState ) const +PlayerOptions::FailType GameState::GetPlayerFailType( const PlayerState *pPlayerState ) const { PlayerNumber pn = pPlayerState->m_PlayerNumber; - SongOptions::FailType ft = m_SongOptions.GetCurrent().m_FailType; + PlayerOptions::FailType ft = pPlayerState->m_PlayerOptions.GetCurrent().m_FailType; /* If the player changed the fail mode explicitly, leave it alone. */ if( m_bChangedFailTypeOnScreenSongOptions ) @@ -1306,7 +1306,7 @@ SongOptions::FailType GameState::GetPlayerFailType( const PlayerState *pPlayerSt if( IsCourseMode() ) { if( PREFSMAN->m_bMinimum1FullSongInCourses && GetCourseSongIndex()==0 ) - ft = max( ft, SongOptions::FAIL_IMMEDIATE_CONTINUE ); // take the least harsh of the two FailTypes + ft = max( ft, PlayerOptions::FAIL_IMMEDIATE_CONTINUE ); // take the least harsh of the two FailTypes } else { @@ -1323,18 +1323,18 @@ SongOptions::FailType GameState::GetPlayerFailType( const PlayerState *pPlayerSt /* Easy and beginner are never harder than FAIL_IMMEDIATE_CONTINUE. */ if( dc <= Difficulty_Easy ) - setmax( ft, SongOptions::FAIL_IMMEDIATE_CONTINUE ); + setmax( ft, PlayerOptions::FAIL_IMMEDIATE_CONTINUE ); if( dc <= Difficulty_Easy && bFirstStageForAny && PREFSMAN->m_bFailOffForFirstStageEasy ) - setmax( ft, SongOptions::FAIL_OFF ); + setmax( ft, PlayerOptions::FAIL_OFF ); /* If beginner's steps were chosen, and this is the first stage, * turn off failure completely. */ if( dc == Difficulty_Beginner && bFirstStageForAny ) - setmax( ft, SongOptions::FAIL_OFF ); + setmax( ft, PlayerOptions::FAIL_OFF ); if( dc == Difficulty_Beginner && PREFSMAN->m_bFailOffInBeginner ) - setmax( ft, SongOptions::FAIL_OFF ); + setmax( ft, PlayerOptions::FAIL_OFF ); } return ft; diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index c739dabbc3..30f4eceb4e 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -10,6 +10,7 @@ #include "MessageManager.h" #include "ModsGroup.h" #include "RageTimer.h" +#include "PlayerOptions.h" #include "SongOptions.h" #include @@ -237,7 +238,7 @@ public: bool CurrentOptionsDisqualifyPlayer( PlayerNumber pn ); bool PlayerIsUsingModifier( PlayerNumber pn, const RString &sModifier ); - SongOptions::FailType GetPlayerFailType( const PlayerState *pPlayerState ) const; + PlayerOptions::FailType GetPlayerFailType( const PlayerState *pPlayerState ) const; // character stuff Character* m_pCurCharacters[NUM_PLAYERS]; diff --git a/stepmania/src/PlayerOptions.cpp b/stepmania/src/PlayerOptions.cpp index 25fd23208c..8a2e157353 100644 --- a/stepmania/src/PlayerOptions.cpp +++ b/stepmania/src/PlayerOptions.cpp @@ -37,6 +37,7 @@ void PlayerOptions::Init() ZERO( m_bTurns ); ZERO( m_bTransforms ); m_bMuteOnError = false; + m_FailType = FAIL_IMMEDIATE; m_ScoreDisplay = SCORING_ADD; m_sNoteSkin = ""; } @@ -180,6 +181,15 @@ void PlayerOptions::GetMods( vector &AddTo, bool bForceNoteSkin ) const if( m_bTransforms[TRANSFORM_NOSTRETCH] )AddTo.push_back( "NoStretch" ); if( m_bMuteOnError ) AddTo.push_back( "MuteOnError" ); + switch( m_FailType ) + { + case FAIL_IMMEDIATE: break; + case FAIL_IMMEDIATE_CONTINUE: AddTo.push_back("FailImmediateContinue"); break; + case FAIL_AT_END: AddTo.push_back("FailAtEnd"); break; + case FAIL_OFF: AddTo.push_back("FailOff"); break; + default: ASSERT(0); + } + if( m_fSkew==0 && m_fPerspectiveTilt==0 ) { if( m_bSetTiltOrSkew ) AddTo.push_back( "Overhead" ); } else if( m_fSkew == 0 ) { @@ -354,6 +364,18 @@ void PlayerOptions::FromString( const RString &sOptions, bool bWarnOnInvalid ) else if( NOTESKIN && NOTESKIN->DoesNoteSkinExist(sBit) ) m_sNoteSkin = sBit; else if( sBit == "noteskin" && !on ) /* "no noteskin" */ m_sNoteSkin = CommonMetrics::DEFAULT_NOTESKIN_NAME; else if( sBit == "randomspeed" ) SET_FLOAT( fRandomSpeed ) + else if( sBit == "failarcade" || + sBit == "failimmediate" ) m_FailType = FAIL_IMMEDIATE; + else if( sBit == "failendofsong" || + sBit == "failimmediatecontinue" ) m_FailType = FAIL_IMMEDIATE_CONTINUE; + else if( sBit == "failatend" ) m_FailType = FAIL_AT_END; + else if( sBit == "failoff" ) m_FailType = FAIL_OFF; + else if( sBit == "faildefault" ) + { + PlayerOptions po; + GAMESTATE->GetDefaultPlayerOptions( po ); + m_FailType = po.m_FailType; + } else if( sBit == "addscore" ) m_ScoreDisplay = SCORING_ADD; else if( sBit == "subtractscore" ) m_ScoreDisplay = SCORING_SUBTRACT; else if( sBit == "averagescore" ) m_ScoreDisplay = SCORING_AVERAGE; @@ -570,6 +592,7 @@ bool PlayerOptions::operator==( const PlayerOptions &other ) const COMPARE(m_fScrollBPM); COMPARE(m_fRandomSpeed); COMPARE(m_ScoreDisplay); + COMPARE(m_FailType); COMPARE(m_bMuteOnError); COMPARE(m_fDark); COMPARE(m_fBlind); diff --git a/stepmania/src/PlayerOptions.h b/stepmania/src/PlayerOptions.h index bf5a9032d5..318ceb255f 100644 --- a/stepmania/src/PlayerOptions.h +++ b/stepmania/src/PlayerOptions.h @@ -135,6 +135,13 @@ public: bool m_bTransforms[NUM_TRANSFORMS]; bool m_bMuteOnError; ScoreDisplay m_ScoreDisplay; + enum FailType { + FAIL_IMMEDIATE=0, // fail immediately when life touches 0 + FAIL_IMMEDIATE_CONTINUE, // fail immediately when life touches 0, but allow playing the rest of the song + FAIL_AT_END, // fail if life is at 0 when the song ends + FAIL_OFF // never fail + }; + FailType m_FailType; RString m_sNoteSkin; // "" means "no change" diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 21d3d2063a..3f0b09ceb1 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -996,7 +996,10 @@ void ScreenGameplay::LoadNextSong() /* If we're in battery mode, force FailImmediate. We assume in Player::Step that * failed players can't step. */ if( GAMESTATE->m_SongOptions.GetCurrent().m_LifeType == SongOptions::LIFE_BATTERY ) - SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Song, m_FailType, SongOptions::FAIL_IMMEDIATE ); + { + FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi ) + PO_GROUP_ASSIGN( pi->GetPlayerState()->m_PlayerOptions, ModsLevel_Song, m_FailType, PlayerOptions::FAIL_IMMEDIATE ); + } m_textSongOptions.SetText( GAMESTATE->m_SongOptions.GetCurrent().GetString() ); @@ -1490,7 +1493,7 @@ void ScreenGameplay::Update( float fDeltaTime ) { HealthState &hs = pi->GetPlayerState()->m_HealthState; HealthState OldHealthState = hs; - if( GAMESTATE->GetPlayerFailType(pi->GetPlayerState()) != SongOptions::FAIL_OFF && + if( GAMESTATE->GetPlayerFailType(pi->GetPlayerState()) != PlayerOptions::FAIL_OFF && pi->m_pLifeMeter && pi->m_pLifeMeter->IsFailing() ) { hs = HealthState_Dead; @@ -1499,7 +1502,7 @@ void ScreenGameplay::Update( float fDeltaTime ) { hs = HealthState_Hot; } - else if( GAMESTATE->GetPlayerFailType(pi->GetPlayerState()) != SongOptions::FAIL_OFF && + else if( GAMESTATE->GetPlayerFailType(pi->GetPlayerState()) != PlayerOptions::FAIL_OFF && pi->m_pLifeMeter && pi->m_pLifeMeter->IsInDanger() ) { hs = HealthState_Danger; @@ -1539,10 +1542,10 @@ void ScreenGameplay::Update( float fDeltaTime ) { PlayerNumber pn = pi->GetStepsAndTrailIndex(); - SongOptions::FailType ft = GAMESTATE->GetPlayerFailType( pi->GetPlayerState() ); + PlayerOptions::FailType ft = GAMESTATE->GetPlayerFailType( pi->GetPlayerState() ); SongOptions::LifeType lt = GAMESTATE->m_SongOptions.GetCurrent().m_LifeType; - if( ft == SongOptions::FAIL_OFF || ft == SongOptions::FAIL_AT_END ) + if( ft == PlayerOptions::FAIL_OFF || ft == PlayerOptions::FAIL_AT_END ) continue; // check for individual fail @@ -1570,7 +1573,7 @@ void ScreenGameplay::Update( float fDeltaTime ) bAllowOniDie = true; break; } - if( bAllowOniDie && ft == SongOptions::FAIL_IMMEDIATE ) + if( bAllowOniDie && ft == PlayerOptions::FAIL_IMMEDIATE ) { if( !STATSMAN->m_CurStageStats.AllFailed() ) // if not the last one to fail { @@ -1586,18 +1589,18 @@ void ScreenGameplay::Update( float fDeltaTime ) bool bAllFailed = true; FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi ) { - SongOptions::FailType ft = GAMESTATE->GetPlayerFailType( pi->GetPlayerState() ); + PlayerOptions::FailType ft = GAMESTATE->GetPlayerFailType( pi->GetPlayerState() ); switch( ft ) { - case SongOptions::FAIL_IMMEDIATE: + case PlayerOptions::FAIL_IMMEDIATE: if( pi->m_pLifeMeter && !pi->m_pLifeMeter->IsFailing() ) bAllFailed = false; break; - case SongOptions::FAIL_IMMEDIATE_CONTINUE: - case SongOptions::FAIL_AT_END: + case PlayerOptions::FAIL_IMMEDIATE_CONTINUE: + case PlayerOptions::FAIL_AT_END: bAllFailed = false; // wait until the end of the song to fail. break; - case SongOptions::FAIL_OFF: + case PlayerOptions::FAIL_OFF: bAllFailed = false; // never fail. break; default: @@ -2328,7 +2331,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi ) { /* Mark failure. */ - if( GAMESTATE->GetPlayerFailType(pi->GetPlayerState()) != SongOptions::FAIL_OFF && + if( GAMESTATE->GetPlayerFailType(pi->GetPlayerState()) != PlayerOptions::FAIL_OFF && (pi->m_pLifeMeter && pi->m_pLifeMeter->IsFailing()) ) pi->GetPlayerStageStats()->m_bFailed = true; diff --git a/stepmania/src/ScreenJukebox.cpp b/stepmania/src/ScreenJukebox.cpp index 71517b2b7f..4821328d7b 100644 --- a/stepmania/src/ScreenJukebox.cpp +++ b/stepmania/src/ScreenJukebox.cpp @@ -207,7 +207,6 @@ void ScreenJukebox::Init() PO_GROUP_ASSIGN_N( GAMESTATE->m_pPlayerState[p]->m_PlayerOptions, ModsLevel_Stage, m_fEffects, PlayerOptions::EFFECT_MINI, 1.0f ); } SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_LifeType, SongOptions::LIFE_BATTERY ); - SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_FailType, SongOptions::FAIL_OFF ); } FOREACH_EnabledPlayer( p ) @@ -228,7 +227,8 @@ void ScreenJukebox::Init() GAMESTATE->GetDefaultSongOptions( so ); GAMESTATE->m_SongOptions.Assign( ModsLevel_Stage, so ); - SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_FailType, SongOptions::FAIL_OFF ); + FOREACH_EnabledPlayer( p ) + PO_GROUP_ASSIGN( GAMESTATE->m_pPlayerState[p]->m_PlayerOptions, ModsLevel_Stage, m_FailType, PlayerOptions::FAIL_OFF ); GAMESTATE->m_bDemonstrationOrJukebox = true; diff --git a/stepmania/src/ScreenOptionsMasterPrefs.cpp b/stepmania/src/ScreenOptionsMasterPrefs.cpp index 68fb8c17e7..53ce9e432f 100644 --- a/stepmania/src/ScreenOptionsMasterPrefs.cpp +++ b/stepmania/src/ScreenOptionsMasterPrefs.cpp @@ -441,9 +441,9 @@ static void DefaultFailType( int &sel, bool ToSel, const ConfOption *pConfOption { if( ToSel ) { - SongOptions so; - so.FromString( PREFSMAN->m_sDefaultModifiers ); - sel = so.m_FailType; + PlayerOptions po; + po.FromString( PREFSMAN->m_sDefaultModifiers ); + sel = po.m_FailType; } else { @@ -453,10 +453,10 @@ static void DefaultFailType( int &sel, bool ToSel, const ConfOption *pConfOption switch( sel ) { - case 0: so.m_FailType = SongOptions::FAIL_IMMEDIATE; break; - case 1: so.m_FailType = SongOptions::FAIL_IMMEDIATE_CONTINUE; break; - case 2: so.m_FailType = SongOptions::FAIL_AT_END; break; - case 3: so.m_FailType = SongOptions::FAIL_OFF; break; + case 0: po.m_FailType = PlayerOptions::FAIL_IMMEDIATE; break; + case 1: po.m_FailType = PlayerOptions::FAIL_IMMEDIATE_CONTINUE; break; + case 2: po.m_FailType = PlayerOptions::FAIL_AT_END; break; + case 3: po.m_FailType = PlayerOptions::FAIL_OFF; break; default: ASSERT(0); } diff --git a/stepmania/src/ScreenSongOptions.cpp b/stepmania/src/ScreenSongOptions.cpp index 41ab6dfe8d..5006b43ac3 100644 --- a/stepmania/src/ScreenSongOptions.cpp +++ b/stepmania/src/ScreenSongOptions.cpp @@ -4,6 +4,7 @@ #include "GameState.h" #include "ThemeManager.h" #include "PrefsManager.h" +#include "PlayerState.h" REGISTER_SCREEN_CLASS( ScreenSongOptions ); @@ -22,11 +23,13 @@ void ScreenSongOptions::Init() void ScreenSongOptions::ExportOptions( int iRow, const vector &vpns ) { - const SongOptions::FailType ft = GAMESTATE->m_SongOptions.GetPreferred().m_FailType; + PlayerNumber pn = GAMESTATE->m_MasterPlayerNumber; + PlayerState *pPS = GAMESTATE->m_pPlayerState[pn]; + const PlayerOptions::FailType ft = pPS->m_PlayerOptions.GetPreferred().m_FailType; ScreenOptionsMaster::ExportOptions( iRow, vpns ); - if( ft != GAMESTATE->m_SongOptions.GetPreferred().m_FailType ) + if( ft != pPS->m_PlayerOptions.GetPreferred().m_FailType ) GAMESTATE->m_bChangedFailTypeOnScreenSongOptions = true; } diff --git a/stepmania/src/SongOptions.cpp b/stepmania/src/SongOptions.cpp index 60dd4bc6eb..88b274192e 100644 --- a/stepmania/src/SongOptions.cpp +++ b/stepmania/src/SongOptions.cpp @@ -9,7 +9,6 @@ void SongOptions::Init() m_LifeType = LIFE_BAR; m_DrainType = DRAIN_NORMAL; m_iBatteryLives = 4; - m_FailType = FAIL_IMMEDIATE; m_bAssistClap = false; m_bAssistMetronome = false; m_fMusicRate = 1.0f; @@ -74,15 +73,6 @@ void SongOptions::GetMods( vector &AddTo ) const } - switch( m_FailType ) - { - case FAIL_IMMEDIATE: break; - case FAIL_IMMEDIATE_CONTINUE: AddTo.push_back("FailImmediateContinue"); break; - case FAIL_AT_END: AddTo.push_back("FailAtEnd"); break; - case FAIL_OFF: AddTo.push_back("FailOff"); break; - default: ASSERT(0); - } - if( m_fMusicRate != 1 ) { RString s = ssprintf( "%2.2f", m_fMusicRate ); @@ -182,19 +172,6 @@ void SongOptions::FromString( const RString &sOptions ) sBit == "death" ) m_DrainType = DRAIN_SUDDEN_DEATH; else if( sBit == "power-drop" ) m_DrainType = DRAIN_NO_RECOVER; else if( sBit == "normal-drain" ) m_DrainType = DRAIN_NORMAL; - else if( sBit == "failarcade" || - sBit == "failimmediate" ) m_FailType = FAIL_IMMEDIATE; - else if( sBit == "failendofsong" || - sBit == "failimmediatecontinue" ) m_FailType = FAIL_IMMEDIATE_CONTINUE; - else if( sBit == "failatend" ) m_FailType = FAIL_AT_END; - else if( sBit == "failoff" ) m_FailType = FAIL_OFF; - - else if( sBit == "faildefault" ) - { - SongOptions so; - GAMESTATE->GetDefaultSongOptions( so ); - m_FailType = so.m_FailType; - } else if( sBit == "clap" ) m_bAssistClap = on; else if( sBit == "metronome" ) m_bAssistMetronome = on; @@ -224,7 +201,6 @@ bool SongOptions::operator==( const SongOptions &other ) const COMPARE( m_LifeType ); COMPARE( m_DrainType ); COMPARE( m_iBatteryLives ); - COMPARE( m_FailType ); COMPARE( m_fMusicRate ); COMPARE( m_fHaste ); COMPARE( m_bAssistClap ); diff --git a/stepmania/src/SongOptions.h b/stepmania/src/SongOptions.h index 76e25b78e9..6b1088c42a 100644 --- a/stepmania/src/SongOptions.h +++ b/stepmania/src/SongOptions.h @@ -22,12 +22,6 @@ public: }; DrainType m_DrainType; // only used with LifeBar int m_iBatteryLives; - enum FailType { - FAIL_IMMEDIATE=0, // fail immediately when life touches 0 - FAIL_IMMEDIATE_CONTINUE, // fail immediately when life touches 0, but allow playing the rest of the song - FAIL_AT_END, // fail if life is at 0 when the song ends - FAIL_OFF }; // never fail - FailType m_FailType; float m_fMusicRate, m_SpeedfMusicRate; float m_fHaste, m_SpeedfHaste; bool m_bAssistClap;