add courses preferred sort
This commit is contained in:
@@ -884,6 +884,27 @@ void Course::CalculateRadarValues()
|
||||
}
|
||||
}
|
||||
|
||||
bool Course::Matches( RString sGroup, RString sCourse ) const
|
||||
{
|
||||
if( sGroup.size() && sGroup.CompareNoCase(this->m_sGroupName) != 0)
|
||||
return false;
|
||||
|
||||
RString sFile = m_sPath;
|
||||
sFile.Replace("\\","/");
|
||||
vector<RString> bits;
|
||||
split( sFile, "/", bits );
|
||||
ASSERT(bits.size() >= 2); /* should always have at least two parts */
|
||||
const RString &sLastBit = bits[bits.size()-1];
|
||||
|
||||
if( sCourse.EqualsNoCase(sLastBit) )
|
||||
return true;
|
||||
if( sCourse.EqualsNoCase(this->GetTranslitFullTitle()) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// lua start
|
||||
#include "LuaBinding.h"
|
||||
|
||||
|
||||
@@ -186,6 +186,8 @@ public:
|
||||
ProfileSlot GetLoadedFromProfileSlot() const { return m_LoadedFromProfile; }
|
||||
void SetLoadedFromProfile( ProfileSlot slot ) { m_LoadedFromProfile = slot; }
|
||||
|
||||
bool Matches(RString sGroup, RString sCourse) const;
|
||||
|
||||
// Lua
|
||||
void PushSelf( lua_State *L );
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ void GameCommand::LoadOne( const Command& cmd )
|
||||
|
||||
else if( sName == "course" )
|
||||
{
|
||||
m_pCourse = SONGMAN->FindCourse( sValue );
|
||||
m_pCourse = SONGMAN->FindCourse( "", sValue );
|
||||
if( m_pCourse == NULL )
|
||||
{
|
||||
m_sInvalidReason = ssprintf( "Course \"%s\" not found", sValue.c_str() );
|
||||
|
||||
@@ -624,14 +624,14 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
|
||||
switch( so )
|
||||
{
|
||||
case SORT_NONSTOP_COURSES:
|
||||
SONGMAN->GetCourses( COURSE_TYPE_NONSTOP, apCourses, PREFSMAN->m_bAutogenGroupCourses );
|
||||
SONGMAN->GetPreferredSortCourses( COURSE_TYPE_NONSTOP, apCourses, PREFSMAN->m_bAutogenGroupCourses );
|
||||
break;
|
||||
case SORT_ONI_COURSES:
|
||||
SONGMAN->GetCourses( COURSE_TYPE_ONI, apCourses, PREFSMAN->m_bAutogenGroupCourses );
|
||||
SONGMAN->GetCourses( COURSE_TYPE_SURVIVAL, apCourses, PREFSMAN->m_bAutogenGroupCourses );
|
||||
SONGMAN->GetPreferredSortCourses( COURSE_TYPE_ONI, apCourses, PREFSMAN->m_bAutogenGroupCourses );
|
||||
SONGMAN->GetPreferredSortCourses( COURSE_TYPE_SURVIVAL, apCourses, PREFSMAN->m_bAutogenGroupCourses );
|
||||
break;
|
||||
case SORT_ENDLESS_COURSES:
|
||||
SONGMAN->GetCourses( COURSE_TYPE_ENDLESS, apCourses, PREFSMAN->m_bAutogenGroupCourses );
|
||||
SONGMAN->GetPreferredSortCourses( COURSE_TYPE_ENDLESS, apCourses, PREFSMAN->m_bAutogenGroupCourses );
|
||||
break;
|
||||
case SORT_ALL_COURSES:
|
||||
SONGMAN->GetAllCourses( apCourses, PREFSMAN->m_bAutogenGroupCourses );
|
||||
@@ -647,6 +647,8 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
|
||||
{
|
||||
switch( PREFSMAN->m_CourseSortOrder )
|
||||
{
|
||||
case PrefsManager::COURSE_SOFT_PREFERRED:
|
||||
break;
|
||||
case PrefsManager::COURSE_SORT_METER:
|
||||
CourseUtil::SortCoursePointerArrayByAvgDifficulty( apCourses );
|
||||
break;
|
||||
@@ -684,7 +686,7 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
|
||||
{
|
||||
switch( pCourse->GetPlayMode() )
|
||||
{
|
||||
case PLAY_MODE_ONI: sThisSection = "Oni"; break;
|
||||
case PLAY_MODE_ONI: sThisSection = "Oni"; break;
|
||||
case PLAY_MODE_NONSTOP: sThisSection = "Nonstop"; break;
|
||||
case PLAY_MODE_ENDLESS: sThisSection = "Endless"; break;
|
||||
}
|
||||
@@ -702,7 +704,7 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
|
||||
sLastSection = sThisSection;
|
||||
}
|
||||
|
||||
RageColor c = ( pCourse->m_sGroupName.size() == 0 ) ? pCourse->GetColor() : pCourse->GetColor() * SONGMAN->GetCourseColor(pCourse);
|
||||
RageColor c = ( pCourse->m_sGroupName.size() == 0 ) ? pCourse->GetColor() : SONGMAN->GetCourseColor(pCourse);
|
||||
arrayWheelItemDatas.push_back( WheelItemData(TYPE_COURSE, NULL, sThisSection, pCourse, c) );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -190,7 +190,7 @@ public:
|
||||
Preference<bool> m_bSignProfileData;
|
||||
|
||||
// course ranking
|
||||
enum CourseSortOrders { COURSE_SORT_SONGS, COURSE_SORT_METER, COURSE_SORT_METER_SUM, COURSE_SORT_RANK };
|
||||
enum CourseSortOrders { COURSE_SOFT_PREFERRED, COURSE_SORT_SONGS, COURSE_SORT_METER, COURSE_SORT_METER_SUM, COURSE_SORT_RANK };
|
||||
Preference<CourseSortOrders,int> m_CourseSortOrder;
|
||||
Preference<bool> m_bSubSortByNumSteps;
|
||||
enum GetRankingName { RANKING_OFF, RANKING_ON, RANKING_LIST };
|
||||
|
||||
+175
-58
@@ -355,19 +355,19 @@ RageColor SongManager::GetSongColor( const Song* pSong )
|
||||
|
||||
if( USE_PREFERRED_SORT_COLOR )
|
||||
{
|
||||
FOREACH_CONST( SongPointerVector, m_vPreferredSortGroups, v )
|
||||
FOREACH_CONST( SongPointerVector, m_vPreferredSongSort, v )
|
||||
{
|
||||
FOREACH_CONST( Song*, *v, s )
|
||||
{
|
||||
if( *s == pSong )
|
||||
{
|
||||
int i = v - m_vPreferredSortGroups.begin();
|
||||
int i = v - m_vPreferredSongSort.begin();
|
||||
return SONG_GROUP_COLOR.GetValue( i%NUM_SONG_GROUP_COLORS );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int i = m_vPreferredSortGroups.size();
|
||||
int i = m_vPreferredSongSort.size();
|
||||
return SONG_GROUP_COLOR.GetValue( i%NUM_SONG_GROUP_COLORS );
|
||||
}
|
||||
else
|
||||
@@ -449,7 +449,33 @@ RageColor SongManager::GetCourseGroupColor( const RString &sCourseGroup )
|
||||
|
||||
RageColor SongManager::GetCourseColor( const Course* pCourse )
|
||||
{
|
||||
return GetCourseGroupColor( pCourse->m_sGroupName );
|
||||
// Use unlock color if applicable
|
||||
const UnlockEntry *pUE = UNLOCKMAN->FindCourse( pCourse );
|
||||
if( pUE )
|
||||
return UNLOCK_COLOR;
|
||||
|
||||
|
||||
if( USE_PREFERRED_SORT_COLOR )
|
||||
{
|
||||
FOREACH_CONST( CoursePointerVector, m_vPreferredCourseSort, v )
|
||||
{
|
||||
FOREACH_CONST( Course*, *v, s )
|
||||
{
|
||||
if( *s == pCourse )
|
||||
{
|
||||
int i = v - m_vPreferredCourseSort.begin();
|
||||
return COURSE_GROUP_COLOR.GetValue( i%NUM_COURSE_GROUP_COLORS );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int i = m_vPreferredCourseSort.size();
|
||||
return COURSE_GROUP_COLOR.GetValue( i%NUM_COURSE_GROUP_COLORS );
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetCourseGroupColor( pCourse->m_sGroupName );
|
||||
}
|
||||
}
|
||||
|
||||
static void GetSongsFromVector( const vector<Song*> &Songs, vector<Song*> &AddTo, RString sGroupName, int iMaxStages )
|
||||
@@ -474,17 +500,31 @@ void SongManager::GetPopularSongs( vector<Song*> &AddTo, RString sGroupName, int
|
||||
|
||||
void SongManager::GetPreferredSortSongs( vector<Song*> &AddTo, int iMaxStages ) const
|
||||
{
|
||||
if( m_vPreferredSortGroups.empty() )
|
||||
if( m_vPreferredSongSort.empty() )
|
||||
{
|
||||
GetSongs( AddTo, iMaxStages );
|
||||
return;
|
||||
}
|
||||
|
||||
FOREACH_CONST( SongPointerVector, m_vPreferredSortGroups, v )
|
||||
FOREACH_CONST( SongPointerVector, m_vPreferredSongSort, v )
|
||||
FOREACH_CONST( Song*, *v, s )
|
||||
AddTo.push_back( *s );
|
||||
}
|
||||
|
||||
void SongManager::GetPreferredSortCourses( CourseType ct, vector<Course*> &AddTo, bool bIncludeAutogen ) const
|
||||
{
|
||||
if( m_vPreferredCourseSort.empty() )
|
||||
{
|
||||
GetCourses( ct, AddTo, bIncludeAutogen );
|
||||
return;
|
||||
}
|
||||
|
||||
FOREACH_CONST( CoursePointerVector, m_vPreferredCourseSort, v )
|
||||
FOREACH_CONST( Course*, *v, c )
|
||||
if( (*c)->GetCourseType() == ct )
|
||||
AddTo.push_back( *c );
|
||||
}
|
||||
|
||||
int SongManager::GetNumSongs() const
|
||||
{
|
||||
return m_pSongs.size();
|
||||
@@ -957,7 +997,7 @@ void SongManager::GetAllCourses( vector<Course*> &AddTo, bool bIncludeAutogen )
|
||||
AddTo.push_back( m_pCourses[i] );
|
||||
}
|
||||
|
||||
void SongManager::GetCourses( CourseType ct, vector<Course*> &AddTo, bool bIncludeAutogen )
|
||||
void SongManager::GetCourses( CourseType ct, vector<Course*> &AddTo, bool bIncludeAutogen ) const
|
||||
{
|
||||
for( unsigned i=0; i<m_pCourses.size(); i++ )
|
||||
if( m_pCourses[i]->GetCourseType() == ct )
|
||||
@@ -1234,21 +1274,35 @@ Song *SongManager::FindSong( RString sPath )
|
||||
Song *SongManager::FindSong( RString sGroup, RString sSong )
|
||||
{
|
||||
// foreach song
|
||||
for( unsigned i = 0; i < m_pSongs.size(); i++ )
|
||||
FOREACH_CONST( Song*, m_pSongs, s )
|
||||
{
|
||||
if( m_pSongs[i]->Matches(sGroup, sSong) )
|
||||
return m_pSongs[i];
|
||||
if( (*s)->Matches(sGroup, sSong) )
|
||||
return *s;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Course *SongManager::FindCourse( RString sName )
|
||||
Course *SongManager::FindCourse( RString sPath )
|
||||
{
|
||||
for( unsigned i = 0; i < m_pCourses.size(); i++ )
|
||||
sPath.Replace( '\\', '/' );
|
||||
vector<RString> bits;
|
||||
split( sPath, "/", bits );
|
||||
|
||||
if( bits.size() == 1 )
|
||||
return FindCourse( "", bits[0] );
|
||||
else if( bits.size() == 2 )
|
||||
return FindCourse( bits[0], bits[1] );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Course *SongManager::FindCourse( RString sGroup, RString sName )
|
||||
{
|
||||
FOREACH_CONST( Course*, m_pCourses, c )
|
||||
{
|
||||
if( !sName.CompareNoCase(m_pCourses[i]->GetDisplayFullTitle()) )
|
||||
return m_pCourses[i];
|
||||
if( (*c)->Matches(sGroup, sName) )
|
||||
return *c;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1314,64 +1368,127 @@ void SongManager::UpdatePreferredSort()
|
||||
{
|
||||
ASSERT( UNLOCKMAN );
|
||||
|
||||
m_vPreferredSortGroups.clear();
|
||||
|
||||
RString sFile = THEME->GetPathO( "SongManager", "PreferredSort.txt" );
|
||||
RageFile file;
|
||||
if( !file.Open( sFile ) )
|
||||
return;
|
||||
|
||||
vector<Song*> vpSongs;
|
||||
|
||||
RString sLine;
|
||||
while( file.GetLine(sLine) )
|
||||
{
|
||||
bool bSectionDivider = sLine.find("---") != RString::npos;
|
||||
if( bSectionDivider )
|
||||
m_vPreferredSongSort.clear();
|
||||
|
||||
RString sFile = THEME->GetPathO( "SongManager", "PreferredSongs.txt" );
|
||||
RageFile file;
|
||||
if( !file.Open( sFile ) )
|
||||
return;
|
||||
|
||||
vector<Song*> vpSongs;
|
||||
|
||||
RString sLine;
|
||||
while( file.GetLine(sLine) )
|
||||
{
|
||||
if( !vpSongs.empty() )
|
||||
bool bSectionDivider = sLine.find("---") != RString::npos;
|
||||
if( bSectionDivider )
|
||||
{
|
||||
m_vPreferredSortGroups.push_back( vpSongs );
|
||||
vpSongs.clear();
|
||||
if( !vpSongs.empty() )
|
||||
{
|
||||
m_vPreferredSongSort.push_back( vpSongs );
|
||||
vpSongs.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Song *pSong = NULL;
|
||||
if( !sLine.empty() )
|
||||
pSong = FindSong( sLine );
|
||||
if( pSong )
|
||||
vpSongs.push_back( pSong );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if( !vpSongs.empty() )
|
||||
{
|
||||
Song *pSong = NULL;
|
||||
if( !sLine.empty() )
|
||||
pSong = FindSong( sLine );
|
||||
if( pSong )
|
||||
vpSongs.push_back( pSong );
|
||||
m_vPreferredSongSort.push_back( vpSongs );
|
||||
vpSongs.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if( !vpSongs.empty() )
|
||||
{
|
||||
m_vPreferredSortGroups.push_back( vpSongs );
|
||||
vpSongs.clear();
|
||||
}
|
||||
|
||||
// move all unlock songs to a group at the bottom
|
||||
vector<Song*> vpUnlockSongs;
|
||||
FOREACH( UnlockEntry, UNLOCKMAN->m_UnlockEntries, ue )
|
||||
{
|
||||
if( ue->m_Type == UnlockRewardType_Song )
|
||||
vpUnlockSongs.push_back( ue->m_pSong );
|
||||
}
|
||||
|
||||
FOREACH( SongPointerVector, m_vPreferredSortGroups, v )
|
||||
{
|
||||
for( int i=v->size()-1; i>=0; i-- )
|
||||
// move all unlock songs to a group at the bottom
|
||||
vector<Song*> vpUnlockSongs;
|
||||
FOREACH( UnlockEntry, UNLOCKMAN->m_UnlockEntries, ue )
|
||||
{
|
||||
Song *pSong = (*v)[i];
|
||||
if( find(vpUnlockSongs.begin(),vpUnlockSongs.end(),pSong) != vpUnlockSongs.end() )
|
||||
if( ue->m_Type == UnlockRewardType_Song )
|
||||
vpUnlockSongs.push_back( ue->m_pSong );
|
||||
}
|
||||
|
||||
FOREACH( SongPointerVector, m_vPreferredSongSort, v )
|
||||
{
|
||||
for( int i=v->size()-1; i>=0; i-- )
|
||||
{
|
||||
v->erase( v->begin()+i );
|
||||
Song *pSong = (*v)[i];
|
||||
if( find(vpUnlockSongs.begin(),vpUnlockSongs.end(),pSong) != vpUnlockSongs.end() )
|
||||
{
|
||||
v->erase( v->begin()+i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_vPreferredSongSort.push_back( vpUnlockSongs );
|
||||
}
|
||||
|
||||
m_vPreferredSortGroups.push_back( vpUnlockSongs );
|
||||
{
|
||||
m_vPreferredCourseSort.clear();
|
||||
|
||||
RString sFile = THEME->GetPathO( "SongManager", "PreferredCourses.txt" );
|
||||
RageFile file;
|
||||
if( !file.Open( sFile ) )
|
||||
return;
|
||||
|
||||
vector<Course*> vpCourses;
|
||||
|
||||
RString sLine;
|
||||
while( file.GetLine(sLine) )
|
||||
{
|
||||
bool bSectionDivider = sLine.find("---") != RString::npos;
|
||||
if( bSectionDivider )
|
||||
{
|
||||
if( !vpCourses.empty() )
|
||||
{
|
||||
m_vPreferredCourseSort.push_back( vpCourses );
|
||||
vpCourses.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Course *pCourse = NULL;
|
||||
if( !sLine.empty() )
|
||||
pCourse = FindCourse( sLine );
|
||||
if( pCourse )
|
||||
vpCourses.push_back( pCourse );
|
||||
}
|
||||
}
|
||||
|
||||
if( !vpCourses.empty() )
|
||||
{
|
||||
m_vPreferredCourseSort.push_back( vpCourses );
|
||||
vpCourses.clear();
|
||||
}
|
||||
|
||||
// move all unlock Courses to a group at the bottom
|
||||
vector<Course*> vpUnlockCourses;
|
||||
FOREACH( UnlockEntry, UNLOCKMAN->m_UnlockEntries, ue )
|
||||
{
|
||||
if( ue->m_Type == UnlockRewardType_Course )
|
||||
vpUnlockCourses.push_back( ue->m_pCourse );
|
||||
}
|
||||
|
||||
FOREACH( CoursePointerVector, m_vPreferredCourseSort, v )
|
||||
{
|
||||
for( int i=v->size()-1; i>=0; i-- )
|
||||
{
|
||||
Course *pCourse = (*v)[i];
|
||||
if( find(vpUnlockCourses.begin(),vpUnlockCourses.end(),pCourse) != vpUnlockCourses.end() )
|
||||
{
|
||||
v->erase( v->begin()+i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_vPreferredCourseSort.push_back( vpUnlockCourses );
|
||||
}
|
||||
}
|
||||
|
||||
void SongManager::SortSongs()
|
||||
|
||||
@@ -83,7 +83,8 @@ public:
|
||||
void GetSongs( vector<Song*> &AddTo ) const { GetSongs(AddTo,GROUP_ALL,INT_MAX); }
|
||||
Song *FindSong( RString sPath );
|
||||
Song *FindSong( RString sGroup, RString sSong );
|
||||
Course *FindCourse( RString sName );
|
||||
Course *FindCourse( RString sPath );
|
||||
Course *FindCourse( RString sGroup, RString sName );
|
||||
int GetNumSongs() const;
|
||||
int GetNumSongGroups() const;
|
||||
int GetNumCourses() const;
|
||||
@@ -98,8 +99,9 @@ public:
|
||||
bool WasLoadedFromAdditionalSongs( const Song *pSong ) const;
|
||||
|
||||
void GetAllCourses( vector<Course*> &AddTo, bool bIncludeAutogen );
|
||||
void GetCourses( CourseType ct, vector<Course*> &AddTo, bool bIncludeAutogen );
|
||||
void GetCourses( CourseType ct, vector<Course*> &AddTo, bool bIncludeAutogen ) const;
|
||||
void GetCoursesInGroup( vector<Course*> &AddTo, const RString &sCourseGroup, bool bIncludeAutogen );
|
||||
void GetPreferredSortCourses( CourseType ct, vector<Course*> &AddTo, bool bIncludeAutogen ) const;
|
||||
|
||||
void GetExtraStageInfo( bool bExtra2, const Style *s,
|
||||
Song*& pSongOut, Steps*& pStepsOut, PlayerOptions *pPlayerOptionsOut, SongOptions *pSongOptionsOut );
|
||||
@@ -132,7 +134,7 @@ protected:
|
||||
vector<Song*> m_pPopularSongs[NUM_ProfileSlot];
|
||||
vector<Song*> m_pShuffledSongs; // used by GetRandomSong
|
||||
typedef vector<Song*> SongPointerVector;
|
||||
vector<SongPointerVector> m_vPreferredSortGroups;
|
||||
vector<SongPointerVector> m_vPreferredSongSort;
|
||||
vector<RString> m_sSongGroupNames;
|
||||
vector<RString> m_sSongGroupBannerPaths; // each song group may have a banner associated with it
|
||||
|
||||
@@ -144,6 +146,8 @@ protected:
|
||||
RString m_sBannerPath;
|
||||
};
|
||||
map<RString,CourseGroupInfo> m_mapCourseGroupToInfo;
|
||||
typedef vector<Course*> CoursePointerVector;
|
||||
vector<CoursePointerVector> m_vPreferredCourseSort;
|
||||
|
||||
RageTexturePreloader m_TexturePreload;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user