Best -> Popular
populate SORT_PREFERRED from a txt file
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user