2002-06-23 02:50:33 +00:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
/*
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
Class: NoteDataWithScoring
|
|
|
|
|
|
|
|
|
|
Desc: See header.
|
|
|
|
|
|
|
|
|
|
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
|
|
|
|
Chris Danford
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "NoteDataWithScoring.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NoteDataWithScoring::NoteDataWithScoring()
|
|
|
|
|
{
|
|
|
|
|
Init();
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-03 21:38:22 +00:00
|
|
|
void NoteDataWithScoring::Init(int taps, int holds)
|
2002-08-01 21:55:40 +00:00
|
|
|
{
|
|
|
|
|
NoteData::Init();
|
|
|
|
|
|
2002-06-23 02:50:33 +00:00
|
|
|
for( int t=0; t<MAX_NOTE_TRACKS; t++ )
|
|
|
|
|
for( int i=0; i<MAX_TAP_NOTE_ROWS; i++ )
|
|
|
|
|
m_TapNoteScores[t][i] = TNS_NONE;
|
|
|
|
|
|
2002-11-03 21:38:22 +00:00
|
|
|
m_HoldNoteScores.clear();
|
|
|
|
|
m_HoldNoteScores.insert(m_HoldNoteScores.begin(), holds, HNS_NONE);
|
|
|
|
|
|
|
|
|
|
m_fHoldNoteLife.clear();
|
|
|
|
|
// start with full life
|
|
|
|
|
m_fHoldNoteLife.insert(m_fHoldNoteLife.begin(), holds, 1.0f);
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-12 02:31:52 +00:00
|
|
|
int NoteDataWithScoring::GetNumTapNotesWithScore( TapNoteScore tns, const float fStartBeat, const float fEndBeat )
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
|
|
|
|
int iNumSuccessfulTapNotes = 0;
|
|
|
|
|
|
|
|
|
|
int iStartIndex = BeatToNoteRow( fStartBeat );
|
|
|
|
|
int iEndIndex = BeatToNoteRow( fEndBeat );
|
|
|
|
|
|
|
|
|
|
for( int i=iStartIndex; i<min(iEndIndex, MAX_TAP_NOTE_ROWS); i++ )
|
|
|
|
|
{
|
|
|
|
|
for( int t=0; t<m_iNumTracks; t++ )
|
|
|
|
|
{
|
2002-12-17 22:07:59 +00:00
|
|
|
if( this->GetTapNote(t, i) != TAP_EMPTY && GetTapNoteScore(t, i) == tns )
|
2002-06-23 02:50:33 +00:00
|
|
|
iNumSuccessfulTapNotes++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return iNumSuccessfulTapNotes;
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-12 02:31:52 +00:00
|
|
|
int NoteDataWithScoring::GetNumDoublesWithScore( TapNoteScore tns, const float fStartBeat, const float fEndBeat )
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
|
|
|
|
int iNumSuccessfulDoubles = 0;
|
|
|
|
|
|
|
|
|
|
int iStartIndex = BeatToNoteRow( fStartBeat );
|
|
|
|
|
int iEndIndex = BeatToNoteRow( fEndBeat );
|
|
|
|
|
|
|
|
|
|
for( int i=iStartIndex; i<min(iEndIndex, MAX_TAP_NOTE_ROWS); i++ )
|
|
|
|
|
{
|
|
|
|
|
int iNumNotesThisIndex = 0;
|
|
|
|
|
TapNoteScore minTapNoteScore = TNS_PERFECT;
|
|
|
|
|
for( int t=0; t<m_iNumTracks; t++ )
|
|
|
|
|
{
|
2002-10-25 04:37:00 +00:00
|
|
|
if( GetTapNote(t, i) != TAP_EMPTY )
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
|
|
|
|
iNumNotesThisIndex++;
|
2002-12-17 22:07:59 +00:00
|
|
|
minTapNoteScore = min( minTapNoteScore, GetTapNoteScore(t, i) );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
2002-09-12 02:31:52 +00:00
|
|
|
if( iNumNotesThisIndex >= 2 && minTapNoteScore == tns )
|
2002-06-23 02:50:33 +00:00
|
|
|
iNumSuccessfulDoubles++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return iNumSuccessfulDoubles;
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-12 02:31:52 +00:00
|
|
|
int NoteDataWithScoring::GetNumHoldNotesWithScore( HoldNoteScore hns, const float fStartBeat, const float fEndBeat )
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
|
|
|
|
int iNumSuccessfulHolds = 0;
|
|
|
|
|
|
2002-11-02 22:59:12 +00:00
|
|
|
for( int i=0; i<GetNumHoldNotes(); i++ )
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
2002-11-02 22:46:15 +00:00
|
|
|
const HoldNote &hn = GetHoldNote(i);
|
2002-09-12 02:31:52 +00:00
|
|
|
if( fStartBeat <= hn.m_fStartBeat && hn.m_fEndBeat <= fEndBeat && m_HoldNoteScores[i] == hns )
|
2002-06-23 02:50:33 +00:00
|
|
|
iNumSuccessfulHolds++;
|
|
|
|
|
}
|
|
|
|
|
return iNumSuccessfulHolds;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-17 22:05:17 +00:00
|
|
|
bool NoteDataWithScoring::IsRowComplete( int index )
|
|
|
|
|
{
|
|
|
|
|
for( int t=0; t<m_iNumTracks; t++ )
|
2002-12-17 22:07:59 +00:00
|
|
|
if( GetTapNote(t, index) != TAP_EMPTY && GetTapNoteScore(t, index) < TNS_GREAT )
|
2002-12-17 22:05:17 +00:00
|
|
|
return false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float NoteDataWithScoring::GetActualRadarValue( RadarCategory rv, float fSongSeconds )
|
|
|
|
|
{
|
|
|
|
|
switch( rv )
|
|
|
|
|
{
|
|
|
|
|
case RADAR_STREAM: return GetActualStreamRadarValue( fSongSeconds ); break;
|
|
|
|
|
case RADAR_VOLTAGE: return GetActualVoltageRadarValue( fSongSeconds ); break;
|
|
|
|
|
case RADAR_AIR: return GetActualAirRadarValue( fSongSeconds ); break;
|
|
|
|
|
case RADAR_FREEZE: return GetActualFreezeRadarValue( fSongSeconds ); break;
|
|
|
|
|
case RADAR_CHAOS: return GetActualChaosRadarValue( fSongSeconds ); break;
|
|
|
|
|
default: ASSERT(0); return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-06-23 02:50:33 +00:00
|
|
|
|
|
|
|
|
float NoteDataWithScoring::GetActualStreamRadarValue( float fSongSeconds )
|
|
|
|
|
{
|
|
|
|
|
// density of steps
|
2002-09-12 02:31:52 +00:00
|
|
|
int iNumSuccessfulNotes =
|
|
|
|
|
GetNumTapNotesWithScore(TNS_PERFECT) +
|
|
|
|
|
GetNumTapNotesWithScore(TNS_GREAT)/2 +
|
|
|
|
|
GetNumHoldNotesWithScore(HNS_OK);
|
2002-06-23 02:50:33 +00:00
|
|
|
float fNotesPerSecond = iNumSuccessfulNotes/fSongSeconds;
|
2002-07-03 21:27:26 +00:00
|
|
|
float fReturn = fNotesPerSecond / 7;
|
2002-07-03 03:13:13 +00:00
|
|
|
return min( fReturn, 1.0f );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float NoteDataWithScoring::GetActualVoltageRadarValue( float fSongSeconds )
|
|
|
|
|
{
|
2002-07-03 21:27:26 +00:00
|
|
|
float fAvgBPS = GetLastBeat() / fSongSeconds;
|
2002-06-23 02:50:33 +00:00
|
|
|
|
2002-07-03 21:27:26 +00:00
|
|
|
// peak density of steps
|
|
|
|
|
float fMaxDensitySoFar = 0;
|
2002-06-23 02:50:33 +00:00
|
|
|
|
2002-07-03 21:27:26 +00:00
|
|
|
const int BEAT_WINDOW = 8;
|
2002-06-23 02:50:33 +00:00
|
|
|
|
2002-07-03 21:27:26 +00:00
|
|
|
for( int i=0; i<MAX_BEATS; i+=BEAT_WINDOW )
|
|
|
|
|
{
|
2002-09-12 02:31:52 +00:00
|
|
|
int iNumNotesThisWindow = GetNumTapNotesWithScore(TNS_PERFECT,(float)i,(float)i+BEAT_WINDOW) + GetNumHoldNotesWithScore(HNS_OK,(float)i,(float)i+BEAT_WINDOW);
|
2002-07-03 21:27:26 +00:00
|
|
|
float fDensityThisWindow = iNumNotesThisWindow/(float)BEAT_WINDOW;
|
|
|
|
|
fMaxDensitySoFar = max( fMaxDensitySoFar, fDensityThisWindow );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
2002-07-03 21:27:26 +00:00
|
|
|
float fReturn = fMaxDensitySoFar*fAvgBPS/10;
|
2002-07-03 03:13:13 +00:00
|
|
|
return min( fReturn, 1.0f );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float NoteDataWithScoring::GetActualAirRadarValue( float fSongSeconds )
|
|
|
|
|
{
|
|
|
|
|
// number of doubles
|
2002-09-12 02:31:52 +00:00
|
|
|
int iNumDoubles =
|
|
|
|
|
GetNumDoublesWithScore(TNS_PERFECT) +
|
|
|
|
|
GetNumDoublesWithScore(TNS_GREAT)/2;
|
2002-07-03 03:13:13 +00:00
|
|
|
float fReturn = iNumDoubles / fSongSeconds;
|
|
|
|
|
return min( fReturn, 1.0f );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float NoteDataWithScoring::GetActualChaosRadarValue( float fSongSeconds )
|
|
|
|
|
{
|
2002-07-03 03:13:13 +00:00
|
|
|
// count number of triplets
|
2002-07-03 21:27:26 +00:00
|
|
|
int iNumChaosNotesCompleted = 0;
|
2002-07-03 03:13:13 +00:00
|
|
|
for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ )
|
|
|
|
|
{
|
2002-08-23 20:18:29 +00:00
|
|
|
if( !IsRowEmpty(r) && IsRowComplete(r) && GetNoteType(r) >= NOTE_TYPE_12TH )
|
2002-07-31 19:40:40 +00:00
|
|
|
iNumChaosNotesCompleted++;
|
2002-07-03 03:13:13 +00:00
|
|
|
}
|
|
|
|
|
|
2002-07-11 19:02:26 +00:00
|
|
|
float fReturn = iNumChaosNotesCompleted / fSongSeconds * 0.5f;
|
2002-07-03 03:13:13 +00:00
|
|
|
return min( fReturn, 1.0f );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float NoteDataWithScoring::GetActualFreezeRadarValue( float fSongSeconds )
|
|
|
|
|
{
|
|
|
|
|
// number of hold steps
|
2002-09-12 02:31:52 +00:00
|
|
|
float fReturn = GetNumHoldNotesWithScore(HNS_OK) / fSongSeconds;
|
2002-07-03 03:13:13 +00:00
|
|
|
return min( fReturn, 1.0f );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|