Best -> Popular

populate SORT_PREFERRED from a txt file
This commit is contained in:
Chris Danford
2006-03-20 01:04:46 +00:00
parent 020d3faaba
commit 64ea81fac1
6 changed files with 152 additions and 72 deletions
+2 -2
View File
@@ -220,11 +220,11 @@ void GameState::Reset()
FOREACH_PlayerNumber( pn ) FOREACH_PlayerNumber( pn )
PROFILEMAN->UnloadProfile( pn ); PROFILEMAN->UnloadProfile( pn );
SONGMAN->UpdateBest(); SONGMAN->UpdatePopular();
SONGMAN->UpdateShuffled(); SONGMAN->UpdateShuffled();
/* We may have cached trails from before everything was loaded (eg. from before /* We may have cached trails from before everything was loaded (eg. from before
* SongManager::UpdateBest could be called). Erase the cache. */ * SongManager::UpdatePopular could be called). Erase the cache. */
SONGMAN->RegenerateNonFixedCourses(); SONGMAN->RegenerateNonFixedCourses();
STATSMAN->Reset(); STATSMAN->Reset();
+15 -9
View File
@@ -141,7 +141,7 @@ void MusicWheel::Load( RString sType )
GAMESTATE->m_PreferredSortOrder = GAMESTATE->m_SortOrder; GAMESTATE->m_PreferredSortOrder = GAMESTATE->m_SortOrder;
/* Update for SORT_MOST_PLAYED. */ /* Update for SORT_MOST_PLAYED. */
SONGMAN->UpdateBest(); SONGMAN->UpdatePopular();
/* Sort SONGMAN's songs by CompareSongPointersByTitle, so we can do other sorts (with /* Sort SONGMAN's songs by CompareSongPointersByTitle, so we can do other sorts (with
* stable_sort) from its output, and title will be the secondary sort, without having * stable_sort) from its output, and title will be the secondary sort, without having
@@ -351,17 +351,21 @@ bool MusicWheel::SelectModeMenuItem()
return true; return true;
} }
void MusicWheel::GetSongList(vector<Song*> &arraySongs, SortOrder so, RString sPreferredGroup ) void MusicWheel::GetSongList(vector<Song*> &arraySongs, SortOrder so, const RString &sPreferredGroup )
{ {
vector<Song*> apAllSongs; vector<Song*> apAllSongs;
// if( so==SORT_PREFERRED && GAMESTATE->m_sPreferredGroup!=GROUP_ALL) switch( so )
// SONGMAN->GetSongs( apAllSongs, GAMESTATE->m_sPreferredGroup, GAMESTATE->GetNumStagesLeft() ); {
// else case SORT_PREFERRED:
// SONGMAN->GetSongs( apAllSongs, GAMESTATE->GetNumStagesLeft() ); SONGMAN->GetPreferredSortSongs( apAllSongs, GAMESTATE->GetNumStagesLeft() );
if( so == SORT_POPULARITY ) break;
SONGMAN->GetBestSongs( apAllSongs, GAMESTATE->m_sPreferredSongGroup, GAMESTATE->GetNumStagesLeft() ); case SORT_POPULARITY:
else SONGMAN->GetPopularSongs( apAllSongs, GAMESTATE->m_sPreferredSongGroup, GAMESTATE->GetNumStagesLeft() );
break;
default:
SONGMAN->GetSongs( apAllSongs, GAMESTATE->m_sPreferredSongGroup, GAMESTATE->GetNumStagesLeft() ); SONGMAN->GetSongs( apAllSongs, GAMESTATE->m_sPreferredSongGroup, GAMESTATE->GetNumStagesLeft() );
break;
}
// copy only songs that have at least one Steps for the current GameMode // copy only songs that have at least one Steps for the current GameMode
for( unsigned i=0; i<apAllSongs.size(); i++ ) for( unsigned i=0; i<apAllSongs.size(); i++ )
@@ -469,6 +473,8 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
switch( so ) switch( so )
{ {
case SORT_PREFERRED: case SORT_PREFERRED:
// obey order specified by the preferred sort list
break;
case SORT_ROULETTE: case SORT_ROULETTE:
SongUtil::SortSongPointerArrayByMeter( arraySongs, DIFFICULTY_EASY ); SongUtil::SortSongPointerArrayByMeter( arraySongs, DIFFICULTY_EASY );
if( (bool)PREFSMAN->m_bPreferredSortUsesGroups ) if( (bool)PREFSMAN->m_bPreferredSortUsesGroups )
+1 -1
View File
@@ -60,7 +60,7 @@ public:
protected: protected:
virtual void LoadFromMetrics( RString sType ); virtual void LoadFromMetrics( RString sType );
virtual bool MoveSpecific(int n); virtual bool MoveSpecific(int n);
void GetSongList(vector<Song*> &arraySongs, SortOrder so, RString sPreferredGroup ); void GetSongList(vector<Song*> &arraySongs, SortOrder so, const RString &sPreferredGroup );
void BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItems, SortOrder so ); void BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItems, SortOrder so );
bool SelectSongOrCourse(); bool SelectSongOrCourse();
bool SelectCourse( Course *p ); bool SelectCourse( Course *p );
+2 -2
View File
@@ -1527,7 +1527,7 @@ void ScreenSelectMusic::AfterMusicChange()
g_sCDTitlePath = pSong->GetCDTitlePath(); g_sCDTitlePath = pSong->GetCDTitlePath();
g_bWantFallbackCdTitle = true; g_bWantFallbackCdTitle = true;
const vector<Song*> best = SONGMAN->GetBestSongs( ProfileSlot_Machine ); const vector<Song*> best = SONGMAN->GetPopularSongs( ProfileSlot_Machine );
const int index = FindIndex( best.begin(), best.end(), pSong ); const int index = FindIndex( best.begin(), best.end(), pSong );
if( index != -1 ) if( index != -1 )
m_MachineRank.SetText( FormatNumberAndSuffix( index+1 ) ); m_MachineRank.SetText( FormatNumberAndSuffix( index+1 ) );
@@ -1660,7 +1660,7 @@ void ScreenSelectMusic::AfterMusicChange()
} }
CourseType ct = PlayModeToCourseType( GAMESTATE->m_PlayMode ); CourseType ct = PlayModeToCourseType( GAMESTATE->m_PlayMode );
const vector<Course*> best = SONGMAN->GetBestCourses( ct, ProfileSlot_Machine ); const vector<Course*> best = SONGMAN->GetPopularCourses( ct, ProfileSlot_Machine );
const int index = FindCourseIndexOfSameMode( best.begin(), best.end(), pCourse ); const int index = FindCourseIndexOfSameMode( best.begin(), best.end(), pCourse );
if( index != -1 ) if( index != -1 )
m_MachineRank.SetText( FormatNumberAndSuffix( index+1 ) ); m_MachineRank.SetText( FormatNumberAndSuffix( index+1 ) );
+117 -47
View File
@@ -41,10 +41,9 @@ SongManager* SONGMAN = NULL; // global and accessable from anywhere in our progr
const RString SONGS_DIR = "Songs/"; const RString SONGS_DIR = "Songs/";
const RString COURSES_DIR = "Courses/"; const RString COURSES_DIR = "Courses/";
static const ThemeMetric<RageColor> EXTRA_COLOR ("SongManager","ExtraColor"); static const ThemeMetric<RageColor> EXTRA_COLOR ("SongManager","ExtraColor");
static const ThemeMetric<int> EXTRA_COLOR_METER ("SongManager","ExtraColorMeter"); static const ThemeMetric<int> EXTRA_COLOR_METER ("SongManager","ExtraColorMeter");
static const ThemeMetric<bool> USE_UNLOCK_COLOR ("SongManager","UseUnlockColor"); static const ThemeMetric<bool> USE_PREFERRED_SORT_COLOR ("SongManager","UsePreferredSortColor");
static const ThemeMetric<RageColor> UNLOCK_COLOR ("SongManager","UnlockColor");
RString SONG_GROUP_COLOR_NAME( size_t i ) { return ssprintf("SongGroupColor%i",(int) i+1); } RString SONG_GROUP_COLOR_NAME( size_t i ) { return ssprintf("SongGroupColor%i",(int) i+1); }
RString COURSE_GROUP_COLOR_NAME( size_t i ) { return ssprintf("CourseGroupColor%i",(int) i+1); } RString COURSE_GROUP_COLOR_NAME( size_t i ) { return ssprintf("CourseGroupColor%i",(int) i+1); }
@@ -71,6 +70,8 @@ void SongManager::InitAll( LoadingWindow *ld )
InitSongsFromDisk( ld ); InitSongsFromDisk( ld );
InitCoursesFromDisk( ld ); InitCoursesFromDisk( ld );
InitAutogenCourses(); InitAutogenCourses();
UpdatePreferredSort();
} }
static LocalizedString RELOADING ( "SongManager", "Reloading..." ); static LocalizedString RELOADING ( "SongManager", "Reloading..." );
@@ -123,7 +124,8 @@ void SongManager::AddGroup( RString sDir, RString sGroupDirName )
{ {
unsigned j; unsigned j;
for(j = 0; j < m_sSongGroupNames.size(); ++j) for(j = 0; j < m_sSongGroupNames.size(); ++j)
if( sGroupDirName == m_sSongGroupNames[j] ) break; if( sGroupDirName == m_sSongGroupNames[j] )
break;
if( j != m_sSongGroupNames.size() ) if( j != m_sSongGroupNames.size() )
return; /* the group is already added */ return; /* the group is already added */
@@ -304,7 +306,7 @@ void SongManager::FreeSongs()
m_sSongGroupBannerPaths.clear(); m_sSongGroupBannerPaths.clear();
for( int i = 0; i < NUM_ProfileSlot; ++i ) for( int i = 0; i < NUM_ProfileSlot; ++i )
m_pBestSongs[i].clear(); m_pPopularSongs[i].clear();
m_pShuffledSongs.clear(); m_pShuffledSongs.clear();
} }
@@ -345,41 +347,59 @@ RageColor SongManager::GetSongColor( const Song* pSong )
{ {
ASSERT( pSong ); ASSERT( pSong );
if( USE_UNLOCK_COLOR && UNLOCKMAN->FindSong(pSong) != NULL ) if( USE_PREFERRED_SORT_COLOR )
return UNLOCK_COLOR;
/* XXX:
* Previously, this matched all notes, which set a song to "extra" if it
* had any 10-foot steps at all, even edits or doubles.
*
* For now, only look at notes for the current note type. This means that
* if a song has 10-foot steps on Doubles, it'll only show up red in Doubles.
* That's not too bad, I think. This will also change it in the song scroll,
* which is a little odd but harmless.
*
* XXX: Ack. This means this function can only be called when we have a style
* set up, which is too restrictive. How to handle this?
*/
// const StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
const vector<Steps*>& vpSteps = pSong->GetAllSteps();
for( unsigned i=0; i<vpSteps.size(); i++ )
{ {
const Steps* pSteps = vpSteps[i]; FOREACH_CONST( SongPointerVector, m_vPreferredSortGroups, v )
switch( pSteps->GetDifficulty() )
{ {
case DIFFICULTY_CHALLENGE: FOREACH_CONST( Song*, *v, s )
case DIFFICULTY_EDIT: {
continue; if( *s == pSong )
{
int i = v - m_vPreferredSortGroups.begin();
return SONG_GROUP_COLOR.GetValue( i%NUM_SONG_GROUP_COLORS );
}
}
} }
// if(pSteps->m_StepsType != st) int i = m_vPreferredSortGroups.size();
// continue; return SONG_GROUP_COLOR.GetValue( i%NUM_SONG_GROUP_COLORS );
if( pSteps->GetMeter() >= EXTRA_COLOR_METER )
return (RageColor)EXTRA_COLOR;
} }
else
{
return GetSongGroupColor( pSong->m_sGroupName ); /* XXX:
* Previously, this matched all notes, which set a song to "extra" if it
* had any 10-foot steps at all, even edits or doubles.
*
* For now, only look at notes for the current note type. This means that
* if a song has 10-foot steps on Doubles, it'll only show up red in Doubles.
* That's not too bad, I think. This will also change it in the song scroll,
* which is a little odd but harmless.
*
* XXX: Ack. This means this function can only be called when we have a style
* set up, which is too restrictive. How to handle this?
*/
// const StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
const vector<Steps*>& vpSteps = pSong->GetAllSteps();
for( unsigned i=0; i<vpSteps.size(); i++ )
{
const Steps* pSteps = vpSteps[i];
switch( pSteps->GetDifficulty() )
{
case DIFFICULTY_CHALLENGE:
case DIFFICULTY_EDIT:
continue;
}
// if(pSteps->m_StepsType != st)
// continue;
if( pSteps->GetMeter() >= EXTRA_COLOR_METER )
return (RageColor)EXTRA_COLOR;
}
return GetSongGroupColor( pSong->m_sGroupName );
}
} }
RString SongManager::GetCourseGroupBannerPath( const RString &sCourseGroup ) RString SongManager::GetCourseGroupBannerPath( const RString &sCourseGroup )
@@ -423,9 +443,6 @@ RageColor SongManager::GetCourseGroupColor( const RString &sCourseGroup )
RageColor SongManager::GetCourseColor( const Course* pCourse ) RageColor SongManager::GetCourseColor( const Course* pCourse )
{ {
if( USE_UNLOCK_COLOR && UNLOCKMAN->FindCourse(pCourse) != NULL )
return UNLOCK_COLOR;
return GetCourseGroupColor( pCourse->m_sGroupName ); return GetCourseGroupColor( pCourse->m_sGroupName );
} }
@@ -444,9 +461,22 @@ void SongManager::GetSongs( vector<Song*> &AddTo, RString sGroupName, int iMaxSt
GetSongsFromVector( m_pSongs, AddTo, sGroupName, iMaxStages ); GetSongsFromVector( m_pSongs, AddTo, sGroupName, iMaxStages );
} }
void SongManager::GetBestSongs( vector<Song*> &AddTo, RString sGroupName, int iMaxStages, ProfileSlot slot ) const void SongManager::GetPopularSongs( vector<Song*> &AddTo, RString sGroupName, int iMaxStages, ProfileSlot slot ) const
{ {
GetSongsFromVector( m_pBestSongs[slot], AddTo, sGroupName, iMaxStages ); GetSongsFromVector( m_pPopularSongs[slot], AddTo, sGroupName, iMaxStages );
}
void SongManager::GetPreferredSortSongs( vector<Song*> &AddTo, int iMaxStages ) const
{
if( m_vPreferredSortGroups.empty() )
{
GetSongs( AddTo, iMaxStages );
return;
}
FOREACH_CONST( SongPointerVector, m_vPreferredSortGroups, v )
FOREACH_CONST( Song*, *v, s )
AddTo.push_back( *s );
} }
int SongManager::GetNumSongs() const int SongManager::GetNumSongs() const
@@ -653,7 +683,7 @@ void SongManager::FreeCourses()
for( int i = 0; i < NUM_ProfileSlot; ++i ) for( int i = 0; i < NUM_ProfileSlot; ++i )
FOREACH_CourseType( ct ) FOREACH_CourseType( ct )
m_pBestCourses[i][ct].clear(); m_pPopularCourses[i][ct].clear();
m_pShuffledCourses.clear(); m_pShuffledCourses.clear();
m_mapCourseGroupToInfo.clear(); m_mapCourseGroupToInfo.clear();
@@ -662,7 +692,7 @@ void SongManager::FreeCourses()
void SongManager::AddCourse( Course *pCourse ) void SongManager::AddCourse( Course *pCourse )
{ {
m_pCourses.push_back( pCourse ); m_pCourses.push_back( pCourse );
UpdateBest(); UpdatePopular();
UpdateShuffled(); UpdateShuffled();
m_mapCourseGroupToInfo[ pCourse->m_sGroupName ]; // insert m_mapCourseGroupToInfo[ pCourse->m_sGroupName ]; // insert
} }
@@ -672,7 +702,7 @@ void SongManager::DeleteCourse( Course *pCourse )
vector<Course*>::iterator iter = find( m_pCourses.begin(), m_pCourses.end(), pCourse ); vector<Course*>::iterator iter = find( m_pCourses.begin(), m_pCourses.end(), pCourse );
ASSERT( iter != m_pCourses.end() ); ASSERT( iter != m_pCourses.end() );
m_pCourses.erase( iter ); m_pCourses.erase( iter );
UpdateBest(); UpdatePopular();
UpdateShuffled(); UpdateShuffled();
RefreshCourseGroupInfo(); RefreshCourseGroupInfo();
} }
@@ -1212,7 +1242,7 @@ Course *SongManager::FindCourse( RString sName )
return NULL; return NULL;
} }
void SongManager::UpdateBest() void SongManager::UpdatePopular()
{ {
// update players best // update players best
vector<Song*> apBestSongs = m_pSongs; vector<Song*> apBestSongs = m_pSongs;
@@ -1245,13 +1275,13 @@ void SongManager::UpdateBest()
FOREACH_ProfileSlot( i ) FOREACH_ProfileSlot( i )
{ {
m_pBestSongs[i] = apBestSongs; m_pPopularSongs[i] = apBestSongs;
SongUtil::SortSongPointerArrayByNumPlays( m_pBestSongs[i], i, true ); SongUtil::SortSongPointerArrayByNumPlays( m_pPopularSongs[i], i, true );
FOREACH_CourseType( ct ) FOREACH_CourseType( ct )
{ {
vector<Course*> &vpCourses = m_pBestCourses[i][ct]; vector<Course*> &vpCourses = m_pPopularCourses[i][ct];
vpCourses = apBestCourses[ct]; vpCourses = apBestCourses[ct];
CourseUtil::SortCoursePointerArrayByNumPlays( vpCourses, i, true ); CourseUtil::SortCoursePointerArrayByNumPlays( vpCourses, i, true );
} }
@@ -1268,6 +1298,46 @@ void SongManager::UpdateShuffled()
random_shuffle( m_pShuffledCourses.begin(), m_pShuffledCourses.end() ); random_shuffle( m_pShuffledCourses.begin(), m_pShuffledCourses.end() );
} }
void SongManager::UpdatePreferredSort()
{
m_vPreferredSortGroups.clear();
RString sFile = THEME->GetPathO( "SongManager", "PreferredSort.txt" );
RageFile file;
if( file.Open( sFile ) )
{
vector<Song*> vpSongs;
RString sLine;
while( file.GetLine(sLine) )
{
bool bSectionDivider = sLine.find("---") != -1;
if( bSectionDivider )
{
if( !vpSongs.empty() )
{
m_vPreferredSortGroups.push_back( vpSongs );
vpSongs.clear();
}
}
else
{
Song *pSong = NULL;
if( !sLine.empty() )
pSong = FindSong( sLine );
if( pSong )
vpSongs.push_back( pSong );
}
}
if( !vpSongs.empty() )
{
m_vPreferredSortGroups.push_back( vpSongs );
vpSongs.clear();
}
}
}
void SongManager::SortSongs() void SongManager::SortSongs()
{ {
SongUtil::SortSongPointerArrayByTitle( m_pSongs ); SongUtil::SortSongPointerArrayByTitle( m_pSongs );
+14 -10
View File
@@ -74,9 +74,10 @@ public:
// Lookup // Lookup
const vector<Song*> &GetAllSongs() const { return m_pSongs; } const vector<Song*> &GetAllSongs() const { return m_pSongs; }
void GetBestSongs( vector<Song*> &AddTo, RString sGroupName, int iMaxStages = INT_MAX, ProfileSlot slot=ProfileSlot_Machine ) const; void GetPopularSongs( vector<Song*> &AddTo, RString sGroupName, int iMaxStages = INT_MAX, ProfileSlot slot=ProfileSlot_Machine ) const;
const vector<Song*> &GetBestSongs( ProfileSlot slot=ProfileSlot_Machine ) const { return m_pBestSongs[slot]; } void GetPreferredSortSongs( vector<Song*> &AddTo, int iMaxStages = INT_MAX ) const;
const vector<Course*> &GetBestCourses( CourseType ct, ProfileSlot slot=ProfileSlot_Machine ) const { return m_pBestCourses[slot][ct]; } const vector<Song*> &GetPopularSongs( ProfileSlot slot=ProfileSlot_Machine ) const { return m_pPopularSongs[slot]; }
const vector<Course*> &GetPopularCourses( CourseType ct, ProfileSlot slot=ProfileSlot_Machine ) const { return m_pPopularCourses[slot][ct]; }
void GetSongs( vector<Song*> &AddTo, RString sGroupName, int iMaxStages = INT_MAX ) const; void GetSongs( vector<Song*> &AddTo, RString sGroupName, int iMaxStages = INT_MAX ) const;
void GetSongs( vector<Song*> &AddTo, int iMaxStages ) const { GetSongs(AddTo,GROUP_ALL,iMaxStages); } void GetSongs( vector<Song*> &AddTo, int iMaxStages ) const { GetSongs(AddTo,GROUP_ALL,iMaxStages); }
void GetSongs( vector<Song*> &AddTo ) const { GetSongs(AddTo,GROUP_ALL,INT_MAX); } void GetSongs( vector<Song*> &AddTo ) const { GetSongs(AddTo,GROUP_ALL,INT_MAX); }
@@ -106,9 +107,10 @@ public:
Course* GetCourseFromName( RString sName ); Course* GetCourseFromName( RString sName );
void UpdateBest(); // update Players Best void UpdatePopular();
void UpdateShuffled(); // re-shuffle songs and courses void UpdateShuffled(); // re-shuffle songs and courses
void SortSongs(); // sort m_pSongs void UpdatePreferredSort();
void SortSongs(); // sort m_pSongs by CompareSongPointersByTitle
void UpdateRankingCourses(); // courses shown on the ranking screen void UpdateRankingCourses(); // courses shown on the ranking screen
void RefreshCourseGroupInfo(); void RefreshCourseGroupInfo();
@@ -126,13 +128,15 @@ protected:
int GetNumEditsLoadedFromProfile( ProfileSlot slot ) const; int GetNumEditsLoadedFromProfile( ProfileSlot slot ) const;
vector<Song*> m_pSongs; // all songs that can be played vector<Song*> m_pSongs; // all songs that can be played
vector<Song*> m_pBestSongs[NUM_ProfileSlot]; vector<Song*> m_pPopularSongs[NUM_ProfileSlot];
vector<Song*> m_pShuffledSongs; // used by GetRandomSong vector<Song*> m_pShuffledSongs; // used by GetRandomSong
typedef vector<Song*> SongPointerVector;
vector<SongPointerVector> m_vPreferredSortGroups;
vector<RString> m_sSongGroupNames; vector<RString> m_sSongGroupNames;
vector<RString> m_sSongGroupBannerPaths; // each song group may have a banner associated with it vector<RString> m_sSongGroupBannerPaths; // each song group may have a banner associated with it
vector<Course*> m_pCourses; vector<Course*> m_pCourses;
vector<Course*> m_pBestCourses[NUM_ProfileSlot][NUM_CourseType]; vector<Course*> m_pPopularCourses[NUM_ProfileSlot][NUM_CourseType];
vector<Course*> m_pShuffledCourses; // used by GetRandomCourse vector<Course*> m_pShuffledCourses; // used by GetRandomCourse
struct CourseGroupInfo struct CourseGroupInfo
{ {
@@ -142,9 +146,9 @@ protected:
RageTexturePreloader m_TexturePreload; RageTexturePreloader m_TexturePreload;
ThemeMetric<int> NUM_SONG_GROUP_COLORS; ThemeMetric<int> NUM_SONG_GROUP_COLORS;
ThemeMetric1D<RageColor> SONG_GROUP_COLOR; ThemeMetric1D<RageColor> SONG_GROUP_COLOR;
ThemeMetric<int> NUM_COURSE_GROUP_COLORS; ThemeMetric<int> NUM_COURSE_GROUP_COLORS;
ThemeMetric1D<RageColor> COURSE_GROUP_COLOR; ThemeMetric1D<RageColor> COURSE_GROUP_COLOR;
}; };