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; } }