From e1b5bf94046f109fb3c0ae4dd79eb9f0556471ff Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Sun, 25 Jan 2004 16:24:34 +0000 Subject: [PATCH] simplify --- stepmania/src/MusicWheel.cpp | 11 +- stepmania/src/ScreenUnlock.cpp | 6 +- stepmania/src/UnlockSystem.cpp | 180 ++++++++++++++++----------------- stepmania/src/UnlockSystem.h | 29 +++--- 4 files changed, 112 insertions(+), 114 deletions(-) diff --git a/stepmania/src/MusicWheel.cpp b/stepmania/src/MusicWheel.cpp index 42c3e0eb36..1227e93af7 100644 --- a/stepmania/src/MusicWheel.cpp +++ b/stepmania/src/MusicWheel.cpp @@ -346,13 +346,14 @@ void MusicWheel::GetSongList(vector &arraySongs, SongSortOrder so, CStrin { Song* pSong = apAllSongs[i]; - /* If we're on an extra stage, and this song is selected, ignore - * #SELECTABLE. */ + /* If we're on an extra stage, and this song is selected, ignore #SELECTABLE. */ if( pSong != GAMESTATE->m_pCurSong || (!GAMESTATE->IsExtraStage() && !GAMESTATE->IsExtraStage2()) ) { /* Hide songs that asked to be hidden via #SELECTABLE. */ if( so!=SORT_ROULETTE && !pSong->NormallyDisplayed() ) continue; + /* Don't show in roulette if #SELECTABLE:NO unless some other song in the same + * roulette class has previously been unlocked. */ if( so==SORT_ROULETTE && !(pSong->RouletteDisplayed() || UNLOCKSYS->SongIsRoulette( pSong )) ) continue; @@ -1215,9 +1216,9 @@ bool MusicWheel::Select() // return true if this selection ends the screen StartRandom(); return false; case TYPE_SONG: - if (PREFSMAN->m_bUseUnlockSystem) - UNLOCKSYS->RouletteUnlock( m_CurWheelItemData[m_iSelection]->m_pSong ); - // fall-through - we want to check for unlocking only if its a song + if( !GAMESTATE->IsExtraStage() && !GAMESTATE->IsExtraStage2() ) + UNLOCKSYS->UnlockSong( m_CurWheelItemData[m_iSelection]->m_pSong ); + return true; case TYPE_COURSE: return true; case TYPE_SORT: diff --git a/stepmania/src/ScreenUnlock.cpp b/stepmania/src/ScreenUnlock.cpp index 714d971539..1bda1cc7b6 100644 --- a/stepmania/src/ScreenUnlock.cpp +++ b/stepmania/src/ScreenUnlock.cpp @@ -86,7 +86,7 @@ ScreenUnlock::ScreenUnlock( CString sClassName ) : ScreenAttract( sClassName ) entry->Command(IconCommand); Unlocks.push_back(entry); - if ( !pSong->isLocked ) + if ( !pSong->IsLocked() ) this->AddChild(Unlocks[Unlocks.size() - 1]); } @@ -156,7 +156,7 @@ ScreenUnlock::ScreenUnlock( CString sClassName ) : ScreenAttract( sClassName ) if (pSong != NULL && pSong->m_pSong != NULL) { - if( pSong->isLocked) // song is locked + if( pSong->IsLocked() ) // song is locked { text->SetText("???"); text->SetZoomX(1); @@ -215,7 +215,7 @@ ScreenUnlock::ScreenUnlock( CString sClassName ) : ScreenAttract( sClassName ) if (UNLOCK_TEXT_SCROLL == 3) { - if (!pSong->isLocked) + if ( !pSong->IsLocked() ) LastUnlocks.push_back(i); } } diff --git a/stepmania/src/UnlockSystem.cpp b/stepmania/src/UnlockSystem.cpp index 631aec0134..e2ec937c5c 100644 --- a/stepmania/src/UnlockSystem.cpp +++ b/stepmania/src/UnlockSystem.cpp @@ -25,7 +25,6 @@ UnlockSystem* UNLOCKSYS = NULL; // global and accessable from anywhere in our program #define UNLOCKS_PATH "Data/Unlocks.dat" - #define MEMCARD_PATH "Data/MemCard.ini" static const char *g_UnlockNames[NUM_UNLOCK_TYPES] = @@ -41,32 +40,26 @@ static const char *g_UnlockNames[NUM_UNLOCK_TYPES] = UnlockSystem::UnlockSystem() { + UNLOCKSYS = this; + LoadFromDATFile(); memset( m_fScores, 0, sizeof(m_fScores) ); - RouletteSeeds = "1"; - - ReadValues( MEMCARD_PATH ); // in case its ever accessed, + ReadValues(); // in case its ever accessed, // we want the values to be available - WriteValues( MEMCARD_PATH ); // create if it does not exist + WriteValues(); // create if it does not exist } -void UnlockSystem::RouletteUnlock( const Song *song ) +void UnlockSystem::UnlockSong( const Song *song ) { - // if its an extra stage, don't count it - if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() ) - return; - - UnlockEntry *p = FindSong( song ); + const UnlockEntry *p = FindSong( song ); if( !p ) return; // does not exist - if( p->m_iRouletteSeed == 0 ) - return; // already unlocked + if( p->m_iCode == -1 ) + return; - ASSERT( p->m_iRouletteSeed < (int) RouletteSeeds.size() ); - RouletteSeeds[p->m_iRouletteSeed] = '1'; - WriteValues( MEMCARD_PATH ); + UnlockCode( p->m_iCode ); } bool UnlockSystem::CourseIsLocked( const Course *course ) @@ -78,8 +71,7 @@ bool UnlockSystem::CourseIsLocked( const Course *course ) if( p == NULL ) return false; - p->UpdateLocked(); - return p->isLocked; + return p->IsLocked(); } bool UnlockSystem::SongIsLocked( const Song *song ) @@ -91,21 +83,24 @@ bool UnlockSystem::SongIsLocked( const Song *song ) if( p == NULL ) return false; - p->UpdateLocked(); - - LOG->Trace( "current status: %slocked", p->isLocked? "":"un" ); - - return p->isLocked; + return p->IsLocked(); } +/* Return true if the song is available in roulette (overriding #SELECTABLE). */ bool UnlockSystem::SongIsRoulette( const Song *song ) { if( !PREFSMAN->m_bUseUnlockSystem ) return false; const UnlockEntry *p = FindSong( song ); + if( !p ) + return false; - return p && p->m_iRouletteSeed != 0; + /* If the song is locked by a code, and it's a roulette code, honor IsLocked. */ + if( p->m_iCode != -1 && + m_RouletteCodes.find( p->m_iCode ) != m_RouletteCodes.end() ) + return p->IsLocked(); + return true; } UnlockEntry *UnlockSystem::FindLockEntry( CString songname ) @@ -139,33 +134,23 @@ UnlockEntry *UnlockSystem::FindCourse( const Course *pCourse ) UnlockEntry::UnlockEntry() { memset( m_fRequired, 0, sizeof(m_fRequired) ); - m_iRouletteSeed = 0; + m_iCode = -1; m_pSong = NULL; m_pCourse = NULL; - - isLocked = true; } -void UnlockEntry::UpdateLocked() +bool UnlockEntry::IsLocked() const { - if( !isLocked ) - return; - - isLocked = true; for( int i = 0; i < NUM_UNLOCK_TYPES; ++i ) if( m_fRequired[i] && UNLOCKSYS->m_fScores[i] >= m_fRequired[i] ) - isLocked = false; + return false; - if ( m_iRouletteSeed ) - { - const CString &tmp = UNLOCKSYS->RouletteSeeds; + if( m_iCode != -1 && UNLOCKSYS->m_UnlockedCodes.find(m_iCode) != UNLOCKSYS->m_UnlockedCodes.end() ) + return false; - LOG->Trace("Seed in question: %d Roulette seeds: %s", m_iRouletteSeed, tmp.c_str() ); - if( tmp[m_iRouletteSeed] == '1' ) - isLocked = false; - } + return true; } bool UnlockSystem::LoadFromDATFile() @@ -179,7 +164,6 @@ bool UnlockSystem::LoadFromDATFile() return false; } - int MaxRouletteSlot = 0; unsigned i, j; for( i=0; iWarn("Unrecognized unlock tag \"%s\", ignored.", sValueName.c_str()); @@ -232,25 +223,24 @@ bool UnlockSystem::LoadFromDATFile() current.m_fRequired[UNLOCK_TOASTY] = datavalue; if( unlock_type == "CS" ) current.m_fRequired[UNLOCK_CLEARED] = datavalue; + if( unlock_type == "CODE" ) + current.m_iCode = (int) datavalue; if( unlock_type == "RO" ) { - current.m_iRouletteSeed = (int)datavalue; - MaxRouletteSlot = max( MaxRouletteSlot, (int) datavalue ); + m_UnlockedCodes.insert( (int)datavalue ); + m_RouletteCodes.insert( (int)datavalue ); } } - current.UpdateLocked(); m_SongEntries.push_back(current); } - InitRouletteSeeds( MaxRouletteSlot ); // resize roulette seeds for more efficient use of file - UpdateSongs(); for(i=0; i < m_SongEntries.size(); i++) { CString tmp = " "; - if (!m_SongEntries[i].isLocked) tmp = "un"; + if (!m_SongEntries[i].IsLocked()) tmp = "un"; LOG->Trace( "UnlockSystem Entry %s", m_SongEntries[i].m_sSongName.c_str() ); if (m_SongEntries[i].m_pSong != NULL) @@ -259,7 +249,7 @@ bool UnlockSystem::LoadFromDATFile() LOG->Trace( " DP %f", m_SongEntries[i].m_fRequired[UNLOCK_DANCE_POINTS] ); LOG->Trace( " SP %f", m_SongEntries[i].m_fRequired[UNLOCK_SONG_POINTS] ); LOG->Trace( " CS %f", m_SongEntries[i].m_fRequired[UNLOCK_CLEARED] ); - LOG->Trace( " RO %i", m_SongEntries[i].m_iRouletteSeed ); + LOG->Trace( " CODE %i", m_SongEntries[i].m_iCode ); LOG->Trace( " Status %slocked", tmp.c_str() ); if (m_SongEntries[i].m_pSong) LOG->Trace( " Found matching song entry" ); @@ -298,56 +288,57 @@ void UnlockSystem::UpdateSongs() if (m_SongEntries[i].m_pSong == NULL && m_SongEntries[i].m_pCourse == NULL) { - LOG->Warn("UnlockSystem::UpdateSongs(): Cannot find a " - "matching entry for %s.\nPlease check the song title. " - "Song titles should include the title and song title, e.g. " - "Can't Stop Fallin' In Love -Speed Mix-.", - m_SongEntries[i].m_sSongName.c_str() ); + LOG->Warn("Unlock: Cannot find a matching entry for \"%s\"", m_SongEntries[i].m_sSongName.c_str() ); m_SongEntries.erase(m_SongEntries.begin() + i); + --i; } } } -// This is mainly to streamline the INI for unnecessary values. -void UnlockSystem::InitRouletteSeeds(int MaxRouletteSlot) -{ - MaxRouletteSlot++; // we actually need one more - - // Truncate the value if we have too many seeds: - if ( (int)RouletteSeeds.size() > MaxRouletteSlot ) - RouletteSeeds = RouletteSeeds.Left( MaxRouletteSlot ); - - // Lengthen the value if we have too few seeds: - while ( (int)RouletteSeeds.size() < MaxRouletteSlot ) - RouletteSeeds += "0"; -} - -bool UnlockSystem::ReadValues( CString filename) +bool UnlockSystem::ReadValues() { IniFile data; - data.SetPath( filename ); + data.SetPath( MEMCARD_PATH ); if( !data.ReadFile() ) return false; for( int i = 0; i < NUM_UNLOCK_TYPES; ++i ) data.GetValue( "Unlock", g_UnlockNames[i], m_fScores[i] ); - data.GetValue ( "Unlock", "RouletteSeeds", RouletteSeeds ); + + m_UnlockedCodes.clear(); + CString s; + if( data.GetValue( "Unlock", "UnlockedCodes", s ) ) + { + vector sCodes; + split( s, ",", sCodes, true ); + for( unsigned c = 0; c < sCodes.size(); ++c ) + { + const int n = atoi( sCodes[c] ); + m_UnlockedCodes.insert( n ); + } + } return true; } -bool UnlockSystem::WriteValues( CString filename) +bool UnlockSystem::WriteValues() const { IniFile data; - data.SetPath( filename ); + data.SetPath( MEMCARD_PATH ); for( int i = 0; i < NUM_UNLOCK_TYPES; ++i ) data.SetValue( "Unlock", g_UnlockNames[i], m_fScores[i] ); - data.SetValue( "Unlock", "RouletteSeeds", RouletteSeeds ); + + vector sCodes; + for( set::const_iterator it = m_UnlockedCodes.begin(); it != m_UnlockedCodes.end(); ++it ) + sCodes.push_back( ssprintf("%i", *it) ); + + const CString list = join( ",", sCodes ); + data.SetValue( "Unlock", "UnlockedCodes", list ); data.WriteFile(); @@ -356,14 +347,14 @@ bool UnlockSystem::WriteValues( CString filename) void UnlockSystem::UnlockAddAP(float credit) { - ReadValues( MEMCARD_PATH ); + ReadValues(); m_fScores[UNLOCK_ARCADE_POINTS] += credit; - WriteValues( MEMCARD_PATH ); + WriteValues(); } void UnlockSystem::UnlockAddAP(Grade grade) { - ReadValues( MEMCARD_PATH ); + ReadValues(); switch( grade ) { case GRADE_FAILED: @@ -380,29 +371,29 @@ void UnlockSystem::UnlockAddAP(Grade grade) m_fScores[UNLOCK_ARCADE_POINTS] += 1; break; } - WriteValues( MEMCARD_PATH ); + WriteValues(); } void UnlockSystem::UnlockAddDP(float credit) { - ReadValues( MEMCARD_PATH ); + ReadValues(); // we don't want to ever take away dance points if( credit > 0 ) m_fScores[UNLOCK_DANCE_POINTS] += credit; - WriteValues( MEMCARD_PATH ); + WriteValues(); } void UnlockSystem::UnlockAddSP(float credit) { - ReadValues( MEMCARD_PATH ); + ReadValues(); m_fScores[UNLOCK_SONG_POINTS] += credit; - WriteValues( MEMCARD_PATH ); + WriteValues(); } void UnlockSystem::UnlockAddSP( Grade grade ) { - ReadValues( MEMCARD_PATH ); + ReadValues(); // TODO: move these to PREFS switch( grade ) @@ -416,35 +407,42 @@ void UnlockSystem::UnlockAddSP( Grade grade ) case GRADE_TIER_7:/*D*/ m_fScores[UNLOCK_SONG_POINTS] += 1; break; } - WriteValues( MEMCARD_PATH ); + WriteValues(); } void UnlockSystem::UnlockClearExtraStage() { - ReadValues( MEMCARD_PATH ); + ReadValues(); ++m_fScores[UNLOCK_EXTRA_CLEARED]; - WriteValues( MEMCARD_PATH ); + WriteValues(); } void UnlockSystem::UnlockFailExtraStage() { - ReadValues( MEMCARD_PATH ); + ReadValues(); ++m_fScores[UNLOCK_EXTRA_FAILED]; - WriteValues( MEMCARD_PATH ); + WriteValues(); } void UnlockSystem::UnlockClearStage() { - ReadValues( MEMCARD_PATH ); + ReadValues(); ++m_fScores[UNLOCK_CLEARED]; - WriteValues( MEMCARD_PATH ); + WriteValues(); } void UnlockSystem::UnlockToasty() { - ReadValues( MEMCARD_PATH ); + ReadValues(); ++m_fScores[UNLOCK_TOASTY]; - WriteValues( MEMCARD_PATH ); + WriteValues(); +} + +void UnlockSystem::UnlockCode( int num ) +{ + ReadValues(); + m_UnlockedCodes.insert( num ); + WriteValues(); } int UnlockSystem::GetNumUnlocks() const diff --git a/stepmania/src/UnlockSystem.h b/stepmania/src/UnlockSystem.h index 4221c0e99c..314055f064 100644 --- a/stepmania/src/UnlockSystem.h +++ b/stepmania/src/UnlockSystem.h @@ -2,6 +2,8 @@ #define UNLOCK_SYSTEM_H #include "Grade.h" +#include + /* ----------------------------------------------------------------------------- Class: UnlockSystem @@ -40,14 +42,11 @@ struct UnlockEntry Course *m_pCourse; float m_fRequired[NUM_UNLOCK_TYPES]; - int m_iRouletteSeed; + int m_iCode; - bool isLocked; // cached locked tag bool IsCourse() const { return m_pCourse != NULL; } - void UpdateLocked(); // updates isLocked - - void UpdateData(); + bool IsLocked() const; }; class UnlockSystem @@ -87,28 +86,28 @@ public: void UnlockClearStage(); void UnlockToasty(); - // unlocks given song in roulette - void RouletteUnlock( const Song *song ); + void UnlockCode( int num ); + + // unlocks the song's code + void UnlockSong( const Song *song ); - // read and write unlock in values - bool ReadValues( CString filename); - bool WriteValues( CString filename); - UnlockEntry *FindLockEntry( CString lockname ); // All locked songs are stored here vector m_SongEntries; private: + // read and write unlock in values + bool ReadValues(); + bool WriteValues() const; + UnlockEntry *FindSong( const Song *pSong ); UnlockEntry *FindCourse( const Course *pCourse ); - // makes RouletteSeeds more efficient - void InitRouletteSeeds(int MaxRouletteSlot); - // unlock values, cached float m_fScores[NUM_UNLOCK_TYPES]; - CString RouletteSeeds; + set m_UnlockedCodes; + set m_RouletteCodes; // "codes" which are available in roulette and which unlock if rouletted }; extern UnlockSystem* UNLOCKSYS; // global and accessable from anywhere in program