From fb003c318905dd7a765d466b827090c00c1079a2 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Thu, 16 Jun 2005 21:36:58 +0000 Subject: [PATCH] Don't judge rolls inside of HandleStep. It's redundant because all holds and rolls are judged in Update. Move calls to Step for autoplay of rolls outside the HoldNote update loop to fix double-grading. --- stepmania/src/Player.cpp | 206 ++++++++++++++++++++------------------- 1 file changed, 105 insertions(+), 101 deletions(-) diff --git a/stepmania/src/Player.cpp b/stepmania/src/Player.cpp index ef64d01e7d..0ae42fca20 100644 --- a/stepmania/src/Player.cpp +++ b/stepmania/src/Player.cpp @@ -417,6 +417,42 @@ void Player::Update( float fDeltaTime ) m_pNoteField->SetPressed( col ); } + + // + // handle Autoplay for rolls + // + { + const int iStartCheckingAt = max( 0, iSongRow-BeatToNoteRow(1) ); + for( int iTrack=0; iTracksecond; + if( tn.type != TapNote::hold_head ) + continue; + + HoldNoteScore hns = tn.HoldResult.hns; + if( hns != HNS_NONE ) // if this HoldNote already has a result + continue; // we don't need to update the logic for this one + + if( m_pPlayerState->m_PlayerController != PC_HUMAN ) + { + // TODO: Make the CPU miss sometimes. + if( tn.subType == TapNote::hold_head_roll && tn.HoldResult.fLife < 0.5f ) + { + RageTimer now; + Step( iTrack, now, false ); + } + } + } + } + } + + // // update HoldNotes logic // @@ -453,21 +489,7 @@ void Player::Update( float fDeltaTime ) if( m_pPlayerState->m_PlayerController != PC_HUMAN ) { // TODO: Make the CPU miss sometimes. - switch( tn.subType ) - { - case TapNote::hold_head_hold: - bIsHoldingButton = true; - break; - case TapNote::hold_head_roll: - if( tn.HoldResult.fLife < 0.5f ) - { - RageTimer now; - Step( iTrack, now, false ); - } - break; - default: - ASSERT(0); - } + bIsHoldingButton = true; } else { @@ -790,7 +812,6 @@ void Player::Step( int col, const RageTimer &tm, bool bHeld ) void Player::HandleStep( int col, const RageTimer &tm, bool bHeld ) { - //LOG->Trace( "Player::HandlePlayerStep()" ); ASSERT_M( col >= 0 && col <= m_NoteData.GetNumTracks(), ssprintf("%i, %i", col, m_NoteData.GetNumTracks()) ); @@ -841,6 +862,8 @@ void Player::HandleStep( int col, const RageTimer &tm, bool bHeld ) fPositionSeconds -= tm.Ago(); const float fSongBeat = GAMESTATE->m_pCurSong ? GAMESTATE->m_pCurSong->GetBeatFromElapsedTime( fPositionSeconds ) : GAMESTATE->m_fSongBeat; + + // // Check for step on a TapNote // @@ -1075,106 +1098,87 @@ void Player::HandleStep( int col, const RageTimer &tm, bool bHeld ) } } + + if( m_pNoteField ) m_pNoteField->Step( col, score ); - /* Search for keyed sounds separately. If we can't find a nearby note, search - * backwards indefinitely, and ignore grading. */ - if( iIndexOverlappingNote == -1 ) - iIndexOverlappingNote = GetClosestNote( col, BeatToNoteRow(fSongBeat), - iStepSearchRows, MAX_NOTE_ROW, true ); - if( iIndexOverlappingNote != -1 ) + bool bSteppedOnATap = score != TNS_NONE; + + if( bSteppedOnATap ) { - TapNote tn = m_NoteData.GetTapNote( col, iIndexOverlappingNote ); - if( tn.bKeysound && tn.iKeysoundIndex < (int) m_vKeysounds.size() ) - m_vKeysounds[tn.iKeysoundIndex].Play(); + /* Search for keyed sounds separately. If we can't find a nearby note, search + * backwards indefinitely, and ignore grading. */ + if( iIndexOverlappingNote == -1 ) + iIndexOverlappingNote = GetClosestNote( col, BeatToNoteRow(fSongBeat), + iStepSearchRows, MAX_NOTE_ROW, true ); + if( iIndexOverlappingNote != -1 ) + { + TapNote tn = m_NoteData.GetTapNote( col, iIndexOverlappingNote ); + if( tn.bKeysound && tn.iKeysoundIndex < (int) m_vKeysounds.size() ) + m_vKeysounds[tn.iKeysoundIndex].Play(); + } } + - // Update roll life - // Let's not check the whole array every time. - // Instead, only check 1 beat back. Even 1 is overkill. - const int iSongRow = BeatToNoteRow(fSongBeat); - const int iStartCheckingAt = max( 0, iSongRow-BeatToNoteRow(1) ); - NoteData::iterator begin, end; - m_NoteData.GetTapNoteRangeInclusive( col, iStartCheckingAt, iSongRow+1, begin, end ); - for( ; begin != end; ++begin ) { - TapNote &tn = begin->second; - if( tn.type != TapNote::hold_head ) - continue; - int iRow = begin->first; - - HoldNoteScore hns = tn.HoldResult.hns; - if( hns != HNS_NONE ) // if this HoldNote already has a result - continue; // we don't need to update the logic for this one - - // if they got a bad score or haven't stepped on the corresponding tap yet - const TapNoteScore tns = tn.result.tns; - const bool bSteppedOnTapNote = tns != TNS_NONE && tns != TNS_MISS; // did they step on the start of this roll? - - int iEndRow = iRow + tn.iDuration; - - float fLife = tn.HoldResult.fLife; - if( bSteppedOnTapNote && fLife != 0 ) + // Update roll life + // Let's not check the whole array every time. + // Instead, only check 1 beat back. Even 1 is overkill. + // Just update the life here and let Update judge the roll. + const int iSongRow = BeatToNoteRow(fSongBeat); + const int iStartCheckingAt = max( 0, iSongRow-BeatToNoteRow(1) ); + NoteData::iterator begin, end; + m_NoteData.GetTapNoteRangeInclusive( col, iStartCheckingAt, iSongRow+1, begin, end ); + for( ; begin != end; ++begin ) { - /* This hold note is not judged and we stepped on its head. Update iLastHeldRow. - * Do this even if we're a little beyond the end of the hold note, to make sure - * iLastHeldRow is clamped to iEndRow if the hold note is held all the way. */ - tn.HoldResult.iLastHeldRow = min( iSongRow, iEndRow ); - } + TapNote &tn = begin->second; + if( tn.type != TapNote::hold_head ) + continue; + int iRow = begin->first; - // If the song beat is in the range of this hold: - if( iRow <= iSongRow && iRow <= iEndRow ) - { - switch( tn.subType ) + HoldNoteScore hns = tn.HoldResult.hns; + if( hns != HNS_NONE ) // if this HoldNote already has a result + continue; // we don't need to update the logic for this one + + // if they got a bad score or haven't stepped on the corresponding tap yet + const TapNoteScore tns = tn.result.tns; + const bool bSteppedOnTapNote = tns != TNS_NONE && tns != TNS_MISS; // did they step on the start of this roll? + + int iEndRow = iRow + tn.iDuration; + + if( bSteppedOnTapNote && tn.HoldResult.fLife != 0 ) { - case TapNote::hold_head_hold: - // this is handled in Update - break; - case TapNote::hold_head_roll: - { - // Increase life - fLife = 1; + /* This hold note is not judged and we stepped on its head. Update iLastHeldRow. + * Do this even if we're a little beyond the end of the hold note, to make sure + * iLastHeldRow is clamped to iEndRow if the hold note is held all the way. */ + tn.HoldResult.iLastHeldRow = min( iSongRow, iEndRow ); + } - bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD; - if( m_pNoteField ) - m_pNoteField->DidHoldNote( col, HNS_OK, bBright ); + // If the song beat is in the range of this hold: + if( iRow <= iSongRow && iRow <= iEndRow ) + { + switch( tn.subType ) + { + case TapNote::hold_head_hold: + // this is handled in Update + break; + case TapNote::hold_head_roll: + { + // Increase life + tn.HoldResult.fLife = 1; + + bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD; + if( m_pNoteField ) + m_pNoteField->DidHoldNote( col, HNS_OK, bBright ); + } + break; + default: + ASSERT(0); } - break; - default: - ASSERT(0); } } - - /* check for NG. If the head was missed completely, don't count an NG. */ - if( bSteppedOnTapNote && fLife == 0 ) // the player has not pressed the button for a long time! - hns = HNS_NG; - - // check for OK - if( iSongRow >= iEndRow && bSteppedOnTapNote && fLife > 0 ) // if this HoldNote is in the past - { - fLife = 1; - hns = HNS_OK; - bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD; - if( m_pNoteField ) - m_pNoteField->DidHoldNote( col, HNS_OK, bBright ); - } - - if( hns != HNS_NONE ) - { - /* this note has been judged */ - HandleHoldScore( hns, tns ); - m_HoldJudgment[col].SetHoldJudgment( hns ); - - int ms_error = (hns == HNS_OK)? 0:MAX_PRO_TIMING_ERROR; - - if( m_pPlayerStageStats ) - m_pPlayerStageStats->iTotalError += ms_error; - } - - tn.HoldResult.fLife = fLife; - tn.HoldResult.hns = hns; } }