Advertisement
Jousway

ScoreKeeperMAX2.h ScoreKeeperMAX2.ccp

Dec 11th, 2011
501
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.81 KB | None | 0 0
  1. /* ScoreKeeperMAX2 - MAX2-style scorekeeping. */
  2.  
  3. #ifndef SCOREKEEPER_MAX2_H
  4. #define SCOREKEEPER_MAX2_H
  5.  
  6. #include "ScoreKeeper.h"
  7. #include "NoteDataWithScoring.h"
  8. class Steps;
  9.  
  10. class ScoreKeeperMAX2: public ScoreKeeper
  11. {
  12.     int             m_iScoreRemainder;
  13.     int             m_iMaxPossiblePoints;
  14.     int             m_iTapNotesHit; // number of notes judged so far, needed by scoring
  15.  
  16.     int             m_iNumTapsAndHolds;
  17.     int             m_iMaxScoreSoFar; // for nonstop scoring
  18.     int             m_iPointBonus; // the difference to award at the end
  19.     int             m_iCurToastyCombo;
  20.     bool            m_bIsLastSongInCourse;
  21.  
  22.     const vector<Steps*>& apSteps;
  23.  
  24.     void AddScore( TapNoteScore score );
  25.  
  26.     /* Configuration: */
  27.     /* Score after each tap will be rounded to the nearest m_iRoundTo; 1 to do nothing. */
  28.     int             m_iRoundTo;
  29.     int             m_ComboBonusFactor[NUM_TAP_NOTE_SCORES];
  30.  
  31. public:
  32.     ScoreKeeperMAX2( const vector<Song*>& apSongs, const vector<Steps*>& apSteps, const vector<AttackArray> &asModifiers, PlayerNumber pn);
  33.  
  34.     // before a song plays (called multiple times if course)
  35.     void OnNextSong( int iSongInCourseIndex, const Steps* pSteps, const NoteData* pNoteData );
  36.  
  37.     void HandleTapScore( TapNoteScore score );
  38.     void HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTapsInRow );
  39.     void HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tapScore );
  40.  
  41.     // This must be calculated using only cached radar values so that we can
  42.     // do it quickly.
  43.     static int  GetPossibleDancePoints( const RadarValues& fRadars );
  44.     static int  GetPossibleDancePoints( const RadarValues& fOriginalRadars, const RadarValues& fPostRadars );
  45.  
  46. private:
  47.     static int TapNoteScoreToDancePoints( TapNoteScore tns );
  48.     static int HoldNoteScoreToDancePoints( HoldNoteScore hns );
  49.  
  50. };
  51.  
  52. #endif
  53.  
  54. /*
  55.  * (c) 2001-2004 Chris Danford, Glenn Maynard
  56.  * All rights reserved.
  57.  *
  58.  * Permission is hereby granted, free of charge, to any person obtaining a
  59.  * copy of this software and associated documentation files (the
  60.  * "Software"), to deal in the Software without restriction, including
  61.  * without limitation the rights to use, copy, modify, merge, publish,
  62.  * distribute, and/or sell copies of the Software, and to permit persons to
  63.  * whom the Software is furnished to do so, provided that the above
  64.  * copyright notice(s) and this permission notice appear in all copies of
  65.  * the Software and that both the above copyright notice(s) and this
  66.  * permission notice appear in supporting documentation.
  67.  *
  68.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  69.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  70.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
  71.  * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
  72.  * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
  73.  * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  74.  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  75.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  76.  * PERFORMANCE OF THIS SOFTWARE.
  77.  */
  78.  
  79. #include "global.h"
  80. #include "ScoreKeeperMAX2.h"
  81. #include "GameState.h"
  82. #include "PrefsManager.h"
  83. #include "Steps.h"
  84. #include "PrefsManager.h"
  85. #include "ScreenManager.h"
  86. #include "ScreenGameplay.h"
  87. #include "GameState.h"
  88. #include "Course.h"
  89. #include "SongManager.h"
  90. #include "NoteDataUtil.h"
  91. #include "RageLog.h"
  92. #include "StageStats.h"
  93. #include "ProfileManager.h"
  94. #include "NetworkSyncManager.h"
  95.  
  96. ScoreKeeperMAX2::ScoreKeeperMAX2( const vector<Song*>& apSongs, const vector<Steps*>& apSteps_, const vector<AttackArray> &asModifiers, PlayerNumber pn_ ):
  97.     ScoreKeeper(pn_), apSteps(apSteps_)
  98. {
  99.     ASSERT( apSongs.size() == apSteps_.size() );
  100.     ASSERT( apSongs.size() == asModifiers.size() );
  101.     //
  102.     // Fill in g_CurStageStats, calculate multiplier
  103.     //
  104.     int iTotalPossibleDancePoints = 0;
  105.     for( unsigned i=0; i<apSteps.size(); i++ )
  106.     {
  107.         Song* pSong = apSongs[i];
  108.         Steps* pSteps = apSteps[i];
  109.         const AttackArray &aa = asModifiers[i];
  110.         NoteData ndTemp;
  111.         pSteps->GetNoteData( &ndTemp );
  112.  
  113.         /* We might have been given lots of songs; don't keep them in memory uncompressed. */
  114.         pSteps->Compress();
  115.  
  116.         const Style* pStyle = GAMESTATE->GetCurrentStyle();
  117.         NoteData nd;
  118.         pStyle->GetTransformedNoteDataForStyle( pn_, &ndTemp, &nd );
  119.  
  120.         /* Compute RadarValues before applying any user-selected mods.  Apply
  121.          * Course mods and count them in the "pre" RadarValues because they're
  122.          * forced and not chosen by the user.
  123.          */
  124.         NoteDataUtil::TransformNoteData( nd, aa, pSteps->m_StepsType, pSong );
  125.         RadarValues rvPre;
  126.         NoteDataUtil::GetRadarValues( nd, pSong->m_fMusicLengthSeconds, rvPre );
  127.  
  128.         /* Apply user transforms to find out how the notes will really look.
  129.          *
  130.          * XXX: This is brittle: if we end up combining mods for a song differently
  131.          * than ScreenGameplay, we'll end up with the wrong data.  We should probably
  132.          * have eg. GAMESTATE->GetOptionsForCourse(po,so,pn) to get options based on
  133.          * the last call to StoreSelectedOptions and the modifiers list, but that'd
  134.          * mean moving the queues in ScreenGameplay to GameState ... */
  135.         NoteDataUtil::TransformNoteData( nd, GAMESTATE->m_PlayerOptions[pn_], pSteps->m_StepsType );
  136.         RadarValues rvPost;
  137.         NoteDataUtil::GetRadarValues( nd, pSong->m_fMusicLengthSeconds, rvPost );
  138.          
  139.         iTotalPossibleDancePoints += this->GetPossibleDancePoints( rvPre, rvPost );
  140.     }
  141.     g_CurStageStats.iPossibleDancePoints[pn_] = iTotalPossibleDancePoints;
  142.  
  143.  
  144.     m_iScoreRemainder = 0;
  145.     m_iCurToastyCombo = 0;
  146.     m_iMaxScoreSoFar = 0;
  147.     m_iPointBonus = 0;
  148.     m_iNumTapsAndHolds = 0;
  149.     m_bIsLastSongInCourse = false;
  150.  
  151.     memset( m_ComboBonusFactor, 0, sizeof(m_ComboBonusFactor) );
  152.     switch( PREFSMAN->m_iScoringType )
  153.     {
  154.     case PrefsManager::SCORING_MAX2:
  155.         m_iRoundTo = 1;
  156.         break;
  157.     case PrefsManager::SCORING_5TH:
  158.         m_iRoundTo = 5;
  159.         if (!GAMESTATE->IsCourseMode())
  160.         {
  161.             m_ComboBonusFactor[TNS_MARVELOUS] = 55;
  162.             m_ComboBonusFactor[TNS_PERFECT] = 55;
  163.             m_ComboBonusFactor[TNS_GREAT] = 33;
  164.         }
  165.         break;
  166.     default:
  167.         ASSERT(0);
  168.     }
  169.  
  170. }
  171.  
  172. void ScoreKeeperMAX2::OnNextSong( int iSongInCourseIndex, const Steps* pSteps, const NoteData* pNoteData )
  173. {
  174. /*
  175.   http://www.aaroninjapan.com/ddr2.html
  176.  
  177.   Note on NONSTOP Mode scoring
  178.  
  179.   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:
  180.  
  181.   10,000,000 for the first song
  182.   20,000,000 for the second song
  183.   30,000,000 for the third song
  184.   40,000,000 for the fourth song
  185.  
  186.   We extend this to work with nonstop courses of any length.
  187.  
  188.   We also keep track of this scoring type in endless, with 100mil per iteration
  189.   of all songs, though this score isn't actually seen anywhere right now.
  190. */
  191.     //
  192.     // Calculate the score multiplier
  193.     //
  194.     m_iMaxPossiblePoints = 0;
  195.     if( GAMESTATE->IsCourseMode() )
  196.     {
  197.         const int numSongsInCourse = apSteps.size();
  198.         ASSERT( numSongsInCourse != 0 );
  199.  
  200.         const int iIndex = iSongInCourseIndex % numSongsInCourse;
  201.         m_bIsLastSongInCourse = (iIndex+1 == numSongsInCourse);
  202.  
  203.         if( numSongsInCourse < 10 )
  204.         {
  205.             const int courseMult = (numSongsInCourse * (numSongsInCourse + 1)) / 2;
  206.             ASSERT(courseMult >= 0);
  207.  
  208.             m_iMaxPossiblePoints = (100000000 * (iIndex+1)) / courseMult;
  209.         }
  210.         else
  211.         {
  212.             /* When we have lots of songs, the scale above biases too much: in a
  213.              * course with 50 songs, the first song is worth 80k, the last 4mil, which
  214.              * is too much of a difference.
  215.              *
  216.              * With this, each song in a 50-song course will be worth 2mil. */
  217.             m_iMaxPossiblePoints = 100000000 / numSongsInCourse;
  218.         }
  219.     }
  220.     else
  221.     {
  222.         const int iMeter = clamp( pSteps->GetMeter(), 1, 10 );
  223.  
  224.         // long ver and marathon ver songs have higher max possible scores
  225.         int iLengthMultiplier = SongManager::GetNumStagesForSong( GAMESTATE->m_pCurSong );
  226.         switch( PREFSMAN->m_iScoringType )
  227.         {
  228.         case PrefsManager::SCORING_MAX2:
  229.             m_iMaxPossiblePoints = iMeter * 10000000 * iLengthMultiplier;
  230.             break;
  231.         case PrefsManager::SCORING_5TH:
  232.             m_iMaxPossiblePoints = (iMeter * iLengthMultiplier + 1) * 5000000;
  233.             break;
  234.         default:
  235.             ASSERT(0);
  236.         }
  237.     }
  238.     ASSERT( m_iMaxPossiblePoints >= 0 );
  239.     m_iMaxScoreSoFar += m_iMaxPossiblePoints;
  240.  
  241.     m_iNumTapsAndHolds = pNoteData->GetNumRowsWithTapOrHoldHead() + pNoteData->GetNumHoldNotes();
  242.  
  243.     m_iPointBonus = m_iMaxPossiblePoints;
  244.  
  245.     ASSERT( m_iPointBonus >= 0 );
  246.  
  247.     m_iTapNotesHit = 0;
  248. }
  249.  
  250. static int GetScore(int p, int B, int S, int n)
  251. {
  252.     /* There's a problem with the scoring system described below.  B/S is truncated
  253.      * to an int.  However, in some cases we can end up with very small base scores.
  254.      * Each song in a 50-song nonstop course will be worth 2mil, which is a base of
  255.      * 200k; B/S will end up being zero.
  256.      *
  257.      * If we rearrange the equation to (p*B*n) / S, this problem goes away.
  258.      * (To do that, we need to either use 64-bit ints or rearrange it a little
  259.      * more and use floats, since p*B*n won't fit a 32-bit int.)  However, this
  260.      * changes the scoring rules slightly.
  261.      */
  262.  
  263. #if 0
  264.     /* This is the actual method described below. */
  265.     return p * (B / S) * n;
  266. #elif 1
  267.     /* This doesn't round down B/S. */
  268.     return int(int64_t(p) * n * B / S);
  269. #else
  270.     /* This also doesn't round down B/S. Use this if you don't have 64-bit ints. */
  271.     return int(p * n * (float(B) / S));
  272. #endif
  273.  
  274. }
  275.  
  276. void ScoreKeeperMAX2::AddScore( TapNoteScore score )
  277. {
  278.     int &iScore = g_CurStageStats.iScore[m_PlayerNumber];
  279. /*
  280.   http://www.aaroninjapan.com/ddr2.html
  281.  
  282.   Regular scoring:
  283.  
  284.   Let p = score multiplier (Perfect = 10, Great = 5, other = 0)
  285.  
  286.   Note on NONSTOP Mode scoring
  287.  
  288.   Let p = score multiplier (Marvelous = 10, Perfect = 9, Great = 5, other = 0)
  289.  
  290.   N = total number of steps and freeze steps
  291.   S = The sum of all integers from 1 to N (the total number of steps/freeze steps)
  292.   n = number of the current step or freeze step (varies from 1 to N)
  293.   B = Base value of the song (1,000,000 X the number of feet difficulty) - All edit data is rated as 5 feet
  294.   So, the score for one step is:
  295.   one_step_score = p * (B/S) * n
  296.  
  297.   *IMPORTANT* : Double steps (U+L, D+R, etc.) count as two steps instead of one *for your combo count only*,
  298.   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,
  299.   as the combo counter might otherwise imply.  
  300.    
  301.   Now, through simple algebraic manipulation:
  302.   S = 1+...+N = (1+N)*N/2 (1 through N added together)
  303.  
  304.   Okay, time for an example.  Suppose we wanted to calculate the step score of a "Great" on the 57th step of
  305.   a 441 step, 8-foot difficulty song (I'm just making this one up):
  306.  
  307.   S = (1 + 441)*441 / 2
  308.   = 194,222 / 2
  309.   = 97,461
  310.   StepScore = p * (B/S) * n
  311.   = 5 * (8,000,000 / 97,461) * 57
  312.   = 5 * (82) * 57 (The 82 is rounded down from 82.08411...)
  313.   = 23,370
  314.  
  315.   Remember this is just the score for the step, not the cumulative score up to the 57th step. Also, please note that
  316.   I am currently checking into rounding errors with the system and if there are any, how they are resolved in the system.
  317.  
  318.   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
  319.   score for any song is the number of feet difficulty X 10,000,000.
  320. */
  321.     int p = 0;  // score multiplier
  322.  
  323.     switch( score )
  324.     {
  325.     case TNS_MARVELOUS: p = 10;     break;
  326.     case TNS_PERFECT:   p = GAMESTATE->ShowMarvelous()? 9:10; break;
  327.     case TNS_GREAT:     p = 5;      break;
  328.     default:            p = 0;      break;
  329.     }
  330.  
  331.     m_iTapNotesHit++;
  332.  
  333.     const int N = m_iNumTapsAndHolds;
  334.     const int sum = (N * (N + 1)) / 2;
  335.     const int B = m_iMaxPossiblePoints/10;
  336.  
  337.     // Don't use a multiplier if the player has failed
  338.     if( g_CurStageStats.bFailedEarlier[m_PlayerNumber] )
  339.     {
  340.         iScore += p;
  341.         // make score evenly divisible by 5
  342.         // only update this on the next step, to make it less *obvious*
  343.         /* Round to the nearest 5, instead of always rounding down, so a base score
  344.          * of 9 will round to 10, not 5. */
  345.         if (p > 0)
  346.             iScore = ((iScore+2) / 5) * 5;
  347.     }
  348.     else
  349.     {
  350.         iScore += GetScore(p, B, sum, m_iTapNotesHit);
  351.         const int &iCurrentCombo = g_CurStageStats.iCurCombo[m_PlayerNumber];
  352.         g_CurStageStats.iBonus[m_PlayerNumber] += m_ComboBonusFactor[score] * iCurrentCombo;
  353.     }
  354.  
  355.     /* Subtract the maximum this step could have been worth from the bonus. */
  356.     m_iPointBonus -= GetScore(10, B, sum, m_iTapNotesHit);
  357.  
  358.     if ( m_iTapNotesHit == m_iNumTapsAndHolds && score >= TNS_PERFECT )
  359.     {
  360.         if (!g_CurStageStats.bFailedEarlier[m_PlayerNumber])
  361.             iScore += m_iPointBonus;
  362.         if ( m_bIsLastSongInCourse )
  363.         {
  364.             iScore += 100000000 - m_iMaxScoreSoFar;
  365.  
  366.             /* If we're in Endless mode, we'll come around here again, so reset
  367.              * the bonus counter. */
  368.             m_iMaxScoreSoFar = 0;
  369.         }
  370.     }
  371.  
  372.     ASSERT( iScore >= 0 );
  373.  
  374.     /* Undo rounding from the last tap, and re-round. */
  375.     iScore += m_iScoreRemainder;
  376.     m_iScoreRemainder = (iScore % m_iRoundTo);
  377.     iScore = iScore - m_iScoreRemainder;
  378.    
  379.     ASSERT( iScore >= 0 );
  380.  
  381.     printf( "score: %i\n", iScore );
  382. }
  383.  
  384. void ScoreKeeperMAX2::HandleTapScore( TapNoteScore score )
  385. {
  386.     if( score == TNS_HIT_MINE )
  387.     {
  388.         if( GAMESTATE->m_HealthState[m_PlayerNumber] != GameState::DEAD )
  389.             g_CurStageStats.iActualDancePoints[m_PlayerNumber] += TapNoteScoreToDancePoints( TNS_HIT_MINE );
  390.         g_CurStageStats.iTapNoteScores[m_PlayerNumber][TNS_HIT_MINE] += 1;
  391.     }
  392. }
  393.  
  394. void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTapsInRow )
  395. {
  396.     ASSERT( iNumTapsInRow >= 1 );
  397.  
  398.     // Update dance points.
  399.     if( GAMESTATE->m_HealthState[m_PlayerNumber] != GameState::DEAD )
  400.         g_CurStageStats.iActualDancePoints[m_PlayerNumber] += TapNoteScoreToDancePoints( scoreOfLastTap );
  401.     // update judged row totals
  402.     g_CurStageStats.iTapNoteScores[m_PlayerNumber][scoreOfLastTap] += 1;
  403.  
  404.     //
  405.     // Regular combo
  406.     //
  407.    
  408. /*
  409.   http://www.aaroninjapan.com/ddr2.html
  410.  
  411.   Note on ONI Mode scoring
  412.  
  413.   Your combo counter only increased with a "Marvelous/Perfect", and double Marvelous/Perfect steps (left and right, etc.)
  414.   only add 1 to your combo instead of 2. The combo counter thus becomes a "Marvelous/Perfect" counter.
  415. */
  416.     /* True if a jump is one to combo, false if combo is purely based on tap count. */
  417.     bool ComboIsPerRow = true;
  418.     switch( PREFSMAN->m_iScoringType )
  419.     {
  420.     case PrefsManager::SCORING_MAX2:
  421.         ComboIsPerRow = (GAMESTATE->m_PlayMode == PLAY_MODE_ONI);
  422.         break;
  423.     case PrefsManager::SCORING_5TH:
  424.         ComboIsPerRow = true;
  425.         break;
  426.     default:
  427.         ASSERT(0);
  428.     }
  429.     const int ComboCountIfHit = ComboIsPerRow? 1: iNumTapsInRow;
  430.     TapNoteScore MinScoreToContinueCombo = GAMESTATE->m_PlayMode == PLAY_MODE_ONI? TNS_PERFECT:TNS_GREAT;
  431.  
  432.     if( scoreOfLastTap >= MinScoreToContinueCombo )
  433.         g_CurStageStats.iCurCombo[m_PlayerNumber] += ComboCountIfHit;
  434.  
  435.     AddScore( scoreOfLastTap );     // only score once per row
  436.  
  437.     //
  438.     // handle combo logic
  439.     //
  440. #ifndef DEBUG
  441.     if( PREFSMAN->m_bAutoPlay && !GAMESTATE->m_bDemonstrationOrJukebox )    // cheaters never prosper
  442.     {
  443.         m_iCurToastyCombo = 0;
  444.         return;
  445.     }
  446. #endif //DEBUG
  447.  
  448.     //
  449.     // Toasty combo
  450.     //
  451.     switch( scoreOfLastTap )
  452.     {
  453.     case TNS_MARVELOUS:
  454.     case TNS_PERFECT:
  455.         m_iCurToastyCombo += iNumTapsInRow;
  456.  
  457.         if( m_iCurToastyCombo >= 250 &&
  458.             m_iCurToastyCombo - iNumTapsInRow < 250 &&
  459.             !GAMESTATE->m_bDemonstrationOrJukebox )
  460.         {
  461.             SCREENMAN->PostMessageToTopScreen( SM_PlayToasty, 0 );
  462.             PROFILEMAN->IncrementToastiesCount( m_PlayerNumber );
  463.         }
  464.         break;
  465.     default:
  466.         m_iCurToastyCombo = 0;
  467.         break;
  468.     }
  469.  
  470.    
  471.     NSMAN->ReportScore(m_PlayerNumber, scoreOfLastTap,
  472.                        g_CurStageStats.iScore[m_PlayerNumber],
  473.                        g_CurStageStats.iCurCombo[m_PlayerNumber]);
  474. }
  475.  
  476.  
  477. void ScoreKeeperMAX2::HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tapScore )
  478. {
  479.     // update dance points totals
  480.     if( GAMESTATE->m_HealthState[m_PlayerNumber] != GameState::DEAD )
  481.         g_CurStageStats.iActualDancePoints[m_PlayerNumber] += HoldNoteScoreToDancePoints( holdScore );
  482.     g_CurStageStats.iHoldNoteScores[m_PlayerNumber][holdScore] ++;
  483.  
  484.     if( holdScore == HNS_OK )
  485.         AddScore( TNS_MARVELOUS );
  486.  
  487.     NSMAN->ReportScore(m_PlayerNumber, holdScore+7,
  488.                        g_CurStageStats.iScore[m_PlayerNumber],
  489.                        g_CurStageStats.iCurCombo[m_PlayerNumber]);
  490.  
  491.  
  492. }
  493.  
  494.  
  495. int ScoreKeeperMAX2::GetPossibleDancePoints( const RadarValues& radars )
  496. {
  497.     /* Note that, if Marvelous timing is disabled or not active (not course mode),
  498.      * PERFECT will be used instead. */
  499.  
  500.     int NumTaps = int(radars[RADAR_NUM_TAPS_AND_HOLDS]);
  501.     int NumHolds = int(radars[RADAR_NUM_HOLDS]);
  502.     return NumTaps*TapNoteScoreToDancePoints(TNS_MARVELOUS)+
  503.        NumHolds*HoldNoteScoreToDancePoints(HNS_OK);
  504. }
  505.  
  506. int ScoreKeeperMAX2::GetPossibleDancePoints( const RadarValues& fOriginalRadars, const RadarValues& fPostRadars )
  507. {
  508.     /*
  509.      * The logic here is that if you use a modifier that adds notes, you should have to
  510.      * hit the new notes to get a high grade.  However, if you use one that removes notes,
  511.      * they should simply be counted as misses. */
  512.     return max(
  513.         GetPossibleDancePoints(fOriginalRadars),
  514.         GetPossibleDancePoints(fPostRadars) );
  515. }
  516.  
  517.  
  518. int ScoreKeeperMAX2::TapNoteScoreToDancePoints( TapNoteScore tns )
  519. {
  520.     if( !GAMESTATE->ShowMarvelous() && tns == TNS_MARVELOUS )
  521.         tns = TNS_PERFECT;
  522.  
  523. /*
  524.   http://www.aaroninjapan.com/ddr2.html
  525.  
  526.   Note on ONI Mode scoring
  527.  
  528.   The total number of Dance Points is calculated with Marvelous steps being worth 3 points, Perfects getting
  529.   2 points, OKs getting 3 points, Greats getting 1 point, and everything else is worth 0 points. (Note: The
  530.  
  531. */
  532.  
  533.     /* This is used for Oni percentage displays.  Grading values are currently in
  534.      * StageStats::GetGrade. */
  535.     switch( tns )
  536.     {
  537.     case TNS_NONE:      return 0;
  538.     case TNS_HIT_MINE:  return PREFSMAN->m_iPercentScoreWeightHitMine;
  539.     case TNS_MISS:      return PREFSMAN->m_iPercentScoreWeightMiss;
  540.     case TNS_BOO:       return PREFSMAN->m_iPercentScoreWeightBoo;
  541.     case TNS_GOOD:      return PREFSMAN->m_iPercentScoreWeightGood;
  542.     case TNS_GREAT:     return PREFSMAN->m_iPercentScoreWeightGreat;
  543.     case TNS_PERFECT:   return PREFSMAN->m_iPercentScoreWeightPerfect;
  544.     case TNS_MARVELOUS: return PREFSMAN->m_iPercentScoreWeightMarvelous;
  545.     default: FAIL_M( ssprintf("%i", tns) );
  546.     }
  547. }
  548.  
  549. int ScoreKeeperMAX2::HoldNoteScoreToDancePoints( HoldNoteScore hns )
  550. {
  551.     switch( hns )
  552.     {
  553.     case HNS_NONE: return 0;
  554.     case HNS_NG: return PREFSMAN->m_iPercentScoreWeightNG;
  555.     case HNS_OK: return PREFSMAN->m_iPercentScoreWeightOK;
  556.     default: FAIL_M( ssprintf("%i", hns) );
  557.     }
  558. }
  559.  
  560. /*
  561.  * (c) 2001-2004 Chris Danford, Glenn Maynard
  562.  * All rights reserved.
  563.  *
  564.  * Permission is hereby granted, free of charge, to any person obtaining a
  565.  * copy of this software and associated documentation files (the
  566.  * "Software"), to deal in the Software without restriction, including
  567.  * without limitation the rights to use, copy, modify, merge, publish,
  568.  * distribute, and/or sell copies of the Software, and to permit persons to
  569.  * whom the Software is furnished to do so, provided that the above
  570.  * copyright notice(s) and this permission notice appear in all copies of
  571.  * the Software and that both the above copyright notice(s) and this
  572.  * permission notice appear in supporting documentation.
  573.  *
  574.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  575.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  576.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
  577.  * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
  578.  * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
  579.  * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  580.  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  581.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  582.  * PERFORMANCE OF THIS SOFTWARE.
  583.  */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement