fix combo and life history don't accumulate correctly in courses
change combo and life history position units to Seconds from Beats
This commit is contained in:
@@ -27,14 +27,14 @@ void ComboGraph::Load( CString Path, const StageStats &s, PlayerNumber pn )
|
||||
|
||||
const bool IsMax = (combo.GetStageCnt() == MaxComboSize);
|
||||
|
||||
LOG->Trace("combo %i is %f+%f", i, combo.start, combo.size);
|
||||
LOG->Trace("combo %i is %f+%f", i, combo.fStartSecond, combo.fSizeSeconds);
|
||||
Sprite *sprite = new Sprite;
|
||||
sprite->SetName( "ComboBar" );
|
||||
const CString path = ssprintf( "%s %s", Path.c_str(), IsMax? "max":"normal" );
|
||||
sprite->Load( THEME->GetPathToG(path) );
|
||||
|
||||
const float start = SCALE( combo.start, s.fFirstPos[pn], s.fLastPos[pn], 0.0f, 1.0f );
|
||||
const float size = SCALE( combo.size, 0, s.fLastPos[pn]-s.fFirstPos[pn], 0.0f, 1.0f );
|
||||
const float start = SCALE( combo.fStartSecond, s.fFirstSecond[pn], s.fLastSecond[pn], 0.0f, 1.0f );
|
||||
const float size = SCALE( combo.fSizeSeconds, 0, s.fLastSecond[pn]-s.fFirstSecond[pn], 0.0f, 1.0f );
|
||||
sprite->SetCropLeft ( SCALE( size, 0.0f, 1.0f, 0.5f, 0.0f ) );
|
||||
sprite->SetCropRight( SCALE( size, 0.0f, 1.0f, 0.5f, 0.0f ) );
|
||||
|
||||
@@ -66,8 +66,8 @@ void ComboGraph::Load( CString Path, const StageStats &s, PlayerNumber pn )
|
||||
text->SetName( "ComboMaxNumber" );
|
||||
text->LoadFromFont( THEME->GetPathToF(Path) );
|
||||
|
||||
const float start = SCALE( combo.start, s.fFirstPos[pn], s.fLastPos[pn], 0.0f, 1.0f );
|
||||
const float size = SCALE( combo.size, 0, s.fLastPos[pn]-s.fFirstPos[pn], 0.0f, 1.0f );
|
||||
const float start = SCALE( combo.fStartSecond, s.fFirstSecond[pn], s.fLastSecond[pn], 0.0f, 1.0f );
|
||||
const float size = SCALE( combo.fSizeSeconds, 0, s.fLastSecond[pn]-s.fFirstSecond[pn], 0.0f, 1.0f );
|
||||
|
||||
const float CenterPercent = start + size/2;
|
||||
const float CenterXPos = SCALE( CenterPercent, 0.0f, 1.0f, -width/2.0f, width/2.0f );
|
||||
|
||||
@@ -289,7 +289,7 @@ float NoteDataWithScoring::GetActualVoltageRadarValue( float fSongSeconds, Playe
|
||||
* 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. */
|
||||
const StageStats::Combo_t MaxCombo = g_CurStageStats.GetMaxCombo( pn );
|
||||
float fComboPercent = SCALE( MaxCombo.size, 0, g_CurStageStats.fLastPos[pn]-g_CurStageStats.fFirstPos[pn], 0.0f, 1.0f );
|
||||
float fComboPercent = SCALE( MaxCombo.fSizeSeconds, 0, g_CurStageStats.fLastSecond[pn]-g_CurStageStats.fFirstSecond[pn], 0.0f, 1.0f );
|
||||
return clamp( fComboPercent, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
|
||||
@@ -1177,7 +1177,7 @@ void PlayerMinus::HandleTapRowScore( unsigned row )
|
||||
/* Use the real current beat, not the beat we've been passed. That's because we
|
||||
* want to record the current life/combo to the current time; eg. if it's a MISS,
|
||||
* the beat we're registering is in the past, but the life is changing now. */
|
||||
g_CurStageStats.UpdateComboList( m_PlayerNumber, GAMESTATE->m_fSongBeat, false );
|
||||
g_CurStageStats.UpdateComboList( m_PlayerNumber, g_CurStageStats.fAliveSeconds[m_PlayerNumber], false );
|
||||
|
||||
float life = -1;
|
||||
if( m_pLifeMeter )
|
||||
@@ -1189,7 +1189,7 @@ void PlayerMinus::HandleTapRowScore( unsigned row )
|
||||
life = 1.0f - life;
|
||||
}
|
||||
if( life != -1 )
|
||||
g_CurStageStats.SetLifeRecord( m_PlayerNumber, life, GAMESTATE->m_fSongBeat );
|
||||
g_CurStageStats.SetLifeRecordAt( m_PlayerNumber, life, g_CurStageStats.fAliveSeconds[m_PlayerNumber] );
|
||||
|
||||
if (m_pScoreDisplay)
|
||||
m_pScoreDisplay->SetScore(g_CurStageStats.iScore[m_PlayerNumber]);
|
||||
|
||||
@@ -121,8 +121,8 @@ ScreenEnding::ScreenEnding( CString sClassName ) : ScreenAttract( sClassName, fa
|
||||
for( float f = 0; f < 100.0f; f += 1.0f )
|
||||
{
|
||||
float fP1 = fmodf(f/100*4+.3f,1);
|
||||
g_CurStageStats.SetLifeRecord( PLAYER_1, fP1, f );
|
||||
g_CurStageStats.SetLifeRecord( PLAYER_2, 1-fP1, f );
|
||||
g_CurStageStats.SetLifeRecordAt( PLAYER_1, fP1, f );
|
||||
g_CurStageStats.SetLifeRecordAt( PLAYER_2, 1-fP1, f );
|
||||
}
|
||||
|
||||
g_CurStageStats.iActualDancePoints[PLAYER_1] = rand()%3;
|
||||
|
||||
@@ -120,8 +120,8 @@ void ScreenEvaluation::Init()
|
||||
for( float f = 0; f < 100.0f; f += 1.0f )
|
||||
{
|
||||
float fP1 = fmodf(f/100*4+.3f,1);
|
||||
g_CurStageStats.SetLifeRecord( PLAYER_1, fP1, f );
|
||||
g_CurStageStats.SetLifeRecord( PLAYER_2, 1-fP1, f );
|
||||
g_CurStageStats.SetLifeRecordAt( PLAYER_1, fP1, f );
|
||||
g_CurStageStats.SetLifeRecordAt( PLAYER_2, 1-fP1, f );
|
||||
}
|
||||
|
||||
g_CurStageStats.iActualDancePoints[PLAYER_1] = rand()%3;
|
||||
|
||||
@@ -28,15 +28,14 @@ void StageStats::Init()
|
||||
fSecondsBeforeFail[p] = 0;
|
||||
iSongsPassed[p] = iSongsPlayed[p] = 0;
|
||||
iTotalError[p] = 0;
|
||||
fFirstPos[p] = fLastPos[p] = 0;
|
||||
|
||||
memset( iTapNoteScores[p], 0, sizeof(iTapNoteScores[p]) );
|
||||
memset( iHoldNoteScores[p], 0, sizeof(iHoldNoteScores[p]) );
|
||||
radarPossible[p].Init();
|
||||
radarActual[p].Init();
|
||||
|
||||
fFirstPos[p] = 999999;
|
||||
fLastPos[p] = 0;
|
||||
fFirstSecond[p] = 999999;
|
||||
fLastSecond[p] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,15 +76,16 @@ void StageStats::AddStats( const StageStats& other )
|
||||
iSongsPlayed[p] += other.iSongsPlayed[p];
|
||||
iTotalError[p] += other.iTotalError[p];
|
||||
|
||||
const float fOtherFirst = other.fFirstPos[p] + fLastPos[p];
|
||||
const float fOtherLast = other.fLastPos[p] + fLastPos[p];
|
||||
const float fOtherFirstSecond = other.fFirstSecond[p] + fLastSecond[p];
|
||||
const float fOtherLastSecond = other.fLastSecond[p] + fLastSecond[p];
|
||||
fLastSecond[p] = fOtherLastSecond;
|
||||
|
||||
map<float,float>::const_iterator it;
|
||||
for( it = other.fLifeRecord[p].begin(); it != other.fLifeRecord[p].end(); ++it )
|
||||
{
|
||||
const float pos = it->first;
|
||||
const float life = it->second;
|
||||
fLifeRecord[p][fOtherFirst+pos] = life;
|
||||
fLifeRecord[p][fOtherFirstSecond+pos] = life;
|
||||
}
|
||||
|
||||
unsigned i;
|
||||
@@ -94,7 +94,7 @@ void StageStats::AddStats( const StageStats& other )
|
||||
const Combo_t &combo = other.ComboList[p][i];
|
||||
|
||||
Combo_t newcombo(combo);
|
||||
newcombo.start += fOtherFirst;
|
||||
newcombo.fStartSecond += fOtherFirstSecond;
|
||||
ComboList[p].push_back( newcombo );
|
||||
}
|
||||
|
||||
@@ -104,19 +104,17 @@ void StageStats::AddStats( const StageStats& other )
|
||||
{
|
||||
Combo_t &prevcombo = ComboList[p][i-1];
|
||||
Combo_t &combo = ComboList[p][i];
|
||||
const float PrevComboEnd = prevcombo.start + prevcombo.size;
|
||||
const float ThisComboStart = combo.start;
|
||||
const float PrevComboEnd = prevcombo.fStartSecond + prevcombo.fSizeSeconds;
|
||||
const float ThisComboStart = combo.fStartSecond;
|
||||
if( fabsf(PrevComboEnd - ThisComboStart) > 0.001 )
|
||||
continue;
|
||||
|
||||
/* These are really the same combo. */
|
||||
prevcombo.size += combo.size;
|
||||
prevcombo.fSizeSeconds += combo.fSizeSeconds;
|
||||
prevcombo.cnt += combo.cnt;
|
||||
ComboList[p].erase( ComboList[p].begin()+i );
|
||||
--i;
|
||||
}
|
||||
|
||||
fLastPos[p] = fOtherLast;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,28 +246,29 @@ float StageStats::GetPercentDancePoints( PlayerNumber pn ) const
|
||||
return fPercentDancePoints;
|
||||
}
|
||||
|
||||
void StageStats::SetLifeRecord( PlayerNumber pn, float life, float pos )
|
||||
void StageStats::SetLifeRecordAt( PlayerNumber pn, float fLife, float fSecond )
|
||||
{
|
||||
if( pos < 0 )
|
||||
if( fSecond < 0 )
|
||||
return;
|
||||
|
||||
fFirstPos[pn] = min( pos, fFirstPos[pn] );
|
||||
fLastPos[pn] = max( pos, fLastPos[pn] );
|
||||
fFirstSecond[pn] = min( fSecond, fFirstSecond[pn] );
|
||||
fLastSecond[pn] = max( fSecond, fLastSecond[pn] );
|
||||
LOG->Trace( "fLastSecond = %f", fLastSecond[pn] );
|
||||
|
||||
if( !fLifeRecord[pn].empty() )
|
||||
{
|
||||
const float old = GetLifeRecordAt( pn, pos );
|
||||
if( fabsf(old-pos) < 0.001f )
|
||||
const float old = GetLifeRecordAt( pn, fSecond );
|
||||
if( fabsf(old-fSecond) < 0.001f )
|
||||
return; /* no change */
|
||||
}
|
||||
|
||||
fLifeRecord[pn][pos] = life;
|
||||
fLifeRecord[pn][fSecond] = fLife;
|
||||
}
|
||||
|
||||
float StageStats::GetLifeRecordAt( PlayerNumber pn, float pos ) const
|
||||
float StageStats::GetLifeRecordAt( PlayerNumber pn, float fSecond ) const
|
||||
{
|
||||
/* Find the first element whose key is not less than k. */
|
||||
map<float,float>::const_iterator it = fLifeRecord[pn].lower_bound( pos );
|
||||
map<float,float>::const_iterator it = fLifeRecord[pn].lower_bound( fSecond );
|
||||
|
||||
/* Find the first element whose key is less than k. */
|
||||
if( it != fLifeRecord[pn].begin() )
|
||||
@@ -279,10 +278,10 @@ float StageStats::GetLifeRecordAt( PlayerNumber pn, float pos ) const
|
||||
|
||||
}
|
||||
|
||||
float StageStats::GetLifeRecordLerpAt( PlayerNumber pn, float pos ) const
|
||||
float StageStats::GetLifeRecordLerpAt( PlayerNumber pn, float fSecond ) const
|
||||
{
|
||||
/* Find the first element whose key is not less than k. */
|
||||
map<float,float>::const_iterator later = fLifeRecord[pn].lower_bound( pos );
|
||||
map<float,float>::const_iterator later = fLifeRecord[pn].lower_bound( fSecond );
|
||||
|
||||
/* Find the first element whose key is less than k. */
|
||||
map<float,float>::const_iterator earlier = later;
|
||||
@@ -293,31 +292,32 @@ float StageStats::GetLifeRecordLerpAt( PlayerNumber pn, float pos ) const
|
||||
return earlier->second;
|
||||
|
||||
/* earlier <= pos <= later */
|
||||
const float f = SCALE( pos, earlier->first, later->first, 1, 0 );
|
||||
const float f = SCALE( fSecond, earlier->first, later->first, 1, 0 );
|
||||
return earlier->second * f + later->second * (1-f);
|
||||
}
|
||||
|
||||
|
||||
void StageStats::GetLifeRecord( PlayerNumber pn, float *life, int nout ) const
|
||||
void StageStats::GetLifeRecord( PlayerNumber pn, float *fLifeOut, int iNumSamples ) const
|
||||
{
|
||||
for( int i = 0; i < nout; ++i )
|
||||
for( int i = 0; i < iNumSamples; ++i )
|
||||
{
|
||||
float from = SCALE( i, 0, (float)nout, fFirstPos[pn], fLastPos[pn] );
|
||||
life[i] = GetLifeRecordLerpAt( (PlayerNumber)pn, from );
|
||||
float from = SCALE( i, 0, (float)iNumSamples, fFirstSecond[pn], fLastSecond[pn] );
|
||||
fLifeOut[i] = GetLifeRecordLerpAt( pn, from );
|
||||
}
|
||||
}
|
||||
|
||||
/* If "rollover" is true, we're being called before gameplay begins, so we can record
|
||||
* the amount of the first combo that comes from the previous song. */
|
||||
void StageStats::UpdateComboList( PlayerNumber pn, float pos, bool rollover )
|
||||
void StageStats::UpdateComboList( PlayerNumber pn, float fSecond, bool rollover )
|
||||
{
|
||||
if( pos < 0 )
|
||||
if( fSecond < 0 )
|
||||
return;
|
||||
|
||||
if( !rollover )
|
||||
{
|
||||
fFirstPos[pn] = min( pos, fFirstPos[pn] );
|
||||
fLastPos[pn] = max( pos, fLastPos[pn] );
|
||||
fFirstSecond[pn] = min( fSecond, fFirstSecond[pn] );
|
||||
fLastSecond[pn] = max( fSecond, fLastSecond[pn] );
|
||||
LOG->Trace( "fLastSecond = %f", fLastSecond[pn] );
|
||||
}
|
||||
|
||||
int cnt = iCurCombo[pn];
|
||||
@@ -328,7 +328,7 @@ void StageStats::UpdateComboList( PlayerNumber pn, float pos, bool rollover )
|
||||
{
|
||||
/* If the previous combo (if any) starts on -9999, then we rolled over some
|
||||
* combo, but missed the first step. Remove it. */
|
||||
if( ComboList[pn].size() && ComboList[pn].back().start == -9999 )
|
||||
if( ComboList[pn].size() && ComboList[pn].back().fStartSecond == -9999 )
|
||||
ComboList[pn].erase( ComboList[pn].begin()+ComboList[pn].size()-1, ComboList[pn].end() );
|
||||
|
||||
/* This is a new combo. */
|
||||
@@ -338,17 +338,17 @@ void StageStats::UpdateComboList( PlayerNumber pn, float pos, bool rollover )
|
||||
* a placeholder in and set it on the next call. (Otherwise, start will be less
|
||||
* than fFirstPos.) */
|
||||
if( rollover )
|
||||
NewCombo.start = -9999;
|
||||
NewCombo.fStartSecond = -9999;
|
||||
else
|
||||
NewCombo.start = pos;
|
||||
NewCombo.fStartSecond = fSecond;
|
||||
ComboList[pn].push_back( NewCombo );
|
||||
}
|
||||
|
||||
Combo_t &combo = ComboList[pn].back();
|
||||
combo.size = pos - combo.start;
|
||||
combo.fSizeSeconds = fSecond - combo.fStartSecond;
|
||||
combo.cnt = cnt;
|
||||
if( !rollover && combo.start == -9999 )
|
||||
combo.start = pos;
|
||||
if( !rollover && combo.fStartSecond == -9999 )
|
||||
combo.fStartSecond = fSecond;
|
||||
|
||||
if( rollover )
|
||||
combo.rollover = cnt;
|
||||
|
||||
@@ -58,17 +58,16 @@ struct StageStats
|
||||
int iTotalError[NUM_PLAYERS];
|
||||
|
||||
map<float,float> fLifeRecord[NUM_PLAYERS];
|
||||
void SetLifeRecord( PlayerNumber pn, float life, float pos );
|
||||
void GetLifeRecord( PlayerNumber pn, float *life, int nout ) const;
|
||||
float GetLifeRecordAt( PlayerNumber pn, float pos ) const;
|
||||
float GetLifeRecordLerpAt( PlayerNumber pn, float pos ) const;
|
||||
void SetLifeRecordAt( PlayerNumber pn, float fLife, float fSecond );
|
||||
void GetLifeRecord( PlayerNumber pn, float *fLifeOut, int iNumSamples ) const;
|
||||
float GetLifeRecordAt( PlayerNumber pn, float fSecond ) const;
|
||||
float GetLifeRecordLerpAt( PlayerNumber pn, float fSecond ) const;
|
||||
|
||||
/* pos,combo */
|
||||
struct Combo_t
|
||||
{
|
||||
/* Start and size of this combo, in the same scale as the combo list mapping and
|
||||
* the life record. */
|
||||
float start, size;
|
||||
float fStartSecond, fSizeSeconds;
|
||||
|
||||
/* Combo size, in steps. */
|
||||
int cnt;
|
||||
@@ -80,11 +79,11 @@ struct StageStats
|
||||
/* Get the size of the combo that came from this song. */
|
||||
int GetStageCnt() const { return cnt - rollover; }
|
||||
|
||||
Combo_t(): start(0), size(0), cnt(0), rollover(0) { }
|
||||
bool IsZero() const { return start < 0; }
|
||||
Combo_t(): fStartSecond(0), fSizeSeconds(0), cnt(0), rollover(0) { }
|
||||
bool IsZero() const { return fStartSecond < 0; }
|
||||
};
|
||||
vector<Combo_t> ComboList[NUM_PLAYERS];
|
||||
float fFirstPos[NUM_PLAYERS], fLastPos[NUM_PLAYERS];
|
||||
float fFirstSecond[NUM_PLAYERS], fLastSecond[NUM_PLAYERS];
|
||||
|
||||
int GetComboAtStartOfStage( PlayerNumber pn ) const;
|
||||
bool FullComboOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const;
|
||||
@@ -93,7 +92,7 @@ struct StageStats
|
||||
bool OneOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const;
|
||||
int GetTotalTaps( PlayerNumber pn ) const;
|
||||
float GetPercentageOfTaps( PlayerNumber pn, TapNoteScore tns ) const;
|
||||
void UpdateComboList( PlayerNumber pn, float pos, bool rollover );
|
||||
void UpdateComboList( PlayerNumber pn, float fSecond, bool rollover );
|
||||
Combo_t GetMaxCombo( PlayerNumber pn ) const;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user