int NoteDataWithScoring::GetNumNWithScore( TapNoteScore tns, int MinTaps, const float fStartBeat, float fEndBeat ) const { if( fEndBeat == -1 ) fEndBeat = GetNumBeats(); int iStartIndex = BeatToNoteRow( fStartBeat ); int iEndIndex = BeatToNoteRow( fEndBeat ); iStartIndex = max( iStartIndex, 0 ); iEndIndex = min( iEndIndex, GetNumRows()-1 ); int iNumSuccessfulDoubles = 0; for( int i=iStartIndex; i<=iEndIndex; i++ ) { int iNumNotesThisIndex = 0; TapNoteScore minTapNoteScore = TNS_MARVELOUS; for( int t=0; t<GetNumTracks(); t++ ) { switch( GetTapNote(t, i).type ) { case TapNote::tap: case TapNote::hold_head: iNumNotesThisIndex++; minTapNoteScore = min( minTapNoteScore, GetTapNoteScore(t, i) ); } } if( iNumNotesThisIndex >= MinTaps && minTapNoteScore >= tns ) iNumSuccessfulDoubles++; } return iNumSuccessfulDoubles; }
int NoteData::GetNumN( int MinTaps, 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++ ) { int iNumNotesThisIndex = 0; for( int t=0; t<m_iNumTracks; t++ ) { TapNote tn = GetTapNoteX(t, i); if( tn.type != TapNote::mine && tn.type != TapNote::empty ) // mines don't count iNumNotesThisIndex++; } if( iNumNotesThisIndex >= MinTaps ) iNum++; } return iNum; }
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; }
int NoteData::GetNumTapNotes( float fStartBeat, float fEndBeat ) const { int iNumNotes = 0; 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 ); for( int t=0; t<m_iNumTracks; t++ ) { for( int i=iStartIndex; i<=iEndIndex; i++ ) { TapNote tn = GetTapNoteX(t, i); if( tn.type != TapNote::empty && tn.type != TapNote::mine ) iNumNotes++; } } return iNumNotes; }
/* 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; }
int NoteData::GetNumRowsWithTapOrHoldHead( float fStartBeat, float fEndBeat ) const { int iNumNotes = 0; if(fEndBeat == -1) fEndBeat = GetNumBeats(); int iStartIndex = BeatToNoteRow( fStartBeat ); int iEndIndex = BeatToNoteRow( fEndBeat ); for( int i=iStartIndex; i<=iEndIndex; i++ ) if( IsThereATapOrHoldHeadAtRow(i) ) iNumNotes++; return iNumNotes; }
int NoteData::GetNumHoldNotes( float fStartBeat, float fEndBeat ) const { if( fEndBeat == -1 ) fEndBeat = GetNumBeats(); int iStartIndex = BeatToNoteRow( fStartBeat ); int iEndIndex = BeatToNoteRow( fEndBeat ); int iNumHolds = 0; for( int i=0; i<GetNumHoldNotes(); i++ ) { const HoldNote &hn = GetHoldNote(i); if( iStartIndex <= hn.iStartRow && hn.iEndRow <= iEndIndex ) iNumHolds++; } return iNumHolds; }
int NoteDataWithScoring::GetNumHoldNotesWithScore( HoldNoteScore hns, const float fStartBeat, float fEndBeat ) const { int iNumSuccessfulHolds = 0; if(fEndBeat == -1) fEndBeat = GetNumBeats(); int iStartIndex = BeatToNoteRow( fStartBeat ); int iEndIndex = BeatToNoteRow( fEndBeat ); for( int i=0; i<GetNumHoldNotes(); i++ ) { const HoldNote &hn = GetHoldNote(i); if( iStartIndex > hn.iStartRow || hn.iEndRow > iEndIndex ) continue; if( GetHoldNoteScore(hn) == hns ) iNumSuccessfulHolds++; } return iNumSuccessfulHolds; }
int NoteDataWithScoring::GetNumTapNotesWithScore( TapNoteScore tns, const float fStartBeat, float fEndBeat ) const { int iNumSuccessfulTapNotes = 0; if(fEndBeat == -1) fEndBeat = GetNumBeats()+1; unsigned iStartIndex = BeatToNoteRow( fStartBeat ); unsigned iEndIndex = BeatToNoteRow( fEndBeat ); for( unsigned i=iStartIndex; i<min(float(iEndIndex), float(m_TapNoteScores[0].size())); i++ ) { for( int t=0; t<GetNumTracks(); t++ ) { if( this->GetTapNote(t, i).type != TapNote::empty && GetTapNoteScore(t, i) >= tns ) iNumSuccessfulTapNotes++; } } return iNumSuccessfulTapNotes; }
int NoteDataWithScoring::GetSuccessfulMines( float fStartBeat, float fEndBeat ) const { if( fEndBeat == -1 ) fEndBeat = GetNumBeats(); int iStartIndex = BeatToNoteRow( fStartBeat ); int iEndIndex = BeatToNoteRow( fEndBeat ); iStartIndex = max( iStartIndex, 0 ); iEndIndex = min( iEndIndex, GetNumRows()-1 ); int iNumSuccessfulMinesNotes = 0; for( int i=iStartIndex; i<=iEndIndex; i++ ) { for( int t=0; t<GetNumTracks(); t++ ) { if( this->GetTapNote(t,i).type == TapNote::mine && GetTapNoteScore(t, i) != TNS_HIT_MINE ) iNumSuccessfulMinesNotes++; } } return iNumSuccessfulMinesNotes; }