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:
Chris Danford
2004-07-24 18:11:04 +00:00
parent fa6f155c70
commit 05257b050c
7 changed files with 59 additions and 60 deletions
+5 -5
View File
@@ -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 );
+1 -1
View File
@@ -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 );
}
+2 -2
View File
@@ -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]);
+2 -2
View File
@@ -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;
+2 -2
View File
@@ -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;
+38 -38
View File
@@ -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;
+9 -10
View File
@@ -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;
};