add top5 high score saving of Courses and Steps for memory cards/ranking screen
This commit is contained in:
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 )
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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] );
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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 );
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user