示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
int NoteData::RowNeedsHands( const int row ) const
{
	int iNumNotesThisIndex = 0;
	for( int t=0; t<m_iNumTracks; t++ )
	{
		TapNote tn = GetTapNoteX(t, row);
		switch( tn.type )
		{
		case TapNote::mine:
		case TapNote::empty:
		case TapNote::hold_tail:
			continue;	// skip these types - they don't count
		}
		++iNumNotesThisIndex;
	}

	/* We must have at least one non-hold-body at this row to count it. */
	if( !iNumNotesThisIndex )
		return false;

	if( iNumNotesThisIndex < 3 )
	{
		/* We have at least one, but not enough.  Count holds. */
		for( int j=0; j<GetNumHoldNotes(); j++ )
		{
			const HoldNote &hn = GetHoldNote(j);
			if( hn.iStartRow+1 <= row && row <= hn.iEndRow )
				++iNumNotesThisIndex;
		}
	}

	return iNumNotesThisIndex >= 3;
}
/* 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;
}
示例#5
0
int NoteData::GetFirstNonEmptyTrack( int index ) const
{
	/* If this is out of range, we don't have any notes there, so all tracks are empty. */
	if( index < 0 || index >= GetNumRows() )
		return 0;

	for( int t=0; t<m_iNumTracks; t++ )
		if( GetTapNoteX( t, index ).type != TapNote::empty )
			return t;
	return -1;
}
示例#6
0
bool NoteData::IsRowEmpty( int index ) const
{
	/* If this is out of range, we don't have any notes there, so all tracks are empty. */
	if( index < 0 || index >= GetNumRows() )
		return true;

	for( int t=0; t<m_iNumTracks; t++ )
		if( GetTapNoteX(t, index).type != TapNote::empty )
			return false;
	return true;
}
示例#7
0
bool NoteData::IsRangeEmpty( int track, int iIndexBegin, int iIndexEnd ) const
{
	ASSERT( track<m_iNumTracks );
	
	CLAMP( iIndexBegin, 0, GetNumRows()-1 );
	CLAMP( iIndexEnd, 0, GetNumRows()-1 );

	for( int i=iIndexBegin; i<=iIndexEnd; i++ )
		if( GetTapNoteX(track,i).type != TapNote::empty )
			return false;
	return true;
}
示例#8
0
int NoteData::GetFirstTrackWithTapOrHoldHead( int index ) const
{
	/* If this is out of range, we don't have any notes there, so all tracks are empty. */
	if( index < 0 || index >= GetNumRows() )
		return -1;

	for( int t=0; t<m_iNumTracks; t++ )
	{
		TapNote tn = GetTapNoteX( t, index );
		if( tn.type == TapNote::tap || tn.type == TapNote::hold_head )
			return t;
	}
	return -1;
}
示例#9
0
int NoteData::GetNumTracksWithTap( int index ) const
{
	/* If this is out of range, we don't have any notes there, so all tracks are empty. */
	if( index < 0 || index >= GetNumRows() )
		return 0;

	int iNum = 0;
	for( int t=0; t<m_iNumTracks; t++ )
	{
		TapNote tn = GetTapNoteX( t, index );
		if( tn.type == TapNote::tap )
			iNum++;
	}
	return iNum;
}