fix incorrect song counts for courses
cleanup: make StageStats hold a list of Songs and Steps that were played during the stage
This commit is contained in:
+42
-49
@@ -227,19 +227,6 @@ void GameState::BeginGame()
|
||||
MEMCARDMAN->LockCards( false );
|
||||
}
|
||||
|
||||
void CheckStageStats( const StageStats &ss, int p )
|
||||
{
|
||||
if( ss.pSong )
|
||||
CHECKPOINT_M( ss.pSong->GetFullTranslitTitle() );
|
||||
ASSERT( ss.pSteps[p] );
|
||||
ASSERT_M( ss.playMode < NUM_PLAY_MODES, ssprintf("playmode %i", ss.playMode) );
|
||||
ASSERT( ss.pStyle != NULL );
|
||||
ASSERT_M( ss.pSteps[p]->GetDifficulty() < NUM_DIFFICULTIES, ssprintf("difficulty %i", ss.pSteps[p]->GetDifficulty()) );
|
||||
/* Meter values can exceed MAX_METER; MAX_METER is just the highest meter value we
|
||||
* display/track. */
|
||||
// ASSERT_M( ss.iMeter[p] < MAX_METER+1, ssprintf("%i", ss.iMeter[p]) );
|
||||
}
|
||||
|
||||
void GameState::PlayersFinalized()
|
||||
{
|
||||
if( m_bPlayersFinalized )
|
||||
@@ -288,33 +275,43 @@ void GameState::PlayersFinalized()
|
||||
}
|
||||
|
||||
/* This data is added to each player profile, and to the machine profile per-player. */
|
||||
void AddPlayerStatsToProfile( Profile *pProfile, const StageStats &ss, PlayerNumber p )
|
||||
void AddPlayerStatsToProfile( Profile *pProfile, const StageStats &ss, PlayerNumber pn )
|
||||
{
|
||||
CheckStageStats( ss, p );
|
||||
ss.AssertValid( pn );
|
||||
CHECKPOINT;
|
||||
const int iMeter = clamp( ss.iMeter[p], 0, MAX_METER );
|
||||
|
||||
pProfile->m_iNumSongsPlayedByPlayMode[ss.playMode]++;
|
||||
StyleID sID;
|
||||
sID.FromStyle( ss.pStyle );
|
||||
pProfile->m_iNumSongsPlayedByStyle[sID]++;
|
||||
pProfile->m_iNumSongsPlayedByDifficulty[ss.pSteps[p]->GetDifficulty()]++;
|
||||
pProfile->m_iNumSongsPlayedByMeter[iMeter]++;
|
||||
pProfile->m_iTotalDancePoints += ss.iActualDancePoints[p];
|
||||
|
||||
ASSERT( ss.vpSongs.size() == ss.vpSteps[pn].size() );
|
||||
for( unsigned i=0; i<ss.vpSongs.size(); i++ )
|
||||
{
|
||||
Song *pSong = ss.vpSongs[i];
|
||||
Steps *pSteps = ss.vpSteps[pn][i];
|
||||
|
||||
pProfile->m_iNumSongsPlayedByPlayMode[ss.playMode]++;
|
||||
pProfile->m_iNumSongsPlayedByStyle[sID] ++;
|
||||
pProfile->m_iNumSongsPlayedByDifficulty[pSteps->GetDifficulty()] ++;
|
||||
pProfile->m_iNumSongsPlayedByMeter[pSteps->GetMeter()] ++;
|
||||
}
|
||||
|
||||
pProfile->m_iTotalDancePoints += ss.iActualDancePoints[pn];
|
||||
|
||||
if( ss.StageType == StageStats::STAGE_EXTRA || ss.StageType == StageStats::STAGE_EXTRA2 )
|
||||
{
|
||||
if( ss.bFailed[p] )
|
||||
if( ss.bFailed[pn] )
|
||||
++pProfile->m_iNumExtraStagesFailed;
|
||||
else
|
||||
++pProfile->m_iNumExtraStagesPassed;
|
||||
}
|
||||
|
||||
if( !ss.bFailed[p] )
|
||||
{
|
||||
pProfile->m_iNumSongsPassedByPlayMode[ss.playMode]++;
|
||||
pProfile->m_iNumSongsPassedByGrade[ss.GetGrade(p)]++;
|
||||
}
|
||||
// If you fail in a course, you passed all but the final song.
|
||||
// FIXME: Not true. If playing with 2 players, one player could have failed earlier.
|
||||
int iNumSongsPassed = ss.vpSongs.size();
|
||||
if( ss.bFailed[pn] )
|
||||
iNumSongsPassed -= 1;
|
||||
pProfile->m_iNumSongsPassedByPlayMode[ss.playMode] += iNumSongsPassed;
|
||||
pProfile->m_iNumSongsPassedByGrade[ss.GetGrade(pn)] += iNumSongsPassed;
|
||||
}
|
||||
|
||||
void GameState::EndGame()
|
||||
@@ -1013,9 +1010,9 @@ StageResult GameState::GetStageResult( PlayerNumber pn ) const
|
||||
return win;
|
||||
}
|
||||
|
||||
void GameState::GetFinalEvalStatsAndSongs( StageStats& statsOut, vector<Song*>& vSongsOut ) const
|
||||
void GameState::GetFinalEvalStats( StageStats& statsOut ) const
|
||||
{
|
||||
statsOut = StageStats();
|
||||
statsOut.Init();
|
||||
|
||||
// Show stats only for the latest 3 normal songs + passed extra stages
|
||||
int PassedRegularSongsLeft = 3;
|
||||
@@ -1035,11 +1032,9 @@ void GameState::GetFinalEvalStatsAndSongs( StageStats& statsOut, vector<Song*>&
|
||||
}
|
||||
|
||||
statsOut.AddStats( s );
|
||||
|
||||
vSongsOut.insert( vSongsOut.begin(), s.pSong );
|
||||
}
|
||||
|
||||
if(!vSongsOut.size()) return;
|
||||
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. */
|
||||
@@ -1047,8 +1042,8 @@ void GameState::GetFinalEvalStatsAndSongs( StageStats& statsOut, vector<Song*>&
|
||||
{
|
||||
for( int r = 0; r < RADAR_NUM_TAPS_AND_HOLDS; r++)
|
||||
{
|
||||
statsOut.radarPossible[p][r] /= vSongsOut.size();
|
||||
statsOut.radarActual[p][r] /= vSongsOut.size();
|
||||
statsOut.radarPossible[p][r] /= statsOut.vpSongs.size();
|
||||
statsOut.radarActual[p][r] /= statsOut.vpSongs.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1386,7 +1381,6 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
|
||||
case PLAY_MODE_REGULAR:
|
||||
{
|
||||
CHECKPOINT;
|
||||
unsigned i, j;
|
||||
|
||||
StepsType st = this->GetCurrentStyle()->m_StepsType;
|
||||
|
||||
@@ -1397,13 +1391,13 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
|
||||
//
|
||||
vector<SongAndSteps> vSongAndSteps;
|
||||
|
||||
for( i=0; i<g_vPlayedStageStats.size(); i++ )
|
||||
for( unsigned i=0; i<g_vPlayedStageStats.size(); i++ )
|
||||
{
|
||||
CHECKPOINT_M( ssprintf("%u/%i", i, (int)g_vPlayedStageStats.size() ) );
|
||||
SongAndSteps sas;
|
||||
sas.pSong = g_vPlayedStageStats[i].pSong;
|
||||
sas.pSong = g_vPlayedStageStats[i].vpSongs[0];
|
||||
ASSERT( sas.pSong );
|
||||
sas.pSteps = g_vPlayedStageStats[i].pSteps[pn];
|
||||
sas.pSteps = g_vPlayedStageStats[i].vpSteps[pn][0];
|
||||
ASSERT( sas.pSteps );
|
||||
vSongAndSteps.push_back( sas );
|
||||
}
|
||||
@@ -1415,7 +1409,7 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
|
||||
vSongAndSteps.erase(toDelete, vSongAndSteps.end());
|
||||
|
||||
CHECKPOINT;
|
||||
for( i=0; i<vSongAndSteps.size(); i++ )
|
||||
for( unsigned i=0; i<vSongAndSteps.size(); i++ )
|
||||
{
|
||||
Song* pSong = vSongAndSteps[i].pSong;
|
||||
Steps* pSteps = vSongAndSteps[i].pSteps;
|
||||
@@ -1423,7 +1417,7 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
|
||||
// Find Machine Records
|
||||
{
|
||||
HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSong,pSteps);
|
||||
for( j=0; j<hsl.vHighScores.size(); j++ )
|
||||
for( unsigned j=0; j<hsl.vHighScores.size(); j++ )
|
||||
{
|
||||
HighScore &hs = hsl.vHighScores[j];
|
||||
|
||||
@@ -1451,7 +1445,7 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
|
||||
if( pProf )
|
||||
{
|
||||
HighScoreList &hsl = pProf->GetStepsHighScoreList(pSong,pSteps);
|
||||
for( j=0; j<hsl.vHighScores.size(); j++ )
|
||||
for( unsigned j=0; j<hsl.vHighScores.size(); j++ )
|
||||
{
|
||||
HighScore &hs = hsl.vHighScores[j];
|
||||
|
||||
@@ -1481,8 +1475,7 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
|
||||
|
||||
CHECKPOINT;
|
||||
StageStats stats;
|
||||
vector<Song*> vSongs;
|
||||
GetFinalEvalStatsAndSongs( stats, vSongs );
|
||||
GetFinalEvalStats( stats );
|
||||
|
||||
|
||||
// Find Machine Category Records
|
||||
@@ -1497,11 +1490,11 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
|
||||
|
||||
RankingFeat feat;
|
||||
feat.Type = RankingFeat::CATEGORY;
|
||||
feat.Feat = ssprintf("MR #%d in Type %c (%d)", j+1, 'A'+i, stats.iMeter[pn] );
|
||||
feat.Feat = ssprintf("MR #%d in Type %c (%d)", j+1, 'A'+rc, stats.GetAverageMeter(pn) );
|
||||
feat.pStringToFill = &hs.sName;
|
||||
feat.grade = GRADE_NO_DATA;
|
||||
feat.iScore = (int) hs.iScore;
|
||||
feat.fPercentDP = (float) hs.fPercentDP;
|
||||
feat.iScore = hs.iScore;
|
||||
feat.fPercentDP = hs.fPercentDP;
|
||||
asFeatsOut.push_back( feat );
|
||||
}
|
||||
}
|
||||
@@ -1520,11 +1513,11 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
|
||||
|
||||
RankingFeat feat;
|
||||
feat.Type = RankingFeat::CATEGORY;
|
||||
feat.Feat = ssprintf("PR #%d in Type %c (%d)", j+1, 'A'+i, stats.iMeter[pn] );
|
||||
feat.Feat = ssprintf("PR #%d in Type %c (%d)", j+1, 'A'+rc, stats.GetAverageMeter(pn) );
|
||||
feat.pStringToFill = &hs.sName;
|
||||
feat.grade = GRADE_NO_DATA;
|
||||
feat.iScore = (int) hs.iScore;
|
||||
feat.fPercentDP = (float) hs.fPercentDP;
|
||||
feat.iScore = hs.iScore;
|
||||
feat.fPercentDP = hs.fPercentDP;
|
||||
asFeatsOut.push_back( feat );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ public:
|
||||
StageResult GetStageResult( PlayerNumber pn ) const;
|
||||
|
||||
void ResetStageStatistics(); // Call this when it's time to play a new stage.
|
||||
void GetFinalEvalStatsAndSongs( StageStats& statsOut, vector<Song*>& vSongsOut ) const; // shown on arcade final evaluation
|
||||
void GetFinalEvalStats( StageStats& statsOut ) const; // shown on final evaluation
|
||||
|
||||
|
||||
//
|
||||
|
||||
@@ -338,11 +338,11 @@ void NetworkSyncManager::StartRequest(short position)
|
||||
unsigned char ctr=0;
|
||||
|
||||
Steps * tSteps;
|
||||
tSteps = g_CurStageStats.pSteps[PLAYER_1];
|
||||
tSteps = g_CurStageStats.vpSteps[PLAYER_1].back();
|
||||
if (tSteps!=NULL)
|
||||
ctr = uint8_t(ctr+tSteps->GetMeter()*16);
|
||||
|
||||
tSteps = g_CurStageStats.pSteps[PLAYER_2];
|
||||
tSteps = g_CurStageStats.vpSteps[PLAYER_2].back();
|
||||
if (tSteps!=NULL)
|
||||
ctr = uint8_t(ctr+tSteps->GetMeter());
|
||||
|
||||
|
||||
@@ -146,8 +146,8 @@ ScreenEnding::ScreenEnding( CString sClassName ) : ScreenAttract( sClassName, fa
|
||||
GAMESTATE->m_pCurCourse = SONGMAN->GetRandomCourse();
|
||||
GAMESTATE->m_pCurSteps[PLAYER_1] = GAMESTATE->m_pCurSong->GetAllSteps()[0];
|
||||
GAMESTATE->m_pCurSteps[PLAYER_2] = GAMESTATE->m_pCurSong->GetAllSteps()[0];
|
||||
g_CurStageStats.pSteps[PLAYER_1] = GAMESTATE->m_pCurSteps[PLAYER_1];
|
||||
g_CurStageStats.pSteps[PLAYER_2] = GAMESTATE->m_pCurSteps[PLAYER_2];
|
||||
g_CurStageStats.vpSteps[PLAYER_1].push_back( GAMESTATE->m_pCurSteps[PLAYER_1] );
|
||||
g_CurStageStats.vpSteps[PLAYER_2].push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
|
||||
GAMESTATE->m_PlayerOptions[PLAYER_1].m_fScrollSpeed = 2;
|
||||
GAMESTATE->m_PlayerOptions[PLAYER_2].m_fScrollSpeed = 2;
|
||||
GAMESTATE->m_iCurrentStageIndex = 0;
|
||||
|
||||
@@ -109,8 +109,8 @@ void ScreenEvaluation::Init()
|
||||
GAMESTATE->m_pCurCourse = SONGMAN->GetRandomCourse();
|
||||
GAMESTATE->m_pCurSteps[PLAYER_1] = GAMESTATE->m_pCurSong->GetAllSteps()[0];
|
||||
GAMESTATE->m_pCurSteps[PLAYER_2] = GAMESTATE->m_pCurSong->GetAllSteps()[0];
|
||||
g_CurStageStats.pSteps[PLAYER_1] = GAMESTATE->m_pCurSteps[PLAYER_1];
|
||||
g_CurStageStats.pSteps[PLAYER_2] = GAMESTATE->m_pCurSteps[PLAYER_2];
|
||||
g_CurStageStats.vpSteps[PLAYER_1].push_back( GAMESTATE->m_pCurSteps[PLAYER_1] );
|
||||
g_CurStageStats.vpSteps[PLAYER_2].push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
|
||||
GAMESTATE->m_PlayerOptions[PLAYER_1].m_fScrollSpeed = 2;
|
||||
GAMESTATE->m_PlayerOptions[PLAYER_2].m_fScrollSpeed = 2;
|
||||
GAMESTATE->m_iCurrentStageIndex = 0;
|
||||
@@ -189,12 +189,10 @@ void ScreenEvaluation::Init()
|
||||
// Figure out which statistics and songs we're going to display
|
||||
//
|
||||
StageStats stageStats;
|
||||
|
||||
vector<Song*> vSongsToShow;
|
||||
switch( m_Type )
|
||||
{
|
||||
case summary:
|
||||
GAMESTATE->GetFinalEvalStatsAndSongs( stageStats, vSongsToShow );
|
||||
GAMESTATE->GetFinalEvalStats( stageStats );
|
||||
break;
|
||||
case stage:
|
||||
case course:
|
||||
@@ -333,9 +331,11 @@ void ScreenEvaluation::Init()
|
||||
break;
|
||||
case summary:
|
||||
{
|
||||
for( unsigned i=0; i<vSongsToShow.size(); i++ )
|
||||
for( unsigned i=0; i<stageStats.vpSongs.size(); i++ )
|
||||
{
|
||||
m_SmallBanner[i].LoadFromSong( vSongsToShow[i] );
|
||||
Song *pSong = stageStats.vpSongs[i];
|
||||
|
||||
m_SmallBanner[i].LoadFromSong( pSong );
|
||||
m_SmallBanner[i].ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT );
|
||||
m_SmallBanner[i].SetName( ssprintf("SmallBanner%d",i+1) );
|
||||
SET_XY_AND_ON_COMMAND( m_SmallBanner[i] );
|
||||
@@ -959,7 +959,7 @@ void ScreenEvaluation::CommitScores(
|
||||
if( stageStats.bFailed[p] )
|
||||
continue;
|
||||
|
||||
float fAverageMeter = stageStats.iMeter[p] / (float)PREFSMAN->m_iNumArcadeStages;
|
||||
float fAverageMeter = stageStats.GetAverageMeter(p);
|
||||
rcOut[p] = AverageMeterToRankingCategory( fAverageMeter );
|
||||
|
||||
PROFILEMAN->AddCategoryScore( st, rcOut[p], p, hs, iPersonalHighScoreIndexOut[p], iMachineHighScoreIndexOut[p] );
|
||||
|
||||
@@ -221,15 +221,12 @@ void ScreenGameplay::Init()
|
||||
/* Called once per stage (single song or single course). */
|
||||
GAMESTATE->BeginStage();
|
||||
|
||||
g_CurStageStats.pSong = NULL; // set in LoadNextSong
|
||||
g_CurStageStats.playMode = GAMESTATE->m_PlayMode;
|
||||
g_CurStageStats.pStyle = GAMESTATE->m_pCurStyle;
|
||||
|
||||
FOREACH_EnabledPlayer(p)
|
||||
{
|
||||
ASSERT( !m_vpStepsQueue[p].empty() );
|
||||
g_CurStageStats.pSteps[p] = m_vpStepsQueue[p][0];
|
||||
g_CurStageStats.iMeter[p] = m_vpStepsQueue[p][0]->GetMeter();
|
||||
|
||||
/* Record combo rollover. */
|
||||
g_CurStageStats.UpdateComboList( p, 0, true );
|
||||
@@ -877,7 +874,7 @@ void ScreenGameplay::LoadNextSong()
|
||||
int iPlaySongIndex = GAMESTATE->GetCourseSongIndex();
|
||||
iPlaySongIndex %= m_apSongsQueue.size();
|
||||
GAMESTATE->m_pCurSong = m_apSongsQueue[iPlaySongIndex];
|
||||
g_CurStageStats.pSong = GAMESTATE->m_pCurSong;
|
||||
g_CurStageStats.vpSongs.push_back( GAMESTATE->m_pCurSong );
|
||||
|
||||
// No need to do this here. We do it in SongFinished().
|
||||
//GAMESTATE->RemoveAllActiveAttacks();
|
||||
@@ -899,7 +896,7 @@ void ScreenGameplay::LoadNextSong()
|
||||
|
||||
Song* pSong = GAMESTATE->m_pCurSong;
|
||||
Steps* pSteps = GAMESTATE->m_pCurSteps[p];
|
||||
g_CurStageStats.pSteps[p] = pSteps;
|
||||
g_CurStageStats.vpSteps[p].push_back( pSteps );
|
||||
|
||||
ASSERT( GAMESTATE->m_pCurSteps[p] );
|
||||
m_textStepsDescription[p].SetText( GAMESTATE->m_pCurSteps[p]->GetDescription() );
|
||||
|
||||
@@ -136,32 +136,32 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
|
||||
StageStats ss;
|
||||
for( int z = 0; z < 3; ++z )
|
||||
{
|
||||
ss.pSong = SONGMAN->GetRandomSong();
|
||||
ss.vpSongs.push_back( SONGMAN->GetRandomSong() );
|
||||
ss.iPossibleDancePoints[PLAYER_1] = 100;
|
||||
ss.iActualDancePoints[PLAYER_1] = 100;
|
||||
ss.iScore[PLAYER_1] = 100;
|
||||
ss.iPossibleDancePoints[PLAYER_2] = 100;
|
||||
ss.iActualDancePoints[PLAYER_2] = 100;
|
||||
ss.iScore[PLAYER_2] = 100;
|
||||
ASSERT( ss.pSong );
|
||||
ASSERT( ss.pSong->GetAllSteps().size() );
|
||||
ASSERT( ss.vpSongs[0]->GetAllSteps().size() );
|
||||
FOREACH_PlayerNumber( p )
|
||||
{
|
||||
GAMESTATE->m_pCurSteps[p] = ss.pSteps[p] = ss.pSong->GetAllSteps()[0];
|
||||
ss.vpSteps[p].push_back( ss.vpSongs[0]->GetAllSteps()[0] );
|
||||
GAMESTATE->m_pCurSteps[p] = ss.vpSteps[p][0];
|
||||
ss.iPossibleDancePoints[p] = 1000;
|
||||
ss.iActualDancePoints[p] = 985;
|
||||
|
||||
HighScore hs;
|
||||
hs.grade = GRADE_TIER_3;
|
||||
hs.fPercentDP = ss.GetPercentDancePoints((PlayerNumber)p);
|
||||
hs.fPercentDP = ss.GetPercentDancePoints(p);
|
||||
hs.iScore = ss.iScore[p];
|
||||
StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
|
||||
int a, b;
|
||||
PROFILEMAN->AddStepsScore( ss.pSong, GAMESTATE->m_pCurSteps[p], (PlayerNumber)p, hs, a, b );
|
||||
PROFILEMAN->AddStepsScore( ss.pSong, GAMESTATE->m_pCurSteps[p], (PlayerNumber)p, hs, a, b );
|
||||
PROFILEMAN->AddStepsScore( ss.pSong, GAMESTATE->m_pCurSteps[p], (PlayerNumber)p, hs, a, b );
|
||||
PROFILEMAN->AddStepsScore( ss.pSong, GAMESTATE->m_pCurSteps[p], (PlayerNumber)p, hs, a, b );
|
||||
PROFILEMAN->AddStepsScore( ss.pSong, GAMESTATE->m_pCurSteps[p], (PlayerNumber)p, hs, a, b );
|
||||
PROFILEMAN->AddStepsScore( ss.vpSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
|
||||
PROFILEMAN->AddStepsScore( ss.vpSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
|
||||
PROFILEMAN->AddStepsScore( ss.vpSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
|
||||
PROFILEMAN->AddStepsScore( ss.vpSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
|
||||
PROFILEMAN->AddStepsScore( ss.vpSongs[0], GAMESTATE->m_pCurSteps[p], p, hs, a, b );
|
||||
PROFILEMAN->AddCategoryScore( st, RANKING_A, p, hs, a, b );
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
|
||||
FOREACH_PlayerNumber( p )
|
||||
{
|
||||
vector<GameState::RankingFeat> aFeats;
|
||||
GAMESTATE->GetRankingFeats( (PlayerNumber)p, aFeats );
|
||||
GAMESTATE->GetRankingFeats( p, aFeats );
|
||||
m_bStillEnteringName[p] = aFeats.size()>0;
|
||||
m_CurFeat[p] = 0;
|
||||
}
|
||||
@@ -265,7 +265,7 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
|
||||
PositionCharsAndCursor( p );
|
||||
|
||||
// load last used ranking name if any
|
||||
const Profile* pProfile = PROFILEMAN->GetProfile((PlayerNumber)p);
|
||||
const Profile* pProfile = PROFILEMAN->GetProfile(p);
|
||||
if( pProfile && !pProfile->m_sLastUsedHighScoreName.empty() )
|
||||
{
|
||||
m_sSelection[p] = CStringToWstring( pProfile->m_sLastUsedHighScoreName );
|
||||
@@ -273,7 +273,7 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
|
||||
m_sSelection[p].erase( MAX_RANKING_NAME_LENGTH );
|
||||
ASSERT( (int) m_sSelection[p].size() <= MAX_RANKING_NAME_LENGTH );
|
||||
if( m_sSelection[p].size() )
|
||||
SelectChar( (PlayerNumber) p, CHAR_OK );
|
||||
SelectChar( p, CHAR_OK );
|
||||
}
|
||||
|
||||
UpdateSelectionText( p );
|
||||
@@ -308,8 +308,8 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
|
||||
for( unsigned i = 0; i < g_vPlayedStageStats.size(); ++i )
|
||||
{
|
||||
StageStats &ss = g_vPlayedStageStats[i];
|
||||
Song* pSong = ss.pSong;
|
||||
Steps* pSteps = ss.pSteps[p];
|
||||
Song* pSong = ss.vpSongs[0];
|
||||
Steps* pSteps = ss.vpSteps[p][0];
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
Trail* pTrail = GAMESTATE->m_pCurTrail[p];
|
||||
|
||||
@@ -536,7 +536,7 @@ void ScreenNameEntryTraditional::HandleScreenMessage( const ScreenMessage SM )
|
||||
if( !m_Out.IsTransitioning() )
|
||||
{
|
||||
FOREACH_PlayerNumber( p )
|
||||
Finish( (PlayerNumber)p );
|
||||
Finish( p );
|
||||
MenuStart( PLAYER_INVALID, IET_FIRST_PRESS );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1055,7 +1055,7 @@ void ScreenSelectMusic::MenuStart( PlayerNumber pn )
|
||||
if( PREFSMAN->m_bEventMode )
|
||||
i = max( 0, int(g_vPlayedStageStats.size())-5 );
|
||||
for( ; i < (int)g_vPlayedStageStats.size(); ++i )
|
||||
if( g_vPlayedStageStats[i].pSong == m_MusicWheel.GetSelectedSong() )
|
||||
if( g_vPlayedStageStats[i].vpSongs.back() == m_MusicWheel.GetSelectedSong() )
|
||||
bIsRepeat = true;
|
||||
|
||||
/* Don't complain about repeats if the user didn't get to pick. */
|
||||
|
||||
@@ -695,24 +695,23 @@ void SongManager::RevertFromDisk( Song *pSong, bool bAllowNotesLoss )
|
||||
// Fix GAMESTATE->m_CurSteps, g_CurStageStats, g_vPlayedStageStats[] after reloading.
|
||||
/* XXX: This is very brittle. However, we must know about all globals uses of Steps*,
|
||||
* so we can check to make sure we didn't lose any steps which are referenced ... */
|
||||
StepsID OldCurSteps[NUM_PLAYERS];
|
||||
StepsID OldCurStageStats[NUM_PLAYERS];
|
||||
vector<StepsID> OldPlayedStageStats[NUM_PLAYERS];
|
||||
FOREACH_PlayerNumber( p )
|
||||
{
|
||||
Steps* pCurSteps = GAMESTATE->m_pCurSteps[p];
|
||||
Steps* pCurStageStats = g_CurStageStats.pSteps[p];
|
||||
|
||||
OldCurSteps[p].FromSteps( pCurSteps );
|
||||
OldCurStageStats[p].FromSteps( pCurStageStats );
|
||||
for( unsigned i = 0; i < g_vPlayedStageStats.size(); ++i )
|
||||
{
|
||||
const StageStats &ss = g_vPlayedStageStats[i];;
|
||||
OldPlayedStageStats[p].push_back( StepsID() );
|
||||
OldPlayedStageStats[p][i].FromSteps( ss.pSteps[p] );
|
||||
}
|
||||
|
||||
//
|
||||
// Save list of all old Steps pointers for the song
|
||||
//
|
||||
map<Steps*,StepsID> mapOldStepsToStepsID;
|
||||
FOREACH_CONST( Steps*, pSong->GetAllSteps(), pSteps )
|
||||
{
|
||||
StepsID id;
|
||||
id.FromSteps( *pSteps );
|
||||
mapOldStepsToStepsID[*pSteps] = id;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Reload the song
|
||||
//
|
||||
const CString dir = pSong->GetSongDir();
|
||||
FILEMAN->FlushDirCache( dir );
|
||||
|
||||
@@ -734,21 +733,23 @@ void SongManager::RevertFromDisk( Song *pSong, bool bAllowNotesLoss )
|
||||
StepsID::Invalidate( pSong );
|
||||
|
||||
|
||||
|
||||
#define CONVERT_STEPS_POINTER( pSteps ) { \
|
||||
StepsID id = mapOldStepsToStepsID[pSteps]; /* this will always succeed */ \
|
||||
pSteps = id.ToSteps( pSong, bAllowNotesLoss ); }
|
||||
|
||||
|
||||
|
||||
FOREACH_PlayerNumber( p )
|
||||
{
|
||||
CHECKPOINT;
|
||||
if( GAMESTATE->m_pCurSong == pSong )
|
||||
GAMESTATE->m_pCurSteps[p] = OldCurSteps[p].ToSteps( pSong, bAllowNotesLoss );
|
||||
CHECKPOINT;
|
||||
if( g_CurStageStats.pSong == pSong )
|
||||
g_CurStageStats.pSteps[p] = OldCurStageStats[p].ToSteps( pSong, bAllowNotesLoss );
|
||||
CHECKPOINT;
|
||||
for( unsigned i = 0; i < g_vPlayedStageStats.size(); ++i )
|
||||
{
|
||||
CHECKPOINT_M(ssprintf("%i", i));
|
||||
if( g_vPlayedStageStats[i].pSong == pSong )
|
||||
g_vPlayedStageStats[i].pSteps[p] = OldPlayedStageStats[p][i].ToSteps( pSong, bAllowNotesLoss );
|
||||
}
|
||||
CONVERT_STEPS_POINTER( GAMESTATE->m_pCurSteps[p] );
|
||||
|
||||
FOREACH( Steps*, g_CurStageStats.vpSteps[p], pSteps )
|
||||
CONVERT_STEPS_POINTER( *pSteps );
|
||||
|
||||
FOREACH( StageStats, g_vPlayedStageStats, ss )
|
||||
FOREACH( Steps*, ss->vpSteps[p], pSteps )
|
||||
CONVERT_STEPS_POINTER( *pSteps );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#include "SongManager.h"
|
||||
#include "RageUtil.h"
|
||||
#include "PrefsManager.h"
|
||||
#include "Foreach.h"
|
||||
#include "Steps.h"
|
||||
#include "Song.h"
|
||||
|
||||
StageStats g_CurStageStats;
|
||||
vector<StageStats> g_vPlayedStageStats;
|
||||
@@ -13,14 +16,13 @@ void StageStats::Init()
|
||||
{
|
||||
playMode = PLAY_MODE_INVALID;
|
||||
pStyle = NULL;
|
||||
pSong = NULL;
|
||||
vpSongs.clear();
|
||||
StageType = STAGE_INVALID;
|
||||
fGameplaySeconds = 0;
|
||||
|
||||
FOREACH_PlayerNumber( p )
|
||||
{
|
||||
pSteps[p] = NULL;
|
||||
iMeter[p] = 0;
|
||||
vpSteps[p].clear();
|
||||
fAliveSeconds[p] = 0;
|
||||
bFailed[p] = bFailedEarlier[p] = false;
|
||||
iPossibleDancePoints[p] = iActualDancePoints[p] = 0;
|
||||
@@ -39,22 +41,53 @@ void StageStats::Init()
|
||||
}
|
||||
}
|
||||
|
||||
void StageStats::AssertValid( PlayerNumber pn ) const
|
||||
{
|
||||
if( vpSongs[0] )
|
||||
CHECKPOINT_M( vpSongs[0]->GetFullTranslitTitle() );
|
||||
ASSERT( vpSteps[pn][0] );
|
||||
ASSERT_M( playMode < NUM_PLAY_MODES, ssprintf("playmode %i", playMode) );
|
||||
ASSERT( pStyle != NULL );
|
||||
ASSERT_M( vpSteps[pn][0]->GetDifficulty() < NUM_DIFFICULTIES, ssprintf("difficulty %i", vpSteps[pn][0]->GetDifficulty()) );
|
||||
ASSERT( vpSongs.size() == vpSteps[pn].size() );
|
||||
}
|
||||
|
||||
|
||||
int StageStats::GetAverageMeter( PlayerNumber pn ) const
|
||||
{
|
||||
int iTotalMeter = 0;
|
||||
int iTotalCount = 0;
|
||||
ASSERT( vpSongs.size() == vpSteps[pn].size() );
|
||||
|
||||
for( unsigned i=0; i<vpSongs.size(); i++ )
|
||||
{
|
||||
Song* pSong = vpSongs[i];
|
||||
Steps* pSteps = vpSteps[pn][i];
|
||||
|
||||
// weight long and marathon songs
|
||||
int iWeight = SongManager::GetNumStagesForSong( pSong );
|
||||
int iMeter = pSteps->GetMeter();
|
||||
|
||||
iTotalMeter += iMeter;
|
||||
iTotalCount += iWeight;
|
||||
}
|
||||
return iTotalMeter / iTotalCount; // round down
|
||||
}
|
||||
|
||||
void StageStats::AddStats( const StageStats& other )
|
||||
{
|
||||
pSong = NULL; // meaningless
|
||||
ASSERT( !other.vpSongs.empty() );
|
||||
FOREACH_CONST( Song*, other.vpSongs, s )
|
||||
vpSongs.push_back( *s );
|
||||
StageType = STAGE_INVALID; // meaningless
|
||||
memset( fAliveSeconds, 0, sizeof(fAliveSeconds) ); // why? -Chris
|
||||
memset( fAliveSeconds, 0, sizeof(fAliveSeconds) ); // why not accumulate? -Chris
|
||||
|
||||
// weight long and marathon songs
|
||||
ASSERT( other.pSong );
|
||||
const int iLengthMultiplier = SongManager::GetNumStagesForSong( other.pSong );
|
||||
|
||||
fGameplaySeconds += other.fGameplaySeconds;
|
||||
|
||||
FOREACH_PlayerNumber( p )
|
||||
{
|
||||
pSteps[p] = NULL;
|
||||
iMeter[p] += other.iMeter[p] * iLengthMultiplier;
|
||||
FOREACH_CONST( Steps*, other.vpSteps[p], s )
|
||||
vpSteps[p].push_back( *s );
|
||||
fAliveSeconds[p] += other.fAliveSeconds[p];
|
||||
bFailed[p] |= other.bFailed[p];
|
||||
bFailedEarlier[p] |= other.bFailedEarlier[p];
|
||||
@@ -496,22 +529,20 @@ Grade GetFinalGrade( PlayerNumber pn )
|
||||
{
|
||||
if( !GAMESTATE->IsHumanPlayer(pn) )
|
||||
return GRADE_NO_DATA;
|
||||
vector<Song*> vSongs;
|
||||
StageStats stats;
|
||||
GAMESTATE->GetFinalEvalStatsAndSongs( stats, vSongs );
|
||||
GAMESTATE->GetFinalEvalStats( stats );
|
||||
return stats.GetGrade( pn );
|
||||
}
|
||||
LuaFunction_PlayerNumber( GetFinalGrade, GetFinalGrade( pn ) );
|
||||
LuaFunction_PlayerNumber( GetFinalGrade, GetFinalGrade(pn) );
|
||||
|
||||
Grade GetBestFinalGrade()
|
||||
{
|
||||
Grade top_grade = GRADE_FAILED;
|
||||
vector<Song*> vSongs;
|
||||
StageStats stats;
|
||||
GAMESTATE->GetFinalEvalStatsAndSongs( stats, vSongs );
|
||||
GAMESTATE->GetFinalEvalStats( stats );
|
||||
FOREACH_PlayerNumber( p )
|
||||
if( GAMESTATE->IsHumanPlayer(p) )
|
||||
top_grade = min( top_grade, stats.GetGrade((PlayerNumber)p) );
|
||||
top_grade = min( top_grade, stats.GetGrade(p) );
|
||||
return top_grade;
|
||||
}
|
||||
LuaFunction_NoArgs( GetBestFinalGrade, GetBestFinalGrade() );
|
||||
|
||||
@@ -16,6 +16,9 @@ struct StageStats
|
||||
{
|
||||
StageStats() { Init(); }
|
||||
void Init();
|
||||
|
||||
void AssertValid( PlayerNumber pn ) const;
|
||||
|
||||
void AddStats( const StageStats& other ); // accumulate
|
||||
Grade GetGrade( PlayerNumber pn ) const;
|
||||
bool OnePassed() const;
|
||||
@@ -25,10 +28,10 @@ struct StageStats
|
||||
|
||||
PlayMode playMode;
|
||||
const Style* pStyle;
|
||||
Song* pSong;
|
||||
vector<Song*> vpSongs;
|
||||
enum { STAGE_INVALID, STAGE_NORMAL, STAGE_EXTRA, STAGE_EXTRA2 } StageType;
|
||||
Steps* pSteps[NUM_PLAYERS];
|
||||
int iMeter[NUM_PLAYERS];
|
||||
vector<Steps*> vpSteps[NUM_PLAYERS];
|
||||
int GetAverageMeter( PlayerNumber pn ) const;
|
||||
float fAliveSeconds[NUM_PLAYERS]; // how far into the music did they last before failing? Updated by Gameplay, scaled by music rate.
|
||||
float fGameplaySeconds; // how many seconds before gameplay ended. Updated by Gameplay, not scaled by music rate.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user