diff --git a/src/HighScore.cpp b/src/HighScore.cpp index e70bf6a701..cc9e17c0c6 100644 --- a/src/HighScore.cpp +++ b/src/HighScore.cpp @@ -17,10 +17,10 @@ struct HighScoreImpl { RString sName; // name that shows in the machine's ranking screen Grade grade; - int iScore; + unsigned int iScore; float fPercentDP; float fSurviveSeconds; - int iMaxCombo; // maximum combo obtained [SM5 alpha 1a+] + unsigned int iMaxCombo; // maximum combo obtained [SM5 alpha 1a+] StageAward stageAward; // stage award [SM5 alpha 1a+] PeakComboAward peakComboAward; // peak combo award [SM5 alpha 1a+] RString sModifiers; @@ -191,8 +191,8 @@ bool HighScore::IsEmpty() const RString HighScore::GetName() const { return m_Impl->sName; } Grade HighScore::GetGrade() const { return m_Impl->grade; } -int HighScore::GetScore() const { return m_Impl->iScore; } -int HighScore::GetMaxCombo() const { return m_Impl->iMaxCombo; } +unsigned int HighScore::GetScore() const { return m_Impl->iScore; } +unsigned int HighScore::GetMaxCombo() const { return m_Impl->iMaxCombo; } StageAward HighScore::GetStageAward() const { return m_Impl->stageAward; } PeakComboAward HighScore::GetPeakComboAward() const { return m_Impl->peakComboAward; } float HighScore::GetPercentDP() const { return m_Impl->fPercentDP; } @@ -211,8 +211,8 @@ bool HighScore::GetDisqualified() const { return m_Impl->bDisqualified; } void HighScore::SetName( const RString &sName ) { m_Impl->sName = sName; } void HighScore::SetGrade( Grade g ) { m_Impl->grade = g; } -void HighScore::SetScore( int iScore ) { m_Impl->iScore = iScore; } -void HighScore::SetMaxCombo( int i ) { m_Impl->iMaxCombo = i; } +void HighScore::SetScore( unsigned int iScore ) { m_Impl->iScore = iScore; } +void HighScore::SetMaxCombo( unsigned int i ) { m_Impl->iMaxCombo = i; } void HighScore::SetStageAward( StageAward a ) { m_Impl->stageAward = a; } void HighScore::SetPeakComboAward( PeakComboAward a ) { m_Impl->peakComboAward = a; } void HighScore::SetPercentDP( float f ) { m_Impl->fPercentDP = f; } diff --git a/src/HighScore.h b/src/HighScore.h index c3e8ed86bc..568ad191ea 100644 --- a/src/HighScore.h +++ b/src/HighScore.h @@ -30,7 +30,7 @@ struct HighScore /** * @brief Retrieve the score earned. * @return the score. */ - int GetScore() const; + unsigned int GetScore() const; /** * @brief Determine if any judgments were tallied during this run. * @return true if no judgments were recorded, false otherwise. */ @@ -41,7 +41,7 @@ struct HighScore * @return the number of seconds left. */ float GetSurviveSeconds() const; float GetSurvivalSeconds() const; - int GetMaxCombo() const; + unsigned int GetMaxCombo() const; StageAward GetStageAward() const; PeakComboAward GetPeakComboAward() const; /** @@ -66,10 +66,10 @@ struct HighScore * @param sName the name of the Player. */ void SetName( const RString &sName ); void SetGrade( Grade g ); - void SetScore( int iScore ); + void SetScore( unsigned int iScore ); void SetPercentDP( float f ); void SetAliveSeconds( float f ); - void SetMaxCombo( int i ); + void SetMaxCombo( unsigned int i ); void SetStageAward( StageAward a ); void SetPeakComboAward( PeakComboAward a ); void SetModifiers( RString s ); diff --git a/src/Inventory.cpp b/src/Inventory.cpp index 5124d15c33..aabb821bad 100644 --- a/src/Inventory.cpp +++ b/src/Inventory.cpp @@ -25,7 +25,7 @@ ThemeMetric ITEM_USE_RATE_SECONDS("Inventory","ItemUseRateSeconds"); struct Item { AttackLevel level; - int iCombo; + unsigned int iCombo; RString sModifier; }; static vector g_Items; @@ -100,9 +100,9 @@ void Inventory::Update( float fDelta ) // check to see if they deserve a new item if( STATSMAN->m_CurStageStats.m_player[pn].m_iCurCombo != m_iLastSeenCombo ) { - int iOldCombo = m_iLastSeenCombo; + unsigned int iOldCombo = m_iLastSeenCombo; m_iLastSeenCombo = STATSMAN->m_CurStageStats.m_player[pn].m_iCurCombo; - int iNewCombo = m_iLastSeenCombo; + unsigned int iNewCombo = m_iLastSeenCombo; #define CROSSED(i) (iOldCombo=i) #define BROKE_ABOVE(i) (iNewCombo=i) diff --git a/src/Inventory.h b/src/Inventory.h index 5ad36dfe71..93712c3e17 100644 --- a/src/Inventory.h +++ b/src/Inventory.h @@ -28,7 +28,7 @@ protected: void AwardItem( int iItemIndex ); PlayerState* m_pPlayerState; - int m_iLastSeenCombo; + unsigned int m_iLastSeenCombo; /** @brief a sound played when an item has been acquired. */ RageSound m_soundAcquireItem; diff --git a/src/LuaManager.cpp b/src/LuaManager.cpp index 3e703474fb..116e9d8d1b 100644 --- a/src/LuaManager.cpp +++ b/src/LuaManager.cpp @@ -81,6 +81,7 @@ namespace LuaHelpers template<> void Push( lua_State *L, const bool &Object ) { lua_pushboolean( L, Object ); } template<> void Push( lua_State *L, const float &Object ) { lua_pushnumber( L, Object ); } template<> void Push( lua_State *L, const int &Object ) { lua_pushinteger( L, Object ); } + template<> void Push( lua_State *L, const unsigned int &Object ) { lua_pushnumber( L, double(Object) ); } template<> void Push( lua_State *L, const RString &Object ) { lua_pushlstring( L, Object.data(), Object.size() ); } template<> bool FromStack( Lua *L, bool &Object, int iOffset ) { Object = !!lua_toboolean( L, iOffset ); return true; } diff --git a/src/Player.cpp b/src/Player.cpp index 6c8a3bfc56..83634f4191 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -371,6 +371,7 @@ void Player::Init( m_pSecondaryScoreKeeper = pSecondaryScoreKeeper; m_iLastSeenCombo = -1; + m_bSeenComboYet = false; // set initial life if( m_pLifeMeter && m_pPlayerStageStats ) @@ -763,10 +764,10 @@ void Player::Load() m_pIterUnjudgedMineRows = new NoteData::all_tracks_iterator( m_NoteData.GetTapNoteRangeAllTracks(iNoteRow, MAX_NOTE_ROW ) ); } -void Player::SendComboMessages( int iOldCombo, int iOldMissCombo ) +void Player::SendComboMessages( unsigned int iOldCombo, unsigned int iOldMissCombo ) { - const int iCurCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; - if( iOldCombo > COMBO_STOPPED_AT && iCurCombo < COMBO_STOPPED_AT ) + const unsigned int iCurCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; + if( iOldCombo > (unsigned int)COMBO_STOPPED_AT && iCurCombo < (unsigned int)COMBO_STOPPED_AT ) { SCREENMAN->PostMessageToTopScreen( SM_ComboStopped, 0 ); } @@ -1410,7 +1411,7 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorTrace("initiated note and didn't let go"); fLife = 1; // xxx: should be MAX_HOLD_LIFE instead? -aj hns = HNS_Held; - bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->m_iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD; + bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->m_iCurCombo>(unsigned int)BRIGHT_GHOST_COMBO_THRESHOLD; if( m_pNoteField ) { FOREACH( TrackRowTapNote, vTN, trtn ) @@ -1462,19 +1463,7 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorm_iCurCombo : 0; - const int iOldMissCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurMissCombo : 0; - - if( m_pPlayerStageStats ) - { - m_pPlayerStageStats->m_iCurCombo = 0; - m_pPlayerStageStats->m_iCurMissCombo++; - SetCombo( m_pPlayerStageStats->m_iCurCombo, m_pPlayerStageStats->m_iCurMissCombo ); - } - - SendComboMessages( iOldCombo, iOldMissCombo ); - } + IncrementMissCombo(); if( hns != HNS_None ) { @@ -1918,8 +1907,8 @@ void Player::DoTapScoreNone() Message msg( "ScoreNone" ); MESSAGEMAN->Broadcast( msg ); - const int iOldCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; - const int iOldMissCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurMissCombo : 0; + const unsigned int iOldCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; + const unsigned int iOldMissCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurMissCombo : 0; /* The only real way to tell if a mine has been scored is if it has disappeared * but this only works for hit mines so update the scores for avoided mines here. */ @@ -2105,21 +2094,9 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b if( ROLL_BODY_INCREMENTS_COMBO && m_pPlayerState->m_PlayerController != PC_AUTOPLAY ) { - // increment combo - const int iOldCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; - const int iOldMissCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurMissCombo : 0; - - if( m_pPlayerStageStats ) - { - m_pPlayerStageStats->m_iCurCombo++; - m_pPlayerStageStats->m_iCurMissCombo = 0; - } - - SendComboMessages( iOldCombo, iOldMissCombo ); - if( m_pPlayerStageStats ) - SetCombo( m_pPlayerStageStats->m_iCurCombo, m_pPlayerStageStats->m_iCurMissCombo ); - - bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->m_iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD; + IncrementCombo(); + + bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->m_iCurCombo>(unsigned int)BRIGHT_GHOST_COMBO_THRESHOLD; if( m_pNoteField ) m_pNoteField->DidHoldNote( col, HNS_Held, bBright ); } @@ -2576,7 +2553,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b const bool bBlind = (m_pPlayerState->m_PlayerOptions.GetCurrent().m_fBlind != 0); // XXX: This is the wrong combo for shared players. // STATSMAN->m_CurStageStats.m_Player[pn] might work, but could be wrong. - const bool bBright = ( m_pPlayerStageStats && m_pPlayerStageStats->m_iCurCombo > int(BRIGHT_GHOST_COMBO_THRESHOLD) ) || bBlind; + const bool bBright = ( m_pPlayerStageStats && m_pPlayerStageStats->m_iCurCombo > (unsigned int)BRIGHT_GHOST_COMBO_THRESHOLD ) || bBlind; if( m_pNoteField ) m_pNoteField->DidTapNote( col, bBlind? TNS_W1:score, bBright ); if( score >= m_pPlayerState->m_PlayerOptions.GetCurrent().m_MinTNSToHideNotes || bBlind ) @@ -2915,7 +2892,7 @@ void Player::FlashGhostRow( int iRow ) { TapNoteScore lastTNS = NoteDataWithScoring::LastTapNoteWithResult( m_NoteData, iRow ).result.tns; const bool bBlind = (m_pPlayerState->m_PlayerOptions.GetCurrent().m_fBlind != 0); - const bool bBright = ( m_pPlayerStageStats && m_pPlayerStageStats->m_iCurCombo > int(BRIGHT_GHOST_COMBO_THRESHOLD) ) || bBlind; + const bool bBright = ( m_pPlayerStageStats && m_pPlayerStageStats->m_iCurCombo > (unsigned int)BRIGHT_GHOST_COMBO_THRESHOLD ) || bBlind; for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack ) { @@ -3104,8 +3081,8 @@ void Player::HandleTapRowScore( unsigned row ) return; TapNoteScore scoreOfLastTap = NoteDataWithScoring::LastTapNoteWithResult(m_NoteData, row).result.tns; - const int iOldCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; - const int iOldMissCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurMissCombo : 0; + const unsigned int iOldCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; + const unsigned int iOldMissCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurMissCombo : 0; if( scoreOfLastTap == TNS_Miss ) m_LastTapNoteScore = TNS_Miss; @@ -3130,8 +3107,8 @@ void Player::HandleTapRowScore( unsigned row ) if( m_pSecondaryScoreKeeper != NULL ) m_pSecondaryScoreKeeper->HandleTapRowScore( m_NoteData, row ); - const int iCurCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; - const int iCurMissCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurMissCombo : 0; + const unsigned int iCurCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; + const unsigned int iCurMissCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurMissCombo : 0; SendComboMessages( iOldCombo, iOldMissCombo ); @@ -3211,8 +3188,8 @@ void Player::HandleHoldCheckpoint(int iRow, if( bNoCheating && m_pPlayerState->m_PlayerController == PC_AUTOPLAY ) return; - const int iOldCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; - const int iOldMissCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurMissCombo : 0; + const unsigned int iOldCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; + const unsigned int iOldMissCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurMissCombo : 0; if( m_pPrimaryScoreKeeper ) m_pPrimaryScoreKeeper->HandleHoldCheckpointScore(m_NoteData, @@ -3233,7 +3210,7 @@ void Player::HandleHoldCheckpoint(int iRow, FOREACH_CONST( int, viColsWithHold, i ) { bool bBright = m_pPlayerStageStats - && m_pPlayerStageStats->m_iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD; + && m_pPlayerStageStats->m_iCurCombo>(unsigned int)BRIGHT_GHOST_COMBO_THRESHOLD; if( m_pNoteField ) m_pNoteField->DidHoldNote( *i, HNS_Held, bBright ); } @@ -3402,17 +3379,20 @@ void Player::SetHoldJudgment( TapNote &tn, int iTrack ) } } -void Player::SetCombo( int iCombo, int iMisses ) +void Player::SetCombo( unsigned int iCombo, unsigned int iMisses ) { - if( m_iLastSeenCombo == -1 ) // first update, don't set bIsMilestone=true + if( !m_bSeenComboYet ) // first update, don't set bIsMilestone=true + { + m_bSeenComboYet = true; m_iLastSeenCombo = iCombo; - + } + bool b25Milestone = false; bool b50Milestone = false; bool b100Milestone = false; bool b250Milestone = false; bool b1000Milestone = false; - for( int i=m_iLastSeenCombo+1; i<=iCombo; i++ ) + for( unsigned int i=m_iLastSeenCombo+1; i<=iCombo; i++ ) { if( i < 600 ) { @@ -3484,6 +3464,29 @@ void Player::SetCombo( int iCombo, int iMisses ) } } +void Player::IncrementComboOrMissCombo(bool bComboOrMissCombo) +{ + const unsigned int iOldCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; + const unsigned int iOldMissCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurMissCombo : 0; + + if( m_pPlayerStageStats ) + { + if( bComboOrMissCombo ) + { + m_pPlayerStageStats->m_iCurCombo++; + m_pPlayerStageStats->m_iCurMissCombo = 0; + } + else + { + m_pPlayerStageStats->m_iCurCombo = 0; + m_pPlayerStageStats->m_iCurMissCombo++; + } + SetCombo( m_pPlayerStageStats->m_iCurCombo, m_pPlayerStageStats->m_iCurMissCombo ); + } + + SendComboMessages( iOldCombo, iOldMissCombo ); +} + RString Player::ApplyRandomAttack() { if( GAMESTATE->m_RandomAttacks.size() < 1 ) diff --git a/src/Player.h b/src/Player.h index 9d75b98235..acdb82bed2 100644 --- a/src/Player.h +++ b/src/Player.h @@ -128,14 +128,17 @@ protected: void HandleHoldCheckpoint( int iRow, int iNumHoldsHeldThisRow, int iNumHoldsMissedThisRow, const vector &viColsWithHold ); void DrawTapJudgments(); void DrawHoldJudgments(); - void SendComboMessages( int iOldCombo, int iOldMissCombo ); + void SendComboMessages( unsigned int iOldCombo, unsigned int iOldMissCombo ); void PlayKeysound( const TapNote &tn, TapNoteScore score ); void SetMineJudgment( TapNoteScore tns , int iTrack ); void SetJudgment( int iRow, int iFirstTrack, const TapNote &tn ) { SetJudgment( iRow, iFirstTrack, tn, tn.result.tns, tn.result.fTapNoteOffset ); } void SetJudgment( int iRow, int iFirstTrack, const TapNote &tn, TapNoteScore tns, float fTapNoteOffset ); // -1 if no track as in TNS_Miss void SetHoldJudgment( TapNote &tn, int iTrack ); - void SetCombo( int iCombo, int iMisses ); + void SetCombo( unsigned int iCombo, unsigned int iMisses ); + void IncrementComboOrMissCombo( bool bComboOrMissCombo ); + void IncrementCombo() { IncrementComboOrMissCombo(true); }; + void IncrementMissCombo() { IncrementComboOrMissCombo(false); }; void ChangeLife( TapNoteScore tns ); void ChangeLife( HoldNoteScore hns, TapNoteScore tns ); @@ -194,7 +197,8 @@ protected: NoteData::all_tracks_iterator *m_pIterUncrossedRows; NoteData::all_tracks_iterator *m_pIterUnjudgedRows; NoteData::all_tracks_iterator *m_pIterUnjudgedMineRows; - int m_iLastSeenCombo; + unsigned int m_iLastSeenCombo; + bool m_bSeenComboYet; JudgedRows *m_pJudgedRows; RageSound m_soundMine; diff --git a/src/PlayerStageStats.h b/src/PlayerStageStats.h index d0ef051395..53482124b5 100644 --- a/src/PlayerStageStats.h +++ b/src/PlayerStageStats.h @@ -63,18 +63,18 @@ public: int m_iTapNoteScores[NUM_TapNoteScore]; int m_iHoldNoteScores[NUM_HoldNoteScore]; /** @brief The Player's current combo. */ - int m_iCurCombo; + unsigned int m_iCurCombo; /** @brief The Player's max combo. */ - int m_iMaxCombo; + unsigned int m_iMaxCombo; /** @brief The Player's current miss combo. */ - int m_iCurMissCombo; + unsigned int m_iCurMissCombo; int m_iCurScoreMultiplier; /** @brief The player's current score. */ - int m_iScore; + unsigned int m_iScore; /** @brief The theoretically highest score the Player could have at this point. */ - int m_iCurMaxScore; + unsigned int m_iCurMaxScore; /** @brief The maximum score the Player can get this goaround. */ - int m_iMaxScore; + unsigned int m_iMaxScore; /** * @brief The possible RadarValues for a song. diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index 6cb4e42ec0..78286933cb 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -260,8 +260,8 @@ void ScoreKeeperNormal::AddScoreInternal( TapNoteScore score ) if( m_UseInternalScoring ) { - int &iScore = m_pPlayerStageStats->m_iScore; - int &iCurMaxScore = m_pPlayerStageStats->m_iCurMaxScore; + unsigned int &iScore = m_pPlayerStageStats->m_iScore; + unsigned 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. @@ -277,8 +277,8 @@ void ScoreKeeperNormal::AddScoreInternal( TapNoteScore score ) m_iTapNotesHit++; - const int N = m_iNumTapsAndHolds; - const int sum = (N * (N + 1)) / 2; + const uint64_t N = uint64_t(m_iNumTapsAndHolds); + const int sum = int((N * (N + 1)) / 2); const int Z = m_iMaxPossiblePoints/10; // Don't use a multiplier if the player has failed @@ -320,15 +320,11 @@ void ScoreKeeperNormal::AddScoreInternal( TapNoteScore score ) 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" ); - // LOG->Trace( "score: %i", iScore ); } } diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index a821eb2aac..1a8bd1e974 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -1846,7 +1846,7 @@ void ScreenGameplay::Update( float fDeltaTime ) } if (bAllHumanHaveBigMissCombo) // possible to get in here. { - bAllHumanHaveBigMissCombo = FAIL_ON_MISS_COMBO.GetValue() != -1 && STATSMAN->m_CurStageStats.GetMinimumMissCombo() >= FAIL_ON_MISS_COMBO; + bAllHumanHaveBigMissCombo = FAIL_ON_MISS_COMBO.GetValue() != -1 && STATSMAN->m_CurStageStats.GetMinimumMissCombo() >= (unsigned int)FAIL_ON_MISS_COMBO; } if( bGiveUpTimerFired || bAllHumanHaveBigMissCombo ) { diff --git a/src/StageStats.cpp b/src/StageStats.cpp index 348b0c0ecb..8cd894129b 100644 --- a/src/StageStats.cpp +++ b/src/StageStats.cpp @@ -334,9 +334,9 @@ bool StageStats::PlayerHasHighScore( PlayerNumber pn ) const return false; } -int StageStats::GetMinimumMissCombo() const +unsigned int StageStats::GetMinimumMissCombo() const { - int iMin = INT_MAX; + unsigned int iMin = INT_MAX; FOREACH_HumanPlayer( p ) iMin = min( iMin, m_player[p].m_iCurMissCombo ); return iMin; diff --git a/src/StageStats.h b/src/StageStats.h index a5a52587ef..60db5b32cc 100644 --- a/src/StageStats.h +++ b/src/StageStats.h @@ -75,7 +75,7 @@ public: * @param pn the PlayerNumber in question. * @return true if the PlayerNumber has a high score, false otherwise. */ bool PlayerHasHighScore( PlayerNumber pn ) const; - int GetMinimumMissCombo() const; + unsigned int GetMinimumMissCombo() const; // Lua void PushSelf( lua_State *L );