Implement a Fisher-Yates shuffle on background music

This fixes sometimes getting repetitive background music
experimental
Harry 7 years ago
parent 1bdcecc32e
commit 2a85c5f011

@ -271,7 +271,6 @@ namespace MWSound
return sound; return sound;
} }
// Gets the combined volume settings for the given sound type // Gets the combined volume settings for the given sound type
float SoundManager::volumeFromType(PlayType type) const float SoundManager::volumeFromType(PlayType type) const
{ {
@ -298,7 +297,6 @@ namespace MWSound
return volume; return volume;
} }
void SoundManager::stopMusic() void SoundManager::stopMusic()
{ {
if(mMusic) if(mMusic)
@ -367,7 +365,9 @@ namespace MWSound
} }
mMusicFiles[mCurrentPlaylist] = filelist; mMusicFiles[mCurrentPlaylist] = filelist;
mMusicToPlay.reserve(mMusicToPlay.size() + filelist.size());
for(int it = 0; it < filelist.size(); it++)
mMusicToPlay.push_back(it);
} }
else else
filelist = mMusicFiles[mCurrentPlaylist]; filelist = mMusicFiles[mCurrentPlaylist];
@ -375,15 +375,23 @@ namespace MWSound
if(filelist.empty()) if(filelist.empty())
return; return;
int i = Misc::Rng::rollDice(filelist.size()); // Do a Fisher-Yates shuffle
if(mMusicFiles.size() == 0)
// Don't play the same music track twice in a row
if (filelist[i] == mLastPlayedMusic)
{ {
i = (i+1) % filelist.size(); mMusicToPlay.reserve(filelist.size());
for (int it = 0; it < filelist.size(); it++)
mMusicToPlay.push_back(it);
} }
advanceMusic(filelist[i]); int i = Misc::Rng::rollDice(mMusicToPlay.size());
// Fix last played music being the same after another shuffle
if(filelist[mMusicToPlay[i]] == mLastPlayedMusic)
i = (i+1) % mMusicToPlay.size();
advanceMusic(filelist[mMusicToPlay[i]]);
mMusicToPlay[i] = mMusicToPlay.back();
mMusicToPlay.pop_back();
} }
bool SoundManager::isMusicPlaying() bool SoundManager::isMusicPlaying()

@ -49,6 +49,7 @@ namespace MWSound
// Caches available music tracks by <playlist name, (sound files) > // Caches available music tracks by <playlist name, (sound files) >
std::map<std::string, std::vector<std::string> > mMusicFiles; std::map<std::string, std::vector<std::string> > mMusicFiles;
std::vector<int> mMusicToPlay; // The list of music files not played yet
std::string mLastPlayedMusic; // The music file that was last played std::string mLastPlayedMusic; // The music file that was last played
float mMasterVolume; float mMasterVolume;

Loading…
Cancel
Save