diff --git a/stepmania/src/ScoreKeeperMAX2.cpp b/stepmania/src/ScoreKeeperMAX2.cpp index d695c4e36d..7547149fb2 100644 --- a/stepmania/src/ScoreKeeperMAX2.cpp +++ b/stepmania/src/ScoreKeeperMAX2.cpp @@ -21,9 +21,10 @@ #include "UnlockSystem.h" #include "SDL_utils.h" #include "SongManager.h" +#include "NoteDataUtil.h" -ScoreKeeperMAX2::ScoreKeeperMAX2( const vector& apNotes_, PlayerNumber pn_ ): +ScoreKeeperMAX2::ScoreKeeperMAX2( const vector& apNotes_, const CStringArray &asModifiers, PlayerNumber pn_ ): ScoreKeeper(pn_), apNotes(apNotes_) { // @@ -36,11 +37,27 @@ ScoreKeeperMAX2::ScoreKeeperMAX2( const vector& apNotes_, PlayerNumber p NoteData notedata; pSteps->GetNoteData( ¬edata ); + /* We might have been given lots of songs; don't keep them in memory uncompressed. */ + pSteps->Compress(); + const StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef(); NoteData playerNoteData; pStyleDef->GetTransformedNoteDataForStyle( pn_, ¬edata, &playerNoteData ); - iTotalPossibleDancePoints += this->GetPossibleDancePoints( ¬edata ); + /* Apply transforms to find out how the notes will really look. + * + * XXX: This is brittle: if we end up combining mods for a song differently + * than ScreenGameplay, we'll end up with the wrong data. We should probably + * have eg. GAMESTATE->GetOptionsForCourse(po,so,pn) to get options based on + * the last call to StoreSelectedOptions and the modifiers list, but that'd + * mean moving the queues in ScreenGameplay to GameState ... */ + PlayerOptions ModsForThisSong( GAMESTATE->m_PlayerOptions[pn_] ); + ModsForThisSong.FromString( asModifiers[i] ); + + NoteData playerNoteDataPostModifiers(playerNoteData); + NoteDataUtil::TransformNoteData( playerNoteData, ModsForThisSong, GAMESTATE->GetCurrentStyleDef()->m_StepsType ); + + iTotalPossibleDancePoints += this->GetPossibleDancePoints( playerNoteData, playerNoteDataPostModifiers ); } GAMESTATE->m_CurStageStats.iPossibleDancePoints[pn_] = iTotalPossibleDancePoints; @@ -411,12 +428,19 @@ void ScoreKeeperMAX2::HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tap } -int ScoreKeeperMAX2::GetPossibleDancePoints( const NoteData* pNoteData ) +int ScoreKeeperMAX2::GetPossibleDancePoints( const NoteData &preNoteData, const NoteData &postNoteData ) { /* Note that, if Marvelous timing is disabled or not active (not course mode), * PERFECT will be used instead. */ - return pNoteData->GetNumRowsWithTaps()*TapNoteScoreToDancePoints(TNS_MARVELOUS)+ - pNoteData->GetNumHoldNotes()*HoldNoteScoreToDancePoints(HNS_OK); + + /* + * The logic here is that if you use a modifier that adds notes, you should have to + * hit the new notes to get a high grade. However, if you use one that removes notes, + * they should simply be counted as misses. */ + int NumTaps = max( preNoteData.GetNumRowsWithTaps(), postNoteData.GetNumRowsWithTaps() ); + int NumHolds = max( preNoteData.GetNumHoldNotes(), postNoteData.GetNumHoldNotes() ); + return NumTaps*TapNoteScoreToDancePoints(TNS_MARVELOUS)+ + NumHolds*HoldNoteScoreToDancePoints(HNS_OK); } diff --git a/stepmania/src/ScoreKeeperMAX2.h b/stepmania/src/ScoreKeeperMAX2.h index 4daa4edac4..7795be16ff 100644 --- a/stepmania/src/ScoreKeeperMAX2.h +++ b/stepmania/src/ScoreKeeperMAX2.h @@ -33,7 +33,7 @@ class ScoreKeeperMAX2: public ScoreKeeper void AddScore( TapNoteScore score ); public: - ScoreKeeperMAX2( const vector& apNotes, PlayerNumber pn); + ScoreKeeperMAX2( const vector& apNotes, const CStringArray &asModifiers, PlayerNumber pn); // before a song plays (called multiple times if course) void OnNextSong( int iSongInCourseIndex, Steps* pNotes, NoteData* pNoteData ); @@ -41,9 +41,10 @@ public: void HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTapsInRow, int iNumAdditions ); void HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tapScore ); +private: int TapNoteScoreToDancePoints( TapNoteScore tns ); int HoldNoteScoreToDancePoints( HoldNoteScore hns ); - int GetPossibleDancePoints( const NoteData* pNoteData ); + int GetPossibleDancePoints( const NoteData &preNoteData, const NoteData &postNoteData ); }; #endif diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 01dcb14861..b7817a7d02 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -188,7 +188,7 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration ) : Screen("ScreenGameplay") switch( PREFSMAN->m_iScoringType ) { case PrefsManager::SCORING_MAX2: - m_pPrimaryScoreKeeper[p] = new ScoreKeeperMAX2( m_apNotesQueue[p], (PlayerNumber)p ); + m_pPrimaryScoreKeeper[p] = new ScoreKeeperMAX2( m_apNotesQueue[p], m_asModifiersQueue[p], (PlayerNumber)p ); break; case PrefsManager::SCORING_5TH: m_pPrimaryScoreKeeper[p] = new ScoreKeeper5th( m_apNotesQueue[p], (PlayerNumber)p );