show life and combo graphs over the whole song/course - not just over the time the player was alive

This commit is contained in:
Chris Danford
2005-04-20 06:13:06 +00:00
parent a09bf4042e
commit f57e898966
17 changed files with 118 additions and 82 deletions
+14 -11
View File
@@ -12,19 +12,22 @@ const int MinComboSizeToShow = 5;
static ThemeMetric<float> NUMBERS_Y("ComboGraph","NumbersY");
void ComboGraph::Load( const CString& sScreen, const CString& sElement, const StageStats &s, PlayerNumber pn )
void ComboGraph::Load( const CString& sScreen, const CString& sElement, const StageStats &s, const PlayerStageStats &pss )
{
ASSERT( m_SubActors.size() == 0 );
const float fFirstSecond = 0;
const float fLastSecond = s.GetTotalPossibleMusicLengthSeconds();
/* Find the largest combo. */
int MaxComboSize = 0;
for( unsigned i = 0; i < s.m_player[pn].ComboList.size(); ++i )
MaxComboSize = max( MaxComboSize, s.m_player[pn].ComboList[i].GetStageCnt() );
for( unsigned i = 0; i < pss.ComboList.size(); ++i )
MaxComboSize = max( MaxComboSize, pss.ComboList[i].GetStageCnt() );
float width = -1;
for( unsigned i = 0; i < s.m_player[pn].ComboList.size(); ++i )
for( unsigned i = 0; i < pss.ComboList.size(); ++i )
{
const PlayerStageStats::Combo_t &combo = s.m_player[pn].ComboList[i];
const PlayerStageStats::Combo_t &combo = pss.ComboList[i];
if( combo.GetStageCnt() < MinComboSizeToShow )
continue; /* too small */
@@ -35,8 +38,8 @@ void ComboGraph::Load( const CString& sScreen, const CString& sElement, const St
sprite->SetName( "ComboBar" );
sprite->Load( THEME->GetPathG( sScreen, sElement + (IsMax? " max":" normal") ) );
const float start = SCALE( combo.fStartSecond, s.m_player[pn].fFirstSecond, s.m_player[pn].fLastSecond, 0.0f, 1.0f );
const float size = SCALE( combo.fSizeSeconds, 0, s.m_player[pn].fLastSecond-s.m_player[pn].fFirstSecond, 0.0f, 1.0f );
const float start = SCALE( combo.fStartSecond, fFirstSecond, fLastSecond, 0.0f, 1.0f );
const float size = SCALE( combo.fSizeSeconds, 0, fLastSecond-fFirstSecond, 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 ) );
@@ -51,9 +54,9 @@ void ComboGraph::Load( const CString& sScreen, const CString& sElement, const St
this->AddChild( sprite );
}
for( unsigned i = 0; i < s.m_player[pn].ComboList.size(); ++i )
for( unsigned i = 0; i < pss.ComboList.size(); ++i )
{
const PlayerStageStats::Combo_t &combo = s.m_player[pn].ComboList[i];
const PlayerStageStats::Combo_t &combo = pss.ComboList[i];
if( combo.GetStageCnt() < MinComboSizeToShow )
continue; /* too small */
@@ -68,8 +71,8 @@ void ComboGraph::Load( const CString& sScreen, const CString& sElement, const St
text->SetName( "ComboMaxNumber" );
text->LoadFromFont( THEME->GetPathF(sScreen,sElement) );
const float start = SCALE( combo.fStartSecond, s.m_player[pn].fFirstSecond, s.m_player[pn].fLastSecond, 0.0f, 1.0f );
const float size = SCALE( combo.fSizeSeconds, 0, s.m_player[pn].fLastSecond-s.m_player[pn].fFirstSecond, 0.0f, 1.0f );
const float start = SCALE( combo.fStartSecond, fFirstSecond, fLastSecond, 0.0f, 1.0f );
const float size = SCALE( combo.fSizeSeconds, 0, fLastSecond-fFirstSecond, 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 );
+3 -1
View File
@@ -5,11 +5,13 @@
#include "PlayerNumber.h"
struct StageStats;
struct PlayerStageStats;
class ComboGraph: public ActorFrame
{
public:
~ComboGraph() { Unload(); }
void Load( const CString& sScreen, const CString& sElement, const StageStats &s, PlayerNumber pn );
void Load( const CString& sScreen, const CString& sElement, const StageStats &s, const PlayerStageStats &pss );
void Unload();
void TweenOffScreen();
+2 -2
View File
@@ -1403,9 +1403,9 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
{
CHECKPOINT_M( ssprintf("%u/%i", i, (int)STATSMAN->m_vPlayedStageStats.size() ) );
SongAndSteps sas;
sas.pSong = STATSMAN->m_vPlayedStageStats[i].vpSongs[0];
sas.pSong = STATSMAN->m_vPlayedStageStats[i].vpPlayedSongs[0];
ASSERT( sas.pSong );
sas.pSteps = STATSMAN->m_vPlayedStageStats[i].m_player[pn].vpSteps[0];
sas.pSteps = STATSMAN->m_vPlayedStageStats[i].m_player[pn].vpPlayedSteps[0];
ASSERT( sas.pSteps );
vSongAndSteps.push_back( sas );
}
+2 -2
View File
@@ -39,11 +39,11 @@ void GraphDisplay::Unload()
m_pTexture = NULL;
}
void GraphDisplay::LoadFromStageStats( const PlayerStageStats &s )
void GraphDisplay::LoadFromStageStats( const StageStats &ss, const PlayerStageStats &pss )
{
memcpy( m_LastValues, m_CurValues, sizeof(m_CurValues) );
m_Position = 0;
s.GetLifeRecord( m_DestValues, VALUE_RESOLUTION );
pss.GetLifeRecord( m_DestValues, VALUE_RESOLUTION, ss.GetTotalPossibleMusicLengthSeconds() );
for( unsigned i=0; i<ARRAYSIZE(m_DestValues); i++ )
CLAMP( m_DestValues[i], 0.f, 1.f );
UpdateVerts();
+3 -2
View File
@@ -4,6 +4,7 @@
#include "ActorFrame.h"
#include "RageTexture.h"
struct StageStats;
struct PlayerStageStats;
class GraphDisplay: public ActorFrame
@@ -14,14 +15,14 @@ public:
void Load( const CString &TexturePath, float height );
void Unload();
void LoadFromStageStats( const PlayerStageStats &s );
void LoadFromStageStats( const StageStats &ss, const PlayerStageStats &s );
void Update( float fDeltaTime );
void DrawPrimitives();
private:
void UpdateVerts();
enum { VALUE_RESOLUTION=100 };
enum { VALUE_RESOLUTION=200 };
float m_CurValues[VALUE_RESOLUTION];
float m_DestValues[VALUE_RESOLUTION];
float m_LastValues[VALUE_RESOLUTION];
+12 -6
View File
@@ -15,7 +15,8 @@
void PlayerStageStats::Init()
{
vpSteps.clear();
vpPlayedSteps.clear();
vpPossibleSteps.clear();
fAliveSeconds = 0;
bFailed = bFailedEarlier = false;
iPossibleDancePoints = iCurPossibleDancePoints = iActualDancePoints = 0;
@@ -35,8 +36,10 @@ void PlayerStageStats::Init()
void PlayerStageStats::AddStats( const PlayerStageStats& other )
{
FOREACH_CONST( Steps*, other.vpSteps, s )
vpSteps.push_back( *s );
FOREACH_CONST( Steps*, other.vpPlayedSteps, s )
vpPlayedSteps.push_back( *s );
FOREACH_CONST( Steps*, other.vpPossibleSteps, s )
vpPossibleSteps.push_back( *s );
fAliveSeconds += other.fAliveSeconds;
bFailed |= other.bFailed;
bFailedEarlier |= other.bFailedEarlier;
@@ -292,7 +295,10 @@ float PlayerStageStats::GetLifeRecordLerpAt( float fSecond ) const
if( earlier != fLifeRecord.begin() )
--earlier;
if( earlier->first == later->first )
if( earlier->first == later->first ) // two samples from the same time. Don't divide by zero in SCALE
return earlier->second;
if( later == fLifeRecord.end() )
return earlier->second;
/* earlier <= pos <= later */
@@ -300,11 +306,11 @@ float PlayerStageStats::GetLifeRecordLerpAt( float fSecond ) const
}
void PlayerStageStats::GetLifeRecord( float *fLifeOut, int iNumSamples ) const
void PlayerStageStats::GetLifeRecord( float *fLifeOut, int iNumSamples, float fEndSecond ) const
{
for( int i = 0; i < iNumSamples; ++i )
{
float from = SCALE( i, 0, (float)iNumSamples, fFirstSecond, fLastSecond );
float from = SCALE( i, 0, (float)iNumSamples, 0.0f, fEndSecond );
fLifeOut[i] = GetLifeRecordLerpAt( from );
}
}
+3 -2
View File
@@ -22,7 +22,8 @@ struct PlayerStageStats
float GetPercentDancePoints() const;
float GetCurMaxPercentDancePoints() const;
vector<Steps*> vpSteps;
vector<Steps*> vpPlayedSteps;
vector<Steps*> vpPossibleSteps;
float fAliveSeconds; // how far into the music did they last before failing? Updated by Gameplay, scaled by music rate.
/* Set if the player actually failed at any point during the song. This is always
@@ -57,7 +58,7 @@ struct PlayerStageStats
map<float,float> fLifeRecord;
void SetLifeRecordAt( float fLife, float fSecond );
void GetLifeRecord( float *fLifeOut, int iNumSamples ) const;
void GetLifeRecord( float *fLifeOut, int iNumSamples, float fEndSecond ) const;
float GetLifeRecordAt( float fSecond ) const;
float GetLifeRecordLerpAt( float fSecond ) const;
+2 -2
View File
@@ -149,8 +149,8 @@ ScreenEnding::ScreenEnding( CString sClassName ) : ScreenAttract( sClassName, fa
GAMESTATE->m_pCurCourse = SONGMAN->GetRandomCourse();
GAMESTATE->m_pCurSteps[PLAYER_1].Set( GAMESTATE->m_pCurSong->GetAllSteps()[0] );
GAMESTATE->m_pCurSteps[PLAYER_2].Set( GAMESTATE->m_pCurSong->GetAllSteps()[0] );
STATSMAN->m_CurStageStats.m_player[PLAYER_1].vpSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_1] );
STATSMAN->m_CurStageStats.m_player[PLAYER_2].vpSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
STATSMAN->m_CurStageStats.m_player[PLAYER_1].vpPlayedSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_1] );
STATSMAN->m_CurStageStats.m_player[PLAYER_2].vpPlayedSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_pPlayerState[PLAYER_2]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_iCurrentStageIndex = 0;
+7 -7
View File
@@ -110,12 +110,12 @@ ScreenEvaluation::ScreenEvaluation( CString sClassName ) : ScreenWithMenuElement
GAMESTATE->m_bSideIsJoined[PLAYER_2] = true;
GAMESTATE->m_MasterPlayerNumber = PLAYER_1;
GAMESTATE->m_pCurSong.Set( SONGMAN->GetRandomSong() );
STATSMAN->m_CurStageStats.vpSongs.push_back( GAMESTATE->m_pCurSong );
STATSMAN->m_CurStageStats.vpPlayedSongs.push_back( GAMESTATE->m_pCurSong );
GAMESTATE->m_pCurCourse = SONGMAN->GetRandomCourse();
GAMESTATE->m_pCurSteps[PLAYER_1].Set( GAMESTATE->m_pCurSong->GetAllSteps()[0] );
GAMESTATE->m_pCurSteps[PLAYER_2].Set( GAMESTATE->m_pCurSong->GetAllSteps()[0] );
STATSMAN->m_CurStageStats.m_player[PLAYER_1].vpSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_1] );
STATSMAN->m_CurStageStats.m_player[PLAYER_2].vpSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
STATSMAN->m_CurStageStats.m_player[PLAYER_1].vpPlayedSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_1] );
STATSMAN->m_CurStageStats.m_player[PLAYER_2].vpPlayedSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_pPlayerState[PLAYER_2]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_iCurrentStageIndex = 0;
@@ -335,9 +335,9 @@ void ScreenEvaluation::Init()
break;
case summary:
{
for( unsigned i=0; i<stageStats.vpSongs.size(); i++ )
for( unsigned i=0; i<stageStats.vpPlayedSongs.size(); i++ )
{
Song *pSong = stageStats.vpSongs[i];
Song *pSong = stageStats.vpPlayedSongs[i];
m_SmallBanner[i].LoadFromSong( pSong );
m_SmallBanner[i].ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT );
@@ -455,7 +455,7 @@ void ScreenEvaluation::Init()
m_Graph[p].SetName( ssprintf("GraphP%i",p+1) );
m_Graph[p].Load( THEME->GetPathG(m_sName,ssprintf("graph p%i", p+1)), GRAPH_START_HEIGHT );
m_Graph[p].LoadFromStageStats( stageStats.m_player[p] );
m_Graph[p].LoadFromStageStats( stageStats, stageStats.m_player[p] );
SET_XY_AND_ON_COMMAND( m_Graph[p] );
this->AddChild( &m_Graph[p] );
}
@@ -466,7 +466,7 @@ void ScreenEvaluation::Init()
FOREACH_EnabledPlayer( p )
{
m_Combo[p].SetName( m_sName, ssprintf("ComboP%i",p+1) );
m_Combo[p].Load( m_sName, ssprintf("combo p%i",p+1), stageStats, p );
m_Combo[p].Load( m_sName, ssprintf("combo p%i",p+1), stageStats, stageStats.m_player[p] );
SET_XY_AND_ON_COMMAND( m_Combo[p] );
this->AddChild( &m_Combo[p] );
+9 -4
View File
@@ -704,7 +704,7 @@ void ScreenGameplay::InitSongQueues()
m_apSongsQueue.push_back( e->pSong );
}
FOREACH_EnabledPlayer(p)
FOREACH_EnabledPlayer(p)
{
Trail *pTrail = GAMESTATE->m_pCurTrail[p];
ASSERT( pTrail );
@@ -724,12 +724,17 @@ void ScreenGameplay::InitSongQueues()
else
{
m_apSongsQueue.push_back( GAMESTATE->m_pCurSong );
FOREACH_PlayerNumber(p)
FOREACH_PlayerNumber(p)
{
m_vpStepsQueue[p].push_back( GAMESTATE->m_pCurSteps[p] );
m_asModifiersQueue[p].push_back( AttackArray() );
}
}
// Fill StageStats
STATSMAN->m_CurStageStats.vpPossibleSongs = m_apSongsQueue;
FOREACH_PlayerNumber(p)
STATSMAN->m_CurStageStats.m_player[p].vpPossibleSteps = m_vpStepsQueue[p];
}
ScreenGameplay::~ScreenGameplay()
@@ -864,7 +869,7 @@ void ScreenGameplay::LoadNextSong()
int iPlaySongIndex = GAMESTATE->GetCourseSongIndex();
iPlaySongIndex %= m_apSongsQueue.size();
GAMESTATE->m_pCurSong.Set( m_apSongsQueue[iPlaySongIndex] );
STATSMAN->m_CurStageStats.vpSongs.push_back( GAMESTATE->m_pCurSong );
STATSMAN->m_CurStageStats.vpPlayedSongs.push_back( GAMESTATE->m_pCurSong );
// No need to do this here. We do it in SongFinished().
//GAMESTATE->RemoveAllActiveAttacks();
@@ -885,7 +890,7 @@ void ScreenGameplay::LoadNextSong()
{
Song* pSong = GAMESTATE->m_pCurSong;
Steps* pSteps = GAMESTATE->m_pCurSteps[p];
STATSMAN->m_CurStageStats.m_player[p].vpSteps.push_back( pSteps );
STATSMAN->m_CurStageStats.m_player[p].vpPlayedSteps.push_back( pSteps );
ASSERT( GAMESTATE->m_pCurSteps[p] );
m_textStepsDescription[p].SetText( GAMESTATE->m_pCurSteps[p]->GetDescription() );
+2 -2
View File
@@ -346,7 +346,7 @@ void ScreenGameplayMultiplayer::LoadNextSong()
int iPlaySongIndex = GAMESTATE->GetCourseSongIndex();
iPlaySongIndex %= m_vpSongsQueue.size();
GAMESTATE->m_pCurSong.Set( m_vpSongsQueue[iPlaySongIndex] );
STATSMAN->m_CurStageStats.vpSongs.push_back( GAMESTATE->m_pCurSong );
STATSMAN->m_CurStageStats.vpPlayedSongs.push_back( GAMESTATE->m_pCurSong );
// No need to do this here. We do it in SongFinished().
//GAMESTATE->RemoveAllActiveAttacks();
@@ -361,7 +361,7 @@ void ScreenGameplayMultiplayer::LoadNextSong()
Steps* pSteps = GAMESTATE->m_pCurSteps[GAMESTATE->m_MasterPlayerNumber];
STATSMAN->m_CurStageStats.m_player[GAMESTATE->m_MasterPlayerNumber].vpSteps.push_back( pSteps );
STATSMAN->m_CurStageStats.m_player[GAMESTATE->m_MasterPlayerNumber].vpPlayedSteps.push_back( pSteps );
FOREACH_MultiPlayer( p )
{
+11 -11
View File
@@ -136,18 +136,18 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
StageStats ss;
for( int z = 0; z < 3; ++z )
{
ss.vpSongs.push_back( SONGMAN->GetRandomSong() );
ss.vpPlayedSongs.push_back( SONGMAN->GetRandomSong() );
ss.m_player[PLAYER_1].iPossibleDancePoints = 100;
ss.m_player[PLAYER_1].iActualDancePoints = 100;
ss.m_player[PLAYER_1].iScore = 100;
ss.m_player[PLAYER_2].iPossibleDancePoints = 100;
ss.m_player[PLAYER_2].iActualDancePoints = 100;
ss.m_player[PLAYER_2].iScore = 100;
ASSERT( ss.vpSongs[0]->GetAllSteps().size() );
ASSERT( ss.vpPlayedSongs[0]->GetAllSteps().size() );
FOREACH_PlayerNumber( p )
{
ss.m_player[p].vpSteps.push_back( ss.vpSongs[0]->GetAllSteps()[0] );
GAMESTATE->m_pCurSteps[p].Set( ss.m_player[p].vpSteps[0] );
ss.m_player[p].vpPlayedSteps.push_back( ss.vpPlayedSongs[0]->GetAllSteps()[0] );
GAMESTATE->m_pCurSteps[p].Set( ss.m_player[p].vpPlayedSteps[0] );
ss.m_player[p].iPossibleDancePoints = 1000;
ss.m_player[p].iActualDancePoints = 985;
@@ -157,11 +157,11 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
hs.iScore = ss.m_player[p].iScore;
StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
int a, b;
PROFILEMAN->AddStepsScore( ss.vpSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
PROFILEMAN->AddStepsScore( ss.vpSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
PROFILEMAN->AddStepsScore( ss.vpSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
PROFILEMAN->AddStepsScore( ss.vpSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
PROFILEMAN->AddStepsScore( ss.vpSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
PROFILEMAN->AddStepsScore( ss.vpPlayedSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
PROFILEMAN->AddStepsScore( ss.vpPlayedSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
PROFILEMAN->AddStepsScore( ss.vpPlayedSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
PROFILEMAN->AddStepsScore( ss.vpPlayedSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
PROFILEMAN->AddStepsScore( ss.vpPlayedSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
PROFILEMAN->AddCategoryScore( st, RANKING_A, p, hs, a, b );
}
@@ -318,8 +318,8 @@ void ScreenNameEntryTraditional::Init()
for( unsigned i = 0; i < STATSMAN->m_vPlayedStageStats.size(); ++i )
{
StageStats &ss = STATSMAN->m_vPlayedStageStats[i];
Song* pSong = ss.vpSongs[0];
Steps* pSteps = ss.m_player[p].vpSteps[0];
Song* pSong = ss.vpPlayedSongs[0];
Steps* pSteps = ss.m_player[p].vpPlayedSteps[0];
Course* pCourse = GAMESTATE->m_pCurCourse;
Trail* pTrail = GAMESTATE->m_pCurTrail[p];
+1 -1
View File
@@ -1152,7 +1152,7 @@ void ScreenSelectMusic::MenuStart( PlayerNumber pn )
if( GAMESTATE->IsEventMode() )
i = max( 0, int(STATSMAN->m_vPlayedStageStats.size())-5 );
for( ; i < (int)STATSMAN->m_vPlayedStageStats.size(); ++i )
if( STATSMAN->m_vPlayedStageStats[i].vpSongs.back() == m_MusicWheel.GetSelectedSong() )
if( STATSMAN->m_vPlayedStageStats[i].vpPlayedSongs.back() == m_MusicWheel.GetSelectedSong() )
bIsRepeat = true;
/* Don't complain about repeats if the user didn't get to pick. */
+2 -2
View File
@@ -812,11 +812,11 @@ void SongManager::RevertFromDisk( Song *pSong, bool bAllowNotesLoss )
{
CONVERT_STEPS_POINTER( GAMESTATE->m_pCurSteps[p], mapOldStepsToStepsID, pSong, bAllowNotesLoss );
FOREACH( Steps*, STATSMAN->m_CurStageStats.m_player[p].vpSteps, pSteps )
FOREACH( Steps*, STATSMAN->m_CurStageStats.m_player[p].vpPlayedSteps, pSteps )
CONVERT_STEPS_POINTER( *pSteps, mapOldStepsToStepsID, pSong, bAllowNotesLoss );
FOREACH( StageStats, STATSMAN->m_vPlayedStageStats, ss )
FOREACH( Steps*, ss->m_player[p].vpSteps, pSteps )
FOREACH( Steps*, ss->m_player[p].vpPlayedSteps, pSteps )
CONVERT_STEPS_POINTER( *pSteps, mapOldStepsToStepsID, pSong, bAllowNotesLoss );
}
+35 -20
View File
@@ -9,7 +9,8 @@ StageStats::StageStats()
{
playMode = PLAY_MODE_INVALID;
pStyle = NULL;
vpSongs.clear();
vpPlayedSongs.clear();
vpPossibleSongs.clear();
StageType = STAGE_INVALID;
fGameplaySeconds = 0;
}
@@ -21,50 +22,55 @@ void StageStats::Init()
void StageStats::AssertValid( PlayerNumber pn ) const
{
ASSERT( vpSongs.size() != 0 );
if( vpSongs[0] )
CHECKPOINT_M( vpSongs[0]->GetFullTranslitTitle() );
ASSERT( m_player[pn].vpSteps.size() != 0 );
ASSERT( m_player[pn].vpSteps[0] );
ASSERT( vpPlayedSongs.size() != 0 );
ASSERT( vpPossibleSongs.size() != 0 );
if( vpPlayedSongs[0] )
CHECKPOINT_M( vpPlayedSongs[0]->GetFullTranslitTitle() );
ASSERT( m_player[pn].vpPlayedSteps.size() != 0 );
ASSERT( m_player[pn].vpPlayedSteps[0] );
ASSERT_M( playMode < NUM_PLAY_MODES, ssprintf("playmode %i", playMode) );
ASSERT( pStyle != NULL );
ASSERT_M( m_player[pn].vpSteps[0]->GetDifficulty() < NUM_DIFFICULTIES, ssprintf("difficulty %i", m_player[pn].vpSteps[0]->GetDifficulty()) );
ASSERT( vpSongs.size() == m_player[pn].vpSteps.size() );
ASSERT_M( m_player[pn].vpPlayedSteps[0]->GetDifficulty() < NUM_DIFFICULTIES, ssprintf("difficulty %i", m_player[pn].vpPlayedSteps[0]->GetDifficulty()) );
ASSERT( vpPlayedSongs.size() == m_player[pn].vpPlayedSteps.size() );
ASSERT( vpPossibleSongs.size() == m_player[pn].vpPossibleSteps.size() );
}
int StageStats::GetAverageMeter( PlayerNumber pn ) const
{
int iTotalMeter = 0;
ASSERT( vpSongs.size() == m_player[pn].vpSteps.size() );
AssertValid( pn );
for( unsigned i=0; i<vpSongs.size(); i++ )
// TODO: This isn't correct for courses.
int iTotalMeter = 0;
for( unsigned i=0; i<vpPlayedSongs.size(); i++ )
{
const Steps* pSteps = m_player[pn].vpSteps[i];
const Steps* pSteps = m_player[pn].vpPlayedSteps[i];
iTotalMeter += pSteps->GetMeter();
}
return iTotalMeter / vpSongs.size(); // round down
return iTotalMeter / vpPlayedSongs.size(); // round down
}
void StageStats::AddStats( const StageStats& other )
{
ASSERT( !other.vpSongs.empty() );
FOREACH_CONST( Song*, other.vpSongs, s )
vpSongs.push_back( *s );
ASSERT( !other.vpPlayedSongs.empty() );
FOREACH_CONST( Song*, other.vpPlayedSongs, s )
vpPlayedSongs.push_back( *s );
FOREACH_CONST( Song*, other.vpPossibleSongs, s )
vpPossibleSongs.push_back( *s );
StageType = STAGE_INVALID; // meaningless
fGameplaySeconds += other.fGameplaySeconds;
FOREACH_PlayerNumber( p )
{
m_player[p].AddStats( other.m_player[p] );
}
}
bool StageStats::OnePassed() const
{
FOREACH_PlayerNumber( p )
if( GAMESTATE->IsHumanPlayer(p) && !m_player[p].bFailed )
FOREACH_HumanPlayer( p )
if( !m_player[p].bFailed )
return true;
return false;
}
@@ -85,6 +91,15 @@ bool StageStats::AllFailedEarlier() const
return true;
}
float StageStats::GetTotalPossibleMusicLengthSeconds() const
{
float fSecs = 0;
FOREACH_CONST( Song*, vpPossibleSongs, s )
fSecs += (*s)->m_fMusicLengthSeconds;
return fSecs;
}
// lua start
#include "LuaBinding.h"
+4 -1
View File
@@ -27,10 +27,13 @@ struct StageStats
PlayMode playMode;
const Style* pStyle;
vector<Song*> vpSongs;
vector<Song*> vpPlayedSongs;
vector<Song*> vpPossibleSongs;
enum { STAGE_INVALID, STAGE_NORMAL, STAGE_EXTRA, STAGE_EXTRA2 } StageType;
float fGameplaySeconds; // how many seconds before gameplay ended. Updated by Gameplay, not scaled by music rate.
float GetTotalPossibleMusicLengthSeconds() const; // TODO: Scale this by the music rate
PlayerStageStats m_player[NUM_PLAYERS];
// Lua
+6 -6
View File
@@ -20,7 +20,7 @@ StageStats AccumStageStats( const vector<StageStats>& vss )
FOREACH_CONST( StageStats, vss, ss )
ssreturn.AddStats( *ss );
unsigned uNumSongs = ssreturn.vpSongs.size();
unsigned uNumSongs = ssreturn.vpPlayedSongs.size();
if( uNumSongs == 0 ) return ssreturn; // don't divide by 0 below
@@ -84,10 +84,10 @@ void AddPlayerStatsToProfile( Profile *pProfile, const StageStats &ss, PlayerNum
StyleID sID;
sID.FromStyle( ss.pStyle );
ASSERT( ss.vpSongs.size() == ss.m_player[pn].vpSteps.size() );
for( unsigned i=0; i<ss.vpSongs.size(); i++ )
ASSERT( ss.vpPlayedSongs.size() == ss.m_player[pn].vpPlayedSteps.size() );
for( unsigned i=0; i<ss.vpPlayedSongs.size(); i++ )
{
Steps *pSteps = ss.m_player[pn].vpSteps[i];
Steps *pSteps = ss.m_player[pn].vpPlayedSteps[i];
pProfile->m_iNumSongsPlayedByPlayMode[ss.playMode]++;
pProfile->m_iNumSongsPlayedByStyle[sID] ++;
@@ -142,7 +142,7 @@ void StatsManager::CommitStatsToProfiles()
pMachineProfile->m_iTotalGameplaySeconds += iGameplaySeconds;
pMachineProfile->m_iCurrentCombo = 0;
pMachineProfile->m_iNumTotalSongsPlayed += m_CurStageStats.vpSongs.size();
pMachineProfile->m_iNumTotalSongsPlayed += m_CurStageStats.vpPlayedSongs.size();
CHECKPOINT;
FOREACH_HumanPlayer( pn )
@@ -157,7 +157,7 @@ void StatsManager::CommitStatsToProfiles()
PREFSMAN->m_bComboContinuesBetweenSongs ?
m_CurStageStats.m_player[pn].iCurCombo :
0;
pPlayerProfile->m_iNumTotalSongsPlayed += m_CurStageStats.vpSongs.size();
pPlayerProfile->m_iNumTotalSongsPlayed += m_CurStageStats.vpPlayedSongs.size();
}
AddPlayerStatsToProfile( pMachineProfile, m_CurStageStats, pn );