support for full CRS specification and PlayerBest/Worst
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
#COURSE:All Music Random;
|
||||
#SONG:*:TRICK;
|
||||
#SONG:*:TRICK;
|
||||
#SONG:*:TRICK;
|
||||
#SONG:*:TRICK;
|
||||
@@ -0,0 +1,6 @@
|
||||
#COURSE:Players Best 1-4;
|
||||
#SONG:PlayersBest1:TRICK;
|
||||
#SONG:PlayersBest2:TRICK;
|
||||
#SONG:PlayersBest3:TRICK;
|
||||
#SONG:PlayersBest4:TRICK;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#COURSE:Players Best 13-16;
|
||||
#SONG:PlayersBest13:TRICK;
|
||||
#SONG:PlayersBest14:TRICK;
|
||||
#SONG:PlayersBest15:TRICK;
|
||||
#SONG:PlayersBest16:TRICK;
|
||||
@@ -0,0 +1,5 @@
|
||||
#COURSE:Players Best 5-8;
|
||||
#SONG:PlayersBest5:TRICK;
|
||||
#SONG:PlayersBest6:TRICK;
|
||||
#SONG:PlayersBest7:TRICK;
|
||||
#SONG:PlayersBest8:TRICK;
|
||||
@@ -0,0 +1,5 @@
|
||||
#COURSE:Players Best 9-12;
|
||||
#SONG:PlayersBest9:TRICK;
|
||||
#SONG:PlayersBest10:TRICK;
|
||||
#SONG:PlayersBest11:TRICK;
|
||||
#SONG:PlayersBest12:TRICK;
|
||||
@@ -0,0 +1,5 @@
|
||||
#COURSE:Players Worst;
|
||||
#SONG:PlayersWorst1:TRICK;
|
||||
#SONG:PlayersWorst2:TRICK;
|
||||
#SONG:PlayersWorst3:TRICK;
|
||||
#SONG:PlayersWorst4:TRICK;
|
||||
@@ -0,0 +1,5 @@
|
||||
#COURSE:Tricky;
|
||||
#SONG:*:TRICK:1.5x,reverse;
|
||||
#SONG:*:TRICK:expand;
|
||||
#SONG:*:TRICK:0.25x,dark;
|
||||
#SONG:*:TRICK:sudden,boost;
|
||||
+160
-62
@@ -154,17 +154,53 @@ void Course::LoadFromCRSFile( CString sPath )
|
||||
|
||||
else if( 0 == stricmp(sValueName, "SONG") )
|
||||
{
|
||||
CString sSongDir = sParams[1];
|
||||
Difficulty dc = StringToDifficulty( sParams[2] );
|
||||
CString sModifiers = sParams[3];
|
||||
// infer entry::Type from the first param
|
||||
Entry new_entry;
|
||||
|
||||
if( sSongDir.GetLength() == 0 ) {
|
||||
/* Err. */
|
||||
LOG->Trace( "Course file '%s' has an empty #SONG. Ignored.", sPath.GetString(), sSongDir.GetString() );
|
||||
continue;
|
||||
if( sParams[1].Left(strlen("PlayersBest")) == "PlayersBest" )
|
||||
{
|
||||
new_entry.type = Entry::players_best;
|
||||
new_entry.players_index = atoi( sParams[1].Right(sParams[1].size()-strlen("PlayersBest")) ) - 1;
|
||||
CLAMP( new_entry.players_index, 0, 500 );
|
||||
}
|
||||
|
||||
m_entries.push_back( course_entry(sSongDir, dc, sModifiers) );
|
||||
else if( sParams[1].Left(strlen("PlayersWorst")) == "PlayersWorst" )
|
||||
{
|
||||
new_entry.type = Entry::players_worst;
|
||||
new_entry.players_index = atoi( sParams[1].Right(sParams[1].size()-strlen("PlayersWorst")) ) - 1;
|
||||
CLAMP( new_entry.players_index, 0, 500 );
|
||||
}
|
||||
else if( sParams[1] == "*" )
|
||||
{
|
||||
new_entry.type = Entry::random;
|
||||
}
|
||||
else if( sParams[1].Right(1) == "*" )
|
||||
{
|
||||
new_entry.type = Entry::random_within_group;
|
||||
CString sThrowAway;
|
||||
splitrelpath( sParams[1], new_entry.group_name, sThrowAway, sThrowAway );
|
||||
new_entry.group_name.resize( new_entry.group_name.size()-1 ); // chomp triling slash
|
||||
}
|
||||
else
|
||||
{
|
||||
new_entry.type = Entry::fixed;
|
||||
CString sThrowAway;
|
||||
splitrelpath( sParams[1], new_entry.group_name, new_entry.song_name, sThrowAway );
|
||||
}
|
||||
|
||||
new_entry.difficulty = StringToDifficulty( sParams[2] );
|
||||
if( new_entry.difficulty == DIFFICULTY_INVALID )
|
||||
{
|
||||
int retval = sscanf( sParams[2], "%d..%d", &new_entry.low_meter, &new_entry.high_meter );
|
||||
if( retval != 2 )
|
||||
{
|
||||
new_entry.low_meter = 3;
|
||||
new_entry.high_meter = 6;
|
||||
}
|
||||
}
|
||||
|
||||
new_entry.modifiers = sParams[3];
|
||||
|
||||
m_entries.push_back( new_entry );
|
||||
}
|
||||
|
||||
else
|
||||
@@ -205,11 +241,12 @@ void Course::AutoGenEndlessFromGroupAndDifficulty( CString sGroupName, Difficult
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
for( unsigned s=0; s<apSongsInGroup.size(); s++ )
|
||||
{
|
||||
Song* pSong = apSongsInGroup[s];
|
||||
m_entries.push_back( course_entry(pSong->GetSongDir(), dc, "") );
|
||||
}
|
||||
// only need one song because it repeats
|
||||
Entry e;
|
||||
e.type = Entry::random_within_group;
|
||||
e.group_name = sGroupName;
|
||||
e.difficulty = dc;
|
||||
m_entries.push_back( e );
|
||||
}
|
||||
|
||||
|
||||
@@ -221,8 +258,13 @@ bool Course::HasDifficult() const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Course::IsPlayableIn( NotesType nt ) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Course::GetCourseInfo(
|
||||
|
||||
void Course::GetStageInfo(
|
||||
vector<Song*>& vSongsOut,
|
||||
vector<Notes*>& vNotesOut,
|
||||
vector<CString>& vsModifiersOut,
|
||||
@@ -233,58 +275,91 @@ void Course::GetCourseInfo(
|
||||
ASSERT( HasDifficult() );
|
||||
|
||||
|
||||
vector<course_entry> entries = m_entries;
|
||||
vector<Entry> entries = m_entries;
|
||||
|
||||
if( m_bRandomize )
|
||||
random_shuffle( entries.begin(), entries.end() );
|
||||
|
||||
for( unsigned i=0; i<entries.size(); i++ )
|
||||
{
|
||||
CString sSongDir = entries[i].songDir;
|
||||
const Entry& e = entries[i];
|
||||
|
||||
Song* pSong;
|
||||
if( sSongDir.Left(strlen("PlayersBest")) == "PlayersBest" )
|
||||
Song* pSong = NULL; // fill this in
|
||||
Notes* pNotes = NULL; // fill this in
|
||||
|
||||
vector<Song*> vSongsByMostPlayed = SONGMAN->GetAllSongs();
|
||||
SortSongPointerArrayByMostPlayed( vSongsByMostPlayed );
|
||||
|
||||
|
||||
switch( e.type )
|
||||
{
|
||||
int iNumber = atoi( sSongDir.Right(sSongDir.length()-strlen("PlayersBest")) );
|
||||
int index = iNumber - 1;
|
||||
pSong = SONGMAN->GetPlayersBest( index );
|
||||
case Entry::fixed:
|
||||
pSong = SONGMAN->GetSongFromDir( e.group_name + "/" + e.song_name );
|
||||
break;
|
||||
case Entry::random:
|
||||
case Entry::random_within_group:
|
||||
{
|
||||
vector<Song*> vSongs;
|
||||
SONGMAN->GetSongs( vSongs, e.group_name );
|
||||
|
||||
if( vSongs.size() == 0 )
|
||||
break;
|
||||
|
||||
// probe to find a song with the notes we want
|
||||
for( int j=0; j<500; j++ ) // try 500 times before giving up
|
||||
{
|
||||
pSong = vSongs[rand()%vSongs.size()];
|
||||
if( e.difficulty == DIFFICULTY_INVALID )
|
||||
pNotes = pSong->GetNotes( nt, e.low_meter, e.high_meter );
|
||||
else
|
||||
pNotes = pSong->GetNotes( nt, e.difficulty );
|
||||
if( pNotes ) // found a match
|
||||
break; // stop searching
|
||||
else
|
||||
{
|
||||
pSong = NULL;
|
||||
pNotes = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Entry::players_best:
|
||||
case Entry::players_worst:
|
||||
{
|
||||
if( e.players_index >= (int)vSongsByMostPlayed.size() )
|
||||
break;
|
||||
|
||||
switch( e.type )
|
||||
{
|
||||
case Entry::players_best:
|
||||
pSong = vSongsByMostPlayed[e.players_index];
|
||||
break;
|
||||
case Entry::players_worst:
|
||||
pSong = vSongsByMostPlayed[vSongsByMostPlayed.size()-1-e.players_index];
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
if( e.difficulty == DIFFICULTY_INVALID )
|
||||
pNotes = pSong->GetNotes( nt, e.low_meter, e.high_meter );
|
||||
else
|
||||
pNotes = pSong->GetNotes( nt, e.difficulty );
|
||||
|
||||
if( pNotes == NULL )
|
||||
pNotes = pSong->GetClosestNotes( nt, DIFFICULTY_MEDIUM );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
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( 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
|
||||
|
||||
|
||||
CString sModifiers = entries[i].modifiers;
|
||||
if( !pSong || !pNotes )
|
||||
continue; // this song entry isn't playable. Skip.
|
||||
|
||||
vSongsOut.push_back( pSong );
|
||||
vNotesOut.push_back( pNotes );
|
||||
vsModifiersOut.push_back( sModifiers );
|
||||
vsModifiersOut.push_back( e.modifiers );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,7 +373,7 @@ bool Course::GetFirstStageInfo(
|
||||
vector<Notes*> vNotes;
|
||||
vector<CString> vsModifiers;
|
||||
|
||||
GetCourseInfo(
|
||||
GetStageInfo(
|
||||
vSongs,
|
||||
vNotes,
|
||||
vsModifiers,
|
||||
@@ -326,8 +401,26 @@ RageColor Course::GetColor() const
|
||||
|
||||
bool Course::IsMysterySong( int stage ) const
|
||||
{
|
||||
CString sSongDir = m_entries[stage].songDir;
|
||||
return sSongDir.Right(1) == "*";
|
||||
switch( m_entries[stage].type )
|
||||
{
|
||||
case Entry::fixed: return false;
|
||||
case Entry::random: return true;
|
||||
case Entry::random_within_group: return true;
|
||||
case Entry::players_best: return false;
|
||||
case Entry::players_worst: return false;
|
||||
default: ASSERT(0); return true;
|
||||
}
|
||||
}
|
||||
|
||||
Difficulty Course::GetDifficulty( int stage ) const
|
||||
{
|
||||
return m_entries[stage].difficulty;
|
||||
}
|
||||
|
||||
void Course::GetMeterRange( int stage, int& iMeterLowOut, int& iMeterHighOut ) const
|
||||
{
|
||||
iMeterLowOut = m_entries[stage].low_meter;
|
||||
iMeterHighOut = m_entries[stage].high_meter;
|
||||
}
|
||||
|
||||
bool Course::ContainsAnyMysterySongs() const
|
||||
@@ -346,7 +439,7 @@ bool Course::GetTotalSeconds( float& fSecondsOut ) const
|
||||
vector<Song*> vSongsOut;
|
||||
vector<Notes*> vNotesOut;
|
||||
vector<CString> vsModifiersOut;
|
||||
GetCourseInfo(
|
||||
GetStageInfo(
|
||||
vSongsOut,
|
||||
vNotesOut,
|
||||
vsModifiersOut,
|
||||
@@ -380,9 +473,6 @@ struct RankingToInsert
|
||||
|
||||
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] )
|
||||
{
|
||||
m_MemCardScores[MEMORY_CARD_MACHINE][nt].iNumTimesPlayed++;
|
||||
|
||||
|
||||
vector<RankingToInsert> vHS;
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
@@ -395,6 +485,7 @@ void Course::AddScores( NotesType nt, bool bPlayerEnabled[NUM_PLAYERS], int iDan
|
||||
|
||||
// Update memory card
|
||||
m_MemCardScores[p][nt].iNumTimesPlayed++;
|
||||
m_MemCardScores[MEMORY_CARD_MACHINE][nt].iNumTimesPlayed++;
|
||||
|
||||
if( iDancePoints[p] > m_MemCardScores[p][nt].iDancePoints )
|
||||
{
|
||||
@@ -403,6 +494,12 @@ void Course::AddScores( NotesType nt, bool bPlayerEnabled[NUM_PLAYERS], int iDan
|
||||
bNewRecordOut[p] = true;
|
||||
}
|
||||
|
||||
if( iDancePoints[p] > m_MemCardScores[MEMORY_CARD_MACHINE][nt].iDancePoints )
|
||||
{
|
||||
m_MemCardScores[MEMORY_CARD_MACHINE][nt].iDancePoints = iDancePoints[p];
|
||||
m_MemCardScores[MEMORY_CARD_MACHINE][nt].fSurviveTime = fSurviveTime[p];
|
||||
}
|
||||
|
||||
|
||||
// Update Ranking
|
||||
RankingToInsert hs;
|
||||
@@ -425,13 +522,14 @@ void Course::AddScores( NotesType nt, bool bPlayerEnabled[NUM_PLAYERS], int iDan
|
||||
if( newHS.iDancePoints > rankingScores[i].iDancePoints )
|
||||
{
|
||||
// We found the insert point. Shift down.
|
||||
for( int j=i+1; j<NUM_RANKING_LINES; j++ )
|
||||
for( int j=NUM_RANKING_LINES-1; j>i; j-- )
|
||||
rankingScores[j] = rankingScores[j-1];
|
||||
// insert
|
||||
rankingScores[i].fSurviveTime = newHS.fSurviveTime;
|
||||
rankingScores[i].iDancePoints = newHS.iDancePoints;
|
||||
rankingScores[i].sName = DEFAULT_RANKING_NAME;
|
||||
iRankingIndexOut[newHS.pn] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+21
-12
@@ -20,19 +20,25 @@ struct Notes;
|
||||
|
||||
class Course
|
||||
{
|
||||
struct course_entry {
|
||||
course_entry( CString dir, Difficulty dc, CString mod )
|
||||
{
|
||||
songDir = dir;
|
||||
difficulty = dc;
|
||||
modifiers = mod;
|
||||
}
|
||||
struct Entry {
|
||||
enum Type { fixed, random, random_within_group, players_best, players_worst } type;
|
||||
CString group_name;
|
||||
CString song_name; // the name of the song folder
|
||||
Difficulty difficulty; // = DIFFICULTY_INVALID if no difficulty specified
|
||||
int low_meter; // = -1 if no meter range specified
|
||||
int high_meter; // = -1 if no meter range specified
|
||||
int players_index; // ignored if type isn't a players_*
|
||||
CString modifiers; // set player and song options using these
|
||||
|
||||
CString songDir;
|
||||
Difficulty difficulty; // the Notes description
|
||||
CString modifiers; // set player and song options from these
|
||||
Entry()
|
||||
{
|
||||
difficulty = DIFFICULTY_INVALID;
|
||||
low_meter = -1;
|
||||
high_meter = -1;
|
||||
players_index = -1;
|
||||
}
|
||||
};
|
||||
vector<course_entry> m_entries;
|
||||
vector<Entry> m_entries;
|
||||
|
||||
public:
|
||||
Course();
|
||||
@@ -50,7 +56,8 @@ public:
|
||||
|
||||
int GetEstimatedNumStages() const { return m_entries.size(); }
|
||||
bool HasDifficult() const;
|
||||
void GetCourseInfo( // Derefrences course_entries and returns only the playable Songs and Notes
|
||||
bool IsPlayableIn( NotesType nt ) const;
|
||||
void GetStageInfo( // Derefrences course_entries and returns only the playable Songs and Notes
|
||||
vector<Song*>& vSongsOut,
|
||||
vector<Notes*>& vNotesOut,
|
||||
vector<CString>& vsModifiersOut,
|
||||
@@ -63,6 +70,8 @@ public:
|
||||
NotesType nt ) const;
|
||||
RageColor GetColor() const;
|
||||
bool IsMysterySong( int stage ) const;
|
||||
Difficulty GetDifficulty( int stage ) const;
|
||||
void GetMeterRange( int stage, int& iMeterLowOut, int& iMeterHighOut ) const;
|
||||
bool ContainsAnyMysterySongs() const;
|
||||
bool GetTotalSeconds( float& fSecondsOut ) const;
|
||||
|
||||
|
||||
@@ -61,12 +61,13 @@ CourseContentDisplay::CourseContentDisplay()
|
||||
this->AddChild( &m_textDifficultyNumber );
|
||||
}
|
||||
|
||||
void CourseContentDisplay::Load( int iNum, Song* pSong, Notes* pNotes )
|
||||
|
||||
void CourseContentDisplay::LoadFromSongAndNotes( int iNum, Song* pSong, Notes* pNotes )
|
||||
{
|
||||
m_textNumber.SetText( ssprintf("%d", iNum) );
|
||||
|
||||
RageColor colorGroup = SONGMAN->GetSongColor( pSong );
|
||||
RageColor colorNotes = pNotes->GetColor();
|
||||
RageColor colorNotes = SONGMAN->GetDifficultyColor( pNotes->GetDifficulty() );
|
||||
|
||||
m_TextBanner.LoadFromSong( pSong );
|
||||
m_TextBanner.SetDiffuse( colorGroup );
|
||||
@@ -78,7 +79,39 @@ void CourseContentDisplay::Load( int iNum, Song* pSong, Notes* pNotes )
|
||||
m_textDifficultyNumber.SetDiffuse( colorNotes );
|
||||
}
|
||||
|
||||
void CourseContentDisplay::LoadFromDifficulty( int iNum, Difficulty dc )
|
||||
{
|
||||
m_textNumber.SetText( ssprintf("%d", iNum) );
|
||||
|
||||
RageColor colorGroup = RageColor(1,1,1,1); // TODO: What should this be?
|
||||
RageColor colorNotes = SONGMAN->GetDifficultyColor( dc );
|
||||
|
||||
m_TextBanner.LoadFromString( "??????????", "??????????", "", "", "", "" );
|
||||
m_TextBanner.SetDiffuse( colorGroup );
|
||||
|
||||
m_textFoot.SetText( "1" );
|
||||
m_textFoot.SetDiffuse( colorNotes );
|
||||
|
||||
m_textDifficultyNumber.SetText( "?" );
|
||||
m_textDifficultyNumber.SetDiffuse( colorNotes );
|
||||
}
|
||||
|
||||
void CourseContentDisplay::LoadFromMeterRange( int iNum, int iLow, int iHigh )
|
||||
{
|
||||
m_textNumber.SetText( ssprintf("%d", iNum) );
|
||||
|
||||
RageColor colorGroup = RageColor(1,1,1,1); // TODO: What should this be?
|
||||
RageColor colorNotes = RageColor(1,1,1,1);
|
||||
|
||||
m_TextBanner.LoadFromString( "??????????", "??????????", "", "", "", "" );
|
||||
m_TextBanner.SetDiffuse( colorGroup );
|
||||
|
||||
m_textFoot.SetText( "1" );
|
||||
m_textFoot.SetDiffuse( colorNotes );
|
||||
|
||||
m_textDifficultyNumber.SetText( ssprintf("%d-%d", iLow, iHigh) );
|
||||
m_textDifficultyNumber.SetDiffuse( colorNotes );
|
||||
}
|
||||
|
||||
CourseContentsFrame::CourseContentsFrame()
|
||||
{
|
||||
@@ -105,24 +138,38 @@ void CourseContentsFrame::SetFromCourse( Course* pCourse )
|
||||
vector<Song*> vSongs;
|
||||
vector<Notes*> vNotes;
|
||||
vector<CString> vsModifiers;
|
||||
pCourse->GetCourseInfo( vSongs, vNotes, vsModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType, false );
|
||||
pCourse->GetStageInfo( vSongs, vNotes, vsModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType, false );
|
||||
|
||||
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];
|
||||
CourseContentDisplay& display = m_CourseContentDisplays[m_iNumContents];
|
||||
|
||||
if( pCourse->IsMysterySong(i) )
|
||||
{
|
||||
Difficulty dc = pCourse->GetDifficulty(i);
|
||||
int iMeterLow, iMeterHigh;
|
||||
pCourse->GetMeterRange(i, iMeterLow, iMeterHigh);
|
||||
|
||||
LOG->Trace( "Adding song '%s'\n", pSong->m_sMainTitle.GetString() );
|
||||
m_CourseContentDisplays[m_iNumContents].Load( m_iNumContents+1, pSong, pNotes );
|
||||
m_CourseContentDisplays[m_iNumContents].SetXY( 0, -((MAX_VISIBLE_CONTENTS-1)/2) * float(ContentsBarHeight) );
|
||||
m_CourseContentDisplays[m_iNumContents].StopTweening();
|
||||
m_CourseContentDisplays[m_iNumContents].BeginTweening( m_iNumContents*0.1f );
|
||||
m_CourseContentDisplays[m_iNumContents].SetTweenY( (-(MAX_VISIBLE_CONTENTS-1)/2 + m_iNumContents) * float(ContentsBarHeight) );
|
||||
if( dc == DIFFICULTY_INVALID )
|
||||
display.LoadFromMeterRange( m_iNumContents+1, iMeterLow, iMeterHigh );
|
||||
else
|
||||
display.LoadFromDifficulty( m_iNumContents+1, pCourse->GetDifficulty(i) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Song* pSong = vSongs[i];
|
||||
Notes* pNotes = vNotes[i];
|
||||
CString sModifiers = vsModifiers[i];
|
||||
display.LoadFromSongAndNotes( m_iNumContents+1, pSong, pNotes );
|
||||
}
|
||||
|
||||
display.SetXY( 0, -((MAX_VISIBLE_CONTENTS-1)/2) * float(ContentsBarHeight) );
|
||||
display.StopTweening();
|
||||
display.BeginTweening( m_iNumContents*0.1f );
|
||||
display.SetTweenY( (-(MAX_VISIBLE_CONTENTS-1)/2 + m_iNumContents) * float(ContentsBarHeight) );
|
||||
|
||||
m_iNumContents ++;
|
||||
}
|
||||
LOG->Trace( "m_iNumContents is %d\n", m_iNumContents );
|
||||
}
|
||||
|
||||
void CourseContentsFrame::Update( float fDeltaTime )
|
||||
|
||||
@@ -31,7 +31,9 @@ class CourseContentDisplay : public ActorFrame
|
||||
public:
|
||||
CourseContentDisplay();
|
||||
|
||||
void Load( int iNum, Song* pSong, Notes* pNotes );
|
||||
void LoadFromSongAndNotes( int iNum, Song* pSong, Notes* pNotes );
|
||||
void LoadFromDifficulty( int iNum, Difficulty dc );
|
||||
void LoadFromMeterRange( int iNum, int iLow, int iHigh );
|
||||
|
||||
Sprite m_sprFrame;
|
||||
BitmapText m_textNumber;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "PrefsManager.h"
|
||||
#include "ThemeManager.h"
|
||||
#include "Notes.h"
|
||||
#include "SongManager.h"
|
||||
|
||||
|
||||
const int NUM_FEET_IN_METER = 10;
|
||||
@@ -40,7 +41,7 @@ void FootMeter::SetFromNotes( Notes* pNotes )
|
||||
else
|
||||
this->SetEffectNone();
|
||||
|
||||
SetDiffuse( pNotes->GetColor() );
|
||||
SetDiffuse( SONGMAN->GetDifficultyColor(pNotes->GetDifficulty()) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -95,8 +95,8 @@ void GameState::ResetLastRanking()
|
||||
{
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
m_LastRankingCategory[p] = (RankingCategory)-1;
|
||||
m_iLastRankingIndex[p] = -1;
|
||||
m_RankingCategory[p] = (RankingCategory)-1;
|
||||
m_iRankingIndex[p] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -126,10 +126,10 @@ public:
|
||||
|
||||
|
||||
// Filled in by ScreenNameEntry and used by ScreenRanking to flash the recent high scores
|
||||
NotesType m_LastRankingNotesType; // meaningless if a course was played
|
||||
RankingCategory m_LastRankingCategory[NUM_PLAYERS]; // meaningless if a course was played
|
||||
Course* m_pLastPlayedCourse; // meaningless if arcade was played
|
||||
int m_iLastRankingIndex[NUM_PLAYERS]; // -1 if no new high score
|
||||
NotesType m_RankingNotesType; // meaningless if a course was played
|
||||
RankingCategory m_RankingCategory[NUM_PLAYERS]; // meaningless if a course was played
|
||||
Course* m_pRankingCourse; // meaningless unless Course was played
|
||||
int m_iRankingIndex[NUM_PLAYERS]; // -1 if no new high score
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -447,10 +447,7 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
|
||||
Course* pCourse = apCourses[c];
|
||||
|
||||
// check that this course has at least one song playable in the current style
|
||||
Song* pSongs;
|
||||
Notes* pNotes;
|
||||
CString sModifiers;
|
||||
if( pCourse->GetFirstStageInfo(pSongs, pNotes, sModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType) )
|
||||
if( pCourse->IsPlayableIn(GAMESTATE->GetCurrentStyleDef()->m_NotesType) )
|
||||
arrayWheelItemDatas.push_back( WheelItemData(TYPE_COURSE, NULL, "", pCourse, pCourse->GetColor()) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,14 +23,8 @@
|
||||
#include "RageException.h"
|
||||
#include "MsdFile.h"
|
||||
#include "GameManager.h"
|
||||
#include "ThemeManager.h"
|
||||
|
||||
|
||||
#define COLOR_BEGINNER THEME->GetMetricC("Notes","ColorBeginner")
|
||||
#define COLOR_EASY THEME->GetMetricC("Notes","ColorEasy")
|
||||
#define COLOR_MEDIUM THEME->GetMetricC("Notes","ColorMedium")
|
||||
#define COLOR_HARD THEME->GetMetricC("Notes","ColorHard")
|
||||
#define COLOR_CHALLENGE THEME->GetMetricC("Notes","ColorChallenge")
|
||||
|
||||
Notes::Notes()
|
||||
{
|
||||
@@ -106,19 +100,6 @@ CString Notes::GetSMNoteData() const
|
||||
return *notes_comp;
|
||||
}
|
||||
|
||||
RageColor Notes::GetColor() const
|
||||
{
|
||||
switch( GetDifficulty() )
|
||||
{
|
||||
case DIFFICULTY_BEGINNER: return COLOR_BEGINNER;
|
||||
case DIFFICULTY_EASY: return COLOR_EASY;
|
||||
case DIFFICULTY_MEDIUM: return COLOR_MEDIUM;
|
||||
case DIFFICULTY_HARD: return COLOR_HARD;
|
||||
case DIFFICULTY_CHALLENGE: return COLOR_CHALLENGE;
|
||||
default: ASSERT(0); return COLOR_BEGINNER;
|
||||
}
|
||||
}
|
||||
|
||||
void Notes::TidyUpData()
|
||||
{
|
||||
if( GetDifficulty() == DIFFICULTY_INVALID )
|
||||
|
||||
@@ -45,7 +45,6 @@ public:
|
||||
void SetNoteData( NoteData* pNewNoteData );
|
||||
void SetSMNoteData( const CString &out );
|
||||
CString GetSMNoteData() const;
|
||||
RageColor GetColor() const; // a function of difficulty
|
||||
|
||||
// initializers
|
||||
void AutogenFrom( Notes *parent, NotesType ntTo );
|
||||
|
||||
@@ -247,25 +247,55 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
//
|
||||
// update persistent statistics
|
||||
//
|
||||
bool bIsPlayerEnabled[NUM_PLAYERS];
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
bIsPlayerEnabled[p] = GAMESTATE->IsPlayerEnabled(p);
|
||||
int iRankingLine[NUM_PLAYERS] = { -1, -1 };
|
||||
bool bNewRecord[NUM_PLAYERS] = { false, false };
|
||||
|
||||
|
||||
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] );
|
||||
{
|
||||
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:
|
||||
{
|
||||
NotesType nt = GAMESTATE->GetCurrentStyleDef()->m_NotesType;
|
||||
bool bIsPlayerEnabled[NUM_PLAYERS];
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
bIsPlayerEnabled[p] = GAMESTATE->IsPlayerEnabled(p);
|
||||
|
||||
RankingCategory cat[NUM_PLAYERS];
|
||||
int iRankingIndex[NUM_PLAYERS];
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
float fAverageMeter = stageStats.iMeter[p] / (float)PREFSMAN->m_iNumArcadeStages;
|
||||
cat[p] = AverageMeterToRankingCategory( fAverageMeter );
|
||||
}
|
||||
|
||||
SONGMAN->AddScores( nt, bIsPlayerEnabled, cat, stageStats.fScore, iRankingIndex );
|
||||
|
||||
COPY( GAMESTATE->m_RankingCategory, cat );
|
||||
COPY( GAMESTATE->m_iRankingIndex, iRankingIndex );
|
||||
GAMESTATE->m_RankingNotesType = nt;
|
||||
}
|
||||
break;
|
||||
case RM_COURSE:
|
||||
NotesType nt;
|
||||
nt = GAMESTATE->GetCurrentStyleDef()->m_NotesType;
|
||||
GAMESTATE->m_pCurCourse->AddScores( nt, bIsPlayerEnabled, stageStats.iActualDancePoints, stageStats.fAliveSeconds, iRankingLine, bNewRecord );
|
||||
{
|
||||
NotesType nt = GAMESTATE->GetCurrentStyleDef()->m_NotesType;
|
||||
bool bIsPlayerEnabled[NUM_PLAYERS];
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
bIsPlayerEnabled[p] = GAMESTATE->IsPlayerEnabled(p);
|
||||
|
||||
int iRankingIndex[NUM_PLAYERS];
|
||||
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
pCourse->AddScores( nt, bIsPlayerEnabled, stageStats.iActualDancePoints, stageStats.fAliveSeconds, iRankingIndex, bNewRecord );
|
||||
COPY( GAMESTATE->m_iRankingIndex, iRankingIndex );
|
||||
GAMESTATE->m_pRankingCourse = pCourse;
|
||||
GAMESTATE->m_RankingNotesType = nt;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
|
||||
@@ -141,7 +141,7 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
|
||||
case PLAY_MODE_ENDLESS:
|
||||
{
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
pCourse->GetCourseInfo( m_apCourseSongs, m_apCourseNotes, m_asCourseModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType, false );
|
||||
pCourse->GetStageInfo( m_apCourseSongs, m_apCourseNotes, m_asCourseModifiers, GAMESTATE->GetCurrentStyleDef()->m_NotesType, false );
|
||||
|
||||
int iTotalMeter = 0;
|
||||
int iTotalPossibleDancePoints = 0;
|
||||
|
||||
@@ -125,68 +125,6 @@ ScreenNameEntry::ScreenNameEntry()
|
||||
}
|
||||
|
||||
|
||||
// Find out if any of the players deserve to enter their name
|
||||
switch( GAMESTATE->m_PlayMode )
|
||||
{
|
||||
case PLAY_MODE_ARCADE:
|
||||
{
|
||||
StageStats stageStats;
|
||||
vector<Song*> vSongs;
|
||||
GAMESTATE->GetFinalEvalStatsAndSongs( stageStats, vSongs );
|
||||
|
||||
float fAverageMeter[NUM_PLAYERS];
|
||||
RankingCategory cat[NUM_PLAYERS];
|
||||
float fScore[NUM_PLAYERS];
|
||||
int iRankingIndex[NUM_PLAYERS];
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
fAverageMeter[p] = stageStats.iMeter[p] / (float)PREFSMAN->m_iNumArcadeStages;
|
||||
cat[p] = AverageMeterToRankingCategory( fAverageMeter[p] );
|
||||
fScore[p] = stageStats.fScore[p];
|
||||
}
|
||||
|
||||
NotesType nt = GAMESTATE->GetCurrentStyleDef()->m_NotesType;
|
||||
SONGMAN->AddMachineRecords( nt, cat, fScore, iRankingIndex );
|
||||
|
||||
GAMESTATE->m_LastRankingNotesType = nt;
|
||||
COPY( GAMESTATE->m_LastRankingCategory, cat );
|
||||
COPY( GAMESTATE->m_iLastRankingIndex, iRankingIndex );
|
||||
}
|
||||
break;
|
||||
case PLAY_MODE_NONSTOP:
|
||||
case PLAY_MODE_ONI:
|
||||
case PLAY_MODE_ENDLESS:
|
||||
{
|
||||
StageStats stageStats;
|
||||
vector<Song*> vSongs;
|
||||
GAMESTATE->GetFinalEvalStatsAndSongs( stageStats, vSongs );
|
||||
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
|
||||
bool bPlayerIsEnabled[NUM_PLAYERS];
|
||||
int iDancePoints[NUM_PLAYERS];
|
||||
float fAliveSeconds[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->AddScores( nt, bPlayerIsEnabled, iDancePoints, fAliveSeconds, iRankingIndex, bNewRecord );
|
||||
|
||||
GAMESTATE->m_LastRankingNotesType = nt;
|
||||
GAMESTATE->m_pLastPlayedCourse = pCourse;
|
||||
COPY( GAMESTATE->m_iLastRankingIndex, iRankingIndex );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
GAMESTATE->m_bPastHereWeGo = true; // enable the gray arrows
|
||||
|
||||
m_Background.LoadFromAniDir( THEME->GetPathTo("BGAnimations","name entry") );
|
||||
@@ -194,7 +132,8 @@ ScreenNameEntry::ScreenNameEntry()
|
||||
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
bool bNewHighScore = GAMESTATE->m_iLastRankingIndex[p] != -1;
|
||||
// Find out if player deserves to enter their name
|
||||
bool bNewHighScore = GAMESTATE->m_iRankingIndex[p] != -1;
|
||||
m_bStillEnteringName[p] = bNewHighScore; // false if they made a new high score
|
||||
for( int i=0; i<MAX_RANKING_NAME_LENGTH; i++ )
|
||||
m_sSelectedName[p] += ' ';
|
||||
@@ -235,16 +174,21 @@ ScreenNameEntry::ScreenNameEntry()
|
||||
m_textCategory[p].LoadFromFont( THEME->GetPathTo("Fonts","header2") );
|
||||
m_textCategory[p].SetX( (float)GAMESTATE->GetCurrentStyleDef()->m_iCenterX[p] );
|
||||
m_textCategory[p].SetY( CATEGORY_Y );
|
||||
CString sCategoryText = ssprintf("No. %d", GAMESTATE->m_iLastRankingIndex[p]+1);
|
||||
CString sCategoryText = ssprintf("No. %d", GAMESTATE->m_iRankingIndex[p]+1);
|
||||
switch( GAMESTATE->m_PlayMode )
|
||||
{
|
||||
case PLAY_MODE_ARCADE:
|
||||
sCategoryText += ssprintf(" in Type %c", 'A'+GAMESTATE->m_LastRankingCategory[p]);
|
||||
{
|
||||
StageStats SS;
|
||||
vector<Song*> vSongs;
|
||||
GAMESTATE->GetFinalEvalStatsAndSongs( SS, vSongs );
|
||||
sCategoryText += ssprintf(" in Type %c (%d)", 'A'+GAMESTATE->m_RankingCategory[p], SS.iMeter );
|
||||
}
|
||||
break;
|
||||
case PLAY_MODE_NONSTOP:
|
||||
case PLAY_MODE_ONI:
|
||||
case PLAY_MODE_ENDLESS:
|
||||
sCategoryText += ssprintf(" in %s", GAMESTATE->m_pCurCourse->m_sName.c_str());
|
||||
sCategoryText += ssprintf(" in \n%s", GAMESTATE->m_pCurCourse->m_sName.c_str());
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
@@ -419,12 +363,12 @@ void ScreenNameEntry::MenuStart( PlayerNumber pn )
|
||||
switch( GAMESTATE->m_PlayMode )
|
||||
{
|
||||
case PLAY_MODE_ARCADE:
|
||||
SONGMAN->m_MachineScores[GAMESTATE->m_LastRankingNotesType][GAMESTATE->m_LastRankingCategory[pn]][GAMESTATE->m_iLastRankingIndex[pn]].sName = m_sSelectedName[pn];
|
||||
SONGMAN->m_MachineScores[GAMESTATE->m_RankingNotesType][GAMESTATE->m_RankingCategory[pn]][GAMESTATE->m_iRankingIndex[pn]].sName = m_sSelectedName[pn];
|
||||
break;
|
||||
case PLAY_MODE_NONSTOP:
|
||||
case PLAY_MODE_ONI:
|
||||
case PLAY_MODE_ENDLESS:
|
||||
GAMESTATE->m_pLastPlayedCourse->m_RankingScores[GAMESTATE->m_LastRankingNotesType][GAMESTATE->m_iLastRankingIndex[pn]].sName = m_sSelectedName[pn];
|
||||
GAMESTATE->m_pRankingCourse->m_RankingScores[GAMESTATE->m_RankingNotesType][GAMESTATE->m_iRankingIndex[pn]].sName = m_sSelectedName[pn];
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
|
||||
@@ -211,9 +211,9 @@ void ScreenRanking::SetPage( PageToShow pts )
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
bRecentHighScore |=
|
||||
pts.nt == GAMESTATE->m_LastRankingNotesType &&
|
||||
GAMESTATE->m_LastRankingCategory[p] == pts.category &&
|
||||
GAMESTATE->m_iLastRankingIndex[p] == l;
|
||||
pts.nt == GAMESTATE->m_RankingNotesType &&
|
||||
GAMESTATE->m_RankingCategory[p] == pts.category &&
|
||||
GAMESTATE->m_iRankingIndex[p] == l;
|
||||
}
|
||||
|
||||
if( bRecentHighScore )
|
||||
@@ -248,9 +248,9 @@ void ScreenRanking::SetPage( PageToShow pts )
|
||||
m_textTime[l].SetDiffuse( TEXT_COLOR );
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( pts.pCourse == GAMESTATE->m_pLastPlayedCourse &&
|
||||
pts.nt == GAMESTATE->m_LastRankingNotesType &&
|
||||
GAMESTATE->m_iLastRankingIndex[p] == l )
|
||||
if( pts.pCourse == GAMESTATE->m_pRankingCourse &&
|
||||
pts.nt == GAMESTATE->m_RankingNotesType &&
|
||||
GAMESTATE->m_iRankingIndex[p] == l )
|
||||
{
|
||||
m_textNames[l].SetEffectBlinking();
|
||||
m_textScores[l].SetEffectBlinking();
|
||||
|
||||
+67
-11
@@ -376,7 +376,10 @@ bool Song::LoadFromSongDir( CString sDir )
|
||||
/* Add AutoGen pointers. (These aren't cached.) */
|
||||
AddAutoGenNotes();
|
||||
|
||||
return true;
|
||||
if( !HasMusic() )
|
||||
return false; // don't load this song
|
||||
else
|
||||
return true; // do load this song
|
||||
}
|
||||
|
||||
|
||||
@@ -627,22 +630,75 @@ void Song::ReCalculateRadarValuesAndLastBeat()
|
||||
}
|
||||
}
|
||||
|
||||
void Song::GetNotes( vector<Notes*>& arrayAddTo, NotesType nt, bool bIncludeAutoGen ) const
|
||||
void Song::GetNotes( vector<Notes*>& arrayAddTo, NotesType nt, Difficulty dc, int iMeterLow, int iMeterHigh, CString sDescription, bool bIncludeAutoGen ) const
|
||||
{
|
||||
for( unsigned i=0; i<m_apNotes.size(); i++ ) // for each of the Song's Notes
|
||||
if( m_apNotes[i]->m_NotesType == nt )
|
||||
if( bIncludeAutoGen || !m_apNotes[i]->IsAutogen() )
|
||||
arrayAddTo.push_back( m_apNotes[i] );
|
||||
if( dc==DIFFICULTY_INVALID || dc==m_apNotes[i]->GetDifficulty() )
|
||||
if( iMeterLow==-1 || iMeterLow>=m_apNotes[i]->GetMeter() )
|
||||
if( iMeterHigh==-1 || iMeterHigh<=m_apNotes[i]->GetMeter() )
|
||||
if( sDescription=="" || sDescription==m_apNotes[i]->GetDescription() )
|
||||
if( bIncludeAutoGen || !m_apNotes[i]->IsAutogen() )
|
||||
arrayAddTo.push_back( m_apNotes[i] );
|
||||
}
|
||||
|
||||
Notes* Song::GetNotes( NotesType nt, Difficulty dc, bool bIncludeAutoGen, CString sDescription ) const
|
||||
Notes* Song::GetNotes( NotesType nt, Difficulty dc ) 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() )
|
||||
if( sDescription.empty() || m_apNotes[i]->GetDescription()==sDescription )
|
||||
return m_apNotes[i];
|
||||
return NULL;
|
||||
vector<Notes*> vNotes;
|
||||
GetNotes( vNotes, nt, dc );
|
||||
if( vNotes.size() == 0 )
|
||||
return NULL;
|
||||
else
|
||||
return vNotes[0];
|
||||
}
|
||||
|
||||
Notes* Song::GetNotes( NotesType nt, int iMeterLow, int iMeterHigh ) const
|
||||
{
|
||||
vector<Notes*> vNotes;
|
||||
GetNotes( vNotes, nt, DIFFICULTY_INVALID, iMeterLow, iMeterHigh );
|
||||
if( vNotes.size() == 0 )
|
||||
return NULL;
|
||||
else
|
||||
return vNotes[0];
|
||||
}
|
||||
|
||||
Notes* Song::GetNotes( NotesType nt, CString sDescription ) const
|
||||
{
|
||||
vector<Notes*> vNotes;
|
||||
GetNotes( vNotes, nt, DIFFICULTY_INVALID, -1, -1, sDescription );
|
||||
if( vNotes.size() == 0 )
|
||||
return NULL;
|
||||
else
|
||||
return vNotes[0];
|
||||
}
|
||||
|
||||
|
||||
Notes* Song::GetClosestNotes( NotesType nt, Difficulty dc ) const
|
||||
{
|
||||
Difficulty newDC = dc;
|
||||
Notes* pNotes;
|
||||
pNotes = GetNotes( nt, newDC );
|
||||
if( pNotes )
|
||||
return pNotes;
|
||||
newDC = (Difficulty)(dc-1);
|
||||
CLAMP( (int&)newDC, 0, NUM_DIFFICULTIES-1 );
|
||||
pNotes = GetNotes( nt, newDC );
|
||||
if( pNotes )
|
||||
return pNotes;
|
||||
newDC = (Difficulty)(dc+1);
|
||||
CLAMP( (int&)newDC, 0, NUM_DIFFICULTIES-1 );
|
||||
pNotes = GetNotes( nt, newDC );
|
||||
if( pNotes )
|
||||
return pNotes;
|
||||
newDC = (Difficulty)(dc-2);
|
||||
CLAMP( (int&)newDC, 0, NUM_DIFFICULTIES-1 );
|
||||
pNotes = GetNotes( nt, newDC );
|
||||
if( pNotes )
|
||||
return pNotes;
|
||||
newDC = (Difficulty)(dc+2);
|
||||
CLAMP( (int&)newDC, 0, NUM_DIFFICULTIES-1 );
|
||||
pNotes = GetNotes( nt, newDC );
|
||||
return pNotes;
|
||||
}
|
||||
|
||||
void Song::GetEdits( vector<Notes*>& arrayAddTo, NotesType nt, bool bIncludeAutoGen ) const
|
||||
|
||||
@@ -40,6 +40,11 @@ const int COURSE_SCORES_VERSION = 1;
|
||||
|
||||
#define NUM_GROUP_COLORS THEME->GetMetricI("SongManager","NumGroupColors")
|
||||
#define GROUP_COLOR( i ) THEME->GetMetricC("SongManager",ssprintf("GroupColor%d",i+1))
|
||||
#define BEGINNER_COLOR THEME->GetMetricC("SongManager","BeginnerColor")
|
||||
#define EASY_COLOR THEME->GetMetricC("SongManager","EasyColor")
|
||||
#define MEDIUM_COLOR THEME->GetMetricC("SongManager","MediumColor")
|
||||
#define HARD_COLOR THEME->GetMetricC("SongManager","HardColor")
|
||||
#define CHALLENGE_COLOR THEME->GetMetricC("SongManager","ChallengeColor")
|
||||
#define EXTRA_COLOR THEME->GetMetricC("SongManager","ExtraColor")
|
||||
|
||||
vector<RageColor> g_vGroupColors;
|
||||
@@ -315,8 +320,13 @@ void SongManager::InitMachineScoresFromDisk()
|
||||
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 );
|
||||
fscanf(fp, "%d\n%d\n%[^\n]\n", &nt, &dc, szDescription);
|
||||
Notes* pNotes = NULL;
|
||||
if( pSong )
|
||||
if( dc==DIFFICULTY_INVALID )
|
||||
pNotes = pSong->GetNotes( nt, szDescription );
|
||||
else
|
||||
pNotes = pSong->GetNotes( nt, dc );
|
||||
|
||||
int iNumTimesPlayed;
|
||||
Grade grade;
|
||||
@@ -536,6 +546,19 @@ RageColor SongManager::GetSongColor( const Song* pSong )
|
||||
return GetGroupColor( pSong->m_sGroupName );
|
||||
}
|
||||
|
||||
RageColor SongManager::GetDifficultyColor( Difficulty dc )
|
||||
{
|
||||
switch( dc )
|
||||
{
|
||||
case DIFFICULTY_BEGINNER: return BEGINNER_COLOR;
|
||||
case DIFFICULTY_EASY: return EASY_COLOR;
|
||||
case DIFFICULTY_MEDIUM: return MEDIUM_COLOR;
|
||||
case DIFFICULTY_HARD: return HARD_COLOR;
|
||||
case DIFFICULTY_CHALLENGE: return CHALLENGE_COLOR;
|
||||
default: ASSERT(0); return CHALLENGE_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
void SongManager::GetSongs( vector<Song*> &AddTo, CString sGroupName, int iMaxStages ) const
|
||||
{
|
||||
AddTo.clear();
|
||||
@@ -650,29 +673,19 @@ void SongManager::CleanData()
|
||||
|
||||
void SongManager::GetNonstopCourses( vector<Course*> &AddTo )
|
||||
{
|
||||
PlayerOptions po;
|
||||
for( unsigned i=0; i<m_pCourses.size(); i++ )
|
||||
{
|
||||
if( m_pCourses[i]->m_bRepeat )
|
||||
continue; // skip
|
||||
if( m_pCourses[i]->m_iLives > 0 ) // use battery life meter
|
||||
continue;
|
||||
|
||||
AddTo.push_back( m_pCourses[i] );
|
||||
if( !m_pCourses[i]->m_bRepeat && m_pCourses[i]->m_iLives <= 0 ) // use bar life meter
|
||||
AddTo.push_back( m_pCourses[i] );
|
||||
}
|
||||
}
|
||||
|
||||
void SongManager::GetOniCourses( vector<Course*> &AddTo )
|
||||
{
|
||||
PlayerOptions po;
|
||||
for( unsigned i=0; i<m_pCourses.size(); i++ )
|
||||
{
|
||||
if( m_pCourses[i]->m_bRepeat )
|
||||
continue; // skip
|
||||
if( m_pCourses[i]->m_iLives <= 0 ) // use bar life meter
|
||||
continue;
|
||||
|
||||
AddTo.push_back( m_pCourses[i] );
|
||||
if( !m_pCourses[i]->m_bRepeat && m_pCourses[i]->m_iLives > 0 ) // use battery life meter
|
||||
AddTo.push_back( m_pCourses[i] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -834,24 +847,6 @@ 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] != '/' )
|
||||
@@ -907,14 +902,14 @@ struct CategoryScoreToInsert
|
||||
}
|
||||
};
|
||||
|
||||
void SongManager::AddMachineRecords( NotesType nt, RankingCategory hsc[NUM_PLAYERS], float fScore[NUM_PLAYERS], int iNewRecordIndexOut[NUM_PLAYERS] ) // set iNewRecordIndex = -1 if not a new record
|
||||
void SongManager::AddScores( NotesType nt, bool bPlayerEnabled[NUM_PLAYERS], RankingCategory hsc[NUM_PLAYERS], float fScore[NUM_PLAYERS], int iNewRecordIndexOut[NUM_PLAYERS] ) // set iNewRecordIndex = -1 if not a new record
|
||||
{
|
||||
vector<CategoryScoreToInsert> vHS;
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
iNewRecordIndexOut[p] = -1;
|
||||
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) )
|
||||
if( !bPlayerEnabled[p] )
|
||||
continue; // skip
|
||||
|
||||
CategoryScoreToInsert hs;
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
void GetGroupNames( CStringArray &AddTo );
|
||||
RageColor GetGroupColor( const CString &sGroupName );
|
||||
RageColor GetSongColor( const Song* pSong );
|
||||
RageColor GetDifficultyColor( Difficulty dc );
|
||||
|
||||
static CString ShortenGroupName( CString sLongGroupName );
|
||||
static int GetNumStagesForSong( const Song* pSong ); // LongVer songs take 2 stages, MarathonVer take 3
|
||||
@@ -60,8 +61,6 @@ public:
|
||||
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.
|
||||
@@ -93,7 +92,7 @@ public:
|
||||
float fScore;
|
||||
CString sName;
|
||||
} m_MachineScores[NUM_NOTES_TYPES][NUM_RANKING_CATEGORIES][NUM_RANKING_LINES];
|
||||
void AddMachineRecords( NotesType nt, RankingCategory hsc[NUM_PLAYERS], float fScore[NUM_PLAYERS], int iNewRecordIndexOut[NUM_PLAYERS] ); // set iNewRecordIndex = -1 if not a new record
|
||||
void AddScores( NotesType nt, bool bPlayerEnabled[NUM_PLAYERS], RankingCategory hsc[NUM_PLAYERS], float fScore[NUM_PLAYERS], int iNewRecordIndexOut[NUM_PLAYERS] ); // set iNewRecordIndex = -1 if not a new record
|
||||
|
||||
protected:
|
||||
void LoadStepManiaSongDir( CString sDir, LoadingWindow *ld );
|
||||
|
||||
@@ -89,20 +89,14 @@ TextBanner::TextBanner()
|
||||
}
|
||||
|
||||
|
||||
bool TextBanner::LoadFromSong( const Song* pSong )
|
||||
void TextBanner::LoadFromString(
|
||||
CString sDisplayTitle, CString sTranslitTitle,
|
||||
CString sDisplaySubTitle, CString sTranslitSubTitle,
|
||||
CString sDisplayArtist, CString sTranslitArtist )
|
||||
{
|
||||
if( pSong == NULL )
|
||||
{
|
||||
m_textTitle.SetText( "" );
|
||||
m_textSubTitle.SetText( "" );
|
||||
m_textArtist.SetText( "" );
|
||||
return true;
|
||||
}
|
||||
|
||||
m_textTitle.SetText( pSong->GetDisplayMainTitle(), pSong->GetTranslitMainTitle() );
|
||||
m_textSubTitle.SetText( pSong->GetDisplaySubTitle(), pSong->GetTranslitSubTitle() );
|
||||
m_textArtist.SetText( g_sArtistPrependString + pSong->GetDisplayArtist(),
|
||||
g_sArtistPrependString + pSong->GetTranslitArtist() );
|
||||
m_textTitle.SetText( sDisplayTitle, sTranslitTitle );
|
||||
m_textSubTitle.SetText( sDisplaySubTitle, sTranslitSubTitle );
|
||||
m_textArtist.SetText( sDisplayArtist, sTranslitArtist );
|
||||
|
||||
bool bTwoLines = m_textSubTitle.GetText().size() == 0;
|
||||
|
||||
@@ -129,7 +123,20 @@ bool TextBanner::LoadFromSong( const Song* pSong )
|
||||
m_textTitle.SetY( fTitleY );
|
||||
m_textSubTitle.SetY( fSubTitleY );
|
||||
m_textArtist.SetY( fArtistY );
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextBanner::LoadFromSong( const Song* pSong )
|
||||
{
|
||||
CString sDisplayTitle = pSong ? pSong->GetDisplayMainTitle() : "";
|
||||
CString sTranslitTitle = pSong ? pSong->GetTranslitMainTitle() : "";
|
||||
CString sDisplaySubTitle = pSong ? pSong->GetDisplaySubTitle() : "";
|
||||
CString sTranslitSubTitle = pSong ? pSong->GetTranslitSubTitle() : "";
|
||||
CString sDisplayArtist = pSong ? g_sArtistPrependString + pSong->GetDisplayArtist() : "";
|
||||
CString sTranslitArtist = pSong ? g_sArtistPrependString + pSong->GetTranslitArtist() : "";
|
||||
|
||||
LoadFromString(
|
||||
sDisplayTitle, sTranslitTitle,
|
||||
sDisplaySubTitle, sTranslitSubTitle,
|
||||
sDisplayArtist, sTranslitArtist );
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,14 @@ class TextBanner : public ActorFrame
|
||||
{
|
||||
public:
|
||||
TextBanner();
|
||||
bool LoadFromSong( const Song* pSong );
|
||||
void LoadFromSong( const Song* pSong );
|
||||
void LoadFromString(
|
||||
CString sDisplayTitle, CString sTranslitTitle,
|
||||
CString sDisplaySubTitle, CString sTranslitSubTitle,
|
||||
CString sDisplayArtist, CString sTranslitArtist );
|
||||
|
||||
private:
|
||||
|
||||
BitmapText m_textTitle, m_textSubTitle, m_textArtist;
|
||||
};
|
||||
|
||||
|
||||
@@ -205,8 +205,11 @@ public:
|
||||
bool SongCompleteForStyle( const StyleDef *st ) const;
|
||||
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, CString sDescription = "" ) const;
|
||||
void GetNotes( vector<Notes*>& arrayAddTo, NotesType nt, Difficulty dc = DIFFICULTY_INVALID, int iMeterLow = -1, int iMeterHigh = -1, CString sDescription = "", bool bIncludeAutoGen = true ) const;
|
||||
Notes* GetNotes( NotesType nt, Difficulty dc ) const;
|
||||
Notes* GetNotes( NotesType nt, int iMeterLow, int iMeterHigh ) const;
|
||||
Notes* GetNotes( NotesType nt, CString sDescription ) const;
|
||||
Notes* GetClosestNotes( NotesType nt, Difficulty dc ) 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