From 82835dae6a92a9789124979f2b1b8561d1df5ebc Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Wed, 3 May 2006 22:56:23 +0000 Subject: [PATCH] change unlock entry IDs to strings so that auto generated entry ids won't shift around and unlock different things when new songs are added --- stepmania/src/GameCommand.cpp | 8 ++-- stepmania/src/GameCommand.h | 6 +-- stepmania/src/Profile.cpp | 24 +++++------ stepmania/src/Profile.h | 4 +- stepmania/src/ScreenUnlockBrowse.cpp | 2 +- stepmania/src/UnlockManager.cpp | 62 ++++++++++++++-------------- stepmania/src/UnlockManager.h | 16 +++---- 7 files changed, 62 insertions(+), 60 deletions(-) diff --git a/stepmania/src/GameCommand.cpp b/stepmania/src/GameCommand.cpp index ee2a93b0af..1c29817b70 100644 --- a/stepmania/src/GameCommand.cpp +++ b/stepmania/src/GameCommand.cpp @@ -44,7 +44,7 @@ void GameCommand::Init() m_pTrail = NULL; m_pCharacter = NULL; m_SortOrder = SORT_INVALID; - m_iUnlockEntryID = -1; + m_sUnlockEntryID = ""; m_sSoundPath = ""; m_vsScreensToPrepare.clear(); m_iWeightPounds = -1; @@ -336,7 +336,7 @@ void GameCommand::LoadOne( const Command& cmd ) else if( sName == "unlock" ) { - m_iUnlockEntryID = atoi( sValue ); + m_sUnlockEntryID = sValue; } else if( sName == "sound" ) @@ -687,8 +687,8 @@ void GameCommand::ApplySelf( const vector &vpns ) const GAMESTATE->m_sPreferredSongGroup.Set( m_sSongGroup ); if( m_SortOrder != SORT_INVALID ) GAMESTATE->m_PreferredSortOrder = m_SortOrder; - if( m_iUnlockEntryID != -1 ) - UNLOCKMAN->UnlockEntryID( m_iUnlockEntryID ); + if( !m_sUnlockEntryID.empty() ) + UNLOCKMAN->UnlockEntryID( m_sUnlockEntryID ); if( m_sSoundPath != "" ) SOUND->PlayOnce( THEME->GetPathS( "", m_sSoundPath ) ); if( m_iWeightPounds != -1 ) diff --git a/stepmania/src/GameCommand.h b/stepmania/src/GameCommand.h index 981a46b839..f7a7bd558d 100644 --- a/stepmania/src/GameCommand.h +++ b/stepmania/src/GameCommand.h @@ -71,11 +71,11 @@ public: std::map m_SetEnv; RString m_sSongGroup; SortOrder m_SortOrder; - int m_iUnlockEntryID; // -1 for no unlock + RString m_sUnlockEntryID; // "" for no unlock RString m_sSoundPath; // "" for no sound vector m_vsScreensToPrepare; - int m_iWeightPounds; // -1 == none specified - int m_iGoalCalories; // -1 == none specified + int m_iWeightPounds; // -1 == none specified + int m_iGoalCalories; // -1 == none specified GoalType m_GoalType; RString m_sProfileID; diff --git a/stepmania/src/Profile.cpp b/stepmania/src/Profile.cpp index eea5d59f69..aa71a8c615 100644 --- a/stepmania/src/Profile.cpp +++ b/stepmania/src/Profile.cpp @@ -514,9 +514,9 @@ void Profile::SetDefaultModifiers( const Game* pGameType, const RString &sModifi m_sDefaultModifiers[pGameType->m_szName] = sModifiers; } -bool Profile::IsCodeUnlocked( int iCode ) const +bool Profile::IsCodeUnlocked( RString sUnlockEntryID ) const { - return m_UnlockedEntryIDs.find( iCode ) != m_UnlockedEntryIDs.end(); + return m_UnlockedEntryIDs.find( sUnlockEntryID ) != m_UnlockedEntryIDs.end(); } @@ -1037,9 +1037,9 @@ XNode* Profile::SaveGeneralDataCreateNode() const } { - XNode* pUnlockedSongs = pGeneralDataNode->AppendChild("UnlockedSongs"); - FOREACHS_CONST( int, m_UnlockedEntryIDs, it ) - pUnlockedSongs->AppendChild( ssprintf("Unlock%i", *it) ); + XNode* pUnlocks = pGeneralDataNode->AppendChild("Unlocks"); + FOREACHS_CONST( RString, m_UnlockedEntryIDs, it ) + pUnlocks->AppendChild("UnlockEntry")->AppendAttr( "UnlockEntryID", it->c_str() ); } { @@ -1216,14 +1216,14 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode ) } { - const XNode* pUnlockedSongs = pNode->GetChild("UnlockedSongs"); - if( pUnlockedSongs ) + const XNode* pUnlocks = pNode->GetChild("Unlocks"); + if( pUnlocks ) { - FOREACH_CONST_Child( pUnlockedSongs, song ) + FOREACH_CONST_Child( pUnlocks, unlock ) { - int iUnlock; - if( sscanf(song->m_sName.c_str(),"Unlock%d",&iUnlock) == 1 ) - m_UnlockedEntryIDs.insert( iUnlock ); + RString sUnlockEntryID; + if( unlock->GetAttrValue("UnlockEntryID",sUnlockEntryID) ) + m_UnlockedEntryIDs.insert( sUnlockEntryID ); } } } @@ -1941,7 +1941,7 @@ public: static int GetCaloriesBurnedToday( T* p, lua_State *L ) { lua_pushnumber(L, p->GetCaloriesBurnedToday() ); return 1; } static int GetSaved( T* p, lua_State *L ) { p->m_SavedLuaData.PushSelf(L); return 1; } static int GetTotalNumSongsPlayed( T* p, lua_State *L ) { lua_pushnumber(L, p->m_iNumTotalSongsPlayed ); return 1; } - static int IsCodeUnlocked( T* p, lua_State *L ) { lua_pushboolean(L, p->IsCodeUnlocked(IArg(1)) ); return 1; } + static int IsCodeUnlocked( T* p, lua_State *L ) { lua_pushboolean(L, p->IsCodeUnlocked(SArg(1)) ); return 1; } static int GetSongsActual( T* p, lua_State *L ) { lua_pushnumber(L, p->GetSongsActual((StepsType)IArg(1),(Difficulty)IArg(2)) ); return 1; } static int GetCoursesActual( T* p, lua_State *L ) { lua_pushnumber(L, p->GetCoursesActual((StepsType)IArg(1),(CourseDifficulty)IArg(2)) ); return 1; } static int GetSongsPossible( T* p, lua_State *L ) { lua_pushnumber(L, p->GetSongsPossible((StepsType)IArg(1),(Difficulty)IArg(2)) ); return 1; } diff --git a/stepmania/src/Profile.h b/stepmania/src/Profile.h index ebf9616c3e..bac7286561 100644 --- a/stepmania/src/Profile.h +++ b/stepmania/src/Profile.h @@ -86,7 +86,7 @@ public: float GetSongsAndCoursesPercentCompleteAllDifficulties( StepsType st ) const; bool GetDefaultModifiers( const Game* pGameType, RString &sModifiersOut ) const; void SetDefaultModifiers( const Game* pGameType, const RString &sModifiers ); - bool IsCodeUnlocked( int iCode ) const; + bool IsCodeUnlocked( RString sUnlockEntryID ) const; Song *GetMostPopularSong() const; Course *GetMostPopularCourse() const; @@ -132,7 +132,7 @@ public: int m_iTotalRolls; int m_iTotalMines; int m_iTotalHands; - set m_UnlockedEntryIDs; + set m_UnlockedEntryIDs; mutable RString m_sLastPlayedMachineGuid; // mutable because we overwrite this on save, and I don't want to remove const from the whole save chain. -Chris mutable DateTime m_LastPlayedDate; /* These stats count twice in the machine profile if two players are playing; diff --git a/stepmania/src/ScreenUnlockBrowse.cpp b/stepmania/src/ScreenUnlockBrowse.cpp index d063eacf4d..3ce17eb203 100644 --- a/stepmania/src/ScreenUnlockBrowse.cpp +++ b/stepmania/src/ScreenUnlockBrowse.cpp @@ -14,7 +14,7 @@ void ScreenUnlockBrowse::Init() if( ue->GetUnlockEntryStatus() >= UnlockEntryStatus_RequirementsMet ) gc.m_bInvalid = false; gc.m_iIndex = ue - UNLOCKMAN->m_UnlockEntries.begin(); - gc.m_iUnlockEntryID = ue->m_iEntryID; + gc.m_sUnlockEntryID = ue->m_sEntryID; gc.m_sName = ssprintf("%d",gc.m_iIndex); m_aGameCommands.push_back( gc ); diff --git a/stepmania/src/UnlockManager.cpp b/stepmania/src/UnlockManager.cpp index 589725c1dc..e5aa099a94 100644 --- a/stepmania/src/UnlockManager.cpp +++ b/stepmania/src/UnlockManager.cpp @@ -60,13 +60,13 @@ void UnlockManager::UnlockSong( const Song *song ) const UnlockEntry *p = FindSong( song ); if( !p ) return; // does not exist - if( p->m_iEntryID == -1 ) + if( p->m_sEntryID.empty() ) return; - UnlockEntryID( p->m_iEntryID ); + UnlockEntryID( p->m_sEntryID ); } -int UnlockManager::FindEntryID( const RString &sName ) const +RString UnlockManager::FindEntryID( const RString &sName ) const { const UnlockEntry *pEntry = NULL; @@ -84,10 +84,10 @@ int UnlockManager::FindEntryID( const RString &sName ) const if( pEntry == NULL ) { LOG->Warn( "Couldn't find locked entry \"%s\"", sName.c_str() ); - return -1; + return ""; } - return pEntry->m_iEntryID; + return pEntry->m_sEntryID; } bool UnlockManager::CourseIsLocked( const Course *course ) const @@ -125,7 +125,7 @@ bool UnlockManager::SongIsRouletteOnly( const Song *song ) const return false; /* If the song is locked by a code, and it's a roulette code, honor IsLocked. */ - if( p->m_iEntryID == -1 || m_RouletteCodes.find( p->m_iEntryID ) == m_RouletteCodes.end() ) + if( p->m_sEntryID.empty() || m_RouletteCodes.find( p->m_sEntryID ) == m_RouletteCodes.end() ) return false; return p->IsLocked(); @@ -294,7 +294,7 @@ bool UnlockEntry::IsValid() const UnlockEntryStatus UnlockEntry::GetUnlockEntryStatus() const { - if( m_iEntryID != -1 && PROFILEMAN->GetMachineProfile()->m_UnlockedEntryIDs.find(m_iEntryID) != PROFILEMAN->GetMachineProfile()->m_UnlockedEntryIDs.end() ) + if( !m_sEntryID.empty() && PROFILEMAN->GetMachineProfile()->m_UnlockedEntryIDs.find(m_sEntryID) != PROFILEMAN->GetMachineProfile()->m_UnlockedEntryIDs.end() ) return UnlockEntryStatus_Unlocked; float fScores[NUM_UnlockRequirement]; @@ -336,7 +336,7 @@ RString UnlockEntry::GetDescription() const return m_pCourse ? m_pCourse->GetDisplayFullTitle() : ""; case UnlockRewardType_Modifier: return CommonMetrics::LocalizeOptionItem( GetModifier(), false ); - } + } } RString UnlockEntry::GetBannerFile() const @@ -425,7 +425,7 @@ void UnlockManager::Load() // Hack: Lua only has a floating point type, and codes may be big enough // that converting them from string to float to int introduces rounding // error. Convert directly to int. - current.m_iEntryID = atoi( (RString) cmd.GetArg(1) ); + current.m_sEntryID = (RString)cmd.GetArg(1); } else if( sName == "roulette" ) { @@ -444,7 +444,7 @@ void UnlockManager::Load() } if( bRoulette ) - m_RouletteCodes.insert( current.m_iEntryID ); + m_RouletteCodes.insert( current.m_sEntryID ); m_UnlockEntries.push_back( current ); } @@ -455,6 +455,8 @@ void UnlockManager::Load() { if( (*s)->GetOneSteps(STEPS_TYPE_INVALID, DIFFICULTY_HARD) == NULL ) continue; + if( SONGMAN->WasLoadedFromAdditionalSongs(*s) ) + continue; UnlockEntry ue; ue.m_Type = UnlockRewardType_Steps; @@ -470,8 +472,8 @@ void UnlockManager::Load() // FOREACH( UnlockEntry, m_UnlockEntries, e ) { - if( e->m_iEntryID == -1 ) - e->m_iEntryID = e - m_UnlockEntries.begin(); + if( e->m_sEntryID.empty() ) + e->m_sEntryID = e->m_cmd.GetOriginalCommandString(); } // Make sure that we don't have duplicate unlock IDs. This can cause problems @@ -479,7 +481,7 @@ void UnlockManager::Load() 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) ); + ASSERT_M( ue->m_sEntryID != ue2->m_sEntryID, ssprintf("duplicate unlock entry id %s",ue->m_sEntryID.c_str()) ); UpdateCachedPointers(); @@ -495,7 +497,7 @@ void UnlockManager::Load() if( e->m_bRequirePassHardSteps ) str += "RequrePassHardSteps; "; - str += ssprintf( "entryID = %i ", e->m_iEntryID ); + str += ssprintf( "entryID = %s ", e->m_sEntryID.c_str() ); str += e->IsLocked()? "locked":"unlocked"; if( e->m_pSong ) str += ( " (found song)" ); @@ -577,27 +579,27 @@ void UnlockManager::UpdateCachedPointers() -void UnlockManager::UnlockEntryID( int iEntryID ) +void UnlockManager::UnlockEntryID( RString sEntryID ) { FOREACH_PlayerNumber( pn ) if( PROFILEMAN->IsPersistentProfile(pn) ) - PROFILEMAN->GetProfile(pn)->m_UnlockedEntryIDs.insert( iEntryID ); + PROFILEMAN->GetProfile(pn)->m_UnlockedEntryIDs.insert( sEntryID ); - PROFILEMAN->GetMachineProfile()->m_UnlockedEntryIDs.insert( iEntryID ); + PROFILEMAN->GetMachineProfile()->m_UnlockedEntryIDs.insert( sEntryID ); } void UnlockManager::UnlockEntryIndex( int iEntryIndex ) { - int iEntryID = m_UnlockEntries[iEntryIndex].m_iEntryID; - UnlockEntryID( iEntryID ); + RString sEntryID = m_UnlockEntries[iEntryIndex].m_sEntryID; + UnlockEntryID( sEntryID ); } -void UnlockManager::PreferUnlockEntryID( int iUnlockEntryID ) +void UnlockManager::PreferUnlockEntryID( RString sUnlockEntryID ) { for( unsigned i = 0; i < m_UnlockEntries.size(); ++i ) { UnlockEntry &pEntry = m_UnlockEntries[i]; - if( pEntry.m_iEntryID != iUnlockEntryID ) + if( pEntry.m_sEntryID != sUnlockEntryID ) continue; if( pEntry.m_pSong != NULL ) @@ -645,24 +647,24 @@ void UnlockManager::GetUnlocksByType( UnlockRewardType t, vector apEntries.push_back( &m_UnlockEntries[i] ); } -void UnlockManager::GetSongsUnlockedByEntryID( vector &apSongsOut, int iUnlockEntryID ) +void UnlockManager::GetSongsUnlockedByEntryID( vector &apSongsOut, RString sUnlockEntryID ) { vector apEntries; GetUnlocksByType( UnlockRewardType_Song, apEntries ); for( unsigned i = 0; i < apEntries.size(); ++i ) - if( apEntries[i]->m_iEntryID == iUnlockEntryID ) + if( apEntries[i]->m_sEntryID == sUnlockEntryID ) apSongsOut.push_back( apEntries[i]->m_pSong ); } -void UnlockManager::GetStepsUnlockedByEntryID( vector &apSongsOut, vector &apDifficultyOut, int iUnlockEntryID ) +void UnlockManager::GetStepsUnlockedByEntryID( vector &apSongsOut, vector &apDifficultyOut, RString sUnlockEntryID ) { vector apEntries; GetUnlocksByType( UnlockRewardType_Steps, apEntries ); for( unsigned i = 0; i < apEntries.size(); ++i ) { - if( apEntries[i]->m_iEntryID == iUnlockEntryID ) + if( apEntries[i]->m_sEntryID == sUnlockEntryID ) { apSongsOut.push_back( apEntries[i]->m_pSong ); apDifficultyOut.push_back( apEntries[i]->m_dc ); @@ -704,10 +706,10 @@ class LunaUnlockManager: public Luna public: LunaUnlockManager() { LUA->Register( Register ); } - static int FindEntryID( T* p, lua_State *L ) { RString sName = SArg(1); int i = p->FindEntryID(sName); if( i == -1 ) lua_pushnil(L); else lua_pushnumber(L, i); return 1; } - static int UnlockEntryID( T* p, lua_State *L ) { int iUnlockEntryID = IArg(1); p->UnlockEntryID(iUnlockEntryID); return 0; } + static int FindEntryID( T* p, lua_State *L ) { RString sName = SArg(1); RString s = p->FindEntryID(sName); if( s.empty() ) lua_pushnil(L); else lua_pushstring(L, s); return 1; } + static int UnlockEntryID( T* p, lua_State *L ) { RString sUnlockEntryID = SArg(1); p->UnlockEntryID(sUnlockEntryID); return 0; } static int UnlockEntryIndex( T* p, lua_State *L ) { int iUnlockEntryID = IArg(1); p->UnlockEntryIndex(iUnlockEntryID); return 0; } - static int PreferUnlockEntryID( T* p, lua_State *L ) { int iUnlockEntryID = IArg(1); p->PreferUnlockEntryID(iUnlockEntryID); return 0; } + static int PreferUnlockEntryID( T* p, lua_State *L ) { RString sUnlockEntryID = SArg(1); p->PreferUnlockEntryID(sUnlockEntryID); return 0; } static int GetNumUnlocks( T* p, lua_State *L ) { lua_pushnumber( L, p->GetNumUnlocks() ); return 1; } static int GetNumUnlocked( T* p, lua_State *L ) { lua_pushnumber( L, p->GetNumUnlocked() ); return 1; } static int AnyUnlocksToCelebrate( T* p, lua_State *L ) { lua_pushboolean( L, p->AnyUnlocksToCelebrate() ); return 1; } @@ -715,7 +717,7 @@ public: static int GetSongsUnlockedByEntryID( T* p, lua_State *L ) { vector apSongs; - UNLOCKMAN->GetSongsUnlockedByEntryID( apSongs, IArg(1) ); + UNLOCKMAN->GetSongsUnlockedByEntryID( apSongs, SArg(1) ); LuaHelpers::CreateTableFromArray( apSongs, L ); return 1; } @@ -725,7 +727,7 @@ public: // Return the song each steps are associated with, too. vector apSongs; vector apDifficulty; - UNLOCKMAN->GetStepsUnlockedByEntryID( apSongs, apDifficulty, IArg(1) ); + UNLOCKMAN->GetStepsUnlockedByEntryID( apSongs, apDifficulty, SArg(1) ); LuaHelpers::CreateTableFromArray( apSongs, L ); LuaHelpers::CreateTableFromArray( apDifficulty, L ); return 2; diff --git a/stepmania/src/UnlockManager.h b/stepmania/src/UnlockManager.h index 8bd0084cff..de310a9dfe 100644 --- a/stepmania/src/UnlockManager.h +++ b/stepmania/src/UnlockManager.h @@ -58,7 +58,7 @@ public: ZERO( m_fRequirement ); m_bRequirePassHardSteps = false; - m_iEntryID = -1; // -1 == not yet filled. This will be filled in automatically if not specified. + m_sEntryID = ""; // "" means not yet filled. This will be filled in automatically if not specified. } UnlockRewardType m_Type; @@ -72,7 +72,7 @@ public: float m_fRequirement[NUM_UnlockRequirement]; // unlocked if any of of these are met bool m_bRequirePassHardSteps; - int m_iEntryID; + RString m_sEntryID; bool IsValid() const; bool IsLocked() const { return GetUnlockEntryStatus() != UnlockEntryStatus_Unlocked; } @@ -117,20 +117,20 @@ public: void GetPoints( const Profile *pProfile, float fScores[NUM_UnlockRequirement] ) const; // Unlock an entry by code. - void UnlockEntryID( int iEntryID ); + void UnlockEntryID( RString sEntryID ); void UnlockEntryIndex( int iEntryIndex ); /* * If a code is associated with at least one song or course, set the preferred song * and/or course in GAMESTATE to them. */ - void PreferUnlockEntryID( int iEntryID ); + void PreferUnlockEntryID( RString sEntryID ); // Unlocks a song. void UnlockSong( const Song *pSong ); // Return the associated EntryID. - int FindEntryID( const RString &sName ) const; + RString FindEntryID( const RString &sName ) const; // All locked songs are stored here vector m_UnlockEntries; @@ -139,8 +139,8 @@ public: void UpdateCachedPointers(); void GetUnlocksByType( UnlockRewardType t, vector &apEntries ); - void GetSongsUnlockedByEntryID( vector &apSongsOut, int iEntryID ); - void GetStepsUnlockedByEntryID( vector &apSongsOut, vector &apStepsOut, int iEntryID ); + void GetSongsUnlockedByEntryID( vector &apSongsOut, RString sEntryID ); + void GetStepsUnlockedByEntryID( vector &apSongsOut, vector &apStepsOut, RString sEntryID ); const UnlockEntry *FindSong( const Song *pSong ) const; const UnlockEntry *FindSteps( const Song *pSong, const Steps *pSteps ) const; @@ -154,7 +154,7 @@ private: // read unlocks void Load(); - set m_RouletteCodes; // "codes" which are available in roulette and which unlock if rouletted + set m_RouletteCodes; // "codes" which are available in roulette and which unlock if rouletted }; extern UnlockManager* UNLOCKMAN; // global and accessable from anywhere in program