working on course ranking scores and mem card saving
This commit is contained in:
@@ -934,3 +934,13 @@ TwoLinesArtistY=8
|
||||
ThreeLinesTitleY=-10
|
||||
ThreeLinesSubTitleY=0
|
||||
ThreeLinesArtistY=10
|
||||
|
||||
[CourseContentDisplay]
|
||||
TextBannerX=0
|
||||
TextBannerY=0
|
||||
NumberX=-118
|
||||
NumberY=0
|
||||
FootX=102
|
||||
FootY=8
|
||||
DifficultyX=120
|
||||
DifficultyY=8
|
||||
|
||||
+168
-143
@@ -15,7 +15,6 @@
|
||||
#include "Song.h"
|
||||
#include "GameManager.h"
|
||||
#include "SongManager.h"
|
||||
#include "GameState.h"
|
||||
#include "RageException.h"
|
||||
#include "RageLog.h"
|
||||
#include "MsdFile.h"
|
||||
@@ -24,31 +23,31 @@
|
||||
#include "RageUtil.h"
|
||||
#include "TitleSubstitution.h"
|
||||
|
||||
|
||||
Course::Course()
|
||||
{
|
||||
m_bIsAutoGen = false;
|
||||
m_bRepeat = false;
|
||||
m_bRandomize = false;
|
||||
m_iLives = -1;
|
||||
m_iExtra = 0;
|
||||
m_iNumTimesPlayed = 0;
|
||||
|
||||
//
|
||||
// Init high scores
|
||||
//
|
||||
unsigned i, j;
|
||||
for( i=0; i<NUM_NOTES_TYPES; i++ )
|
||||
for( j=0; j<NUM_RANKING_LINES; j++ )
|
||||
for( unsigned i=0; i<NUM_NOTES_TYPES; i++ )
|
||||
for( unsigned j=0; j<NUM_RANKING_LINES; j++ )
|
||||
{
|
||||
m_MachineScores[i][j].iDancePoints = 573;
|
||||
m_MachineScores[i][j].fSurviveTime = 57.3f;
|
||||
m_MachineScores[i][j].sName = "STEP";
|
||||
m_RankingScores[i][j].iDancePoints = 573;
|
||||
m_RankingScores[i][j].fSurviveTime = 57.3f;
|
||||
m_RankingScores[i][j].sName = DEFAULT_RANKING_NAME;
|
||||
}
|
||||
|
||||
for( i=0; i<NUM_NOTES_TYPES; i++ )
|
||||
for( j=0; j<NUM_PLAYERS; j++ )
|
||||
for( unsigned m=0; m<NUM_MEMORY_CARDS; m++ )
|
||||
for( unsigned i=0; i<NUM_NOTES_TYPES; i++ )
|
||||
{
|
||||
m_MemCardScores[i][j].iDancePoints = 0;
|
||||
m_MemCardScores[i][j].fSurviveTime = 0;
|
||||
m_MemCardScores[m][i].iNumTimesPlayed = 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.
|
||||
*/
|
||||
|
||||
Song *Course::FindSong(CString sSongDir)
|
||||
Song *Course::FindSong(CString sSongDir) const
|
||||
{
|
||||
const vector<Song*> &apSongs = SONGMAN->GetAllSongs();
|
||||
|
||||
@@ -156,21 +155,16 @@ void Course::LoadFromCRSFile( CString sPath )
|
||||
else if( 0 == stricmp(sValueName, "SONG") )
|
||||
{
|
||||
CString sSongDir = sParams[1];
|
||||
CString sNotesDescription = sParams[2];
|
||||
Difficulty dc = StringToDifficulty( sParams[2] );
|
||||
CString sModifiers = sParams[3];
|
||||
|
||||
if(!sSongDir.GetLength()) {
|
||||
if( sSongDir.GetLength() == 0 ) {
|
||||
/* Err. */
|
||||
LOG->Trace( "Course file '%s' has an empty #SONG. Ignored.", sPath.GetString(), sSongDir.GetString() );
|
||||
continue;
|
||||
}
|
||||
|
||||
Song *pSong = FindSong(sSongDir);
|
||||
|
||||
if( pSong == NULL ) // we didn't find the Song
|
||||
continue; // skip this song
|
||||
|
||||
AddStage( pSong, sNotesDescription, sModifiers );
|
||||
m_entries.push_back( course_entry(sSongDir, dc, sModifiers) );
|
||||
}
|
||||
|
||||
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_bRandomize = true;
|
||||
m_iLives = -1;
|
||||
@@ -213,162 +208,204 @@ void Course::CreateEndlessCourseFromGroupAndDifficulty( CString sGroupName, Diff
|
||||
for( unsigned s=0; s<apSongsInGroup.size(); 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( int i = 0; i < GetNumStages(); ++i)
|
||||
swap(order[i], order[rand() % GetNumStages()]);
|
||||
for( unsigned i=0; i<m_entries.size(); i++ )
|
||||
if( m_entries[i].difficulty >= DIFFICULTY_HARD )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Notes* Course::GetNotesForStage( int iStage )
|
||||
|
||||
void Course::GetCourseInfo(
|
||||
vector<Song*>& vSongsOut,
|
||||
vector<Notes*>& vNotesOut,
|
||||
vector<CString>& vsModifiersOut,
|
||||
NotesType nt,
|
||||
bool bDifficult ) const
|
||||
{
|
||||
Song* pSong = GetSong(iStage);
|
||||
CString sDescription = entries[iStage].description;
|
||||
|
||||
/* First, search for an exact description match. */
|
||||
unsigned i;
|
||||
for( i=0; i<pSong->m_apNotes.size(); i++ )
|
||||
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) )
|
||||
continue;
|
||||
Song* pSong;
|
||||
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) )
|
||||
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() )
|
||||
if( pSong == NULL )
|
||||
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 )
|
||||
continue; // skip
|
||||
|
||||
apSongsOut.push_back( pSong );
|
||||
apNotesOut.push_back( pNotes );
|
||||
asModifiersOut.push_back( sModifiers );
|
||||
|
||||
CString sModifiers = entries[i].modifiers;
|
||||
|
||||
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
|
||||
if( GetNumStages() >= 7 )
|
||||
if( m_entries.size() >= 7 )
|
||||
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
|
||||
else
|
||||
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();
|
||||
//hack: The lifebar modifiers were not showing up (in the extra stages) - had to add it here.
|
||||
if( entries.size() > 0 )
|
||||
pSO_out->FromString( entries[0].modifiers );
|
||||
pSO_out->m_LifeType = (m_iLives==-1) ? SongOptions::LIFE_BAR : SongOptions::LIFE_BATTERY;
|
||||
if( m_iLives != -1 )
|
||||
pSO_out->m_iBatteryLives = m_iLives;
|
||||
for( unsigned i=0; i<m_entries.size(); i++ )
|
||||
if( IsMysterySong(i) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
int iDancePoints;
|
||||
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;
|
||||
else if( hs1.iDancePoints == hs2.iDancePoints ) return 0;
|
||||
else return +1;
|
||||
}
|
||||
static void SortDescending( vector<CourseScoreToInsert>& vHSout )
|
||||
static void SortDescending( vector<RankingToInsert>& vHSout )
|
||||
{
|
||||
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++ )
|
||||
{
|
||||
iRankingIndexOut[p] = -1;
|
||||
bNewRecordOut = false;
|
||||
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) )
|
||||
if( !bPlayerEnabled[p] )
|
||||
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.fSurviveTime = fSurviveTime[p];
|
||||
hs.pn = (PlayerNumber)p;
|
||||
@@ -377,48 +414,36 @@ void Course::AddMachineRecords( NotesType nt, int iDancePoints[NUM_PLAYERS], flo
|
||||
|
||||
// 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
|
||||
CourseScoreToInsert::SortDescending( vHS );
|
||||
RankingToInsert::SortDescending( vHS );
|
||||
|
||||
for( unsigned i=0; i<vHS.size(); i++ )
|
||||
{
|
||||
CourseScoreToInsert& newHS = vHS[i];
|
||||
MachineScore* machineScores = m_MachineScores[nt];
|
||||
RankingToInsert& newHS = vHS[i];
|
||||
RankingScore* rankingScores = m_RankingScores[nt];
|
||||
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.
|
||||
for( int j=i+1; j<NUM_RANKING_LINES; j++ )
|
||||
machineScores[j] = machineScores[j-1];
|
||||
rankingScores[j] = rankingScores[j-1];
|
||||
// insert
|
||||
machineScores[i].fSurviveTime = newHS.fSurviveTime;
|
||||
machineScores[i].iDancePoints = newHS.iDancePoints;
|
||||
machineScores[i].sName = "STEP";
|
||||
rankingScores[i].fSurviveTime = newHS.fSurviveTime;
|
||||
rankingScores[i].iDancePoints = newHS.iDancePoints;
|
||||
rankingScores[i].sName = DEFAULT_RANKING_NAME;
|
||||
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
|
||||
//
|
||||
static int CompareCoursePointersByDifficulty(const Course* pCourse1, const Course* pCourse2)
|
||||
{
|
||||
return pCourse1->GetNumStages() < pCourse2->GetNumStages();
|
||||
return pCourse1->GetEstimatedNumStages() < pCourse2->GetEstimatedNumStages();
|
||||
}
|
||||
|
||||
void SortCoursePointerArrayByDifficulty( vector<Course*> &apCourses )
|
||||
|
||||
+40
-28
@@ -21,63 +21,75 @@ struct Notes;
|
||||
class Course
|
||||
{
|
||||
struct course_entry {
|
||||
CString description; // the Notes description
|
||||
CString modifiers; // set player and song options from these
|
||||
Song *song;
|
||||
course_entry( CString dir, Difficulty dc, CString mod )
|
||||
{
|
||||
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<int> order;
|
||||
vector<course_entry> m_entries;
|
||||
|
||||
public:
|
||||
Course();
|
||||
|
||||
bool m_bIsAutoGen; // was this created by AutoGen?
|
||||
CString m_sPath;
|
||||
CString m_sName;
|
||||
CString m_sBannerPath;
|
||||
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
|
||||
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 CreateEndlessCourseFromGroupAndDifficulty( CString sGroupName, Difficulty dc, vector<Song*> &apSongsInGroup );
|
||||
void AddStage( Song* pSong, CString sDescription, CString sModifiers );
|
||||
void AutoGenEndlessFromGroupAndDifficulty( CString sGroupName, Difficulty dc, vector<Song*> &apSongsInGroup );
|
||||
|
||||
void GetSongAndNotesForCurrentStyle( vector<Song*>& apSongsOut, vector<Notes*>& apNotesOut, CStringArray& asModifiersOut, bool bShuffled );
|
||||
RageColor GetColor();
|
||||
|
||||
// Statistics
|
||||
int m_iNumTimesPlayed;
|
||||
|
||||
struct MachineScore
|
||||
struct RankingScore
|
||||
{
|
||||
int iDancePoints;
|
||||
float fSurviveTime;
|
||||
CString sName;
|
||||
} m_MachineScores[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
|
||||
|
||||
} m_RankingScores[NUM_NOTES_TYPES][NUM_RANKING_LINES]; // sorted highest to lowest by iDancePoints
|
||||
struct MemCardScore
|
||||
{
|
||||
int iNumTimesPlayed;
|
||||
int iDancePoints;
|
||||
float fSurviveTime;
|
||||
} m_MemCardScores[NUM_NOTES_TYPES][NUM_PLAYERS];
|
||||
bool AddMemCardRecord( PlayerNumber pn, NotesType nt, int iDancePoints, float fSurviveTime ); // return true if this is a new record
|
||||
} m_MemCardScores[NUM_MEMORY_CARDS][NUM_NOTES_TYPES];
|
||||
|
||||
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:
|
||||
void Shuffle();
|
||||
Song *FindSong(CString sSongDir);
|
||||
Song *FindSong(CString sSongDir) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -22,19 +22,18 @@
|
||||
#include "RageDisplay.h"
|
||||
#include "ThemeManager.h"
|
||||
#include "Notes.h"
|
||||
#include "GameState.h"
|
||||
#include "StyleDef.h"
|
||||
|
||||
|
||||
const float TEXT_BANNER_X = 0;
|
||||
const float TEXT_BANNER_Y = 0;
|
||||
|
||||
const float NUMBER_X = -118;
|
||||
const float NUMBER_Y = 0;
|
||||
|
||||
const float FOOT_X = 102;
|
||||
const float FOOT_Y = 8;
|
||||
|
||||
const float DIFFICULTY_X = FOOT_X+18;
|
||||
const float DIFFICULTY_Y = FOOT_Y;
|
||||
#define TEXT_BANNER_X THEME->GetMetricF("CourseContentDisplay","TextBannerX")
|
||||
#define TEXT_BANNER_Y THEME->GetMetricF("CourseContentDisplay","TextBannerY")
|
||||
#define NUMBER_X THEME->GetMetricF("CourseContentDisplay","NumberX")
|
||||
#define NUMBER_Y THEME->GetMetricF("CourseContentDisplay","NumberY")
|
||||
#define FOOT_X THEME->GetMetricF("CourseContentDisplay","FootX")
|
||||
#define FOOT_Y THEME->GetMetricF("CourseContentDisplay","FootY")
|
||||
#define DIFFICULTY_X THEME->GetMetricF("CourseContentDisplay","DifficultyX")
|
||||
#define DIFFICULTY_Y THEME->GetMetricF("CourseContentDisplay","DifficultyY")
|
||||
|
||||
|
||||
CourseContentDisplay::CourseContentDisplay()
|
||||
@@ -103,13 +102,16 @@ void CourseContentsFrame::SetFromCourse( Course* pCourse )
|
||||
|
||||
m_iNumContents = 0;
|
||||
|
||||
for( int i=0; i<min(pCourse->GetNumStages(), MAX_TOTAL_CONTENTS); i++ )
|
||||
{
|
||||
Song* pSong = pCourse->GetSong(i);
|
||||
Notes* pNotes = pCourse->GetNotesForStage(i);
|
||||
vector<Song*> vSongs;
|
||||
vector<Notes*> vNotes;
|
||||
vector<CString> vsModifiers;
|
||||
pCourse->GetCourseInfo( vSongs, vNotes, vsModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType, false );
|
||||
|
||||
if( pNotes == NULL )
|
||||
continue; // skip
|
||||
for( int i=0; i<min((int)vSongs.size(), MAX_TOTAL_CONTENTS); i++ )
|
||||
{
|
||||
Song* pSong = vSongs[i];
|
||||
Notes* pNotes = vNotes[i];
|
||||
CString sModifiers = vsModifiers[i];
|
||||
|
||||
LOG->Trace( "Adding song '%s'\n", pSong->m_sMainTitle.GetString() );
|
||||
m_CourseContentDisplays[m_iNumContents].Load( m_iNumContents+1, pSong, pNotes );
|
||||
|
||||
@@ -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
|
||||
//
|
||||
@@ -186,6 +198,8 @@ enum RankingCategory
|
||||
NUM_RANKING_CATEGORIES
|
||||
};
|
||||
|
||||
const CString DEFAULT_RANKING_NAME = "STEP";
|
||||
|
||||
RankingCategory AverageMeterToRankingCategory( float fAverageMeter );
|
||||
|
||||
const int NUM_RANKING_LINES = 5;
|
||||
|
||||
@@ -199,6 +199,15 @@ RageColor GameState::GetStageColor()
|
||||
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()
|
||||
{
|
||||
ASSERT( m_CurGame != GAME_INVALID ); // the game must be set before calling this
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
bool m_bEditing; // NoteField does special stuff when this is true
|
||||
bool m_bDemonstration; // ScreenGameplay does special stuff when this is true
|
||||
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 GetNumStagesLeft();
|
||||
@@ -78,6 +78,7 @@ public:
|
||||
bool IsExtraStage2();
|
||||
CString GetStageText();
|
||||
RageColor GetStageColor();
|
||||
int GetCourseSongIndex();
|
||||
|
||||
//
|
||||
// State Info used during gameplay
|
||||
|
||||
@@ -447,13 +447,11 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
|
||||
Course* pCourse = apCourses[c];
|
||||
|
||||
// check that this course has at least one song playable in the current style
|
||||
vector<Song*> apSongs;
|
||||
vector<Notes*> apNotes;
|
||||
CStringArray asModifiers;
|
||||
pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes, asModifiers, false );
|
||||
|
||||
if( !apNotes.empty() )
|
||||
arrayWheelItemDatas.push_back( WheelItemData(TYPE_COURSE, NULL, "", pCourse, pCourse->GetColor()) );
|
||||
Song* pSongs;
|
||||
Notes* pNotes;
|
||||
CString sModifiers;
|
||||
if( pCourse->GetFirstStageInfo(pSongs, pNotes, sModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType) )
|
||||
arrayWheelItemDatas.push_back( WheelItemData(TYPE_COURSE, NULL, "", pCourse, pCourse->GetColor()) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
+17
-7
@@ -44,15 +44,15 @@ Notes::Notes()
|
||||
for(int i = 0; i < NUM_RADAR_CATEGORIES; ++i)
|
||||
m_fRadarValues[i] = -1; /* unknown */
|
||||
|
||||
m_iNumTimesPlayed = 0;
|
||||
notes = NULL;
|
||||
notes_comp = 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[p].fScore = 0;
|
||||
m_MemCardScores[m].iNumTimesPlayed = 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;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
m_MemCardScores[pn].fScore = fScore;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -54,16 +54,15 @@ public:
|
||||
void CreateBlank( NotesType ntTo );
|
||||
|
||||
|
||||
// High scores;
|
||||
int m_iNumTimesPlayed;
|
||||
|
||||
// High scores
|
||||
struct MemCardScore
|
||||
{
|
||||
int iNumTimesPlayed;
|
||||
Grade grade;
|
||||
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();
|
||||
|
||||
@@ -247,36 +247,28 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
//
|
||||
// update persistent statistics
|
||||
//
|
||||
bool bNewRecord[NUM_PLAYERS];
|
||||
memset( bNewRecord, 0, sizeof(bNewRecord) );
|
||||
bool bIsPlayerEnabled[NUM_PLAYERS];
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) || grade[p] == GRADE_E )
|
||||
continue; // can't be a new record
|
||||
bIsPlayerEnabled[p] = GAMESTATE->IsPlayerEnabled(p);
|
||||
int iRankingLine[NUM_PLAYERS] = { -1, -1 };
|
||||
bool bNewRecord[NUM_PLAYERS] = { false, false };
|
||||
|
||||
switch( m_ResultMode )
|
||||
{
|
||||
case RM_ARCADE_STAGE:
|
||||
{
|
||||
Notes* pNotes = GAMESTATE->m_pCurNotes[p];
|
||||
if( SONGMAN->IsUsingMemoryCard((PlayerNumber)p) )
|
||||
bNewRecord[p] = pNotes->AddMemCardRecord( (PlayerNumber)p, grade[p], stageStats.fScore[p] );
|
||||
}
|
||||
break;
|
||||
case RM_ARCADE_SUMMARY:
|
||||
{
|
||||
}
|
||||
break;
|
||||
case RM_COURSE:
|
||||
{
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
NotesType nt = GAMESTATE->GetCurrentStyleDef()->m_NotesType;
|
||||
pCourse->AddMemCardRecord( (PlayerNumber)p, nt, stageStats.iActualDancePoints[p], stageStats.fAliveSeconds[p] );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
switch( m_ResultMode )
|
||||
{
|
||||
case RM_ARCADE_STAGE:
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
if( GAMESTATE->IsPlayerEnabled(p) )
|
||||
GAMESTATE->m_pCurNotes[p]->AddScore( (PlayerNumber)p, grade[p], stageStats.fScore[p], bNewRecord[p] );
|
||||
break;
|
||||
case RM_ARCADE_SUMMARY:
|
||||
break;
|
||||
case RM_COURSE:
|
||||
NotesType nt;
|
||||
nt = GAMESTATE->GetCurrentStyleDef()->m_NotesType;
|
||||
GAMESTATE->m_pCurCourse->AddScores( nt, bIsPlayerEnabled, stageStats.iActualDancePoints, stageStats.fAliveSeconds, iRankingLine, bNewRecord );
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
m_bTryExtraStage =
|
||||
|
||||
@@ -34,16 +34,16 @@
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
#define SONGSEL_SCREEN THEME->GetMetric("ScreenGameplay","SongSelectScreen")
|
||||
#define MAXCOMBO_X THEME->GetMetricF("ScreenGameplay","MAXCOMBOX")
|
||||
#define MAXCOMBO_Y THEME->GetMetricF("ScreenGameplay","MAXCOMBOY")
|
||||
#define MAXCOMBO_ZOOM THEME->GetMetricF("ScreenGameplay","MAXCOMBOZoom")
|
||||
#define BPM_X THEME->GetMetricF("ScreenGameplay","BPMX")
|
||||
#define BPM_Y THEME->GetMetricF("ScreenGameplay","BPMY")
|
||||
#define BPM_ZOOM THEME->GetMetricF("ScreenGameplay","BPMZoom")
|
||||
#define STAGENAME_X THEME->GetMetricF("ScreenGameplay","StagenameX")
|
||||
#define STAGENAME_Y THEME->GetMetricF("ScreenGameplay","StagenameY")
|
||||
#define STAGENAME_ZOOM THEME->GetMetricF("ScreenGameplay","StagenameZoom")
|
||||
#define SONGSEL_SCREEN THEME->GetMetric("ScreenGameplay","SongSelectScreen")
|
||||
#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_ZOOM THEME->GetMetricF("ScreenGameplay","MAXCOMBOZoom")
|
||||
#define BPM_X THEME->GetMetricF("ScreenGameplay","BPMX")
|
||||
#define BPM_Y THEME->GetMetricF("ScreenGameplay","BPMY")
|
||||
#define BPM_ZOOM THEME->GetMetricF("ScreenGameplay","BPMZoom")
|
||||
#define STAGENAME_X THEME->GetMetricF("ScreenGameplay","StagenameX")
|
||||
#define STAGENAME_Y THEME->GetMetricF("ScreenGameplay","StagenameY")
|
||||
#define STAGENAME_ZOOM THEME->GetMetricF("ScreenGameplay","StagenameZoom")
|
||||
#define LIFE_FRAME_X THEME->GetMetricF("ScreenGameplay","LifeFrameX")
|
||||
#define LIFE_FRAME_Y( e ) THEME->GetMetricF("ScreenGameplay",ssprintf("LifeFrame%sY",e?"Extra":""))
|
||||
#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 )
|
||||
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;
|
||||
m_pScoreDisplay[p] = NULL;
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
m_pLifeMeter[p] = NULL;
|
||||
m_pScoreDisplay[p] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_fTickEarlySecondsCache = TICK_EARLY_SECONDS;
|
||||
|
||||
SOUNDMAN->StopMusic();
|
||||
|
||||
|
||||
GAMESTATE->m_CurStageStats = StageStats(); // clear values
|
||||
|
||||
|
||||
// Fill in m_CurStageStats
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
NoteData notedata;
|
||||
switch( GAMESTATE->m_PlayMode )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) )
|
||||
continue; // skip
|
||||
|
||||
NoteData notedata;
|
||||
switch( GAMESTATE->m_PlayMode )
|
||||
case PLAY_MODE_ARCADE:
|
||||
{
|
||||
case PLAY_MODE_ARCADE:
|
||||
GAMESTATE->m_CurStageStats.pSong = GAMESTATE->m_pCurSong;
|
||||
GAMESTATE->m_CurStageStats.iMeter[p] = GAMESTATE->m_pCurNotes[p]->GetMeter();
|
||||
|
||||
GAMESTATE->m_pCurNotes[p]->GetNoteData( ¬edata );
|
||||
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] = notedata.GetPossibleDancePoints();
|
||||
break;
|
||||
case PLAY_MODE_NONSTOP:
|
||||
case PLAY_MODE_ONI:
|
||||
case PLAY_MODE_ENDLESS:
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
GAMESTATE->m_CurStageStats.pSong = NULL;
|
||||
GAMESTATE->m_CurStageStats.iMeter[p] = 0;
|
||||
|
||||
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] = 0;
|
||||
|
||||
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( ¬edata );
|
||||
int iPossibleDancePoints = notedata.GetPossibleDancePoints();
|
||||
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] += iPossibleDancePoints;
|
||||
}
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) )
|
||||
continue; // skip
|
||||
GAMESTATE->m_CurStageStats.iMeter[p] = GAMESTATE->m_pCurNotes[p]->GetMeter();
|
||||
GAMESTATE->m_pCurNotes[p]->GetNoteData( ¬edata );
|
||||
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] = notedata.GetPossibleDancePoints();
|
||||
}
|
||||
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( ¬edata );
|
||||
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 );
|
||||
|
||||
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
|
||||
continue;
|
||||
@@ -495,23 +495,10 @@ bool ScreenGameplay::IsLastSong()
|
||||
case PLAY_MODE_ENDLESS:
|
||||
{
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
|
||||
if( pCourse->m_bRepeat )
|
||||
return false;
|
||||
|
||||
vector<Song*> apSongs;
|
||||
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
|
||||
else
|
||||
return GAMESTATE->GetCourseSongIndex() == (int)m_apCourseSongs.size();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -540,31 +527,18 @@ void ScreenGameplay::LoadNextSong()
|
||||
if( GAMESTATE->m_CurStageStats.iSongsPassed[p] == 0 )
|
||||
GAMESTATE->m_SelectedOptions[p] = GAMESTATE->m_PlayerOptions[p];
|
||||
}
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
vector<Song*> apSongs;
|
||||
vector<Notes*> apNotes;
|
||||
CStringArray asModifiers;
|
||||
int iPlaySongIndex = GAMESTATE->GetCourseSongIndex();
|
||||
iPlaySongIndex %= m_apCourseSongs.size();
|
||||
GAMESTATE->m_pCurSong = m_apCourseSongs[iPlaySongIndex];
|
||||
|
||||
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++ )
|
||||
{
|
||||
GAMESTATE->m_pCurNotes[p] = apNotes[iPlaySongIndex];
|
||||
// Wipe the options used on the last song (including course specified ones)
|
||||
GAMESTATE->m_PlayerOptions[p].Init();
|
||||
// Now restore the player's originally selected options.
|
||||
GAMESTATE->m_pCurNotes[p] = m_apCourseNotes[iPlaySongIndex];
|
||||
// Restore the player's originally selected options.
|
||||
GAMESTATE->m_PlayerOptions[p] = GAMESTATE->m_SelectedOptions[p];
|
||||
if( asModifiers[iPlaySongIndex] != "" ) // some modifiers specified
|
||||
GAMESTATE->m_PlayerOptions[p].FromString( asModifiers[iPlaySongIndex] ); // put them into effect
|
||||
// Put courses options into effect.
|
||||
GAMESTATE->m_PlayerOptions[p].FromString( m_asCourseModifiers[iPlaySongIndex] );
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1070,7 +1044,7 @@ void SaveChanges()
|
||||
* 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
|
||||
* 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 )
|
||||
{
|
||||
case PLAY_MODE_ARCADE:
|
||||
@@ -1080,11 +1054,9 @@ void SaveChanges()
|
||||
case PLAY_MODE_ONI:
|
||||
case PLAY_MODE_ENDLESS:
|
||||
{
|
||||
for( int i=0; i<GAMESTATE->m_pCurCourse->GetNumStages(); i++ )
|
||||
{
|
||||
Song* pSong = GAMESTATE->m_pCurCourse->GetSong(i);
|
||||
pSong->Save();
|
||||
}
|
||||
// FIXME
|
||||
//for( int i=0; i<m_apCourseSongs.size(); i++ )
|
||||
// m_apCourseSongs[i]->Save();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1105,11 +1077,12 @@ void DontSaveChanges()
|
||||
case PLAY_MODE_ONI:
|
||||
case PLAY_MODE_ENDLESS:
|
||||
{
|
||||
for( int i=0; i<GAMESTATE->m_pCurCourse->GetNumStages(); i++ )
|
||||
{
|
||||
Song* pSong = GAMESTATE->m_pCurCourse->GetSong(i);
|
||||
ld.LoadFromSMFile( GAMESTATE->m_pCurSong->GetCacheFilePath(), *pSong );
|
||||
}
|
||||
// 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 );
|
||||
// }
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -77,8 +77,11 @@ protected:
|
||||
STATE_DANCING,
|
||||
STATE_OUTRO, // not allowed to press Back
|
||||
NUM_DANCING_STATES
|
||||
};
|
||||
DancingState m_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;
|
||||
|
||||
float m_fTimeLeftBeforeDancingComment; // this counter is only running while STATE_DANCING
|
||||
|
||||
@@ -49,7 +49,7 @@ ScreenLogo::ScreenLogo() : ScreenAttract("ScreenLogo","logo")
|
||||
|
||||
m_textSongs.LoadFromFont( THEME->GetPathTo("Fonts","normal") );
|
||||
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.SetXY( SONGS_X, SONGS_Y );
|
||||
m_textSongs.SetZoom( 0.5f );
|
||||
|
||||
@@ -163,17 +163,21 @@ ScreenNameEntry::ScreenNameEntry()
|
||||
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
|
||||
bool bPlayerIsEnabled[NUM_PLAYERS];
|
||||
int iDancePoints[NUM_PLAYERS];
|
||||
float fAliveSeconds[NUM_PLAYERS];
|
||||
int iRankingIndex[NUM_PLAYERS];
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
bPlayerIsEnabled[p] = GAMESTATE->IsPlayerEnabled(p);
|
||||
iDancePoints[p] = stageStats.iActualDancePoints[p];
|
||||
fAliveSeconds[p] = stageStats.fAliveSeconds[p];
|
||||
}
|
||||
|
||||
int iRankingIndex[NUM_PLAYERS];
|
||||
bool bNewRecord[NUM_PLAYERS];
|
||||
|
||||
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_pLastPlayedCourse = pCourse;
|
||||
@@ -409,7 +413,7 @@ void ScreenNameEntry::MenuStart( PlayerNumber pn )
|
||||
TrimLeft( m_sSelectedName[pn], " " );
|
||||
|
||||
if( m_sSelectedName[pn] == "" )
|
||||
m_sSelectedName[pn] = "STEP";
|
||||
m_sSelectedName[pn] = DEFAULT_RANKING_NAME;
|
||||
|
||||
|
||||
switch( GAMESTATE->m_PlayMode )
|
||||
@@ -420,7 +424,7 @@ void ScreenNameEntry::MenuStart( PlayerNumber pn )
|
||||
case PLAY_MODE_NONSTOP:
|
||||
case PLAY_MODE_ONI:
|
||||
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;
|
||||
default:
|
||||
ASSERT(0);
|
||||
|
||||
@@ -236,9 +236,9 @@ void ScreenRanking::SetPage( PageToShow pts )
|
||||
for( int l=0; l<NUM_RANKING_LINES; l++ )
|
||||
{
|
||||
m_sprBullets[l].SetDiffuse( RageColor(1,1,1,1) );
|
||||
CString sName = pts.pCourse->m_MachineScores[pts.nt][l].sName;
|
||||
int iDancePoints = pts.pCourse->m_MachineScores[pts.nt][l].iDancePoints;
|
||||
float fSurviveTime = pts.pCourse->m_MachineScores[pts.nt][l].fSurviveTime;
|
||||
CString sName = pts.pCourse->m_RankingScores[pts.nt][l].sName;
|
||||
int iDancePoints = pts.pCourse->m_RankingScores[pts.nt][l].iDancePoints;
|
||||
float fSurviveTime = pts.pCourse->m_RankingScores[pts.nt][l].fSurviveTime;
|
||||
m_textNames[l].SetText( sName );
|
||||
m_textScores[l].SetText( "" );
|
||||
m_textPoints[l].SetText( ssprintf("%04d",iDancePoints) );
|
||||
|
||||
@@ -299,9 +299,13 @@ void ScreenSelectCourse::MenuStart( PlayerNumber pn )
|
||||
|
||||
Course* pCourse = m_MusicWheel.GetSelectedCourse();
|
||||
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++ )
|
||||
pCourse->GetPlayerOptions( 0, &GAMESTATE->m_PlayerOptions[p] );
|
||||
pCourse->GetSongOptions( &GAMESTATE->m_SongOptions );
|
||||
GAMESTATE->m_PlayerOptions[p].FromString( sModifiers );
|
||||
GAMESTATE->m_SongOptions.FromString( sModifiers );
|
||||
|
||||
m_Menu.StopTimer();
|
||||
|
||||
@@ -328,11 +332,12 @@ void ScreenSelectCourse::AfterCourseChange()
|
||||
{
|
||||
Course* pCourse = m_MusicWheel.GetSelectedCourse();
|
||||
|
||||
m_textNumSongs.SetText( ssprintf("%d", pCourse->GetNumStages()) );
|
||||
float fTotalSeconds = 0;
|
||||
for( int i=0; i<pCourse->GetNumStages(); i++ )
|
||||
fTotalSeconds += pCourse->GetSong(i)->m_fMusicLengthSeconds;
|
||||
m_textTime.SetText( SecondsToTime(fTotalSeconds) );
|
||||
m_textNumSongs.SetText( ssprintf("%d", pCourse->GetEstimatedNumStages()) );
|
||||
float fTotalSeconds;
|
||||
if( pCourse->GetTotalSeconds(fTotalSeconds) )
|
||||
m_textTime.SetText( SecondsToTime(fTotalSeconds) );
|
||||
else
|
||||
m_textTime.SetText( "??:??:??" );
|
||||
|
||||
m_Banner.LoadFromCourse( pCourse );
|
||||
|
||||
|
||||
@@ -635,12 +635,13 @@ void Song::GetNotes( vector<Notes*>& arrayAddTo, NotesType nt, bool bIncludeAuto
|
||||
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
|
||||
if( m_apNotes[i]->m_NotesType==nt && m_apNotes[i]->GetDifficulty()==dc )
|
||||
if( bIncludeAutoGen || !m_apNotes[i]->IsAutogen() )
|
||||
return m_apNotes[i];
|
||||
if( sDescription.empty() || m_apNotes[i]->GetDescription()==sDescription )
|
||||
return m_apNotes[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1008,7 +1009,7 @@ int Song::GetNumTimesPlayed() const
|
||||
int iTotalNumTimesPlayed = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
+251
-64
@@ -28,10 +28,14 @@
|
||||
SongManager* SONGMAN = NULL; // global and accessable from anywhere in our program
|
||||
|
||||
|
||||
const CString CATEGORY_TOP_SCORE_FILE = "CategoryTopScores.dat";
|
||||
const CString COURSE_TOP_SCORE_FILE = "CourseTopScores.dat";
|
||||
const int CATEGORY_TOP_SCORE_VERSION = 1;
|
||||
const int COURSE_TOP_SCORE_VERSION = 1;
|
||||
const CString CATEGORY_RANKING_FILE = "CategoryRanking.dat";
|
||||
const CString COURSE_RANKING_FILE = "CourseRanking.dat";
|
||||
const CString NOTES_SCORES_FILE[NUM_MEMORY_CARDS] = { "Player1NotesScores.dat", "Player2NotesScores.dat", "MachineNotesScores.dat" };
|
||||
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")
|
||||
@@ -211,25 +215,25 @@ void SongManager::ReloadSongArray()
|
||||
void SongManager::InitMachineScoresFromDisk()
|
||||
{
|
||||
|
||||
// Init category top scores
|
||||
// Init category ranking
|
||||
{
|
||||
for( int i=0; i<NUM_NOTES_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].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 )
|
||||
{
|
||||
int 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 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 )
|
||||
{
|
||||
int version;
|
||||
fscanf(fp, "%d\n", &version );
|
||||
if( version == COURSE_TOP_SCORE_VERSION )
|
||||
fscanf(fp, "%[^\n]\n", &version );
|
||||
if( version == COURSE_RANKING_VERSION )
|
||||
{
|
||||
while( fp && !feof(fp) )
|
||||
{
|
||||
char szPath[256];
|
||||
fscanf(fp, "%s\n", szPath);
|
||||
Course* pCourse = GetCourseFromPath( szPath );
|
||||
|
||||
char szPath[256];
|
||||
fscanf(fp, "%s\n", szPath);
|
||||
Course* pCourse = GetCourseFromPath( szPath );
|
||||
if( pCourse == NULL )
|
||||
pCourse = GetCourseFromName( szPath );
|
||||
|
||||
for( int i=0; i<NUM_NOTES_TYPES; i++ )
|
||||
for( int j=0; j<NUM_RANKING_LINES; j++ )
|
||||
if( fp && !feof(fp) )
|
||||
for( int j=0; j<NUM_RANKING_LINES; j++ )
|
||||
if( fp && !feof(fp) )
|
||||
{
|
||||
int iDancePoints;
|
||||
float fSurviveTime;
|
||||
char szName[256];
|
||||
fscanf(fp, "%d %f %[^\n]\n", &iDancePoints, &fSurviveTime, szName);
|
||||
if( pCourse )
|
||||
{
|
||||
int iDancePoints;
|
||||
float fSurviveTime;
|
||||
char szName[256];
|
||||
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;
|
||||
}
|
||||
pCourse->m_RankingScores[i][j].iDancePoints = iDancePoints;
|
||||
pCourse->m_RankingScores[i][j].fSurviveTime = fSurviveTime;
|
||||
pCourse->m_RankingScores[i][j].sName = szName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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()
|
||||
{
|
||||
// Write category top scores
|
||||
// category ranking
|
||||
{
|
||||
FILE* fp = fopen( CATEGORY_TOP_SCORE_FILE, "w" );
|
||||
FILE* fp = fopen( CATEGORY_RANKING_FILE, "w" );
|
||||
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 j=0; j<NUM_RANKING_CATEGORIES; j++ )
|
||||
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 )
|
||||
{
|
||||
fprintf(fp,"%d",COURSE_TOP_SCORE_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];
|
||||
|
||||
fprintf(fp, "%s\n", pCourse->m_sPath.c_str());
|
||||
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++ )
|
||||
for( int j=0; j<NUM_RANKING_LINES; j++ )
|
||||
fprintf(fp, "%d %f %s\n",
|
||||
pCourse->m_MachineScores[i][j].iDancePoints,
|
||||
pCourse->m_MachineScores[i][j].fSurviveTime,
|
||||
pCourse->m_MachineScores[i][j].sName.c_str());
|
||||
pCourse->m_RankingScores[i][j].iDancePoints,
|
||||
pCourse->m_RankingScores[i][j].fSurviveTime,
|
||||
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();
|
||||
}
|
||||
|
||||
int SongManager::GetNumCourses() const
|
||||
{
|
||||
return m_pCourses.size();
|
||||
}
|
||||
|
||||
CString SongManager::ShortenGroupName( CString sLongGroupName )
|
||||
{
|
||||
sLongGroupName.Replace( "Dance Dance Revolution", "DDR" );
|
||||
@@ -434,10 +598,7 @@ void SongManager::InitCoursesFromDisk()
|
||||
{
|
||||
Course* pCourse = new Course;
|
||||
pCourse->LoadFromCRSFile( saCourseFiles[i] );
|
||||
if( pCourse->GetNumStages() > 0 )
|
||||
m_pCourses.push_back( pCourse );
|
||||
else
|
||||
delete pCourse;
|
||||
m_pCourses.push_back( pCourse );
|
||||
}
|
||||
|
||||
//
|
||||
@@ -455,12 +616,9 @@ void SongManager::InitCoursesFromDisk()
|
||||
for( Difficulty dc=DIFFICULTY_EASY; dc<=DIFFICULTY_HARD; dc=Difficulty(dc+1) ) // foreach Difficulty
|
||||
{
|
||||
Course* pCourse = new Course;
|
||||
pCourse->CreateEndlessCourseFromGroupAndDifficulty( sGroupName, dc, apGroupSongs );
|
||||
pCourse->AutoGenEndlessFromGroupAndDifficulty( sGroupName, dc, apGroupSongs );
|
||||
|
||||
if( pCourse->GetNumStages() > 0 )
|
||||
m_pCourses.push_back( pCourse );
|
||||
else
|
||||
delete pCourse;
|
||||
m_pCourses.push_back( pCourse );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -556,16 +714,17 @@ bool SongManager::GetExtraStageInfoFromCourse( bool bExtra2, CString sPreferredG
|
||||
|
||||
Course course;
|
||||
course.LoadFromCRSFile( sCoursePath );
|
||||
if( course.GetNumStages() <= 0 ) return false;
|
||||
if( course.GetEstimatedNumStages() <= 0 ) return false;
|
||||
|
||||
pSongOut = course.GetSong(0);
|
||||
pNotesOut = course.GetNotesForStage( 0 );
|
||||
if( pNotesOut == NULL ) return false;
|
||||
|
||||
course.GetPlayerOptions( 0, &po_out );
|
||||
course.GetSongOptions( &so_out );
|
||||
|
||||
return true;
|
||||
CString sModifiers;
|
||||
if( course.GetFirstStageInfo( pSongOut, pNotesOut, sModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType ) )
|
||||
{
|
||||
po_out.FromString( sModifiers );
|
||||
so_out.FromString( sModifiers );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return true if n1 < n2. */
|
||||
@@ -670,6 +829,24 @@ Song* SongManager::GetRandomSong()
|
||||
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 )
|
||||
{
|
||||
if( sDir[sDir.GetLength()-1] != '/' )
|
||||
@@ -691,6 +868,16 @@ Course* SongManager::GetCourseFromPath( CString sPath )
|
||||
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 )
|
||||
{
|
||||
return true;
|
||||
@@ -749,7 +936,7 @@ void SongManager::AddMachineRecords( NotesType nt, RankingCategory hsc[NUM_PLAYE
|
||||
machineScores[j] = machineScores[j-1];
|
||||
// insert
|
||||
machineScores[i].fScore = newHS.fScore;
|
||||
machineScores[i].sName = "STEP";
|
||||
machineScores[i].sName = DEFAULT_RANKING_NAME;
|
||||
iNewRecordIndexOut[newHS.pn] = i;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,11 @@ public:
|
||||
void GetSongs( vector<Song*> &AddTo ) const { GetSongs(AddTo,"",100000 /*inf*/ ); }
|
||||
int GetNumSongs() const;
|
||||
int GetNumGroups() const;
|
||||
int GetNumCourses() const;
|
||||
Song* GetRandomSong();
|
||||
Song* GetPlayersBest( int index );
|
||||
Song* GetPlayersWorst( int index );
|
||||
|
||||
|
||||
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.
|
||||
@@ -69,6 +73,7 @@ public:
|
||||
|
||||
Song* GetSongFromDir( CString sDir );
|
||||
Course* GetCourseFromPath( CString sPath ); // path to .crs file, or path to song group dir
|
||||
Course* GetCourseFromName( CString sName );
|
||||
|
||||
|
||||
//
|
||||
|
||||
@@ -206,7 +206,7 @@ public:
|
||||
bool SongHasNotesType( NotesType nt ) const;
|
||||
bool SongHasNotesTypeAndDifficulty( NotesType nt, Difficulty dc ) 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;
|
||||
int GetNumTimesPlayed() const;
|
||||
bool IsNew() const;
|
||||
|
||||
Reference in New Issue
Block a user