save per-difficulty course scores

This commit is contained in:
Chris Danford
2004-02-22 06:04:01 +00:00
parent a381630ac2
commit 69600d9d80
11 changed files with 84 additions and 55 deletions
+3 -2
View File
@@ -1249,11 +1249,12 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeats> &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<hsl.vHighScores.size(); i++ )
{
HighScore &hs = hsl.vHighScores[i];
@@ -1276,7 +1277,7 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeats> &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; i<hsl.vHighScores.size(); i++ )
{
HighScore& hs = hsl.vHighScores[i];
+4 -3
View File
@@ -174,6 +174,7 @@ void PaneDisplay::SetContent( PaneContents c )
const Steps *pSteps = GAMESTATE->m_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:
+52 -26
View File
@@ -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<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
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<const Course*,HighScoresForACourse>::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; st<NUM_STEPS_TYPES; ((int&)st)++ )
{
// skip course/steps types that have never been played
if( pProfile->GetCourseHighScoreList(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 );
}
}
}
}
+5 -5
View File
@@ -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<const Course*,HighScoresForACourse> 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 );
//
+6 -6
View File
@@ -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 );
}
+2 -2
View File
@@ -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
+2 -1
View File
@@ -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;
+1 -1
View File
@@ -176,7 +176,7 @@ void ScreenGameplay::Init()
if( !m_bDemonstration )
for( p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(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; p<NUM_PLAYERS; p++ )
{
+5 -7
View File
@@ -318,6 +318,7 @@ ScreenRanking::ScreenRanking( CString sClassName ) : ScreenAttract( sClassName )
pts.colorIndex = i;
pts.nt = aStepsTypesToShow[i];
pts.pCourse = SONGMAN->GetCourseFromPath( 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; l<NUM_RANKING_LINES; l++ )
{
HighScore hs;
@@ -817,13 +818,10 @@ float ScreenRanking::SetPage( PageToShow pts )
const Course* pCourse = pCourseScoreRowItem->m_pCourse;
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++ )
FOREACH_CourseDifficulty( cd )
{
//
// FIXME: have separate high scores for each difficulty
//
BitmapText* pTextStepsScore = &pCourseScoreRowItem->m_textStepsScore[d];
const HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList( pCourse, pts.nt, cd );
BitmapText* pTextStepsScore = &pCourseScoreRowItem->m_textStepsScore[cd];
HighScore hs;
bool bRecentHighScore = false;
+1
View File
@@ -37,6 +37,7 @@ protected:
StepsType nt;
RankingCategory category;
Course* pCourse;
CourseDifficulty cd;
PageToShow(): pCourse(NULL) { }
};
+3 -2
View File
@@ -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; p<NUM_PLAYERS; p++ )
{
const StepsType &st = GAMESTATE->GetCurrentStyleDef()->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 */