diff --git a/stepmania/src/LifeMeterBar.cpp b/stepmania/src/LifeMeterBar.cpp index d437f6d4d9..3be0dc34ed 100644 --- a/stepmania/src/LifeMeterBar.cpp +++ b/stepmania/src/LifeMeterBar.cpp @@ -358,6 +358,10 @@ void LifeMeterBar::ChangeLife( TapNoteScore score ) m_iComboToRegainLife = max( m_iComboToRegainLife, NewComboToRegainLife ); } + /* If we've already failed, there's no point in letting them fill up the bar again. */ + if( GAMESTATE->m_CurStageStats.bFailed[m_PlayerNumber] ) + fDeltaLife = 0; + switch( GAMESTATE->m_SongOptions.m_DrainType ) { case SongOptions::DRAIN_NORMAL: diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 0eead1c148..d13a6f9692 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -1035,10 +1035,6 @@ void ScreenGameplay::Update( float fDeltaTime ) switch( m_DancingState ) { case STATE_DANCING: - // Check to see what we animate on this one - // ------------------------------------------- - - // // Update living players' alive time // @@ -1053,6 +1049,19 @@ void ScreenGameplay::Update( float fDeltaTime ) if( GAMESTATE->m_fMusicSeconds > fSecondsToStop && !m_NextSongOut.IsTransitioning() ) this->PostScreenMessage( SM_NotesEnded, 0 ); + // + // Handle the background danger graphic. Never show it in FAIL_OFF. Don't + // show it if everyone is already failing: it's already too late and it's + // annoying for it to show for the entire duration of a song. + // + if( GAMESTATE->m_SongOptions.m_FailType != SongOptions::FAIL_OFF ) + { + if( AllAreInDanger() && !AllAreFailing() ) + m_Background.TurnDangerOn(); + else + m_Background.TurnDangerOff(); + } + // // check for fail // @@ -1159,19 +1168,10 @@ void ScreenGameplay::Update( float fDeltaTime ) m_soundAssistTick.Play(); } -/* Set m_CurStageStats.bFailed for failed players, send SM_BeginFailed - * if all players failed, and kill dead Oni players. This is all FAIL_ARCADE - * only. In FAIL_END_OF_SONG, this happens in SM_NotesEnded. */ +/* Set m_CurStageStats.bFailed for failed players. In, FAIL_ARCADE, send + * SM_BeginFailed if all players failed, and kill dead Oni players. */ void ScreenGameplay::UpdateCheckFail() { - if( GAMESTATE->m_SongOptions.m_FailType != SongOptions::FAIL_ARCADE ) - return; - - /* Handle the background danger graphic. */ - if( AllAreFailing() ) SCREENMAN->PostMessageToTopScreen( SM_BeginFailed, 0 ); - if( AllAreInDanger() ) m_Background.TurnDangerOn(); - else m_Background.TurnDangerOff(); - // check for individual fail for ( int pn=0; pnm_CurStageStats.bFailed[pn] ) continue; /* failed and is already dead */ + /* If recovery is enabled, only set fail if both are failing. */ + if( PREFSMAN->m_bTwoPlayerRecovery && !AllAreFailing() ) + continue; + LOG->Trace("Player %d failed", (int)pn); GAMESTATE->m_CurStageStats.bFailed[pn] = true; // fail - if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY ) + if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && + GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_ARCADE ) { if( !AllFailedEarlier() ) // if not the last one to fail { @@ -1198,6 +1203,11 @@ void ScreenGameplay::UpdateCheckFail() } } } + + /* If FAIL_ARCADE and everyone is failing, start SM_BeginFailed. */ + if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_ARCADE && + AllAreFailing() ) + SCREENMAN->PostMessageToTopScreen( SM_BeginFailed, 0 ); } void ScreenGameplay::AbortGiveUp() @@ -1560,14 +1570,6 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) GAMESTATE->RemoveAllActiveAttacks(); - /* All players failed. */ - if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_END_OF_SONG && AllFailedEarlier() ) - { - for( p=0; pIsPlayerEnabled(p) ) - GAMESTATE->m_CurStageStats.bFailed[p]=true; - } - for( p=0; pIsPlayerEnabled(p) ) @@ -1610,7 +1612,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) GAMESTATE->RemoveAllActiveAttacks(); - if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_END_OF_SONG && AllFailedEarlier() ) + if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_END_OF_SONG && AllAreFailing() ) { this->PostScreenMessage( SM_BeginFailed, 0 ); } diff --git a/stepmania/src/StageStats.cpp b/stepmania/src/StageStats.cpp index 1e752ebe25..967a1ff452 100644 --- a/stepmania/src/StageStats.cpp +++ b/stepmania/src/StageStats.cpp @@ -65,7 +65,7 @@ Grade StageStats::GetGrade( PlayerNumber pn ) { ASSERT( GAMESTATE->IsPlayerEnabled(pn) ); // should be calling this is player isn't joined! - if( bFailed[pn] ) + if( bFailedEarlier[pn] ) return GRADE_E; /* XXX: This entire calculation should be in ScoreKeeper, but final evaluation diff --git a/stepmania/src/StageStats.h b/stepmania/src/StageStats.h index 3db28d8c05..ece95a5600 100644 --- a/stepmania/src/StageStats.h +++ b/stepmania/src/StageStats.h @@ -30,9 +30,12 @@ struct StageStats enum { STAGE_INVALID, STAGE_NORMAL, STAGE_EXTRA, STAGE_EXTRA2 } StageType; int iMeter[NUM_PLAYERS]; float fAliveSeconds[NUM_PLAYERS]; // how far into the music did they last before failing? Updated by Gameplay. - /* This indicates whether the player failed the song; it's always false for FAIL_OFF - * and is only set to true in FAIL_END_OF_SONG at the end of the song. */ + + /* Set if the player actually failed at any point during the song. This is always + * false in FAIL_OFF. If recovery is enabled and two players are playing, + * this is only set if both players were failing at the same time. */ bool bFailed[NUM_PLAYERS]; + /* This indicates whether the player bottomed out his bar/ran out of lives at some * point during the song. It's set in all fail modes. */ bool bFailedEarlier[NUM_PLAYERS];