2003-02-16 04:01:45 +00:00
|
|
|
#include "global.h"
|
2002-06-23 02:50:33 +00:00
|
|
|
/*
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
Class: NoteDataWithScoring
|
|
|
|
|
|
|
|
|
|
Desc: See header.
|
|
|
|
|
|
|
|
|
|
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
|
|
|
|
Chris Danford
|
2003-12-16 02:15:31 +00:00
|
|
|
Glenn Maynard
|
2002-06-23 02:50:33 +00:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "NoteDataWithScoring.h"
|
2003-07-24 19:44:59 +00:00
|
|
|
#include "GameState.h"
|
2003-07-31 01:18:52 +00:00
|
|
|
#include "RageUtil.h"
|
2003-12-23 00:26:00 +00:00
|
|
|
#include "StageStats.h"
|
2002-06-23 02:50:33 +00:00
|
|
|
|
|
|
|
|
NoteDataWithScoring::NoteDataWithScoring()
|
|
|
|
|
{
|
|
|
|
|
Init();
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-18 22:24:34 +00:00
|
|
|
void NoteDataWithScoring::Init()
|
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++ )
|
2002-12-17 23:31:35 +00:00
|
|
|
m_TapNoteScores[t].clear();
|
2002-06-23 02:50:33 +00:00
|
|
|
|
2002-11-03 21:38:22 +00:00
|
|
|
m_HoldNoteScores.clear();
|
|
|
|
|
m_fHoldNoteLife.clear();
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
2003-03-26 17:53:31 +00:00
|
|
|
int NoteDataWithScoring::GetNumTapNotesWithScore( TapNoteScore tns, const float fStartBeat, float fEndBeat ) const
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
|
|
|
|
int iNumSuccessfulTapNotes = 0;
|
|
|
|
|
|
2003-03-06 22:25:21 +00:00
|
|
|
if(fEndBeat == -1)
|
|
|
|
|
fEndBeat = GetMaxBeat()+1;
|
|
|
|
|
|
2002-12-17 23:31:35 +00:00
|
|
|
unsigned iStartIndex = BeatToNoteRow( fStartBeat );
|
|
|
|
|
unsigned iEndIndex = BeatToNoteRow( fEndBeat );
|
2002-06-23 02:50:33 +00:00
|
|
|
|
2003-04-20 22:08:32 +00:00
|
|
|
for( unsigned i=iStartIndex; i<min(float(iEndIndex), float(m_TapNoteScores[0].size())); i++ )
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
2003-02-01 05:16:38 +00:00
|
|
|
for( int t=0; t<GetNumTracks(); t++ )
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
2003-12-16 02:15:31 +00:00
|
|
|
if( this->GetTapNote(t, i) != TAP_EMPTY && GetTapNoteScore(t, i) >= tns )
|
2002-06-23 02:50:33 +00:00
|
|
|
iNumSuccessfulTapNotes++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return iNumSuccessfulTapNotes;
|
|
|
|
|
}
|
|
|
|
|
|
2003-12-16 02:15:31 +00:00
|
|
|
int NoteDataWithScoring::GetNumNWithScore( TapNoteScore tns, int MinTaps, const float fStartBeat, float fEndBeat ) const
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
2003-12-16 02:15:31 +00:00
|
|
|
if( fEndBeat == -1 )
|
|
|
|
|
fEndBeat = GetMaxBeat();
|
2002-06-23 02:50:33 +00:00
|
|
|
|
2003-12-16 02:15:31 +00:00
|
|
|
int iStartIndex = BeatToNoteRow( fStartBeat );
|
|
|
|
|
int iEndIndex = BeatToNoteRow( fEndBeat );
|
2003-03-06 22:25:21 +00:00
|
|
|
|
2003-12-16 02:15:31 +00:00
|
|
|
iStartIndex = max( iStartIndex, 0 );
|
|
|
|
|
iEndIndex = min( iEndIndex, GetMaxRow()-1 );
|
2002-06-23 02:50:33 +00:00
|
|
|
|
2003-12-16 02:15:31 +00:00
|
|
|
int iNumSuccessfulDoubles = 0;
|
|
|
|
|
for( int i=iStartIndex; i<=iEndIndex; i++ )
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
|
|
|
|
int iNumNotesThisIndex = 0;
|
2003-01-11 08:55:21 +00:00
|
|
|
TapNoteScore minTapNoteScore = TNS_MARVELOUS;
|
2003-02-01 05:16:38 +00:00
|
|
|
for( int t=0; t<GetNumTracks(); t++ )
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
2003-12-16 02:15:31 +00:00
|
|
|
switch( GetTapNote(t, i) )
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
2003-12-16 02:15:31 +00:00
|
|
|
case TAP_TAP:
|
|
|
|
|
case TAP_HOLD_HEAD:
|
|
|
|
|
case TAP_ADDITION:
|
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
|
|
|
}
|
|
|
|
|
}
|
2003-12-16 02:15:31 +00:00
|
|
|
if( iNumNotesThisIndex >= MinTaps && minTapNoteScore >= tns )
|
2002-06-23 02:50:33 +00:00
|
|
|
iNumSuccessfulDoubles++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return iNumSuccessfulDoubles;
|
|
|
|
|
}
|
|
|
|
|
|
2003-03-26 17:53:31 +00:00
|
|
|
int NoteDataWithScoring::GetNumHoldNotesWithScore( HoldNoteScore hns, const float fStartBeat, float fEndBeat ) const
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
|
|
|
|
int iNumSuccessfulHolds = 0;
|
|
|
|
|
|
2003-03-06 22:25:21 +00:00
|
|
|
if(fEndBeat == -1)
|
2003-12-16 04:00:39 +00:00
|
|
|
fEndBeat = GetMaxBeat();
|
|
|
|
|
|
|
|
|
|
int iStartIndex = BeatToNoteRow( fStartBeat );
|
|
|
|
|
int iEndIndex = BeatToNoteRow( fEndBeat );
|
2003-03-06 22:25:21 +00:00
|
|
|
|
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);
|
2003-12-16 06:10:50 +00:00
|
|
|
if( iStartIndex > hn.iStartRow || hn.iEndRow > iEndIndex )
|
|
|
|
|
continue;
|
|
|
|
|
if( GetHoldNoteScore(hn) == hns )
|
2002-06-23 02:50:33 +00:00
|
|
|
iNumSuccessfulHolds++;
|
|
|
|
|
}
|
|
|
|
|
return iNumSuccessfulHolds;
|
|
|
|
|
}
|
|
|
|
|
|
2003-12-16 02:15:31 +00:00
|
|
|
int NoteDataWithScoring::GetSuccessfulMines( float fStartBeat, float fEndBeat ) const
|
|
|
|
|
{
|
|
|
|
|
if( fEndBeat == -1 )
|
|
|
|
|
fEndBeat = GetMaxBeat();
|
|
|
|
|
|
|
|
|
|
int iStartIndex = BeatToNoteRow( fStartBeat );
|
|
|
|
|
int iEndIndex = BeatToNoteRow( fEndBeat );
|
|
|
|
|
|
|
|
|
|
iStartIndex = max( iStartIndex, 0 );
|
|
|
|
|
iEndIndex = min( iEndIndex, GetMaxRow()-1 );
|
|
|
|
|
|
|
|
|
|
int iNumSuccessfulMinesNotes = 0;
|
|
|
|
|
for( int i=iStartIndex; i<=iEndIndex; i++ )
|
|
|
|
|
{
|
|
|
|
|
for( int t=0; t<GetNumTracks(); t++ )
|
|
|
|
|
{
|
|
|
|
|
if( this->GetTapNote(t, i) == TAP_MINE && GetTapNoteScore(t, i) != TNS_MISS )
|
|
|
|
|
iNumSuccessfulMinesNotes++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return iNumSuccessfulMinesNotes;
|
|
|
|
|
}
|
|
|
|
|
|
2003-12-16 07:58:37 +00:00
|
|
|
/* See NoteData::GetNumHands(). */
|
|
|
|
|
int NoteDataWithScoring::GetSuccessfulHands( float fStartBeat, float fEndBeat ) const
|
2003-12-16 04:00:39 +00:00
|
|
|
{
|
2003-12-16 07:58:37 +00:00
|
|
|
if( fEndBeat == -1 )
|
|
|
|
|
fEndBeat = GetMaxBeat();
|
|
|
|
|
|
|
|
|
|
int iStartIndex = BeatToNoteRow( fStartBeat );
|
|
|
|
|
int iEndIndex = BeatToNoteRow( fEndBeat );
|
|
|
|
|
|
|
|
|
|
/* Clamp to known-good ranges. */
|
|
|
|
|
iStartIndex = max( iStartIndex, 0 );
|
|
|
|
|
iEndIndex = min( iEndIndex, GetMaxRow()-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 == TAP_MINE || tn == TAP_EMPTY ) // 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);
|
|
|
|
|
if( hn.iStartRow+1 <= i && i <= hn.iEndRow && GetHoldNoteScore(hn) != HNS_OK )
|
|
|
|
|
Missed = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( !Missed )
|
|
|
|
|
iNum++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return iNum;
|
2003-12-16 04:00:39 +00:00
|
|
|
}
|
|
|
|
|
|
2003-03-26 19:34:59 +00:00
|
|
|
/* Return the minimum tap score of a row. If the row isn't complete (not all
|
|
|
|
|
* taps have been hit), return TNS_NONE or TNS_MISS. */
|
|
|
|
|
TapNoteScore NoteDataWithScoring::MinTapNoteScore(unsigned row) const
|
2002-12-17 22:05:17 +00:00
|
|
|
{
|
2003-03-26 19:34:59 +00:00
|
|
|
TapNoteScore score = TNS_MARVELOUS;
|
2003-02-01 05:16:38 +00:00
|
|
|
for( int t=0; t<GetNumTracks(); t++ )
|
2003-03-26 19:34:59 +00:00
|
|
|
{
|
2003-11-11 07:36:28 +00:00
|
|
|
/* Don't coun, or else the score
|
|
|
|
|
* will always be TNS_NONE. */
|
|
|
|
|
TapNote tn = GetTapNote(t, row);
|
|
|
|
|
if( tn == TAP_EMPTY || tn == TAP_MINE )
|
2003-04-10 05:46:31 +00:00
|
|
|
continue;
|
2003-03-26 19:34:59 +00:00
|
|
|
score = min( score, GetTapNoteScore(t, row) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return score;
|
2002-12-17 22:05:17 +00:00
|
|
|
}
|
|
|
|
|
|
2003-04-10 05:46:31 +00:00
|
|
|
bool NoteDataWithScoring::IsRowCompletelyJudged(unsigned row) const
|
|
|
|
|
{
|
|
|
|
|
return MinTapNoteScore(row) >= TNS_MISS;
|
|
|
|
|
}
|
|
|
|
|
|
2003-03-26 19:34:59 +00:00
|
|
|
/* Return the last tap score of a row: the grade of the tap that completed
|
2003-03-27 18:40:58 +00:00
|
|
|
* the row. If the row has no tap notes, return -1. If any tap notes aren't
|
|
|
|
|
* graded (any tap is TNS_NONE) or are missed (TNS_MISS), return it. */
|
2003-03-27 00:39:17 +00:00
|
|
|
int NoteDataWithScoring::LastTapNoteScoreTrack(unsigned row) const
|
2003-03-26 19:34:59 +00:00
|
|
|
{
|
|
|
|
|
float scoretime = -9999;
|
2003-03-27 00:39:17 +00:00
|
|
|
int best_track = -1;
|
2003-03-26 19:34:59 +00:00
|
|
|
for( int t=0; t<GetNumTracks(); t++ )
|
|
|
|
|
{
|
2003-11-11 07:36:28 +00:00
|
|
|
/* Skip empty tracks and mines */
|
|
|
|
|
TapNote tn = GetTapNote(t, row);
|
|
|
|
|
if( tn == TAP_EMPTY || tn == TAP_MINE )
|
|
|
|
|
continue;
|
2003-03-26 19:34:59 +00:00
|
|
|
|
2003-03-26 22:22:44 +00:00
|
|
|
TapNoteScore tns = GetTapNoteScore(t, row);
|
2003-08-10 19:07:54 +00:00
|
|
|
|
2003-09-27 18:50:38 +00:00
|
|
|
if( tns == TNS_MISS || tns == TNS_NONE )
|
|
|
|
|
return t;
|
2003-03-26 22:22:44 +00:00
|
|
|
|
2003-03-26 19:34:59 +00:00
|
|
|
float tm = GetTapNoteOffset(t, row);
|
|
|
|
|
if(tm < scoretime) continue;
|
|
|
|
|
|
|
|
|
|
scoretime = tm;
|
2003-03-27 00:39:17 +00:00
|
|
|
best_track = t;
|
2003-03-26 19:34:59 +00:00
|
|
|
}
|
|
|
|
|
|
2003-03-27 00:39:17 +00:00
|
|
|
return best_track;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TapNoteScore NoteDataWithScoring::LastTapNoteScore(unsigned row) const
|
|
|
|
|
{
|
|
|
|
|
int track = LastTapNoteScoreTrack(row);
|
|
|
|
|
if(track == -1) return TNS_NONE;
|
|
|
|
|
return GetTapNoteScore(track, row);
|
2003-03-26 19:34:59 +00:00
|
|
|
}
|
|
|
|
|
|
2003-08-01 07:00:40 +00:00
|
|
|
/* From aaroninjapan.com (http://www.aaroninjapan.com/ddr2.html)
|
|
|
|
|
*
|
|
|
|
|
* Stream: The ratio of your number of Perfects to getting all Perfects
|
|
|
|
|
* Voltage: The ratio of your maximum combo to getting a Full Combo
|
|
|
|
|
* Air: The ratio of your number of Perfects on all your jumps (R+L, R+D, etc) to getting all Perfects on all Jumps
|
|
|
|
|
* Chaos: The ratio of your dance level compared to that of AAA (all Perfect) level
|
|
|
|
|
* Freeze: The ratio of your total number of "OK"s on all the Freeze arrows to getting all "OK" on all the Freeze arrows
|
|
|
|
|
*
|
|
|
|
|
* I don't think chaos is correct, at least relative to DDREX. You can AA songs and get a full Chaos graph.
|
|
|
|
|
* No idea what it actually could be, though.
|
|
|
|
|
*/
|
2003-03-26 19:34:59 +00:00
|
|
|
|
2003-07-24 19:44:59 +00:00
|
|
|
float NoteDataWithScoring::GetActualRadarValue( RadarCategory rv, PlayerNumber pn, float fSongSeconds ) const
|
2002-12-17 22:05:17 +00:00
|
|
|
{
|
|
|
|
|
switch( rv )
|
|
|
|
|
{
|
2003-07-24 19:44:59 +00:00
|
|
|
case RADAR_STREAM: return GetActualStreamRadarValue( fSongSeconds, pn ); break;
|
|
|
|
|
case RADAR_VOLTAGE: return GetActualVoltageRadarValue( fSongSeconds, pn ); break;
|
|
|
|
|
case RADAR_AIR: return GetActualAirRadarValue( fSongSeconds, pn ); break;
|
|
|
|
|
case RADAR_FREEZE: return GetActualFreezeRadarValue( fSongSeconds, pn ); break;
|
|
|
|
|
case RADAR_CHAOS: return GetActualChaosRadarValue( fSongSeconds, pn ); break;
|
2003-12-16 02:15:31 +00:00
|
|
|
case RADAR_NUM_TAPS_AND_HOLDS: return (float) GetNumNWithScore( TNS_GOOD, 1 );
|
|
|
|
|
case RADAR_NUM_JUMPS: return (float) GetNumNWithScore( TNS_GOOD, 2 );
|
|
|
|
|
case RADAR_NUM_HOLDS: return (float) GetNumHoldNotesWithScore( HNS_OK );
|
|
|
|
|
case RADAR_NUM_MINES: return (float) GetSuccessfulMines();
|
2003-12-16 04:00:39 +00:00
|
|
|
case RADAR_NUM_HANDS: return (float) GetSuccessfulHands();
|
2003-12-16 02:15:31 +00:00
|
|
|
default: ASSERT(0); return 0;
|
2002-12-17 22:05:17 +00:00
|
|
|
}
|
|
|
|
|
}
|
2002-06-23 02:50:33 +00:00
|
|
|
|
2003-07-24 19:44:59 +00:00
|
|
|
float NoteDataWithScoring::GetActualStreamRadarValue( float fSongSeconds, PlayerNumber pn ) const
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
2003-09-25 01:21:01 +00:00
|
|
|
int TotalSteps = GetNumTapNotes();
|
|
|
|
|
if( !TotalSteps )
|
|
|
|
|
return 1;
|
2003-07-24 13:35:20 +00:00
|
|
|
|
2003-12-16 02:15:31 +00:00
|
|
|
const int Perfects = GetNumTapNotesWithScore(TNS_PERFECT);
|
2003-09-25 01:21:01 +00:00
|
|
|
return clamp( float(Perfects)/TotalSteps, 0.0f, 1.0f );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
2003-07-24 19:44:59 +00:00
|
|
|
float NoteDataWithScoring::GetActualVoltageRadarValue( float fSongSeconds, PlayerNumber pn ) const
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
2003-12-23 00:26:00 +00:00
|
|
|
/* g_CurStageStats.iMaxCombo is unrelated to GetNumTapNotes: m_bComboContinuesBetweenSongs
|
2003-11-02 17:06:25 +00:00
|
|
|
* might be on, and the way combo is counted varies depending on the mode and score
|
|
|
|
|
* keeper. Instead, let's use the length of the longest recorded combo. This is
|
|
|
|
|
* only subtly different: it's the percent of the song the longest combo took to get. */
|
2003-12-23 00:26:00 +00:00
|
|
|
const StageStats::Combo_t MaxCombo = g_CurStageStats.GetMaxCombo( pn );
|
2003-11-02 17:06:25 +00:00
|
|
|
return clamp( MaxCombo.size, 0.0f, 1.0f );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
2003-07-24 19:44:59 +00:00
|
|
|
float NoteDataWithScoring::GetActualAirRadarValue( float fSongSeconds, PlayerNumber pn ) const
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
2003-09-25 01:21:01 +00:00
|
|
|
const int iTotalDoubles = GetNumDoubles();
|
|
|
|
|
if (iTotalDoubles == 0)
|
|
|
|
|
return 1; // no jumps in song
|
2003-07-24 13:35:20 +00:00
|
|
|
|
2003-09-25 01:21:01 +00:00
|
|
|
// number of doubles
|
2003-12-16 02:15:31 +00:00
|
|
|
const int iNumDoubles = GetNumNWithScore( TNS_PERFECT, 2 );
|
2003-09-25 01:21:01 +00:00
|
|
|
return clamp( (float)iNumDoubles / iTotalDoubles, 0.0f, 1.0f );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
2003-07-24 19:44:59 +00:00
|
|
|
float NoteDataWithScoring::GetActualChaosRadarValue( float fSongSeconds, PlayerNumber pn ) const
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
2003-12-23 00:26:00 +00:00
|
|
|
const int PossibleDP = g_CurStageStats.iPossibleDancePoints[pn];
|
2003-09-25 01:21:01 +00:00
|
|
|
if ( PossibleDP == 0 )
|
2003-11-02 17:06:25 +00:00
|
|
|
return 1;
|
2003-07-24 13:35:20 +00:00
|
|
|
|
2003-12-23 00:26:00 +00:00
|
|
|
const int ActualDP = g_CurStageStats.iActualDancePoints[pn];
|
2003-09-25 01:21:01 +00:00
|
|
|
return clamp( float(ActualDP)/PossibleDP, 0.0f, 1.0f );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
2003-07-24 19:44:59 +00:00
|
|
|
float NoteDataWithScoring::GetActualFreezeRadarValue( float fSongSeconds, PlayerNumber pn ) const
|
2002-06-23 02:50:33 +00:00
|
|
|
{
|
|
|
|
|
// number of hold steps
|
2003-09-25 01:21:01 +00:00
|
|
|
const int TotalHolds = GetNumHoldNotes();
|
|
|
|
|
if ( TotalHolds == 0 )
|
|
|
|
|
return 1.0f;
|
|
|
|
|
|
|
|
|
|
const int ActualHolds = GetNumHoldNotesWithScore(HNS_OK);
|
|
|
|
|
return clamp( float(ActualHolds) / TotalHolds, 0.0f, 1.0f );
|
2002-06-23 02:50:33 +00:00
|
|
|
}
|
2002-12-18 22:24:34 +00:00
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
void extend(vector<T> &v, T val, unsigned pos)
|
|
|
|
|
{
|
|
|
|
|
int needed = pos - v.size() + 1;
|
|
|
|
|
if(needed > 0)
|
|
|
|
|
{
|
|
|
|
|
needed += 100; /* optimization: give it a little more than it needs */
|
|
|
|
|
v.insert(v.end(), needed, val);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TapNoteScore NoteDataWithScoring::GetTapNoteScore(unsigned track, unsigned row) const
|
|
|
|
|
{
|
|
|
|
|
if(row >= m_TapNoteScores[track].size())
|
|
|
|
|
return TNS_NONE;
|
|
|
|
|
return m_TapNoteScores[track][row];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NoteDataWithScoring::SetTapNoteScore(unsigned track, unsigned row, TapNoteScore tns)
|
|
|
|
|
{
|
|
|
|
|
extend(m_TapNoteScores[track], TNS_NONE, row);
|
|
|
|
|
m_TapNoteScores[track][row] = tns;
|
|
|
|
|
}
|
|
|
|
|
|
2003-03-26 19:34:59 +00:00
|
|
|
float NoteDataWithScoring::GetTapNoteOffset(unsigned track, unsigned row) const
|
|
|
|
|
{
|
|
|
|
|
if(row >= m_TapNoteOffset[track].size())
|
|
|
|
|
return 0;
|
|
|
|
|
return m_TapNoteOffset[track][row];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NoteDataWithScoring::SetTapNoteOffset(unsigned track, unsigned row, float offset)
|
|
|
|
|
{
|
|
|
|
|
extend(m_TapNoteOffset[track], 0.f, row);
|
|
|
|
|
m_TapNoteOffset[track][row] = offset;
|
|
|
|
|
}
|
|
|
|
|
|
2003-12-16 06:10:50 +00:00
|
|
|
/* We use the end row to index hold notes, instead of the start row, because the start row
|
|
|
|
|
* changes when hold notes are being stepped on, but end rows never change. */
|
|
|
|
|
HoldNoteScore NoteDataWithScoring::GetHoldNoteScore( const HoldNote &hn ) const
|
2002-12-18 22:24:34 +00:00
|
|
|
{
|
2003-12-18 02:34:59 +00:00
|
|
|
map<RowTrack, HoldNoteScore>::const_iterator it = m_HoldNoteScores.find( RowTrack(hn) );
|
2003-12-16 06:10:50 +00:00
|
|
|
if( it == m_HoldNoteScores.end() )
|
2002-12-18 22:24:34 +00:00
|
|
|
return HNS_NONE;
|
2003-12-16 06:10:50 +00:00
|
|
|
return it->second;
|
2002-12-18 22:24:34 +00:00
|
|
|
}
|
|
|
|
|
|
2003-12-16 06:10:50 +00:00
|
|
|
void NoteDataWithScoring::SetHoldNoteScore( const HoldNote &hn, HoldNoteScore hns )
|
2002-12-18 22:24:34 +00:00
|
|
|
{
|
2003-12-18 02:34:59 +00:00
|
|
|
m_HoldNoteScores[RowTrack(hn)] = hns;
|
2002-12-18 22:24:34 +00:00
|
|
|
}
|
|
|
|
|
|
2003-12-16 06:10:50 +00:00
|
|
|
void NoteDataWithScoring::SetHoldNoteLife( const HoldNote &hn, float f )
|
2002-12-18 22:24:34 +00:00
|
|
|
{
|
2003-12-18 02:34:59 +00:00
|
|
|
m_fHoldNoteLife[RowTrack(hn)] = f;
|
2002-12-18 22:24:34 +00:00
|
|
|
}
|
|
|
|
|
|
2003-12-16 06:10:50 +00:00
|
|
|
float NoteDataWithScoring::GetHoldNoteLife( const HoldNote &hn ) const
|
2002-12-18 22:24:34 +00:00
|
|
|
{
|
2003-12-18 02:34:59 +00:00
|
|
|
map<RowTrack, float>::const_iterator it = m_fHoldNoteLife.find( RowTrack(hn) );
|
2003-12-16 06:10:50 +00:00
|
|
|
if( it == m_fHoldNoteLife.end() )
|
2002-12-18 22:24:34 +00:00
|
|
|
return 1.0f;
|
2003-12-16 06:10:50 +00:00
|
|
|
return it->second;
|
2002-12-18 22:24:34 +00:00
|
|
|
}
|