move all high score data into Profile

This commit is contained in:
Chris Danford
2004-02-09 06:26:13 +00:00
parent 52a46b9468
commit d7f0e6c2bc
19 changed files with 796 additions and 627 deletions
+6 -44
View File
@@ -439,23 +439,6 @@ void Course::AutogenNonstopFromGroup( CString sGroupName, vector<Song*> &apSongs
m_entries.pop_back(); m_entries.pop_back();
} }
void Course::MemCardData::AddHighScore( HighScore hs, int &iIndexOut )
{
int i;
for( i=0; i<(int)vHighScores.size(); i++ )
{
if( hs >= vHighScores[i] )
break;
}
if( i < NUM_RANKING_LINES )
{
vHighScores.insert( vHighScores.begin()+i, hs );
iIndexOut = i;
if( vHighScores.size() > unsigned(NUM_RANKING_LINES) )
vHighScores.erase( vHighScores.begin()+NUM_RANKING_LINES, vHighScores.end() );
}
}
/* /*
* Difficult courses do the following: * Difficult courses do the following:
* *
@@ -1029,24 +1012,6 @@ bool Course::IsRanking() const
return false; return false;
} }
void Course::AddHighScore( StepsType st, PlayerNumber pn, MemCardData::HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut )
{
hs.sName = RANKING_TO_FILL_IN_MARKER[pn];
if( PROFILEMAN->IsUsingProfile(pn) )
m_MemCardDatas[st][pn].AddHighScore( hs, iPersonalIndexOut );
else
iPersonalIndexOut = -1;
m_MemCardDatas[st][PROFILE_SLOT_MACHINE].AddHighScore( hs, iMachineIndexOut );
}
int Course::GetNumTimesPlayed( ProfileSlot card ) const
{
int iTotalNumTimesPlayed = 0;
for( unsigned i = 0; i < NUM_STEPS_TYPES; ++i )
iTotalNumTimesPlayed += GetNumTimesPlayed( (StepsType) i, card );
return iTotalNumTimesPlayed;
}
static map<const Course*, float> course_sort_val; static map<const Course*, float> course_sort_val;
bool CompareCoursePointersBySortValueAscending(const Course *pSong1, const Course *pSong2) bool CompareCoursePointersBySortValueAscending(const Course *pSong1, const Course *pSong2)
@@ -1077,18 +1042,15 @@ void SortCoursePointerArrayByAvgDifficulty( vector<Course*> &apCourses )
} }
void SortCoursePointerArrayByMostPlayed( vector<Course*> &arrayCoursePointers, ProfileSlot card ) void SortCoursePointerArrayByMostPlayed( vector<Course*> &arrayCoursePointers, ProfileSlot slot )
{ {
Profile* pProfile = PROFILEMAN->GetProfile(slot);
if( pProfile == NULL )
return; // nothing to do since we don't have data
for(unsigned i = 0; i < arrayCoursePointers.size(); ++i) for(unsigned i = 0; i < arrayCoursePointers.size(); ++i)
course_sort_val[arrayCoursePointers[i]] = (float) arrayCoursePointers[i]->GetNumTimesPlayed( card ); course_sort_val[arrayCoursePointers[i]] = (float) pProfile->GetCourseNumTimesPlayed(arrayCoursePointers[i]);
stable_sort( arrayCoursePointers.begin(), arrayCoursePointers.end(), CompareCoursePointersBySortValueDescending ); stable_sort( arrayCoursePointers.begin(), arrayCoursePointers.end(), CompareCoursePointersBySortValueDescending );
course_sort_val.clear(); course_sort_val.clear();
} }
bool Course::MemCardData::HighScore::operator>=( const HighScore& other ) const
{
if( PREFSMAN->m_bPercentageScoring )
return fPercentDP >= other.fPercentDP;
else
return iScore >= other.iScore;
}
-53
View File
@@ -139,59 +139,6 @@ public:
void AutogenNonstopFromGroup( CString sGroupName, vector<Song*> &apSongsInGroup ); void AutogenNonstopFromGroup( CString sGroupName, vector<Song*> &apSongsInGroup );
struct MemCardData
{
MemCardData()
{
iNumTimesPlayed = 0;
}
int iNumTimesPlayed;
struct HighScore
{
CString sName;
int iScore;
float fPercentDP;
float fSurviveTime;
HighScore()
{
iScore = 0;
fPercentDP = 0;
fSurviveTime = 0;
}
bool operator>=( const HighScore& other ) const;
};
vector<HighScore> vHighScores;
void AddHighScore( HighScore hs, int &iIndexOut );
HighScore GetTopScore()
{
if( vHighScores.empty() )
return HighScore();
else
return vHighScores[0];
}
} m_MemCardDatas[NUM_STEPS_TYPES][NUM_PROFILE_SLOTS];
void AddHighScore( StepsType st, PlayerNumber pn, MemCardData::HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut );
MemCardData::HighScore GetTopScore( StepsType st, ProfileSlot slot )
{
return m_MemCardDatas[st][slot].GetTopScore();
}
int GetNumTimesPlayed( StepsType st, ProfileSlot slot ) const
{
return m_MemCardDatas[st][slot].iNumTimesPlayed;
}
int GetNumTimesPlayed( ProfileSlot slot ) const;
// sorting values // sorting values
int SortOrder_TotalDifficulty; int SortOrder_TotalDifficulty;
int SortOrder_Ranking; int SortOrder_Ranking;
+74 -57
View File
@@ -1132,48 +1132,56 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeats> &asFeatsO
Steps* pSteps = vSongAndSteps[i].pSteps; Steps* pSteps = vSongAndSteps[i].pSteps;
// Find Machine Records // Find Machine Records
vector<Steps::MemCardData::HighScore> &vMachineHighScores = pSteps->m_MemCardDatas[PROFILE_SLOT_MACHINE].vHighScores;
for( j=0; j<vMachineHighScores.size(); j++ )
{ {
if( vMachineHighScores[j].sName != RANKING_TO_FILL_IN_MARKER[pn] ) HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSteps);
continue; for( j=0; j<hsl.vHighScores.size(); j++ )
{
HighScore &hs = hsl.vHighScores[j];
RankingFeats feat; if( hs.sName != RANKING_TO_FILL_IN_MARKER[pn] )
feat.Type = RankingFeats::SONG; continue;
feat.Feat = ssprintf("MR #%d in %s %s", j+1, pSong->GetTranslitMainTitle().c_str(), DifficultyToString(pSteps->GetDifficulty()).c_str() );
feat.pStringToFill = &vMachineHighScores[j].sName;
feat.grade = vMachineHighScores[j].grade;
feat.fPercentDP = vMachineHighScores[j].fPercentDP;
feat.iScore = vMachineHighScores[j].iScore;
if( pSong->HasBanner() ) RankingFeats feat;
feat.Banner = pSong->GetBannerPath(); feat.Type = RankingFeats::SONG;
feat.Feat = ssprintf("MR #%d in %s %s", j+1, pSong->GetTranslitMainTitle().c_str(), DifficultyToString(pSteps->GetDifficulty()).c_str() );
feat.pStringToFill = &hs.sName;
feat.grade = hs.grade;
feat.fPercentDP = hs.fPercentDP;
feat.iScore = hs.iScore;
asFeatsOut.push_back( feat ); if( pSong->HasBanner() )
feat.Banner = pSong->GetBannerPath();
asFeatsOut.push_back( feat );
}
} }
// Find Personal Records // Find Personal Records
vector<Steps::MemCardData::HighScore> &vPersonalHighScores = pSteps->m_MemCardDatas[pn].vHighScores;
for( j=0; j<vPersonalHighScores.size(); j++ )
{ {
if( vPersonalHighScores[j].sName != RANKING_TO_FILL_IN_MARKER[pn] ) HighScoreList &hsl = PROFILEMAN->GetProfile(pn)->GetStepsHighScoreList(pSteps);
continue; for( j=0; j<hsl.vHighScores.size(); j++ )
{
HighScore &hs = hsl.vHighScores[j];
RankingFeats feat; if( hs.sName != RANKING_TO_FILL_IN_MARKER[pn] )
feat.Type = RankingFeats::SONG; continue;
feat.Feat = ssprintf("PR #%d in %s %s", j+1, pSong->GetTranslitMainTitle().c_str(), DifficultyToString(pSteps->GetDifficulty()).c_str() );
feat.pStringToFill = &vPersonalHighScores[j].sName;
feat.grade = vPersonalHighScores[j].grade;
feat.fPercentDP = vMachineHighScores[j].fPercentDP;
feat.iScore = vMachineHighScores[j].iScore;
// XXX: temporary hack RankingFeats feat;
if( pSong->HasBackground() ) feat.Type = RankingFeats::SONG;
feat.Banner = pSong->GetBackgroundPath(); feat.Feat = ssprintf("PR #%d in %s %s", j+1, pSong->GetTranslitMainTitle().c_str(), DifficultyToString(pSteps->GetDifficulty()).c_str() );
// if( pSong->HasBanner() ) feat.pStringToFill = &hs.sName;
// feat.Banner = pSong->GetBannerPath(); feat.grade = hs.grade;
feat.fPercentDP = hs.fPercentDP;
feat.iScore = hs.iScore;
asFeatsOut.push_back( feat ); // XXX: temporary hack
if( pSong->HasBackground() )
feat.Banner = pSong->GetBackgroundPath();
// if( pSong->HasBanner() )
// feat.Banner = pSong->GetBannerPath();
asFeatsOut.push_back( feat );
}
} }
} }
@@ -1183,42 +1191,46 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeats> &asFeatsO
GetFinalEvalStatsAndSongs( stats, vSongs ); GetFinalEvalStatsAndSongs( stats, vSongs );
// Find Machine Records // Find Machine Category Records
for( i=0; i<NUM_RANKING_CATEGORIES; i++ ) for( i=0; i<NUM_RANKING_CATEGORIES; i++ )
{ {
vector<ProfileManager::CategoryData::HighScore> &vHighScores = PROFILEMAN->m_CategoryDatas[PROFILE_SLOT_MACHINE][nt][i].vHighScores; RankingCategory rc = (RankingCategory)i;
for( unsigned j=0; j<vHighScores.size(); j++ ) HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCategoryHighScoreList( nt, rc );
for( unsigned j=0; j<hsl.vHighScores.size(); j++ )
{ {
if( vHighScores[j].sName != RANKING_TO_FILL_IN_MARKER[pn] ) HighScore &hs = hsl.vHighScores[j];
if( hs.sName != RANKING_TO_FILL_IN_MARKER[pn] )
continue; continue;
RankingFeats feat; RankingFeats feat;
feat.Type = RankingFeats::CATEGORY; feat.Type = RankingFeats::CATEGORY;
feat.Feat = ssprintf("MR #%d in Type %c (%d)", j+1, 'A'+i, stats.iMeter[pn] ); feat.Feat = ssprintf("MR #%d in Type %c (%d)", j+1, 'A'+i, stats.iMeter[pn] );
feat.pStringToFill = &vHighScores[j].sName; feat.pStringToFill = &hs.sName;
feat.grade = GRADE_NO_DATA; feat.grade = GRADE_NO_DATA;
feat.iScore = (int) vHighScores[j].iScore; feat.iScore = (int) hs.iScore;
feat.fPercentDP = (float) vHighScores[j].fPercentDP; feat.fPercentDP = (float) hs.fPercentDP;
asFeatsOut.push_back( feat ); asFeatsOut.push_back( feat );
} }
} }
// Find Personal Records // Find Personal Category Records
for( i=0; i<NUM_RANKING_CATEGORIES; i++ ) for( i=0; i<NUM_RANKING_CATEGORIES; i++ )
{ {
vector<ProfileManager::CategoryData::HighScore> &vHighScores = PROFILEMAN->m_CategoryDatas[pn][nt][i].vHighScores; RankingCategory rc = (RankingCategory)i;
for( unsigned j=0; j<vHighScores.size(); j++ ) HighScoreList &hsl = PROFILEMAN->GetProfile(pn)->GetCategoryHighScoreList( nt, rc );
for( unsigned j=0; j<hsl.vHighScores.size(); j++ )
{ {
if( vHighScores[j].sName != RANKING_TO_FILL_IN_MARKER[pn] ) HighScore &hs = hsl.vHighScores[j];
if( hs.sName != RANKING_TO_FILL_IN_MARKER[pn] )
continue; continue;
RankingFeats feat; RankingFeats feat;
feat.Type = RankingFeats::CATEGORY; feat.Type = RankingFeats::CATEGORY;
feat.Feat = ssprintf("PR #%d in Type %c (%d)", j+1, 'A'+i, stats.iMeter[pn] ); feat.Feat = ssprintf("PR #%d in Type %c (%d)", j+1, 'A'+i, stats.iMeter[pn] );
feat.pStringToFill = &vHighScores[j].sName; feat.pStringToFill = &hs.sName;
feat.grade = GRADE_NO_DATA; feat.grade = GRADE_NO_DATA;
feat.iScore = (int) vHighScores[j].iScore; feat.iScore = (int) hs.iScore;
feat.fPercentDP = (float) vHighScores[j].fPercentDP; feat.fPercentDP = (float) hs.fPercentDP;
asFeatsOut.push_back( feat ); asFeatsOut.push_back( feat );
} }
} }
@@ -1238,19 +1250,21 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeats> &asFeatsO
// Find Machine Records // Find Machine Records
{ {
vector<Course::MemCardData::HighScore> &vHighScores = pCourse->m_MemCardDatas[nt][PROFILE_SLOT_MACHINE].vHighScores; Profile* pProfile = PROFILEMAN->GetMachineProfile();
for( unsigned i=0; i<vHighScores.size(); i++ ) HighScoreList &hsl = pProfile->GetCourseHighScoreList( pCourse, nt );
for( unsigned i=0; i<hsl.vHighScores.size(); i++ )
{ {
if( vHighScores[i].sName != RANKING_TO_FILL_IN_MARKER[pn] ) HighScore &hs = hsl.vHighScores[i];
if( hs.sName != RANKING_TO_FILL_IN_MARKER[pn] )
continue; continue;
RankingFeats feat; RankingFeats feat;
feat.Type = RankingFeats::COURSE; feat.Type = RankingFeats::COURSE;
feat.Feat = ssprintf("MR #%d in %s", i+1, pCourse->m_sName.c_str() ); feat.Feat = ssprintf("MR #%d in %s", i+1, pCourse->m_sName.c_str() );
feat.pStringToFill = &vHighScores[i].sName; feat.pStringToFill = &hs.sName;
feat.grade = GRADE_NO_DATA; feat.grade = GRADE_NO_DATA;
feat.iScore = vHighScores[i].iScore; feat.iScore = hs.iScore;
feat.fPercentDP = vHighScores[i].fPercentDP; feat.fPercentDP = hs.fPercentDP;
if( pCourse->HasBanner() ) if( pCourse->HasBanner() )
feat.Banner = pCourse->m_sBannerPath; feat.Banner = pCourse->m_sBannerPath;
asFeatsOut.push_back( feat ); asFeatsOut.push_back( feat );
@@ -1258,20 +1272,23 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeats> &asFeatsO
} }
// Find Personal Records // Find Personal Records
vector<Course::MemCardData::HighScore> &vHighScores = pCourse->m_MemCardDatas[nt][pn].vHighScores; if( PROFILEMAN->IsUsingProfile( pn ) )
{ {
for( unsigned i=0; i<vHighScores.size(); i++ ) Profile* pProfile = PROFILEMAN->GetProfile( pn );
HighScoreList &hsl = pProfile->GetCourseHighScoreList( pCourse, nt );
for( unsigned i=0; i<hsl.vHighScores.size(); i++ )
{ {
if( vHighScores[i].sName != RANKING_TO_FILL_IN_MARKER[pn] ) HighScore& hs = hsl.vHighScores[i];
if( hs.sName != RANKING_TO_FILL_IN_MARKER[pn] )
continue; continue;
RankingFeats feat; RankingFeats feat;
feat.Type = RankingFeats::COURSE; feat.Type = RankingFeats::COURSE;
feat.Feat = ssprintf("PR #%d in %s", i+1, pCourse->m_sName.c_str() ); feat.Feat = ssprintf("PR #%d in %s", i+1, pCourse->m_sName.c_str() );
feat.pStringToFill = &vHighScores[i].sName; feat.pStringToFill = &hs.sName;
feat.grade = GRADE_NO_DATA; feat.grade = GRADE_NO_DATA;
feat.iScore = vHighScores[i].iScore; feat.iScore = hs.iScore;
feat.fPercentDP = vHighScores[i].fPercentDP; feat.fPercentDP = hs.fPercentDP;
if( pCourse->HasBanner() ) if( pCourse->HasBanner() )
feat.Banner = pCourse->m_sBannerPath; feat.Banner = pCourse->m_sBannerPath;
asFeatsOut.push_back( feat ); asFeatsOut.push_back( feat );
+2 -3
View File
@@ -186,7 +186,6 @@ void MusicWheelItem::LoadFromWheelItemData( WheelItemData* pWID )
ASSERT( 0 ); // invalid type ASSERT( 0 ); // invalid type
} }
} }
Steps::MemCardData::HighScore GetHighScoreForDifficulty( const Song *s, const StyleDef *st, ProfileSlot card, Difficulty dc );
void MusicWheelItem::RefreshGrades() void MusicWheelItem::RefreshGrades()
{ {
@@ -207,9 +206,9 @@ void MusicWheelItem::RefreshGrades()
dc = GAMESTATE->m_PreferredDifficulty[p]; dc = GAMESTATE->m_PreferredDifficulty[p];
Grade grade; Grade grade;
if( PROFILEMAN->IsUsingProfile((PlayerNumber)p) ) if( PROFILEMAN->IsUsingProfile((PlayerNumber)p) )
grade = GetHighScoreForDifficulty( data->m_pSong, GAMESTATE->GetCurrentStyleDef(), (ProfileSlot)p, dc ).grade; grade = PROFILEMAN->GetHighScoreForDifficulty( data->m_pSong, GAMESTATE->GetCurrentStyleDef(), (ProfileSlot)p, dc ).grade;
else else
grade = GetHighScoreForDifficulty( data->m_pSong, GAMESTATE->GetCurrentStyleDef(), PROFILE_SLOT_MACHINE, dc ).grade; grade = PROFILEMAN->GetHighScoreForDifficulty( data->m_pSong, GAMESTATE->GetCurrentStyleDef(), PROFILE_SLOT_MACHINE, dc ).grade;
m_GradeDisplay[p].SetGrade( (PlayerNumber)p, grade ); m_GradeDisplay[p].SetGrade( (PlayerNumber)p, grade );
} }
+18 -13
View File
@@ -170,6 +170,11 @@ void PaneDisplay::SetContent( PaneContents c )
} }
} }
const Song *pSong = GAMESTATE->m_pCurSong;
const Steps *pSteps = GAMESTATE->m_pCurNotes[m_PlayerNumber];
StepsType st = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
const Course *pCourse = GAMESTATE->m_pCurCourse;
float val = 0; float val = 0;
CString str; CString str;
switch( c ) switch( c )
@@ -190,21 +195,21 @@ void PaneDisplay::SetContent( PaneContents c )
case SONG_DIFFICULTY_RADAR_FREEZE: val = fRadarValues[RADAR_FREEZE]; break; case SONG_DIFFICULTY_RADAR_FREEZE: val = fRadarValues[RADAR_FREEZE]; break;
case SONG_DIFFICULTY_RADAR_CHAOS: val = fRadarValues[RADAR_CHAOS]; break; case SONG_DIFFICULTY_RADAR_CHAOS: val = fRadarValues[RADAR_CHAOS]; break;
case SONG_PROFILE_HIGH_SCORE: case SONG_PROFILE_HIGH_SCORE:
val = 100.0f * GAMESTATE->m_pCurNotes[m_PlayerNumber]->GetTopScore( PlayerMemCard(m_PlayerNumber) ).fPercentDP; val = 100.0f * PROFILEMAN->GetProfile(m_PlayerNumber)->GetStepsHighScoreList(pSteps).GetTopScore().fPercentDP;
break; break;
case SONG_PROFILE_NUM_PLAYS: case SONG_PROFILE_NUM_PLAYS:
val = (float) GAMESTATE->m_pCurNotes[m_PlayerNumber]->GetNumTimesPlayed( PlayerMemCard(m_PlayerNumber) ); val = (float) PROFILEMAN->GetProfile(m_PlayerNumber)->GetStepsNumTimesPlayed(pSteps);
break; break;
case SONG_MACHINE_HIGH_NAME: /* set val for color */ case SONG_MACHINE_HIGH_NAME: /* set val for color */
case SONG_MACHINE_HIGH_SCORE: case SONG_MACHINE_HIGH_SCORE:
val = 100.0f * GAMESTATE->m_pCurNotes[m_PlayerNumber]->GetTopScore( PROFILE_SLOT_MACHINE ).fPercentDP; val = 100.0f * PROFILEMAN->GetProfile(m_PlayerNumber)->GetStepsHighScoreList(pSteps).GetTopScore().fPercentDP;
break; break;
case SONG_MACHINE_RANK: case SONG_MACHINE_RANK:
{ {
const vector<Song*> best = SONGMAN->GetBestSongs( PROFILE_SLOT_MACHINE ); const vector<Song*> best = SONGMAN->GetBestSongs( PROFILE_SLOT_MACHINE );
val = (float) FindIndex( best.begin(), best.end(), GAMESTATE->m_pCurSong ); val = (float) FindIndex( best.begin(), best.end(), pSong );
val += 1; val += 1;
break; break;
} }
@@ -212,38 +217,38 @@ void PaneDisplay::SetContent( PaneContents c )
case SONG_PROFILE_RANK: case SONG_PROFILE_RANK:
{ {
const vector<Song*> best = SONGMAN->GetBestSongs( PlayerMemCard(m_PlayerNumber) ); const vector<Song*> best = SONGMAN->GetBestSongs( PlayerMemCard(m_PlayerNumber) );
val = (float) FindIndex( best.begin(), best.end(), GAMESTATE->m_pCurSong ); val = (float) FindIndex( best.begin(), best.end(), pSong );
val += 1; val += 1;
break; break;
} }
case COURSE_MACHINE_HIGH_NAME: /* set val for color */ case COURSE_MACHINE_HIGH_NAME: /* set val for color */
case COURSE_MACHINE_HIGH_SCORE: case COURSE_MACHINE_HIGH_SCORE:
val = 100.0f * GAMESTATE->m_pCurCourse->GetTopScore( GAMESTATE->GetCurrentStyleDef()->m_StepsType, PROFILE_SLOT_MACHINE ).fPercentDP; val = 100.0f * PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse,st).GetTopScore().fPercentDP;
break; break;
case COURSE_MACHINE_NUM_PLAYS: case COURSE_MACHINE_NUM_PLAYS:
val = (float) GAMESTATE->m_pCurCourse->GetNumTimesPlayed( PROFILE_SLOT_MACHINE ); val = (float) PROFILEMAN->GetMachineProfile()->GetCourseNumTimesPlayed( pCourse );
break; break;
case COURSE_MACHINE_RANK: case COURSE_MACHINE_RANK:
{ {
const vector<Course*> best = SONGMAN->GetBestCourses( PROFILE_SLOT_MACHINE ); const vector<Course*> best = SONGMAN->GetBestCourses( PROFILE_SLOT_MACHINE );
val = (float) FindIndex( best.begin(), best.end(), GAMESTATE->m_pCurCourse ); val = (float) FindIndex( best.begin(), best.end(), pCourse );
val += 1; val += 1;
} }
break; break;
case COURSE_PROFILE_HIGH_SCORE: case COURSE_PROFILE_HIGH_SCORE:
val = 100.0f * GAMESTATE->m_pCurCourse->GetTopScore( GAMESTATE->GetCurrentStyleDef()->m_StepsType, PlayerMemCard(m_PlayerNumber) ).fPercentDP; val = 100.0f * PROFILEMAN->GetProfile(m_PlayerNumber)->GetCourseHighScoreList(pCourse,st).GetTopScore().fPercentDP;
break; break;
case COURSE_PROFILE_NUM_PLAYS: case COURSE_PROFILE_NUM_PLAYS:
val = (float) GAMESTATE->m_pCurCourse->GetNumTimesPlayed( PlayerMemCard(m_PlayerNumber) ); val = (float) PROFILEMAN->GetProfile(m_PlayerNumber)->GetCourseNumTimesPlayed( pCourse );
break; break;
case COURSE_PROFILE_RANK: case COURSE_PROFILE_RANK:
const vector<Course*> best = SONGMAN->GetBestCourses( PlayerMemCard(m_PlayerNumber) ); const vector<Course*> best = SONGMAN->GetBestCourses( PlayerMemCard(m_PlayerNumber) );
val = (float) FindIndex( best.begin(), best.end(), GAMESTATE->m_pCurCourse ); val = (float) FindIndex( best.begin(), best.end(), pCourse );
val += 1; val += 1;
break; break;
}; };
@@ -265,10 +270,10 @@ void PaneDisplay::SetContent( PaneContents c )
switch( c ) switch( c )
{ {
case SONG_MACHINE_HIGH_NAME: case SONG_MACHINE_HIGH_NAME:
str = GAMESTATE->m_pCurNotes[m_PlayerNumber]->GetTopScore( PROFILE_SLOT_MACHINE ).sName; str = PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSteps).GetTopScore().sName;
break; break;
case COURSE_MACHINE_HIGH_NAME: case COURSE_MACHINE_HIGH_NAME:
str = GAMESTATE->m_pCurCourse->GetTopScore( GAMESTATE->GetCurrentStyleDef()->m_StepsType, PROFILE_SLOT_MACHINE ).sName; str = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse, st).GetTopScore().sName;
break; break;
case SONG_MACHINE_HIGH_SCORE: case SONG_MACHINE_HIGH_SCORE:
+168 -2
View File
@@ -1,7 +1,7 @@
#include "global.h" #include "global.h"
/* /*
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Class: ProfileManager Class: Profile
Desc: See header. Desc: See header.
@@ -10,8 +10,64 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
*/ */
#include "ProfileManager.h" #include "Profile.h"
#include "RageUtil.h" #include "RageUtil.h"
#include "PrefsManager.h"
bool HighScore::operator>=( const HighScore& other ) const
{
/* Make sure we treat AAAA as higher than AAA, even though the score
* is the same.
*
* XXX: Isn't it possible to beat the grade but not beat the score, since
* grading and scores are on completely different systems? Should we be
* checking for these completely separately? */
if( PREFSMAN->m_bPercentageScoring )
{
if( fPercentDP == other.fPercentDP )
return grade >= other.grade;
else
return fPercentDP >= other.fPercentDP;
}
else
{
if( iScore == other.iScore )
return grade >= other.grade;
else
return iScore >= other.iScore;
}
}
void HighScoreList::AddHighScore( HighScore hs, int &iIndexOut )
{
int i;
for( i=0; i<(int)vHighScores.size(); i++ )
{
if( hs >= vHighScores[i] )
break;
}
if( i < NUM_RANKING_LINES )
{
vHighScores.insert( vHighScores.begin()+i, hs );
iIndexOut = i;
if( vHighScores.size() > unsigned(NUM_RANKING_LINES) )
vHighScores.erase( vHighScores.begin()+NUM_RANKING_LINES, vHighScores.end() );
}
}
const HighScore& HighScoreList::GetTopScore() const
{
if( vHighScores.empty() )
{
static HighScore hs;
hs = HighScore();
return hs;
}
else
{
return vHighScores[0];
}
}
CString Profile::GetDisplayName() CString Profile::GetDisplayName()
{ {
@@ -40,3 +96,113 @@ int Profile::GetTotalNumSongsPlayed()
} }
//
// Steps high scores
//
void Profile::AddStepsHighScore( const Steps* pSteps, HighScore hs, int &iIndexOut )
{
std::map<const Steps*,HighScoresForASteps>::iterator iter = m_StepsHighScores.find( pSteps );
if( iter == m_StepsHighScores.end() )
m_StepsHighScores[pSteps].hs.AddHighScore( hs, iIndexOut ); // operator[] inserts into map
else
iter->second.hs.AddHighScore( hs, iIndexOut );
}
HighScoreList& Profile::GetStepsHighScoreList( const Steps* pSteps )
{
std::map<const Steps*,HighScoresForASteps>::iterator iter = m_StepsHighScores.find( pSteps );
if( iter == m_StepsHighScores.end() )
return m_StepsHighScores[pSteps].hs; // operator[] inserts into map
else
return iter->second.hs;
}
int Profile::GetStepsNumTimesPlayed( const Steps* pSteps ) const
{
std::map<const Steps*,HighScoresForASteps>::const_iterator iter = m_StepsHighScores.find( pSteps );
if( iter == m_StepsHighScores.end() )
{
return 0;
}
else
{
int iTotalNumTimesPlayed = 0;
for( unsigned st = 0; st < NUM_STEPS_TYPES; ++st )
iTotalNumTimesPlayed += iter->second.hs.iNumTimesPlayed;
return iTotalNumTimesPlayed;
}
}
void Profile::IncrementStepsPlayCount( const Steps* pSteps )
{
GetStepsHighScoreList(pSteps).iNumTimesPlayed++;
}
//
// Course high scores
//
void Profile::AddCourseHighScore( const Course* pCourse, StepsType st, HighScore hs, int &iIndexOut )
{
std::map<const Course*,HighScoresForACourse>::iterator iter = m_CourseHighScores.find( pCourse );
if( iter == m_CourseHighScores.end() )
m_CourseHighScores[pCourse].hs[st].AddHighScore( hs, iIndexOut ); // operator[] inserts into map
else
iter->second.hs[st].AddHighScore( hs, iIndexOut );
}
HighScoreList& Profile::GetCourseHighScoreList( const Course* pCourse, StepsType st )
{
std::map<const Course*,HighScoresForACourse>::iterator iter = m_CourseHighScores.find( pCourse );
if( iter == m_CourseHighScores.end() )
return m_CourseHighScores[pCourse].hs[st]; // operator[] inserts into map
else
return iter->second.hs[st];
}
int Profile::GetCourseNumTimesPlayed( const Course* pCourse ) const
{
std::map<const Course*,HighScoresForACourse>::const_iterator iter = m_CourseHighScores.find( pCourse );
if( iter == m_CourseHighScores.end() )
{
return 0;
}
else
{
int iTotalNumTimesPlayed = 0;
for( unsigned st = 0; st < NUM_STEPS_TYPES; ++st )
iTotalNumTimesPlayed += iter->second.hs[st].iNumTimesPlayed;
return iTotalNumTimesPlayed;
}
}
void Profile::IncrementCoursePlayCount( const Course* pCourse, StepsType st )
{
GetCourseHighScoreList(pCourse,st).iNumTimesPlayed++;
}
//
// Category high scores
//
void Profile::AddCategoryHighScore( StepsType st, RankingCategory rc, HighScore hs, int &iIndexOut )
{
m_CategoryHighScores[st][rc].AddHighScore( hs, iIndexOut );
}
HighScoreList& Profile::GetCategoryHighScoreList( StepsType st, RankingCategory rc )
{
return m_CategoryHighScores[st][rc];
}
int Profile::GetCategoryNumTimesPlayed( RankingCategory rc ) const
{
int iNumTimesPlayed = 0;
for( int st=0; st<NUM_STEPS_TYPES; st++ )
iNumTimesPlayed += m_CategoryHighScores[st][rc].iNumTimesPlayed;
return iNumTimesPlayed;
}
void Profile::IncrementCategoryPlayCount( StepsType st, RankingCategory rc )
{
m_CategoryHighScores[st][rc].iNumTimesPlayed++;
}
+84
View File
@@ -14,6 +14,47 @@
#include "GameConstantsAndTypes.h" #include "GameConstantsAndTypes.h"
#include "Style.h" #include "Style.h"
#include "Grade.h"
#include <map>
class Steps;
class Course;
struct HighScore
{
CString sName;
Grade grade;
int iScore;
float fPercentDP;
float fSurviveTime;
HighScore()
{
grade = GRADE_NO_DATA;
iScore = 0;
fPercentDP = 0;
fSurviveTime = 0;
}
bool operator>=( const HighScore& other ) const;
};
struct HighScoreList
{
int iNumTimesPlayed;
vector<HighScore> vHighScores;
HighScoreList()
{
iNumTimesPlayed = 0;
}
void AddHighScore( HighScore hs, int &iIndexOut );
const HighScore& GetTopScore() const;
};
struct Profile struct Profile
{ {
@@ -62,6 +103,49 @@ struct Profile
int m_iNumSongsPlayedByStyle[NUM_STYLES]; int m_iNumSongsPlayedByStyle[NUM_STYLES];
int m_iNumSongsPlayedByDifficulty[NUM_DIFFICULTIES]; int m_iNumSongsPlayedByDifficulty[NUM_DIFFICULTIES];
int m_iNumSongsPlayedByMeter[MAX_METER+1]; int m_iNumSongsPlayedByMeter[MAX_METER+1];
//
// Steps high scores
//
struct HighScoresForASteps
{
HighScoreList hs;
};
std::map<const Steps*,HighScoresForASteps> m_StepsHighScores;
void AddStepsHighScore( const Steps* pSteps, HighScore hs, int &iIndexOut );
HighScoreList& GetStepsHighScoreList( const Steps* pSteps );
int GetStepsNumTimesPlayed( const Steps* pSteps ) const;
void IncrementStepsPlayCount( const Steps* pSteps );
//
// Course high scores
//
// struct was a typedef'd array of HighScores, but VC6 freaks out
// in processing the templates for map::operator[].
struct HighScoresForACourse
{
HighScoreList hs[NUM_STEPS_TYPES];
};
std::map<const Course*,HighScoresForACourse> m_CourseHighScores;
void AddCourseHighScore( const Course* pCourse, StepsType st, HighScore hs, int &iIndexOut );
HighScoreList& GetCourseHighScoreList( const Course* pCourse, StepsType st );
int GetCourseNumTimesPlayed( const Course* pCourse ) const;
void IncrementCoursePlayCount( const Course* pCourse, StepsType st );
//
// Category high scores
//
HighScoreList m_CategoryHighScores[NUM_STEPS_TYPES][NUM_RANKING_CATEGORIES];
void AddCategoryHighScore( StepsType st, RankingCategory rc, HighScore hs, int &iIndexOut );
HighScoreList& GetCategoryHighScoreList( StepsType st, RankingCategory rc );
int GetCategoryNumTimesPlayed( RankingCategory rc ) const;
void IncrementCategoryPlayCount( StepsType st, RankingCategory rc );
}; };
File diff suppressed because it is too large Load Diff
+37 -26
View File
@@ -17,6 +17,9 @@
#include "Style.h" #include "Style.h"
#include "Profile.h" #include "Profile.h"
class Song;
class StyleDef;
class ProfileManager class ProfileManager
{ {
public: public:
@@ -38,7 +41,22 @@ public:
void SaveMachineProfile(); void SaveMachineProfile();
bool IsUsingProfile( PlayerNumber pn ) { return !m_sProfileDir[pn].empty(); } bool IsUsingProfile( PlayerNumber pn ) { return !m_sProfileDir[pn].empty(); }
bool IsUsingProfile( ProfileSlot slot )
{
switch( slot )
{
case PROFILE_SLOT_PLAYER_1:
case PROFILE_SLOT_PLAYER_2:
return !m_sProfileDir[slot].empty();
case PROFILE_SLOT_MACHINE:
return true;
default:
ASSERT(0);
return false;
}
}
Profile* GetProfile( PlayerNumber pn ); Profile* GetProfile( PlayerNumber pn );
Profile* GetProfile( ProfileSlot slot );
CString GetProfileDir( ProfileSlot slot ); CString GetProfileDir( ProfileSlot slot );
Profile* GetMachineProfile() { return &m_MachineProfile; } Profile* GetMachineProfile() { return &m_MachineProfile; }
@@ -53,36 +71,29 @@ public:
void InitMachineScoresFromDisk(); void InitMachineScoresFromDisk();
void SaveMachineScoresToDisk(); void SaveMachineScoresToDisk();
struct CategoryData //
{ // Song stats
struct HighScore //
{ int GetSongNumTimesPlayed( Song* pSong, ProfileSlot card ) const;
CString sName; bool IsSongNew( Song* pSong ) const { return GetSongNumTimesPlayed(pSong,PROFILE_SLOT_MACHINE)==0; }
int iScore; void AddStepsHighScore( const Steps* pSteps, PlayerNumber pn, HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut );
float fPercentDP; void IncrementStepsPlayCount( const Steps* pSteps, PlayerNumber pn );
HighScore GetHighScoreForDifficulty( const Song *s, const StyleDef *st, ProfileSlot slot, Difficulty dc );
HighScore() //
{ // Course stats
iScore = 0; //
fPercentDP = 0; void AddCourseHighScore( const Course* pCourse, StepsType st, PlayerNumber pn, HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut );
} void IncrementCoursePlayCount( const Course* pCourse, StepsType st, PlayerNumber pn );
bool operator>=( const HighScore& other ) const; //
}; // Category stats
vector<HighScore> vHighScores; //
void AddCategoryHighScore( StepsType nt, RankingCategory rc, PlayerNumber pn, HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut );
void IncrementCategoryPlayCount( StepsType nt, RankingCategory rc, PlayerNumber pn );
void AddHighScore( HighScore hs, int &iIndexOut );
} m_CategoryDatas[NUM_PROFILE_SLOTS][NUM_STEPS_TYPES][NUM_RANKING_CATEGORIES]; // void ReadSM300NoteScores();
void AddHighScore( StepsType nt, RankingCategory rc, PlayerNumber pn, CategoryData::HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut )
{
hs.sName = RANKING_TO_FILL_IN_MARKER[pn];
m_CategoryDatas[pn][nt][rc].AddHighScore( hs, iPersonalIndexOut );
m_CategoryDatas[PROFILE_SLOT_MACHINE][nt][rc].AddHighScore( hs, iMachineIndexOut );
}
void ReadSM300NoteScores();
void ReadSongScoresFromDir( CString sDir, ProfileSlot slot ); void ReadSongScoresFromDir( CString sDir, ProfileSlot slot );
void ReadCourseScoresFromDir( CString sDir, ProfileSlot slot ); void ReadCourseScoresFromDir( CString sDir, ProfileSlot slot );
void ReadCategoryScoresFromDir( CString sDir, ProfileSlot slot ); void ReadCategoryScoresFromDir( CString sDir, ProfileSlot slot );
+11 -17
View File
@@ -866,6 +866,14 @@ void ScreenEvaluation::CommitScores( const StageStats &stageStats, int iPersonal
// depends on if this is a course or not ... it's handled // depends on if this is a course or not ... it's handled
// below in the switch // below in the switch
HighScore hs;
hs.grade = stageStats.GetGrade( (PlayerNumber)p );
hs.iScore = stageStats.iScore[p];
hs.fPercentDP = stageStats.GetPercentDancePoints( (PlayerNumber)p );
hs.fSurviveTime = stageStats.fAliveSeconds[p];
StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
switch( m_Type ) switch( m_Type )
{ {
case stage: case stage:
@@ -876,12 +884,8 @@ void ScreenEvaluation::CommitScores( const StageStats &stageStats, int iPersonal
ASSERT( GAMESTATE->m_pCurNotes[p] ); ASSERT( GAMESTATE->m_pCurNotes[p] );
Steps::MemCardData::HighScore hs;
hs.grade = stageStats.GetGrade( (PlayerNumber)p );
hs.iScore = stageStats.iScore[p] + stageStats.iBonus[p];
hs.fPercentDP = stageStats.GetPercentDancePoints( (PlayerNumber)p );
if( hs.fPercentDP > PREFSMAN->m_fMinPercentageForHighScore ) if( hs.fPercentDP > PREFSMAN->m_fMinPercentageForHighScore )
GAMESTATE->m_pCurNotes[p]->AddHighScore( (PlayerNumber)p, hs, iPersonalHighScoreIndex[p], iMachineHighScoreIndex[p] ); PROFILEMAN->AddStepsHighScore( GAMESTATE->m_pCurNotes[p], (PlayerNumber)p, hs, iPersonalHighScoreIndex[p], iMachineHighScoreIndex[p] );
} }
break; break;
@@ -891,16 +895,11 @@ void ScreenEvaluation::CommitScores( const StageStats &stageStats, int iPersonal
if( stageStats.bFailed[p] ) if( stageStats.bFailed[p] )
continue; continue;
StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
float fAverageMeter = stageStats.iMeter[p] / (float)PREFSMAN->m_iNumArcadeStages; float fAverageMeter = stageStats.iMeter[p] / (float)PREFSMAN->m_iNumArcadeStages;
rc[p] = AverageMeterToRankingCategory( fAverageMeter ); rc[p] = AverageMeterToRankingCategory( fAverageMeter );
ProfileManager::CategoryData::HighScore hs;
hs.iScore = stageStats.iScore[p];
hs.fPercentDP = stageStats.GetPercentDancePoints( (PlayerNumber)p );
if( hs.fPercentDP > PREFSMAN->m_fMinPercentageForHighScore ) if( hs.fPercentDP > PREFSMAN->m_fMinPercentageForHighScore )
PROFILEMAN->AddHighScore( nt, rc[p], (PlayerNumber)p, hs, iPersonalHighScoreIndex[p], iMachineHighScoreIndex[p] ); PROFILEMAN->AddCategoryHighScore( nt, rc[p], (PlayerNumber)p, hs, iPersonalHighScoreIndex[p], iMachineHighScoreIndex[p] );
} }
break; break;
@@ -914,13 +913,8 @@ void ScreenEvaluation::CommitScores( const StageStats &stageStats, int iPersonal
if( stageStats.bFailed[p] && pCourse->IsNonstop() ) if( stageStats.bFailed[p] && pCourse->IsNonstop() )
continue; continue;
StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
Course::MemCardData::HighScore hs;
hs.iScore = stageStats.iScore[p];
hs.fPercentDP = stageStats.GetPercentDancePoints( (PlayerNumber)p );
hs.fSurviveTime = stageStats.fAliveSeconds[p];
if( hs.fPercentDP > PREFSMAN->m_fMinPercentageForHighScore ) if( hs.fPercentDP > PREFSMAN->m_fMinPercentageForHighScore )
pCourse->AddHighScore( nt, (PlayerNumber)p, hs, iPersonalHighScoreIndex[p], iMachineHighScoreIndex[p] ); PROFILEMAN->AddCourseHighScore( pCourse, nt, (PlayerNumber)p, hs, iPersonalHighScoreIndex[p], iMachineHighScoreIndex[p] );
} }
} }
break; break;
+4 -9
View File
@@ -173,10 +173,9 @@ ScreenGameplay::ScreenGameplay( CString sName, bool bDemonstration ) : Screen("S
const StepsType st = GAMESTATE->GetCurrentStyleDef()->m_StepsType; const StepsType st = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
/* Increment the play count. */ /* Increment the play count. */
if( !m_bDemonstration ) if( !m_bDemonstration )
{ for( p=0; p<NUM_PLAYERS; p++ )
for( int mc = 0; mc < NUM_PROFILE_SLOTS; ++mc ) if( GAMESTATE->IsPlayerEnabled(p) )
++GAMESTATE->m_pCurCourse->m_MemCardDatas[st][mc].iNumTimesPlayed; PROFILEMAN->IncrementCoursePlayCount( GAMESTATE->m_pCurCourse, st, (PlayerNumber)p );
}
for( int p=0; p<NUM_PLAYERS; p++ ) for( int p=0; p<NUM_PLAYERS; p++ )
{ {
@@ -872,11 +871,7 @@ void ScreenGameplay::LoadNextSong()
/* Increment the play count even if the player fails. (It's still popular, /* Increment the play count even if the player fails. (It's still popular,
* even if the people playing it aren't good at it.) */ * even if the people playing it aren't good at it.) */
if( !m_bDemonstration ) if( !m_bDemonstration )
{ PROFILEMAN->IncrementStepsPlayCount( GAMESTATE->m_pCurNotes[p], (PlayerNumber)p );
for( int mc = 0; mc < NUM_PROFILE_SLOTS; ++mc )
++GAMESTATE->m_pCurNotes[p]->m_MemCardDatas[mc].iNumTimesPlayed;
}
m_textPlayerOptions[p].SetText( GAMESTATE->m_PlayerOptions[p].GetString() ); m_textPlayerOptions[p].SetText( GAMESTATE->m_PlayerOptions[p].GetString() );
+4 -4
View File
@@ -81,18 +81,18 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
st.iPossibleDancePoints[i] = 1000; st.iPossibleDancePoints[i] = 1000;
st.iActualDancePoints[i] = 985; st.iActualDancePoints[i] = 985;
Steps::MemCardData::HighScore hs; HighScore hs;
hs.grade = GRADE_TIER_3; hs.grade = GRADE_TIER_3;
hs.iScore = 42; hs.iScore = 42;
int a, b; int a, b;
GAMESTATE->m_pCurNotes[i]->AddHighScore( (PlayerNumber)i, hs, a, b ); PROFILEMAN->AddStepsHighScore( GAMESTATE->m_pCurNotes[i], (PlayerNumber)i, hs, a, b );
if( i == 0 ) if( i == 0 )
{ {
ProfileManager::CategoryData::HighScore hs; HighScore hs;
hs.iScore = 1234567; hs.iScore = 1234567;
StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType; StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
PROFILEMAN->AddHighScore( nt, RANKING_A, (PlayerNumber)i, hs, a, b ); PROFILEMAN->AddCategoryHighScore( nt, RANKING_A, (PlayerNumber)i, hs, a, b );
} }
} }
+24 -16
View File
@@ -671,12 +671,13 @@ float ScreenRanking::SetPage( PageToShow pts )
for( int l=0; l<NUM_RANKING_LINES; l++ ) for( int l=0; l<NUM_RANKING_LINES; l++ )
{ {
ProfileManager::CategoryData::HighScore hs; HighScoreList& hsl = PROFILEMAN->GetMachineProfile()->GetCategoryHighScoreList(pts.nt,pts.category);
HighScore hs;
bool bRecentHighScore = false; bool bRecentHighScore = false;
if( l < (int)PROFILEMAN->m_CategoryDatas[PROFILE_SLOT_MACHINE][pts.nt][pts.category].vHighScores.size() ) if( l < (int)hsl.vHighScores.size() )
{ {
hs = PROFILEMAN->m_CategoryDatas[PROFILE_SLOT_MACHINE][pts.nt][pts.category].vHighScores[l]; hs = hsl.vHighScores[l];
CString *psName = &PROFILEMAN->m_CategoryDatas[PROFILE_SLOT_MACHINE][pts.nt][pts.category].vHighScores[l].sName; CString *psName = &hsl.vHighScores[l].sName;
bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end(); bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end();
} }
else else
@@ -710,20 +711,22 @@ float ScreenRanking::SetPage( PageToShow pts )
m_Banner.LoadFromCourse( pts.pCourse ); m_Banner.LoadFromCourse( pts.pCourse );
m_textStepsType.SetText( GameManager::NotesTypeToString(pts.nt) ); m_textStepsType.SetText( GameManager::NotesTypeToString(pts.nt) );
const HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList( pts.pCourse, pts.nt );
for( int l=0; l<NUM_RANKING_LINES; l++ ) for( int l=0; l<NUM_RANKING_LINES; l++ )
{ {
Course::MemCardData::HighScore hs; HighScore hs;
bool bRecentHighScore = false; bool bRecentHighScore = false;
if( l < (int)pts.pCourse->m_MemCardDatas[pts.nt][PROFILE_SLOT_MACHINE].vHighScores.size() ) if( l < (int)hsl.vHighScores.size() )
{ {
hs = pts.pCourse->m_MemCardDatas[pts.nt][PROFILE_SLOT_MACHINE].vHighScores[l]; hs = hsl.vHighScores[l];
CString *psName = &pts.pCourse->m_MemCardDatas[pts.nt][PROFILE_SLOT_MACHINE].vHighScores[l].sName; const CString *psName = &hsl.vHighScores[l].sName;
bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end(); bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end();
} }
else else
{ {
hs.sName = NO_SCORE_NAME; hs.sName = NO_SCORE_NAME;
} }
if( hs.sName.empty() ) if( hs.sName.empty() )
hs.sName = EMPTY_SCORE_NAME; hs.sName = EMPTY_SCORE_NAME;
@@ -778,12 +781,13 @@ float ScreenRanking::SetPage( PageToShow pts )
} }
else else
{ {
Steps::MemCardData::HighScore hs; HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSteps);
HighScore hs = hsl.GetTopScore();
bool bRecentHighScore = false; bool bRecentHighScore = false;
if( !pSteps->m_MemCardDatas[PROFILE_SLOT_MACHINE].vHighScores.empty() ) if( !hsl.vHighScores.empty() )
{ {
hs = pSteps->m_MemCardDatas[PROFILE_SLOT_MACHINE].vHighScores[0]; hs = hsl.GetTopScore();
const CString *psName = &pSteps->m_MemCardDatas[PROFILE_SLOT_MACHINE].vHighScores[0].sName; const CString *psName = &hsl.GetTopScore().sName;
bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end(); bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end();
} }
else else
@@ -812,16 +816,20 @@ float ScreenRanking::SetPage( PageToShow pts )
const Course* pCourse = pCourseScoreRowItem->m_pCourse; const Course* pCourse = pCourseScoreRowItem->m_pCourse;
pCourseScoreRowItem->m_textSongTitle.SetText( pCourse->m_sName ); pCourseScoreRowItem->m_textSongTitle.SetText( pCourse->m_sName );
const HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList( pCourse, pts.nt );
for( int d=0; d<NUM_COURSE_DIFFICULTIES; d++ ) for( int d=0; d<NUM_COURSE_DIFFICULTIES; d++ )
{ {
//
// FIXME: have separate high scores for each difficulty
//
BitmapText* pTextStepsScore = &pCourseScoreRowItem->m_textStepsScore[d]; BitmapText* pTextStepsScore = &pCourseScoreRowItem->m_textStepsScore[d];
Course::MemCardData::HighScore hs; HighScore hs;
bool bRecentHighScore = false; bool bRecentHighScore = false;
if( !pCourse->m_MemCardDatas[pts.nt][PROFILE_SLOT_MACHINE].vHighScores.empty() ) if( !hsl.vHighScores.empty() )
{ {
hs = pCourse->m_MemCardDatas[pts.nt][PROFILE_SLOT_MACHINE].vHighScores[0]; hs = hsl.vHighScores[0];
const CString *psName = &pCourse->m_MemCardDatas[pts.nt][PROFILE_SLOT_MACHINE].vHighScores[0].sName; const CString *psName = &hsl.GetTopScore().sName;
bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end(); bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end();
} }
else else
+8 -9
View File
@@ -416,21 +416,23 @@ void ScreenSelectCourse::AfterCourseChange()
{ {
const StepsType &st = GAMESTATE->GetCurrentStyleDef()->m_StepsType; const StepsType &st = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
int mc = PROFILE_SLOT_MACHINE; Profile* pProfile;
if( PROFILEMAN->IsUsingProfile( (PlayerNumber)p ) ) if( PROFILEMAN->IsUsingProfile( (PlayerNumber)p ) )
mc = p; pProfile = PROFILEMAN->GetProfile((PlayerNumber)p);
else
pProfile = PROFILEMAN->GetMachineProfile();
/* Courses are scored by survive time, dance points, /* Courses are scored by survive time, dance points,
* percent, and normal score. Every last mother will * percent, and normal score. Every last mother will
* have an opinion on which should be used here for * have an opinion on which should be used here for
* each of oni, endless, nonstop -- * each of oni, endless, nonstop --
* should this choice be an option or a metric? */ * should this choice be an option or a metric? */
const HighScoreList& hsl = pProfile->GetCourseHighScoreList( pCourse, st );
if ( pCourse->IsOni() || pCourse->IsEndless() ) if ( pCourse->IsOni() || pCourse->IsEndless() )
{ {
/* use survive time */ /* use survive time */
float fSurviveTime = 0.0f; float fSurviveTime = hsl.GetTopScore().fSurviveTime;
if( !pCourse->m_MemCardDatas[st][mc].vHighScores.empty() )
fSurviveTime = pCourse->m_MemCardDatas[st][mc].vHighScores[0].fSurviveTime;
CString s = SecondsToTime(fSurviveTime); CString s = SecondsToTime(fSurviveTime);
/* dim the inital unsignificant digits */ /* dim the inital unsignificant digits */
@@ -452,10 +454,7 @@ void ScreenSelectCourse::AfterCourseChange()
else /* pCourse->IsNonStop() */ else /* pCourse->IsNonStop() */
{ {
/* use score */ /* use score */
int iScore = 0; int iScore = hsl.GetTopScore().iScore;
if( !pCourse->m_MemCardDatas[st][mc].vHighScores.empty() )
iScore = pCourse->m_MemCardDatas[st][mc].vHighScores[0].iScore;
m_HighScore[p].SetText( ssprintf("%*i", NUM_SCORE_DIGITS, iScore) ); m_HighScore[p].SetText( ssprintf("%*i", NUM_SCORE_DIGITS, iScore) );
} }
+9 -15
View File
@@ -1008,7 +1008,7 @@ void ScreenSelectMusic::MenuStart( PlayerNumber pn )
switch( m_MusicWheel.GetSelectedType() ) switch( m_MusicWheel.GetSelectedType() )
{ {
case TYPE_SONG: { case TYPE_SONG: {
const bool bIsNew = m_MusicWheel.GetSelectedSong()->IsNew(); const bool bIsNew = PROFILEMAN->IsSongNew( m_MusicWheel.GetSelectedSong() );
bool bIsHard = false; bool bIsHard = false;
for( int p=0; p<NUM_PLAYERS; p++ ) for( int p=0; p<NUM_PLAYERS; p++ )
{ {
@@ -1133,27 +1133,21 @@ void ScreenSelectMusic::AfterNotesChange( PlayerNumber pn )
m_iSelection[pn] = clamp( m_iSelection[pn], 0, int(m_arrayNotes.size()-1) ); // bounds clamping m_iSelection[pn] = clamp( m_iSelection[pn], 0, int(m_arrayNotes.size()-1) ); // bounds clamping
Steps* pNotes = m_arrayNotes.empty()? NULL: m_arrayNotes[m_iSelection[pn]]; Steps* pSteps = m_arrayNotes.empty()? NULL: m_arrayNotes[m_iSelection[pn]];
GAMESTATE->m_pCurNotes[pn] = pNotes; GAMESTATE->m_pCurNotes[pn] = pSteps;
// m_BPMDisplay.SetZoomY( 0 ); // m_BPMDisplay.SetZoomY( 0 );
// m_BPMDisplay.BeginTweening( 0.2f ); // m_BPMDisplay.BeginTweening( 0.2f );
// m_BPMDisplay.SetZoomY( 1.2f ); // m_BPMDisplay.SetZoomY( 1.2f );
if( pNotes ) if( pSteps )
{ {
int iScore = 0; int iScore = 0;
if( PROFILEMAN->IsUsingProfile(pn) ) if( PROFILEMAN->IsUsingProfile(pn) )
{ iScore = PROFILEMAN->GetProfile(pn)->GetStepsHighScoreList(pSteps).GetTopScore().iScore;
if( !pNotes->m_MemCardDatas[pn].vHighScores.empty() )
iScore = pNotes->m_MemCardDatas[pn].vHighScores[0].iScore;
}
else else
{ iScore = PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSteps).GetTopScore().iScore;
if( !pNotes->m_MemCardDatas[PROFILE_SLOT_MACHINE].vHighScores.empty() )
iScore = pNotes->m_MemCardDatas[PROFILE_SLOT_MACHINE].vHighScores[0].iScore;
}
m_textHighScore[pn].SetText( ssprintf("%*i", NUM_SCORE_DIGITS, iScore) ); m_textHighScore[pn].SetText( ssprintf("%*i", NUM_SCORE_DIGITS, iScore) );
} }
else else
@@ -1161,8 +1155,8 @@ void ScreenSelectMusic::AfterNotesChange( PlayerNumber pn )
m_textHighScore[pn].SetText( ssprintf("%*i", NUM_SCORE_DIGITS, 0) ); m_textHighScore[pn].SetText( ssprintf("%*i", NUM_SCORE_DIGITS, 0) );
} }
m_DifficultyIcon[pn].SetFromNotes( pn, pNotes ); m_DifficultyIcon[pn].SetFromNotes( pn, pSteps );
if( pNotes && pNotes->IsAutogen() ) if( pSteps && pSteps->IsAutogen() )
{ {
m_AutoGenIcon[pn].SetEffectDiffuseShift(); m_AutoGenIcon[pn].SetEffectDiffuseShift();
} }
@@ -1174,7 +1168,7 @@ void ScreenSelectMusic::AfterNotesChange( PlayerNumber pn )
m_DifficultyMeter[pn].SetFromGameState( pn ); m_DifficultyMeter[pn].SetFromGameState( pn );
if( SHOW_DIFFICULTY_LIST ) if( SHOW_DIFFICULTY_LIST )
m_DifficultyList.SetFromGameState(); m_DifficultyList.SetFromGameState();
m_GrooveRadar.SetFromNotes( pn, pNotes ); m_GrooveRadar.SetFromNotes( pn, pSteps );
m_MusicWheel.NotesChanged( pn ); m_MusicWheel.NotesChanged( pn );
if( SHOW_PANES ) if( SHOW_PANES )
m_PaneDisplay[pn].SetFromGameState(); m_PaneDisplay[pn].SetFromGameState();
+6 -34
View File
@@ -34,6 +34,7 @@
#include "RageFileManager.h" #include "RageFileManager.h"
#include "NoteDataUtil.h" #include "NoteDataUtil.h"
#include "SDL_utils.h" #include "SDL_utils.h"
#include "ProfileManager.h"
#include "NotesLoaderSM.h" #include "NotesLoaderSM.h"
#include "NotesLoaderDWI.h" #include "NotesLoaderDWI.h"
@@ -860,7 +861,8 @@ void Song::GetSteps( vector<Steps*>& arrayAddTo, StepsType nt, Difficulty dc, in
if( !Max ) if( !Max )
break; break;
if( m_apNotes[i]->m_StepsType != nt ) continue; if( nt != STEPS_TYPE_INVALID && m_apNotes[i]->m_StepsType != nt )
continue;
if( dc != DIFFICULTY_INVALID && dc != m_apNotes[i]->GetDifficulty() ) if( dc != DIFFICULTY_INVALID && dc != m_apNotes[i]->GetDifficulty() )
continue; continue;
if( iMeterLow != -1 && iMeterLow > m_apNotes[i]->GetMeter() ) if( iMeterLow != -1 && iMeterLow > m_apNotes[i]->GetMeter() )
@@ -1114,28 +1116,6 @@ void Song::RemoveAutoGenNotes()
} }
} }
Steps::MemCardData::HighScore GetHighScoreForDifficulty( const Song *s, const StyleDef *st, ProfileSlot card, Difficulty dc )
{
// return max grade of notes in difficulty class
vector<Steps*> aNotes;
s->GetSteps( aNotes, st->m_StepsType );
SortNotesArrayByDifficulty( aNotes );
Steps* pSteps = s->GetStepsByDifficulty( st->m_StepsType, dc );
if( pSteps )
return pSteps->GetTopScore(card);
else
return Steps::MemCardData::HighScore();
}
bool Song::IsNew() const
{
return GetNumTimesPlayed(PROFILE_SLOT_MACHINE) == 0;
}
bool Song::IsEasy( StepsType nt ) const bool Song::IsEasy( StepsType nt ) const
{ {
const Steps* pHardNotes = GetStepsByDifficulty( nt, DIFFICULTY_HARD ); const Steps* pHardNotes = GetStepsByDifficulty( nt, DIFFICULTY_HARD );
@@ -1387,10 +1367,10 @@ bool CompareSongPointersBySortValueDescending(const Song *pSong1, const Song *pS
return song_sort_val[pSong1] > song_sort_val[pSong2]; return song_sort_val[pSong1] > song_sort_val[pSong2];
} }
void SortSongPointerArrayByMostPlayed( vector<Song*> &arraySongPointers, ProfileSlot card ) void SortSongPointerArrayByMostPlayed( vector<Song*> &arraySongPointers, ProfileSlot slot )
{ {
for(unsigned i = 0; i < arraySongPointers.size(); ++i) for(unsigned i = 0; i < arraySongPointers.size(); ++i)
song_sort_val[arraySongPointers[i]] = ssprintf("%9i", arraySongPointers[i]->GetNumTimesPlayed(card)); song_sort_val[arraySongPointers[i]] = ssprintf("%9i", PROFILEMAN->GetSongNumTimesPlayed(arraySongPointers[i],slot));
stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortValueDescending ); stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortValueDescending );
song_sort_val.clear(); song_sort_val.clear();
} }
@@ -1553,14 +1533,6 @@ bool Song::HasBackground() const {return m_sBackgroundFile != "" && IsAFile(G
bool Song::HasCDTitle() const {return m_sCDTitleFile != "" && IsAFile(GetCDTitlePath()); } bool Song::HasCDTitle() const {return m_sCDTitleFile != "" && IsAFile(GetCDTitlePath()); }
bool Song::HasBGChanges() const {return !m_BackgroundChanges.empty(); } bool Song::HasBGChanges() const {return !m_BackgroundChanges.empty(); }
int Song::GetNumTimesPlayed( ProfileSlot card ) const
{
int iTotalNumTimesPlayed = 0;
for( unsigned i=0; i<m_apNotes.size(); i++ )
iTotalNumTimesPlayed += m_apNotes[i]->GetNumTimesPlayed( card );
return iTotalNumTimesPlayed;
}
/* Note that supplying a path relative to the top-level directory is only for compatibility /* Note that supplying a path relative to the top-level directory is only for compatibility
* with DWI. We prefer paths relative to the song directory. */ * with DWI. We prefer paths relative to the song directory. */
@@ -1673,7 +1645,7 @@ int Song::GetNumNotesWithGrade( Grade g ) const
{ {
Steps* pSteps = vNotes[j]; Steps* pSteps = vNotes[j];
if( pSteps->GetTopScore(PROFILE_SLOT_MACHINE).grade == g ) if( PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSteps).GetTopScore().grade == g )
iCount++; iCount++;
} }
return iCount; return iCount;
+5 -50
View File
@@ -327,10 +327,13 @@ bool CompareStepsPointersBySortValueDescending(const Steps *pSteps1, const Steps
return steps_sort_val[pSteps1] > steps_sort_val[pSteps2]; return steps_sort_val[pSteps1] > steps_sort_val[pSteps2];
} }
void SortStepsPointerArrayByMostPlayed( vector<Steps*> &vStepsPointers, ProfileSlot card ) void SortStepsPointerArrayByMostPlayed( vector<Steps*> &vStepsPointers, ProfileSlot slot )
{ {
Profile* pProfile = PROFILEMAN->GetProfile(slot);
ASSERT( pProfile ); // we shouldn't be requesting this sort unless there's a Profile in this slot
for(unsigned i = 0; i < vStepsPointers.size(); ++i) for(unsigned i = 0; i < vStepsPointers.size(); ++i)
steps_sort_val[vStepsPointers[i]] = ssprintf("%9i", vStepsPointers[i]->GetNumTimesPlayed(card)); steps_sort_val[vStepsPointers[i]] = ssprintf("%9i", pProfile->GetStepsNumTimesPlayed(vStepsPointers[i]));
stable_sort( vStepsPointers.begin(), vStepsPointers.end(), CompareStepsPointersBySortValueDescending ); stable_sort( vStepsPointers.begin(), vStepsPointers.end(), CompareStepsPointersBySortValueDescending );
steps_sort_val.clear(); steps_sort_val.clear();
} }
@@ -382,51 +385,3 @@ void SortStepsByTypeAndDifficulty( vector<Steps*> &arraySongPointers )
} }
bool Steps::MemCardData::HighScore::operator>=( const Steps::MemCardData::HighScore& other ) const
{
if( PREFSMAN->m_bPercentageScoring )
return fPercentDP >= other.fPercentDP;
else
return iScore >= other.iScore;
/* Make sure we treat AAAA as higher than AAA, even though the score
* is the same.
*
* XXX: Isn't it possible to beat the grade but not beat the score, since
* grading and scores are on completely different systems? Should we be
* checking for these completely separately? */
// if( vsScore > this->fScore )
// return true;
// if( vsScore < this->fScore )
// return false;
// return vsGrade > this->grade;
}
void Steps::MemCardData::AddHighScore( Steps::MemCardData::HighScore hs, int &iIndexOut )
{
int i;
for( i=0; i<(int)vHighScores.size(); i++ )
{
if( hs >= vHighScores[i] ) // tie goes to new score
break;
}
if( i < NUM_RANKING_LINES )
{
vHighScores.insert( vHighScores.begin()+i, hs );
iIndexOut = i;
if( (int)vHighScores.size() > NUM_RANKING_LINES )
vHighScores.erase( vHighScores.begin()+NUM_RANKING_LINES, vHighScores.end() );
}
}
void Steps::AddHighScore( PlayerNumber pn, MemCardData::HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut )
{
hs.sName = RANKING_TO_FILL_IN_MARKER[pn];
if( PROFILEMAN->IsUsingProfile(pn) )
m_MemCardDatas[pn].AddHighScore( hs, iPersonalIndexOut );
else
iPersonalIndexOut = -1;
m_MemCardDatas[PROFILE_SLOT_MACHINE].AddHighScore( hs, iMachineIndexOut );
}
-52
View File
@@ -55,58 +55,6 @@ public:
void SetSMNoteData( const CString &notes_comp, const CString &attacks_comp ); void SetSMNoteData( const CString &notes_comp, const CString &attacks_comp );
void GetSMNoteData( CString &notes_comp_out, CString &attacks_comp_out ) const; void GetSMNoteData( CString &notes_comp_out, CString &attacks_comp_out ) const;
struct MemCardData
{
MemCardData()
{
iNumTimesPlayed = 0;
}
int iNumTimesPlayed;
struct HighScore
{
CString sName;
Grade grade;
int iScore;
float fPercentDP;
HighScore()
{
grade = GRADE_NO_DATA;
iScore = 0;
fPercentDP = 0;
}
bool operator>=( const HighScore& other ) const;
};
vector<HighScore> vHighScores;
void AddHighScore( MemCardData::HighScore hs, int &iIndexOut );
HighScore GetTopScore()
{
if( vHighScores.empty() )
return HighScore();
else
return vHighScores[0];
}
} m_MemCardDatas[NUM_PROFILE_SLOTS];
void AddHighScore( PlayerNumber pn, MemCardData::HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut );
MemCardData::HighScore GetTopScore( ProfileSlot slot )
{
return m_MemCardDatas[slot].GetTopScore();
}
int GetNumTimesPlayed( ProfileSlot slot )
{
return m_MemCardDatas[slot].iNumTimesPlayed;
}
void TidyUpData(); void TidyUpData();
protected: protected:
+1 -3
View File
@@ -182,14 +182,12 @@ public:
bool SongHasNotesType( StepsType nt ) const; bool SongHasNotesType( StepsType nt ) const;
bool SongHasNotesTypeAndDifficulty( StepsType nt, Difficulty dc ) const; bool SongHasNotesTypeAndDifficulty( StepsType nt, Difficulty dc ) const;
const vector<Steps*>& GetAllSteps() const { return m_apNotes; } const vector<Steps*>& GetAllSteps() const { return m_apNotes; }
void GetSteps( vector<Steps*>& arrayAddTo, StepsType nt, Difficulty dc = DIFFICULTY_INVALID, int iMeterLow = -1, int iMeterHigh = -1, const CString &sDescription = "", bool bIncludeAutoGen = true, int Max = -1 ) const; void GetSteps( vector<Steps*>& arrayAddTo, StepsType nt = STEPS_TYPE_INVALID, Difficulty dc = DIFFICULTY_INVALID, int iMeterLow = -1, int iMeterHigh = -1, const CString &sDescription = "", bool bIncludeAutoGen = true, int Max = -1 ) const;
Steps* GetStepsByDifficulty( StepsType nt, Difficulty dc, bool bIncludeAutoGen = true ) const; Steps* GetStepsByDifficulty( StepsType nt, Difficulty dc, bool bIncludeAutoGen = true ) const;
Steps* GetStepsByMeter( StepsType nt, int iMeterLow, int iMeterHigh, bool bIncludeAutoGen = true ) const; Steps* GetStepsByMeter( StepsType nt, int iMeterLow, int iMeterHigh, bool bIncludeAutoGen = true ) const;
Steps* GetStepsByDescription( StepsType nt, CString sDescription, bool bIncludeAutoGen = true ) const; Steps* GetStepsByDescription( StepsType nt, CString sDescription, bool bIncludeAutoGen = true ) const;
Steps* GetClosestNotes( StepsType nt, Difficulty dc, bool bIncludeAutoGen = true ) const; Steps* GetClosestNotes( StepsType nt, Difficulty dc, bool bIncludeAutoGen = true ) const;
void GetEdits( vector<Steps*>& arrayAddTo, StepsType nt, bool bIncludeAutoGen = true ) const; void GetEdits( vector<Steps*>& arrayAddTo, StepsType nt, bool bIncludeAutoGen = true ) const;
int GetNumTimesPlayed( ProfileSlot slot ) const;
bool IsNew() const;
bool IsEasy( StepsType nt ) const; bool IsEasy( StepsType nt ) const;
bool HasEdits( StepsType nt ) const; bool HasEdits( StepsType nt ) const;
bool NormallyDisplayed() const; bool NormallyDisplayed() const;