From 69600d9d80d96da9bbe51551b79425c6d9c61a79 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sun, 22 Feb 2004 06:04:01 +0000 Subject: [PATCH] save per-difficulty course scores --- stepmania/src/GameState.cpp | 5 +- stepmania/src/PaneDisplay.cpp | 7 +-- stepmania/src/Profile.cpp | 78 ++++++++++++++++++---------- stepmania/src/Profile.h | 10 ++-- stepmania/src/ProfileManager.cpp | 12 ++--- stepmania/src/ProfileManager.h | 4 +- stepmania/src/ScreenEvaluation.cpp | 3 +- stepmania/src/ScreenGameplay.cpp | 2 +- stepmania/src/ScreenRanking.cpp | 12 ++--- stepmania/src/ScreenRanking.h | 1 + stepmania/src/ScreenSelectCourse.cpp | 5 +- 11 files changed, 84 insertions(+), 55 deletions(-) diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index 986659212d..099e3a762f 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -1249,11 +1249,12 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector &asFeatsO StepsType nt = this->GetCurrentStyleDef()->m_StepsType; Course* pCourse = this->m_pCurCourse; ASSERT( pCourse ); + CourseDifficulty cd = this->m_CourseDifficulty[pn]; // Find Machine Records { Profile* pProfile = PROFILEMAN->GetMachineProfile(); - HighScoreList &hsl = pProfile->GetCourseHighScoreList( pCourse, nt ); + HighScoreList &hsl = pProfile->GetCourseHighScoreList( pCourse, nt, cd ); for( unsigned i=0; i &asFeatsO // Find Personal Records if( PROFILEMAN->IsUsingProfile( pn ) ) { - HighScoreList &hsl = pProf->GetCourseHighScoreList( pCourse, nt ); + HighScoreList &hsl = pProf->GetCourseHighScoreList( pCourse, nt, cd ); for( unsigned i=0; im_pCurNotes[m_PlayerNumber]; StepsType st = GAMESTATE->GetCurrentStyleDef()->m_StepsType; const Course *pCourse = GAMESTATE->m_pCurCourse; + const CourseDifficulty cd = GAMESTATE->m_CourseDifficulty[m_PlayerNumber]; float val = 0; CString str; @@ -225,7 +226,7 @@ void PaneDisplay::SetContent( PaneContents c ) case COURSE_MACHINE_HIGH_NAME: /* set val for color */ case COURSE_MACHINE_HIGH_SCORE: - val = 100.0f * PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse,st).GetTopScore().fPercentDP; + val = 100.0f * PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse,st,cd).GetTopScore().fPercentDP; break; case COURSE_MACHINE_NUM_PLAYS: @@ -241,7 +242,7 @@ void PaneDisplay::SetContent( PaneContents c ) break; case COURSE_PROFILE_HIGH_SCORE: - val = 100.0f * PROFILEMAN->GetProfile(m_PlayerNumber)->GetCourseHighScoreList(pCourse,st).GetTopScore().fPercentDP; + val = 100.0f * PROFILEMAN->GetProfile(m_PlayerNumber)->GetCourseHighScoreList(pCourse,st,cd).GetTopScore().fPercentDP; break; case COURSE_PROFILE_NUM_PLAYS: val = (float) PROFILEMAN->GetProfile(m_PlayerNumber)->GetCourseNumTimesPlayed( pCourse ); @@ -274,7 +275,7 @@ void PaneDisplay::SetContent( PaneContents c ) str = PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSteps).GetTopScore().sName; break; case COURSE_MACHINE_HIGH_NAME: - str = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse, st).GetTopScore().sName; + str = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse,st,cd).GetTopScore().sName; break; case SONG_MACHINE_HIGH_SCORE: diff --git a/stepmania/src/Profile.cpp b/stepmania/src/Profile.cpp index fa5114e303..643eedb64e 100644 --- a/stepmania/src/Profile.cpp +++ b/stepmania/src/Profile.cpp @@ -187,27 +187,27 @@ void Profile::IncrementStepsPlayCount( const Steps* pSteps ) // // Course high scores // -void Profile::AddCourseHighScore( const Course* pCourse, StepsType st, HighScore hs, int &iIndexOut ) +void Profile::AddCourseHighScore( const Course* pCourse, StepsType st, CourseDifficulty cd, HighScore hs, int &iIndexOut ) { std::map::iterator iter = m_CourseHighScores.find( pCourse ); if( iter == m_CourseHighScores.end() ) - m_CourseHighScores[pCourse].hs[st].AddHighScore( hs, iIndexOut ); // operator[] inserts into map + m_CourseHighScores[pCourse].hs[st][cd].AddHighScore( hs, iIndexOut ); // operator[] inserts into map else - iter->second.hs[st].AddHighScore( hs, iIndexOut ); + iter->second.hs[st][cd].AddHighScore( hs, iIndexOut ); } -const HighScoreList& Profile::GetCourseHighScoreList( const Course* pCourse, StepsType st ) const +const HighScoreList& Profile::GetCourseHighScoreList( const Course* pCourse, StepsType st, CourseDifficulty cd ) const { - return ((Profile *)this)->m_CourseHighScores[pCourse].hs[st]; + return ((Profile *)this)->m_CourseHighScores[pCourse].hs[st][cd]; } -HighScoreList& Profile::GetCourseHighScoreList( const Course* pCourse, StepsType st ) +HighScoreList& Profile::GetCourseHighScoreList( const Course* pCourse, StepsType st, CourseDifficulty cd ) { std::map::iterator iter = m_CourseHighScores.find( pCourse ); if( iter == m_CourseHighScores.end() ) - return m_CourseHighScores[pCourse].hs[st]; // operator[] inserts into map + return m_CourseHighScores[pCourse].hs[st][cd]; // operator[] inserts into map else - return iter->second.hs[st]; + return iter->second.hs[st][cd]; } int Profile::GetCourseNumTimesPlayed( const Course* pCourse ) const @@ -221,14 +221,15 @@ int Profile::GetCourseNumTimesPlayed( const Course* pCourse ) const { int iTotalNumTimesPlayed = 0; for( unsigned st = 0; st < NUM_STEPS_TYPES; ++st ) - iTotalNumTimesPlayed += iter->second.hs[st].iNumTimesPlayed; + FOREACH_CourseDifficulty( cd ) + iTotalNumTimesPlayed += iter->second.hs[st][cd].iNumTimesPlayed; return iTotalNumTimesPlayed; } } -void Profile::IncrementCoursePlayCount( const Course* pCourse, StepsType st ) +void Profile::IncrementCoursePlayCount( const Course* pCourse, StepsType st, CourseDifficulty cd ) { - GetCourseHighScoreList(pCourse,st).iNumTimesPlayed++; + GetCourseHighScoreList(pCourse,st,cd).iNumTimesPlayed++; } // @@ -960,7 +961,7 @@ void Profile::LoadCourseScoresFromDirSM390a12( CString sDir ) if( !FileRead(f, iNumTimesPlayed) ) WARN_AND_RETURN; - HighScoreList &hsl = pProfile->GetCourseHighScoreList( pCourse, (StepsType)st ); + HighScoreList &hsl = pProfile->GetCourseHighScoreList( pCourse, (StepsType)st, COURSE_DIFFICULTY_REGULAR ); if( pCourse ) hsl.iNumTimesPlayed = iNumTimesPlayed; @@ -1029,16 +1030,28 @@ XNode* Profile::SaveCourseScoresCreateNode() const for( StepsType st=(StepsType)0; stGetCourseHighScoreList(pCourse, st).iNumTimesPlayed == 0 ) - continue; - - LPXNode pStepsTypeNode = pCourseNode->AppendChild( "StepsType" ); + // TRICKY: Only append this node if one we have at least one child. + // There's no point to saving a bunch of empty StepsType nodes. + LPXNode pStepsTypeNode = new XNode; + pStepsTypeNode->name = "StepsType"; pStepsTypeNode->AppendAttr( "Type", GameManager::NotesTypeToString(st) ); - - const HighScoreList &hsl = pProfile->GetCourseHighScoreList( pCourse, st ); - pStepsTypeNode->AppendChild( hsl.CreateNode() ); + FOREACH_CourseDifficulty( cd ) + { + // skip course/steps types that have never been played + if( pProfile->GetCourseHighScoreList(pCourse, st, cd).iNumTimesPlayed == 0 ) + continue; + + LPXNode pCourseDifficultyNode = pStepsTypeNode->AppendChild( "CourseDifficulty" ); + pCourseDifficultyNode->AppendAttr( "Type", CourseDifficultyToString(cd) ); + + const HighScoreList &hsl = pProfile->GetCourseHighScoreList( pCourse, st, cd ); + + pCourseDifficultyNode->AppendChild( hsl.CreateNode() ); + } + + if( !pStepsTypeNode->childs.empty() ) + pCourseNode->AppendChild( pStepsTypeNode ); } } @@ -1082,12 +1095,25 @@ void Profile::LoadCourseScoresFromNode( const XNode* pNode ) if( st == STEPS_TYPE_INVALID ) WARN_AND_CONTINUE; - XNode *pHighScoreListNode = (*stepsType)->GetChild("HighScoreList"); - if( pHighScoreListNode == NULL ) - WARN_AND_CONTINUE; - - HighScoreList &hsl = this->GetCourseHighScoreList( pCourse, st ); - hsl.LoadFromNode( pHighScoreListNode ); + for( XNodes::iterator courseDifficulty = (*stepsType)->childs.begin(); + courseDifficulty != (*stepsType)->childs.end(); + courseDifficulty++ ) + { + + const LPXAttr TypeAttr = (*courseDifficulty)->GetAttr( "Type" ); + if( TypeAttr == NULL ) + WARN_AND_CONTINUE; + CourseDifficulty cd = StringToCourseDifficulty( TypeAttr->value ); + if( cd == COURSE_DIFFICULTY_INVALID ) + WARN_AND_CONTINUE; + + XNode *pHighScoreListNode = (*courseDifficulty)->GetChild("HighScoreList"); + if( pHighScoreListNode == NULL ) + WARN_AND_CONTINUE; + + HighScoreList &hsl = this->GetCourseHighScoreList( pCourse, st, cd ); + hsl.LoadFromNode( pHighScoreListNode ); + } } } } diff --git a/stepmania/src/Profile.h b/stepmania/src/Profile.h index b3569aba25..e700befc4a 100644 --- a/stepmania/src/Profile.h +++ b/stepmania/src/Profile.h @@ -117,15 +117,15 @@ public: // in processing the templates for map::operator[]. struct HighScoresForACourse { - HighScoreList hs[NUM_STEPS_TYPES]; + HighScoreList hs[NUM_STEPS_TYPES][NUM_COURSE_DIFFICULTIES]; }; std::map m_CourseHighScores; - void AddCourseHighScore( const Course* pCourse, StepsType st, HighScore hs, int &iIndexOut ); - HighScoreList& GetCourseHighScoreList( const Course* pCourse, StepsType st ); - const HighScoreList& GetCourseHighScoreList( const Course* pCourse, StepsType st ) const; + void AddCourseHighScore( const Course* pCourse, StepsType st, CourseDifficulty cd, HighScore hs, int &iIndexOut ); + HighScoreList& GetCourseHighScoreList( const Course* pCourse, StepsType st, CourseDifficulty cd ); + const HighScoreList& GetCourseHighScoreList( const Course* pCourse, StepsType st, CourseDifficulty cd ) const; int GetCourseNumTimesPlayed( const Course* pCourse ) const; - void IncrementCoursePlayCount( const Course* pCourse, StepsType st ); + void IncrementCoursePlayCount( const Course* pCourse, StepsType st, CourseDifficulty cd ); // diff --git a/stepmania/src/ProfileManager.cpp b/stepmania/src/ProfileManager.cpp index 6fbe0ad95a..326d87d8bf 100644 --- a/stepmania/src/ProfileManager.cpp +++ b/stepmania/src/ProfileManager.cpp @@ -471,21 +471,21 @@ HighScore ProfileManager::GetHighScoreForDifficulty( const Song *s, const StyleD // // Course stats // -void ProfileManager::AddCourseHighScore( const Course* pCourse, StepsType st, PlayerNumber pn, HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut ) +void ProfileManager::AddCourseHighScore( const Course* pCourse, StepsType st, CourseDifficulty cd, PlayerNumber pn, HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut ) { hs.sName = RANKING_TO_FILL_IN_MARKER[pn]; if( PROFILEMAN->IsUsingProfile(pn) ) - PROFILEMAN->GetProfile(pn)->AddCourseHighScore( pCourse, st, hs, iPersonalIndexOut ); + PROFILEMAN->GetProfile(pn)->AddCourseHighScore( pCourse, st, cd, hs, iPersonalIndexOut ); else iPersonalIndexOut = -1; - PROFILEMAN->GetMachineProfile()->AddCourseHighScore( pCourse, st, hs, iMachineIndexOut ); + PROFILEMAN->GetMachineProfile()->AddCourseHighScore( pCourse, st, cd, hs, iMachineIndexOut ); } -void ProfileManager::IncrementCoursePlayCount( const Course* pCourse, StepsType st, PlayerNumber pn ) +void ProfileManager::IncrementCoursePlayCount( const Course* pCourse, StepsType st, CourseDifficulty cd, PlayerNumber pn ) { if( PROFILEMAN->IsUsingProfile(pn) ) - PROFILEMAN->GetProfile(pn)->IncrementCoursePlayCount( pCourse, st ); - PROFILEMAN->GetMachineProfile()->IncrementCoursePlayCount( pCourse, st ); + PROFILEMAN->GetProfile(pn)->IncrementCoursePlayCount( pCourse, st, cd ); + PROFILEMAN->GetMachineProfile()->IncrementCoursePlayCount( pCourse, st, cd ); } diff --git a/stepmania/src/ProfileManager.h b/stepmania/src/ProfileManager.h index 7f46eae895..3145bbac5b 100644 --- a/stepmania/src/ProfileManager.h +++ b/stepmania/src/ProfileManager.h @@ -84,8 +84,8 @@ public: // // Course stats // - void AddCourseHighScore( const Course* pCourse, StepsType st, PlayerNumber pn, HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut ); - void IncrementCoursePlayCount( const Course* pCourse, StepsType st, PlayerNumber pn ); + void AddCourseHighScore( const Course* pCourse, StepsType st, CourseDifficulty cd, PlayerNumber pn, HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut ); + void IncrementCoursePlayCount( const Course* pCourse, StepsType st, CourseDifficulty cd, PlayerNumber pn ); // // Category stats diff --git a/stepmania/src/ScreenEvaluation.cpp b/stepmania/src/ScreenEvaluation.cpp index 738d26fffa..62e09dbc26 100644 --- a/stepmania/src/ScreenEvaluation.cpp +++ b/stepmania/src/ScreenEvaluation.cpp @@ -949,6 +949,7 @@ void ScreenEvaluation::CommitScores( const StageStats &stageStats, int iPersonal case course: { Course* pCourse = GAMESTATE->m_pCurCourse; + CourseDifficulty cd = GAMESTATE->m_CourseDifficulty[p]; if( pCourse ) { // don't save scores for a failed Nonstop @@ -957,7 +958,7 @@ void ScreenEvaluation::CommitScores( const StageStats &stageStats, int iPersonal continue; if( hs.fPercentDP > PREFSMAN->m_fMinPercentageForHighScore ) - PROFILEMAN->AddCourseHighScore( pCourse, nt, (PlayerNumber)p, hs, iPersonalHighScoreIndex[p], iMachineHighScoreIndex[p] ); + PROFILEMAN->AddCourseHighScore( pCourse, nt, cd, (PlayerNumber)p, hs, iPersonalHighScoreIndex[p], iMachineHighScoreIndex[p] ); } } break; diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index e2b8248dca..2dfc1490d4 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -176,7 +176,7 @@ void ScreenGameplay::Init() if( !m_bDemonstration ) for( p=0; pIsPlayerEnabled(p) ) - PROFILEMAN->IncrementCoursePlayCount( GAMESTATE->m_pCurCourse, st, (PlayerNumber)p ); + PROFILEMAN->IncrementCoursePlayCount( GAMESTATE->m_pCurCourse, st, GAMESTATE->m_CourseDifficulty[p], (PlayerNumber)p ); for( int p=0; pGetCourseFromPath( asCoursePaths[c] ); + pts.cd = COURSE_DIFFICULTY_REGULAR; if( pts.pCourse ) m_vPagesToShow.push_back( pts ); } @@ -712,7 +713,7 @@ float ScreenRanking::SetPage( PageToShow pts ) m_Banner.LoadFromCourse( pts.pCourse ); m_textStepsType.SetText( GameManager::NotesTypeToString(pts.nt) ); - const HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList( pts.pCourse, pts.nt ); + const HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList( pts.pCourse, pts.nt, pts.cd ); for( int l=0; lm_pCourse; pCourseScoreRowItem->m_textSongTitle.SetText( pCourse->m_sName ); - const HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList( pCourse, pts.nt ); - for( int d=0; dm_textStepsScore[d]; + const HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList( pCourse, pts.nt, cd ); + BitmapText* pTextStepsScore = &pCourseScoreRowItem->m_textStepsScore[cd]; HighScore hs; bool bRecentHighScore = false; diff --git a/stepmania/src/ScreenRanking.h b/stepmania/src/ScreenRanking.h index 21cb3049ba..1f483d2095 100644 --- a/stepmania/src/ScreenRanking.h +++ b/stepmania/src/ScreenRanking.h @@ -37,6 +37,7 @@ protected: StepsType nt; RankingCategory category; Course* pCourse; + CourseDifficulty cd; PageToShow(): pCourse(NULL) { } }; diff --git a/stepmania/src/ScreenSelectCourse.cpp b/stepmania/src/ScreenSelectCourse.cpp index 714f05f20b..8a573020bb 100644 --- a/stepmania/src/ScreenSelectCourse.cpp +++ b/stepmania/src/ScreenSelectCourse.cpp @@ -398,6 +398,7 @@ void ScreenSelectCourse::AfterCourseChange() case TYPE_COURSE: { Course* pCourse = m_MusicWheel.GetSelectedCourse(); + const StepsType &st = GAMESTATE->GetCurrentStyleDef()->m_StepsType; m_textNumSongs.SetText( ssprintf("%d", pCourse->GetEstimatedNumStages()) ); float fTotalSeconds; @@ -414,7 +415,7 @@ void ScreenSelectCourse::AfterCourseChange() ASSERT(pCourse); for( int p=0; pGetCurrentStyleDef()->m_StepsType; + CourseDifficulty cd = GAMESTATE->m_CourseDifficulty[p]; Profile* pProfile; if( PROFILEMAN->IsUsingProfile( (PlayerNumber)p ) ) @@ -428,7 +429,7 @@ void ScreenSelectCourse::AfterCourseChange() * have an opinion on which should be used here for * each of oni, endless, nonstop -- * should this choice be an option or a metric? */ - const HighScoreList& hsl = pProfile->GetCourseHighScoreList( pCourse, st ); + const HighScoreList& hsl = pProfile->GetCourseHighScoreList( pCourse, st, cd ); if ( pCourse->IsOni() || pCourse->IsEndless() ) { /* use survive time */