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 )
PROFILEMAN->UnloadProfile( pn );
SONGMAN->UpdateBest();
SONGMAN->UpdatePopular();
SONGMAN->UpdateShuffled();
/* 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();
STATSMAN->Reset();
+16 -10
View File
@@ -141,7 +141,7 @@ void MusicWheel::Load( RString sType )
GAMESTATE->m_PreferredSortOrder = GAMESTATE->m_SortOrder;
/* Update for SORT_MOST_PLAYED. */
SONGMAN->UpdateBest();
SONGMAN->UpdatePopular();
/* 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
@@ -351,17 +351,21 @@ bool MusicWheel::SelectModeMenuItem()
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;
// if( so==SORT_PREFERRED && GAMESTATE->m_sPreferredGroup!=GROUP_ALL)
// SONGMAN->GetSongs( apAllSongs, GAMESTATE->m_sPreferredGroup, GAMESTATE->GetNumStagesLeft() );
// else
// SONGMAN->GetSongs( apAllSongs, GAMESTATE->GetNumStagesLeft() );
if( so == SORT_POPULARITY )
SONGMAN->GetBestSongs( apAllSongs, GAMESTATE->m_sPreferredSongGroup, GAMESTATE->GetNumStagesLeft() );
else
SONGMAN->GetSongs( apAllSongs, GAMESTATE->m_sPreferredSongGroup, GAMESTATE->GetNumStagesLeft() );
switch( so )
{
case SORT_PREFERRED:
SONGMAN->GetPreferredSortSongs( apAllSongs, GAMESTATE->GetNumStagesLeft() );
break;
case SORT_POPULARITY:
SONGMAN->GetPopularSongs( apAllSongs, GAMESTATE->m_sPreferredSongGroup, GAMESTATE->GetNumStagesLeft() );
break;
default:
SONGMAN->GetSongs( apAllSongs, GAMESTATE->m_sPreferredSongGroup, GAMESTATE->GetNumStagesLeft() );
break;
}
// copy only songs that have at least one Steps for the current GameMode
for( unsigned i=0; i<apAllSongs.size(); i++ )
@@ -469,6 +473,8 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
switch( so )
{
case SORT_PREFERRED:
// obey order specified by the preferred sort list
break;
case SORT_ROULETTE:
SongUtil::SortSongPointerArrayByMeter( arraySongs, DIFFICULTY_EASY );
if( (bool)PREFSMAN->m_bPreferredSortUsesGroups )
+1 -1
View File
@@ -60,7 +60,7 @@ public:
protected:
virtual void LoadFromMetrics( RString sType );
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 );
bool SelectSongOrCourse();
bool SelectCourse( Course *p );
+2 -2
View File
@@ -1527,7 +1527,7 @@ void ScreenSelectMusic::AfterMusicChange()
g_sCDTitlePath = pSong->GetCDTitlePath();
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 );
if( index != -1 )
m_MachineRank.SetText( FormatNumberAndSuffix( index+1 ) );
@@ -1660,7 +1660,7 @@ void ScreenSelectMusic::AfterMusicChange()
}
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 );
if( 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 COURSES_DIR = "Courses/";
static const ThemeMetric<RageColor> EXTRA_COLOR ("SongManager","ExtraColor");
static const ThemeMetric<int> EXTRA_COLOR_METER ("SongManager","ExtraColorMeter");
static const ThemeMetric<bool> USE_UNLOCK_COLOR ("SongManager","UseUnlockColor");
static const ThemeMetric<RageColor> UNLOCK_COLOR ("SongManager","UnlockColor");
static const ThemeMetric<RageColor> EXTRA_COLOR ("SongManager","ExtraColor");
static const ThemeMetric<int> EXTRA_COLOR_METER ("SongManager","ExtraColorMeter");
static const ThemeMetric<bool> USE_PREFERRED_SORT_COLOR ("SongManager","UsePreferredSortColor");
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); }
@@ -71,6 +70,8 @@ void SongManager::InitAll( LoadingWindow *ld )
InitSongsFromDisk( ld );
InitCoursesFromDisk( ld );
InitAutogenCourses();
UpdatePreferredSort();
}
static LocalizedString RELOADING ( "SongManager", "Reloading..." );
@@ -123,7 +124,8 @@ void SongManager::AddGroup( RString sDir, RString sGroupDirName )
{
unsigned 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() )
return; /* the group is already added */
@@ -304,7 +306,7 @@ void SongManager::FreeSongs()
m_sSongGroupBannerPaths.clear();
for( int i = 0; i < NUM_ProfileSlot; ++i )
m_pBestSongs[i].clear();
m_pPopularSongs[i].clear();
m_pShuffledSongs.clear();
}
@@ -345,41 +347,59 @@ RageColor SongManager::GetSongColor( const Song* pSong )
{
ASSERT( pSong );
if( USE_UNLOCK_COLOR && UNLOCKMAN->FindSong(pSong) != NULL )
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++ )
if( USE_PREFERRED_SORT_COLOR )
{
const Steps* pSteps = vpSteps[i];
switch( pSteps->GetDifficulty() )
FOREACH_CONST( SongPointerVector, m_vPreferredSortGroups, v )
{
case DIFFICULTY_CHALLENGE:
case DIFFICULTY_EDIT:
continue;
FOREACH_CONST( Song*, *v, s )
{
if( *s == pSong )
{
int i = v - m_vPreferredSortGroups.begin();
return SONG_GROUP_COLOR.GetValue( i%NUM_SONG_GROUP_COLORS );
}
}
}
// if(pSteps->m_StepsType != st)
// continue;
if( pSteps->GetMeter() >= EXTRA_COLOR_METER )
return (RageColor)EXTRA_COLOR;
int i = m_vPreferredSortGroups.size();
return SONG_GROUP_COLOR.GetValue( i%NUM_SONG_GROUP_COLORS );
}
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 )
@@ -423,9 +443,6 @@ RageColor SongManager::GetCourseGroupColor( const RString &sCourseGroup )
RageColor SongManager::GetCourseColor( const Course* pCourse )
{
if( USE_UNLOCK_COLOR && UNLOCKMAN->FindCourse(pCourse) != NULL )
return UNLOCK_COLOR;
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 );
}
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
@@ -653,7 +683,7 @@ void SongManager::FreeCourses()
for( int i = 0; i < NUM_ProfileSlot; ++i )
FOREACH_CourseType( ct )
m_pBestCourses[i][ct].clear();
m_pPopularCourses[i][ct].clear();
m_pShuffledCourses.clear();
m_mapCourseGroupToInfo.clear();
@@ -662,7 +692,7 @@ void SongManager::FreeCourses()
void SongManager::AddCourse( Course *pCourse )
{
m_pCourses.push_back( pCourse );
UpdateBest();
UpdatePopular();
UpdateShuffled();
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 );
ASSERT( iter != m_pCourses.end() );
m_pCourses.erase( iter );
UpdateBest();
UpdatePopular();
UpdateShuffled();
RefreshCourseGroupInfo();
}
@@ -1212,7 +1242,7 @@ Course *SongManager::FindCourse( RString sName )
return NULL;
}
void SongManager::UpdateBest()
void SongManager::UpdatePopular()
{
// update players best
vector<Song*> apBestSongs = m_pSongs;
@@ -1245,13 +1275,13 @@ void SongManager::UpdateBest()
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 )
{
vector<Course*> &vpCourses = m_pBestCourses[i][ct];
vector<Course*> &vpCourses = m_pPopularCourses[i][ct];
vpCourses = apBestCourses[ct];
CourseUtil::SortCoursePointerArrayByNumPlays( vpCourses, i, true );
}
@@ -1268,6 +1298,46 @@ void SongManager::UpdateShuffled()
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()
{
SongUtil::SortSongPointerArrayByTitle( m_pSongs );
+14 -10
View File
@@ -74,9 +74,10 @@ public:
// Lookup
const vector<Song*> &GetAllSongs() const { return m_pSongs; }
void GetBestSongs( 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]; }
const vector<Course*> &GetBestCourses( CourseType ct, ProfileSlot slot=ProfileSlot_Machine ) const { return m_pBestCourses[slot][ct]; }
void GetPopularSongs( vector<Song*> &AddTo, RString sGroupName, int iMaxStages = INT_MAX, ProfileSlot slot=ProfileSlot_Machine ) const;
void GetPreferredSortSongs( vector<Song*> &AddTo, int iMaxStages = INT_MAX ) const;
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, int iMaxStages ) const { GetSongs(AddTo,GROUP_ALL,iMaxStages); }
void GetSongs( vector<Song*> &AddTo ) const { GetSongs(AddTo,GROUP_ALL,INT_MAX); }
@@ -106,9 +107,10 @@ public:
Course* GetCourseFromName( RString sName );
void UpdateBest(); // update Players Best
void UpdateShuffled(); // re-shuffle songs and courses
void SortSongs(); // sort m_pSongs
void UpdatePopular();
void UpdateShuffled(); // re-shuffle songs and courses
void UpdatePreferredSort();
void SortSongs(); // sort m_pSongs by CompareSongPointersByTitle
void UpdateRankingCourses(); // courses shown on the ranking screen
void RefreshCourseGroupInfo();
@@ -126,13 +128,15 @@ protected:
int GetNumEditsLoadedFromProfile( ProfileSlot slot ) const;
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
typedef vector<Song*> SongPointerVector;
vector<SongPointerVector> m_vPreferredSortGroups;
vector<RString> m_sSongGroupNames;
vector<RString> m_sSongGroupBannerPaths; // each song group may have a banner associated with it
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
struct CourseGroupInfo
{
@@ -142,9 +146,9 @@ protected:
RageTexturePreloader m_TexturePreload;
ThemeMetric<int> NUM_SONG_GROUP_COLORS;
ThemeMetric<int> NUM_SONG_GROUP_COLORS;
ThemeMetric1D<RageColor> SONG_GROUP_COLOR;
ThemeMetric<int> NUM_COURSE_GROUP_COLORS;
ThemeMetric<int> NUM_COURSE_GROUP_COLORS;
ThemeMetric1D<RageColor> COURSE_GROUP_COLOR;
};