void StepsUtil::SortStepsPointerArrayByNumPlays( vector<Steps*> &vStepsPointers, const Profile* pProfile, bool bDecending ) { // ugly... vector<Song*> vpSongs = SONGMAN->GetAllSongs(); vector<Steps*> vpAllSteps; map<Steps*,Song*> mapStepsToSong; { for( unsigned i=0; i<vpSongs.size(); i++ ) { Song* pSong = vpSongs[i]; vector<Steps*> vpSteps = pSong->GetAllSteps(); for( unsigned j=0; j<vpSteps.size(); j++ ) { Steps* pSteps = vpSteps[j]; if( pSteps->IsAutogen() ) continue; // skip vpAllSteps.push_back( pSteps ); mapStepsToSong[pSteps] = pSong; } } } ASSERT( pProfile != NULL ); for(unsigned i = 0; i < vStepsPointers.size(); ++i) { Steps* pSteps = vStepsPointers[i]; Song* pSong = mapStepsToSong[pSteps]; steps_sort_val[vStepsPointers[i]] = ssprintf("%9i", pProfile->GetStepsNumTimesPlayed(pSong,pSteps)); } stable_sort( vStepsPointers.begin(), vStepsPointers.end(), bDecending ? CompareStepsPointersBySortValueDescending : CompareStepsPointersBySortValueAscending ); steps_sort_val.clear(); }
Steps* SongUtil::GetStepsByDifficulty( const Song *pSong, StepsType st, Difficulty dc, bool bIncludeAutoGen ) { const vector<Steps*>& vpSteps = (st == StepsType_Invalid)? pSong->GetAllSteps() : pSong->GetStepsByStepsType(st); for( unsigned i=0; i<vpSteps.size(); i++ ) // for each of the Song's Steps { Steps* pSteps = vpSteps[i]; if( dc != Difficulty_Invalid && dc != pSteps->GetDifficulty() ) continue; if( !bIncludeAutoGen && pSteps->IsAutogen() ) continue; return pSteps; } return NULL; }
void SongUtil::GetSteps( const Song *pSong, vector<Steps*>& arrayAddTo, StepsType st, Difficulty dc, int iMeterLow, int iMeterHigh, const RString &sDescription, bool bIncludeAutoGen, unsigned uHash, int iMaxToGet ) { if( !iMaxToGet ) return; const vector<Steps*> &vpSteps = st == StepsType_Invalid ? pSong->GetAllSteps() : pSong->GetStepsByStepsType(st); for( unsigned i=0; i<vpSteps.size(); i++ ) // for each of the Song's Steps { Steps* pSteps = vpSteps[i]; if( dc != Difficulty_Invalid && dc != pSteps->GetDifficulty() ) continue; if( iMeterLow != -1 && iMeterLow > pSteps->GetMeter() ) continue; if( iMeterHigh != -1 && iMeterHigh < pSteps->GetMeter() ) continue; if( sDescription.size() && sDescription != pSteps->GetDescription() ) continue; if( uHash != 0 && uHash != pSteps->GetHash() ) continue; if( !bIncludeAutoGen && pSteps->IsAutogen() ) continue; arrayAddTo.push_back( pSteps ); if( iMaxToGet != -1 ) { --iMaxToGet; if( !iMaxToGet ) break; } } }
void ScreenJukebox::SetSong() { ThemeMetric<bool> ALLOW_ADVANCED_MODIFIERS(m_sName,"AllowAdvancedModifiers"); vector<Song*> vSongs; /* Check to see if there is a theme course. If there is a course that has * the exact same name as the theme, then we pick a song from this course. */ Course *pCourse = SONGMAN->GetCourseFromName( THEME->GetCurThemeName() ); if( pCourse != NULL ) for ( unsigned i = 0; i < pCourse->m_vEntries.size(); i++ ) if( pCourse->m_vEntries[i].IsFixedSong() ) vSongs.push_back( pCourse->m_vEntries[i].songID.ToSong() ); if ( vSongs.size() == 0 ) vSongs = SONGMAN->GetSongs( GAMESTATE->m_sPreferredSongGroup ); // Still nothing? if( vSongs.size() == 0 ) return; // Calculate what difficulties to show vector<Difficulty> vDifficultiesToShow; if( m_bDemonstration ) { // HACK: This belongs in ScreenDemonstration. ThemeMetricDifficultiesToShow DIFFICULTIES_TO_SHOW_HERE(m_sName,"DifficultiesToShow"); vDifficultiesToShow = DIFFICULTIES_TO_SHOW_HERE.GetValue(); } else { if( GAMESTATE->m_PreferredDifficulty[PLAYER_1] != Difficulty_Invalid ) { vDifficultiesToShow.push_back( GAMESTATE->m_PreferredDifficulty[PLAYER_1] ); } else { FOREACH_ENUM( Difficulty, dc ) vDifficultiesToShow.push_back( dc ); } } ASSERT( !vDifficultiesToShow.empty() ); // Search for a Song and Steps to play during the demo. for( int i=0; i<1000; i++ ) { Song* pSong = vSongs[RandomInt(vSongs.size())]; ASSERT( pSong != NULL ); if( !pSong->HasMusic() ) continue; // skip if( !pSong->NormallyDisplayed() ) continue; if( !pSong->ShowInDemonstrationAndRanking() ) continue; // skip Difficulty dc = vDifficultiesToShow[ RandomInt(vDifficultiesToShow.size()) ]; Steps* pSteps = SongUtil::GetStepsByDifficulty( pSong, GAMESTATE->GetCurrentStyle()->m_StepsType, dc ); if( pSteps == NULL ) continue; // skip if( !PREFSMAN->m_bAutogenSteps && pSteps->IsAutogen()) continue; // skip // Found something we can use! GAMESTATE->m_pCurSong.Set( pSong ); // We just changed the song. Reset the original sync data. AdjustSync::ResetOriginalSyncData(); FOREACH_PlayerNumber( p ) GAMESTATE->m_pCurSteps[p].Set( pSteps ); bool bShowModifiers = randomf(0,1) <= SHOW_COURSE_MODIFIERS_PROBABILITY; if( bShowModifiers ) { /* If we have a modifier course containing this song, apply its * modifiers. Only check fixed course entries. */ vector<Course*> apCourses; SONGMAN->GetAllCourses( apCourses, false ); vector<const CourseEntry *> apOptions; vector<Course*> apPossibleCourses; for( unsigned j = 0; j < apCourses.size(); ++j ) { Course *lCourse = apCourses[j]; const CourseEntry *pEntry = lCourse->FindFixedSong( pSong ); if( pEntry == NULL || pEntry->attacks.size() == 0 ) continue; if( !ALLOW_ADVANCED_MODIFIERS ) { // There are some confusing mods that we don't want to show in demonstration. bool bModsAreOkToShow = true; AttackArray aAttacks = pEntry->attacks; if( !pEntry->sModifiers.empty() ) aAttacks.push_back( Attack::FromGlobalCourseModifier( pEntry->sModifiers ) ); FOREACH_CONST( Attack, aAttacks, a ) { RString s = a->sModifiers; s.MakeLower(); // todo: allow themers to modify this list? -aj if( s.find("dark") != string::npos || s.find("stealth") != string::npos ) { bModsAreOkToShow = false; break; } } if( !bModsAreOkToShow ) continue; // skip } apOptions.push_back( pEntry ); apPossibleCourses.push_back( pCourse ); } if( !apOptions.empty() ) { int iIndex = RandomInt( apOptions.size() ); m_pCourseEntry = apOptions[iIndex]; Course *lCourse = apPossibleCourses[iIndex]; PlayMode pm = CourseTypeToPlayMode( lCourse->GetCourseType() ); GAMESTATE->m_PlayMode.Set( pm ); GAMESTATE->m_pCurCourse.Set( lCourse ); FOREACH_PlayerNumber( p ) { GAMESTATE->m_pCurTrail[p].Set( lCourse->GetTrail( GAMESTATE->GetCurrentStyle()->m_StepsType ) ); ASSERT( GAMESTATE->m_pCurTrail[p] != NULL ); } }
void ScreenJukebox::SetSong() { ThemeMetric<bool> ALLOW_ADVANCED_MODIFIERS(m_sName,"AllowAdvancedModifiers"); vector<Song*> vSongs; //Check to see if there is a theme-course //I.E. If there is a course called exactly the theme name, //then we pick a song from this course. Course *pCourse = SONGMAN->GetCourseFromName( THEME->GetCurThemeName() ); if( pCourse != NULL ) for ( unsigned i = 0; i < pCourse->m_entries.size(); i++ ) vSongs.push_back( pCourse->m_entries[i].pSong ); if ( vSongs.size() == 0 ) SONGMAN->GetSongs( vSongs, GAMESTATE->m_sPreferredSongGroup ); // // Calculate what difficulties to show // vector<Difficulty> vDifficultiesToShow; if( m_bDemonstration ) { // HACK: This belongs in ScreenDemonstration ThemeMetricDifficultiesToShow DIFFICULTIES_TO_SHOW_HERE(m_sName,"DifficultiesToShow"); vDifficultiesToShow = DIFFICULTIES_TO_SHOW_HERE.GetValue(); } else { if( GAMESTATE->m_PreferredDifficulty[PLAYER_1] != DIFFICULTY_INVALID ) { vDifficultiesToShow.push_back( GAMESTATE->m_PreferredDifficulty[PLAYER_1] ); } else { FOREACH_Difficulty( dc ) vDifficultiesToShow.push_back( dc ); } } ASSERT( !vDifficultiesToShow.empty() ) // // Search for a Song and Steps to play during the demo // for( int i=0; i<1000; i++ ) { if( vSongs.size() == 0 ) return; Song* pSong = vSongs[rand()%vSongs.size()]; if( !pSong->HasMusic() ) continue; // skip if( UNLOCKMAN->SongIsLocked(pSong) ) continue; if( !pSong->ShowInDemonstrationAndRanking() ) continue; // skip Difficulty dc = vDifficultiesToShow[ rand()%vDifficultiesToShow.size() ]; Steps* pSteps = pSong->GetStepsByDifficulty( GAMESTATE->GetCurrentStyle()->m_StepsType, dc ); if( pSteps == NULL ) continue; // skip if( !PREFSMAN->m_bAutogenSteps && pSteps->IsAutogen()) continue; // skip // Found something we can use! GAMESTATE->m_pCurSong.Set( pSong ); // We just changed the song. Reset the original sync data. GAMESTATE->ResetOriginalSyncData(); FOREACH_PlayerNumber( p ) GAMESTATE->m_pCurSteps[p].Set( pSteps ); bool bShowModifiers = randomf(0,1) <= SHOW_COURSE_MODIFIERS_PROBABILITY; if( bShowModifiers ) { /* If we have a modifier course containing this song, apply its modifiers. Only check * fixed course entries. */ vector<Course*> apCourses; SONGMAN->GetAllCourses( apCourses, false ); vector<const CourseEntry *> apOptions; vector<Course*> apPossibleCourses; for( unsigned i = 0; i < apCourses.size(); ++i ) { Course *pCourse = apCourses[i]; const CourseEntry *pEntry = pCourse->FindFixedSong( pSong ); if( pEntry == NULL || pEntry->attacks.size() == 0 ) continue; if( !ALLOW_ADVANCED_MODIFIERS ) { // There are some confusing mods that we don't want to show in demonstration. bool bModsAreOkToShow = true; AttackArray aAttacks = pEntry->attacks; if( !pEntry->modifiers.empty() ) aAttacks.push_back( Attack::FromGlobalCourseModifier( pEntry->modifiers ) ); FOREACH_CONST( Attack, aAttacks, a ) { CString s = a->sModifiers; s.MakeLower(); if( s.find("dark") != CString::npos || s.find("stealth") != CString::npos ) { bModsAreOkToShow = false; break; } } if( !bModsAreOkToShow ) continue; // skip } apOptions.push_back( pEntry ); apPossibleCourses.push_back( pCourse ); } if( !apOptions.empty() ) { int iIndex = rand()%apOptions.size(); m_pCourseEntry = apOptions[iIndex]; Course *pCourse = apPossibleCourses[iIndex]; GAMESTATE->m_PlayMode = CourseTypeToPlayMode( pCourse->GetCourseType() ); GAMESTATE->m_pCurCourse.Set( pCourse ); FOREACH_PlayerNumber( p ) { GAMESTATE->m_pCurTrail[p].Set( pCourse->GetTrail( GAMESTATE->GetCurrentStyle()->m_StepsType ) ); ASSERT( GAMESTATE->m_pCurTrail[p] ); } }