diff --git a/stepmania/src/CatalogXml.cpp b/stepmania/src/CatalogXml.cpp index 0c42a4a853..b1344e6fce 100644 --- a/stepmania/src/CatalogXml.cpp +++ b/stepmania/src/CatalogXml.cpp @@ -100,7 +100,7 @@ void CatalogXml::Save( LoadingWindow *loading_window ) if( pSong->IsTutorial() ) continue; // skip: Tutorial song. - if( UNLOCKMAN->SongIsLocked(pSong) ) + if( !pSong->NormallyDisplayed() ) continue; // skip: Locked song. iTotalSongs++; iNumSongsInGroup++; @@ -184,7 +184,7 @@ void CatalogXml::Save( LoadingWindow *loading_window ) if( pSong->IsTutorial() ) continue; // skip: Tutorial song. - if( UNLOCKMAN->SongIsLocked(pSong) ) + if( !pSong->NormallyDisplayed() ) continue; // skip: Locked song. SongID songID; diff --git a/stepmania/src/EditMenu.cpp b/stepmania/src/EditMenu.cpp index 5c98edd955..e3fc18e238 100644 --- a/stepmania/src/EditMenu.cpp +++ b/stepmania/src/EditMenu.cpp @@ -63,7 +63,7 @@ void EditMenu::GetSongsToShowForGroup( const RString &sGroup, vector &vpS for( int i=vpSongsOut.size()-1; i>=0; i-- ) { const Song* pSong = vpSongsOut[i]; - if( UNLOCKMAN->SongIsLocked(pSong) || pSong->IsTutorial() || SONGMAN->WasLoadedFromAdditionalSongs(pSong) ) + if( !pSong->NormallyDisplayed() || pSong->IsTutorial() || SONGMAN->WasLoadedFromAdditionalSongs(pSong) ) vpSongsOut.erase( vpSongsOut.begin()+i ); } break; diff --git a/stepmania/src/MusicWheel.cpp b/stepmania/src/MusicWheel.cpp index 14d05de8f4..4f65035df3 100644 --- a/stepmania/src/MusicWheel.cpp +++ b/stepmania/src/MusicWheel.cpp @@ -343,11 +343,15 @@ void MusicWheel::GetSongList( vector &arraySongs, SortOrder so, const RSt { Song* pSong = apAllSongs[i]; + int iLocked = UNLOCKMAN->SongIsLocked( pSong ); + if( iLocked & LOCKED_DISABLED ) + continue; + /* If we're on an extra stage, and this song is selected, ignore #SELECTABLE. */ if( pSong != GAMESTATE->m_pCurSong || !GAMESTATE->IsAnExtraStage() ) { /* Hide songs that asked to be hidden via #SELECTABLE. */ - if( !pSong->NormallyDisplayed() ) + if( iLocked & LOCKED_SELECTABLE ) continue; if( so!=SORT_ROULETTE && UNLOCKMAN->SongIsRouletteOnly( pSong ) ) continue; @@ -355,7 +359,7 @@ void MusicWheel::GetSongList( vector &arraySongs, SortOrder so, const RSt /* Hide locked songs. If RANDOM_PICKS_LOCKED_SONGS, hide in Roulette and Random, * too. */ - if( (so!=SORT_ROULETTE || !RANDOM_PICKS_LOCKED_SONGS) && UNLOCKMAN->SongIsLocked(pSong) ) + if( (so!=SORT_ROULETTE || !RANDOM_PICKS_LOCKED_SONGS) && iLocked ) continue; // If the song has at least one steps, add it. diff --git a/stepmania/src/Profile.cpp b/stepmania/src/Profile.cpp index 42d053fcf2..507f5912d6 100644 --- a/stepmania/src/Profile.cpp +++ b/stepmania/src/Profile.cpp @@ -253,7 +253,7 @@ int Profile::GetTotalStepsWithTopGrade( StepsType st, Difficulty d, Grade g ) co FOREACH_CONST( Song*, SONGMAN->GetSongs(), pSong ) { - if( (*pSong)->GetDisplayed() == Song::SHOW_NEVER ) + if( !(*pSong)->NormallyDisplayed() ) continue; // skip FOREACH_CONST( Steps*, (*pSong)->GetAllSteps(), pSteps ) @@ -315,7 +315,7 @@ float Profile::GetSongsPossible( StepsType st, Difficulty dc ) const { Song* pSong = vSongs[i]; - if( pSong->GetDisplayed() == Song::SHOW_NEVER ) + if( !pSong->NormallyDisplayed() ) continue; // skip vector vSteps = pSong->GetAllSteps(); @@ -355,7 +355,7 @@ float Profile::GetSongsActual( StepsType st, Difficulty dc ) const if( pSong == NULL ) continue; - if( pSong->GetDisplayed() == Song::SHOW_NEVER ) + if( !pSong->NormallyDisplayed() ) continue; // skip CHECKPOINT_M( ssprintf("Profile::GetSongsActual: song %s", pSong->GetSongDir().c_str()) ); diff --git a/stepmania/src/ScreenJukebox.cpp b/stepmania/src/ScreenJukebox.cpp index ffe7c9be89..9ea5f24473 100644 --- a/stepmania/src/ScreenJukebox.cpp +++ b/stepmania/src/ScreenJukebox.cpp @@ -83,7 +83,7 @@ void ScreenJukebox::SetSong() ASSERT( pSong != NULL ); if( !pSong->HasMusic() ) continue; // skip - if( UNLOCKMAN->SongIsLocked(pSong) ) + if( !pSong->NormallyDisplayed() ) continue; if( !pSong->ShowInDemonstrationAndRanking() ) continue; // skip diff --git a/stepmania/src/ScreenRanking.cpp b/stepmania/src/ScreenRanking.cpp index e6f9f966a5..ea629d57c5 100644 --- a/stepmania/src/ScreenRanking.cpp +++ b/stepmania/src/ScreenRanking.cpp @@ -39,7 +39,7 @@ static void GetAllSongsToShow( vector &vpOut, bool bShowOnlyMostRecentSco vpOut.clear(); FOREACH_CONST( Song*, SONGMAN->GetSongs(), s ) { - if( UNLOCKMAN->SongIsLocked(*s) ) + if( !(*s)->NormallyDisplayed() ) continue; // skip if( !(*s)->ShowInDemonstrationAndRanking() ) continue; // skip diff --git a/stepmania/src/ScreenSelectGroup.cpp b/stepmania/src/ScreenSelectGroup.cpp index 6bba81c05c..c421061d02 100644 --- a/stepmania/src/ScreenSelectGroup.cpp +++ b/stepmania/src/ScreenSelectGroup.cpp @@ -39,7 +39,7 @@ void ScreenSelectGroup::Init() { bool DisplaySong = aAllSongs[j]->NormallyDisplayed(); - if( UNLOCKMAN->SongIsLocked( aAllSongs[j] ) ) + if( !aAllSongs[j]->NormallyDisplayed() ) DisplaySong = false; if( aAllSongs[j]->SongCompleteForStyle(GAMESTATE->GetCurrentStyle()) && diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 95f8790dd5..271826f109 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -26,7 +26,7 @@ #include "NotesLoaderSM.h" #include "NotesWriterDWI.h" #include "NotesWriterSM.h" - +#include "UnlockManager.h" #include "LyricsLoader.h" #include @@ -66,6 +66,7 @@ Song::Song() m_fLastBeat = -1; m_fSpecifiedLastBeat = -1; m_SelectionDisplay = SHOW_ALWAYS; + m_bEnabled = true; m_DisplayBPMType = DISPLAY_ACTUAL; m_fSpecifiedBPMMin = 0; m_fSpecifiedBPMMax = 0; @@ -1042,13 +1043,14 @@ bool Song::HasEdits( StepsType st ) const return false; } -Song::SelectionDisplay Song::GetDisplayed() const +/* Return false if the song should not be displayed for selection in normal + * gameplay (but may still be available in random selection, during extra + * stages, or in other special conditions). */ +bool Song::NormallyDisplayed() const { - if( !PREFSMAN->m_bHiddenSongs ) - return SHOW_ALWAYS; - return m_SelectionDisplay; + return UNLOCKMAN == NULL || !UNLOCKMAN->SongIsLocked(this); } -bool Song::NormallyDisplayed() const { return GetDisplayed() == SHOW_ALWAYS; } + bool Song::ShowInDemonstrationAndRanking() const { return !IsTutorial() && NormallyDisplayed(); } diff --git a/stepmania/src/SongManager.cpp b/stepmania/src/SongManager.cpp index d9dda6484e..6db9f1598d 100644 --- a/stepmania/src/SongManager.cpp +++ b/stepmania/src/SongManager.cpp @@ -582,7 +582,8 @@ int SongManager::GetNumUnlockedSongs() const int iNum = 0; FOREACH_CONST( Song*, m_pSongs, i ) { - if( UNLOCKMAN->SongIsLocked( *i ) ) + // If locked for any reason other than LOCKED_LOCK: + if( UNLOCKMAN->SongIsLocked(*i) & ~LOCKED_LOCK ) continue; ++iNum; } @@ -594,9 +595,8 @@ int SongManager::GetNumSelectableAndUnlockedSongs() const int iNum = 0; FOREACH_CONST( Song*, m_pSongs, i ) { - if( UNLOCKMAN->SongIsLocked( *i ) ) - continue; - if( (*i)->GetDisplayed() != Song::SHOW_ALWAYS ) + // If locked for any reason other than LOCKED_LOCK or LOCKED_SELECTABLE: + if( UNLOCKMAN->SongIsLocked(*i) & ~(LOCKED_LOCK|LOCKED_SELECTABLE) ) continue; ++iNum; } @@ -1102,7 +1102,7 @@ Song* SongManager::GetRandomSong() Song *pSong = m_pShuffledSongs[ i ]; if( pSong->IsTutorial() ) continue; - if( UNLOCKMAN->SongIsLocked(pSong) ) + if( !pSong->NormallyDisplayed() ) continue; return pSong; } @@ -1251,12 +1251,8 @@ void SongManager::UpdatePopular() for ( unsigned j=0; j < apBestSongs.size() ; ++j ) { bool bFiltered = false; - /* Filter out hidden songs. */ - if( apBestSongs[j]->GetDisplayed() != Song::SHOW_ALWAYS ) - bFiltered = true; /* Filter out locked songs. */ - // XXX Hack, this depends on UNLOCKMAN being around. - if( UNLOCKMAN && UNLOCKMAN->SongIsLocked(apBestSongs[j]) ) + if( !apBestSongs[j]->NormallyDisplayed() ) bFiltered = true; if( !bFiltered ) continue; @@ -1328,7 +1324,7 @@ void SongManager::UpdatePreferredSort() Song *pSong = NULL; if( !sLine.empty() ) pSong = FindSong( sLine ); - if( pSong && pSong->GetDisplayed() != Song::SHOW_NEVER ) + if( pSong && UNLOCKMAN->SongIsLocked(pSong) & LOCKED_SELECTABLE ) vpSongs.push_back( pSong ); } } diff --git a/stepmania/src/SongUtil.cpp b/stepmania/src/SongUtil.cpp index cf69961847..c6b8c007af 100644 --- a/stepmania/src/SongUtil.cpp +++ b/stepmania/src/SongUtil.cpp @@ -24,6 +24,9 @@ bool SongCriteria::Matches( const Song *pSong ) const if( !m_sGroupName.empty() && m_sGroupName != pSong->m_sGroupName ) return false; + if( UNLOCKMAN->SongIsLocked(pSong) & LOCKED_DISABLED ) + return false; + if( m_bUseSongGenreAllowedList ) { if( find(m_vsSongGenreAllowedList.begin(),m_vsSongGenreAllowedList.end(),pSong->m_sGenre) == m_vsSongGenreAllowedList.end() ) @@ -34,11 +37,11 @@ bool SongCriteria::Matches( const Song *pSong ) const { DEFAULT_FAIL(m_Selectable); case Selectable_Yes: - if( pSong->GetDisplayed() != Song::SHOW_ALWAYS ) + if( UNLOCKMAN && !(UNLOCKMAN->SongIsLocked(pSong) & LOCKED_SELECTABLE) ) return false; break; case Selectable_No: - if( pSong->GetDisplayed() != Song::SHOW_NEVER ) + if( UNLOCKMAN && UNLOCKMAN->SongIsLocked(pSong) & LOCKED_SELECTABLE ) return false; break; case Selectable_DontCare: @@ -73,11 +76,11 @@ bool SongCriteria::Matches( const Song *pSong ) const { DEFAULT_FAIL(m_Locked); case Locked_Locked: - if( UNLOCKMAN && !UNLOCKMAN->SongIsLocked(pSong) ) + if( UNLOCKMAN && !(UNLOCKMAN->SongIsLocked(pSong) & LOCKED_LOCK) ) return false; break; case Locked_Unlocked: - if( UNLOCKMAN && UNLOCKMAN->SongIsLocked(pSong) ) + if( UNLOCKMAN && UNLOCKMAN->SongIsLocked(pSong) & LOCKED_LOCK ) return false; break; case Locked_DontCare: diff --git a/stepmania/src/UnlockManager.cpp b/stepmania/src/UnlockManager.cpp index a9e31ac1f8..c135a2ec03 100644 --- a/stepmania/src/UnlockManager.cpp +++ b/stepmania/src/UnlockManager.cpp @@ -118,16 +118,20 @@ bool UnlockManager::CourseIsLocked( const Course *course ) const return p->IsLocked(); } -bool UnlockManager::SongIsLocked( const Song *song ) const +int UnlockManager::SongIsLocked( const Song *pSong ) const { - if( !PREFSMAN->m_bUseUnlockSystem ) - return false; - - const UnlockEntry *p = FindSong( song ); - if( p == NULL ) - return false; - - return p->IsLocked(); + int iRet = 0; + if( PREFSMAN->m_bUseUnlockSystem ) + { + const UnlockEntry *p = FindSong( pSong ); + if( p != NULL && p->IsLocked() ) + iRet |= LOCKED_LOCK; + } + if( PREFSMAN->m_bHiddenSongs && pSong->m_SelectionDisplay == Song::SHOW_NEVER ) + iRet |= LOCKED_SELECTABLE; + if( !pSong->m_bEnabled ) + iRet |= LOCKED_DISABLED; + return iRet; } /* Return true if the song is *only* available in roulette. */ diff --git a/stepmania/src/UnlockManager.h b/stepmania/src/UnlockManager.h index a4df2a7299..c7d244b07e 100644 --- a/stepmania/src/UnlockManager.h +++ b/stepmania/src/UnlockManager.h @@ -90,6 +90,16 @@ public: void PushSelf( lua_State *L ); }; +// Option is locked due to an unsatisfied unlock entry. +#define LOCKED_LOCK 0x1 + +// Option is locked due to a #SELECTABLE tag. +#define LOCKED_SELECTABLE 0x2 + +// Option is disabled by the operator. (For courses, this means that a song in the +// course is disabled.) +#define LOCKED_DISABLED 0x4 + class UnlockManager { friend class UnlockEntry; @@ -100,7 +110,7 @@ public: void Reload(); float PointsUntilNextUnlock( UnlockRequirement t ) const; - bool SongIsLocked( const Song *song ) const; + int SongIsLocked( const Song *pSong ) const; bool SongIsRouletteOnly( const Song *song ) const; bool StepsIsLocked( const Song *pSong, const Steps *pSteps ) const; bool CourseIsLocked( const Course *course ) const; diff --git a/stepmania/src/song.h b/stepmania/src/song.h index 7a9d716c32..de1b4c2320 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -101,6 +101,7 @@ public: ProfileSlot m_LoadedFromProfile; // ProfileSlot_Invalid if wasn't loaded from a profile bool m_bIsSymLink; + bool m_bEnabled; RString m_sMainTitle, m_sSubTitle, m_sArtist; RString m_sMainTitleTranslit, m_sSubTitleTranslit, m_sArtistTranslit; @@ -206,7 +207,8 @@ public: bool IsEasy( StepsType st ) const; bool IsTutorial() const; bool HasEdits( StepsType st ) const; - SelectionDisplay GetDisplayed() const; + + bool SetEnabled( bool b ) { m_bEnabled = b; } bool NormallyDisplayed() const; bool ShowInDemonstrationAndRanking() const; @@ -232,7 +234,6 @@ public: void PushSelf( lua_State *L ); private: - vector m_vpSteps; vector m_vpStepsByType[NUM_StepsType]; };