Partially fix song repetition in generated courses.
The old algorithm for generating courses has a tendency to repeat songs. This commit prevents that from happening. Songs will instead shuffle, and will only repeat if the current song list has finished. This is a partial fix, since for some reason, the method responsible for getting all the songs in a song group is not doing its work properly. That means for a course that's supposed to have a 100 songs, only 95 of them would appear. The other 5 will never appear, and the last 5 will be a repeat of the first 5 songs.
This commit is contained in:
+24
-22
@@ -447,13 +447,20 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
|
|||||||
|
|
||||||
vector<Song*> vpAllPossibleSongs;
|
vector<Song*> vpAllPossibleSongs;
|
||||||
vector<SongAndSteps> vSongAndSteps;
|
vector<SongAndSteps> vSongAndSteps;
|
||||||
|
vector<Song*> vpSongs;
|
||||||
|
typedef vector<Steps*> StepsVector;
|
||||||
|
map<Song*, StepsVector> mapSongToSteps;
|
||||||
|
int songIndex = 0;
|
||||||
|
bool vpSongsSorted = false;
|
||||||
|
|
||||||
// Resolve each entry to a Song and Steps.
|
// Resolve each entry to a Song and Steps.
|
||||||
FOREACH_CONST( CourseEntry, entries, e )
|
FOREACH_CONST( CourseEntry, entries, e )
|
||||||
{
|
{
|
||||||
|
|
||||||
SongAndSteps resolved; // fill this in
|
SongAndSteps resolved; // fill this in
|
||||||
SongCriteria soc = e->songCriteria;
|
SongCriteria soc = e->songCriteria;
|
||||||
|
|
||||||
|
|
||||||
Song *pSong = e->songID.ToSong();
|
Song *pSong = e->songID.ToSong();
|
||||||
if( pSong )
|
if( pSong )
|
||||||
{
|
{
|
||||||
@@ -482,38 +489,32 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
|
|||||||
StepsUtil::GetAllMatching( soc, stc, vSongAndSteps );
|
StepsUtil::GetAllMatching( soc, stc, vSongAndSteps );
|
||||||
}
|
}
|
||||||
|
|
||||||
// It looks bad to have the same song 2x in a row in a randomly generated course.
|
|
||||||
// Don't allow the same song to be played 2x in a row, unless there's only
|
|
||||||
// one song in vpPossibleSongs.
|
|
||||||
if( trail.m_vEntries.size() > 0 && vSongAndSteps.size() > 1 )
|
|
||||||
{
|
|
||||||
const TrailEntry &teLast = trail.m_vEntries.back();
|
|
||||||
RemoveIf( vSongAndSteps, SongIsEqual(teLast.pSong) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// if there are no songs to choose from, abort this CourseEntry
|
// if there are no songs to choose from, abort this CourseEntry
|
||||||
if( vSongAndSteps.empty() )
|
if( vSongAndSteps.empty() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vector<Song*> vpSongs;
|
if( !vpSongsSorted && !vSongAndSteps.empty() ) {
|
||||||
typedef vector<Steps*> StepsVector;
|
FOREACH_CONST( SongAndSteps, vSongAndSteps, sas )
|
||||||
map<Song*,StepsVector> mapSongToSteps;
|
{
|
||||||
FOREACH_CONST( SongAndSteps, vSongAndSteps, sas )
|
StepsVector &v = mapSongToSteps[ sas->pSong ];
|
||||||
{
|
v.push_back( sas->pSteps );
|
||||||
StepsVector &v = mapSongToSteps[sas->pSong];
|
if( v.size() == 1 )
|
||||||
|
vpSongs.push_back( sas->pSong );
|
||||||
v.push_back( sas->pSteps );
|
}
|
||||||
if( v.size() == 1 )
|
vpSongsSorted = true;
|
||||||
vpSongs.push_back( sas->pSong );
|
CourseSortSongs( e->songSort, vpSongs, rnd );
|
||||||
|
songIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CourseSortSongs( e->songSort, vpSongs, rnd );
|
|
||||||
|
|
||||||
ASSERT( e->iChooseIndex >= 0 );
|
ASSERT( e->iChooseIndex >= 0 );
|
||||||
if( e->iChooseIndex < int(vSongAndSteps.size()) )
|
if( e->iChooseIndex < int(vSongAndSteps.size()) )
|
||||||
{
|
{
|
||||||
resolved.pSong = vpSongs[e->iChooseIndex];
|
if( songIndex >= vpSongs.size() ) {
|
||||||
|
songIndex = 0;
|
||||||
|
}
|
||||||
|
resolved.pSong = vpSongs[songIndex];
|
||||||
const vector<Steps*> &mappedSongs = mapSongToSteps[resolved.pSong];
|
const vector<Steps*> &mappedSongs = mapSongToSteps[resolved.pSong];
|
||||||
|
songIndex++;
|
||||||
resolved.pSteps = mappedSongs[ RandomInt(mappedSongs.size()) ];
|
resolved.pSteps = mappedSongs[ RandomInt(mappedSongs.size()) ];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -610,6 +611,7 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
|
|||||||
* This may or may not be the same as e.difficulty. */
|
* This may or may not be the same as e.difficulty. */
|
||||||
te.dc = dc;
|
te.dc = dc;
|
||||||
}
|
}
|
||||||
|
|
||||||
trail.m_vEntries.push_back( te );
|
trail.m_vEntries.push_back( te );
|
||||||
|
|
||||||
// LOG->Trace( "Chose: %s, %d", te.pSong->GetSongDir().c_str(), te.pSteps->GetMeter() );
|
// LOG->Trace( "Chose: %s, %d", te.pSong->GetSongDir().c_str(), te.pSteps->GetMeter() );
|
||||||
|
|||||||
Reference in New Issue
Block a user