add top5 high score saving of Courses and Steps for memory cards/ranking screen

This commit is contained in:
Chris Danford
2003-10-14 17:06:30 +00:00
parent 278e7cd57d
commit 668d1974f3
22 changed files with 703 additions and 640 deletions
-111
View File
@@ -53,30 +53,6 @@ Course::Course()
m_bDifficult = false;
m_iLives = -1;
m_iMeter = -1;
SetDefaultScore();
}
void Course::SetDefaultScore()
{
//
// Init high scores
//
for( unsigned i=0; i<NUM_STEPS_TYPES; i++ )
for( int j=0; j<NUM_RANKING_LINES; j++ )
{
m_RankingScores[i][j].iScore = IsOni()? 573:573000;
m_RankingScores[i][j].fSurviveTime = 57.3f;
m_RankingScores[i][j].sName = DEFAULT_RANKING_NAME;
}
for( unsigned m=0; m<NUM_MEMORY_CARDS; m++ )
for( unsigned i=0; i<NUM_STEPS_TYPES; i++ )
{
m_MemCardScores[m][i].iNumTimesPlayed = 0;
m_MemCardScores[m][i].iScore = 0;
m_MemCardScores[m][i].fSurviveTime = 0;
}
}
PlayMode Course::GetPlayMode() const
@@ -289,8 +265,6 @@ void Course::LoadFromCRSFile( CString sPath )
CString ignore;
tsub.Subst(m_sName, ignore, ignore,
ignore, ignore, ignore);
SetDefaultScore();
}
@@ -392,8 +366,6 @@ void Course::AutogenEndlessFromGroup( CString sGroupName, vector<Song*> &apSongs
SONGMAN->GetSongs( vSongs, e.group_name );
for( unsigned i = 0; i < vSongs.size(); ++i)
m_entries.push_back( e );
SetDefaultScore();
}
void Course::AutogenNonstopFromGroup( CString sGroupName, vector<Song*> &apSongsInGroup )
@@ -409,8 +381,6 @@ void Course::AutogenNonstopFromGroup( CString sGroupName, vector<Song*> &apSongs
m_entries.push_back( m_entries[0] );
while( m_entries.size() > 4 )
m_entries.pop_back();
SetDefaultScore();
}
/*
@@ -742,87 +712,6 @@ bool Course::GetTotalSeconds( float& fSecondsOut ) const
}
struct RankingToInsert
{
PlayerNumber pn;
int iScore;
float fSurviveTime;
static bool CompareDescending( const RankingToInsert &hs1, const RankingToInsert &hs2 )
{
return hs1.iScore > hs2.iScore;
}
static void SortDescending( vector<RankingToInsert>& vHSout )
{
sort( vHSout.begin(), vHSout.end(), CompareDescending );
}
};
void Course::AddScores( StepsType nt, bool bPlayerEnabled[NUM_PLAYERS], int iScore[NUM_PLAYERS], float fSurviveTime[NUM_PLAYERS], int iRankingIndexOut[NUM_PLAYERS], bool bNewRecordOut[NUM_PLAYERS] )
{
vector<RankingToInsert> vHS;
for( int p=0; p<NUM_PLAYERS; p++ )
{
iRankingIndexOut[p] = -1;
bNewRecordOut[p] = false;
if( !bPlayerEnabled[p] )
continue; // skip
// Update memory card
m_MemCardScores[p][nt].iNumTimesPlayed++;
m_MemCardScores[MEMORY_CARD_MACHINE][nt].iNumTimesPlayed++;
if( iScore[p] > m_MemCardScores[p][nt].iScore )
{
m_MemCardScores[p][nt].iScore = iScore[p];
m_MemCardScores[p][nt].fSurviveTime = fSurviveTime[p];
bNewRecordOut[p] = true;
}
if( iScore[p] > m_MemCardScores[MEMORY_CARD_MACHINE][nt].iScore )
{
m_MemCardScores[MEMORY_CARD_MACHINE][nt].iScore = iScore[p];
m_MemCardScores[MEMORY_CARD_MACHINE][nt].fSurviveTime = fSurviveTime[p];
}
// Update Ranking
RankingToInsert hs;
hs.iScore = iScore[p];
hs.fSurviveTime = fSurviveTime[p];
hs.pn = (PlayerNumber)p;
vHS.push_back( hs );
}
// Sort descending before inserting.
// This guarantees that a high score will not switch poitions on us when we later insert scores for the other player
RankingToInsert::SortDescending( vHS );
for( unsigned i=0; i<vHS.size(); i++ )
{
RankingToInsert& newHS = vHS[i];
RankingScore* rankingScores = m_RankingScores[nt];
for( int i=0; i<NUM_RANKING_LINES; i++ )
{
if( newHS.iScore > rankingScores[i].iScore )
{
// We found the insert point. Shift down.
for( int j=NUM_RANKING_LINES-1; j>i; j-- )
rankingScores[j] = rankingScores[j-1];
// insert
rankingScores[i].fSurviveTime = newHS.fSurviveTime;
rankingScores[i].iScore = newHS.iScore;
rankingScores[i].sName = DEFAULT_RANKING_NAME;
iRankingIndexOut[newHS.pn] = i;
break;
}
}
}
}
//
// Sorting stuff
//
+66 -14
View File
@@ -131,22 +131,75 @@ public:
void AutogenNonstopFromGroup( CString sGroupName, vector<Song*> &apSongsInGroup );
// Statistics
struct RankingScore
{
/* Dance points for oni, regular score for nonstop. */
int iScore;
float fSurviveTime;
CString sName;
} m_RankingScores[NUM_STEPS_TYPES][NUM_RANKING_LINES]; // sorted highest to lowest by iDancePoints
struct MemCardScore
struct MemCardData
{
MemCardData()
{
iNumTimesPlayed = 0;
}
int iNumTimesPlayed;
int iScore;
float fSurviveTime;
} m_MemCardScores[NUM_MEMORY_CARDS][NUM_STEPS_TYPES];
struct HighScore
{
int iScore;
float fSurviveTime;
CString sName;
HighScore()
{
iScore = 0;
fSurviveTime = 0;
}
bool operator>( const HighScore& other )
{
return iScore > other.iScore;
}
};
vector<HighScore> vHighScores;
void AddHighScore( HighScore hs, int &iIndexOut )
{
for( int i=0; i<vHighScores.size() && i<NUM_RANKING_LINES; i++ )
{
if( hs > vHighScores[i] )
{
vHighScores.insert( vHighScores.begin()+i, hs );
iIndexOut = i;
break;
}
}
if( vHighScores.size() > NUM_RANKING_LINES )
vHighScores.erase( vHighScores.begin()+NUM_RANKING_LINES, vHighScores.end() );
}
HighScore GetTopScore()
{
if( vHighScores.empty() )
return HighScore();
else
return vHighScores[0];
}
} m_MemCardDatas[NUM_STEPS_TYPES][NUM_MEMORY_CARDS];
void AddScores( StepsType nt, bool bPlayerEnabled[NUM_PLAYERS], int iDancePoints[NUM_PLAYERS], float fSurviveTime[NUM_PLAYERS], int iRankingIndexOut[NUM_PLAYERS], bool bNewRecordOut[NUM_PLAYERS] ); // iNewRecordIndexOut[p] = -1 if not a new record
void AddHighScore( StepsType st, PlayerNumber pn, MemCardData::HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut )
{
hs.sName = RANKING_TO_FILL_IN_MARKER[pn];
m_MemCardDatas[st][pn].AddHighScore( hs, iPersonalIndexOut );
m_MemCardDatas[st][MEMORY_CARD_MACHINE].AddHighScore( hs, iMachineIndexOut );
}
MemCardData::HighScore GetTopScore( StepsType st, MemoryCard card )
{
return m_MemCardDatas[st][card].GetTopScore();
}
int GetNumTimesPlayed( StepsType st, MemoryCard card )
{
return m_MemCardDatas[st][card].iNumTimesPlayed;
}
// sorting values
int SortOrder_TotalDifficulty;
@@ -155,7 +208,6 @@ public:
void UpdateCourseStats();
private:
void SetDefaultScore();
void GetMeterRange( int stage, int& iMeterLowOut, int& iMeterHighOut, int Difficult = -1 ) const;
};
+3 -1
View File
@@ -13,6 +13,7 @@
-----------------------------------------------------------------------------
*/
#include "PlayerNumber.h" // TODO: Get rid of this dependency. -Chris
//
// Screen Dimensions
@@ -194,7 +195,8 @@ enum RankingCategory
NUM_RANKING_CATEGORIES
};
#define DEFAULT_RANKING_NAME CString("STEP")
const CString DEFAULT_RANKING_NAME = "";
const CString RANKING_TO_FILL_IN_MARKER[NUM_PLAYERS] = {"#P1#","#P2#"};
RankingCategory AverageMeterToRankingCategory( float fAverageMeter );
+78 -20
View File
@@ -47,7 +47,6 @@ GameState::GameState()
m_pPosition = NULL;
m_pUnlockingSys = new UnlockSystem;
ResetLastRanking();
ReloadCharacters();
}
@@ -160,25 +159,6 @@ void GameState::Update( float fDelta )
}
}
void GameState::ResetLastRanking()
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
m_RankingCategory[p] = (RankingCategory)-1;
m_iRankingIndex[p] = -1;
}
}
void GameState::StoreRankingName( PlayerNumber pn, CString name )
{
const int index = GAMESTATE->m_iRankingIndex[pn];
if( GAMESTATE->IsCourseMode() )
GAMESTATE->m_pRankingCourse->m_RankingScores[GAMESTATE->m_RankingNotesType][index].sName = name;
else
SONGMAN->m_MachineScores[GAMESTATE->m_RankingNotesType][GAMESTATE->m_RankingCategory[pn]][index].sName = name;
}
void GameState::ReloadCharacters()
{
unsigned i;
@@ -771,3 +751,81 @@ Character* GameState::GetDefaultCharacter()
ASSERT(0);
return NULL;
}
void GameState::GetRankingFeats( PlayerNumber pn, CStringArray &asFeatsOut, vector<CString*> &vpStringsToFillOut )
{
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
{
int i;
StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
for( i=0; i<m_vPlayedStageStats.size(); i++ )
{
Song* pSong = m_vPlayedStageStats[i].pSong;
Steps* pSteps = m_vPlayedStageStats[i].pSteps[pn];
vector<Steps::MemCardData::HighScore> &vHighScores = pSteps->m_MemCardDatas[MEMORY_CARD_MACHINE].vHighScores;
for( int j=0; j<vHighScores.size(); j++ )
{
if( vHighScores[j].sName == RANKING_TO_FILL_IN_MARKER[pn] )
{
CString s = ssprintf("No. %d in %s", j+1, pSong->GetFullTranslitTitle().c_str() );
asFeatsOut.push_back( s );
vpStringsToFillOut.push_back( &vHighScores[j].sName );
}
}
}
StageStats stats;
vector<Song*> vSongs;
GetFinalEvalStatsAndSongs( stats, vSongs );
for( i=0; i<NUM_RANKING_CATEGORIES; i++ )
{
vector<SongManager::CategoryData::HighScore> &vHighScores = SONGMAN->m_CategoryDatas[nt][i].vHighScores;
for( int j=0; j<vHighScores.size(); j++ )
{
CString s = ssprintf("No. %d in Type %c (%d)", j+1, 'A'+i, stats.iMeter[pn] );
vpStringsToFillOut.push_back( &vHighScores[j].sName );
}
}
}
break;
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
break;
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
{
StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
Course* pCourse = GAMESTATE->m_pCurCourse;
vector<Course::MemCardData::HighScore> &vHighScores = pCourse->m_MemCardDatas[nt][MEMORY_CARD_MACHINE].vHighScores;
for( int i=0; i<vHighScores.size(); i++ )
{
if( vHighScores[i].sName == RANKING_TO_FILL_IN_MARKER[pn] )
{
CString s = ssprintf("No. %d in %s", i+1, pCourse->m_sName.c_str() );
asFeatsOut.push_back( s );
vpStringsToFillOut.push_back( &vHighScores[i].sName );
}
}
}
break;
default:
ASSERT(0);
}
}
void GameState::StoreRankingName( PlayerNumber pn, CString name )
{
vector<CString*> vpStringsToFill;
CStringArray asFeats;
GetRankingFeats( pn, asFeats, vpStringsToFill );
for( int i=0; i<vpStringsToFill.size(); i++ )
{
(*vpStringsToFill[i]) = name;
}
}
+1 -7
View File
@@ -36,7 +36,6 @@ public:
GameState();
~GameState();
void Reset();
void ResetLastRanking();
void Update( float fDelta );
@@ -245,12 +244,7 @@ public:
//
// Ranking Stuff
//
// Filled in by ScreenNameEntry and used by ScreenRanking to flash the recent high scores
StepsType m_RankingNotesType; // meaningless if a course was played
RankingCategory m_RankingCategory[NUM_PLAYERS]; // meaningless if a course was played
Course* m_pRankingCourse; // meaningless unless Course was played
int m_iRankingIndex[NUM_PLAYERS]; // -1 if no new high score
void GetRankingFeats( PlayerNumber pn, CStringArray &asFeatsOut, vector<CString*> &vpStringsToFillOut );
/* Called by name entry screens: */
void StoreRankingName( PlayerNumber pn, CString name );
+2 -2
View File
@@ -200,9 +200,9 @@ void MusicWheelItem::RefreshGrades()
dc = GAMESTATE->m_PreferredDifficulty[p];
Grade grade;
if( PROFILEMAN->IsUsingProfile((PlayerNumber)p) )
grade = data->m_pSong->GetGradeForDifficulty( GAMESTATE->GetCurrentStyleDef(), (MemoryCard)p, dc );
grade = data->m_pSong->GetHighScoreForDifficulty( GAMESTATE->GetCurrentStyleDef(), (MemoryCard)p, dc ).grade;
else
grade = data->m_pSong->GetGradeForDifficulty( GAMESTATE->GetCurrentStyleDef(), MEMORY_CARD_MACHINE, dc );
grade = data->m_pSong->GetHighScoreForDifficulty( GAMESTATE->GetCurrentStyleDef(), MEMORY_CARD_MACHINE, dc ).grade;
m_GradeDisplay[p].SetGrade( (PlayerNumber)p, grade );
}
+6 -6
View File
@@ -24,8 +24,8 @@ ProfileManager* PROFILEMAN = NULL; // global and accessable from anywhere in our
#define PROFILE_FILE "Profile.ini"
#define NOTES_SCORES_FILE "NotesScores.dat"
#define COURSE_SCORES_FILE "CourseScores.dat"
#define STEPS_MEM_CARD_DATA_FILE "StepsMemCardData.dat"
#define COURSE_MEM_CARD_DATA_FILE "CourseMemCardData.dat"
ProfileManager::ProfileManager()
{
@@ -90,8 +90,8 @@ void ProfileManager::TryLoadProfile( PlayerNumber pn )
//
// Load scores into SONGMAN
//
SONGMAN->ReadNoteScoresFromFile( m_sProfileDir[pn]+NOTES_SCORES_FILE, (MemoryCard)pn );
SONGMAN->ReadCourseScoresFromFile( m_sProfileDir[pn]+COURSE_SCORES_FILE, (MemoryCard)pn );
SONGMAN->ReadStepsMemCardDataFromFile( m_sProfileDir[pn]+STEPS_MEM_CARD_DATA_FILE, (MemoryCard)pn );
SONGMAN->ReadCourseMemCardDataFromFile( m_sProfileDir[pn]+COURSE_MEM_CARD_DATA_FILE, (MemoryCard)pn );
}
void ProfileManager::UnloadProfile( PlayerNumber pn )
@@ -104,8 +104,8 @@ void ProfileManager::UnloadProfile( PlayerNumber pn )
//
// Save scores into SONGMAN
//
SONGMAN->SaveNoteScoresToFile( m_sProfileDir[pn]+NOTES_SCORES_FILE, (MemoryCard)pn );
SONGMAN->SaveCourseScoresToFile( m_sProfileDir[pn]+COURSE_SCORES_FILE, (MemoryCard)pn );
SONGMAN->SaveStepsMemCardDataToFile( m_sProfileDir[pn]+STEPS_MEM_CARD_DATA_FILE, (MemoryCard)pn );
SONGMAN->SaveCourseMemCardDataToFile( m_sProfileDir[pn]+COURSE_MEM_CARD_DATA_FILE, (MemoryCard)pn );
// clear out the displayname and highscore name when we unload the profile.
m_Profile[pn].Init();
+129 -102
View File
@@ -165,119 +165,146 @@ ScreenEvaluation::ScreenEvaluation( CString sClassName ) : Screen(sClassName)
//
// update persistent statistics
//
bool bNewRecord[NUM_PLAYERS];
ZERO( bNewRecord );
int iPersonalHighScoreIndex[NUM_PLAYERS];
int iMachineHighScoreIndex[NUM_PLAYERS];
RankingCategory rc[NUM_PLAYERS];
memset( iPersonalHighScoreIndex, -1, sizeof(iPersonalHighScoreIndex) );
memset( iMachineHighScoreIndex, -1, sizeof(iMachineHighScoreIndex) );
memset( rc, -1, sizeof(rc) );
switch( m_Type )
for( p=0; p<NUM_PLAYERS; p++ )
{
case stage:
if( !GAMESTATE->IsHumanPlayer(p) )
continue; // skip
if( !GAMESTATE->m_SongOptions.m_bSaveScore )
continue; // skip
switch( m_Type )
{
for( int p=0; p<NUM_PLAYERS; p++ )
case stage:
{
if( GAMESTATE->IsHumanPlayer(p) && GAMESTATE->m_SongOptions.m_bSaveScore )
{
if( GAMESTATE->m_pCurNotes[p] )
{
float score;
if( PREFSMAN->m_bPercentageScoring )
score = stageStats.GetPercentDancePoints( (PlayerNumber)p );
else
score = float(stageStats.iScore[p] + stageStats.iBonus[p]);
GAMESTATE->m_pCurNotes[p]->AddScore( (PlayerNumber)p, grade[p], score, bNewRecord[p] );
}
// update unlock data if unlocks are on
if ( PREFSMAN->m_bUseUnlockSystem )
{
UNLOCKSYS->UnlockClearStage();
UNLOCKSYS->UnlockAddAP( grade[p] );
UNLOCKSYS->UnlockAddSP( grade[p] );
// we want to save dance points here if we are in event mode.
// otherwise, dance points will never get saved except
// in nonstop mode.
if( PREFSMAN->m_bEventMode )
UNLOCKSYS->UnlockAddDP( (float)stageStats.iActualDancePoints[p] );
}
}
}
}
break;
case summary:
{
StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
bool bIsHumanPlayer[NUM_PLAYERS];
for( p=0; p<NUM_PLAYERS; p++ )
bIsHumanPlayer[p] = GAMESTATE->IsHumanPlayer(p);
RankingCategory cat[NUM_PLAYERS];
int iRankingIndex[NUM_PLAYERS];
float fTotalDP = 0;
for( int p=0; p<NUM_PLAYERS; p++ )
{
float fAverageMeter = stageStats.iMeter[p] / (float)PREFSMAN->m_iNumArcadeStages;
cat[p] = AverageMeterToRankingCategory( fAverageMeter );
fTotalDP += stageStats.iActualDancePoints[p];
}
SONGMAN->AddScores( nt, bIsHumanPlayer, cat, stageStats.iScore, iRankingIndex );
COPY( GAMESTATE->m_RankingCategory, cat );
COPY( GAMESTATE->m_iRankingIndex, iRankingIndex );
GAMESTATE->m_RankingNotesType = nt;
// If unlocking is enabled, save the dance points
if( PREFSMAN->m_bUseUnlockSystem )
UNLOCKSYS->UnlockAddDP( fTotalDP );
}
break;
case course:
{
bool bIsHumanPlayer[NUM_PLAYERS];
for( p=0; p<NUM_PLAYERS; p++ )
bIsHumanPlayer[p] = GAMESTATE->IsHumanPlayer(p);
int iRankingIndex[NUM_PLAYERS];
Course* pCourse = GAMESTATE->m_pCurCourse;
if( pCourse )
{
int *score;
if( pCourse->IsOni() )
score = stageStats.iActualDancePoints;
ASSERT( GAMESTATE->m_pCurNotes[p] );
float score;
if( PREFSMAN->m_bPercentageScoring )
score = stageStats.GetPercentDancePoints( (PlayerNumber)p );
else
score = stageStats.iScore;
StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
pCourse->AddScores( nt, bIsHumanPlayer, score, stageStats.fAliveSeconds, iRankingIndex, bNewRecord );
COPY( GAMESTATE->m_iRankingIndex, iRankingIndex );
GAMESTATE->m_pRankingCourse = pCourse;
GAMESTATE->m_RankingNotesType = nt;
}
// If unlocking is enabled, save the dance points
// (for courses)
if( PREFSMAN->m_bUseUnlockSystem )
{
for(p=0; p < NUM_PLAYERS; p++)
score = float(stageStats.iScore[p] + stageStats.iBonus[p]);
Steps::MemCardData::HighScore hs;
hs.grade = grade[p];
hs.fScore = score;
GAMESTATE->m_pCurNotes[p]->AddHighScore( (PlayerNumber)p, hs, iPersonalHighScoreIndex[p], iMachineHighScoreIndex[p] );
// update unlock data if unlocks are on
if ( PREFSMAN->m_bUseUnlockSystem )
{
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
continue; // skip
UNLOCKSYS->UnlockClearStage();
UNLOCKSYS->UnlockAddAP( grade[p] );
UNLOCKSYS->UnlockAddSP( grade[p] );
// we want to save dance points here if we are in event mode.
// otherwise, dance points will never get saved except
// in nonstop mode.
if( PREFSMAN->m_bEventMode )
UNLOCKSYS->UnlockAddDP( (float)stageStats.iActualDancePoints[p] );
UNLOCKSYS->UnlockAddDP( (float) stageStats.iActualDancePoints[p] );
UNLOCKSYS->UnlockAddAP( (float) stageStats.iSongsPassed[p] );
UNLOCKSYS->UnlockAddSP( (float) stageStats.iSongsPassed[p] );
}
}
// cannot just use score since it may be nonstop mode
break;
case summary:
{
StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
float fAverageMeter = stageStats.iMeter[p] / (float)PREFSMAN->m_iNumArcadeStages;
rc[p] = AverageMeterToRankingCategory( fAverageMeter );
float fTotalDP = stageStats.iActualDancePoints[p];
SongManager::CategoryData::HighScore hs;
hs.iScore = stageStats.iScore[p];
SONGMAN->AddHighScore( nt, rc[p], (PlayerNumber)p, hs, iMachineHighScoreIndex[p] );
// If unlocking is enabled, save the dance points
if( PREFSMAN->m_bUseUnlockSystem )
UNLOCKSYS->UnlockAddDP( fTotalDP );
}
break;
case course:
{
Course* pCourse = GAMESTATE->m_pCurCourse;
if( pCourse )
{
int score;
if( pCourse->IsOni() )
score = stageStats.iActualDancePoints[p];
else
score = stageStats.iScore[p];
StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
Course::MemCardData::HighScore hs;
hs.iScore = score;
hs.fSurviveTime = stageStats.fAliveSeconds[p];
pCourse->AddHighScore( nt, (PlayerNumber)p, hs, iPersonalHighScoreIndex[p], iMachineHighScoreIndex[p] );
}
// If unlocking is enabled, save the dance points
// (for courses)
if( PREFSMAN->m_bUseUnlockSystem )
{
for(p=0; p < NUM_PLAYERS; p++)
{
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
continue; // skip
UNLOCKSYS->UnlockAddDP( (float) stageStats.iActualDancePoints[p] );
UNLOCKSYS->UnlockAddAP( (float) stageStats.iSongsPassed[p] );
UNLOCKSYS->UnlockAddSP( (float) stageStats.iSongsPassed[p] );
}
}
// cannot just use score since it may be nonstop mode
}
break;
default:
ASSERT(0);
}
}
// If both players get a machine high score, a player
// whose score is added later may bump the players who were
// added earlier. Adjust for this.
for( p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsHumanPlayer(p) )
continue; // skip
if( iMachineHighScoreIndex[p] == -1 ) // no record
continue; // skip
for( int p2=0; p2<p; p2++ )
{
if( !GAMESTATE->IsHumanPlayer(p2) )
continue; // skip
if( iMachineHighScoreIndex[p2] == -1 ) // no record
continue; // skip
bool bPlayedSameSteps;
switch( m_Type )
{
case stage:
bPlayedSameSteps = GAMESTATE->m_pCurNotes[p]==GAMESTATE->m_pCurNotes[p2];
break;
case summary:
bPlayedSameSteps = rc[p] == rc[p2];
break;
case course:
bPlayedSameSteps = true;
break;
}
if( iMachineHighScoreIndex[p] >= iMachineHighScoreIndex[p2] )
{
iMachineHighScoreIndex[p2]++;
if( iMachineHighScoreIndex[p2] >= NUM_RANKING_LINES )
iMachineHighScoreIndex[p2] = -1;
}
}
break;
default:
ASSERT(0);
}
m_bTryExtraStage =
@@ -628,7 +655,7 @@ ScreenEvaluation::ScreenEvaluation( CString sClassName ) : Screen(sClassName)
//
for( p=0; p<NUM_PLAYERS; p++ )
{
if( bNewRecord[p] )
if( iPersonalHighScoreIndex[p] == 0 )
{
m_sprNewRecord[p].Load( THEME->GetPathToG("ScreenEvaluation new record") );
m_sprNewRecord[p].SetName( ssprintf("NewRecordP%d",p+1) );
@@ -639,7 +666,7 @@ ScreenEvaluation::ScreenEvaluation( CString sClassName ) : Screen(sClassName)
bool bOneHasNewRecord = false;
for( p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(p) && bNewRecord[p] )
if( GAMESTATE->IsPlayerEnabled(p) && iPersonalHighScoreIndex[p] == 0 )
bOneHasNewRecord = true;
if( m_bTryExtraStage )
+1
View File
@@ -187,6 +187,7 @@ ScreenGameplay::ScreenGameplay( CString sName, bool bDemonstration ) : Screen("S
continue; // skip
ASSERT( !m_apNotesQueue[p].empty() );
GAMESTATE->m_CurStageStats.pSteps[p] = m_apNotesQueue[p][0];
GAMESTATE->m_CurStageStats.iMeter[p] = m_apNotesQueue[p][0]->GetMeter();
}
+9 -23
View File
@@ -129,9 +129,16 @@ ScreenNameEntry::ScreenNameEntry( CString sClassName ) : Screen( sClassName )
}
int p;
CStringArray asFeats[NUM_PLAYERS];
vector<CString*> vpStringsToFill[NUM_PLAYERS];
// Find out if players deserve to enter their name
for( p=0; p<NUM_PLAYERS; p++ )
m_bStillEnteringName[p] = GAMESTATE->m_iRankingIndex[p] != -1;
{
GAMESTATE->GetRankingFeats( (PlayerNumber)p, asFeats[p], vpStringsToFill[p] );
m_bStillEnteringName[p] = asFeats[p].size()>0;
}
if( !AnyStillEntering() )
{
@@ -201,28 +208,7 @@ ScreenNameEntry::ScreenNameEntry( CString sClassName ) : Screen( sClassName )
m_textCategory[p].LoadFromFont( THEME->GetPathToF("ScreenNameEntry category") );
m_textCategory[p].SetX( (float)GAMESTATE->GetCurrentStyleDef()->m_iCenterX[p] );
m_textCategory[p].SetY( CATEGORY_Y );
CString sCategoryText = ssprintf("No. %d in\n", GAMESTATE->m_iRankingIndex[p]+1);
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
{
StageStats SS;
vector<Song*> vSongs;
GAMESTATE->GetFinalEvalStatsAndSongs( SS, vSongs );
sCategoryText += ssprintf("Type %c (%d)", 'A'+GAMESTATE->m_RankingCategory[p], SS.iMeter[p] );
}
break;
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
sCategoryText += ssprintf("%s", GAMESTATE->m_pCurCourse->m_sName.c_str());
break;
default:
ASSERT(0);
}
m_textCategory[p].SetText( sCategoryText );
m_textCategory[p].SetText( join("\n", asFeats[p]) );
this->AddChild( &m_textCategory[p] );
}
+9 -27
View File
@@ -57,16 +57,19 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
GAMESTATE->m_bSideIsJoined[PLAYER_1] = true;
GAMESTATE->m_bSideIsJoined[PLAYER_2] = true;
GAMESTATE->m_MasterPlayerNumber = PLAYER_1;
GAMESTATE->m_RankingCategory[PLAYER_1] = RANKING_A;
GAMESTATE->m_iRankingIndex[PLAYER_1] = 0;
GAMESTATE->m_RankingCategory[PLAYER_2] = RANKING_A;
GAMESTATE->m_iRankingIndex[PLAYER_2] = 0;
GAMESTATE->m_PlayMode = PLAY_MODE_ARCADE;
int p;
CStringArray asFeats[NUM_PLAYERS];
vector<CString*> vpStringsToFill[NUM_PLAYERS];
// Find out if players deserve to enter their name
for( p=0; p<NUM_PLAYERS; p++ )
m_bStillEnteringName[p] = GAMESTATE->m_iRankingIndex[p] != -1;
{
GAMESTATE->GetRankingFeats( (PlayerNumber)p, asFeats[p], vpStringsToFill[p] );
m_bStillEnteringName[p] = asFeats[p].size()>0;
}
if( !AnyStillEntering() )
{
@@ -146,28 +149,7 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
m_textCategory[p].LoadFromFont( THEME->GetPathToF("ScreenNameEntryTraditional category") );
m_textCategory[p].SetName( ssprintf("Category", p+1) );
SET_XY_AND_ON_COMMAND( m_textCategory[p] );
CString sCategoryText = ssprintf("No. %d in\n", GAMESTATE->m_iRankingIndex[p]+1);
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
{
StageStats SS;
vector<Song*> vSongs;
GAMESTATE->GetFinalEvalStatsAndSongs( SS, vSongs );
sCategoryText += ssprintf("Type %c (%d)", 'A'+GAMESTATE->m_RankingCategory[p], SS.iMeter[p] );
}
break;
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
sCategoryText += ssprintf("%s", GAMESTATE->m_pCurCourse->m_sName.c_str());
break;
default:
ASSERT(0);
}
m_textCategory[p].SetText( sCategoryText );
m_textCategory[p].SetText( join("\n", asFeats[p]) );
this->AddChild( &m_textCategory[p] );
}
+130 -23
View File
@@ -16,6 +16,7 @@
#include "GameState.h"
#include "GameManager.h"
#include "Course.h"
#include "Song.h"
#include "PrefsManager.h"
#define CATEGORY_X THEME->GetMetricF("ScreenRanking","CategoryX")
@@ -37,9 +38,19 @@
#define POINTS_START_Y THEME->GetMetricF("ScreenRanking","PointsStartY")
#define TIME_START_X THEME->GetMetricF("ScreenRanking","TimeStartX")
#define TIME_START_Y THEME->GetMetricF("ScreenRanking","TimeStartY")
#define PERCENT_START_X THEME->GetMetricF("ScreenRanking","PercentStartX")
#define PERCENT_START_Y THEME->GetMetricF("ScreenRanking","PercentStartY")
#define PERCENT_COL_SPACING_X THEME->GetMetricF("ScreenRanking","PercentColSpacingX")
#define PERCENT_COL_SPACING_Y THEME->GetMetricF("ScreenRanking","PercentColSpacingY")
#define SECONDS_PER_PAGE THEME->GetMetricF("ScreenRanking","SecondsPerPage")
#define SHOW_CATEGORIES THEME->GetMetricB("ScreenRanking","ShowCategories")
#define SHOW_ALL_SONGS THEME->GetMetricB("ScreenRanking","ShowAllSongs")
#define NOTES_TYPES_TO_HIDE THEME->GetMetric ("ScreenRanking","NotesTypesToHide")
#define EMPTY_SCORE_NAME THEME->GetMetric ("ScreenRanking","EmptyScoreName")
#define EMPTY_CATEGORY_SCORE THEME->GetMetricI("ScreenRanking","EmptyCategoryScore")
#define EMPTY_COURSE_SCORE THEME->GetMetricI("ScreenRanking","EmptyCourseScore")
#define EMPTY_COURSE_TIME THEME->GetMetricF("ScreenRanking","EmptyCourseTime")
#define EMPTY_SONG_PERCENT THEME->GetMetricF("ScreenRanking","EmptySongPercent")
#define COURSES_TO_SHOW PREFSMAN->m_sCoursesToShowRanking
@@ -97,6 +108,17 @@ ScreenRanking::ScreenRanking( CString sClassName ) : ScreenAttract( sClassName )
m_textTime[i].SetHorizAlign( Actor::align_right );
this->AddChild( &m_textTime[i] );
for( int j=0; j<NUM_DIFFICULTIES; j++ )
{
m_textPercent[i][j].LoadFromFont( THEME->GetPathToF("ScreenRanking letters") );
m_textPercent[i][j].EnableShadow( false );
m_textPercent[i][j].SetX( PERCENT_START_X+LINE_SPACING_X*i+PERCENT_COL_SPACING_X*j );
m_textPercent[i][j].SetY( PERCENT_START_Y+LINE_SPACING_Y*i+PERCENT_COL_SPACING_Y*j );
m_textPercent[i][j].SetZoom( TEXT_ZOOM );
m_textPercent[i][j].SetHorizAlign( Actor::align_right );
this->AddChild( &m_textPercent[i][j] );
}
if( PREFSMAN->m_sCoursesToShowRanking == "" )
PREFSMAN->m_sCoursesToShowRanking = THEME->GetMetric("ScreenRanking","CoursesToShow");
}
@@ -157,6 +179,23 @@ ScreenRanking::ScreenRanking( CString sClassName ) : ScreenAttract( sClassName )
}
}
if( SHOW_ALL_SONGS )
{
vector<Song*> vpSongs = SONGMAN->GetAllSongs();
for( unsigned i=0; i<aNotesTypesToShow.size(); i++ )
{
for( int j=0; j<vpSongs.size(); j++ )
{
PageToShow pts;
pts.type = PageToShow::TYPE_SONG;
pts.colorIndex = i;
pts.pSong = vpSongs[j];
pts.nt = aNotesTypesToShow[i];
m_vPagesToShow.push_back( pts );
}
}
}
this->MoveToTail( &m_In ); // put it in the back so it covers up the stuff we just added
this->MoveToTail( &m_Out ); // put it in the back so it covers up the stuff we just added
@@ -197,6 +236,16 @@ void ScreenRanking::HandleScreenMessage( const ScreenMessage SM )
void ScreenRanking::SetPage( PageToShow pts )
{
// Clear all text
for( int l=0; l<NUM_RANKING_LINES; l++ )
{
m_textScores[l].SetText( "" );
m_textPoints[l].SetText( "" );
m_textTime[l].SetText( "" );
for( int j=0; j<NUM_DIFFICULTIES; j++ )
m_textPercent[l][j].SetText( "" );
}
switch( pts.type )
{
case PageToShow::TYPE_CATEGORY:
@@ -208,24 +257,32 @@ void ScreenRanking::SetPage( PageToShow pts )
m_sprType.Load( THEME->GetPathToG("ScreenRanking type "+GameManager::NotesTypeToString(pts.nt)) );
for( int l=0; l<NUM_RANKING_LINES; l++ )
{
SongManager::CategoryData::HighScore hs;
if( l < SONGMAN->m_CategoryDatas[pts.nt][pts.category].vHighScores.size() )
{
hs = SONGMAN->m_CategoryDatas[pts.nt][pts.category].vHighScores[l];
}
else
{
hs.sName = EMPTY_SCORE_NAME;
hs.iScore = EMPTY_CATEGORY_SCORE;
}
m_sprBullets[l].SetDiffuse( RageColor(1,1,1,1) );
CString sName = SONGMAN->m_MachineScores[pts.nt][pts.category][l].sName;
int iScore = SONGMAN->m_MachineScores[pts.nt][pts.category][l].iScore;
m_textNames[l].SetText( sName );
m_textScores[l].SetText( ssprintf("%09i",iScore) );
m_textPoints[l].SetText( "" );
m_textTime[l].SetText( "" );
m_textNames[l].SetText( hs.sName );
m_textScores[l].SetText( ssprintf("%09i",hs.iScore) );
m_textNames[l].SetDiffuse( TEXT_COLOR(pts.colorIndex) );
m_textScores[l].SetDiffuse( TEXT_COLOR(pts.colorIndex) );
bool bRecentHighScore = false;
for( int p=0; p<NUM_PLAYERS; p++ )
{
bRecentHighScore |=
pts.nt == GAMESTATE->m_RankingNotesType &&
GAMESTATE->m_RankingCategory[p] == pts.category &&
GAMESTATE->m_iRankingIndex[p] == l;
}
// FIXME
// for( int p=0; p<NUM_PLAYERS; p++ )
// {
// bRecentHighScore |=
// pts.nt == GAMESTATE->m_RankingNotesType &&
// GAMESTATE->m_RankingCategory[p] == pts.category &&
// GAMESTATE->m_iRankingIndex[p] == l;
// }
if( bRecentHighScore )
{
@@ -259,20 +316,29 @@ void ScreenRanking::SetPage( PageToShow pts )
m_sprType.Load( THEME->GetPathToG("ScreenRanking type "+GameManager::NotesTypeToString(pts.nt)) );
for( int l=0; l<NUM_RANKING_LINES; l++ )
{
Course::MemCardData::HighScore hs;
if( l < pts.pCourse->m_MemCardDatas[pts.nt][MEMORY_CARD_MACHINE].vHighScores.size() )
{
hs = pts.pCourse->m_MemCardDatas[pts.nt][MEMORY_CARD_MACHINE].vHighScores[l];
}
else
{
hs.sName = EMPTY_SCORE_NAME;
hs.iScore = EMPTY_COURSE_SCORE;
hs.fSurviveTime = EMPTY_COURSE_TIME;
}
m_sprBullets[l].SetDiffuse( RageColor(1,1,1,1) );
CString sName = pts.pCourse->m_RankingScores[pts.nt][l].sName;
const int iScore = pts.pCourse->m_RankingScores[pts.nt][l].iScore;
const float fSurviveTime = pts.pCourse->m_RankingScores[pts.nt][l].fSurviveTime;
m_textNames[l].SetText( sName );
m_textNames[l].SetText( hs.sName );
if( pts.pCourse->IsOni() )
{
m_textPoints[l].SetText( ssprintf("%04d",iScore) );
m_textTime[l].SetText( SecondsToTime(fSurviveTime) );
m_textPoints[l].SetText( ssprintf("%04d",hs.iScore) );
m_textTime[l].SetText( SecondsToTime(hs.fSurviveTime) );
m_textScores[l].SetText( "" );
} else {
m_textPoints[l].SetText( "" );
m_textTime[l].SetText( "" );
m_textScores[l].SetText( ssprintf("%09d",iScore) );
m_textScores[l].SetText( ssprintf("%09d",hs.iScore) );
}
m_textNames[l].SetDiffuse( TEXT_COLOR(pts.colorIndex) );
m_textPoints[l].SetDiffuse( TEXT_COLOR(pts.colorIndex) );
@@ -280,9 +346,12 @@ void ScreenRanking::SetPage( PageToShow pts )
m_textScores[l].SetDiffuse( TEXT_COLOR(pts.colorIndex) );
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( pts.pCourse == GAMESTATE->m_pRankingCourse &&
pts.nt == GAMESTATE->m_RankingNotesType &&
GAMESTATE->m_iRankingIndex[p] == l )
bool bHighlight = false;
// FIXME
// bHighlight = pts.pCourse == GAMESTATE->m_pRankingCourse &&
// pts.nt == GAMESTATE->m_RankingNotesType &&
// GAMESTATE->m_iRankingIndex[p] == l;
if( bHighlight )
{
m_textNames[l].SetEffectGlowBlink(0.1f);
m_textScores[l].SetEffectGlowBlink(0.1f);
@@ -296,6 +365,44 @@ void ScreenRanking::SetPage( PageToShow pts )
}
}
break;
case PageToShow::TYPE_SONG:
{
m_textCategory.SetDiffuseAlpha(0);
m_sprCategory.SetDiffuseAlpha(0);
m_sprCategory.Load( pts.pSong->GetBannerPath() );
m_sprCategory.SetDiffuseAlpha(1);
m_textCategory.SetZoom(1);
m_textCategory.SetTextMaxWidth( CATEGORY_WIDTH, pts.pSong->GetFullTranslitTitle() );
m_textCategory.SetDiffuseAlpha(1);
m_sprType.SetDiffuse( RageColor(1,1,1,1) );
m_sprType.Load( THEME->GetPathToG("ScreenRanking type "+GameManager::NotesTypeToString(pts.nt)) );
for( int l=0; l<NUM_RANKING_LINES; l++ )
{
m_sprBullets[l].SetDiffuse( RageColor(1,1,1,1) );
for( int d=0; d<NUM_DIFFICULTIES; d++ )
{
Difficulty dc = (Difficulty)d;
Steps* pSteps = pts.pSong->GetStepsByDifficulty( pts.nt, dc );
Steps::MemCardData::HighScore hs;
if( l < pSteps->m_MemCardDatas[MEMORY_CARD_MACHINE].vHighScores.size() )
{
hs = pSteps->m_MemCardDatas[MEMORY_CARD_MACHINE].vHighScores[l];
}
else
{
hs.sName = EMPTY_SCORE_NAME;
hs.fScore = EMPTY_SONG_PERCENT;
}
m_textPercent[l][d].SetText( ssprintf("%s %f%", hs.sName.c_str(), hs.fScore) );
}
}
}
break;
default:
ASSERT(0);
}
+4 -1
View File
@@ -16,6 +16,7 @@
#include "BitmapText.h"
class Course;
class Song;
class ScreenRanking : public ScreenAttract
{
@@ -27,11 +28,12 @@ public:
protected:
struct PageToShow
{
enum { TYPE_CATEGORY, TYPE_COURSE } type;
enum { TYPE_CATEGORY, TYPE_COURSE, TYPE_SONG } type;
int colorIndex;
StepsType nt; // used in category and course
RankingCategory category;
Course* pCourse;
Song* pSong;
};
void SetPage( PageToShow pts );
@@ -47,6 +49,7 @@ protected:
BitmapText m_textScores[NUM_RANKING_LINES]; // for category
BitmapText m_textPoints[NUM_RANKING_LINES]; // for course
BitmapText m_textTime[NUM_RANKING_LINES]; // for course
BitmapText m_textPercent[NUM_RANKING_LINES][NUM_DIFFICULTIES]; // for song
vector<PageToShow> m_vPagesToShow;
};
+9 -3
View File
@@ -900,11 +900,17 @@ void ScreenSelectMusic::AfterNotesChange( PlayerNumber pn )
if( pNotes )
{
float fScore;
float fScore = 0;
if( PROFILEMAN->IsUsingProfile(pn) )
fScore = pNotes->m_MemCardScores[pn].fScore;
{
if( !pNotes->m_MemCardDatas[pn].vHighScores.empty() )
fScore = pNotes->m_MemCardDatas[pn].vHighScores[0].fScore;
}
else
fScore = pNotes->m_MemCardScores[MEMORY_CARD_MACHINE].fScore;
{
if( !pNotes->m_MemCardDatas[MEMORY_CARD_MACHINE].vHighScores.empty() )
fScore = pNotes->m_MemCardDatas[MEMORY_CARD_MACHINE].vHighScores[0].fScore;
}
m_textHighScore[pn].SetText( ssprintf("%*i", NUM_SCORE_DIGITS, (int) fScore) );
}
else
+12 -11
View File
@@ -1180,22 +1180,19 @@ void Song::RemoveAutoGenNotes()
}
Grade Song::GetGradeForDifficulty( const StyleDef *st, MemoryCard card, Difficulty dc ) const
Steps::MemCardData::HighScore Song::GetHighScoreForDifficulty( const StyleDef *st, MemoryCard card, Difficulty dc ) const
{
// return max grade of notes in difficulty class
vector<Steps*> aNotes;
this->GetSteps( aNotes, st->m_StepsType );
SortNotesArrayByDifficulty( aNotes );
Grade grade = GRADE_NO_DATA;
for( unsigned i=0; i<aNotes.size(); i++ )
{
const Steps* pNotes = aNotes[i];
if( pNotes->GetDifficulty() == dc )
grade = max( grade, pNotes->m_MemCardScores[card].grade );
}
return grade;
Steps* pSteps = GetStepsByDifficulty( st->m_StepsType, dc );
if( pSteps )
return pSteps->GetTopScore(card);
else
return Steps::MemCardData::HighScore();
}
@@ -1549,7 +1546,7 @@ int Song::GetNumTimesPlayed() const
int iTotalNumTimesPlayed = 0;
for( unsigned i=0; i<m_apNotes.size(); i++ )
{
iTotalNumTimesPlayed += m_apNotes[i]->m_MemCardScores[MEMORY_CARD_MACHINE].iNumTimesPlayed;
iTotalNumTimesPlayed += m_apNotes[i]->GetNumTimesPlayed(MEMORY_CARD_MACHINE);
}
return iTotalNumTimesPlayed;
}
@@ -1696,8 +1693,12 @@ int Song::GetNumNotesWithGrade( Grade g ) const
vector<Steps*> vNotes;
this->GetSteps( vNotes, GAMESTATE->GetCurrentStyleDef()->m_StepsType );
for( unsigned j=0; j<vNotes.size(); j++ )
if( vNotes[j]->m_MemCardScores[MEMORY_CARD_MACHINE].grade == g )
{
Steps* pSteps = vNotes[j];
if( pSteps->GetTopScore(MEMORY_CARD_MACHINE).grade == g )
iCount++;
}
return iCount;
}
+117 -225
View File
@@ -36,14 +36,12 @@ SongManager* SONGMAN = NULL; // global and accessable from anywhere in our progr
#define SONGS_DIR BASE_PATH "Songs" SLASH
#define COURSES_DIR BASE_PATH "Courses" SLASH
#define STATS_PATH BASE_PATH "stats.html"
const CString CATEGORY_RANKING_FILE = BASE_PATH "Data" SLASH "CategoryRanking.dat";
const CString COURSE_RANKING_FILE = BASE_PATH "Data" SLASH "CourseRanking.dat";
const CString MACHINE_NOTES_SCORES_FILE = "Data" SLASH "MachineNotesScores.dat";
const CString MACHINE_COURSE_SCORES_FILE = "Data" SLASH "MachineCourseScores.dat";
const CString CATEGORY_RANKING_FILE = BASE_PATH "Data" SLASH "CategoryRanking.dat";
const CString MACHINE_STEPS_MEM_CARD_DATA = BASE_PATH "Data" SLASH "MachineStepsMemCardData.dat";
const CString MACHINE_COURSE_MEM_CARD_DATA = BASE_PATH "Data" SLASH "MachineCourseMemCardData.dat";
const int CATEGORY_RANKING_VERSION = 1;
const int COURSE_RANKING_VERSION = 1;
const int NOTES_SCORES_VERSION = 2;
const int COURSE_SCORES_VERSION = 1;
const int STEPS_MEM_CARD_DATA_VERSION = 3;
const int COURSE_MEM_CARD_DATA_VERSION = 2;
#define NUM_GROUP_COLORS THEME->GetMetricI("SongManager","NumGroupColors")
@@ -121,9 +119,8 @@ void SongManager::Reload()
void SongManager::SaveMachineScoresToDisk()
{
SaveCategoryRankingsToFile( CATEGORY_RANKING_FILE );
SaveCourseRankingsToFile( COURSE_RANKING_FILE );
SaveNoteScoresToFile( MACHINE_NOTES_SCORES_FILE, MEMORY_CARD_MACHINE );
SaveCourseScoresToFile( MACHINE_COURSE_SCORES_FILE, MEMORY_CARD_MACHINE );
SaveStepsMemCardDataToFile( MACHINE_STEPS_MEM_CARD_DATA, MEMORY_CARD_MACHINE );
SaveCourseMemCardDataToFile( MACHINE_COURSE_MEM_CARD_DATA, MEMORY_CARD_MACHINE );
}
void SongManager::InitSongsFromDisk( LoadingWindow *ld )
@@ -308,7 +305,7 @@ static CString ReadLine( FILE *fp )
}
void SongManager::ReadNoteScoresFromFile( CString fn, int c )
void SongManager::ReadStepsMemCardDataFromFile( CString fn, int c )
{
ifstream f(fn);
if( !f.good() )
@@ -319,7 +316,7 @@ void SongManager::ReadNoteScoresFromFile( CString fn, int c )
int version;
sscanf(line.c_str(), "%i", &version);
if( version != NOTES_SCORES_VERSION )
if( version != STEPS_MEM_CARD_DATA_VERSION )
return;
while( f && !f.eof() )
@@ -357,59 +354,32 @@ void SongManager::ReadNoteScoresFromFile( CString fn, int c )
getline(f, line);
int iNumTimesPlayed;
Grade grade;
float fScore;
if( sscanf(line.c_str(), "%d %d %f\n", &iNumTimesPlayed, (int *)&grade, &fScore) != 3 )
break;
if( sscanf(line.c_str(), "%d\n", &iNumTimesPlayed ) != 1 )
return;
if( pNotes )
pNotes->m_MemCardDatas[c].iNumTimesPlayed = iNumTimesPlayed;
if( pNotes )
pNotes->m_MemCardDatas[c].vHighScores.resize(NUM_RANKING_LINES);
for( int k=0; k<NUM_RANKING_LINES; k++ )
{
pNotes->m_MemCardScores[c].iNumTimesPlayed = iNumTimesPlayed;
pNotes->m_MemCardScores[c].grade = grade;
pNotes->m_MemCardScores[c].fScore = fScore;
Grade grade;
float fScore;
char szName[256]; // TODO: not overflow safe
if( sscanf(line.c_str(), "%d %f %[^\n]\n", (int *)&grade, &fScore, szName) != 3 )
return;
if( pNotes )
{
pNotes->m_MemCardDatas[c].vHighScores[k].grade = grade;
pNotes->m_MemCardDatas[c].vHighScores[k].fScore = fScore;
pNotes->m_MemCardDatas[c].vHighScores[k].sName = szName;
}
}
}
}
}
void SongManager::ReadCourseScoresFromFile( CString fn, int c )
{
FILE* fp = fopen( fn, "r" );
if( !fp )
return;
int version;
fscanf(fp, "%d\n", &version );
if( version == COURSE_SCORES_VERSION )
{
while( fp && !feof(fp) )
{
CString path=ReadLine( fp );
Course* pCourse = GetCourseFromPath( path );
if( pCourse == NULL )
pCourse = GetCourseFromName( path );
for( int i=0; i<NUM_STEPS_TYPES; i++ )
if( !feof(fp) )
{
int iNumTimesPlayed;
int iScore;
float fSurviveTime;
fscanf(fp, "%d %d %f\n", &iNumTimesPlayed, &iScore, &fSurviveTime);
if( pCourse )
{
pCourse->m_MemCardScores[c][i].iNumTimesPlayed = iNumTimesPlayed;
pCourse->m_MemCardScores[c][i].iScore = iScore;
pCourse->m_MemCardScores[c][i].fSurviveTime = fSurviveTime;
}
}
}
}
fclose(fp);
}
void SongManager::ReadCategoryRankingsFromFile( CString fn )
{
@@ -422,27 +392,32 @@ void SongManager::ReadCategoryRankingsFromFile( CString fn )
if( version == CATEGORY_RANKING_VERSION )
{
for( int i=0; i<NUM_STEPS_TYPES; i++ )
{
for( int j=0; j<NUM_RANKING_CATEGORIES; j++ )
{
m_CategoryDatas[i][j].vHighScores.resize(NUM_RANKING_LINES);
for( int k=0; k<NUM_RANKING_LINES; k++ )
if( !feof(fp) )
{
char szName[256];
fscanf(fp, "%i %[^\n]\n", &m_MachineScores[i][j][k].iScore, szName);
m_MachineScores[i][j][k].sName = szName;
char szName[256]; // TODO: not overflow safe
fscanf(fp, "%i %[^\n]\n", &m_CategoryDatas[i][j].vHighScores[k].iScore, szName);
m_CategoryDatas[i][j].vHighScores[k].sName = szName;
}
}
}
}
fclose(fp);
}
void SongManager::ReadCourseRankingsFromFile( CString fn )
void SongManager::ReadCourseMemCardDataFromFile( CString fn, int c )
{
FILE* fp = fopen( fn, "r" );
if( !fp )
return;
int version;
fscanf(fp, "%i\n", &version );
if( version == COURSE_RANKING_VERSION )
if( version == COURSE_MEM_CARD_DATA_VERSION )
{
while( fp && !feof(fp) )
{
@@ -451,22 +426,33 @@ void SongManager::ReadCourseRankingsFromFile( CString fn )
Course* pCourse = GetCourseFromPath( path );
if( pCourse == NULL )
pCourse = GetCourseFromName( path );
// even if we don't find the Course*, we still have to read past the input
for( int i=0; i<NUM_STEPS_TYPES; i++ )
{
int iNumTimesPlayed;
fscanf(fp, "%d\n", &iNumTimesPlayed);
if( pCourse )
pCourse->m_MemCardDatas[i][c].iNumTimesPlayed = iNumTimesPlayed;
if( pCourse )
pCourse->m_MemCardDatas[i][c].vHighScores.resize(NUM_RANKING_LINES);
for( int j=0; j<NUM_RANKING_LINES; j++ )
{
if( !feof(fp) )
{
int iScore;
float fSurviveTime;
char szName[256];
char szName[256]; // TODO: not overflow safe
fscanf(fp, "%d %f %[^\n]\n", &iScore, &fSurviveTime, szName);
if( pCourse )
{
pCourse->m_RankingScores[i][j].iScore = iScore;
pCourse->m_RankingScores[i][j].fSurviveTime = fSurviveTime;
pCourse->m_RankingScores[i][j].sName = szName;
pCourse->m_MemCardDatas[i][c].vHighScores[j].iScore = iScore;
pCourse->m_MemCardDatas[i][c].vHighScores[j].fSurviveTime = fSurviveTime;
pCourse->m_MemCardDatas[i][c].vHighScores[j].sName = szName;
}
}
}
}
}
}
@@ -475,30 +461,17 @@ void SongManager::ReadCourseRankingsFromFile( CString fn )
void SongManager::InitMachineScoresFromDisk()
{
// Init category ranking
{
for( int i=0; i<NUM_STEPS_TYPES; i++ )
for( int j=0; j<NUM_RANKING_CATEGORIES; j++ )
for( int k=0; k<NUM_RANKING_LINES; k++ )
{
m_MachineScores[i][j][k].iScore = 573000;
m_MachineScores[i][j][k].sName = DEFAULT_RANKING_NAME;
}
}
// read old style notes scores
ReadSM300NoteScores();
// category ranking
ReadCategoryRankingsFromFile( CATEGORY_RANKING_FILE );
ReadCourseRankingsFromFile( COURSE_RANKING_FILE );
ReadNoteScoresFromFile( MACHINE_NOTES_SCORES_FILE, MEMORY_CARD_MACHINE );
ReadCourseScoresFromFile( MACHINE_COURSE_SCORES_FILE, MEMORY_CARD_MACHINE );
ReadCourseMemCardDataFromFile( MACHINE_COURSE_MEM_CARD_DATA, MEMORY_CARD_MACHINE );
ReadStepsMemCardDataFromFile( MACHINE_STEPS_MEM_CARD_DATA, MEMORY_CARD_MACHINE );
}
void SongManager::ReadSM300NoteScores()
{
{
IniFile ini;
ini.SetPath( SM_300_STATISTICS_FILE );
if( !ini.ReadFile() ) {
@@ -548,18 +521,20 @@ void SongManager::ReadSM300NoteScores()
char szGradeLetters[10]; // longest possible string is "AAA"
int iMaxCombo; // throw away
pNotes->m_MemCardDatas[MEMORY_CARD_MACHINE].vHighScores.resize(1);
iRetVal = sscanf(
value,
"%d::%[^:]::%f::%d",
&pNotes->m_MemCardScores[MEMORY_CARD_MACHINE].iNumTimesPlayed,
&pNotes->m_MemCardDatas[MEMORY_CARD_MACHINE].iNumTimesPlayed,
szGradeLetters,
&pNotes->m_MemCardScores[MEMORY_CARD_MACHINE].fScore,
&pNotes->m_MemCardDatas[MEMORY_CARD_MACHINE].vHighScores[0].fScore,
&iMaxCombo
);
if( iRetVal != 4 )
continue;
pNotes->m_MemCardScores[MEMORY_CARD_MACHINE].grade = StringToGrade( szGradeLetters );
pNotes->m_MemCardDatas[MEMORY_CARD_MACHINE].vHighScores[0].grade = StringToGrade( szGradeLetters );
}
}
}
@@ -568,66 +543,79 @@ void SongManager::ReadSM300NoteScores()
void SongManager::SaveCategoryRankingsToFile( CString fn )
{
// category ranking
LOG->Trace("Writing category ranking");
LOG->Trace("SongManager::SaveCategoryRankingsToFile");
FILE* fp = fopen( fn, "w" );
if( fp )
{
fprintf(fp,"%d\n",CATEGORY_RANKING_VERSION);
for( int i=0; i<NUM_STEPS_TYPES; i++ )
{
for( int j=0; j<NUM_RANKING_CATEGORIES; j++ )
{
m_CategoryDatas[i][j].vHighScores.resize(NUM_RANKING_LINES);
for( int k=0; k<NUM_RANKING_LINES; k++ )
{
if( fp )
fprintf(fp, "%i %s\n", m_MachineScores[i][j][k].iScore, m_MachineScores[i][j][k].sName.c_str());
{
fprintf(fp, "%i %s\n",
m_CategoryDatas[i][j].vHighScores[k].iScore,
m_CategoryDatas[i][j].vHighScores[k].sName.c_str());
}
}
}
}
fclose(fp);
}
}
void SongManager::SaveCourseRankingsToFile( CString fn )
void SongManager::SaveCourseMemCardDataToFile( CString fn, int c )
{
// course ranking
LOG->Trace("Writing course ranking");
LOG->Trace("SongManager::SaveCourseMemCardDataToFile");
FILE* fp = fopen( fn, "w" );
if( fp )
{
FILE* fp = fopen( fn, "w" );
if( fp )
fprintf(fp,"%d\n",COURSE_MEM_CARD_DATA_VERSION);
for( unsigned i=0; i<m_pCourses.size(); i++ ) // foreach course
{
fprintf(fp,"%d\n",COURSE_RANKING_VERSION);
for( unsigned c=0; c<m_pCourses.size(); c++ ) // foreach course
Course* pCourse = m_pCourses[i];
ASSERT(pCourse);
if( pCourse->m_bIsAutogen )
fprintf(fp, "%s\n", pCourse->m_sName.c_str());
else
fprintf(fp, "%s\n", pCourse->m_sPath.c_str());
for( int j=0; j<NUM_STEPS_TYPES; j++ )
{
Course* pCourse = m_pCourses[c];
ASSERT(pCourse);
if( pCourse->m_bIsAutogen )
fprintf(fp, "%s\n", pCourse->m_sName.c_str());
else
fprintf(fp, "%s\n", pCourse->m_sPath.c_str());
for( int i=0; i<NUM_STEPS_TYPES; i++ )
for( int j=0; j<NUM_RANKING_LINES; j++ )
{
fprintf(fp, "%d %f %s\n",
pCourse->m_RankingScores[i][j].iScore,
pCourse->m_RankingScores[i][j].fSurviveTime,
pCourse->m_RankingScores[i][j].sName.c_str());
}
fprintf(fp, "%d\n", pCourse->m_MemCardDatas[j][c].iNumTimesPlayed);
pCourse->m_MemCardDatas[j][c].vHighScores.resize(NUM_RANKING_LINES);
for( int k=0; k<NUM_RANKING_LINES; k++ )
{
fprintf(fp, "%d %f %s\n",
pCourse->m_MemCardDatas[j][c].vHighScores[k].iScore,
pCourse->m_MemCardDatas[j][c].vHighScores[k].fSurviveTime,
pCourse->m_MemCardDatas[j][c].vHighScores[k].sName.c_str());
}
}
fclose(fp);
}
}
fclose(fp);
}
}
void SongManager::SaveNoteScoresToFile( CString fn, int c )
void SongManager::SaveStepsMemCardDataToFile( CString fn, int c )
{
// notes scores
LOG->Trace("Writing note scores to %s", fn.c_str());
LOG->Trace("SongManager::SaveStepsMemCardDataToFile %s", fn.c_str());
{
FILE* fp = fopen( fn, "w" );
if( fp )
{
fprintf(fp,"%d\n",NOTES_SCORES_VERSION);
fprintf(fp,"%d\n",STEPS_MEM_CARD_DATA_VERSION);
for( unsigned s=0; s<m_pSongs.size(); s++ ) // foreach song
{
@@ -635,15 +623,6 @@ void SongManager::SaveNoteScoresToFile( CString fn, int c )
ASSERT(pSong);
vector<Steps*> vNotes = pSong->m_apNotes;
/* This prevents the play count from being saved for songs that havn't
* been passed. Though, it seems we only increment this when it's
* passed, anyway ...
for( int n=(int)vNotes.size()-1; n>=0; n-- )
{
if( vNotes[n]->m_MemCardScores[c].grade <= GRADE_E )
vNotes.erase( vNotes.begin()+n );
}
*/
if( vNotes.size() == 0 )
continue; // skip
@@ -661,10 +640,17 @@ void SongManager::SaveNoteScoresToFile( CString fn, int c )
pNotes->GetDifficulty(),
pNotes->GetDescription().c_str() );
fprintf(fp, "%d %d %f\n",
pNotes->m_MemCardScores[c].iNumTimesPlayed,
pNotes->m_MemCardScores[c].grade,
pNotes->m_MemCardScores[c].fScore);
fprintf(fp, "%d\n", pNotes->m_MemCardDatas[c].iNumTimesPlayed );
pNotes->m_MemCardDatas[c].vHighScores.resize(NUM_RANKING_LINES);
for( int j=0; j<NUM_RANKING_LINES; j++ )
{
fprintf(fp, "%d %f %s\n",
pNotes->m_MemCardDatas[c].vHighScores[j].grade,
pNotes->m_MemCardDatas[c].vHighScores[j].fScore,
pNotes->m_MemCardDatas[c].vHighScores[j].sName.c_str());
}
}
}
@@ -673,38 +659,6 @@ void SongManager::SaveNoteScoresToFile( CString fn, int c )
}
}
void SongManager::SaveCourseScoresToFile( CString fn, int c )
{
// course scores
LOG->Trace("Writing course scores to %s", fn.c_str());
{
FILE* fp = fopen( fn, "w" );
if( fp )
{
fprintf(fp,"%d\n",COURSE_SCORES_VERSION);
for( unsigned i=0; i<m_pCourses.size(); i++ ) // foreach song
{
Course* pCourse = m_pCourses[i];
ASSERT(pCourse);
if( pCourse->m_bIsAutogen )
fprintf(fp, "%s\n", pCourse->m_sName.c_str());
else
fprintf(fp, "%s\n", pCourse->m_sPath.c_str());
for( int nt=0; nt<NUM_STEPS_TYPES; nt++ )
fprintf(fp, "%d %d %f\n",
pCourse->m_MemCardScores[c][nt].iNumTimesPlayed,
pCourse->m_MemCardScores[c][nt].iScore,
pCourse->m_MemCardScores[c][nt].fSurviveTime);
}
fclose(fp);
}
}
}
CString SongManager::GetGroupBannerPath( CString sGroupName )
{
@@ -1183,68 +1137,6 @@ Course* SongManager::GetCourseFromName( CString sName )
}
struct CategoryScoreToInsert
{
PlayerNumber pn;
RankingCategory cat;
int iScore;
static int CompareDescending( const CategoryScoreToInsert &hs1, const CategoryScoreToInsert &hs2 )
{
return hs1.iScore > hs2.iScore;
}
static void SortDescending( vector<CategoryScoreToInsert>& vHSout )
{
sort( vHSout.begin(), vHSout.end(), CompareDescending );
}
};
// set iNewRecordIndex = -1 if not a new record
void SongManager::AddScores( StepsType nt, bool bPlayerEnabled[NUM_PLAYERS],
RankingCategory hsc[NUM_PLAYERS],
int iScore[NUM_PLAYERS],
int iNewRecordIndexOut[NUM_PLAYERS] )
{
vector<CategoryScoreToInsert> vHS;
for( int p=0; p<NUM_PLAYERS; p++ )
{
iNewRecordIndexOut[p] = -1;
if( !bPlayerEnabled[p] )
continue; // skip
CategoryScoreToInsert hs;
hs.pn = (PlayerNumber)p;
hs.cat = hsc[p];
hs.iScore = iScore[p];
vHS.push_back( hs );
}
// Sort descending before inserting.
// This guarantees that a high score will not switch poitions on us when we later insert scores for the other player
CategoryScoreToInsert::SortDescending( vHS );
for( unsigned i=0; i<vHS.size(); i++ )
{
CategoryScoreToInsert& newHS = vHS[i];
MachineScore* machineScores = m_MachineScores[nt][newHS.cat];
for( int i=0; i<NUM_RANKING_LINES; i++ )
{
if( newHS.iScore > machineScores[i].iScore )
{
// We found the insert point. Shift down.
for( int j=NUM_RANKING_LINES-1; j>i; j-- )
machineScores[j] = machineScores[j-1];
// insert
machineScores[i].iScore = newHS.iScore;
machineScores[i].sName = DEFAULT_RANKING_NAME;
iNewRecordIndexOut[newHS.pn] = i;
break;
}
}
}
}
/*
* GetSongDir() contains a path to the song, possibly a full path, eg:
* Songs\Group\SongName or
+45 -11
View File
@@ -89,26 +89,60 @@ public:
void InitMachineScoresFromDisk();
void SaveMachineScoresToDisk();
struct MachineScore
struct CategoryData
{
int iScore;
CString sName;
} m_MachineScores[NUM_STEPS_TYPES][NUM_RANKING_CATEGORIES][NUM_RANKING_LINES];
void AddScores( StepsType nt, bool bPlayerEnabled[NUM_PLAYERS], RankingCategory hsc[NUM_PLAYERS], int iScore[NUM_PLAYERS], int iNewRecordIndexOut[NUM_PLAYERS] ); // set iNewRecordIndex = -1 if not a new record
struct HighScore
{
int iScore;
CString sName;
HighScore()
{
iScore = 0;
}
bool operator>( const HighScore& other )
{
return iScore > other.iScore;
}
};
vector<HighScore> vHighScores;
void AddHighScore( HighScore hs, int &iIndexOut )
{
for( int i=0; i<vHighScores.size() && i<NUM_RANKING_LINES; i++ )
{
if( hs > vHighScores[i] )
{
vHighScores.insert( vHighScores.begin()+i, hs );
iIndexOut = i;
break;
}
}
if( vHighScores.size() > NUM_RANKING_LINES )
vHighScores.erase( vHighScores.begin()+NUM_RANKING_LINES, vHighScores.end() );
}
} m_CategoryDatas[NUM_STEPS_TYPES][NUM_RANKING_CATEGORIES];
void AddHighScore( StepsType nt, RankingCategory rc, PlayerNumber pn, CategoryData::HighScore hs, int &iMachineIndexOut )
{
hs.sName = RANKING_TO_FILL_IN_MARKER[pn];
m_CategoryDatas[nt][rc].AddHighScore( hs, iMachineIndexOut );
}
void UpdateBest();
void UpdateRankingCourses();
void ReadSM300NoteScores();
void ReadNoteScoresFromFile( CString fn, int c );
void ReadCourseScoresFromFile( CString fn, int c );
void ReadStepsMemCardDataFromFile( CString fn, int c );
void ReadCourseMemCardDataFromFile( CString fn, int c );
void ReadCategoryRankingsFromFile( CString fn );
void ReadCourseRankingsFromFile( CString fn );
void SaveNoteScoresToFile( CString fn, int c );
void SaveCourseScoresToFile( CString fn, int c );
void SaveStepsMemCardDataToFile( CString fn, int c );
void SaveCourseMemCardDataToFile( CString fn, int c );
void SaveCategoryRankingsToFile( CString fn );
void SaveCourseRankingsToFile( CString fn );
protected:
void LoadStepManiaSongDir( CString sDir, LoadingWindow *ld );
+1
View File
@@ -34,6 +34,7 @@ void StageStats::AddStats( const StageStats& other )
for( int p=0; p<NUM_PLAYERS; p++ )
{
pSteps[p] = NULL;
iMeter[p] += other.iMeter[p] * iLengthMultiplier;
fAliveSeconds[p] += other.fAliveSeconds[p];
bFailed[p] |= other.bFailed[p];
+2
View File
@@ -16,6 +16,7 @@
#include "GameConstantsAndTypes.h"
#include "Grade.h"
class Song;
class Steps;
struct StageStats
@@ -28,6 +29,7 @@ struct StageStats
Song* pSong;
enum { STAGE_INVALID, STAGE_NORMAL, STAGE_EXTRA, STAGE_EXTRA2 } StageType;
Steps* pSteps[NUM_PLAYERS];
int iMeter[NUM_PLAYERS];
float fAliveSeconds[NUM_PLAYERS]; // how far into the music did they last before failing? Updated by Gameplay.
-44
View File
@@ -41,13 +41,6 @@ Steps::Steps()
notes = NULL;
notes_comp = NULL;
parent = NULL;
for( int m=0; m<NUM_MEMORY_CARDS; m++ )
{
m_MemCardScores[m].iNumTimesPlayed = 0;
m_MemCardScores[m].grade = GRADE_NO_DATA;
m_MemCardScores[m].fScore = 0;
}
}
Steps::~Steps()
@@ -292,43 +285,6 @@ void Steps::SetRadarValue(int r, float val)
}
/* 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? */
bool Steps::MemCardScore::HigherScore( float vsScore, Grade vsGrade ) const
{
if( vsScore > this->fScore )
return true;
if( vsScore < this->fScore )
return false;
return vsGrade > this->grade;
}
void Steps::AddScore( PlayerNumber pn, Grade grade, float fScore, bool& bNewRecordOut )
{
bNewRecordOut = false;
m_MemCardScores[MEMORY_CARD_MACHINE].iNumTimesPlayed++;
m_MemCardScores[pn].iNumTimesPlayed++;
if( m_MemCardScores[pn].HigherScore(fScore, grade) && fScore > 0)
{
m_MemCardScores[pn].fScore = fScore;
m_MemCardScores[pn].grade = grade;
bNewRecordOut = true;
}
if( m_MemCardScores[MEMORY_CARD_MACHINE].HigherScore(fScore, grade) )
{
m_MemCardScores[MEMORY_CARD_MACHINE].fScore = fScore;
m_MemCardScores[MEMORY_CARD_MACHINE].grade = grade;
}
}
//
// Sorting stuff
//
+77 -7
View File
@@ -53,17 +53,87 @@ public:
CString GetSMNoteData() const;
// High scores
struct MemCardScore
struct MemCardData
{
MemCardData()
{
iNumTimesPlayed = 0;
}
int iNumTimesPlayed;
Grade grade;
float fScore;
bool HigherScore( float fScore, Grade grade ) const;
} m_MemCardScores[NUM_MEMORY_CARDS];
void AddScore( PlayerNumber pn, Grade grade, float fScore, bool& bNewRecordOut );
struct HighScore
{
CString sName;
Grade grade;
float fScore;
HighScore()
{
grade = GRADE_NO_DATA;
fScore = 0;
}
bool operator>( const HighScore& other )
{
return fScore > other.fScore;
/* 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;
}
};
vector<HighScore> vHighScores;
void AddHighScore( MemCardData::HighScore hs, int &iIndexOut )
{
for( int i=0; i<vHighScores.size() && i<NUM_RANKING_LINES; i++ )
{
if( hs > vHighScores[i] )
{
vHighScores.insert( vHighScores.begin()+i, hs );
iIndexOut = i;
break;
}
}
if( vHighScores.size() > NUM_RANKING_LINES )
vHighScores.erase( vHighScores.begin()+NUM_RANKING_LINES, vHighScores.end() );
}
HighScore GetTopScore()
{
if( vHighScores.empty() )
return HighScore();
else
return vHighScores[0];
}
} m_MemCardDatas[NUM_MEMORY_CARDS];
void AddHighScore( PlayerNumber pn, MemCardData::HighScore hs, int &iPersonalIndexOut, int &iMachineIndexOut )
{
hs.sName = RANKING_TO_FILL_IN_MARKER[pn];
m_MemCardDatas[pn].AddHighScore( hs, iPersonalIndexOut );
m_MemCardDatas[MEMORY_CARD_MACHINE].AddHighScore( hs, iMachineIndexOut );
}
MemCardData::HighScore GetTopScore( MemoryCard card )
{
return m_MemCardDatas[card].GetTopScore();
}
int GetNumTimesPlayed( MemoryCard card )
{
return m_MemCardDatas[card].iNumTimesPlayed;
}
void TidyUpData();
+2 -2
View File
@@ -14,7 +14,7 @@
#include "PlayerNumber.h"
#include "GameConstantsAndTypes.h"
#include "Grade.h"
class Steps;
#include "Steps.h" // TODO: remove this dependency!
class StyleDef;
class NotesLoader;
class LyricsLoader;
@@ -254,7 +254,7 @@ public:
bool IsNew() const;
bool IsEasy( StepsType nt ) const;
bool HasEdits( StepsType nt ) const;
Grade GetGradeForDifficulty( const StyleDef *s, MemoryCard card, Difficulty dc ) const;
Steps::MemCardData::HighScore GetHighScoreForDifficulty( const StyleDef *st, MemoryCard card, Difficulty dc ) const;
bool NormallyDisplayed() const;
bool RouletteDisplayed() const;
int GetNumNotesWithGrade( Grade g ) const;