diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index 8bfa297405..9daf0abed6 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -1032,45 +1032,6 @@ StageResult GameState::GetStageResult( PlayerNumber pn ) const return win; } -void GameState::GetFinalEvalStats( StageStats& statsOut ) const -{ - statsOut.Init(); - - // Show stats only for the latest 3 normal songs + passed extra stages - int PassedRegularSongsLeft = 3; - for( int i = (int)STATSMAN->m_vPlayedStageStats.size()-1; i >= 0; --i ) - { - const StageStats &s = STATSMAN->m_vPlayedStageStats[i]; - - if( !s.OnePassed() ) - continue; - - if( s.StageType == StageStats::STAGE_NORMAL ) - { - if( PassedRegularSongsLeft == 0 ) - break; - - --PassedRegularSongsLeft; - } - - statsOut.AddStats( s ); - } - - if( statsOut.vpSongs.empty() ) return; // don't divide by 0 below - - /* Scale radar percentages back down to roughly 0..1. Don't scale RADAR_NUM_TAPS_AND_HOLDS - * and the rest, which are counters. */ - // FIXME: Weight each song by the number of stages it took to account for - // long, marathon. - FOREACH_EnabledPlayer( pn ) - { - for( int r = 0; r < RADAR_NUM_TAPS_AND_HOLDS; r++) - { - statsOut.m_player[pn].radarPossible[r] /= statsOut.vpSongs.size(); - statsOut.m_player[pn].radarActual[r] /= statsOut.vpSongs.size(); - } - } -} void GameState::ApplyModifiers( PlayerNumber pn, CString sModifiers ) @@ -1503,7 +1464,7 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector &asFeatsOu CHECKPOINT; StageStats stats; - GetFinalEvalStats( stats ); + STATSMAN->GetFinalEvalStageStats( stats ); // Find Machine Category Records diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index d78f9a9d4a..a52671128b 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -186,7 +186,6 @@ public: StageResult GetStageResult( PlayerNumber pn ) const; void ResetStageStatistics(); // Call this when it's time to play a new stage. - void GetFinalEvalStats( StageStats& statsOut ) const; // shown on final evaluation // diff --git a/stepmania/src/ScreenEvaluation.cpp b/stepmania/src/ScreenEvaluation.cpp index 8bb847b603..ab739cca86 100644 --- a/stepmania/src/ScreenEvaluation.cpp +++ b/stepmania/src/ScreenEvaluation.cpp @@ -202,11 +202,13 @@ void ScreenEvaluation::Init() // // Figure out which statistics and songs we're going to display // + STATSMAN->CalcAccumStageStats(); + StageStats stageStats; switch( m_Type ) { case summary: - GAMESTATE->GetFinalEvalStats( stageStats ); + STATSMAN->GetFinalEvalStageStats( stageStats ); break; case stage: case course: diff --git a/stepmania/src/StatsManager.cpp b/stepmania/src/StatsManager.cpp index 1d1333c7d0..2736e8d66c 100644 --- a/stepmania/src/StatsManager.cpp +++ b/stepmania/src/StatsManager.cpp @@ -1,6 +1,7 @@ #include "global.h" #include "StatsManager.h" #include "GameState.h" +#include "Foreach.h" StatsManager* STATSMAN = NULL; // global object accessable from anywhere in the program @@ -9,6 +10,69 @@ StatsManager::StatsManager() { } +StageStats AccumStageStats( const vector& vss ) +{ + StageStats ssreturn; + + FOREACH_CONST( StageStats, vss, ss ) + ssreturn.AddStats( *ss ); + + unsigned uNumSongs = ssreturn.vpSongs.size(); + + if( uNumSongs == 0 ) return ssreturn; // don't divide by 0 below + + /* Scale radar percentages back down to roughly 0..1. Don't scale RADAR_NUM_TAPS_AND_HOLDS + * and the rest, which are counters. */ + // FIXME: Weight each song by the number of stages it took to account for + // long, marathon. + FOREACH_EnabledPlayer( pn ) + { + for( int r = 0; r < RADAR_NUM_TAPS_AND_HOLDS; r++) + { + ssreturn.m_player[pn].radarPossible[r] /= uNumSongs; + ssreturn.m_player[pn].radarActual[r] /= uNumSongs; + } + } + + return ssreturn; +} + +void StatsManager::GetFinalEvalStageStats( StageStats& statsOut ) const +{ + statsOut.Init(); + + vector vssToCount; + + // Show stats only for the latest 3 normal songs + passed extra stages + int PassedRegularSongsLeft = 3; + for( int i = (int)m_vPlayedStageStats.size()-1; i >= 0; --i ) + { + const StageStats &ss = m_vPlayedStageStats[i]; + + if( !ss.OnePassed() ) + continue; + + if( ss.StageType == StageStats::STAGE_NORMAL ) + { + if( PassedRegularSongsLeft == 0 ) + break; + + --PassedRegularSongsLeft; + } + + vssToCount.push_back( ss ); + } + + statsOut = AccumStageStats( vssToCount ); +} + + +void StatsManager::CalcAccumStageStats() +{ + m_AccumStageStats = AccumStageStats( m_vPlayedStageStats ); +} + + // lua start #include "LuaBinding.h" @@ -19,10 +83,12 @@ public: LunaStatsManager() { LUA->Register( Register ); } static int GetCurStageStats( T* p, lua_State *L ) { p->m_CurStageStats.PushSelf(L); return 1; } + static int GetAccumStageStats( T* p, lua_State *L ) { p->GetAccumStageStats().PushSelf(L); return 1; } static void Register(lua_State *L) { ADD_METHOD( GetCurStageStats ) + ADD_METHOD( GetAccumStageStats ) Luna::Register( L ); // Add global singleton if constructed already. If it's not constructed yet, @@ -109,7 +175,7 @@ Grade GetFinalGrade( PlayerNumber pn ) if( !GAMESTATE->IsHumanPlayer(pn) ) return GRADE_NO_DATA; StageStats stats; - GAMESTATE->GetFinalEvalStats( stats ); + STATSMAN->GetFinalEvalStageStats( stats ); return stats.m_player[pn].GetGrade(); } LuaFunction_PlayerNumber( GetFinalGrade, GetFinalGrade(pn) ); @@ -118,7 +184,7 @@ Grade GetBestFinalGrade() { Grade top_grade = GRADE_FAILED; StageStats stats; - GAMESTATE->GetFinalEvalStats( stats ); + STATSMAN->GetFinalEvalStageStats( stats ); FOREACH_HumanPlayer( p ) top_grade = min( top_grade, stats.m_player[p].GetGrade() ); return top_grade; diff --git a/stepmania/src/StatsManager.h b/stepmania/src/StatsManager.h index 708eb6aa75..eafeb4a6e1 100644 --- a/stepmania/src/StatsManager.h +++ b/stepmania/src/StatsManager.h @@ -13,8 +13,20 @@ public: StageStats m_CurStageStats; // current stage (not necessarily passed if Extra Stage) vector m_vPlayedStageStats; + // Only the latest 3 normal songs + passed extra stages. + void GetFinalEvalStageStats( StageStats& statsOut ) const; + + // All stages played. Returns a ref to the private member so that + // the object will remain alive while Lua is operating on it. + void CalcAccumStageStats(); + StageStats& GetAccumStageStats() { return m_AccumStageStats; } + // Lua void PushSelf( lua_State *L ); + +private: + StageStats m_AccumStageStats; + StageStats m_FinalEvalStageStats; };