From 3797458bdccdf2348560405af16bbc1b46771c46 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Wed, 26 Mar 2003 18:58:12 +0000 Subject: [PATCH] Change scoring according to http://www.aaroninjapan.com/ddr2.html and fix inaccurate comments --- stepmania/src/ScoreKeeperMAX2.cpp | 261 +++++++++++++++++++----------- 1 file changed, 170 insertions(+), 91 deletions(-) diff --git a/stepmania/src/ScoreKeeperMAX2.cpp b/stepmania/src/ScoreKeeperMAX2.cpp index c1208f3607..c6496a8cdb 100644 --- a/stepmania/src/ScoreKeeperMAX2.cpp +++ b/stepmania/src/ScoreKeeperMAX2.cpp @@ -80,6 +80,8 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa GAMESTATE->m_CurStageStats.iTapNoteScores[m_PlayerNumber][scoreOfLastTap] += 1; /* + http://www.aaroninjapan.com/ddr2.html + A single step's points are calculated as follows: p = score multiplier (Perfect = 10, Great = 5, other = 0) @@ -90,14 +92,15 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa So, the score for one step is: one_step_score = p * (B/S) * n - *IMPORTANT* : Double steps (U+L, D+R, etc.) count as two steps instead of one, so - if you get a double L+R on the 112th step of a song, you score is calculated with a - Perfect/Great/whatever for both the 112th and 113th steps. Got it? Now, through simple - algebraic manipulation + *IMPORTANT* : Double steps (U+L, D+R, etc.) count as two steps instead of one *for your combo count only*, + so if you get a double L+R on the 112th step of a song, you score is calculated for only one step, not two, + as the combo counter might otherwise imply. + + Now, through simple algebraic manipulation: S = 1+...+N = (1+N)*N/2 (1 through N added together) - Okay, time for an example: - - So, for example, suppose we wanted to calculate the step score of a "Great" on the 57th step of a 441 step, 8-foot difficulty song (I'm just making this one up): + + Okay, time for an example. Suppose we wanted to calculate the step score of a "Great" on the 57th step of + a 441 step, 8-foot difficulty song (I'm just making this one up): S = (1 + 441)*441 / 2 = 194,222 / 2 @@ -106,9 +109,13 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa = 5 * (8,000,000 / 97,461) * 57 = 5 * (82) * 57 (The 82 is rounded down from 82.08411...) = 23,370 - Remember this is just the score for the step, not the cumulative score up to the 57th step. Also, please note that I am currently checking into rounding errors with the system and if there are any, how they are resolved in the system. - Note: if you got all Perfect on this song, you would get (p=10)*B, which is 80,000,000. In fact, the maximum possible score for any song is the number of feet difficulty X 10,000,000. + Remember this is just the score for the step, not the cumulative score up to the 57th step. Also, please note that + I am currently checking into rounding errors with the system and if there are any, how they are resolved in the system. + + Note: if you got all Perfect on this song, you would get (p=10)*B, which is 80,000,000. In fact, the maximum possible + score for any song is the number of feet difficulty X 10,000,000. + 3dfsux: I redid this code so it will store the score as a long, then correct the score for each song based on that value. lScore == p * n @@ -116,7 +123,6 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa keeping these seperate for as long as possible improves accuracy. */ -// for( int i=0; im_CurStageStats.iCurCombo[m_PlayerNumber]; + int iOldCombo = iCurCombo; - switch( scoreOfLastTap ) +/* + http://www.aaroninjapan.com/ddr2.html + + Note on ONI Mode scoring + + Your combo counter only increased with a "Marvelous/Perfect", and double Marvelous/Perfect steps (left and right, etc.) + only add 1 to your combo instead of 2. The combo counter thus becomes a "Marvelous/Perfect" counter. +*/ + switch( GAMESTATE->m_PlayMode ) { - case TNS_MARVELOUS: - case TNS_PERFECT: - case TNS_GREAT: + case PLAY_MODE_ARCADE: + case PLAY_MODE_BATTLE: + case PLAY_MODE_NONSTOP: + case PLAY_MODE_ENDLESS: + switch( scoreOfLastTap ) { - int iOldCombo = iCurCombo; - - if( GAMESTATE->m_PlayMode == PLAY_MODE_ONI ) - { - switch( scoreOfLastTap ) - { - case TNS_MARVELOUS: - case TNS_PERFECT: - iCurCombo++; - break; - case TNS_GREAT: -// int aosid = 4; - break; - } - } - else - iCurCombo += iNumTapsInRow; - - #define CROSSED( i ) (iOldComboPostMessageToTopScreen( SM_100Combo, 0 ); - else if( CROSSED(200) ) SCREENMAN->PostMessageToTopScreen( SM_200Combo, 0 ); - else if( CROSSED(300) ) SCREENMAN->PostMessageToTopScreen( SM_300Combo, 0 ); - else if( CROSSED(400) ) SCREENMAN->PostMessageToTopScreen( SM_400Combo, 0 ); - else if( CROSSED(500) ) SCREENMAN->PostMessageToTopScreen( SM_500Combo, 0 ); - else if( CROSSED(600) ) SCREENMAN->PostMessageToTopScreen( SM_600Combo, 0 ); - else if( CROSSED(700) ) SCREENMAN->PostMessageToTopScreen( SM_700Combo, 0 ); - else if( CROSSED(800) ) SCREENMAN->PostMessageToTopScreen( SM_800Combo, 0 ); - else if( CROSSED(900) ) SCREENMAN->PostMessageToTopScreen( SM_900Combo, 0 ); - else if( CROSSED(1000)) SCREENMAN->PostMessageToTopScreen( SM_1000Combo, 0 ); - - // new max combo - GAMESTATE->m_CurStageStats.iMaxCombo[m_PlayerNumber] = max(GAMESTATE->m_CurStageStats.iMaxCombo[m_PlayerNumber], iCurCombo); + case TNS_MARVELOUS: + case TNS_PERFECT: + case TNS_GREAT: + iCurCombo += iNumTapsInRow; + break; } break; - case TNS_GOOD: - case TNS_BOO: - case TNS_MISS: + case PLAY_MODE_ONI: + switch( scoreOfLastTap ) { - // don't play "combo stopped" in battle - switch( GAMESTATE->m_PlayMode ) - { - case PLAY_MODE_BATTLE: - if( pInventory ) - pInventory->OnComboBroken( m_PlayerNumber, iCurCombo ); - default: - if( iCurCombo>50 ) - SCREENMAN->PostMessageToTopScreen( SM_ComboStopped, 0 ); - } - - iCurCombo = 0; + case TNS_MARVELOUS: + case TNS_PERFECT: + iCurCombo++; + break; } break; default: ASSERT(0); } + + +#define CROSSED( i ) (iOldComboPostMessageToTopScreen( SM_100Combo, 0 ); + else if( CROSSED(200) ) SCREENMAN->PostMessageToTopScreen( SM_200Combo, 0 ); + else if( CROSSED(300) ) SCREENMAN->PostMessageToTopScreen( SM_300Combo, 0 ); + else if( CROSSED(400) ) SCREENMAN->PostMessageToTopScreen( SM_400Combo, 0 ); + else if( CROSSED(500) ) SCREENMAN->PostMessageToTopScreen( SM_500Combo, 0 ); + else if( CROSSED(600) ) SCREENMAN->PostMessageToTopScreen( SM_600Combo, 0 ); + else if( CROSSED(700) ) SCREENMAN->PostMessageToTopScreen( SM_700Combo, 0 ); + else if( CROSSED(800) ) SCREENMAN->PostMessageToTopScreen( SM_800Combo, 0 ); + else if( CROSSED(900) ) SCREENMAN->PostMessageToTopScreen( SM_900Combo, 0 ); + else if( CROSSED(1000)) SCREENMAN->PostMessageToTopScreen( SM_1000Combo, 0 ); + + // new max combo + GAMESTATE->m_CurStageStats.iMaxCombo[m_PlayerNumber] = max(GAMESTATE->m_CurStageStats.iMaxCombo[m_PlayerNumber], iCurCombo); + + + switch( scoreOfLastTap ) + { + case TNS_GOOD: + case TNS_BOO: + case TNS_MISS: + // don't play "combo stopped" in battle + switch( GAMESTATE->m_PlayMode ) + { + case PLAY_MODE_BATTLE: + if( pInventory ) + pInventory->OnComboBroken( m_PlayerNumber, iCurCombo ); + default: + if( iCurCombo>50 ) + SCREENMAN->PostMessageToTopScreen( SM_ComboStopped, 0 ); + } + + iCurCombo = 0; + break; + } } @@ -227,19 +250,6 @@ void ScoreKeeperMAX2::HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tap int ScoreKeeperMAX2::GetPossibleDancePoints( const NoteData* pNoteData ) { -//Each song has a certain number of "Dance Points" assigned to it. For regular arrows, this is 2 per arrow. For freeze arrows, it is 6 per arrow. When you add this all up, you get the maximum number of possible "Dance Points". -// -//Your "Dance Points" are calculated as follows: -// -//A "Marvelous" is worth 3 points, but oniy when in oni mode -//A "Perfect" is worth 2 points -//A "Great" is worth 1 points -//A "Good" is worth 0 points -//A "Boo" will subtract 4 points -//A "Miss" will subtract 8 points -//An "OK" (Successful Freeze step) will add 6 points -//A "NG" (Unsuccessful Freeze step) is worth 0 points - /* Note that, if Marvelous timing is disabled or not active (not course mode), * PERFECT will be used instead. */ @@ -257,26 +267,95 @@ int ScoreKeeperMAX2::TapNoteScoreToDancePoints( TapNoteScore tns ) if(!PREFSMAN->m_bMarvelousTiming && tns == TNS_MARVELOUS) tns = TNS_PERFECT; - switch( tns ) +/* + http://www.aaroninjapan.com/ddr2.html + + Regular play scoring + + A "Perfect" is worth 2 points + A "Great" is worth 1 points + A "Good" is worth 0 points + A "Boo" will subtract 4 points + A "Miss" will subtract 8 points + An "OK" (Successful Freeze step) will add 6 points + A "NG" (Unsuccessful Freeze step) is worth 0 points + + Note on ONI Mode scoring + + The total number of Dance Points is calculated with Marvelous steps being worth 3 points, Perfects getting + 2 points, OKs getting 3 points, Greats getting 1 point, and everything else is worth 0 points. (Note: The + "Marvelous" step rating is a new rating to DDR Extreme only used in Oni and Nonstop modes. They are rated + higher than "Perfect" steps). + + Note on NONSTOP Mode scoring + + A "Marvelous" is worth 2 points + A "Perfect" is also worth 2 points + A "Great" is worth 1 points + A "Good" is worth 0 points + A "Boo" will subtract 4 points + A "Miss" will subtract 8 points + An "OK" (Successful Freeze step) will add 6 points + A "NG" (Unsuccessful Freeze step) is worth 0 points +*/ + + switch( GAMESTATE->m_PlayMode ) { - case TNS_MARVELOUS: return bOni ? +3 : +2; - case TNS_PERFECT: return +2; - case TNS_GREAT: return +1; - case TNS_GOOD: return +0; - case TNS_BOO: return bOni ? 0 : -4; - case TNS_MISS: return bOni ? 0 : -8; - case TNS_NONE: return 0; - default: ASSERT(0); return 0; - } + case PLAY_MODE_ARCADE: + case PLAY_MODE_BATTLE: + case PLAY_MODE_ENDLESS: + case PLAY_MODE_NONSTOP: + switch( tns ) + { + case TNS_MARVELOUS: return +2; + case TNS_PERFECT: return +2; + case TNS_GREAT: return +1; + case TNS_GOOD: return +0; + case TNS_BOO: return -4; + case TNS_MISS: return -8; + } + break; + case PLAY_MODE_ONI: + switch( tns ) + { + case TNS_MARVELOUS: return +3; + case TNS_PERFECT: return +2; + case TNS_GREAT: return +1; + case TNS_GOOD: return +0; + case TNS_BOO: return +0; + case TNS_MISS: return +0; + } + break; + default: + ASSERT(0); + } + return +0; } int ScoreKeeperMAX2::HoldNoteScoreToDancePoints( HoldNoteScore hns ) { - switch( hns ) + switch( GAMESTATE->m_PlayMode ) { - case HNS_OK: return GAMESTATE->IsCourseMode() ? +3 : +6; - case HNS_NG: return +0; - default: ASSERT(0); return 0; + case PLAY_MODE_ARCADE: + case PLAY_MODE_BATTLE: + case PLAY_MODE_ENDLESS: + case PLAY_MODE_NONSTOP: + switch( hns ) + { + case HNS_OK: return +6; + case HNS_NG: return +0; + } + break; + case PLAY_MODE_ONI: + switch( hns ) + { + case HNS_OK: return +3; + case HNS_NG: return +0; + } + break; + default: + ASSERT(0); } + return +0; }