working on course ranking scores and mem card saving

This commit is contained in:
Chris Danford
2003-02-14 21:42:44 +00:00
parent b47254c32b
commit e05738f7f7
21 changed files with 672 additions and 422 deletions
+10
View File
@@ -934,3 +934,13 @@ TwoLinesArtistY=8
ThreeLinesTitleY=-10 ThreeLinesTitleY=-10
ThreeLinesSubTitleY=0 ThreeLinesSubTitleY=0
ThreeLinesArtistY=10 ThreeLinesArtistY=10
[CourseContentDisplay]
TextBannerX=0
TextBannerY=0
NumberX=-118
NumberY=0
FootX=102
FootY=8
DifficultyX=120
DifficultyY=8
+168 -143
View File
@@ -15,7 +15,6 @@
#include "Song.h" #include "Song.h"
#include "GameManager.h" #include "GameManager.h"
#include "SongManager.h" #include "SongManager.h"
#include "GameState.h"
#include "RageException.h" #include "RageException.h"
#include "RageLog.h" #include "RageLog.h"
#include "MsdFile.h" #include "MsdFile.h"
@@ -24,31 +23,31 @@
#include "RageUtil.h" #include "RageUtil.h"
#include "TitleSubstitution.h" #include "TitleSubstitution.h"
Course::Course() Course::Course()
{ {
m_bIsAutoGen = false;
m_bRepeat = false; m_bRepeat = false;
m_bRandomize = false; m_bRandomize = false;
m_iLives = -1; m_iLives = -1;
m_iExtra = 0;
m_iNumTimesPlayed = 0;
// //
// Init high scores // Init high scores
// //
unsigned i, j; for( unsigned i=0; i<NUM_NOTES_TYPES; i++ )
for( i=0; i<NUM_NOTES_TYPES; i++ ) for( unsigned j=0; j<NUM_RANKING_LINES; j++ )
for( j=0; j<NUM_RANKING_LINES; j++ )
{ {
m_MachineScores[i][j].iDancePoints = 573; m_RankingScores[i][j].iDancePoints = 573;
m_MachineScores[i][j].fSurviveTime = 57.3f; m_RankingScores[i][j].fSurviveTime = 57.3f;
m_MachineScores[i][j].sName = "STEP"; m_RankingScores[i][j].sName = DEFAULT_RANKING_NAME;
} }
for( i=0; i<NUM_NOTES_TYPES; i++ ) for( unsigned m=0; m<NUM_MEMORY_CARDS; m++ )
for( j=0; j<NUM_PLAYERS; j++ ) for( unsigned i=0; i<NUM_NOTES_TYPES; i++ )
{ {
m_MemCardScores[i][j].iDancePoints = 0; m_MemCardScores[m][i].iNumTimesPlayed = 0;
m_MemCardScores[i][j].fSurviveTime = 0; m_MemCardScores[m][i].iDancePoints = 0;
m_MemCardScores[m][i].fSurviveTime = 0;
} }
} }
@@ -69,7 +68,7 @@ Course::Course()
* songs in "Songs"; we don't want that. * songs in "Songs"; we don't want that.
*/ */
Song *Course::FindSong(CString sSongDir) Song *Course::FindSong(CString sSongDir) const
{ {
const vector<Song*> &apSongs = SONGMAN->GetAllSongs(); const vector<Song*> &apSongs = SONGMAN->GetAllSongs();
@@ -156,21 +155,16 @@ void Course::LoadFromCRSFile( CString sPath )
else if( 0 == stricmp(sValueName, "SONG") ) else if( 0 == stricmp(sValueName, "SONG") )
{ {
CString sSongDir = sParams[1]; CString sSongDir = sParams[1];
CString sNotesDescription = sParams[2]; Difficulty dc = StringToDifficulty( sParams[2] );
CString sModifiers = sParams[3]; CString sModifiers = sParams[3];
if(!sSongDir.GetLength()) { if( sSongDir.GetLength() == 0 ) {
/* Err. */ /* Err. */
LOG->Trace( "Course file '%s' has an empty #SONG. Ignored.", sPath.GetString(), sSongDir.GetString() ); LOG->Trace( "Course file '%s' has an empty #SONG. Ignored.", sPath.GetString(), sSongDir.GetString() );
continue; continue;
} }
Song *pSong = FindSong(sSongDir); m_entries.push_back( course_entry(sSongDir, dc, sModifiers) );
if( pSong == NULL ) // we didn't find the Song
continue; // skip this song
AddStage( pSong, sNotesDescription, sModifiers );
} }
else else
@@ -184,8 +178,9 @@ void Course::LoadFromCRSFile( CString sPath )
} }
void Course::CreateEndlessCourseFromGroupAndDifficulty( CString sGroupName, Difficulty dc, vector<Song*> &apSongsInGroup ) void Course::AutoGenEndlessFromGroupAndDifficulty( CString sGroupName, Difficulty dc, vector<Song*> &apSongsInGroup )
{ {
m_bIsAutoGen = true;
m_bRepeat = true; m_bRepeat = true;
m_bRandomize = true; m_bRandomize = true;
m_iLives = -1; m_iLives = -1;
@@ -213,162 +208,204 @@ void Course::CreateEndlessCourseFromGroupAndDifficulty( CString sGroupName, Diff
for( unsigned s=0; s<apSongsInGroup.size(); s++ ) for( unsigned s=0; s<apSongsInGroup.size(); s++ )
{ {
Song* pSong = apSongsInGroup[s]; Song* pSong = apSongsInGroup[s];
AddStage( pSong, DifficultyToString(dc), "" ); m_entries.push_back( course_entry(pSong->GetSongDir(), dc, "") );
} }
Shuffle();
} }
void Course::Shuffle()
bool Course::HasDifficult() const
{ {
/* Shuffle the list. */ for( unsigned i=0; i<m_entries.size(); i++ )
for( int i = 0; i < GetNumStages(); ++i) if( m_entries[i].difficulty >= DIFFICULTY_HARD )
swap(order[i], order[rand() % GetNumStages()]); return false;
return true;
} }
Notes* Course::GetNotesForStage( int iStage )
{
Song* pSong = GetSong(iStage);
CString sDescription = entries[iStage].description;
/* First, search for an exact description match. */ void Course::GetCourseInfo(
unsigned i; vector<Song*>& vSongsOut,
for( i=0; i<pSong->m_apNotes.size(); i++ ) vector<Notes*>& vNotesOut,
vector<CString>& vsModifiersOut,
NotesType nt,
bool bDifficult ) const
{
if( bDifficult )
ASSERT( HasDifficult() );
vector<course_entry> entries = m_entries;
if( m_bRandomize )
random_shuffle( entries.begin(), entries.end() );
for( unsigned i=0; i<entries.size(); i++ )
{ {
Notes* pNotes = pSong->m_apNotes[i]; CString sSongDir = entries[i].songDir;
if( !GAMESTATE->GetCurrentStyleDef()->MatchesNotesType(pNotes->m_NotesType) ) Song* pSong;
continue; if( sSongDir.Left(strlen("PlayersBest")) == "PlayersBest" )
{
int iNumber = atoi( sSongDir.Right(sSongDir.length()-strlen("PlayersBest")) );
int index = iNumber - 1;
pSong = SONGMAN->GetPlayersBest( index );
}
else if( sSongDir.Left(strlen("PlayersWorst")) == "PlayersWorst" )
{
int iNumber = atoi( sSongDir.Right(sSongDir.length()-strlen("PlayersWorst")) );
int index = iNumber - 1;
pSong = SONGMAN->GetPlayersWorst( index );
}
else if( sSongDir.Right(1) == "*" )
{
CStringArray asSongDirs;
GetDirListing( sSongDir, asSongDirs, true, true );
if( asSongDirs.empty() )
pSong = NULL;
else
pSong = FindSong( asSongDirs[rand()%asSongDirs.size()] );
}
else
pSong = FindSong( sSongDir );
if( !pNotes->GetDescription().CompareNoCase(sDescription) ) if( pSong == NULL )
return pNotes;
}
/* If that failed, try to do a difficulty match. */
Difficulty dc = StringToDifficulty(sDescription);
for( i=0; i < pSong->m_apNotes.size(); i++ )
{
Notes* pNotes = pSong->m_apNotes[i];
if( !GAMESTATE->GetCurrentStyleDef()->MatchesNotesType(pNotes->m_NotesType) )
continue;
if(dc == pNotes->GetDifficulty())
return pNotes;
}
return NULL;
}
Song *Course::GetSong( int iStage ) const
{
return entries[iStage].song;
}
CString Course::GetDescription( int iStage ) const
{
return entries[iStage].description;
}
void Course::AddStage( Song* pSong, CString sDescription, CString sModifiers )
{
course_entry e;
e.song = pSong;
e.description = sDescription;
e.modifiers = sModifiers;
entries.push_back(e);
order.push_back(order.size());
}
/* When bShuffled is true, returns courses in the song ordering list. */
void Course::GetSongAndNotesForCurrentStyle(
vector<Song*>& apSongsOut,
vector<Notes*>& apNotesOut,
CStringArray& asModifiersOut,
bool bShuffled )
{
for( int i=0; i<GetNumStages(); i++ )
{
int num = bShuffled? order[i]:i;
Song* pSong = GetSong(num);
Notes* pNotes = GetNotesForStage( num );
CString sModifiers = entries[num].modifiers;
if( !pSong->HasMusic() )
continue; // skip continue; // skip
Difficulty dc = entries[i].difficulty;
if( bDifficult && dc != NUM_DIFFICULTIES-1 )
dc = (Difficulty)(dc+1);
Notes* pNotes = pSong->GetNotes( nt, dc );
if( pNotes == NULL ) if( pNotes == NULL )
continue; // skip continue; // skip
apSongsOut.push_back( pSong );
apNotesOut.push_back( pNotes ); CString sModifiers = entries[i].modifiers;
asModifiersOut.push_back( sModifiers );
vSongsOut.push_back( pSong );
vNotesOut.push_back( pNotes );
vsModifiersOut.push_back( sModifiers );
} }
} }
RageColor Course::GetColor() bool Course::GetFirstStageInfo(
Song*& pSongOut,
Notes*& pNotesOut,
CString& sModifiersOut,
NotesType nt ) const
{
vector<Song*> vSongs;
vector<Notes*> vNotes;
vector<CString> vsModifiers;
GetCourseInfo(
vSongs,
vNotes,
vsModifiers,
nt,
false );
if( vSongs.empty() )
return false;
pSongOut = vSongs[0];
pNotesOut = vNotes[0];
sModifiersOut = vsModifiers[0];
return true;
}
RageColor Course::GetColor() const
{ {
// This could be made smarter // This could be made smarter
if( GetNumStages() >= 7 ) if( m_entries.size() >= 7 )
return RageColor(1,0,0,1); // red return RageColor(1,0,0,1); // red
else if( GetNumStages() >= 4 ) else if( m_entries.size() >= 4 )
return RageColor(1,0.5f,0,1); // orange return RageColor(1,0.5f,0,1); // orange
else else
return RageColor(0,1,0,1); // green return RageColor(0,1,0,1); // green
} }
void Course::GetPlayerOptions( int iStage, PlayerOptions* pPO_out ) const bool Course::IsMysterySong( int stage ) const
{ {
pPO_out->FromString( entries[iStage].modifiers ); CString sSongDir = m_entries[stage].songDir;
return sSongDir.Right(1) == "*";
} }
void Course::GetSongOptions( SongOptions* pSO_out ) const bool Course::ContainsAnyMysterySongs() const
{ {
*pSO_out = SongOptions(); for( unsigned i=0; i<m_entries.size(); i++ )
//hack: The lifebar modifiers were not showing up (in the extra stages) - had to add it here. if( IsMysterySong(i) )
if( entries.size() > 0 ) return true;
pSO_out->FromString( entries[0].modifiers ); return false;
pSO_out->m_LifeType = (m_iLives==-1) ? SongOptions::LIFE_BAR : SongOptions::LIFE_BATTERY;
if( m_iLives != -1 )
pSO_out->m_iBatteryLives = m_iLives;
} }
int Course::GetNumStages() const bool Course::GetTotalSeconds( float& fSecondsOut ) const
{ {
return entries.size(); if( ContainsAnyMysterySongs() )
return false;
vector<Song*> vSongsOut;
vector<Notes*> vNotesOut;
vector<CString> vsModifiersOut;
GetCourseInfo(
vSongsOut,
vNotesOut,
vsModifiersOut,
NOTES_TYPE_DANCE_SINGLE, // doesn't matter
false ); // doesn't matter
fSecondsOut = 0;
for( unsigned i=0; i<vSongsOut.size(); i++ )
fSecondsOut += vSongsOut[i]->m_fMusicLengthSeconds;
return true;
} }
struct CourseScoreToInsert struct RankingToInsert
{ {
PlayerNumber pn; PlayerNumber pn;
int iDancePoints; int iDancePoints;
float fSurviveTime; float fSurviveTime;
static int CompareDescending( const CourseScoreToInsert &hs1, const CourseScoreToInsert &hs2 ) static int CompareDescending( const RankingToInsert &hs1, const RankingToInsert &hs2 )
{ {
if( hs1.iDancePoints > hs2.iDancePoints ) return -1; if( hs1.iDancePoints > hs2.iDancePoints ) return -1;
else if( hs1.iDancePoints == hs2.iDancePoints ) return 0; else if( hs1.iDancePoints == hs2.iDancePoints ) return 0;
else return +1; else return +1;
} }
static void SortDescending( vector<CourseScoreToInsert>& vHSout ) static void SortDescending( vector<RankingToInsert>& vHSout )
{ {
sort( vHSout.begin(), vHSout.end(), CompareDescending ); sort( vHSout.begin(), vHSout.end(), CompareDescending );
} }
}; };
void Course::AddMachineRecords( NotesType nt, int iDancePoints[NUM_PLAYERS], float fSurviveTime[NUM_PLAYERS], int iRankingIndexOut[NUM_PLAYERS] ) // set iNewRecordIndex = -1 if not a new record void Course::AddScores( NotesType nt, bool bPlayerEnabled[NUM_PLAYERS], int iDancePoints[NUM_PLAYERS], float fSurviveTime[NUM_PLAYERS], int iRankingIndexOut[NUM_PLAYERS], bool bNewRecordOut[NUM_PLAYERS] )
{ {
vector<CourseScoreToInsert> vHS; m_MemCardScores[MEMORY_CARD_MACHINE][nt].iNumTimesPlayed++;
vector<RankingToInsert> vHS;
for( int p=0; p<NUM_PLAYERS; p++ ) for( int p=0; p<NUM_PLAYERS; p++ )
{ {
iRankingIndexOut[p] = -1; iRankingIndexOut[p] = -1;
bNewRecordOut = false;
if( !GAMESTATE->IsPlayerEnabled(p) ) if( !bPlayerEnabled[p] )
continue; // skip continue; // skip
CourseScoreToInsert hs;
// Update memory card
m_MemCardScores[p][nt].iNumTimesPlayed++;
if( iDancePoints[p] > m_MemCardScores[p][nt].iDancePoints )
{
m_MemCardScores[p][nt].iDancePoints = iDancePoints[p];
m_MemCardScores[p][nt].fSurviveTime = fSurviveTime[p];
bNewRecordOut[p] = true;
}
// Update Ranking
RankingToInsert hs;
hs.iDancePoints = iDancePoints[p]; hs.iDancePoints = iDancePoints[p];
hs.fSurviveTime = fSurviveTime[p]; hs.fSurviveTime = fSurviveTime[p];
hs.pn = (PlayerNumber)p; hs.pn = (PlayerNumber)p;
@@ -377,48 +414,36 @@ void Course::AddMachineRecords( NotesType nt, int iDancePoints[NUM_PLAYERS], flo
// Sort descending before inserting. // 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 // This guarantees that a high score will not switch poitions on us when we later insert scores for the other player
CourseScoreToInsert::SortDescending( vHS ); RankingToInsert::SortDescending( vHS );
for( unsigned i=0; i<vHS.size(); i++ ) for( unsigned i=0; i<vHS.size(); i++ )
{ {
CourseScoreToInsert& newHS = vHS[i]; RankingToInsert& newHS = vHS[i];
MachineScore* machineScores = m_MachineScores[nt]; RankingScore* rankingScores = m_RankingScores[nt];
for( int i=0; i<NUM_RANKING_LINES; i++ ) for( int i=0; i<NUM_RANKING_LINES; i++ )
{ {
if( newHS.iDancePoints > machineScores[i].iDancePoints ) if( newHS.iDancePoints > rankingScores[i].iDancePoints )
{ {
// We found the insert point. Shift down. // We found the insert point. Shift down.
for( int j=i+1; j<NUM_RANKING_LINES; j++ ) for( int j=i+1; j<NUM_RANKING_LINES; j++ )
machineScores[j] = machineScores[j-1]; rankingScores[j] = rankingScores[j-1];
// insert // insert
machineScores[i].fSurviveTime = newHS.fSurviveTime; rankingScores[i].fSurviveTime = newHS.fSurviveTime;
machineScores[i].iDancePoints = newHS.iDancePoints; rankingScores[i].iDancePoints = newHS.iDancePoints;
machineScores[i].sName = "STEP"; rankingScores[i].sName = DEFAULT_RANKING_NAME;
iRankingIndexOut[newHS.pn] = i; iRankingIndexOut[newHS.pn] = i;
} }
} }
} }
} }
bool Course::AddMemCardRecord( PlayerNumber pn, NotesType nt, int iDancePoints, float fSurviveTime ) // return true if new record
{
MemCardScore& hs = m_MemCardScores[nt][pn];
if( iDancePoints > hs.iDancePoints )
{
hs.iDancePoints = iDancePoints;
hs.fSurviveTime = fSurviveTime;
return true;
}
return false;
}
// //
// Sorting stuff // Sorting stuff
// //
static int CompareCoursePointersByDifficulty(const Course* pCourse1, const Course* pCourse2) static int CompareCoursePointersByDifficulty(const Course* pCourse1, const Course* pCourse2)
{ {
return pCourse1->GetNumStages() < pCourse2->GetNumStages(); return pCourse1->GetEstimatedNumStages() < pCourse2->GetEstimatedNumStages();
} }
void SortCoursePointerArrayByDifficulty( vector<Course*> &apCourses ) void SortCoursePointerArrayByDifficulty( vector<Course*> &apCourses )
+40 -28
View File
@@ -21,63 +21,75 @@ struct Notes;
class Course class Course
{ {
struct course_entry { struct course_entry {
CString description; // the Notes description course_entry( CString dir, Difficulty dc, CString mod )
CString modifiers; // set player and song options from these {
Song *song; songDir = dir;
difficulty = dc;
modifiers = mod;
}
CString songDir;
Difficulty difficulty; // the Notes description
CString modifiers; // set player and song options from these
}; };
vector<course_entry> entries; vector<course_entry> m_entries;
vector<int> order;
public: public:
Course(); Course();
bool m_bIsAutoGen; // was this created by AutoGen?
CString m_sPath; CString m_sPath;
CString m_sName; CString m_sName;
CString m_sBannerPath; CString m_sBannerPath;
CString m_sCDTitlePath; CString m_sCDTitlePath;
bool m_bRepeat; // repeat after last song? bool m_bRepeat; // repeat after last song? "Endless"
bool m_bRandomize; // play the songs in a random order bool m_bRandomize; // play the songs in a random order
int m_iLives; // -1 means use bar life meter int m_iLives; // -1 means use bar life meter
int m_iExtra; // extra stage number... int m_iExtra; // extra stage number... // not used? -Chris
int GetEstimatedNumStages() const { return m_entries.size(); }
bool HasDifficult() const;
void GetCourseInfo( // Derefrences course_entries and returns only the playable Songs and Notes
vector<Song*>& vSongsOut,
vector<Notes*>& vNotesOut,
vector<CString>& vsModifiersOut,
NotesType nt,
bool bDifficult ) const; // like EX's Standard/Difficult option for courses
bool GetFirstStageInfo(
Song*& pSongOut,
Notes*& pNotesOut,
CString& sModifiersOut,
NotesType nt ) const;
RageColor GetColor() const;
bool IsMysterySong( int stage ) const;
bool ContainsAnyMysterySongs() const;
bool GetTotalSeconds( float& fSecondsOut ) const;
Notes *GetNotesForStage( int iStage );
Song *GetSong( int iStage ) const;
CString GetDescription( int iStage ) const;
// CString GetModifiers( int iStage ) const; // redundant. -Chris
void GetPlayerOptions( int iStage, PlayerOptions* pPO_out ) const;
void GetSongOptions( SongOptions* pSO_out) const;
int GetNumStages() const;
void LoadFromCRSFile( CString sPath ); void LoadFromCRSFile( CString sPath );
void CreateEndlessCourseFromGroupAndDifficulty( CString sGroupName, Difficulty dc, vector<Song*> &apSongsInGroup ); void AutoGenEndlessFromGroupAndDifficulty( CString sGroupName, Difficulty dc, vector<Song*> &apSongsInGroup );
void AddStage( Song* pSong, CString sDescription, CString sModifiers );
void GetSongAndNotesForCurrentStyle( vector<Song*>& apSongsOut, vector<Notes*>& apNotesOut, CStringArray& asModifiersOut, bool bShuffled );
RageColor GetColor();
// Statistics // Statistics
int m_iNumTimesPlayed; struct RankingScore
struct MachineScore
{ {
int iDancePoints; int iDancePoints;
float fSurviveTime; float fSurviveTime;
CString sName; CString sName;
} m_MachineScores[NUM_NOTES_TYPES][NUM_RANKING_LINES]; // sorted highest to lowest by iDancePoints } m_RankingScores[NUM_NOTES_TYPES][NUM_RANKING_LINES]; // sorted highest to lowest by iDancePoints
void AddMachineRecords( NotesType nt, int iDancePoints[NUM_PLAYERS], float fSurviveTime[NUM_PLAYERS], int iLineIndexOut[NUM_PLAYERS] ); // set iNewRecordIndex = -1 if not a new record
struct MemCardScore struct MemCardScore
{ {
int iNumTimesPlayed;
int iDancePoints; int iDancePoints;
float fSurviveTime; float fSurviveTime;
} m_MemCardScores[NUM_NOTES_TYPES][NUM_PLAYERS]; } m_MemCardScores[NUM_MEMORY_CARDS][NUM_NOTES_TYPES];
bool AddMemCardRecord( PlayerNumber pn, NotesType nt, int iDancePoints, float fSurviveTime ); // return true if this is a new record
void AddScores( NotesType 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
private: private:
void Shuffle(); Song *FindSong(CString sSongDir) const;
Song *FindSong(CString sSongDir);
}; };
+19 -17
View File
@@ -22,19 +22,18 @@
#include "RageDisplay.h" #include "RageDisplay.h"
#include "ThemeManager.h" #include "ThemeManager.h"
#include "Notes.h" #include "Notes.h"
#include "GameState.h"
#include "StyleDef.h"
const float TEXT_BANNER_X = 0; #define TEXT_BANNER_X THEME->GetMetricF("CourseContentDisplay","TextBannerX")
const float TEXT_BANNER_Y = 0; #define TEXT_BANNER_Y THEME->GetMetricF("CourseContentDisplay","TextBannerY")
#define NUMBER_X THEME->GetMetricF("CourseContentDisplay","NumberX")
const float NUMBER_X = -118; #define NUMBER_Y THEME->GetMetricF("CourseContentDisplay","NumberY")
const float NUMBER_Y = 0; #define FOOT_X THEME->GetMetricF("CourseContentDisplay","FootX")
#define FOOT_Y THEME->GetMetricF("CourseContentDisplay","FootY")
const float FOOT_X = 102; #define DIFFICULTY_X THEME->GetMetricF("CourseContentDisplay","DifficultyX")
const float FOOT_Y = 8; #define DIFFICULTY_Y THEME->GetMetricF("CourseContentDisplay","DifficultyY")
const float DIFFICULTY_X = FOOT_X+18;
const float DIFFICULTY_Y = FOOT_Y;
CourseContentDisplay::CourseContentDisplay() CourseContentDisplay::CourseContentDisplay()
@@ -103,13 +102,16 @@ void CourseContentsFrame::SetFromCourse( Course* pCourse )
m_iNumContents = 0; m_iNumContents = 0;
for( int i=0; i<min(pCourse->GetNumStages(), MAX_TOTAL_CONTENTS); i++ ) vector<Song*> vSongs;
{ vector<Notes*> vNotes;
Song* pSong = pCourse->GetSong(i); vector<CString> vsModifiers;
Notes* pNotes = pCourse->GetNotesForStage(i); pCourse->GetCourseInfo( vSongs, vNotes, vsModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType, false );
if( pNotes == NULL ) for( int i=0; i<min((int)vSongs.size(), MAX_TOTAL_CONTENTS); i++ )
continue; // skip {
Song* pSong = vSongs[i];
Notes* pNotes = vNotes[i];
CString sModifiers = vsModifiers[i];
LOG->Trace( "Adding song '%s'\n", pSong->m_sMainTitle.GetString() ); LOG->Trace( "Adding song '%s'\n", pSong->m_sMainTitle.GetString() );
m_CourseContentDisplays[m_iNumContents].Load( m_iNumContents+1, pSong, pNotes ); m_CourseContentDisplays[m_iNumContents].Load( m_iNumContents+1, pSong, pNotes );
+14
View File
@@ -174,6 +174,18 @@ inline int HoldNoteScoreToDancePoints( HoldNoteScore hns )
} }
//
// MemCard stuff
//
enum MemoryCard
{
MEMORY_CARD_PLAYER_1,
MEMORY_CARD_PLAYER_2,
MEMORY_CARD_MACHINE,
NUM_MEMORY_CARDS
};
// //
// Ranking stuff // Ranking stuff
// //
@@ -186,6 +198,8 @@ enum RankingCategory
NUM_RANKING_CATEGORIES NUM_RANKING_CATEGORIES
}; };
const CString DEFAULT_RANKING_NAME = "STEP";
RankingCategory AverageMeterToRankingCategory( float fAverageMeter ); RankingCategory AverageMeterToRankingCategory( float fAverageMeter );
const int NUM_RANKING_LINES = 5; const int NUM_RANKING_LINES = 5;
+9
View File
@@ -199,6 +199,15 @@ RageColor GameState::GetStageColor()
else return STAGE_COLOR( min(m_iCurrentStageIndex,4) ); else return STAGE_COLOR( min(m_iCurrentStageIndex,4) );
} }
int GameState::GetCourseSongIndex()
{
int iSongIndex = 0;
for( int p=0; p<NUM_PLAYERS; p++ )
if( IsPlayerEnabled(p) )
iSongIndex = max( iSongIndex, m_CurStageStats.iSongsPassed[p] );
return iSongIndex;
}
GameDef* GameState::GetCurrentGameDef() GameDef* GameState::GetCurrentGameDef()
{ {
ASSERT( m_CurGame != GAME_INVALID ); // the game must be set before calling this ASSERT( m_CurGame != GAME_INVALID ); // the game must be set before calling this
+2 -1
View File
@@ -69,7 +69,7 @@ public:
bool m_bEditing; // NoteField does special stuff when this is true bool m_bEditing; // NoteField does special stuff when this is true
bool m_bDemonstration; // ScreenGameplay does special stuff when this is true bool m_bDemonstration; // ScreenGameplay does special stuff when this is true
bool m_bJukeboxUsesModifiers; bool m_bJukeboxUsesModifiers;
int m_iCurrentStageIndex; // incremented on Eval screen int m_iCurrentStageIndex; // incremented on Eval screen. For a Course, this is always 0
int GetStageIndex(); int GetStageIndex();
int GetNumStagesLeft(); int GetNumStagesLeft();
@@ -78,6 +78,7 @@ public:
bool IsExtraStage2(); bool IsExtraStage2();
CString GetStageText(); CString GetStageText();
RageColor GetStageColor(); RageColor GetStageColor();
int GetCourseSongIndex();
// //
// State Info used during gameplay // State Info used during gameplay
+5 -7
View File
@@ -447,13 +447,11 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
Course* pCourse = apCourses[c]; Course* pCourse = apCourses[c];
// check that this course has at least one song playable in the current style // check that this course has at least one song playable in the current style
vector<Song*> apSongs; Song* pSongs;
vector<Notes*> apNotes; Notes* pNotes;
CStringArray asModifiers; CString sModifiers;
pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes, asModifiers, false ); if( pCourse->GetFirstStageInfo(pSongs, pNotes, sModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType) )
arrayWheelItemDatas.push_back( WheelItemData(TYPE_COURSE, NULL, "", pCourse, pCourse->GetColor()) );
if( !apNotes.empty() )
arrayWheelItemDatas.push_back( WheelItemData(TYPE_COURSE, NULL, "", pCourse, pCourse->GetColor()) );
} }
} }
break; break;
+17 -7
View File
@@ -44,15 +44,15 @@ Notes::Notes()
for(int i = 0; i < NUM_RADAR_CATEGORIES; ++i) for(int i = 0; i < NUM_RADAR_CATEGORIES; ++i)
m_fRadarValues[i] = -1; /* unknown */ m_fRadarValues[i] = -1; /* unknown */
m_iNumTimesPlayed = 0;
notes = NULL; notes = NULL;
notes_comp = NULL; notes_comp = NULL;
parent = NULL; parent = NULL;
for( int p=0; p<NUM_PLAYERS; p++ ) for( int m=0; m<NUM_MEMORY_CARDS; m++ )
{ {
m_MemCardScores[p].grade = GRADE_NO_DATA; m_MemCardScores[m].iNumTimesPlayed = 0;
m_MemCardScores[p].fScore = 0; m_MemCardScores[m].grade = GRADE_NO_DATA;
m_MemCardScores[m].fScore = 0;
} }
} }
@@ -332,13 +332,23 @@ void Notes::SetRadarValue(int r, float val)
m_fRadarValues[r] = val; m_fRadarValues[r] = val;
} }
bool Notes::AddMemCardRecord( PlayerNumber pn, Grade grade, float fScore ) // return true if new high score void Notes::AddScore( PlayerNumber pn, Grade grade, float fScore, bool& bNewRecordOut )
{ {
bNewRecordOut = false;
m_MemCardScores[MEMORY_CARD_MACHINE].iNumTimesPlayed++;
m_MemCardScores[pn].iNumTimesPlayed++;
if( fScore > m_MemCardScores[pn].fScore ) if( fScore > m_MemCardScores[pn].fScore )
{ {
m_MemCardScores[pn].fScore = fScore; m_MemCardScores[pn].fScore = fScore;
m_MemCardScores[pn].grade = grade; m_MemCardScores[pn].grade = grade;
return true; bNewRecordOut = true;
}
if( fScore > m_MemCardScores[MEMORY_CARD_MACHINE].fScore )
{
m_MemCardScores[MEMORY_CARD_MACHINE].fScore = fScore;
m_MemCardScores[MEMORY_CARD_MACHINE].grade = grade;
} }
return false;
} }
+4 -5
View File
@@ -54,16 +54,15 @@ public:
void CreateBlank( NotesType ntTo ); void CreateBlank( NotesType ntTo );
// High scores; // High scores
int m_iNumTimesPlayed;
struct MemCardScore struct MemCardScore
{ {
int iNumTimesPlayed;
Grade grade; Grade grade;
float fScore; float fScore;
} m_MemCardScores[NUM_PLAYERS]; } m_MemCardScores[NUM_MEMORY_CARDS];
bool AddMemCardRecord( PlayerNumber pn, Grade grade, float fScore ); // return true if new high score void AddScore( PlayerNumber pn, Grade grade, float fScore, bool& bNewRecordOut );
void TidyUpData(); void TidyUpData();
+20 -28
View File
@@ -247,36 +247,28 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
// //
// update persistent statistics // update persistent statistics
// //
bool bNewRecord[NUM_PLAYERS]; bool bIsPlayerEnabled[NUM_PLAYERS];
memset( bNewRecord, 0, sizeof(bNewRecord) );
for( p=0; p<NUM_PLAYERS; p++ ) for( p=0; p<NUM_PLAYERS; p++ )
{ bIsPlayerEnabled[p] = GAMESTATE->IsPlayerEnabled(p);
if( !GAMESTATE->IsPlayerEnabled(p) || grade[p] == GRADE_E ) int iRankingLine[NUM_PLAYERS] = { -1, -1 };
continue; // can't be a new record bool bNewRecord[NUM_PLAYERS] = { false, false };
switch( m_ResultMode ) switch( m_ResultMode )
{ {
case RM_ARCADE_STAGE: case RM_ARCADE_STAGE:
{ for( int p=0; p<NUM_PLAYERS; p++ )
Notes* pNotes = GAMESTATE->m_pCurNotes[p]; if( GAMESTATE->IsPlayerEnabled(p) )
if( SONGMAN->IsUsingMemoryCard((PlayerNumber)p) ) GAMESTATE->m_pCurNotes[p]->AddScore( (PlayerNumber)p, grade[p], stageStats.fScore[p], bNewRecord[p] );
bNewRecord[p] = pNotes->AddMemCardRecord( (PlayerNumber)p, grade[p], stageStats.fScore[p] ); break;
} case RM_ARCADE_SUMMARY:
break; break;
case RM_ARCADE_SUMMARY: case RM_COURSE:
{ NotesType nt;
} nt = GAMESTATE->GetCurrentStyleDef()->m_NotesType;
break; GAMESTATE->m_pCurCourse->AddScores( nt, bIsPlayerEnabled, stageStats.iActualDancePoints, stageStats.fAliveSeconds, iRankingLine, bNewRecord );
case RM_COURSE: break;
{ default:
Course* pCourse = GAMESTATE->m_pCurCourse; ASSERT(0);
NotesType nt = GAMESTATE->GetCurrentStyleDef()->m_NotesType;
pCourse->AddMemCardRecord( (PlayerNumber)p, nt, stageStats.iActualDancePoints[p], stageStats.fAliveSeconds[p] );
}
break;
default:
ASSERT(0);
}
} }
m_bTryExtraStage = m_bTryExtraStage =
+73 -100
View File
@@ -34,16 +34,16 @@
// //
// Defines // Defines
// //
#define SONGSEL_SCREEN THEME->GetMetric("ScreenGameplay","SongSelectScreen") #define SONGSEL_SCREEN THEME->GetMetric("ScreenGameplay","SongSelectScreen")
#define MAXCOMBO_X THEME->GetMetricF("ScreenGameplay","MAXCOMBOX") #define MAXCOMBO_X THEME->GetMetricF("ScreenGameplay","MAXCOMBOX") // Please follow the capitalization conventions used everywhere else. This is case sensitive. -Chris
#define MAXCOMBO_Y THEME->GetMetricF("ScreenGameplay","MAXCOMBOY") #define MAXCOMBO_Y THEME->GetMetricF("ScreenGameplay","MAXCOMBOY")
#define MAXCOMBO_ZOOM THEME->GetMetricF("ScreenGameplay","MAXCOMBOZoom") #define MAXCOMBO_ZOOM THEME->GetMetricF("ScreenGameplay","MAXCOMBOZoom")
#define BPM_X THEME->GetMetricF("ScreenGameplay","BPMX") #define BPM_X THEME->GetMetricF("ScreenGameplay","BPMX")
#define BPM_Y THEME->GetMetricF("ScreenGameplay","BPMY") #define BPM_Y THEME->GetMetricF("ScreenGameplay","BPMY")
#define BPM_ZOOM THEME->GetMetricF("ScreenGameplay","BPMZoom") #define BPM_ZOOM THEME->GetMetricF("ScreenGameplay","BPMZoom")
#define STAGENAME_X THEME->GetMetricF("ScreenGameplay","StagenameX") #define STAGENAME_X THEME->GetMetricF("ScreenGameplay","StagenameX")
#define STAGENAME_Y THEME->GetMetricF("ScreenGameplay","StagenameY") #define STAGENAME_Y THEME->GetMetricF("ScreenGameplay","StagenameY")
#define STAGENAME_ZOOM THEME->GetMetricF("ScreenGameplay","StagenameZoom") #define STAGENAME_ZOOM THEME->GetMetricF("ScreenGameplay","StagenameZoom")
#define LIFE_FRAME_X THEME->GetMetricF("ScreenGameplay","LifeFrameX") #define LIFE_FRAME_X THEME->GetMetricF("ScreenGameplay","LifeFrameX")
#define LIFE_FRAME_Y( e ) THEME->GetMetricF("ScreenGameplay",ssprintf("LifeFrame%sY",e?"Extra":"")) #define LIFE_FRAME_Y( e ) THEME->GetMetricF("ScreenGameplay",ssprintf("LifeFrame%sY",e?"Extra":""))
#define SCORE_FRAME_X THEME->GetMetricF("ScreenGameplay","ScoreFrameX") #define SCORE_FRAME_X THEME->GetMetricF("ScreenGameplay","ScoreFrameX")
@@ -106,64 +106,64 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
if( GAMESTATE->m_pCurSong == NULL && GAMESTATE->m_pCurCourse == NULL ) if( GAMESTATE->m_pCurSong == NULL && GAMESTATE->m_pCurCourse == NULL )
return; // ScreenDemonstration will move us to the next scren. We just need to survive for one update without crashing. return; // ScreenDemonstration will move us to the next scren. We just need to survive for one update without crashing.
int p;
for( p=0; p<NUM_PLAYERS; p++ )
{ {
m_pLifeMeter[p] = NULL; for( int p=0; p<NUM_PLAYERS; p++ )
m_pScoreDisplay[p] = NULL; {
m_pLifeMeter[p] = NULL;
m_pScoreDisplay[p] = NULL;
}
} }
g_fTickEarlySecondsCache = TICK_EARLY_SECONDS; g_fTickEarlySecondsCache = TICK_EARLY_SECONDS;
SOUNDMAN->StopMusic();
GAMESTATE->m_CurStageStats = StageStats(); // clear values GAMESTATE->m_CurStageStats = StageStats(); // clear values
// Fill in m_CurStageStats // Fill in m_CurStageStats
for( p=0; p<NUM_PLAYERS; p++ ) NoteData notedata;
switch( GAMESTATE->m_PlayMode )
{ {
if( !GAMESTATE->IsPlayerEnabled(p) ) case PLAY_MODE_ARCADE:
continue; // skip
NoteData notedata;
switch( GAMESTATE->m_PlayMode )
{ {
case PLAY_MODE_ARCADE:
GAMESTATE->m_CurStageStats.pSong = GAMESTATE->m_pCurSong; GAMESTATE->m_CurStageStats.pSong = GAMESTATE->m_pCurSong;
GAMESTATE->m_CurStageStats.iMeter[p] = GAMESTATE->m_pCurNotes[p]->GetMeter(); for( int p=0; p<NUM_PLAYERS; p++ )
GAMESTATE->m_pCurNotes[p]->GetNoteData( &notedata );
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] = notedata.GetPossibleDancePoints();
break;
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
{ {
GAMESTATE->m_CurStageStats.pSong = NULL; if( !GAMESTATE->IsPlayerEnabled(p) )
GAMESTATE->m_CurStageStats.iMeter[p] = 0; continue; // skip
GAMESTATE->m_CurStageStats.iMeter[p] = GAMESTATE->m_pCurNotes[p]->GetMeter();
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] = 0; GAMESTATE->m_pCurNotes[p]->GetNoteData( &notedata );
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] = notedata.GetPossibleDancePoints();
Course* pCourse = GAMESTATE->m_pCurCourse;
vector<Song*> apSongs;
vector<Notes*> apNotes;
CStringArray asModifiers;
pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes, asModifiers, true );
for( unsigned i=0; i<apNotes.size(); i++ )
{
GAMESTATE->m_CurStageStats.iMeter[p] += apNotes[i]->GetMeter();
apNotes[i]->GetNoteData( &notedata );
int iPossibleDancePoints = notedata.GetPossibleDancePoints();
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] += iPossibleDancePoints;
}
} }
break;
default:
ASSERT(0);
} }
break;
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
{
Course* pCourse = GAMESTATE->m_pCurCourse;
pCourse->GetCourseInfo( m_apCourseSongs, m_apCourseNotes, m_asCourseModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType, false );
int iTotalMeter = 0;
int iTotalPossibleDancePoints = 0;
for( unsigned i=0; i<m_apCourseNotes.size(); i++ )
{
iTotalMeter += m_apCourseNotes[i]->GetMeter();
m_apCourseNotes[i]->GetNoteData( &notedata );
iTotalPossibleDancePoints += notedata.GetPossibleDancePoints();
}
GAMESTATE->m_CurStageStats.pSong = NULL;
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled(p) )
continue; // skip
GAMESTATE->m_CurStageStats.iMeter[p] = iTotalMeter;
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] = iTotalPossibleDancePoints;
}
}
break;
default:
ASSERT(0);
} }
@@ -187,7 +187,7 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
this->AddChild( &m_Background ); this->AddChild( &m_Background );
for( p=0; p<NUM_PLAYERS; p++ ) for( int p=0; p<NUM_PLAYERS; p++ )
{ {
if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) ) if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
continue; continue;
@@ -495,23 +495,10 @@ bool ScreenGameplay::IsLastSong()
case PLAY_MODE_ENDLESS: case PLAY_MODE_ENDLESS:
{ {
Course* pCourse = GAMESTATE->m_pCurCourse; Course* pCourse = GAMESTATE->m_pCurCourse;
if( pCourse->m_bRepeat ) if( pCourse->m_bRepeat )
return false; return false;
else
vector<Song*> apSongs; return GAMESTATE->GetCourseSongIndex() == (int)m_apCourseSongs.size();
vector<Notes*> apNotes;
CStringArray asModifiers;
pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes, asModifiers, true );
/* XXX: Should we really be using iSongsPassed to figure out what song we're
* on? Wouldn't m_iCurrentStageIndex be better for that? -glenn */
int iPlaySongIndex = 0;
for( int p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(p) )
iPlaySongIndex = max( iPlaySongIndex, GAMESTATE->m_CurStageStats.iSongsPassed[p] );
return unsigned(iPlaySongIndex) >= apSongs.size(); // there are no more songs left
} }
break; break;
default: default:
@@ -540,31 +527,18 @@ void ScreenGameplay::LoadNextSong()
if( GAMESTATE->m_CurStageStats.iSongsPassed[p] == 0 ) if( GAMESTATE->m_CurStageStats.iSongsPassed[p] == 0 )
GAMESTATE->m_SelectedOptions[p] = GAMESTATE->m_PlayerOptions[p]; GAMESTATE->m_SelectedOptions[p] = GAMESTATE->m_PlayerOptions[p];
} }
Course* pCourse = GAMESTATE->m_pCurCourse; int iPlaySongIndex = GAMESTATE->GetCourseSongIndex();
vector<Song*> apSongs; iPlaySongIndex %= m_apCourseSongs.size();
vector<Notes*> apNotes; GAMESTATE->m_pCurSong = m_apCourseSongs[iPlaySongIndex];
CStringArray asModifiers;
pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes, asModifiers, true );
int iPlaySongIndex = 0;
for( p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(p) )
iPlaySongIndex = max( iPlaySongIndex, GAMESTATE->m_CurStageStats.iSongsPassed[p] );
iPlaySongIndex %= apSongs.size();
GAMESTATE->m_pCurSong = apSongs[iPlaySongIndex];
for( p=0; p<NUM_PLAYERS; p++ ) for( p=0; p<NUM_PLAYERS; p++ )
{ {
GAMESTATE->m_pCurNotes[p] = apNotes[iPlaySongIndex]; GAMESTATE->m_pCurNotes[p] = m_apCourseNotes[iPlaySongIndex];
// Wipe the options used on the last song (including course specified ones) // Restore the player's originally selected options.
GAMESTATE->m_PlayerOptions[p].Init();
// Now restore the player's originally selected options.
GAMESTATE->m_PlayerOptions[p] = GAMESTATE->m_SelectedOptions[p]; GAMESTATE->m_PlayerOptions[p] = GAMESTATE->m_SelectedOptions[p];
if( asModifiers[iPlaySongIndex] != "" ) // some modifiers specified // Put courses options into effect.
GAMESTATE->m_PlayerOptions[p].FromString( asModifiers[iPlaySongIndex] ); // put them into effect GAMESTATE->m_PlayerOptions[p].FromString( m_asCourseModifiers[iPlaySongIndex] );
} }
} }
break; break;
default: default:
@@ -1070,7 +1044,7 @@ void SaveChanges()
* playing out of a course, and use that here, so these things wouldn't need to * playing out of a course, and use that here, so these things wouldn't need to
* special case play modes. Need to make sure m_pCurCourse gets erased * special case play modes. Need to make sure m_pCurCourse gets erased
* correctly, though. -glenn */ * correctly, though. -glenn */
/* That's a very clever idea! I will look into this soon. -Chris */ /* That's a very clever idea! I should look into this. -Chris */
switch( GAMESTATE->m_PlayMode ) switch( GAMESTATE->m_PlayMode )
{ {
case PLAY_MODE_ARCADE: case PLAY_MODE_ARCADE:
@@ -1080,11 +1054,9 @@ void SaveChanges()
case PLAY_MODE_ONI: case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS: case PLAY_MODE_ENDLESS:
{ {
for( int i=0; i<GAMESTATE->m_pCurCourse->GetNumStages(); i++ ) // FIXME
{ //for( int i=0; i<m_apCourseSongs.size(); i++ )
Song* pSong = GAMESTATE->m_pCurCourse->GetSong(i); // m_apCourseSongs[i]->Save();
pSong->Save();
}
} }
break; break;
default: default:
@@ -1105,11 +1077,12 @@ void DontSaveChanges()
case PLAY_MODE_ONI: case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS: case PLAY_MODE_ENDLESS:
{ {
for( int i=0; i<GAMESTATE->m_pCurCourse->GetNumStages(); i++ ) // FIXME
{ // for( int i=0; i<GAMESTATE->m_pCurCourse->GetNumStages(); i++ )
Song* pSong = GAMESTATE->m_pCurCourse->GetSong(i); // {
ld.LoadFromSMFile( GAMESTATE->m_pCurSong->GetCacheFilePath(), *pSong ); // Song* pSong = GAMESTATE->m_pCurCourse->GetSong(i);
} // ld.LoadFromSMFile( GAMESTATE->m_pCurSong->GetCacheFilePath(), *pSong );
// }
} }
break; break;
default: default:
+5 -2
View File
@@ -77,8 +77,11 @@ protected:
STATE_DANCING, STATE_DANCING,
STATE_OUTRO, // not allowed to press Back STATE_OUTRO, // not allowed to press Back
NUM_DANCING_STATES NUM_DANCING_STATES
}; } m_DancingState;
DancingState m_DancingState; vector<Song*> m_apCourseSongs; // used only in a GameModes with courses
vector<Notes*> m_apCourseNotes; // used only in a GameModes with courses
CStringArray m_asCourseModifiers; // used only in a GameModes with courses
bool m_bChangedOffsetOrBPM; bool m_bChangedOffsetOrBPM;
float m_fTimeLeftBeforeDancingComment; // this counter is only running while STATE_DANCING float m_fTimeLeftBeforeDancingComment; // this counter is only running while STATE_DANCING
+1 -1
View File
@@ -49,7 +49,7 @@ ScreenLogo::ScreenLogo() : ScreenAttract("ScreenLogo","logo")
m_textSongs.LoadFromFont( THEME->GetPathTo("Fonts","normal") ); m_textSongs.LoadFromFont( THEME->GetPathTo("Fonts","normal") );
m_textSongs.SetHorizAlign( Actor::align_left ); m_textSongs.SetHorizAlign( Actor::align_left );
m_textSongs.SetText( ssprintf("%d songs in %d groups", SONGMAN->GetNumSongs(), SONGMAN->GetNumGroups()) ); m_textSongs.SetText( ssprintf("%d songs in %d groups, %d courses", SONGMAN->GetNumSongs(), SONGMAN->GetNumGroups(), SONGMAN->GetNumCourses()) );
m_textSongs.SetDiffuse( RageColor(0.6f,0.6f,0.6f,1) ); // light gray m_textSongs.SetDiffuse( RageColor(0.6f,0.6f,0.6f,1) ); // light gray
m_textSongs.SetXY( SONGS_X, SONGS_Y ); m_textSongs.SetXY( SONGS_X, SONGS_Y );
m_textSongs.SetZoom( 0.5f ); m_textSongs.SetZoom( 0.5f );
+8 -4
View File
@@ -163,17 +163,21 @@ ScreenNameEntry::ScreenNameEntry()
Course* pCourse = GAMESTATE->m_pCurCourse; Course* pCourse = GAMESTATE->m_pCurCourse;
bool bPlayerIsEnabled[NUM_PLAYERS];
int iDancePoints[NUM_PLAYERS]; int iDancePoints[NUM_PLAYERS];
float fAliveSeconds[NUM_PLAYERS]; float fAliveSeconds[NUM_PLAYERS];
int iRankingIndex[NUM_PLAYERS];
for( int p=0; p<NUM_PLAYERS; p++ ) for( int p=0; p<NUM_PLAYERS; p++ )
{ {
bPlayerIsEnabled[p] = GAMESTATE->IsPlayerEnabled(p);
iDancePoints[p] = stageStats.iActualDancePoints[p]; iDancePoints[p] = stageStats.iActualDancePoints[p];
fAliveSeconds[p] = stageStats.fAliveSeconds[p]; fAliveSeconds[p] = stageStats.fAliveSeconds[p];
} }
int iRankingIndex[NUM_PLAYERS];
bool bNewRecord[NUM_PLAYERS];
NotesType nt = GAMESTATE->GetCurrentStyleDef()->m_NotesType; NotesType nt = GAMESTATE->GetCurrentStyleDef()->m_NotesType;
pCourse->AddMachineRecords( nt, iDancePoints, fAliveSeconds, iRankingIndex ); pCourse->AddScores( nt, bPlayerIsEnabled, iDancePoints, fAliveSeconds, iRankingIndex, bNewRecord );
GAMESTATE->m_LastRankingNotesType = nt; GAMESTATE->m_LastRankingNotesType = nt;
GAMESTATE->m_pLastPlayedCourse = pCourse; GAMESTATE->m_pLastPlayedCourse = pCourse;
@@ -409,7 +413,7 @@ void ScreenNameEntry::MenuStart( PlayerNumber pn )
TrimLeft( m_sSelectedName[pn], " " ); TrimLeft( m_sSelectedName[pn], " " );
if( m_sSelectedName[pn] == "" ) if( m_sSelectedName[pn] == "" )
m_sSelectedName[pn] = "STEP"; m_sSelectedName[pn] = DEFAULT_RANKING_NAME;
switch( GAMESTATE->m_PlayMode ) switch( GAMESTATE->m_PlayMode )
@@ -420,7 +424,7 @@ void ScreenNameEntry::MenuStart( PlayerNumber pn )
case PLAY_MODE_NONSTOP: case PLAY_MODE_NONSTOP:
case PLAY_MODE_ONI: case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS: case PLAY_MODE_ENDLESS:
GAMESTATE->m_pLastPlayedCourse->m_MachineScores[GAMESTATE->m_LastRankingNotesType][GAMESTATE->m_iLastRankingIndex[pn]].sName = m_sSelectedName[pn]; GAMESTATE->m_pLastPlayedCourse->m_RankingScores[GAMESTATE->m_LastRankingNotesType][GAMESTATE->m_iLastRankingIndex[pn]].sName = m_sSelectedName[pn];
break; break;
default: default:
ASSERT(0); ASSERT(0);
+3 -3
View File
@@ -236,9 +236,9 @@ void ScreenRanking::SetPage( PageToShow pts )
for( int l=0; l<NUM_RANKING_LINES; l++ ) for( int l=0; l<NUM_RANKING_LINES; l++ )
{ {
m_sprBullets[l].SetDiffuse( RageColor(1,1,1,1) ); m_sprBullets[l].SetDiffuse( RageColor(1,1,1,1) );
CString sName = pts.pCourse->m_MachineScores[pts.nt][l].sName; CString sName = pts.pCourse->m_RankingScores[pts.nt][l].sName;
int iDancePoints = pts.pCourse->m_MachineScores[pts.nt][l].iDancePoints; int iDancePoints = pts.pCourse->m_RankingScores[pts.nt][l].iDancePoints;
float fSurviveTime = pts.pCourse->m_MachineScores[pts.nt][l].fSurviveTime; float fSurviveTime = pts.pCourse->m_RankingScores[pts.nt][l].fSurviveTime;
m_textNames[l].SetText( sName ); m_textNames[l].SetText( sName );
m_textScores[l].SetText( "" ); m_textScores[l].SetText( "" );
m_textPoints[l].SetText( ssprintf("%04d",iDancePoints) ); m_textPoints[l].SetText( ssprintf("%04d",iDancePoints) );
+12 -7
View File
@@ -299,9 +299,13 @@ void ScreenSelectCourse::MenuStart( PlayerNumber pn )
Course* pCourse = m_MusicWheel.GetSelectedCourse(); Course* pCourse = m_MusicWheel.GetSelectedCourse();
GAMESTATE->m_pCurCourse = pCourse; GAMESTATE->m_pCurCourse = pCourse;
Song* pSong;
Notes* pNotes;
CString sModifiers;
pCourse->GetFirstStageInfo( pSong, pNotes, sModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType );
for( int p=0; p<NUM_PLAYERS; p++ ) for( int p=0; p<NUM_PLAYERS; p++ )
pCourse->GetPlayerOptions( 0, &GAMESTATE->m_PlayerOptions[p] ); GAMESTATE->m_PlayerOptions[p].FromString( sModifiers );
pCourse->GetSongOptions( &GAMESTATE->m_SongOptions ); GAMESTATE->m_SongOptions.FromString( sModifiers );
m_Menu.StopTimer(); m_Menu.StopTimer();
@@ -328,11 +332,12 @@ void ScreenSelectCourse::AfterCourseChange()
{ {
Course* pCourse = m_MusicWheel.GetSelectedCourse(); Course* pCourse = m_MusicWheel.GetSelectedCourse();
m_textNumSongs.SetText( ssprintf("%d", pCourse->GetNumStages()) ); m_textNumSongs.SetText( ssprintf("%d", pCourse->GetEstimatedNumStages()) );
float fTotalSeconds = 0; float fTotalSeconds;
for( int i=0; i<pCourse->GetNumStages(); i++ ) if( pCourse->GetTotalSeconds(fTotalSeconds) )
fTotalSeconds += pCourse->GetSong(i)->m_fMusicLengthSeconds; m_textTime.SetText( SecondsToTime(fTotalSeconds) );
m_textTime.SetText( SecondsToTime(fTotalSeconds) ); else
m_textTime.SetText( "??:??:??" );
m_Banner.LoadFromCourse( pCourse ); m_Banner.LoadFromCourse( pCourse );
+4 -3
View File
@@ -635,12 +635,13 @@ void Song::GetNotes( vector<Notes*>& arrayAddTo, NotesType nt, bool bIncludeAuto
arrayAddTo.push_back( m_apNotes[i] ); arrayAddTo.push_back( m_apNotes[i] );
} }
Notes* Song::GetNotes( NotesType nt, Difficulty dc, bool bIncludeAutoGen ) const Notes* Song::GetNotes( NotesType nt, Difficulty dc, bool bIncludeAutoGen, CString sDescription ) const
{ {
for( unsigned i=0; i<m_apNotes.size(); i++ ) // for each of the Song's Notes for( unsigned i=0; i<m_apNotes.size(); i++ ) // for each of the Song's Notes
if( m_apNotes[i]->m_NotesType==nt && m_apNotes[i]->GetDifficulty()==dc ) if( m_apNotes[i]->m_NotesType==nt && m_apNotes[i]->GetDifficulty()==dc )
if( bIncludeAutoGen || !m_apNotes[i]->IsAutogen() ) if( bIncludeAutoGen || !m_apNotes[i]->IsAutogen() )
return m_apNotes[i]; if( sDescription.empty() || m_apNotes[i]->GetDescription()==sDescription )
return m_apNotes[i];
return NULL; return NULL;
} }
@@ -1008,7 +1009,7 @@ int Song::GetNumTimesPlayed() const
int iTotalNumTimesPlayed = 0; int iTotalNumTimesPlayed = 0;
for( unsigned i=0; i<m_apNotes.size(); i++ ) for( unsigned i=0; i<m_apNotes.size(); i++ )
{ {
iTotalNumTimesPlayed += m_apNotes[i]->m_iNumTimesPlayed; iTotalNumTimesPlayed += m_apNotes[i]->m_MemCardScores[MEMORY_CARD_MACHINE].iNumTimesPlayed;
} }
return iTotalNumTimesPlayed; return iTotalNumTimesPlayed;
} }
+250 -63
View File
@@ -28,10 +28,14 @@
SongManager* SONGMAN = NULL; // global and accessable from anywhere in our program SongManager* SONGMAN = NULL; // global and accessable from anywhere in our program
const CString CATEGORY_TOP_SCORE_FILE = "CategoryTopScores.dat"; const CString CATEGORY_RANKING_FILE = "CategoryRanking.dat";
const CString COURSE_TOP_SCORE_FILE = "CourseTopScores.dat"; const CString COURSE_RANKING_FILE = "CourseRanking.dat";
const int CATEGORY_TOP_SCORE_VERSION = 1; const CString NOTES_SCORES_FILE[NUM_MEMORY_CARDS] = { "Player1NotesScores.dat", "Player2NotesScores.dat", "MachineNotesScores.dat" };
const int COURSE_TOP_SCORE_VERSION = 1; const CString COURSE_SCORES_FILE[NUM_MEMORY_CARDS] = { "Player1CourseScores.dat", "Player2CourseScores.dat", "MachineCourseScores.dat" };
const int CATEGORY_RANKING_VERSION = 1;
const int COURSE_RANKING_VERSION = 1;
const int NOTES_SCORES_VERSION = 1;
const int COURSE_SCORES_VERSION = 1;
#define NUM_GROUP_COLORS THEME->GetMetricI("SongManager","NumGroupColors") #define NUM_GROUP_COLORS THEME->GetMetricI("SongManager","NumGroupColors")
@@ -211,25 +215,25 @@ void SongManager::ReloadSongArray()
void SongManager::InitMachineScoresFromDisk() void SongManager::InitMachineScoresFromDisk()
{ {
// Init category top scores // Init category ranking
{ {
for( int i=0; i<NUM_NOTES_TYPES; i++ ) for( int i=0; i<NUM_NOTES_TYPES; i++ )
for( int j=0; j<NUM_RANKING_CATEGORIES; j++ ) for( int j=0; j<NUM_RANKING_CATEGORIES; j++ )
for( int k=0; k<NUM_RANKING_LINES; k++ ) for( int k=0; k<NUM_RANKING_LINES; k++ )
{ {
m_MachineScores[i][j][k].fScore = 573000; m_MachineScores[i][j][k].fScore = 573000;
m_MachineScores[i][j][k].sName = "STEP"; m_MachineScores[i][j][k].sName = DEFAULT_RANKING_NAME;
} }
} }
// Read category top scores // category ranking
{ {
FILE* fp = fopen( CATEGORY_TOP_SCORE_FILE, "r" ); FILE* fp = fopen( CATEGORY_RANKING_FILE, "r" );
if( fp ) if( fp )
{ {
int version; int version;
fscanf(fp, "%d\n", &version ); fscanf(fp, "%d\n", &version );
if( version == CATEGORY_TOP_SCORE_VERSION ) if( version == CATEGORY_RANKING_VERSION )
{ {
for( int i=0; i<NUM_NOTES_TYPES; i++ ) for( int i=0; i<NUM_NOTES_TYPES; i++ )
for( int j=0; j<NUM_RANKING_CATEGORIES; j++ ) for( int j=0; j<NUM_RANKING_CATEGORIES; j++ )
@@ -245,52 +249,137 @@ void SongManager::InitMachineScoresFromDisk()
} }
} }
// Read course top scores // course ranking
{ {
FILE* fp = fopen( COURSE_TOP_SCORE_FILE, "r" ); FILE* fp = fopen( COURSE_RANKING_FILE, "r" );
if( fp ) if( fp )
{ {
int version; int version;
fscanf(fp, "%d\n", &version ); fscanf(fp, "%[^\n]\n", &version );
if( version == COURSE_TOP_SCORE_VERSION ) if( version == COURSE_RANKING_VERSION )
{ {
while( fp && !feof(fp) ) while( fp && !feof(fp) )
{ {
char szPath[256]; char szPath[256];
fscanf(fp, "%s\n", szPath); fscanf(fp, "%s\n", szPath);
Course* pCourse = GetCourseFromPath( szPath ); Course* pCourse = GetCourseFromPath( szPath );
if( pCourse == NULL )
pCourse = GetCourseFromName( szPath );
for( int i=0; i<NUM_NOTES_TYPES; i++ ) for( int i=0; i<NUM_NOTES_TYPES; i++ )
for( int j=0; j<NUM_RANKING_LINES; j++ ) for( int j=0; j<NUM_RANKING_LINES; j++ )
if( fp && !feof(fp) ) if( fp && !feof(fp) )
{
int iDancePoints;
float fSurviveTime;
char szName[256];
fscanf(fp, "%d %f %[^\n]\n", &iDancePoints, &fSurviveTime, szName);
if( pCourse )
{ {
int iDancePoints; pCourse->m_RankingScores[i][j].iDancePoints = iDancePoints;
float fSurviveTime; pCourse->m_RankingScores[i][j].fSurviveTime = fSurviveTime;
char szName[256]; pCourse->m_RankingScores[i][j].sName = szName;
fscanf(fp, "%d %f %[^\n]\n", &iDancePoints, &fSurviveTime, szName);
if( pCourse )
{
pCourse->m_MachineScores[i][j].iDancePoints = iDancePoints;
pCourse->m_MachineScores[i][j].fSurviveTime = fSurviveTime;
pCourse->m_MachineScores[i][j].sName = szName;
}
} }
}
} }
} }
fclose(fp); fclose(fp);
} }
} }
// notes scores
for( int c=0; c<NUM_MEMORY_CARDS; c++ )
{
FILE* fp = fopen( NOTES_SCORES_FILE[c], "r" );
if( fp )
{
int version;
fscanf(fp, "%d\n", &version );
if( version == COURSE_SCORES_VERSION )
{
while( fp && !feof(fp) )
{
char szSongDir[256];
unsigned uNumNotes;
fscanf(fp, "%[^\n]\n%u\n", szSongDir, &uNumNotes);
Song* pSong = this->GetSongFromDir( szSongDir );
for( unsigned i=0; i<uNumNotes; i++ )
{
NotesType nt;
Difficulty dc;
char szDescription[256];
fscanf(fp, "[%d\n%d\n%[^\n]\n", &nt, &dc, szDescription);
Notes* pNotes = !pSong ? NULL : pSong->GetNotes( nt, dc, true, szDescription );
int iNumTimesPlayed;
Grade grade;
float fScore;
fscanf(fp, "%d %d %f\n", &iNumTimesPlayed, &grade, &fScore );
if( pNotes )
{
pNotes->m_MemCardScores[c].iNumTimesPlayed = iNumTimesPlayed;
pNotes->m_MemCardScores[c].grade = grade;
pNotes->m_MemCardScores[c].fScore = fScore;
}
}
}
}
fclose(fp);
}
}
// course scores
{
for( int c=0; c<NUM_MEMORY_CARDS; c++ )
{
FILE* fp = fopen( COURSE_SCORES_FILE[c], "r" );
if( fp )
{
int version;
fscanf(fp, "%d\n", &version );
if( version == COURSE_SCORES_VERSION )
{
while( fp && !feof(fp) )
{
char szPath[256];
fscanf(fp, "%[^\n]\n", szPath);
Course* pCourse = GetCourseFromPath( szPath );
if( pCourse == NULL )
pCourse = GetCourseFromName( szPath );
for( int i=0; i<NUM_NOTES_TYPES; i++ )
if( fp && !feof(fp) )
{
int iNumTimesPlayed;
int iDancePoints;
float fSurviveTime;
fscanf(fp, "%d %d %f\n", &iNumTimesPlayed, &iDancePoints, &fSurviveTime);
if( pCourse )
{
pCourse->m_MemCardScores[c][i].iNumTimesPlayed = iNumTimesPlayed;
pCourse->m_MemCardScores[c][i].iDancePoints = iDancePoints;
pCourse->m_MemCardScores[c][i].fSurviveTime = fSurviveTime;
}
}
}
}
fclose(fp);
}
}
}
} }
void SongManager::SaveMachineScoresToDisk() void SongManager::SaveMachineScoresToDisk()
{ {
// Write category top scores // category ranking
{ {
FILE* fp = fopen( CATEGORY_TOP_SCORE_FILE, "w" ); FILE* fp = fopen( CATEGORY_RANKING_FILE, "w" );
if( fp ) if( fp )
{ {
fprintf(fp,"%d\n",CATEGORY_TOP_SCORE_VERSION); fprintf(fp,"%d\n",CATEGORY_RANKING_VERSION);
for( int i=0; i<NUM_NOTES_TYPES; i++ ) for( int i=0; i<NUM_NOTES_TYPES; i++ )
for( int j=0; j<NUM_RANKING_CATEGORIES; j++ ) for( int j=0; j<NUM_RANKING_CATEGORIES; j++ )
for( int k=0; k<NUM_RANKING_LINES; k++ ) for( int k=0; k<NUM_RANKING_LINES; k++ )
@@ -300,30 +389,100 @@ void SongManager::SaveMachineScoresToDisk()
} }
} }
// Write course top scores // course ranking
{ {
FILE* fp = fopen( COURSE_TOP_SCORE_FILE, "w" ); FILE* fp = fopen( COURSE_RANKING_FILE, "w" );
if( fp ) if( fp )
{ {
fprintf(fp,"%d",COURSE_TOP_SCORE_VERSION); fprintf(fp,"%d\n",COURSE_RANKING_VERSION);
for( unsigned i=0; i<m_pCourses.size(); i++ ) // foreach course for( unsigned c=0; c<m_pCourses.size(); c++ ) // foreach course
{ {
Course* pCourse = m_pCourses[i]; Course* pCourse = m_pCourses[c];
if( pCourse->m_bIsAutoGen )
fprintf(fp, "%s\n", pCourse->m_sPath.c_str()); 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_NOTES_TYPES; i++ ) for( int i=0; i<NUM_NOTES_TYPES; i++ )
for( int j=0; j<NUM_RANKING_LINES; j++ ) for( int j=0; j<NUM_RANKING_LINES; j++ )
fprintf(fp, "%d %f %s\n", fprintf(fp, "%d %f %s\n",
pCourse->m_MachineScores[i][j].iDancePoints, pCourse->m_RankingScores[i][j].iDancePoints,
pCourse->m_MachineScores[i][j].fSurviveTime, pCourse->m_RankingScores[i][j].fSurviveTime,
pCourse->m_MachineScores[i][j].sName.c_str()); pCourse->m_RankingScores[i][j].sName.c_str());
}
fclose(fp);
}
}
// notes scores
for( int c=0; c<NUM_MEMORY_CARDS; c++ )
{
FILE* fp = fopen( NOTES_SCORES_FILE[c], "w" );
if( fp )
{
fprintf(fp,"%d\n",NOTES_SCORES_VERSION);
for( unsigned s=0; s<m_pSongs.size(); s++ ) // foreach song
{
Song* pSong = m_pSongs[s];
vector<Notes*> vNotes = pSong->m_apNotes;
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
fprintf(fp, "%s\n%u\n",
pSong->GetSongDir().c_str(),
vNotes.size() );
for( unsigned i=0; i<vNotes.size(); i++ )
{
Notes* pNotes = vNotes[i];
fprintf(fp, "%d\n%d\n%s\n",
pNotes->m_NotesType,
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);
}
}
fclose(fp);
}
}
// course scores
{
for( int c=0; c<NUM_MEMORY_CARDS; c++ )
{
FILE* fp = fopen( COURSE_SCORES_FILE[c], "w" );
if( fp )
{
fprintf(fp,"%d\n",COURSE_SCORES_VERSION);
for( unsigned c=0; c<m_pCourses.size(); c++ ) // foreach song
{
Course* pCourse = m_pCourses[c];
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_NOTES_TYPES; i++ )
fprintf(fp, "%d %d %f\n",
pCourse->m_MemCardScores[c][i].iNumTimesPlayed,
pCourse->m_MemCardScores[c][i].iDancePoints,
pCourse->m_MemCardScores[c][i].fSurviveTime);
}
fclose(fp);
} }
} }
if( fp )
fclose(fp);
} }
} }
@@ -392,6 +551,11 @@ int SongManager::GetNumGroups() const
return m_arrayGroupNames.size(); return m_arrayGroupNames.size();
} }
int SongManager::GetNumCourses() const
{
return m_pCourses.size();
}
CString SongManager::ShortenGroupName( CString sLongGroupName ) CString SongManager::ShortenGroupName( CString sLongGroupName )
{ {
sLongGroupName.Replace( "Dance Dance Revolution", "DDR" ); sLongGroupName.Replace( "Dance Dance Revolution", "DDR" );
@@ -434,10 +598,7 @@ void SongManager::InitCoursesFromDisk()
{ {
Course* pCourse = new Course; Course* pCourse = new Course;
pCourse->LoadFromCRSFile( saCourseFiles[i] ); pCourse->LoadFromCRSFile( saCourseFiles[i] );
if( pCourse->GetNumStages() > 0 ) m_pCourses.push_back( pCourse );
m_pCourses.push_back( pCourse );
else
delete pCourse;
} }
// //
@@ -455,12 +616,9 @@ void SongManager::InitCoursesFromDisk()
for( Difficulty dc=DIFFICULTY_EASY; dc<=DIFFICULTY_HARD; dc=Difficulty(dc+1) ) // foreach Difficulty for( Difficulty dc=DIFFICULTY_EASY; dc<=DIFFICULTY_HARD; dc=Difficulty(dc+1) ) // foreach Difficulty
{ {
Course* pCourse = new Course; Course* pCourse = new Course;
pCourse->CreateEndlessCourseFromGroupAndDifficulty( sGroupName, dc, apGroupSongs ); pCourse->AutoGenEndlessFromGroupAndDifficulty( sGroupName, dc, apGroupSongs );
if( pCourse->GetNumStages() > 0 ) m_pCourses.push_back( pCourse );
m_pCourses.push_back( pCourse );
else
delete pCourse;
} }
} }
} }
@@ -556,16 +714,17 @@ bool SongManager::GetExtraStageInfoFromCourse( bool bExtra2, CString sPreferredG
Course course; Course course;
course.LoadFromCRSFile( sCoursePath ); course.LoadFromCRSFile( sCoursePath );
if( course.GetNumStages() <= 0 ) return false; if( course.GetEstimatedNumStages() <= 0 ) return false;
pSongOut = course.GetSong(0); CString sModifiers;
pNotesOut = course.GetNotesForStage( 0 ); if( course.GetFirstStageInfo( pSongOut, pNotesOut, sModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType ) )
if( pNotesOut == NULL ) return false; {
po_out.FromString( sModifiers );
course.GetPlayerOptions( 0, &po_out ); so_out.FromString( sModifiers );
course.GetSongOptions( &so_out ); return true;
}
return true; else
return false;
} }
/* Return true if n1 < n2. */ /* Return true if n1 < n2. */
@@ -670,6 +829,24 @@ Song* SongManager::GetRandomSong()
return SONGMAN->m_pSongs[ rand()%m_pSongs.size() ]; return SONGMAN->m_pSongs[ rand()%m_pSongs.size() ];
} }
Song* SongManager::GetPlayersBest( int index )
{
vector<Song*> vSongs = m_pSongs;
if( (unsigned)index >= vSongs.size() )
return NULL;
SortSongPointerArrayByMostPlayed( vSongs );
return vSongs[index];
}
Song* SongManager::GetPlayersWorst( int index )
{
vector<Song*> vSongs = m_pSongs;
if( (unsigned)index >= vSongs.size() )
return NULL;
SortSongPointerArrayByMostPlayed( vSongs );
return vSongs[vSongs.size()-1-index];
}
Song* SongManager::GetSongFromDir( CString sDir ) Song* SongManager::GetSongFromDir( CString sDir )
{ {
if( sDir[sDir.GetLength()-1] != '/' ) if( sDir[sDir.GetLength()-1] != '/' )
@@ -691,6 +868,16 @@ Course* SongManager::GetCourseFromPath( CString sPath )
return NULL; return NULL;
} }
Course* SongManager::GetCourseFromName( CString sName )
{
for( unsigned int i=0; i<m_pCourses.size(); i++ )
if( sName.CompareNoCase(m_pCourses[i]->m_sName) == 0 )
return m_pCourses[i];
return NULL;
}
bool SongManager::IsUsingMemoryCard( PlayerNumber pn ) bool SongManager::IsUsingMemoryCard( PlayerNumber pn )
{ {
return true; return true;
@@ -749,7 +936,7 @@ void SongManager::AddMachineRecords( NotesType nt, RankingCategory hsc[NUM_PLAYE
machineScores[j] = machineScores[j-1]; machineScores[j] = machineScores[j-1];
// insert // insert
machineScores[i].fScore = newHS.fScore; machineScores[i].fScore = newHS.fScore;
machineScores[i].sName = "STEP"; machineScores[i].sName = DEFAULT_RANKING_NAME;
iNewRecordIndexOut[newHS.pn] = i; iNewRecordIndexOut[newHS.pn] = i;
break; break;
} }
+5
View File
@@ -58,7 +58,11 @@ public:
void GetSongs( vector<Song*> &AddTo ) const { GetSongs(AddTo,"",100000 /*inf*/ ); } void GetSongs( vector<Song*> &AddTo ) const { GetSongs(AddTo,"",100000 /*inf*/ ); }
int GetNumSongs() const; int GetNumSongs() const;
int GetNumGroups() const; int GetNumGroups() const;
int GetNumCourses() const;
Song* GetRandomSong(); Song* GetRandomSong();
Song* GetPlayersBest( int index );
Song* GetPlayersWorst( int index );
void GetNonstopCourses( vector<Course*> &AddTo ); // add to if life meter type is BAR. void GetNonstopCourses( vector<Course*> &AddTo ); // add to if life meter type is BAR.
void GetOniCourses( vector<Course*> &AddTo ); // add to if life meter type is BATTERY. void GetOniCourses( vector<Course*> &AddTo ); // add to if life meter type is BATTERY.
@@ -69,6 +73,7 @@ public:
Song* GetSongFromDir( CString sDir ); Song* GetSongFromDir( CString sDir );
Course* GetCourseFromPath( CString sPath ); // path to .crs file, or path to song group dir Course* GetCourseFromPath( CString sPath ); // path to .crs file, or path to song group dir
Course* GetCourseFromName( CString sName );
// //
+1 -1
View File
@@ -206,7 +206,7 @@ public:
bool SongHasNotesType( NotesType nt ) const; bool SongHasNotesType( NotesType nt ) const;
bool SongHasNotesTypeAndDifficulty( NotesType nt, Difficulty dc ) const; bool SongHasNotesTypeAndDifficulty( NotesType nt, Difficulty dc ) const;
void GetNotes( vector<Notes*>& arrayAddTo, NotesType nt, bool bIncludeAutoGen = true ) const; void GetNotes( vector<Notes*>& arrayAddTo, NotesType nt, bool bIncludeAutoGen = true ) const;
Notes* GetNotes( NotesType nt, Difficulty dc, bool bIncludeAutoGen = true ) const; Notes* GetNotes( NotesType nt, Difficulty dc, bool bIncludeAutoGen = true, CString sDescription = "" ) const;
void GetEdits( vector<Notes*>& arrayAddTo, NotesType nt, bool bIncludeAutoGen = true ) const; void GetEdits( vector<Notes*>& arrayAddTo, NotesType nt, bool bIncludeAutoGen = true ) const;
int GetNumTimesPlayed() const; int GetNumTimesPlayed() const;
bool IsNew() const; bool IsNew() const;