diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index 4a6cd316a1..a1b7c41875 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -163,117 +163,23 @@ void ScoreKeeperNormal::Load( void ScoreKeeperNormal::OnNextSong( int iSongInCourseIndex, const Steps* pSteps, const NoteData* pNoteData ) { -/* - Note on NONSTOP Mode scoring - Nonstop mode requires the player to play 4 songs in succession, with the total maximum possible score for - the four song set being 100,000,000. This comes from the sum of the four stages' maximum possible scores, - which, regardless of song or difficulty is: - - 10,000,000 for the first song - 20,000,000 for the second song - 30,000,000 for the third song - 40,000,000 for the fourth song - - We extend this to work with nonstop courses of any length. - - We also keep track of this scoring type in endless, with 100mil per iteration - of all songs, though this score isn't actually seen anywhere right now. -*/ - // Calculate the score multiplier - m_iMaxPossiblePoints = 0; - if( GAMESTATE->IsCourseMode() ) - { - const int numSongsInCourse = m_apSteps.size(); - ASSERT( numSongsInCourse != 0 ); - - const int iIndex = iSongInCourseIndex % numSongsInCourse; - m_bIsLastSongInCourse = (iIndex+1 == numSongsInCourse); - - if( numSongsInCourse < 10 ) - { - const int courseMult = (numSongsInCourse * (numSongsInCourse + 1)) / 2; - ASSERT(courseMult >= 0); - - m_iMaxPossiblePoints = (100000000 * (iIndex+1)) / courseMult; - } - else - { - /* When we have lots of songs, the scale above biases too much: in a - * course with 50 songs, the first song is worth 80k, the last 4mil, which - * is too much of a difference. - * - * With this, each song in a 50-song course will be worth 2mil. */ - m_iMaxPossiblePoints = 100000000 / numSongsInCourse; - } - } - else - { - // long ver and marathon ver songs have higher max possible scores - int iLengthMultiplier = GameState::GetNumStagesMultiplierForSong( GAMESTATE->m_pCurSong ); - - /* This is no longer just simple additive/subtractive scoring, - * but start with capping the score at the size of the score counter. */ - m_iMaxPossiblePoints = 10 * 10000000 * iLengthMultiplier; - } - ASSERT( m_iMaxPossiblePoints >= 0 ); - m_iMaxScoreSoFar += m_iMaxPossiblePoints; - - GAMESTATE->SetProcessedTimingData(const_cast(&pSteps->m_Timing)); - - m_iNumTapsAndHolds = pNoteData->GetNumRowsWithTapOrHoldHead() + pNoteData->GetNumHoldNotes() - + pNoteData->GetNumRolls(); - - m_iPointBonus = m_iMaxPossiblePoints; - m_pPlayerStageStats->m_iMaxScore = m_iMaxScoreSoFar; - - /* MercifulBeginner shouldn't clamp weights in course mode, even if a beginner - * song is in a course, since that makes PlayerStageStats::GetGrade hard. */ m_bIsBeginner = pSteps->GetDifficulty() == Difficulty_Beginner && !GAMESTATE->IsCourseMode(); - ASSERT( m_iPointBonus >= 0 ); - m_iTapNotesHit = 0; GAMESTATE->SetProcessedTimingData(NULL); } -static int GetScore(int p, int Z, int S, int n) -{ - /* There's a problem with the scoring system described below. Z/S is truncated - * to an int. However, in some cases we can end up with very small base scores. - * Each song in a 50-song nonstop course will be worth 2mil, which is a base of - * 200k; Z/S will end up being zero. - * - * If we rearrange the equation to (p*Z*n) / S, this problem goes away. - * (To do that, we need to either use 64-bit ints or rearrange it a little - * more and use floats, since p*Z*n won't fit a 32-bit int.) However, this - * changes the scoring rules slightly. - */ - -#if 0 - // This is the actual method described below. - return p * (Z / S) * n; -#elif 1 - // This doesn't round down Z/S. - return int(int64_t(p) * n * Z / S); -#else - // This also doesn't round down Z/S. Use this if you don't have 64-bit ints. - return int(p * n * (float(Z) / S)); -#endif - -} - void ScoreKeeperNormal::AddTapScore( TapNoteScore tns ) { + AddScoreInternal( tns ); } void ScoreKeeperNormal::AddHoldScore( HoldNoteScore hns ) { if( hns == HNS_Held ) AddScoreInternal( TNS_W1 ); - else if ( hns == HNS_LetGo ) - AddScoreInternal( TNS_W4 ); // required for subtractive score display to work properly. } void ScoreKeeperNormal::AddTapRowScore( TapNoteScore score, const NoteData &nd, int iRow ) @@ -300,71 +206,27 @@ void ScoreKeeperNormal::AddScoreInternal( TapNoteScore score ) int &iScore = m_pPlayerStageStats->m_iScore; int &iCurMaxScore = m_pPlayerStageStats->m_iCurMaxScore; - // See Aaron In Japan for more details about the scoring formulas. - // Note: this assumes no custom scoring systems are in use. - int p = 0; // score multiplier + int p = 0; switch( score ) { - case TNS_W1: p = 10; break; - case TNS_W2: p = GAMESTATE->ShowW1()? 9:10; break; - case TNS_W3: p = 5; break; + case TNS_W1: p = 5; break; + case TNS_W2: p = 4; break; + case TNS_W3: p = 3; break; + case TNS_W4: p = 2; break; + case TNS_CheckpointHit: + case TNS_W5: p = 1; break; + case TNS_HitMine: p = -1; break; default: p = 0; break; } - m_iTapNotesHit++; + iScore += p; + iCurMaxScore += 5; - const int N = m_iNumTapsAndHolds; - const int sum = (N * (N + 1)) / 2; - const int Z = m_iMaxPossiblePoints/10; + if( iScore < 0 ) + iScore = 0; - // Don't use a multiplier if the player has failed - if( m_pPlayerStageStats->m_bFailed ) - { - iScore += p; - // make score evenly divisible by 5 - // only update this on the next step, to make it less *obvious* - /* Round to the nearest 5, instead of always rounding down, so a base score - * of 9 will round to 10, not 5. */ - if (p > 0) - iScore = ((iScore+2) / 5) * 5; - } - else - { - iScore += GetScore(p, Z, sum, m_iTapNotesHit); - const int &iCurrentCombo = m_pPlayerStageStats->m_iCurCombo; - iScore += m_ComboBonusFactor[score] * iCurrentCombo; - } - - // Subtract the maximum this step could have been worth from the bonus. - m_iPointBonus -= GetScore(10, Z, sum, m_iTapNotesHit); - // And add the maximum this step could have been worth to the max score up to now. - iCurMaxScore += GetScore(10, Z, sum, m_iTapNotesHit); - - if ( m_iTapNotesHit == m_iNumTapsAndHolds && score >= TNS_W2 ) - { - if( !m_pPlayerStageStats->m_bFailed ) - iScore += m_iPointBonus; - if ( m_bIsLastSongInCourse ) - { - iScore += 100000000 - m_iMaxScoreSoFar; - iCurMaxScore += 100000000 - m_iMaxScoreSoFar; - - /* If we're in Endless mode, we'll come around here again, so reset - * the bonus counter. */ - m_iMaxScoreSoFar = 0; - } - iCurMaxScore += m_iPointBonus; - } - - ASSERT_M( iScore >= 0, "iScore < 0 before re-rounding" ); - - // Undo rounding from the last tap, and re-round. - iScore += m_iScoreRemainder; - m_iScoreRemainder = (iScore % m_iRoundTo); - iScore = iScore - m_iScoreRemainder; - - ASSERT_M( iScore >= 0, "iScore < 0 after re-rounding" ); + ASSERT_M( iScore >= 0, "iScore < 0" ); // LOG->Trace( "score: %i", iScore ); }