int NoteData::GetNumHands( float fStartBeat, float fEndBeat ) const { /* Count the number of times you have to use your hands. This includes * three taps at the same time, a tap while two hold notes are being held, * etc. Only count rows that have at least one tap note (hold heads count). * Otherwise, every row of hold notes counts, so three simultaneous hold * notes will count as hundreds of "hands". */ if( fEndBeat == -1 ) fEndBeat = GetNumBeats(); int iStartIndex = BeatToNoteRow( fStartBeat ); int iEndIndex = BeatToNoteRow( fEndBeat ); /* Clamp to known-good ranges. */ iStartIndex = max( iStartIndex, 0 ); iEndIndex = min( iEndIndex, GetNumRows()-1 ); int iNum = 0; for( int i=iStartIndex; i<=iEndIndex; i++ ) { if( !RowNeedsHands(i) ) continue; iNum++; } return iNum; }
/* See NoteData::GetNumHands(). */ int NoteDataWithScoring::GetSuccessfulHands( float fStartBeat, float fEndBeat ) const { if( fEndBeat == -1 ) fEndBeat = GetNumBeats(); int iStartIndex = BeatToNoteRow( fStartBeat ); int iEndIndex = BeatToNoteRow( fEndBeat ); /* Clamp to known-good ranges. */ iStartIndex = max( iStartIndex, 0 ); iEndIndex = min( iEndIndex, GetNumRows()-1 ); int iNum = 0; for( int i=iStartIndex; i<=iEndIndex; i++ ) { if( !RowNeedsHands(i) ) continue; bool Missed = false; for( int t=0; t<GetNumTracks(); t++ ) { TapNote tn = GetTapNoteX(t, i); if( tn.type == TapNote::empty ) continue; if( tn.type == TapNote::mine ) // mines don't count continue; if( GetTapNoteScore(t, i) <= TNS_BOO ) Missed = true; } if( Missed ) continue; /* Check hold scores. */ for( int j=0; j<GetNumHoldNotes(); j++ ) { const HoldNote &hn = GetHoldNote(j); HoldNoteResult hnr = GetHoldNoteResult( hn ); /* Check if the row we're checking is in range. */ if( !hn.RowIsInRange(i) ) continue; /* If a hold is released *after* a hands containing it, the hands is * still good. So, ignore the judgement and only examine iLastHeldRow * to be sure that the hold was still held at the point of this row. * (Note that if the hold head tap was missed, then iLastHeldRow == i * and this won't fail--but the tap check above will have already failed.) */ if( hnr.iLastHeldRow < i ) Missed = true; } if( !Missed ) iNum++; } return iNum; }