diff --git a/stepmania/src/Course.cpp b/stepmania/src/Course.cpp index a887b0f0c7..cd972de784 100644 --- a/stepmania/src/Course.cpp +++ b/stepmania/src/Course.cpp @@ -31,20 +31,20 @@ #include "ProfileManager.h" /* Amount to increase meter ranges to make them difficult: */ -const int DIFFICULT_METER_CHANGE = 2; +const int COURSE_DIFFICULTY_METER_CHANGE[NUM_COURSE_DIFFICULTIES] = { 0, 2 }; /* Maximum lower value of ranges when difficult: */ const int MAX_BOTTOM_RANGE = 10; -/* -1 is the default parameter of a few Course calls; leaving it out indicates - * to use GAMESTATE->m_bDifficultCourses. */ -static bool IsDifficult( int Difficult ) +/* COURSE_DIFFICULTY_INVALID is the default parameter of a few Course calls; + * leaving it out indicates to use GAMESTATE->m_CourseDifficulty. */ +static CourseDifficulty DerefDifficulty( CourseDifficulty d ) { - if( Difficult == -1 ) - return GAMESTATE->m_bDifficultCourses; + if( d == COURSE_DIFFICULTY_INVALID ) + return GAMESTATE->m_CourseDifficulty; else - return !!Difficult; + return d; } Course::Course() @@ -52,7 +52,7 @@ Course::Course() m_bIsAutogen = false; m_bRepeat = false; m_bRandomize = false; - m_bDifficult = false; +// m_bDifficult = false; m_iLives = -1; m_iMeter = -1; } @@ -64,16 +64,16 @@ PlayMode Course::GetPlayMode() const return m_iLives > 0? PLAY_MODE_ONI:PLAY_MODE_NONSTOP; } -const int DifficultMeterRamp = 3; -float Course::GetMeter( int Difficult ) const +const int DifficultMeterRamp[NUM_COURSE_DIFFICULTIES] = { 0, 3 }; +float Course::GetMeter( CourseDifficulty cd ) const { if( m_iMeter != -1 ) - return float(m_iMeter + (IsDifficult(Difficult)? DifficultMeterRamp:0)); + return float(m_iMeter + DifficultMeterRamp[DerefDifficulty(cd)]); /*LOG->Trace( "Course file '%s' contains a song '%s%s%s' that is not present", m_sPath.c_str(), sGroup.c_str(), sGroup.size()? "/":"", sSong.c_str());*/ vector ci; - GetCourseInfo( GAMESTATE->GetCurrentStyleDef()->m_StepsType, ci, Difficult ); + GetCourseInfo( GAMESTATE->GetCurrentStyleDef()->m_StepsType, ci, cd ); if( ci.size() == 0 ) return 0; @@ -465,13 +465,13 @@ void Course::MemCardData::AddHighScore( HighScore hs, int &iIndexOut ) * play that song, even if we're on difficult and harder notes don't exist. (The * exception is a static song entry with a meter range, but that's not very useful.) */ -bool Course::HasDifficult( StepsType nt ) const +bool Course::HasCourseDifficulty( StepsType nt, CourseDifficulty cd ) const { /* Check to see if any songs would change if difficult. */ vector Normal, Hard; - GetCourseInfo( nt, Normal, false ); - GetCourseInfo( nt, Hard, true ); + GetCourseInfo( nt, Normal, COURSE_DIFFICULTY_REGULAR ); + GetCourseInfo( nt, Hard, cd ); if( Normal.size() != Hard.size() ) return true; /* it changed */ @@ -551,9 +551,9 @@ static vector GetFilteredBestSongs( StepsType nt ) /* This is called by many simple functions, like Course::GetTotalSeconds, and may * be called on all songs to sort. It can take time to execute, so we cache the * results. */ -void Course::GetCourseInfo( StepsType nt, vector &ci, int Difficult ) const +void Course::GetCourseInfo( StepsType nt, vector &ci, CourseDifficulty cd ) const { - const InfoParams params( nt, IsDifficult(Difficult) ); + const InfoParams params( nt, DerefDifficulty(cd) ); InfoCache::const_iterator it = m_InfoCache.find( params ); if( it != m_InfoCache.end() ) { @@ -596,7 +596,7 @@ void Course::GetCourseInfo( StepsType nt, vector &ci, int Difficul /* This applies difficult mode for meter ranges. (If it's a difficulty * class, we'll do it below.) */ int low_meter, high_meter; - GetMeterRange( i, low_meter, high_meter, Difficult ); + GetMeterRange( i, low_meter, high_meter, cd ); switch( e.type ) { @@ -690,16 +690,16 @@ void Course::GetCourseInfo( StepsType nt, vector &ci, int Difficul /* If e.difficulty == DIFFICULTY_INVALID, then we already increased difficulty * based on meter. */ - if( IsDifficult(Difficult) && e.difficulty != DIFFICULTY_INVALID ) + if( DerefDifficulty(cd) > COURSE_DIFFICULTY_REGULAR && e.difficulty != DIFFICULTY_INVALID ) { /* See if we can find a NoteData that's one notch more difficult than * the one we found above. */ Difficulty dc = pNotes->GetDifficulty(); - if(dc < DIFFICULTY_CHALLENGE) + Difficulty new_dc = Difficulty(dc + DerefDifficulty(cd)); + if( new_dc < NUM_DIFFICULTIES ) { - dc = Difficulty(dc + 1); - Steps* pNewNotes = pSong->GetStepsByDifficulty( nt, dc, PREFSMAN->m_bAutogenMissingTypes ); - if(pNewNotes) + Steps* pNewNotes = pSong->GetStepsByDifficulty( nt, new_dc, PREFSMAN->m_bAutogenMissingTypes ); + if( pNewNotes ) pNotes = pNewNotes; } } @@ -712,7 +712,7 @@ void Course::GetCourseInfo( StepsType nt, vector &ci, int Difficul cinfo.Random = ( e.type == COURSE_ENTRY_RANDOM || e.type == COURSE_ENTRY_RANDOM_WITHIN_GROUP ); cinfo.Mystery = e.mystery; cinfo.CourseIndex = i; - cinfo.Difficult = IsDifficult(Difficult); + cinfo.CourseDifficulty = DerefDifficulty(cd); ci.push_back( cinfo ); } @@ -791,22 +791,19 @@ bool Course::IsFixed() const Difficulty Course::GetDifficulty( const Info &stage ) const { Difficulty dc = m_entries[stage.CourseIndex].difficulty; - - if( stage.Difficult && dc < DIFFICULTY_CHALLENGE ) - dc = Difficulty(dc + 1); - - return dc; + Difficulty new_dc = Difficulty( dc + stage.CourseDifficulty ); + return (new_dc < NUM_DIFFICULTIES) ? new_dc : dc; } -void Course::GetMeterRange( int stage, int& iMeterLowOut, int& iMeterHighOut, int Difficult ) const +void Course::GetMeterRange( int stage, int& iMeterLowOut, int& iMeterHighOut, CourseDifficulty cd ) const { iMeterLowOut = m_entries[stage].low_meter; iMeterHighOut = m_entries[stage].high_meter; - if( m_entries[stage].difficulty == DIFFICULTY_INVALID && IsDifficult(Difficult) ) + if( m_entries[stage].difficulty == DIFFICULTY_INVALID ) { - iMeterHighOut += DIFFICULT_METER_CHANGE; - iMeterLowOut += DIFFICULT_METER_CHANGE; + iMeterHighOut += COURSE_DIFFICULTY_METER_CHANGE[ DerefDifficulty(cd) ]; + iMeterLowOut += COURSE_DIFFICULTY_METER_CHANGE[ DerefDifficulty(cd) ]; iMeterLowOut = min( iMeterLowOut, MAX_BOTTOM_RANGE ); } } @@ -814,7 +811,7 @@ void Course::GetMeterRange( int stage, int& iMeterLowOut, int& iMeterHighOut, in void Course::GetMeterRange( const Info &stage, int& iMeterLowOut, int& iMeterHighOut ) const { - GetMeterRange( stage.CourseIndex, iMeterLowOut, iMeterHighOut, stage.Difficult ); + GetMeterRange( stage.CourseIndex, iMeterLowOut, iMeterHighOut, stage.CourseDifficulty ); } bool Course::GetTotalSeconds( float& fSecondsOut ) const @@ -1069,7 +1066,7 @@ void SortCoursePointerArrayByAvgDifficulty( vector &apCourses ) RageTimer foo; course_sort_val.clear(); for(unsigned i = 0; i < apCourses.size(); ++i) - course_sort_val[apCourses[i]] = apCourses[i]->GetMeter( false ); + course_sort_val[apCourses[i]] = apCourses[i]->GetMeter( COURSE_DIFFICULTY_REGULAR ); sort( apCourses.begin(), apCourses.end(), CompareCoursePointersByTitle ); stable_sort( apCourses.begin(), apCourses.end(), CompareCoursePointersBySortValueAscending ); diff --git a/stepmania/src/Course.h b/stepmania/src/Course.h index 7dd61e190d..b007cce657 100644 --- a/stepmania/src/Course.h +++ b/stepmania/src/Course.h @@ -89,7 +89,7 @@ public: bool m_bRepeat; // repeat after last song? "Endless" bool m_bRandomize; // play the songs in a random order - bool m_bDifficult; // only make something difficult once +// bool m_bDifficult; // only make something difficult once int m_iLives; // -1 means use bar life meter int m_iMeter; // -1 autogens @@ -97,7 +97,7 @@ public: struct Info { - Info(): pSong(NULL), pNotes(NULL), Random(false), Difficult(false) { } + Info(): pSong(NULL), pNotes(NULL), Random(false), CourseDifficulty(COURSE_DIFFICULTY_INVALID) { } void GetAttackArray( AttackArray &out ) const; Song* pSong; @@ -106,16 +106,16 @@ public: AttackArray Attacks; bool Random; bool Mystery; - bool Difficult; /* set to true if this is the difficult version */ + CourseDifficulty CourseDifficulty; /* Corresponding entry in m_entries: */ int CourseIndex; }; // Dereferences course_entries and returns only the playable Songs and Steps - void GetCourseInfo( StepsType nt, vector &ci, int Difficult = -1 ) const; + void GetCourseInfo( StepsType nt, vector &ci, CourseDifficulty cd = COURSE_DIFFICULTY_INVALID ) const; int GetEstimatedNumStages() const { return m_entries.size(); } - bool HasDifficult( StepsType nt ) const; + bool HasCourseDifficulty( StepsType nt, CourseDifficulty cd ) const; bool IsPlayableIn( StepsType nt ) const; bool CourseHasBestOrWorst() const; RageColor GetColor() const; @@ -127,7 +127,7 @@ public: bool IsOni() const { return GetPlayMode() == PLAY_MODE_ONI; } bool IsEndless() const { return GetPlayMode() == PLAY_MODE_ENDLESS; } PlayMode GetPlayMode() const; - float GetMeter( int Difficult = -1 ) const; + float GetMeter( CourseDifficulty cd = COURSE_DIFFICULTY_INVALID ) const; bool IsFixed() const; @@ -201,9 +201,9 @@ public: void ClearCache(); private: - void GetMeterRange( int stage, int& iMeterLowOut, int& iMeterHighOut, int Difficult = -1 ) const; + void GetMeterRange( int stage, int& iMeterLowOut, int& iMeterHighOut, CourseDifficulty cd = COURSE_DIFFICULTY_INVALID ) const; - typedef pair InfoParams; + typedef pair InfoParams; typedef vector InfoData; typedef map InfoCache; mutable InfoCache m_InfoCache; diff --git a/stepmania/src/GameConstantsAndTypes.cpp b/stepmania/src/GameConstantsAndTypes.cpp index 40e3e2d106..90b087a4be 100644 --- a/stepmania/src/GameConstantsAndTypes.cpp +++ b/stepmania/src/GameConstantsAndTypes.cpp @@ -71,6 +71,27 @@ Difficulty StringToDifficulty( CString sDC ) } +CString CourseDifficultyToString( CourseDifficulty dc ) +{ + switch( dc ) + { + case COURSE_DIFFICULTY_REGULAR: return "regular"; + case COURSE_DIFFICULTY_DIFFICULT: return "difficult"; + default: ASSERT(0); return ""; // invalid Difficulty + } +} + +/* We prefer the above names; recognize a number of others, too. (They'l + * get normalized when written to SMs, etc.) */ +CourseDifficulty StringToCourseDifficulty( CString sDC ) +{ + sDC.MakeLower(); + if( sDC == "regular" ) return COURSE_DIFFICULTY_REGULAR; + else if( sDC == "difficult" ) return COURSE_DIFFICULTY_DIFFICULT; + else return COURSE_DIFFICULTY_INVALID; +} + + CString PlayModeToString( PlayMode pm ) { switch( pm ) diff --git a/stepmania/src/GameConstantsAndTypes.h b/stepmania/src/GameConstantsAndTypes.h index cfcdfa3ea1..f25e8ddfe5 100644 --- a/stepmania/src/GameConstantsAndTypes.h +++ b/stepmania/src/GameConstantsAndTypes.h @@ -74,6 +74,18 @@ CString DifficultyToString( Difficulty dc ); Difficulty StringToDifficulty( CString sDC ); +enum CourseDifficulty +{ + COURSE_DIFFICULTY_REGULAR, + COURSE_DIFFICULTY_DIFFICULT, + NUM_COURSE_DIFFICULTIES, + COURSE_DIFFICULTY_INVALID +}; + +CString CourseDifficultyToString( CourseDifficulty dc ); +CourseDifficulty StringToCourseDifficulty( CString sDC ); + + enum StepsType { STEPS_TYPE_DANCE_SINGLE = 0, diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index a1f4bd6cf8..85ad7feada 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -94,7 +94,7 @@ void GameState::Reset() m_bJukeboxUsesModifiers = false; m_iCurrentStageIndex = 0; m_bAllow2ndExtraStage = true; - m_bDifficultCourses = false; + m_CourseDifficulty = COURSE_DIFFICULTY_REGULAR; m_BeatToNoteSkinRev = 0; NOTESKIN->RefreshNoteSkinData( GAMESTATE->m_CurGame ); diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index ca98fecbf4..e1a1f215af 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -56,7 +56,7 @@ public: int m_iCoins; // not "credits" PlayerNumber m_MasterPlayerNumber; // used in Styles where one player controls both sides bool m_bIsOnSystemMenu; // system screens will not be effected by the operator key -- Miryokuteki - bool m_bDifficultCourses; // used in nonstop + CourseDifficulty m_CourseDifficulty; // used in nonstop time_t m_timeGameStarted; // from the moment the first player pressed Start /* This is set to a random number per-game/round; it can be used for a random seed. */ diff --git a/stepmania/src/ScreenOptionsMaster.cpp b/stepmania/src/ScreenOptionsMaster.cpp index b359be6ca5..a33fc58742 100644 --- a/stepmania/src/ScreenOptionsMaster.cpp +++ b/stepmania/src/ScreenOptionsMaster.cpp @@ -109,9 +109,19 @@ void ScreenOptionsMaster::SetStep( OptionRowData &row, OptionRowHandler &hand ) else if( GAMESTATE->m_pCurCourse ) // playing a course { row.bOneChoiceForAllPlayers = true; - row.choices.push_back( ENTRY_NAME("RegularCourses") ); - if( GAMESTATE->m_pCurCourse->HasDifficult( GAMESTATE->GetCurrentStyleDef()->m_StepsType ) ) - row.choices.push_back( ENTRY_NAME("DifficultCourses") ); + + Course* pCourse = GAMESTATE->m_pCurCourse; + StepsType st = GAMESTATE->GetCurrentStyleDef()->m_StepsType; + for( int d=0; dHasCourseDifficulty(st,cd) ) + { + CString sDifficulty = CourseDifficultyToString( cd ); + sDifficulty = Capitalize( sDifficulty ); + row.choices.push_back( ENTRY_NAME(sDifficulty+"Courses") ); + } + } } else if( GAMESTATE->m_pCurSong ) // playing a song { @@ -354,9 +364,10 @@ void ScreenOptionsMaster::ImportOption( const OptionRowData &row, const OptionRo if( GAMESTATE->m_pCurCourse ) // playing a course { - if( GAMESTATE->m_bDifficultCourses && - GAMESTATE->m_pCurCourse->HasDifficult( GAMESTATE->GetCurrentStyleDef()->m_StepsType ) ) - SelectExactlyOne( 1+(row.bMultiSelect?1:0), vbSelectedOut ); + Course* pCourse = GAMESTATE->m_pCurCourse; + StepsType st = GAMESTATE->GetCurrentStyleDef()->m_StepsType; + if( pCourse->HasCourseDifficulty( st, GAMESTATE->m_CourseDifficulty ) ) + SelectExactlyOne( GAMESTATE->m_CourseDifficulty+(row.bMultiSelect?1:0), vbSelectedOut ); else SelectExactlyOne( 0+(row.bMultiSelect?1:0), vbSelectedOut ); return; @@ -516,17 +527,7 @@ int ScreenOptionsMaster::ExportOption( const OptionRowData &row, const OptionRow } else if( GAMESTATE->m_pCurCourse ) // playing a course { - if( sel == 1 ) - { - GAMESTATE->m_bDifficultCourses = true; - LOG->Trace("ScreenPlayerOptions: Using difficult course"); - } - else - { - GAMESTATE->m_bDifficultCourses = false; - LOG->Trace("ScreenPlayerOptions: Using normal course"); - } - + GAMESTATE->m_CourseDifficulty = (CourseDifficulty)sel; } else if( GAMESTATE->m_pCurSong ) // playing a song { diff --git a/stepmania/src/ScreenSelectCourse.cpp b/stepmania/src/ScreenSelectCourse.cpp index 6d75db3c97..2179ffb22b 100644 --- a/stepmania/src/ScreenSelectCourse.cpp +++ b/stepmania/src/ScreenSelectCourse.cpp @@ -260,18 +260,18 @@ void ScreenSelectCourse::Input( const DeviceInput& DeviceI, InputEventType type, } if( CodeDetector::EnteredEasierDifficulty(GameI.controller) && - GAMESTATE->m_bDifficultCourses) + GAMESTATE->m_CourseDifficulty > 0 ) { m_soundChangeNotes.Play(); - GAMESTATE->m_bDifficultCourses = false; + GAMESTATE->m_CourseDifficulty = (CourseDifficulty)(GAMESTATE->m_CourseDifficulty-1); SCREENMAN->PostMessageToTopScreen(SM_SongChanged,0); } if( CodeDetector::EnteredHarderDifficulty(GameI.controller) && - !GAMESTATE->m_bDifficultCourses) + GAMESTATE->m_CourseDifficulty < NUM_COURSE_DIFFICULTIES-1 ) { m_soundChangeNotes.Play(); - GAMESTATE->m_bDifficultCourses = true; + GAMESTATE->m_CourseDifficulty = (CourseDifficulty)(GAMESTATE->m_CourseDifficulty+1); SCREENMAN->PostMessageToTopScreen(SM_SongChanged,0); } diff --git a/stepmania/src/ScreenSelectMusic.cpp b/stepmania/src/ScreenSelectMusic.cpp index d30d194bc6..9d70e1ef5b 100644 --- a/stepmania/src/ScreenSelectMusic.cpp +++ b/stepmania/src/ScreenSelectMusic.cpp @@ -820,11 +820,14 @@ void ScreenSelectMusic::EasierDifficulty( PlayerNumber pn ) if( !GAMESTATE->IsHumanPlayer(pn) ) return; - if( m_MusicWheel.GetSelectedType() == TYPE_COURSE && GAMESTATE->m_bDifficultCourses ) + if( m_MusicWheel.GetSelectedType() == TYPE_COURSE ) { - m_soundDifficultyEasier.Play(); - GAMESTATE->m_bDifficultCourses = false; - AfterMusicChange(); + if( GAMESTATE->m_CourseDifficulty > 0 ) + { + m_soundDifficultyEasier.Play(); + GAMESTATE->m_CourseDifficulty = (CourseDifficulty)(GAMESTATE->m_CourseDifficulty-1); + AfterMusicChange(); + } return; } @@ -852,11 +855,14 @@ void ScreenSelectMusic::HarderDifficulty( PlayerNumber pn ) if( !GAMESTATE->IsHumanPlayer(pn) ) return; - if( m_MusicWheel.GetSelectedType() == TYPE_COURSE && !GAMESTATE->m_bDifficultCourses ) + if( m_MusicWheel.GetSelectedType() == TYPE_COURSE ) { - m_soundDifficultyHarder.Play(); - GAMESTATE->m_bDifficultCourses = true; - AfterMusicChange(); + if( GAMESTATE->m_CourseDifficulty < NUM_COURSE_DIFFICULTIES-1 ) + { + m_soundDifficultyHarder.Play(); + GAMESTATE->m_CourseDifficulty = (CourseDifficulty)(GAMESTATE->m_CourseDifficulty+1); + AfterMusicChange(); + } return; }