diff --git a/src/Course.cpp b/src/Course.cpp index f592023db1..420613b0d7 100644 --- a/src/Course.cpp +++ b/src/Course.cpp @@ -36,6 +36,34 @@ XToString( SongSort ); XToLocalizedString( SongSort ); StringToX( SongSort ); +struct OldStyleStringToSongSortMapHolder +{ + std::map conversion_map; + + OldStyleStringToSongSortMapHolder() + { + conversion_map["best"] = SongSort_MostPlays; + conversion_map["worst"] = SongSort_FewestPlays; + conversion_map["gradebest"] = SongSort_TopGrades; + conversion_map["gradeworst"] = SongSort_LowestGrades; + } +}; + +OldStyleStringToSongSortMapHolder OldStyleStringToSongSortMapHolder_converter; + +SongSort OldStyleStringToSongSort(const RString &ss) +{ + RString s2 = ss; + s2.MakeLower(); + std::map::iterator diff= + OldStyleStringToSongSortMapHolder_converter.conversion_map.find(s2); + if(diff != OldStyleStringToSongSortMapHolder_converter.conversion_map.end()) + { + return diff->second; + } + return SongSort_Invalid; +} + /* Maximum lower value of ranges when difficult: */ const int MAX_BOTTOM_RANGE = 10; @@ -368,9 +396,10 @@ bool Course::GetTrailSorted( StepsType st, CourseDifficulty cd, Trail &trail ) c // TODO: Move Course initialization after PROFILEMAN is created static void CourseSortSongs( SongSort sort, std::vector &vpPossibleSongs, RandomGen &rnd ) { - switch( sort ) + LOG->Trace("CourseSortSongs sort= %d | %s", sort, SongSortToString(sort).c_str()); + LOG->Flush(); + switch (sort) { - DEFAULT_FAIL(sort); case SongSort_Randomize: std::shuffle( vpPossibleSongs.begin(), vpPossibleSongs.end(), rnd ); break; @@ -393,6 +422,9 @@ static void CourseSortSongs( SongSort sort, std::vector &vpPossibleSongs, if( PROFILEMAN && GAMESTATE->GetMasterPlayerNumber() != PlayerNumber_Invalid ) SongUtil::SortSongPointerArrayByGrades( vpPossibleSongs, false ); // ascending break; + default: + LOG->Trace("CourseSortSongs sort= %d | %s invalid??", sort, SongSortToString(sort).c_str()); + break; } } @@ -520,8 +552,9 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) if( v.size() == 1 ) vpSongs.push_back( sas->pSong ); } - - CourseSortSongs( e->songSort, vpSongs, rnd ); + LOG->Trace("Course::GetTrailUnsorted"); + + CourseSortSongs(e->songSort, vpSongs, rnd); ASSERT( e->iChooseIndex >= 0 ); if( e->iChooseIndex < int( vSongAndSteps.size() ) ) diff --git a/src/Course.h b/src/Course.h index 75e9062688..8b311acc70 100644 --- a/src/Course.h +++ b/src/Course.h @@ -47,6 +47,7 @@ const RString& SongSortToString( SongSort ss ); const RString& SongSortToLocalizedString( SongSort ss ); SongSort StringToSongSort( const RString& ss ); +SongSort OldStyleStringToSongSort( const RString& ss ); class CourseEntry { diff --git a/src/CourseLoaderCRS.cpp b/src/CourseLoaderCRS.cpp index 310b36ff5c..8efac2cd2a 100644 --- a/src/CourseLoaderCRS.cpp +++ b/src/CourseLoaderCRS.cpp @@ -602,7 +602,27 @@ bool CourseLoaderCRS::ParseCourseSongSelect(const MsdFile::value_t &sParams, Cou } else if( sParamName.EqualsNoCase("SORT") ) { - if( CourseLoaderCRS::ParseCourseSongSort(sParamValue, new_entry, sPath) == false ) + std::vector sortParams; + split(sParamValue, ",", sortParams); + if( sortParams.size() != 2 ) + { + LOG->UserLog( "Course file", sPath, "has an invalid SORT parameter, \"%s\"", sParams[i].c_str()); + return false; + } + + SongSort sort = StringToSongSort(sortParams[0]); + if( sort == SongSort_Invalid ) + { + sort = OldStyleStringToSongSort(sortParams[0]); + } + if( sort == SongSort_Invalid ) + { + LOG->UserLog( "Course file", sPath, "has an invalid SORT parameter, \"%s\"", sParams[i].c_str()); + return false; + } + int index = StringToInt(sortParams[1]) - 1; + + if( CourseLoaderCRS::SetCourseSongSort(new_entry, sort, index, sPath) == false ) { return false; } @@ -661,7 +681,6 @@ bool CourseLoaderCRS::ParseCourseSongSelect(const MsdFile::value_t &sParams, Cou return true; } - bool CourseLoaderCRS::ParseCourseSongSort(RString sParam, CourseEntry &new_entry, const RString &sPath) { int iNumSongs = SONGMAN->GetNumSongs(); @@ -712,6 +731,34 @@ bool CourseLoaderCRS::ParseCourseSongSort(RString sParam, CourseEntry &new_entry } return true; } + +bool CourseLoaderCRS::SetCourseSongSort(CourseEntry &new_entry, SongSort sort, int index, const RString &sPath) +{ + if( sort == SongSort_Invalid ) + { + return false; + } + if( sort == SongSort_Randomize ) + { + new_entry.songSort = sort; + return true; + } + + int iNumSongs = SONGMAN->GetNumSongs(); + int iChooseIndex = index; + if ( iChooseIndex > iNumSongs && (sort == SongSort_MostPlays || sort == SongSort_FewestPlays) ) + { + LOG->UserLog( "Course file", sPath, "is trying to load %s%i with only %i songs installed. " + "This entry will be ignored.", SongSortToString(sort).c_str(), iChooseIndex, iNumSongs); + return false; // skip this #SONG + } + + CLAMP(iChooseIndex, 0, 500); + new_entry.iChooseIndex = iChooseIndex; + new_entry.songSort = sort; + return true; +} + /* * (c) 2001-2004 Chris Danford, Glenn Maynard * All rights reserved. diff --git a/src/CourseLoaderCRS.h b/src/CourseLoaderCRS.h index 8d2a738cbe..b7dc518067 100644 --- a/src/CourseLoaderCRS.h +++ b/src/CourseLoaderCRS.h @@ -5,6 +5,8 @@ #include "GameConstantsAndTypes.h" #include "MsdFile.h" +#include "Course.h" + class Course; class CourseEntry; struct AttackArray; @@ -56,6 +58,7 @@ namespace CourseLoaderCRS bool ParseCourseSong( const MsdFile::value_t &sParams, CourseEntry &new_entry, const RString &sPath ); bool ParseCourseSongSelect(const MsdFile::value_t &sParams, CourseEntry &new_entry, const RString &sPath); bool ParseCourseSongSort(RString sParam, CourseEntry &new_entry, const RString &sPath); + bool SetCourseSongSort(CourseEntry &new_entry, SongSort sort, int index, const RString &sPath); } #endif diff --git a/src/CourseWriterCRS.cpp b/src/CourseWriterCRS.cpp index 83c99333b6..f3bdaeeb68 100644 --- a/src/CourseWriterCRS.cpp +++ b/src/CourseWriterCRS.cpp @@ -263,7 +263,7 @@ bool CourseWriterCRS::WriteSongSelectCourseEntry( const CourseEntry &entry, Rage if( entry.songSort != SongSort_Randomize && entry.iChooseIndex > -1) { RString songSort = SongSortToString(entry.songSort); - songSelectParams.push_back(ssprintf("SORT=%s=%d", songSort.c_str(), entry.iChooseIndex+1)); + songSelectParams.push_back(ssprintf("SORT=%s,%d", songSort.c_str(), entry.iChooseIndex+1)); } if(entry.songCriteria.m_fMinDurationSeconds > 0 && entry.songCriteria.m_fMaxDurationSeconds > 0 )