Fix for "10th score" leaderboard bug, Reduce load from GAMESTATE::StoreRankingName()
- Fixes bug where 10th scores get erased when two players play the same song multiple times and rank on the leaderboard more than once - Only clamping leaderboards and deduping high scores for songs/courses once overall instead of once per player - Instead of looping through every song and course on the machine multiple times -> Only loop through the songs/course played in the past session
This commit is contained in:
+67
-18
@@ -579,6 +579,7 @@ void GameState::BeginGame()
|
|||||||
m_timeGameStarted.Touch();
|
m_timeGameStarted.Touch();
|
||||||
|
|
||||||
m_vpsNamesThatWereFilled.clear();
|
m_vpsNamesThatWereFilled.clear();
|
||||||
|
m_sPlayersThatWereFilled.clear();
|
||||||
|
|
||||||
// Play attract on the ending screen, then on the ranking screen
|
// Play attract on the ending screen, then on the ranking screen
|
||||||
// even if attract sounds are set to off.
|
// even if attract sounds are set to off.
|
||||||
@@ -2349,29 +2350,77 @@ void GameState::StoreRankingName( PlayerNumber pn, RString sName )
|
|||||||
m_vpsNamesThatWereFilled.push_back( aFeats[i].pStringToFill );
|
m_vpsNamesThatWereFilled.push_back( aFeats[i].pStringToFill );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_sPlayersThatWereFilled.insert(pn);
|
||||||
|
|
||||||
Profile *pProfile = PROFILEMAN->GetMachineProfile();
|
// Only attempt to remove/clamp scores after the last enabled player has saved their scores.
|
||||||
|
if (GAMESTATE->GetNumPlayersEnabled() <= static_cast<int>(m_sPlayersThatWereFilled.size())) {
|
||||||
|
StepsType st = GetCurrentStyle(pn)->m_StepsType;
|
||||||
|
PlayMode mode = m_PlayMode.Get();
|
||||||
|
Profile *pProfile = PROFILEMAN->GetMachineProfile();
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case PLAY_MODE_REGULAR:
|
||||||
|
case PLAY_MODE_BATTLE:
|
||||||
|
case PLAY_MODE_RAVE:
|
||||||
|
{
|
||||||
|
// Find unique Song and Steps combinations that were played.
|
||||||
|
// Code is taken from implementation in GetRankingFeats()
|
||||||
|
std::vector<SongAndSteps> vSongAndSteps;
|
||||||
|
|
||||||
if( !PREFSMAN->m_bAllowMultipleHighScoreWithSameName )
|
for( unsigned i=0; i<STATSMAN->m_vPlayedStageStats.size(); i++ )
|
||||||
{
|
{
|
||||||
// erase all but the highest score for each name
|
CHECKPOINT_M( ssprintf("%u/%i", i, (int)STATSMAN->m_vPlayedStageStats.size() ) );
|
||||||
for (auto &songIter : pProfile->m_SongHighScores)
|
SongAndSteps sas;
|
||||||
for (auto &stepIter : songIter.second.m_StepsHighScores)
|
ASSERT( !STATSMAN->m_vPlayedStageStats[i].m_vpPlayedSongs.empty() );
|
||||||
stepIter.second.hsl.RemoveAllButOneOfEachName();
|
sas.pSong = STATSMAN->m_vPlayedStageStats[i].m_vpPlayedSongs[0];
|
||||||
|
ASSERT( sas.pSong != nullptr );
|
||||||
|
|
||||||
for (auto &courseIter : pProfile->m_CourseHighScores)
|
if ( STATSMAN->m_vPlayedStageStats[i].m_player[pn].m_vpPossibleSteps.empty() )
|
||||||
for (auto &trailIter : courseIter.second.m_TrailHighScores)
|
continue;
|
||||||
trailIter.second.hsl.RemoveAllButOneOfEachName();
|
sas.pSteps = STATSMAN->m_vPlayedStageStats[i].m_player[pn].m_vpPossibleSteps[0];
|
||||||
|
ASSERT( sas.pSteps != nullptr );
|
||||||
|
vSongAndSteps.push_back( sas );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SongAndSteps>::iterator toDelete = std::unique( vSongAndSteps.begin(), vSongAndSteps.end() );
|
||||||
|
vSongAndSteps.erase(toDelete, vSongAndSteps.end());
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < vSongAndSteps.size(); ++i)
|
||||||
|
{
|
||||||
|
HighScoreList &hsl = pProfile->GetStepsHighScoreList(vSongAndSteps[i].pSong,vSongAndSteps[i].pSteps);
|
||||||
|
if (!PREFSMAN->m_bAllowMultipleHighScoreWithSameName)
|
||||||
|
{
|
||||||
|
// erase all but the highest score for each name
|
||||||
|
hsl.RemoveAllButOneOfEachName();
|
||||||
|
}
|
||||||
|
hsl.ClampSize(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PLAY_MODE_NONSTOP:
|
||||||
|
case PLAY_MODE_ONI:
|
||||||
|
case PLAY_MODE_ENDLESS:
|
||||||
|
{
|
||||||
|
// Code is taken from implementation in GetRankingFeats()
|
||||||
|
Course* pCourse = m_pCurCourse;
|
||||||
|
ASSERT( pCourse != nullptr );
|
||||||
|
Trail *pTrail = m_pCurTrail[pn];
|
||||||
|
ASSERT( pTrail != nullptr );
|
||||||
|
CourseDifficulty cd = pTrail->m_CourseDifficulty;
|
||||||
|
HighScoreList &hsl = pProfile->GetCourseHighScoreList( pCourse, pTrail );
|
||||||
|
if (!PREFSMAN->m_bAllowMultipleHighScoreWithSameName)
|
||||||
|
{
|
||||||
|
// erase all but the highest score for each name
|
||||||
|
hsl.RemoveAllButOneOfEachName();
|
||||||
|
}
|
||||||
|
hsl.ClampSize(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FAIL_M(ssprintf("Invalid play mode: %i", int(m_PlayMode)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clamp high score sizes
|
|
||||||
for (auto &songIter : pProfile->m_SongHighScores)
|
|
||||||
for (auto &stepIter : songIter.second.m_StepsHighScores)
|
|
||||||
stepIter.second.hsl.ClampSize( true );
|
|
||||||
|
|
||||||
for (auto &courseIter : pProfile->m_CourseHighScores)
|
|
||||||
for (auto &trailIter : courseIter.second.m_TrailHighScores)
|
|
||||||
trailIter.second.hsl.ClampSize( true );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameState::AllAreInDangerOrWorse() const
|
bool GameState::AllAreInDangerOrWorse() const
|
||||||
|
|||||||
@@ -357,6 +357,7 @@ public:
|
|||||||
bool AnyPlayerHasRankingFeats() const;
|
bool AnyPlayerHasRankingFeats() const;
|
||||||
void StoreRankingName( PlayerNumber pn, RString name ); // Called by name entry screens
|
void StoreRankingName( PlayerNumber pn, RString name ); // Called by name entry screens
|
||||||
std::vector<RString*> m_vpsNamesThatWereFilled; // filled on StoreRankingName,
|
std::vector<RString*> m_vpsNamesThatWereFilled; // filled on StoreRankingName,
|
||||||
|
std::set<PlayerNumber> m_sPlayersThatWereFilled; // filled on StoreRankingName,
|
||||||
|
|
||||||
// Award stuff
|
// Award stuff
|
||||||
// lowest priority in front, highest priority at the back.
|
// lowest priority in front, highest priority at the back.
|
||||||
|
|||||||
Reference in New Issue
Block a user