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"); 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 ); ASSERT( m_SubActors.size() == 0 );
const float fFirstSecond = 0;
const float fLastSecond = s.GetTotalPossibleMusicLengthSeconds();
/* Find the largest combo. */ /* Find the largest combo. */
int MaxComboSize = 0; int MaxComboSize = 0;
for( unsigned i = 0; i < s.m_player[pn].ComboList.size(); ++i ) for( unsigned i = 0; i < pss.ComboList.size(); ++i )
MaxComboSize = max( MaxComboSize, s.m_player[pn].ComboList[i].GetStageCnt() ); MaxComboSize = max( MaxComboSize, pss.ComboList[i].GetStageCnt() );
float width = -1; 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 ) if( combo.GetStageCnt() < MinComboSizeToShow )
continue; /* too small */ continue; /* too small */
@@ -35,8 +38,8 @@ void ComboGraph::Load( const CString& sScreen, const CString& sElement, const St
sprite->SetName( "ComboBar" ); sprite->SetName( "ComboBar" );
sprite->Load( THEME->GetPathG( sScreen, sElement + (IsMax? " max":" normal") ) ); 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 start = SCALE( combo.fStartSecond, fFirstSecond, 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 size = SCALE( combo.fSizeSeconds, 0, fLastSecond-fFirstSecond, 0.0f, 1.0f );
sprite->SetCropLeft ( SCALE( size, 0.0f, 1.0f, 0.5f, 0.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 ) ); 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 ); 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 ) if( combo.GetStageCnt() < MinComboSizeToShow )
continue; /* too small */ continue; /* too small */
@@ -68,8 +71,8 @@ void ComboGraph::Load( const CString& sScreen, const CString& sElement, const St
text->SetName( "ComboMaxNumber" ); text->SetName( "ComboMaxNumber" );
text->LoadFromFont( THEME->GetPathF(sScreen,sElement) ); 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 start = SCALE( combo.fStartSecond, fFirstSecond, 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 size = SCALE( combo.fSizeSeconds, 0, fLastSecond-fFirstSecond, 0.0f, 1.0f );
const float CenterPercent = start + size/2; const float CenterPercent = start + size/2;
const float CenterXPos = SCALE( CenterPercent, 0.0f, 1.0f, -width/2.0f, width/2.0f ); 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" #include "PlayerNumber.h"
struct StageStats; struct StageStats;
struct PlayerStageStats;
class ComboGraph: public ActorFrame class ComboGraph: public ActorFrame
{ {
public: public:
~ComboGraph() { Unload(); } ~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 Unload();
void TweenOffScreen(); 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() ) ); CHECKPOINT_M( ssprintf("%u/%i", i, (int)STATSMAN->m_vPlayedStageStats.size() ) );
SongAndSteps sas; SongAndSteps sas;
sas.pSong = STATSMAN->m_vPlayedStageStats[i].vpSongs[0]; sas.pSong = STATSMAN->m_vPlayedStageStats[i].vpPlayedSongs[0];
ASSERT( sas.pSong ); 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 ); ASSERT( sas.pSteps );
vSongAndSteps.push_back( sas ); vSongAndSteps.push_back( sas );
} }
+2 -2
View File
@@ -39,11 +39,11 @@ void GraphDisplay::Unload()
m_pTexture = NULL; 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) ); memcpy( m_LastValues, m_CurValues, sizeof(m_CurValues) );
m_Position = 0; 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++ ) for( unsigned i=0; i<ARRAYSIZE(m_DestValues); i++ )
CLAMP( m_DestValues[i], 0.f, 1.f ); CLAMP( m_DestValues[i], 0.f, 1.f );
UpdateVerts(); UpdateVerts();
+3 -2
View File
@@ -4,6 +4,7 @@
#include "ActorFrame.h" #include "ActorFrame.h"
#include "RageTexture.h" #include "RageTexture.h"
struct StageStats;
struct PlayerStageStats; struct PlayerStageStats;
class GraphDisplay: public ActorFrame class GraphDisplay: public ActorFrame
@@ -14,14 +15,14 @@ public:
void Load( const CString &TexturePath, float height ); void Load( const CString &TexturePath, float height );
void Unload(); void Unload();
void LoadFromStageStats( const PlayerStageStats &s ); void LoadFromStageStats( const StageStats &ss, const PlayerStageStats &s );
void Update( float fDeltaTime ); void Update( float fDeltaTime );
void DrawPrimitives(); void DrawPrimitives();
private: private:
void UpdateVerts(); void UpdateVerts();
enum { VALUE_RESOLUTION=100 }; enum { VALUE_RESOLUTION=200 };
float m_CurValues[VALUE_RESOLUTION]; float m_CurValues[VALUE_RESOLUTION];
float m_DestValues[VALUE_RESOLUTION]; float m_DestValues[VALUE_RESOLUTION];
float m_LastValues[VALUE_RESOLUTION]; float m_LastValues[VALUE_RESOLUTION];
+12 -6
View File
@@ -15,7 +15,8 @@
void PlayerStageStats::Init() void PlayerStageStats::Init()
{ {
vpSteps.clear(); vpPlayedSteps.clear();
vpPossibleSteps.clear();
fAliveSeconds = 0; fAliveSeconds = 0;
bFailed = bFailedEarlier = false; bFailed = bFailedEarlier = false;
iPossibleDancePoints = iCurPossibleDancePoints = iActualDancePoints = 0; iPossibleDancePoints = iCurPossibleDancePoints = iActualDancePoints = 0;
@@ -35,8 +36,10 @@ void PlayerStageStats::Init()
void PlayerStageStats::AddStats( const PlayerStageStats& other ) void PlayerStageStats::AddStats( const PlayerStageStats& other )
{ {
FOREACH_CONST( Steps*, other.vpSteps, s ) FOREACH_CONST( Steps*, other.vpPlayedSteps, s )
vpSteps.push_back( *s ); vpPlayedSteps.push_back( *s );
FOREACH_CONST( Steps*, other.vpPossibleSteps, s )
vpPossibleSteps.push_back( *s );
fAliveSeconds += other.fAliveSeconds; fAliveSeconds += other.fAliveSeconds;
bFailed |= other.bFailed; bFailed |= other.bFailed;
bFailedEarlier |= other.bFailedEarlier; bFailedEarlier |= other.bFailedEarlier;
@@ -292,7 +295,10 @@ float PlayerStageStats::GetLifeRecordLerpAt( float fSecond ) const
if( earlier != fLifeRecord.begin() ) if( earlier != fLifeRecord.begin() )
--earlier; --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; return earlier->second;
/* earlier <= pos <= later */ /* 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 ) 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 ); fLifeOut[i] = GetLifeRecordLerpAt( from );
} }
} }
+3 -2
View File
@@ -22,7 +22,8 @@ struct PlayerStageStats
float GetPercentDancePoints() const; float GetPercentDancePoints() const;
float GetCurMaxPercentDancePoints() 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. 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 /* 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; map<float,float> fLifeRecord;
void SetLifeRecordAt( float fLife, float fSecond ); 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 GetLifeRecordAt( float fSecond ) const;
float GetLifeRecordLerpAt( 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_pCurCourse = SONGMAN->GetRandomCourse();
GAMESTATE->m_pCurSteps[PLAYER_1].Set( GAMESTATE->m_pCurSong->GetAllSteps()[0] ); GAMESTATE->m_pCurSteps[PLAYER_1].Set( GAMESTATE->m_pCurSong->GetAllSteps()[0] );
GAMESTATE->m_pCurSteps[PLAYER_2].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_1].vpPlayedSteps.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_2].vpPlayedSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.m_fScrollSpeed = 2; GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_pPlayerState[PLAYER_2]->m_PlayerOptions.m_fScrollSpeed = 2; GAMESTATE->m_pPlayerState[PLAYER_2]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_iCurrentStageIndex = 0; 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_bSideIsJoined[PLAYER_2] = true;
GAMESTATE->m_MasterPlayerNumber = PLAYER_1; GAMESTATE->m_MasterPlayerNumber = PLAYER_1;
GAMESTATE->m_pCurSong.Set( SONGMAN->GetRandomSong() ); 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_pCurCourse = SONGMAN->GetRandomCourse();
GAMESTATE->m_pCurSteps[PLAYER_1].Set( GAMESTATE->m_pCurSong->GetAllSteps()[0] ); GAMESTATE->m_pCurSteps[PLAYER_1].Set( GAMESTATE->m_pCurSong->GetAllSteps()[0] );
GAMESTATE->m_pCurSteps[PLAYER_2].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_1].vpPlayedSteps.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_2].vpPlayedSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.m_fScrollSpeed = 2; GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_pPlayerState[PLAYER_2]->m_PlayerOptions.m_fScrollSpeed = 2; GAMESTATE->m_pPlayerState[PLAYER_2]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_iCurrentStageIndex = 0; GAMESTATE->m_iCurrentStageIndex = 0;
@@ -335,9 +335,9 @@ void ScreenEvaluation::Init()
break; break;
case summary: 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].LoadFromSong( pSong );
m_SmallBanner[i].ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT ); 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].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].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] ); SET_XY_AND_ON_COMMAND( m_Graph[p] );
this->AddChild( &m_Graph[p] ); this->AddChild( &m_Graph[p] );
} }
@@ -466,7 +466,7 @@ void ScreenEvaluation::Init()
FOREACH_EnabledPlayer( p ) FOREACH_EnabledPlayer( p )
{ {
m_Combo[p].SetName( m_sName, ssprintf("ComboP%i",p+1) ); 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] ); SET_XY_AND_ON_COMMAND( m_Combo[p] );
this->AddChild( &m_Combo[p] ); this->AddChild( &m_Combo[p] );
+7 -2
View File
@@ -730,6 +730,11 @@ void ScreenGameplay::InitSongQueues()
m_asModifiersQueue[p].push_back( AttackArray() ); 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() ScreenGameplay::~ScreenGameplay()
@@ -864,7 +869,7 @@ void ScreenGameplay::LoadNextSong()
int iPlaySongIndex = GAMESTATE->GetCourseSongIndex(); int iPlaySongIndex = GAMESTATE->GetCourseSongIndex();
iPlaySongIndex %= m_apSongsQueue.size(); iPlaySongIndex %= m_apSongsQueue.size();
GAMESTATE->m_pCurSong.Set( m_apSongsQueue[iPlaySongIndex] ); 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(). // No need to do this here. We do it in SongFinished().
//GAMESTATE->RemoveAllActiveAttacks(); //GAMESTATE->RemoveAllActiveAttacks();
@@ -885,7 +890,7 @@ void ScreenGameplay::LoadNextSong()
{ {
Song* pSong = GAMESTATE->m_pCurSong; Song* pSong = GAMESTATE->m_pCurSong;
Steps* pSteps = GAMESTATE->m_pCurSteps[p]; 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] ); ASSERT( GAMESTATE->m_pCurSteps[p] );
m_textStepsDescription[p].SetText( GAMESTATE->m_pCurSteps[p]->GetDescription() ); m_textStepsDescription[p].SetText( GAMESTATE->m_pCurSteps[p]->GetDescription() );
+2 -2
View File
@@ -346,7 +346,7 @@ void ScreenGameplayMultiplayer::LoadNextSong()
int iPlaySongIndex = GAMESTATE->GetCourseSongIndex(); int iPlaySongIndex = GAMESTATE->GetCourseSongIndex();
iPlaySongIndex %= m_vpSongsQueue.size(); iPlaySongIndex %= m_vpSongsQueue.size();
GAMESTATE->m_pCurSong.Set( m_vpSongsQueue[iPlaySongIndex] ); 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(). // No need to do this here. We do it in SongFinished().
//GAMESTATE->RemoveAllActiveAttacks(); //GAMESTATE->RemoveAllActiveAttacks();
@@ -361,7 +361,7 @@ void ScreenGameplayMultiplayer::LoadNextSong()
Steps* pSteps = GAMESTATE->m_pCurSteps[GAMESTATE->m_MasterPlayerNumber]; 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 ) FOREACH_MultiPlayer( p )
{ {
+11 -11
View File
@@ -136,18 +136,18 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
StageStats ss; StageStats ss;
for( int z = 0; z < 3; ++z ) 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].iPossibleDancePoints = 100;
ss.m_player[PLAYER_1].iActualDancePoints = 100; ss.m_player[PLAYER_1].iActualDancePoints = 100;
ss.m_player[PLAYER_1].iScore = 100; ss.m_player[PLAYER_1].iScore = 100;
ss.m_player[PLAYER_2].iPossibleDancePoints = 100; ss.m_player[PLAYER_2].iPossibleDancePoints = 100;
ss.m_player[PLAYER_2].iActualDancePoints = 100; ss.m_player[PLAYER_2].iActualDancePoints = 100;
ss.m_player[PLAYER_2].iScore = 100; ss.m_player[PLAYER_2].iScore = 100;
ASSERT( ss.vpSongs[0]->GetAllSteps().size() ); ASSERT( ss.vpPlayedSongs[0]->GetAllSteps().size() );
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
{ {
ss.m_player[p].vpSteps.push_back( ss.vpSongs[0]->GetAllSteps()[0] ); ss.m_player[p].vpPlayedSteps.push_back( ss.vpPlayedSongs[0]->GetAllSteps()[0] );
GAMESTATE->m_pCurSteps[p].Set( ss.m_player[p].vpSteps[0] ); GAMESTATE->m_pCurSteps[p].Set( ss.m_player[p].vpPlayedSteps[0] );
ss.m_player[p].iPossibleDancePoints = 1000; ss.m_player[p].iPossibleDancePoints = 1000;
ss.m_player[p].iActualDancePoints = 985; ss.m_player[p].iActualDancePoints = 985;
@@ -157,11 +157,11 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
hs.iScore = ss.m_player[p].iScore; hs.iScore = ss.m_player[p].iScore;
StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
int a, b; int 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.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.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.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.vpSongs[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 ); 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 ) for( unsigned i = 0; i < STATSMAN->m_vPlayedStageStats.size(); ++i )
{ {
StageStats &ss = STATSMAN->m_vPlayedStageStats[i]; StageStats &ss = STATSMAN->m_vPlayedStageStats[i];
Song* pSong = ss.vpSongs[0]; Song* pSong = ss.vpPlayedSongs[0];
Steps* pSteps = ss.m_player[p].vpSteps[0]; Steps* pSteps = ss.m_player[p].vpPlayedSteps[0];
Course* pCourse = GAMESTATE->m_pCurCourse; Course* pCourse = GAMESTATE->m_pCurCourse;
Trail* pTrail = GAMESTATE->m_pCurTrail[p]; Trail* pTrail = GAMESTATE->m_pCurTrail[p];
+1 -1
View File
@@ -1152,7 +1152,7 @@ void ScreenSelectMusic::MenuStart( PlayerNumber pn )
if( GAMESTATE->IsEventMode() ) if( GAMESTATE->IsEventMode() )
i = max( 0, int(STATSMAN->m_vPlayedStageStats.size())-5 ); i = max( 0, int(STATSMAN->m_vPlayedStageStats.size())-5 );
for( ; i < (int)STATSMAN->m_vPlayedStageStats.size(); ++i ) 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; bIsRepeat = true;
/* Don't complain about repeats if the user didn't get to pick. */ /* 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 ); 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 ); CONVERT_STEPS_POINTER( *pSteps, mapOldStepsToStepsID, pSong, bAllowNotesLoss );
FOREACH( StageStats, STATSMAN->m_vPlayedStageStats, ss ) 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 ); CONVERT_STEPS_POINTER( *pSteps, mapOldStepsToStepsID, pSong, bAllowNotesLoss );
} }
+35 -20
View File
@@ -9,7 +9,8 @@ StageStats::StageStats()
{ {
playMode = PLAY_MODE_INVALID; playMode = PLAY_MODE_INVALID;
pStyle = NULL; pStyle = NULL;
vpSongs.clear(); vpPlayedSongs.clear();
vpPossibleSongs.clear();
StageType = STAGE_INVALID; StageType = STAGE_INVALID;
fGameplaySeconds = 0; fGameplaySeconds = 0;
} }
@@ -21,50 +22,55 @@ void StageStats::Init()
void StageStats::AssertValid( PlayerNumber pn ) const void StageStats::AssertValid( PlayerNumber pn ) const
{ {
ASSERT( vpSongs.size() != 0 ); ASSERT( vpPlayedSongs.size() != 0 );
if( vpSongs[0] ) ASSERT( vpPossibleSongs.size() != 0 );
CHECKPOINT_M( vpSongs[0]->GetFullTranslitTitle() ); if( vpPlayedSongs[0] )
ASSERT( m_player[pn].vpSteps.size() != 0 ); CHECKPOINT_M( vpPlayedSongs[0]->GetFullTranslitTitle() );
ASSERT( m_player[pn].vpSteps[0] ); ASSERT( m_player[pn].vpPlayedSteps.size() != 0 );
ASSERT( m_player[pn].vpPlayedSteps[0] );
ASSERT_M( playMode < NUM_PLAY_MODES, ssprintf("playmode %i", playMode) ); ASSERT_M( playMode < NUM_PLAY_MODES, ssprintf("playmode %i", playMode) );
ASSERT( pStyle != NULL ); ASSERT( pStyle != NULL );
ASSERT_M( m_player[pn].vpSteps[0]->GetDifficulty() < NUM_DIFFICULTIES, ssprintf("difficulty %i", m_player[pn].vpSteps[0]->GetDifficulty()) ); ASSERT_M( m_player[pn].vpPlayedSteps[0]->GetDifficulty() < NUM_DIFFICULTIES, ssprintf("difficulty %i", m_player[pn].vpPlayedSteps[0]->GetDifficulty()) );
ASSERT( vpSongs.size() == m_player[pn].vpSteps.size() ); ASSERT( vpPlayedSongs.size() == m_player[pn].vpPlayedSteps.size() );
ASSERT( vpPossibleSongs.size() == m_player[pn].vpPossibleSteps.size() );
} }
int StageStats::GetAverageMeter( PlayerNumber pn ) const int StageStats::GetAverageMeter( PlayerNumber pn ) const
{ {
int iTotalMeter = 0; AssertValid( pn );
ASSERT( vpSongs.size() == m_player[pn].vpSteps.size() );
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(); iTotalMeter += pSteps->GetMeter();
} }
return iTotalMeter / vpSongs.size(); // round down return iTotalMeter / vpPlayedSongs.size(); // round down
} }
void StageStats::AddStats( const StageStats& other ) void StageStats::AddStats( const StageStats& other )
{ {
ASSERT( !other.vpSongs.empty() ); ASSERT( !other.vpPlayedSongs.empty() );
FOREACH_CONST( Song*, other.vpSongs, s ) FOREACH_CONST( Song*, other.vpPlayedSongs, s )
vpSongs.push_back( *s ); vpPlayedSongs.push_back( *s );
FOREACH_CONST( Song*, other.vpPossibleSongs, s )
vpPossibleSongs.push_back( *s );
StageType = STAGE_INVALID; // meaningless StageType = STAGE_INVALID; // meaningless
fGameplaySeconds += other.fGameplaySeconds; fGameplaySeconds += other.fGameplaySeconds;
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
{
m_player[p].AddStats( other.m_player[p] ); m_player[p].AddStats( other.m_player[p] );
}
} }
bool StageStats::OnePassed() const bool StageStats::OnePassed() const
{ {
FOREACH_PlayerNumber( p ) FOREACH_HumanPlayer( p )
if( GAMESTATE->IsHumanPlayer(p) && !m_player[p].bFailed ) if( !m_player[p].bFailed )
return true; return true;
return false; return false;
} }
@@ -85,6 +91,15 @@ bool StageStats::AllFailedEarlier() const
return true; return true;
} }
float StageStats::GetTotalPossibleMusicLengthSeconds() const
{
float fSecs = 0;
FOREACH_CONST( Song*, vpPossibleSongs, s )
fSecs += (*s)->m_fMusicLengthSeconds;
return fSecs;
}
// lua start // lua start
#include "LuaBinding.h" #include "LuaBinding.h"
+4 -1
View File
@@ -27,10 +27,13 @@ struct StageStats
PlayMode playMode; PlayMode playMode;
const Style* pStyle; const Style* pStyle;
vector<Song*> vpSongs; vector<Song*> vpPlayedSongs;
vector<Song*> vpPossibleSongs;
enum { STAGE_INVALID, STAGE_NORMAL, STAGE_EXTRA, STAGE_EXTRA2 } StageType; 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 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]; PlayerStageStats m_player[NUM_PLAYERS];
// Lua // Lua
+6 -6
View File
@@ -20,7 +20,7 @@ StageStats AccumStageStats( const vector<StageStats>& vss )
FOREACH_CONST( StageStats, vss, ss ) FOREACH_CONST( StageStats, vss, ss )
ssreturn.AddStats( *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 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; StyleID sID;
sID.FromStyle( ss.pStyle ); sID.FromStyle( ss.pStyle );
ASSERT( ss.vpSongs.size() == ss.m_player[pn].vpSteps.size() ); ASSERT( ss.vpPlayedSongs.size() == ss.m_player[pn].vpPlayedSteps.size() );
for( unsigned i=0; i<ss.vpSongs.size(); i++ ) 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_iNumSongsPlayedByPlayMode[ss.playMode]++;
pProfile->m_iNumSongsPlayedByStyle[sID] ++; pProfile->m_iNumSongsPlayedByStyle[sID] ++;
@@ -142,7 +142,7 @@ void StatsManager::CommitStatsToProfiles()
pMachineProfile->m_iTotalGameplaySeconds += iGameplaySeconds; pMachineProfile->m_iTotalGameplaySeconds += iGameplaySeconds;
pMachineProfile->m_iCurrentCombo = 0; pMachineProfile->m_iCurrentCombo = 0;
pMachineProfile->m_iNumTotalSongsPlayed += m_CurStageStats.vpSongs.size(); pMachineProfile->m_iNumTotalSongsPlayed += m_CurStageStats.vpPlayedSongs.size();
CHECKPOINT; CHECKPOINT;
FOREACH_HumanPlayer( pn ) FOREACH_HumanPlayer( pn )
@@ -157,7 +157,7 @@ void StatsManager::CommitStatsToProfiles()
PREFSMAN->m_bComboContinuesBetweenSongs ? PREFSMAN->m_bComboContinuesBetweenSongs ?
m_CurStageStats.m_player[pn].iCurCombo : m_CurStageStats.m_player[pn].iCurCombo :
0; 0;
pPlayerProfile->m_iNumTotalSongsPlayed += m_CurStageStats.vpSongs.size(); pPlayerProfile->m_iNumTotalSongsPlayed += m_CurStageStats.vpPlayedSongs.size();
} }
AddPlayerStatsToProfile( pMachineProfile, m_CurStageStats, pn ); AddPlayerStatsToProfile( pMachineProfile, m_CurStageStats, pn );