From 527b863f1a806f399204897f0c85ee9642f0295a Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Mon, 20 Mar 2006 22:41:41 +0000 Subject: [PATCH] add AutoLockChallengeSteps --- stepmania/src/Banner.cpp | 9 ++- stepmania/src/Profile.cpp | 24 ++++--- stepmania/src/Profile.h | 1 + stepmania/src/ScreenUnlockBrowse.cpp | 4 +- stepmania/src/ScreenUnlockCelebrate.cpp | 13 ++-- stepmania/src/ScreenUnlockCelebrate.h | 1 + stepmania/src/UnlockManager.cpp | 90 +++++++++++++++++++------ stepmania/src/UnlockManager.h | 8 ++- 8 files changed, 108 insertions(+), 42 deletions(-) diff --git a/stepmania/src/Banner.cpp b/stepmania/src/Banner.cpp index 34f2ee9eb4..0311fc384a 100644 --- a/stepmania/src/Banner.cpp +++ b/stepmania/src/Banner.cpp @@ -132,7 +132,8 @@ void Banner::LoadIconFromCharacter( Character* pCharacter ) void Banner::LoadTABreakFromCharacter( Character* pCharacter ) { - if( pCharacter == NULL ) Load( THEME->GetPathG("Common","fallback takingabreak") ); + if( pCharacter == NULL ) + Load( THEME->GetPathG("Common","fallback takingabreak") ); else { Load( pCharacter->GetTakingABreakPath() ); @@ -142,7 +143,8 @@ void Banner::LoadTABreakFromCharacter( Character* pCharacter ) void Banner::LoadBannerFromUnlockEntry( UnlockEntry* pUE ) { - if( pUE == NULL ) LoadFallback(); + if( pUE == NULL ) + LoadFallback(); else { RString sFile = pUE->GetBannerFile(); @@ -153,7 +155,8 @@ void Banner::LoadBannerFromUnlockEntry( UnlockEntry* pUE ) void Banner::LoadBackgroundFromUnlockEntry( UnlockEntry* pUE ) { - if( pUE == NULL ) LoadFallback(); + if( pUE == NULL ) + LoadFallback(); else { RString sFile = pUE->GetBackgroundFile(); diff --git a/stepmania/src/Profile.cpp b/stepmania/src/Profile.cpp index c29598c895..c531bd85f3 100644 --- a/stepmania/src/Profile.cpp +++ b/stepmania/src/Profile.cpp @@ -608,20 +608,26 @@ DateTime Profile::GetSongLastPlayedDateTime( const Song* pSong ) const return dtLatest; } +bool Profile::HasPassedSteps( const Song* pSong, const Steps* pSteps ) const +{ + const HighScoreList &hsl = GetStepsHighScoreList( pSong, pSteps ); + Grade grade = hsl.GetTopScore().GetGrade(); + switch( grade ) + { + case Grade_Failed: + case Grade_NoData: + return false; + default: + return true; + } +} + bool Profile::HasPassedAnyStepsInSong( const Song* pSong ) const { FOREACH_CONST( Steps*, pSong->GetAllSteps(), steps ) { - const HighScoreList &hsl = GetStepsHighScoreList( pSong, *steps ); - Grade grade = hsl.GetTopScore().GetGrade(); - switch( grade ) - { - case Grade_Failed: - case Grade_NoData: - break; - default: + if( HasPassedSteps( pSong, *steps ) ) return true; - } } return false; } diff --git a/stepmania/src/Profile.h b/stepmania/src/Profile.h index b883d03425..ebf9616c3e 100644 --- a/stepmania/src/Profile.h +++ b/stepmania/src/Profile.h @@ -169,6 +169,7 @@ public: int GetSongNumTimesPlayed( const Song* pSong ) const; int GetSongNumTimesPlayed( const SongID& songID ) const; DateTime GetSongLastPlayedDateTime( const Song* pSong ) const; + bool HasPassedSteps( const Song* pSong, const Steps* pSteps ) const; bool HasPassedAnyStepsInSong( const Song* pSong ) const; // diff --git a/stepmania/src/ScreenUnlockBrowse.cpp b/stepmania/src/ScreenUnlockBrowse.cpp index 99a5e4f87f..40802787c0 100644 --- a/stepmania/src/ScreenUnlockBrowse.cpp +++ b/stepmania/src/ScreenUnlockBrowse.cpp @@ -11,11 +11,11 @@ void ScreenUnlockBrowse::Init() FOREACH_CONST( UnlockEntry, UNLOCKMAN->m_UnlockEntries, ue ) { GameCommand gc; - if( !ue->IsLocked() ) + if( ue->IsRequirementMet() ) gc.m_bInvalid = false; gc.m_iIndex = ue - UNLOCKMAN->m_UnlockEntries.begin(); gc.m_iUnlockEntryID = ue->m_iEntryID; - gc.m_sName = ssprintf("%d",ue->m_iEntryID); + gc.m_sName = ssprintf("%d",gc.m_iIndex); m_aGameCommands.push_back( gc ); } diff --git a/stepmania/src/ScreenUnlockCelebrate.cpp b/stepmania/src/ScreenUnlockCelebrate.cpp index 14ff8172af..ac1f4c25c0 100644 --- a/stepmania/src/ScreenUnlockCelebrate.cpp +++ b/stepmania/src/ScreenUnlockCelebrate.cpp @@ -10,10 +10,6 @@ void ScreenUnlockCelebrate::Init() // We shouldn't be called if there aren't any unlocks to celebrate ASSERT( UNLOCKMAN->AnyUnlocksToCelebrate() ); - // Mark this unlock as celebrated - int iUnlockID = UNLOCKMAN->GetUnlockEntryIDToCelebrate(); - UNLOCKMAN->UnlockEntryID( iUnlockID ); - ScreenUnlockBrowse::Init(); } @@ -33,6 +29,15 @@ void ScreenUnlockCelebrate::MenuDown( const InputEventPlus &input ) { } +void ScreenUnlockCelebrate::MenuStart( PlayerNumber pn ) +{ + // Mark this unlock as celebrated + int iUnlockIndex = UNLOCKMAN->GetUnlockEntryIndexToCelebrate(); + UNLOCKMAN->UnlockEntryIndex( iUnlockIndex ); + + ScreenUnlockBrowse::MenuStart( pn ); +} + void ScreenUnlockCelebrate::MenuBack( PlayerNumber pn ) { this->MenuStart(pn); diff --git a/stepmania/src/ScreenUnlockCelebrate.h b/stepmania/src/ScreenUnlockCelebrate.h index 82232eb496..63e2634e37 100644 --- a/stepmania/src/ScreenUnlockCelebrate.h +++ b/stepmania/src/ScreenUnlockCelebrate.h @@ -11,6 +11,7 @@ public: virtual void MenuRight( const InputEventPlus &input ); virtual void MenuUp( const InputEventPlus &input ); virtual void MenuDown( const InputEventPlus &input ); + virtual void MenuStart( PlayerNumber pn ); virtual void MenuBack( PlayerNumber pn ); protected: }; diff --git a/stepmania/src/UnlockManager.cpp b/stepmania/src/UnlockManager.cpp index 2a3b582a94..488df52385 100644 --- a/stepmania/src/UnlockManager.cpp +++ b/stepmania/src/UnlockManager.cpp @@ -21,6 +21,8 @@ UnlockManager* UNLOCKMAN = NULL; // global and accessable from anywhere in our p #define UNLOCK_NAMES THEME->GetMetric ("Unlocks","UnlockNames") #define UNLOCK(sLineName) THEME->GetMetric ("Unlocks",ssprintf("Unlock%s",sLineName.c_str())) +ThemeMetric AUTO_LOCK_CHALLENGE_STEPS( "UnlockManager", "AutoLockChallengeSteps" ); + static const char *UnlockRequirementNames[] = { "ArcadePoints", @@ -299,6 +301,19 @@ bool UnlockEntry::IsRequirementMet() const if( m_fRequirement[i] && fScores[i] >= m_fRequirement[i] ) return true; + if( m_bRequrePassHardSteps && m_pSong ) + { + vector vp; + m_pSong->GetSteps( + vp, + STEPS_TYPE_INVALID, + DIFFICULTY_HARD + ); + FOREACH_CONST( Steps*, vp, s ) + if( PROFILEMAN->GetMachineProfile()->HasPassedSteps( m_pSong, *s ) ) + return true; + } + return false; } @@ -320,7 +335,7 @@ RString UnlockEntry::GetDescription() const case UnlockRewardType_Song: return m_pSong ? m_pSong->GetDisplayFullTitle() : ""; case UnlockRewardType_Steps: - return DifficultyToLocalizedString( m_dc ); + return (m_pSong ? m_pSong->GetDisplayFullTitle() : "") + ", " + DifficultyToLocalizedString( m_dc ); case UnlockRewardType_Course: return m_pCourse ? m_pCourse->GetDisplayFullTitle() : ""; case UnlockRewardType_Modifier: @@ -336,9 +351,8 @@ RString UnlockEntry::GetBannerFile() const ASSERT(0); return ""; case UnlockRewardType_Song: - return m_pSong ? m_pSong->GetBannerPath() : ""; case UnlockRewardType_Steps: - return ""; + return m_pSong ? m_pSong->GetBannerPath() : ""; case UnlockRewardType_Course: return m_pCourse ? m_pCourse->m_sBannerPath : ""; case UnlockRewardType_Modifier: @@ -421,6 +435,10 @@ void UnlockManager::Load() { bRoulette = true; } + else if( sName == "RequrePassHardSteps" ) + { + current.m_bRequrePassHardSteps = true; + } else { const UnlockRequirement ut = StringToUnlockRequirement( cmd.GetName() ); @@ -432,22 +450,54 @@ void UnlockManager::Load() if( bRoulette ) m_RouletteCodes.insert( current.m_iEntryID ); - // Make sure that we don't have duplicate unlock IDs. This can cause problems - // with UnlockCelebrate and with codes. - FOREACH_CONST( UnlockEntry, m_UnlockEntries, ue ) - ASSERT( ue->m_iEntryID != current.m_iEntryID ); - m_UnlockEntries.push_back( current ); } + if( AUTO_LOCK_CHALLENGE_STEPS ) + { + FOREACH_CONST( Song*, SONGMAN->GetAllSongs(), s ) + { + if( (*s)->GetOneSteps(STEPS_TYPE_INVALID, DIFFICULTY_HARD) == NULL ) + continue; + + UnlockEntry ue; + ue.m_Type = UnlockRewardType_Steps; + ue.m_cmd.Load( "steps,"+(*s)->m_sGroupName+"/"+(*s)->GetTranslitFullTitle()+",expert" ); + ue.m_bRequrePassHardSteps = true; + + m_UnlockEntries.push_back( ue ); + } + } + + // + // Fill in unlock entry IDs that weren't specified + // + FOREACH( UnlockEntry, m_UnlockEntries, e ) + { + if( e->m_iEntryID == -1 ) + e->m_iEntryID = e - m_UnlockEntries.begin(); + } + + // Make sure that we don't have duplicate unlock IDs. This can cause problems + // with UnlockCelebrate and with codes. + FOREACH_CONST( UnlockEntry, m_UnlockEntries, ue ) + FOREACH_CONST( UnlockEntry, m_UnlockEntries, ue2 ) + if( ue != ue2 ) + ASSERT_M( ue->m_iEntryID != ue2->m_iEntryID, ssprintf("duplicate unlock entry id %d",ue->m_iEntryID) ); + UpdateCachedPointers(); + // + // Log unlocks + // FOREACH_CONST( UnlockEntry, m_UnlockEntries, e ) { RString str = ssprintf( "Unlock: %s; ", join("\n",e->m_cmd.m_vsArgs).c_str() ); FOREACH_ENUM2( UnlockRequirement, j ) if( e->m_fRequirement[j] ) str += ssprintf( "%s = %f; ", UnlockRequirementToString(j).c_str(), e->m_fRequirement[j] ); + if( e->m_bRequrePassHardSteps ) + str += "RequrePassHardSteps; "; str += ssprintf( "entryID = %i ", e->m_iEntryID ); str += e->IsLocked()? "locked":"unlocked"; @@ -530,6 +580,12 @@ void UnlockManager::UnlockEntryID( int iEntryID ) PROFILEMAN->GetMachineProfile()->m_UnlockedEntryIDs.insert( iEntryID ); } +void UnlockManager::UnlockEntryIndex( int iEntryIndex ) +{ + int iEntryID = m_UnlockEntries[iEntryIndex].m_iEntryID; + UnlockEntryID( iEntryID ); +} + void UnlockManager::PreferUnlockEntryID( int iUnlockEntryID ) { for( unsigned i = 0; i < m_UnlockEntries.size(); ++i ) @@ -560,16 +616,6 @@ bool UnlockManager::AllAreLocked() const return true; } -int UnlockManager::GetUnlockEntryIDToCelebrate() const -{ - FOREACH_CONST( UnlockEntry, m_UnlockEntries, ue ) - { - if( ue->IsRequirementMet() && ue->IsLocked() ) - return ue->m_iEntryID; - } - return -1; -} - int UnlockManager::GetUnlockEntryIndexToCelebrate() const { FOREACH_CONST( UnlockEntry, m_UnlockEntries, ue ) @@ -582,7 +628,7 @@ int UnlockManager::GetUnlockEntryIndexToCelebrate() const bool UnlockManager::AnyUnlocksToCelebrate() const { - return GetUnlockEntryIDToCelebrate() != -1; + return GetUnlockEntryIndexToCelebrate() != -1; } void UnlockManager::GetUnlocksByType( UnlockRewardType t, vector &apEntries ) @@ -627,16 +673,20 @@ public: LunaUnlockEntry() { LUA->Register( Register ); } static int IsLocked( T* p, lua_State *L ) { lua_pushboolean(L, p->IsLocked() ); return 1; } + static int IsRequirementMet( T* p, lua_State *L ) { lua_pushboolean(L, p->IsRequirementMet() ); return 1; } static int GetDescription( T* p, lua_State *L ) { lua_pushstring(L, p->GetDescription() ); return 1; } static int GetUnlockRewardType( T* p, lua_State *L ) { lua_pushnumber(L, p->m_Type ); return 1; } static int GetRequirement( T* p, lua_State *L ) { UnlockRequirement i = (UnlockRequirement)IArg(1); lua_pushnumber(L, p->m_fRequirement[i] ); return 1; } + static int GetRequrePassHardSteps( T* p, lua_State *L ) { lua_pushboolean(L, p->m_bRequrePassHardSteps); return 1; } static void Register(lua_State *L) { ADD_METHOD( IsLocked ); + ADD_METHOD( IsRequirementMet ); ADD_METHOD( GetDescription ); ADD_METHOD( GetUnlockRewardType ); ADD_METHOD( GetRequirement ); + ADD_METHOD( GetRequrePassHardSteps ); Luna::Register( L ); } @@ -654,7 +704,6 @@ public: static int PreferUnlockEntryID( T* p, lua_State *L ) { int iUnlockEntryID = IArg(1); p->PreferUnlockEntryID(iUnlockEntryID); return 0; } static int GetNumUnlocks( T* p, lua_State *L ) { lua_pushnumber( L, p->GetNumUnlocks() ); return 1; } static int AllAreLocked( T* p, lua_State *L ) { lua_pushboolean( L, p->AllAreLocked() ); return 1; } - static int GetUnlockEntryIDToCelebrate( T* p, lua_State *L ) { lua_pushnumber( L, p->GetUnlockEntryIDToCelebrate() ); return 1; } static int GetUnlockEntryIndexToCelebrate( T* p, lua_State *L ) { lua_pushnumber( L, p->GetUnlockEntryIndexToCelebrate() ); return 1; } static int AnyUnlocksToCelebrate( T* p, lua_State *L ) { lua_pushboolean( L, p->AnyUnlocksToCelebrate() ); return 1; } static int GetUnlockEntry( T* p, lua_State *L ) { int iIndex = IArg(1); p->m_UnlockEntries[iIndex].PushSelf(L); return 1; } @@ -684,7 +733,6 @@ public: ADD_METHOD( PreferUnlockEntryID ); ADD_METHOD( GetNumUnlocks ); ADD_METHOD( AllAreLocked ); - ADD_METHOD( GetUnlockEntryIDToCelebrate ); ADD_METHOD( GetUnlockEntryIndexToCelebrate ); ADD_METHOD( AnyUnlocksToCelebrate ); ADD_METHOD( GetUnlockEntry ); diff --git a/stepmania/src/UnlockManager.h b/stepmania/src/UnlockManager.h index 89392f10fd..94d0b7e010 100644 --- a/stepmania/src/UnlockManager.h +++ b/stepmania/src/UnlockManager.h @@ -52,7 +52,8 @@ public: m_pCourse = NULL; ZERO( m_fRequirement ); - m_iEntryID = -1; + m_bRequrePassHardSteps = false; + m_iEntryID = -1; // -1 == not yet filled. This will be filled in automatically if not specified. } UnlockRewardType m_Type; @@ -64,7 +65,8 @@ public: Difficulty m_dc; Course *m_pCourse; - float m_fRequirement[NUM_UnlockRequirement]; + float m_fRequirement[NUM_UnlockRequirement]; // unlocked if any of of these are met + bool m_bRequrePassHardSteps; int m_iEntryID; bool IsValid() const; @@ -102,7 +104,6 @@ public: // Gets number of unlocks for title screen int GetNumUnlocks() const; bool AllAreLocked() const; - int GetUnlockEntryIDToCelebrate() const; int GetUnlockEntryIndexToCelebrate() const; bool AnyUnlocksToCelebrate() const; @@ -110,6 +111,7 @@ public: // Unlock an entry by code. void UnlockEntryID( int iEntryID ); + void UnlockEntryIndex( int iEntryIndex ); /* * If a code is associated with at least one song or course, set the preferred song