diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index 60cd488d00..0d33caddb8 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -1652,6 +1652,34 @@ void GameState::StoreRankingName( PlayerNumber pn, CString name ) // save name pointers as we fill them m_vpsNamesThatWereFilled.push_back( aFeats[i].pStringToFill ); } + + + Profile *pProfile = PROFILEMAN->GetMachineProfile(); + + if( !PREFSMAN->m_bAllowMultipleHighScoreWithSameName ) + { + // + // erase all but the highest score for each name + // + FOREACHM( SongID, Profile::HighScoresForASong, pProfile->m_SongHighScores, iter ) + FOREACHM( StepsID, Profile::HighScoresForASteps, iter->second.m_StepsHighScores, iter2 ) + iter2->second.hsl.RemoveAllButOneOfEachName(); + + FOREACHM( CourseID, Profile::HighScoresForACourse, pProfile->m_CourseHighScores, iter ) + FOREACHM( TrailID, Profile::HighScoresForATrail, iter->second.m_TrailHighScores, iter2 ) + iter2->second.hsl.RemoveAllButOneOfEachName(); + } + + // + // clamp high score sizes + // + FOREACHM( SongID, Profile::HighScoresForASong, pProfile->m_SongHighScores, iter ) + FOREACHM( StepsID, Profile::HighScoresForASteps, iter->second.m_StepsHighScores, iter2 ) + iter2->second.hsl.ClampSize( true ); + + FOREACHM( CourseID, Profile::HighScoresForACourse, pProfile->m_CourseHighScores, iter ) + FOREACHM( TrailID, Profile::HighScoresForATrail, iter->second.m_TrailHighScores, iter2 ) + iter2->second.hsl.ClampSize( true ); } bool GameState::AllAreInDangerOrWorse() const diff --git a/stepmania/src/HighScore.cpp b/stepmania/src/HighScore.cpp index 323fbc2c54..54cfe298af 100644 --- a/stepmania/src/HighScore.cpp +++ b/stepmania/src/HighScore.cpp @@ -129,8 +129,13 @@ void HighScoreList::AddHighScore( HighScore hs, int &iIndexOut, bool bIsMachine { vHighScores.insert( vHighScores.begin()+i, hs ); iIndexOut = i; - if( vHighScores.size() > unsigned(iMaxScores) ) - vHighScores.erase( vHighScores.begin()+iMaxScores, vHighScores.end() ); + + // Delete extra machine high scores in RemoveAllButOneOfEachNameAndClampSize + // and not here so that we don't end up with less than iMaxScores after + // removing HighScores with duplicate names. + // + if( !bIsMachine ) + ClampSize( bIsMachine ); } } @@ -187,6 +192,30 @@ void HighScoreList::LoadFromNode( const XNode* pHighScoreList ) } } +void HighScoreList::RemoveAllButOneOfEachName() +{ + FOREACH( HighScore, vHighScores, i ) + { + for( vector::iterator j = i+1; j != vHighScores.end(); j++ ) + { + if( i->sName == j->sName ) + { + j--; + vHighScores.erase( j+1 ); + } + } + } +} + +void HighScoreList::ClampSize( bool bIsMachine ) +{ + const int iMaxScores = bIsMachine ? + PREFSMAN->m_iMaxHighScoresPerListForMachine : + PREFSMAN->m_iMaxHighScoresPerListForPlayer; + if( vHighScores.size() > unsigned(iMaxScores) ) + vHighScores.erase( vHighScores.begin()+iMaxScores, vHighScores.end() ); +} + XNode* Screenshot::CreateNode() const { XNode* pNode = new XNode; diff --git a/stepmania/src/HighScore.h b/stepmania/src/HighScore.h index 3c818efe02..af515fd338 100644 --- a/stepmania/src/HighScore.h +++ b/stepmania/src/HighScore.h @@ -92,6 +92,9 @@ struct HighScoreList XNode* CreateNode() const; void LoadFromNode( const XNode* pNode ); + + void RemoveAllButOneOfEachName(); + void ClampSize( bool bIsMachine ); }; struct Screenshot diff --git a/stepmania/src/PrefsManager.cpp b/stepmania/src/PrefsManager.cpp index 4b9e260afb..b198afa89d 100644 --- a/stepmania/src/PrefsManager.cpp +++ b/stepmania/src/PrefsManager.cpp @@ -267,6 +267,7 @@ void PrefsManager::Init() m_bHideDefaultNoteSkin = false; m_iMaxHighScoresPerListForMachine = 10; m_iMaxHighScoresPerListForPlayer = 3; + m_bAllowMultipleHighScoreWithSameName = true; m_fPadStickSeconds = 0; m_bForceMipMaps = false; m_bTrilinearFiltering = false; @@ -540,6 +541,7 @@ void PrefsManager::ReadGlobalPrefsFromIni( const IniFile &ini ) ini.GetValue( "Options", "HideDefaultNoteSkin", m_bHideDefaultNoteSkin ); ini.GetValue( "Options", "MaxHighScoresPerListForMachine", m_iMaxHighScoresPerListForMachine ); ini.GetValue( "Options", "MaxHighScoresPerListForPlayer", m_iMaxHighScoresPerListForPlayer ); + ini.GetValue( "Options", "AllowMultipleHighScoreWithSameName", m_bAllowMultipleHighScoreWithSameName ); ini.GetValue( "Options", "PadStickSeconds", m_fPadStickSeconds ); ini.GetValue( "Options", "ForceMipMaps", m_bForceMipMaps ); ini.GetValue( "Options", "TrilinearFiltering", m_bTrilinearFiltering ); @@ -770,6 +772,7 @@ void PrefsManager::SaveGlobalPrefsToIni( IniFile &ini ) const ini.SetValue( "Options", "HideDefaultNoteSkin", m_bHideDefaultNoteSkin ); ini.SetValue( "Options", "MaxHighScoresPerListForMachine", m_iMaxHighScoresPerListForMachine ); ini.SetValue( "Options", "MaxHighScoresPerListForPlayer", m_iMaxHighScoresPerListForPlayer ); + ini.SetValue( "Options", "AllowMultipleHighScoreWithSameName", m_bAllowMultipleHighScoreWithSameName ); ini.SetValue( "Options", "PadStickSeconds", m_fPadStickSeconds ); ini.SetValue( "Options", "ForceMipMaps", m_bForceMipMaps ); ini.SetValue( "Options", "TrilinearFiltering", m_bTrilinearFiltering ); diff --git a/stepmania/src/PrefsManager.h b/stepmania/src/PrefsManager.h index 5ffea8ecdd..1198ef4925 100644 --- a/stepmania/src/PrefsManager.h +++ b/stepmania/src/PrefsManager.h @@ -214,6 +214,7 @@ public: bool m_bHideDefaultNoteSkin; int m_iMaxHighScoresPerListForMachine; int m_iMaxHighScoresPerListForPlayer; + bool m_bAllowMultipleHighScoreWithSameName; bool m_bCelShadeModels; /* experimental: force a specific update rate. This prevents big diff --git a/stepmania/src/Profile.cpp b/stepmania/src/Profile.cpp index 901c395914..3797b84004 100644 --- a/stepmania/src/Profile.cpp +++ b/stepmania/src/Profile.cpp @@ -333,9 +333,9 @@ float Profile::GetSongsActual( StepsType st, Difficulty dc ) const CHECKPOINT; const HighScoresForASteps& h = j->second; - const HighScoreList& hs = h.hs; + const HighScoreList& hsl = h.hsl; - fTotalPercents += hs.GetTopScore().fPercentDP; + fTotalPercents += hsl.GetTopScore().fPercentDP; } CHECKPOINT; } @@ -416,9 +416,9 @@ float Profile::GetCoursesActual( StepsType st, CourseDifficulty cd ) const continue; const HighScoresForATrail& h = j->second; - const HighScoreList& hs = h.hs; + const HighScoreList& hsl = h.hsl; - fTotalPercents += hs.GetTopScore().fPercentDP; + fTotalPercents += hsl.GetTopScore().fPercentDP; } } @@ -474,7 +474,7 @@ int Profile::GetSongNumTimesPlayed( const SongID& songID ) const { const HighScoresForASteps &hsSteps = j->second; - iTotalNumTimesPlayed += hsSteps.hs.iNumTimesPlayed; + iTotalNumTimesPlayed += hsSteps.hsl.iNumTimesPlayed; } return iTotalNumTimesPlayed; } @@ -535,7 +535,7 @@ HighScoreList& Profile::GetStepsHighScoreList( const Song* pSong, const Steps* p HighScoresForASong &hsSong = m_SongHighScores[songID]; // operator[] inserts into map HighScoresForASteps &hsSteps = hsSong.m_StepsHighScores[stepsID]; // operator[] inserts into map - return hsSteps.hs; + return hsSteps.hsl; } int Profile::GetStepsNumTimesPlayed( const Song* pSong, const Steps* pSteps ) const @@ -569,7 +569,7 @@ void Profile::GetGrades( const Song* pSong, StepsType st, int iCounts[NUM_GRADES continue; const HighScoresForASteps &hsSteps = it->second; - if( hsSteps.hs.GetTopScore().grade == g ) + if( hsSteps.hsl.GetTopScore().grade == g ) iCounts[g]++; } } @@ -599,7 +599,7 @@ HighScoreList& Profile::GetCourseHighScoreList( const Course* pCourse, const Tra HighScoresForACourse &hsCourse = m_CourseHighScores[courseID]; // operator[] inserts into map HighScoresForATrail &hsTrail = hsCourse.m_TrailHighScores[trailID]; // operator[] inserts into map - return hsTrail.hs; + return hsTrail.hsl; } int Profile::GetCourseNumTimesPlayed( const Course* pCourse ) const @@ -623,7 +623,7 @@ int Profile::GetCourseNumTimesPlayed( const CourseID &courseID ) const { const HighScoresForATrail &hsTrail = j->second; - iTotalNumTimesPlayed += hsTrail.hs.iNumTimesPlayed; + iTotalNumTimesPlayed += hsTrail.hsl.iNumTimesPlayed; } return iTotalNumTimesPlayed; } @@ -1197,7 +1197,7 @@ XNode* Profile::SaveSongScoresCreateNode() const const StepsID &stepsID = j->first; const HighScoresForASteps &hsSteps = j->second; - const HighScoreList &hsl = hsSteps.hs; + const HighScoreList &hsl = hsSteps.hsl; // skip steps that have never been played if( hsl.iNumTimesPlayed == 0 ) @@ -1242,7 +1242,7 @@ void Profile::LoadSongScoresFromNode( const XNode* pSongScores ) if( pHighScoreListNode == NULL ) WARN_AND_CONTINUE; - HighScoreList &hsl = m_SongHighScores[songID].m_StepsHighScores[stepsID].hs; + HighScoreList &hsl = m_SongHighScores[songID].m_StepsHighScores[stepsID].hsl; hsl.LoadFromNode( pHighScoreListNode ); } } @@ -1280,7 +1280,7 @@ XNode* Profile::SaveCourseScoresCreateNode() const const TrailID &trailID = j->first; const HighScoresForATrail &hsTrail = j->second; - const HighScoreList &hsl = hsTrail.hs; + const HighScoreList &hsl = hsTrail.hsl; // skip steps that have never been played if( hsl.iNumTimesPlayed == 0 ) @@ -1325,7 +1325,7 @@ void Profile::LoadCourseScoresFromNode( const XNode* pCourseScores ) if( pHighScoreListNode == NULL ) WARN_AND_CONTINUE; - HighScoreList &hsl = m_CourseHighScores[courseID].m_TrailHighScores[trailID].hs; + HighScoreList &hsl = m_CourseHighScores[courseID].m_TrailHighScores[trailID].hsl; hsl.LoadFromNode( pHighScoreListNode ); } } diff --git a/stepmania/src/Profile.h b/stepmania/src/Profile.h index a1b770b34c..3bed69781f 100644 --- a/stepmania/src/Profile.h +++ b/stepmania/src/Profile.h @@ -142,7 +142,7 @@ public: // struct HighScoresForASteps { - HighScoreList hs; + HighScoreList hsl; }; struct HighScoresForASong { @@ -165,7 +165,7 @@ public: // in processing the templates for map::operator[]. struct HighScoresForATrail { - HighScoreList hs; + HighScoreList hsl; }; struct HighScoresForACourse {