diff --git a/src/GameState.cpp b/src/GameState.cpp index e89da1b127..82bd81ccdf 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -107,6 +107,7 @@ static ThemeMetric ARE_STAGE_SONG_MODS_FORCED ("GameState","AreStageSongMo static Preference g_Premium( "Premium", Premium_DoubleFor1Credit ); Preference GameState::m_bAutoJoin( "AutoJoin", false ); +Preference GameState::m_bOverrideChordCohesion("OverrideChordCohesion", false); GameState::GameState() : processedTiming( NULL ), @@ -1918,6 +1919,11 @@ void GameState::AddStageToPlayer( PlayerNumber pn ) ++m_iPlayerStageTokens[pn]; } +bool GameState::CountNotesSeparately() +{ + return GetCurrentGame()->m_bCountNotesSeparately || m_bOverrideChordCohesion.Get(); +} + template void setmin( T &a, const T &b ) { diff --git a/src/GameState.h b/src/GameState.h index 0b1214456f..a8d39e7bdc 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -243,8 +243,7 @@ class GameState int GetLoadingCourseSongIndex() const; RString GetEtternaVersion() { return "0.54.1"; } - - + bool CountNotesSeparately(); // State Info used during gameplay @@ -379,6 +378,7 @@ class GameState // Preferences static Preference m_bAutoJoin; + static Preference m_bOverrideChordCohesion; // These options have weird interactions depending on m_bEventMode, // so wrap them. diff --git a/src/NoteData.cpp b/src/NoteData.cpp index 5f2b9a2222..ede3b58316 100644 --- a/src/NoteData.cpp +++ b/src/NoteData.cpp @@ -181,7 +181,9 @@ int NoteData::WifeTotalScoreCalc(TimingData *td, int iStartIndex, int iEndIndex) TapNote tn = GetTapNote(t, r); if (tn.type != TapNoteType_Empty && tn.type != TapNoteType_Mine && tn.type != TapNoteType_Fake && td->IsJudgableAtRow(r)) { taps++; - break; + + if( !GAMESTATE->CountNotesSeparately() ) + break; } } } diff --git a/src/NoteDataWithScoring.cpp b/src/NoteDataWithScoring.cpp index 68a4922c3f..5aabfc771e 100644 --- a/src/NoteDataWithScoring.cpp +++ b/src/NoteDataWithScoring.cpp @@ -36,8 +36,13 @@ int LastTapNoteScoreTrack( const NoteData &in, unsigned iRow, PlayerNumber pn ) TapNoteScore tns = tn.result.tns; - if( tns == TNS_Miss || tns == TNS_None ) + if ( tns == TNS_Miss || (!GAMESTATE->CountNotesSeparately() && tns == TNS_None) ) + { return t; + } + if ( tns == TNS_None ) + continue; + float tm = tn.result.fTapNoteOffset; if(tm < scoretime) continue; diff --git a/src/Player.cpp b/src/Player.cpp index af7c72f57f..2c143875d3 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -2412,7 +2412,7 @@ void Player::Step( int col, int row, const std::chrono::steady_clock::time_point } m_LastTapNoteScore = score; - if( GAMESTATE->GetCurrentGame()->m_bCountNotesSeparately ) + if( GAMESTATE->CountNotesSeparately() ) { if( pTN->type != TapNoteType_Mine ) { @@ -2424,6 +2424,12 @@ void Player::Step( int col, int row, const std::chrono::steady_clock::time_point m_pNoteField->DidTapNote( col, bBlind? TNS_W1:score, bBright ); if( score >= m_pPlayerState->m_PlayerOptions.GetCurrent().m_MinTNSToHideNotes || bBlind ) HideNote( col, iRowOfOverlappingNoteOrRow ); + + if ( pTN->result.tns != TNS_None ) + { + SetJudgment(iRowOfOverlappingNoteOrRow, col, *pTN); + HandleTapRowScore(iRowOfOverlappingNoteOrRow); + } } } else if( NoteDataWithScoring::IsRowCompletelyJudged(m_NoteData, iRowOfOverlappingNoteOrRow) ) @@ -2531,6 +2537,11 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) else { tn.result.tns = TNS_Miss; + if ( GAMESTATE->CountNotesSeparately() ) + { + SetJudgment(iter.Row(), m_NoteData.GetFirstTrackWithTapOrHoldHead(iter.Row()), tn); + HandleTapRowScore(iter.Row()); + } } } } @@ -2540,8 +2551,8 @@ void Player::UpdateJudgedRows(float fDeltaTime) // Look into the future only as far as we need to const int iEndRow = BeatToNoteRow( m_Timing->GetBeatFromElapsedTime( m_pPlayerState->m_Position.m_fMusicSeconds + GetMaxStepDistanceSeconds() ) ); bool bAllJudged = true; - const bool bSeparately = GAMESTATE->GetCurrentGame()->m_bCountNotesSeparately; + if( !GAMESTATE->CountNotesSeparately() ) { NoteData::all_tracks_iterator iter = *m_pIterUnjudgedRows; int iLastSeenRow = -1; @@ -2573,22 +2584,8 @@ void Player::UpdateJudgedRows(float fDeltaTime) if(lastTN.result.tns < TNS_Miss ) continue; - if( bSeparately ) - { - for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack ) - { - const TapNote &tn = m_NoteData.GetTapNote( iTrack, iRow ); - if (tn.type == TapNoteType_Empty || - tn.type == TapNoteType_Mine || - tn.type == TapNoteType_AutoKeysound ) continue; - SetJudgment( iRow, iTrack, tn ); - } - } - else - { - SetJudgment( iRow, m_NoteData.GetFirstTrackWithTapOrHoldHead(iRow), lastTN ); - } - HandleTapRowScore( iRow ); + SetJudgment( iRow, m_NoteData.GetFirstTrackWithTapOrHoldHead(iRow), lastTN ); + HandleTapRowScore(iRow); } } } diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index 67c7694163..e880260193 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -523,7 +523,7 @@ void ScoreKeeperNormal::GetRowCounts( const NoteData &nd, int iRow, ++iNumHitContinueCombo; else if( tns >= m_MinScoreToMaintainCombo ) ++iNumHitMaintainCombo; - else + else if( tns != TNS_None ) ++iNumBreakCombo; } } @@ -542,7 +542,7 @@ void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow ) TapNoteScore scoreOfLastTap = NoteDataWithScoring::LastTapNoteWithResult( nd, iRow ).result.tns; HandleTapNoteScoreInternal( scoreOfLastTap, TNS_W1, iRow ); - if ( GAMESTATE->GetCurrentGame()->m_bCountNotesSeparately ) + if ( GAMESTATE->CountNotesSeparately() ) { HandleComboInternal( iNumHitContinueCombo, iNumHitMaintainCombo, iNumBreakCombo, iRow ); }