split StageStats into player-specific and non-player-specific structs

This commit is contained in:
Chris Danford
2004-12-20 10:47:41 +00:00
parent f840c014a9
commit 09d018444e
23 changed files with 638 additions and 547 deletions
+3 -3
View File
@@ -100,17 +100,17 @@ void Combo::SetCombo( int iCombo, int iMisses )
if( bPastMidpoint ) if( bPastMidpoint )
{ {
if( g_CurStageStats.FullComboOfScore(m_PlayerNumber,TNS_MARVELOUS) ) if( g_CurStageStats.m_player[m_PlayerNumber].FullComboOfScore(TNS_MARVELOUS) )
{ {
sprLabel.RunCommands( FULL_COMBO_MARVELOUSES_COMMAND ); sprLabel.RunCommands( FULL_COMBO_MARVELOUSES_COMMAND );
m_textNumber.RunCommands( FULL_COMBO_MARVELOUSES_COMMAND ); m_textNumber.RunCommands( FULL_COMBO_MARVELOUSES_COMMAND );
} }
else if( bPastMidpoint && g_CurStageStats.FullComboOfScore(m_PlayerNumber,TNS_PERFECT) ) else if( bPastMidpoint && g_CurStageStats.m_player[m_PlayerNumber].FullComboOfScore(TNS_PERFECT) )
{ {
sprLabel.RunCommands( FULL_COMBO_PERFECTS_COMMAND ); sprLabel.RunCommands( FULL_COMBO_PERFECTS_COMMAND );
m_textNumber.RunCommands( FULL_COMBO_PERFECTS_COMMAND ); m_textNumber.RunCommands( FULL_COMBO_PERFECTS_COMMAND );
} }
else if( bPastMidpoint && g_CurStageStats.FullComboOfScore(m_PlayerNumber,TNS_GREAT) ) else if( bPastMidpoint && g_CurStageStats.m_player[m_PlayerNumber].FullComboOfScore(TNS_GREAT) )
{ {
sprLabel.RunCommands( FULL_COMBO_GREATS_COMMAND ); sprLabel.RunCommands( FULL_COMBO_GREATS_COMMAND );
m_textNumber.RunCommands( FULL_COMBO_GREATS_COMMAND ); m_textNumber.RunCommands( FULL_COMBO_GREATS_COMMAND );
+10 -10
View File
@@ -14,13 +14,13 @@ void ComboGraph::Load( CString Path, const StageStats &s, PlayerNumber pn )
/* Find the largest combo. */ /* Find the largest combo. */
int MaxComboSize = 0; int MaxComboSize = 0;
for( unsigned i = 0; i < s.ComboList[pn].size(); ++i ) for( unsigned i = 0; i < s.m_player[pn].ComboList.size(); ++i )
MaxComboSize = max( MaxComboSize, s.ComboList[pn][i].GetStageCnt() ); MaxComboSize = max( MaxComboSize, s.m_player[pn].ComboList[i].GetStageCnt() );
float width = -1; float width = -1;
for( unsigned i = 0; i < s.ComboList[pn].size(); ++i ) for( unsigned i = 0; i < s.m_player[pn].ComboList.size(); ++i )
{ {
const StageStats::Combo_t &combo = s.ComboList[pn][i]; const PlayerStageStats::Combo_t &combo = s.m_player[pn].ComboList[i];
if( combo.GetStageCnt() < MinComboSizeToShow ) if( combo.GetStageCnt() < MinComboSizeToShow )
continue; /* too small */ continue; /* too small */
@@ -32,8 +32,8 @@ void ComboGraph::Load( CString Path, const StageStats &s, PlayerNumber pn )
const CString path = ssprintf( "%s %s", Path.c_str(), IsMax? "max":"normal" ); const CString path = ssprintf( "%s %s", Path.c_str(), IsMax? "max":"normal" );
sprite->Load( THEME->GetPathToG(path) ); sprite->Load( THEME->GetPathToG(path) );
const float start = SCALE( combo.fStartSecond, s.fFirstSecond[pn], s.fLastSecond[pn], 0.0f, 1.0f ); const float start = SCALE( combo.fStartSecond, s.m_player[pn].fFirstSecond, s.m_player[pn].fLastSecond, 0.0f, 1.0f );
const float size = SCALE( combo.fSizeSeconds, 0, s.fLastSecond[pn]-s.fFirstSecond[pn], 0.0f, 1.0f ); const float size = SCALE( combo.fSizeSeconds, 0, s.m_player[pn].fLastSecond-s.m_player[pn].fFirstSecond, 0.0f, 1.0f );
sprite->SetCropLeft ( SCALE( size, 0.0f, 1.0f, 0.5f, 0.0f ) ); sprite->SetCropLeft ( SCALE( size, 0.0f, 1.0f, 0.5f, 0.0f ) );
sprite->SetCropRight( SCALE( size, 0.0f, 1.0f, 0.5f, 0.0f ) ); sprite->SetCropRight( SCALE( size, 0.0f, 1.0f, 0.5f, 0.0f ) );
@@ -48,9 +48,9 @@ void ComboGraph::Load( CString Path, const StageStats &s, PlayerNumber pn )
this->AddChild( sprite ); this->AddChild( sprite );
} }
for( unsigned i = 0; i < s.ComboList[pn].size(); ++i ) for( unsigned i = 0; i < s.m_player[pn].ComboList.size(); ++i )
{ {
const StageStats::Combo_t &combo = s.ComboList[pn][i]; const PlayerStageStats::Combo_t &combo = s.m_player[pn].ComboList[i];
if( combo.GetStageCnt() < MinComboSizeToShow ) if( combo.GetStageCnt() < MinComboSizeToShow )
continue; /* too small */ continue; /* too small */
@@ -65,8 +65,8 @@ void ComboGraph::Load( CString Path, const StageStats &s, PlayerNumber pn )
text->SetName( "ComboMaxNumber" ); text->SetName( "ComboMaxNumber" );
text->LoadFromFont( THEME->GetPathToF(Path) ); text->LoadFromFont( THEME->GetPathToF(Path) );
const float start = SCALE( combo.fStartSecond, s.fFirstSecond[pn], s.fLastSecond[pn], 0.0f, 1.0f ); const float start = SCALE( combo.fStartSecond, s.m_player[pn].fFirstSecond, s.m_player[pn].fLastSecond, 0.0f, 1.0f );
const float size = SCALE( combo.fSizeSeconds, 0, s.fLastSecond[pn]-s.fFirstSecond[pn], 0.0f, 1.0f ); const float size = SCALE( combo.fSizeSeconds, 0, s.m_player[pn].fLastSecond-s.m_player[pn].fFirstSecond, 0.0f, 1.0f );
const float CenterPercent = start + size/2; const float CenterPercent = start + size/2;
const float CenterXPos = SCALE( CenterPercent, 0.0f, 1.0f, -width/2.0f, width/2.0f ); const float CenterXPos = SCALE( CenterPercent, 0.0f, 1.0f, -width/2.0f, width/2.0f );
+13 -11
View File
@@ -1,13 +1,14 @@
// TODO: Remove this class in favor and merge its functionality into the Lua
// conditions already present in BGA.
#include "global.h" #include "global.h"
#include "ConditionalBGA.h"
#include <ctime> #include <ctime>
#include "GameState.h" #include "GameState.h"
#include "GameManager.h" #include "GameManager.h"
#include "song.h" #include "song.h"
#include "GameConstantsAndTypes.h" #include "GameConstantsAndTypes.h"
#include "RageLog.h" #include "RageLog.h"
#include "BGAnimation.h" #include "BGAnimation.h"
#include "ConditionalBGA.h"
#include "ThemeManager.h" #include "ThemeManager.h"
#include "RageUtil.h" #include "RageUtil.h"
#include "RageFile.h" #include "RageFile.h"
@@ -501,7 +502,7 @@ void ConditionalBGA::CheckBgaRequirements(BgaCondInfo info)
bool foundaplayerwithgrade = false; bool foundaplayerwithgrade = false;
FOREACH_EnabledPlayer( pn ) FOREACH_EnabledPlayer( pn )
{ {
if(g_CurStageStats.GetGrade(pn) == info.grades[0]) if(g_CurStageStats.m_player[pn].GetGrade() == info.grades[0])
{ {
LOG->Info("Found Valid Grade"); LOG->Info("Found Valid Grade");
foundaplayerwithgrade = true; foundaplayerwithgrade = true;
@@ -524,19 +525,16 @@ void ConditionalBGA::CheckBgaRequirements(BgaCondInfo info)
{ {
if(d>g) ASSERT(0); // this should never happen. if(d>g) ASSERT(0); // this should never happen.
for(unsigned pn=0; pn<NUM_PLAYERS;pn++) FOREACH_EnabledPlayer( pn )
{ {
if(GAMESTATE->IsPlayerEnabled((PlayerNumber)pn)) LOG->Info("Player%d Grade: %d :: Expected Grade: %d",pn,g_vPlayedStageStats[g].m_player[pn].GetGrade(),info.grades[d]);
{ if(g_vPlayedStageStats[g].m_player[pn].GetGrade() == info.grades[d])
LOG->Info("Player%d Grade: %d :: Expected Grade: %d",pn,g_vPlayedStageStats[g].GetGrade((PlayerNumber)pn),info.grades[d]);
if(g_vPlayedStageStats[g].GetGrade((PlayerNumber)pn) == info.grades[d])
{ {
LOG->Info("One Valid Grade"); LOG->Info("One Valid Grade");
foundavalidgradeforstage = true; foundavalidgradeforstage = true;
} }
} }
} }
}
foundmatchinggrades = foundavalidgradeforstage; foundmatchinggrades = foundavalidgradeforstage;
} }
@@ -610,21 +608,25 @@ void ConditionalBGA::CheckBgaRequirements(BgaCondInfo info)
else if(info.cleared == CBGA_CSMAXCOMBO) else if(info.cleared == CBGA_CSMAXCOMBO)
{ {
FOREACH_EnabledPlayer( pn ) FOREACH_EnabledPlayer( pn )
if(g_CurStageStats.FullCombo((PlayerNumber)pn)) {
if(g_CurStageStats.m_player[pn].FullCombo())
{ {
foundclearcond = true; foundclearcond = true;
LOG->Info("MaxCombo Condition"); LOG->Info("MaxCombo Condition");
} }
} }
}
else if(info.cleared == CBGA_CSBROKECOMBO) else if(info.cleared == CBGA_CSBROKECOMBO)
{ {
FOREACH_EnabledPlayer( pn ) FOREACH_EnabledPlayer( pn )
if(!g_CurStageStats.FullCombo((PlayerNumber)pn)) {
if(!g_CurStageStats.m_player[pn].FullCombo())
{ {
LOG->Info("BrokenCombo Condition"); LOG->Info("BrokenCombo Condition");
foundclearcond = true; foundclearcond = true;
} }
} }
}
valid = foundclearcond; valid = foundclearcond;
} }
+2 -1
View File
@@ -4,7 +4,8 @@
#include "PlayerOptions.h" #include "PlayerOptions.h"
#include "GameConstantsAndTypes.h" #include "GameConstantsAndTypes.h"
#include "BGAnimation.h" #include "BGAnimation.h"
//#include "Style.h"
class Style;
enum CBGACLEAREDSTATES enum CBGACLEAREDSTATES
{ {
+1 -1
View File
@@ -342,7 +342,7 @@ void DancingCharacters::DrawPrimitives()
continue; continue;
} }
bool bFailed = g_CurStageStats.bFailed[p]; bool bFailed = g_CurStageStats.m_player[p].bFailed;
bool bDanger = m_bDrawDangerLight; bool bDanger = m_bDrawDangerLight;
DISPLAY->SetLighting( true ); DISPLAY->SetLighting( true );
+31 -44
View File
@@ -156,7 +156,7 @@ void GameState::Reset()
m_pPosition = new NoteFieldPositioning("Positioning.ini"); m_pPosition = new NoteFieldPositioning("Positioning.ini");
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
m_pPlayerState[p]->m_bAttackBeganThisUpdate = false; m_pPlayerState[p]->Reset();
ResetMusicStatistics(); ResetMusicStatistics();
ResetStageStatistics(); ResetStageStatistics();
@@ -170,12 +170,6 @@ void GameState::Reset()
g_vPlayedStageStats.clear(); g_vPlayedStageStats.clear();
FOREACH_PlayerNumber( p )
{
m_pPlayerState[p]->m_CurrentPlayerOptions.Init();
m_pPlayerState[p]->m_PlayerOptions.Init();
m_pPlayerState[p]->m_StoredPlayerOptions.Init();
}
m_SongOptions.Init(); m_SongOptions.Init();
FOREACH_PlayerNumber(p) FOREACH_PlayerNumber(p)
@@ -200,13 +194,6 @@ void GameState::Reset()
ASSERT( m_pCurCharacters[p] ); ASSERT( m_pCurCharacters[p] );
} }
FOREACH_PlayerNumber(p)
{
m_pPlayerState[p]->m_fSuperMeterGrowthScale = 1;
m_pPlayerState[p]->m_iCpuSkill = 5;
}
LIGHTSMAN->SetLightsMode( LIGHTSMODE_ATTRACT ); LIGHTSMAN->SetLightsMode( LIGHTSMODE_ATTRACT );
ApplyCmdline(); ApplyCmdline();
@@ -301,10 +288,10 @@ void AddPlayerStatsToProfile( Profile *pProfile, const StageStats &ss, PlayerNum
StyleID sID; StyleID sID;
sID.FromStyle( ss.pStyle ); sID.FromStyle( ss.pStyle );
ASSERT( ss.vpSongs.size() == ss.vpSteps[pn].size() ); ASSERT( ss.vpSongs.size() == ss.m_player[pn].vpSteps.size() );
for( unsigned i=0; i<ss.vpSongs.size(); i++ ) for( unsigned i=0; i<ss.vpSongs.size(); i++ )
{ {
Steps *pSteps = ss.vpSteps[pn][i]; Steps *pSteps = ss.m_player[pn].vpSteps[i];
pProfile->m_iNumSongsPlayedByPlayMode[ss.playMode]++; pProfile->m_iNumSongsPlayedByPlayMode[ss.playMode]++;
pProfile->m_iNumSongsPlayedByStyle[sID] ++; pProfile->m_iNumSongsPlayedByStyle[sID] ++;
@@ -312,11 +299,11 @@ void AddPlayerStatsToProfile( Profile *pProfile, const StageStats &ss, PlayerNum
pProfile->m_iNumSongsPlayedByMeter[pSteps->GetMeter()] ++; pProfile->m_iNumSongsPlayedByMeter[pSteps->GetMeter()] ++;
} }
pProfile->m_iTotalDancePoints += ss.iActualDancePoints[pn]; pProfile->m_iTotalDancePoints += ss.m_player[pn].iActualDancePoints;
if( ss.StageType == StageStats::STAGE_EXTRA || ss.StageType == StageStats::STAGE_EXTRA2 ) if( ss.StageType == StageStats::STAGE_EXTRA || ss.StageType == StageStats::STAGE_EXTRA2 )
{ {
if( ss.bFailed[pn] ) if( ss.m_player[pn].bFailed )
++pProfile->m_iNumExtraStagesFailed; ++pProfile->m_iNumExtraStagesFailed;
else else
++pProfile->m_iNumExtraStagesPassed; ++pProfile->m_iNumExtraStagesPassed;
@@ -324,10 +311,10 @@ void AddPlayerStatsToProfile( Profile *pProfile, const StageStats &ss, PlayerNum
// If you fail in a course, you passed all but the final song. // 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. // FIXME: Not true. If playing with 2 players, one player could have failed earlier.
if( !ss.bFailed[pn] ) if( !ss.m_player[pn].bFailed )
{ {
pProfile->m_iNumStagesPassedByPlayMode[ss.playMode] ++; pProfile->m_iNumStagesPassedByPlayMode[ss.playMode] ++;
pProfile->m_iNumStagesPassedByGrade[ss.GetGrade(pn)] ++; pProfile->m_iNumStagesPassedByGrade[ss.m_player[pn].GetGrade()] ++;
} }
} }
@@ -524,14 +511,17 @@ void GameState::ResetStageStatistics()
{ {
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
{ {
Profile* pProfile = PROFILEMAN->GetProfile((PlayerNumber)p); Profile* pProfile = PROFILEMAN->GetProfile(p);
if( pProfile ) if( pProfile )
g_CurStageStats.iCurCombo[p] = pProfile->m_iCurrentCombo; g_CurStageStats.m_player[p].iCurCombo = pProfile->m_iCurrentCombo;
} }
} }
else // GetStageIndex() > 0 else // GetStageIndex() > 0
{ {
memcpy( g_CurStageStats.iCurCombo, OldStats.iCurCombo, sizeof(OldStats.iCurCombo) ); FOREACH_PlayerNumber( p )
{
g_CurStageStats.m_player[p].iCurCombo = OldStats.m_player[p].iCurCombo;
}
} }
} }
@@ -656,11 +646,11 @@ void GameState::FinishStage()
// //
FOREACH_HumanPlayer( pn ) FOREACH_HumanPlayer( pn )
{ {
int iNumTapsAndHolds = (int) g_CurStageStats.radarActual[pn][RADAR_NUM_TAPS_AND_HOLDS]; int iNumTapsAndHolds = (int) g_CurStageStats.m_player[pn].radarActual[RADAR_NUM_TAPS_AND_HOLDS];
int iNumJumps = (int) g_CurStageStats.radarActual[pn][RADAR_NUM_JUMPS]; int iNumJumps = (int) g_CurStageStats.m_player[pn].radarActual[RADAR_NUM_JUMPS];
int iNumHolds = (int) g_CurStageStats.radarActual[pn][RADAR_NUM_HOLDS]; int iNumHolds = (int) g_CurStageStats.m_player[pn].radarActual[RADAR_NUM_HOLDS];
int iNumMines = (int) g_CurStageStats.radarActual[pn][RADAR_NUM_MINES]; int iNumMines = (int) g_CurStageStats.m_player[pn].radarActual[RADAR_NUM_MINES];
int iNumHands = (int) g_CurStageStats.radarActual[pn][RADAR_NUM_HANDS]; int iNumHands = (int) g_CurStageStats.m_player[pn].radarActual[RADAR_NUM_HANDS];
PROFILEMAN->AddStepTotals( pn, iNumTapsAndHolds, iNumJumps, iNumHolds, iNumMines, iNumHands ); PROFILEMAN->AddStepTotals( pn, iNumTapsAndHolds, iNumJumps, iNumHolds, iNumMines, iNumHands );
} }
@@ -684,7 +674,7 @@ void GameState::FinishStage()
pPlayerProfile->m_iTotalGameplaySeconds += iGameplaySeconds; pPlayerProfile->m_iTotalGameplaySeconds += iGameplaySeconds;
pPlayerProfile->m_iCurrentCombo = pPlayerProfile->m_iCurrentCombo =
PREFSMAN->m_bComboContinuesBetweenSongs ? PREFSMAN->m_bComboContinuesBetweenSongs ?
g_CurStageStats.iCurCombo[p] : g_CurStageStats.m_player[p].iCurCombo :
0; 0;
} }
@@ -787,7 +777,7 @@ int GameState::GetCourseSongIndex() const
/* iSongsPlayed includes the current song, so it's 1-based; subtract one. */ /* iSongsPlayed includes the current song, so it's 1-based; subtract one. */
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
if( IsPlayerEnabled(p) ) if( IsPlayerEnabled(p) )
iSongIndex = max( iSongIndex, g_CurStageStats.iSongsPlayed[p]-1 ); iSongIndex = max( iSongIndex, g_CurStageStats.m_player[p].iSongsPlayed-1 );
return iSongIndex; return iSongIndex;
} }
@@ -985,11 +975,8 @@ bool GameState::HasEarnedExtraStage() const
if( (this->IsFinalStage() || this->IsExtraStage()) ) if( (this->IsFinalStage() || this->IsExtraStage()) )
{ {
FOREACH_PlayerNumber( p ) FOREACH_EnabledPlayer( p )
{ {
if( !this->IsPlayerEnabled(p) )
continue; // skip
if( this->m_pCurSteps[p]->GetDifficulty() != DIFFICULTY_HARD && if( this->m_pCurSteps[p]->GetDifficulty() != DIFFICULTY_HARD &&
this->m_pCurSteps[p]->GetDifficulty() != DIFFICULTY_CHALLENGE ) this->m_pCurSteps[p]->GetDifficulty() != DIFFICULTY_CHALLENGE )
continue; /* not hard enough! */ continue; /* not hard enough! */
@@ -999,7 +986,7 @@ bool GameState::HasEarnedExtraStage() const
if( PREFSMAN->m_bPickExtraStage && this->IsExtraStage() && !this->m_bAllow2ndExtraStage ) if( PREFSMAN->m_bPickExtraStage && this->IsExtraStage() && !this->m_bAllow2ndExtraStage )
continue; continue;
if( g_CurStageStats.GetGrade((PlayerNumber)p) <= GRADE_TIER_3 ) if( g_CurStageStats.m_player[p].GetGrade() <= GRADE_TIER_3 )
return true; return true;
} }
} }
@@ -1008,9 +995,9 @@ bool GameState::HasEarnedExtraStage() const
PlayerNumber GameState::GetBestPlayer() const PlayerNumber GameState::GetBestPlayer() const
{ {
for( int p=PLAYER_1; p<NUM_PLAYERS; p++ ) FOREACH_PlayerNumber( p )
if( GetStageResult( (PlayerNumber)p ) == RESULT_WIN ) if( GetStageResult(p) == RESULT_WIN )
return (PlayerNumber)p; return p;
return PLAYER_INVALID; // draw return PLAYER_INVALID; // draw
} }
@@ -1037,11 +1024,11 @@ StageResult GameState::GetStageResult( PlayerNumber pn ) const
continue; continue;
/* If anyone did just as well, at best it's a draw. */ /* If anyone did just as well, at best it's a draw. */
if( g_CurStageStats.iActualDancePoints[p] == g_CurStageStats.iActualDancePoints[pn] ) if( g_CurStageStats.m_player[p].iActualDancePoints == g_CurStageStats.m_player[pn].iActualDancePoints )
win = RESULT_DRAW; win = RESULT_DRAW;
/* If anyone did better, we lost. */ /* If anyone did better, we lost. */
if( g_CurStageStats.iActualDancePoints[p] > g_CurStageStats.iActualDancePoints[pn] ) if( g_CurStageStats.m_player[p].iActualDancePoints > g_CurStageStats.m_player[pn].iActualDancePoints )
return RESULT_LOSE; return RESULT_LOSE;
} }
return win; return win;
@@ -1081,8 +1068,8 @@ void GameState::GetFinalEvalStats( StageStats& statsOut ) const
{ {
for( int r = 0; r < RADAR_NUM_TAPS_AND_HOLDS; r++) for( int r = 0; r < RADAR_NUM_TAPS_AND_HOLDS; r++)
{ {
statsOut.radarPossible[p][r] /= statsOut.vpSongs.size(); statsOut.m_player[p].radarPossible[r] /= statsOut.vpSongs.size();
statsOut.radarActual[p][r] /= statsOut.vpSongs.size(); statsOut.m_player[p].radarActual[r] /= statsOut.vpSongs.size();
} }
} }
} }
@@ -1440,7 +1427,7 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
SongAndSteps sas; SongAndSteps sas;
sas.pSong = g_vPlayedStageStats[i].vpSongs[0]; sas.pSong = g_vPlayedStageStats[i].vpSongs[0];
ASSERT( sas.pSong ); ASSERT( sas.pSong );
sas.pSteps = g_vPlayedStageStats[i].vpSteps[pn][0]; sas.pSteps = g_vPlayedStageStats[i].m_player[pn].vpSteps[0];
ASSERT( sas.pSteps ); ASSERT( sas.pSteps );
vSongAndSteps.push_back( sas ); vSongAndSteps.push_back( sas );
} }
@@ -1702,7 +1689,7 @@ bool GameState::AllAreDead() const
bool GameState::AllHaveComboOf30OrMoreMisses() const bool GameState::AllHaveComboOf30OrMoreMisses() const
{ {
FOREACH_EnabledPlayer( p ) FOREACH_EnabledPlayer( p )
if( g_CurStageStats.iCurMissCombo[p] < 30 ) if( g_CurStageStats.m_player[p].iCurMissCombo < 30 )
return false; return false;
return true; return true;
} }
+1 -1
View File
@@ -43,7 +43,7 @@ void GraphDisplay::LoadFromStageStats( const StageStats &s, PlayerNumber pn )
{ {
memcpy( m_LastValues, m_CurValues, sizeof(m_CurValues) ); memcpy( m_LastValues, m_CurValues, sizeof(m_CurValues) );
m_Position = 0; m_Position = 0;
s.GetLifeRecord( pn, m_DestValues, VALUE_RESOLUTION ); s.m_player[pn].GetLifeRecord( m_DestValues, VALUE_RESOLUTION );
for( unsigned i=0; i<ARRAYSIZE(m_DestValues); i++ ) for( unsigned i=0; i<ARRAYSIZE(m_DestValues); i++ )
CLAMP( m_DestValues[i], 0.f, 1.f ); CLAMP( m_DestValues[i], 0.f, 1.f );
UpdateVerts(); UpdateVerts();
+2 -2
View File
@@ -95,10 +95,10 @@ void Inventory::Update( float fDelta )
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
// check to see if they deserve a new item // check to see if they deserve a new item
if( g_CurStageStats.iCurCombo[pn] != m_iLastSeenCombo ) if( g_CurStageStats.m_player[pn].iCurCombo != m_iLastSeenCombo )
{ {
int iOldCombo = m_iLastSeenCombo; int iOldCombo = m_iLastSeenCombo;
m_iLastSeenCombo = g_CurStageStats.iCurCombo[pn]; m_iLastSeenCombo = g_CurStageStats.m_player[pn].iCurCombo;
int iNewCombo = m_iLastSeenCombo; int iNewCombo = m_iLastSeenCombo;
#define CROSSED(i) (iOldCombo<i)&&(iNewCombo>=i) #define CROSSED(i) (iOldCombo<i)&&(iNewCombo>=i)
+2 -2
View File
@@ -403,7 +403,7 @@ void LifeMeterBar::ChangeLife( float fDeltaLife )
} }
/* If we've already failed, there's no point in letting them fill up the bar again. */ /* If we've already failed, there's no point in letting them fill up the bar again. */
if( g_CurStageStats.bFailed[m_PlayerNumber] ) if( g_CurStageStats.m_player[m_PlayerNumber].bFailed )
fDeltaLife = 0; fDeltaLife = 0;
switch( GAMESTATE->m_SongOptions.m_DrainType ) switch( GAMESTATE->m_SongOptions.m_DrainType )
@@ -432,7 +432,7 @@ void LifeMeterBar::ChangeLife( float fDeltaLife )
CLAMP( m_fLifePercentage, 0, 1 ); CLAMP( m_fLifePercentage, 0, 1 );
if( m_fLifePercentage <= FAIL_THRESHOLD ) if( m_fLifePercentage <= FAIL_THRESHOLD )
g_CurStageStats.bFailedEarlier[m_PlayerNumber] = true; g_CurStageStats.m_player[m_PlayerNumber].bFailedEarlier = true;
m_fLifeVelocity += fDeltaLife; m_fLifeVelocity += fDeltaLife;
} }
+4 -4
View File
@@ -64,7 +64,7 @@ void LifeMeterBattery::Load( PlayerNumber pn )
void LifeMeterBattery::OnSongEnded() void LifeMeterBattery::OnSongEnded()
{ {
if( g_CurStageStats.bFailedEarlier[m_PlayerNumber] ) if( g_CurStageStats.m_player[m_PlayerNumber].bFailedEarlier )
return; return;
if( m_iLivesLeft < GAMESTATE->m_SongOptions.m_iBatteryLives ) if( m_iLivesLeft < GAMESTATE->m_SongOptions.m_iBatteryLives )
@@ -81,7 +81,7 @@ void LifeMeterBattery::OnSongEnded()
void LifeMeterBattery::ChangeLife( TapNoteScore score ) void LifeMeterBattery::ChangeLife( TapNoteScore score )
{ {
if( g_CurStageStats.bFailedEarlier[m_PlayerNumber] ) if( g_CurStageStats.m_player[m_PlayerNumber].bFailedEarlier )
return; return;
switch( score ) switch( score )
@@ -108,7 +108,7 @@ void LifeMeterBattery::ChangeLife( TapNoteScore score )
ASSERT(0); ASSERT(0);
} }
if( m_iLivesLeft == 0 ) if( m_iLivesLeft == 0 )
g_CurStageStats.bFailedEarlier[m_PlayerNumber] = true; g_CurStageStats.m_player[m_PlayerNumber].bFailedEarlier = true;
} }
void LifeMeterBattery::ChangeLife( HoldNoteScore score, TapNoteScore tscore ) void LifeMeterBattery::ChangeLife( HoldNoteScore score, TapNoteScore tscore )
@@ -151,7 +151,7 @@ bool LifeMeterBattery::IsHot() const
bool LifeMeterBattery::IsFailing() const bool LifeMeterBattery::IsFailing() const
{ {
return g_CurStageStats.bFailedEarlier[m_PlayerNumber]; return g_CurStageStats.m_player[m_PlayerNumber].bFailedEarlier;
} }
float LifeMeterBattery::GetLife() const float LifeMeterBattery::GetLife() const
+2 -2
View File
@@ -283,9 +283,9 @@ void NetworkSyncManager::ReportScore(int playerID, int step, int score, int comb
uint8_t ctr = (uint8_t) (playerID * 16 + step - 1); uint8_t ctr = (uint8_t) (playerID * 16 + step - 1);
m_packet.Write1(ctr); m_packet.Write1(ctr);
ctr = uint8_t( g_CurStageStats.GetGrade((PlayerNumber)playerID)*16 ); ctr = uint8_t( g_CurStageStats.m_player[playerID].GetGrade()*16 );
if ( g_CurStageStats.bFailedEarlier[(PlayerNumber)playerID] ) if ( g_CurStageStats.m_player[playerID].bFailedEarlier )
ctr = uint8_t( 112 ); //Code for failed (failed constant seems not to work) ctr = uint8_t( 112 ); //Code for failed (failed constant seems not to work)
m_packet.Write1(ctr); m_packet.Write1(ctr);
+4 -4
View File
@@ -290,8 +290,8 @@ float NoteDataWithScoring::GetActualVoltageRadarValue( float fSongSeconds, Playe
* might be on, and the way combo is counted varies depending on the mode and score * might be on, and the way combo is counted varies depending on the mode and score
* keeper. Instead, let's use the length of the longest recorded combo. This is * keeper. Instead, let's use the length of the longest recorded combo. This is
* only subtly different: it's the percent of the song the longest combo took to get. */ * only subtly different: it's the percent of the song the longest combo took to get. */
const StageStats::Combo_t MaxCombo = g_CurStageStats.GetMaxCombo( pn ); const PlayerStageStats::Combo_t MaxCombo = g_CurStageStats.m_player[pn].GetMaxCombo();
float fComboPercent = SCALE( MaxCombo.fSizeSeconds, 0, g_CurStageStats.fLastSecond[pn]-g_CurStageStats.fFirstSecond[pn], 0.0f, 1.0f ); float fComboPercent = SCALE( MaxCombo.fSizeSeconds, 0, g_CurStageStats.m_player[pn].fLastSecond-g_CurStageStats.m_player[pn].fFirstSecond, 0.0f, 1.0f );
return clamp( fComboPercent, 0.0f, 1.0f ); return clamp( fComboPercent, 0.0f, 1.0f );
} }
@@ -308,11 +308,11 @@ float NoteDataWithScoring::GetActualAirRadarValue( float fSongSeconds, PlayerNum
float NoteDataWithScoring::GetActualChaosRadarValue( float fSongSeconds, PlayerNumber pn ) const float NoteDataWithScoring::GetActualChaosRadarValue( float fSongSeconds, PlayerNumber pn ) const
{ {
const int PossibleDP = g_CurStageStats.iPossibleDancePoints[pn]; const int PossibleDP = g_CurStageStats.m_player[pn].iPossibleDancePoints;
if ( PossibleDP == 0 ) if ( PossibleDP == 0 )
return 1; return 1;
const int ActualDP = g_CurStageStats.iActualDancePoints[pn]; const int ActualDP = g_CurStageStats.m_player[pn].iActualDancePoints;
return clamp( float(ActualDP)/PossibleDP, 0.0f, 1.0f ); return clamp( float(ActualDP)/PossibleDP, 0.0f, 1.0f );
} }
+2 -2
View File
@@ -64,7 +64,7 @@ void PercentageDisplay::Update( float fDeltaTime )
void PercentageDisplay::Refresh() void PercentageDisplay::Refresh()
{ {
const int iActualDancePoints = m_pSource->iActualDancePoints[m_PlayerNumber]; const int iActualDancePoints = m_pSource->m_player[m_PlayerNumber].iActualDancePoints;
if( iActualDancePoints == m_Last ) if( iActualDancePoints == m_Last )
return; return;
@@ -77,7 +77,7 @@ void PercentageDisplay::Refresh()
} }
else else
{ {
float fPercentDancePoints = m_pSource->GetPercentDancePoints( m_PlayerNumber ); float fPercentDancePoints = m_pSource->m_player[m_PlayerNumber].GetPercentDancePoints();
// clamp percentage - feedback is that negative numbers look weird here. // clamp percentage - feedback is that negative numbers look weird here.
CLAMP( fPercentDancePoints, 0.f, 1.f ); CLAMP( fPercentDancePoints, 0.f, 1.f );
+68 -20
View File
@@ -127,7 +127,7 @@ void PlayerMinus::Load(
// init steps // init steps
m_NoteData.Init(); m_NoteData.Init();
bool bOniDead = GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && g_CurStageStats.bFailed[pn]; bool bOniDead = GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && g_CurStageStats.m_player[pn].bFailed;
if( !bOniDead ) if( !bOniDead )
m_NoteData.CopyAll( noteData ); m_NoteData.CopyAll( noteData );
@@ -137,7 +137,7 @@ void PlayerMinus::Load(
m_Judgment.StopTweening(); m_Judgment.StopTweening();
// m_Combo.Reset(); // don't reset combos between songs in a course! // m_Combo.Reset(); // don't reset combos between songs in a course!
m_Combo.Init( pn ); m_Combo.Init( pn );
m_Combo.SetCombo( g_CurStageStats.iCurCombo[pn], g_CurStageStats.iCurMissCombo[pn] ); // combo can persist between songs and games m_Combo.SetCombo( g_CurStageStats.m_player[pn].iCurCombo, g_CurStageStats.m_player[pn].iCurMissCombo ); // combo can persist between songs and games
m_AttackDisplay.Init( m_pPlayerState ); m_AttackDisplay.Init( m_pPlayerState );
m_Judgment.Reset(); m_Judgment.Reset();
@@ -188,8 +188,10 @@ void PlayerMinus::Load(
float fNoteFieldMidde = (GRAY_ARROWS_Y_STANDARD+GRAY_ARROWS_Y_REVERSE)/2; float fNoteFieldMidde = (GRAY_ARROWS_Y_STANDARD+GRAY_ARROWS_Y_REVERSE)/2;
if( m_pNoteField )
m_pNoteField->SetY( fNoteFieldMidde ); m_pNoteField->SetY( fNoteFieldMidde );
m_fNoteFieldHeight = GRAY_ARROWS_Y_REVERSE-GRAY_ARROWS_Y_STANDARD; m_fNoteFieldHeight = GRAY_ARROWS_Y_REVERSE-GRAY_ARROWS_Y_STANDARD;
if( m_pNoteField )
m_pNoteField->Load( &m_NoteData, m_pPlayerState, iStartDrawingAtPixels, iStopDrawingAtPixels, m_fNoteFieldHeight ); m_pNoteField->Load( &m_NoteData, m_pPlayerState, iStartDrawingAtPixels, iStopDrawingAtPixels, m_fNoteFieldHeight );
m_ArrowBackdrop.SetPlayer( pn ); m_ArrowBackdrop.SetPlayer( pn );
@@ -278,6 +280,7 @@ void PlayerMinus::Update( float fDeltaTime )
const float fSongBeat = GAMESTATE->m_fSongBeat; const float fSongBeat = GAMESTATE->m_fSongBeat;
const int iSongRow = BeatToNoteRow( fSongBeat ); const int iSongRow = BeatToNoteRow( fSongBeat );
if( m_pNoteField )
m_pNoteField->Update( fDeltaTime ); m_pNoteField->Update( fDeltaTime );
// //
@@ -304,11 +307,13 @@ void PlayerMinus::Update( float fDeltaTime )
m_ArrowBackdrop.SetY( fGrayYPos ); m_ArrowBackdrop.SetY( fGrayYPos );
// NoteField accounts for reverse on its own now. // NoteField accounts for reverse on its own now.
//if( m_pNoteField )
// m_pNoteField->SetY( fGrayYPos ); // m_pNoteField->SetY( fGrayYPos );
float fMiniPercent = m_pPlayerState->m_CurrentPlayerOptions.m_fEffects[PlayerOptions::EFFECT_MINI]; float fMiniPercent = m_pPlayerState->m_CurrentPlayerOptions.m_fEffects[PlayerOptions::EFFECT_MINI];
float fNoteFieldZoom = 1 - fMiniPercent*0.5f; float fNoteFieldZoom = 1 - fMiniPercent*0.5f;
float fJudgmentZoom = 1 - fMiniPercent*0.25f; float fJudgmentZoom = 1 - fMiniPercent*0.25f;
if( m_pNoteField )
m_pNoteField->SetZoom( fNoteFieldZoom ); m_pNoteField->SetZoom( fNoteFieldZoom );
m_Judgment.SetZoom( fJudgmentZoom ); m_Judgment.SetZoom( fJudgmentZoom );
@@ -333,6 +338,7 @@ void PlayerMinus::Update( float fDeltaTime )
bool bIsHoldingButton = INPUTMAPPER->IsButtonDown( GameI ); bool bIsHoldingButton = INPUTMAPPER->IsButtonDown( GameI );
// TODO: Make this work for non-human-controlled players // TODO: Make this work for non-human-controlled players
if( bIsHoldingButton && !GAMESTATE->m_bDemonstrationOrJukebox && m_pPlayerState->m_PlayerController==PC_HUMAN ) if( bIsHoldingButton && !GAMESTATE->m_bDemonstrationOrJukebox && m_pPlayerState->m_PlayerController==PC_HUMAN )
if( m_pNoteField )
m_pNoteField->SetPressed( col ); m_pNoteField->SetPressed( col );
} }
@@ -344,8 +350,11 @@ void PlayerMinus::Update( float fDeltaTime )
const HoldNote &hn = m_NoteData.GetHoldNote(i); const HoldNote &hn = m_NoteData.GetHoldNote(i);
HoldNoteScore hns = m_NoteData.GetHoldNoteScore(hn); HoldNoteScore hns = m_NoteData.GetHoldNoteScore(hn);
if( m_pNoteField )
{
m_pNoteField->m_HeldHoldNotes[hn] = false; // set hold flag so NoteField can do intelligent drawing m_pNoteField->m_HeldHoldNotes[hn] = false; // set hold flag so NoteField can do intelligent drawing
m_pNoteField->m_ActiveHoldNotes[hn] = false; // set hold flag so NoteField can do intelligent drawing m_pNoteField->m_ActiveHoldNotes[hn] = false; // set hold flag so NoteField can do intelligent drawing
}
if( hns != HNS_NONE ) // if this HoldNote already has a result if( hns != HNS_NONE ) // if this HoldNote already has a result
@@ -375,15 +384,23 @@ void PlayerMinus::Update( float fDeltaTime )
bIsHoldingButton = true; bIsHoldingButton = true;
// set hold flag so NoteField can do intelligent drawing // set hold flag so NoteField can do intelligent drawing
if( m_pNoteField )
{
m_pNoteField->m_HeldHoldNotes[hn] = bIsHoldingButton && bSteppedOnTapNote; m_pNoteField->m_HeldHoldNotes[hn] = bIsHoldingButton && bSteppedOnTapNote;
m_pNoteField->m_ActiveHoldNotes[hn] = bSteppedOnTapNote; m_pNoteField->m_ActiveHoldNotes[hn] = bSteppedOnTapNote;
}
if( bSteppedOnTapNote ) if( bSteppedOnTapNote )
{ {
/* This hold note is not judged and we stepped on its head. Update /* This hold note is not judged and we stepped on its head. Update
* iLastHeldRow. */ * iLastHeldRow. */
HoldNoteResult *hnr = m_pNoteField->CreateHoldNoteResult( hn ); HoldNoteResult *hnr = NULL;
if( m_pNoteField )
{
hnr = m_pNoteField->CreateHoldNoteResult( hn );
hnr->iLastHeldRow = min( iSongRow, hn.iEndRow ); hnr->iLastHeldRow = min( iSongRow, hn.iEndRow );
}
hnr = m_NoteData.CreateHoldNoteResult( hn ); hnr = m_NoteData.CreateHoldNoteResult( hn );
hnr->iLastHeldRow = min( iSongRow, hn.iEndRow ); hnr->iLastHeldRow = min( iSongRow, hn.iEndRow );
@@ -395,6 +412,7 @@ void PlayerMinus::Update( float fDeltaTime )
// Increase life // Increase life
fLife = 1; fLife = 1;
if( m_pNoteField )
m_pNoteField->DidHoldNote( hn.iTrack ); // update the "electric ghost" effect m_pNoteField->DidHoldNote( hn.iTrack ); // update the "electric ghost" effect
} }
else else
@@ -422,6 +440,7 @@ void PlayerMinus::Update( float fDeltaTime )
{ {
fLife = 1; fLife = 1;
hns = HNS_OK; hns = HNS_OK;
if( m_pNoteField )
m_pNoteField->DidTapNote( StyleI.col, TNS_PERFECT, true ); // bright ghost flash m_pNoteField->DidTapNote( StyleI.col, TNS_PERFECT, true ); // bright ghost flash
} }
@@ -436,13 +455,16 @@ void PlayerMinus::Update( float fDeltaTime )
// TODO: Remove use of PlayerNumber. // TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
g_CurStageStats.iTotalError[pn] += ms_error; g_CurStageStats.m_player[pn].iTotalError += ms_error;
if( hns == HNS_NG ) /* don't show a 0 for an OK */ if( hns == HNS_NG ) /* don't show a 0 for an OK */
m_ProTimingDisplay.SetJudgment( ms_error, TNS_MISS ); m_ProTimingDisplay.SetJudgment( ms_error, TNS_MISS );
} }
if( m_pNoteField )
{
m_pNoteField->SetHoldNoteLife(hn, fLife); // update the NoteField display m_pNoteField->SetHoldNoteLife(hn, fLife); // update the NoteField display
m_pNoteField->SetHoldNoteScore(hn, hns); // update the NoteField display m_pNoteField->SetHoldNoteScore(hn, hns); // update the NoteField display
}
m_NoteData.SetHoldNoteLife(hn, fLife); m_NoteData.SetHoldNoteLife(hn, fLife);
m_NoteData.SetHoldNoteScore(hn, hns); m_NoteData.SetHoldNoteScore(hn, hns);
@@ -486,6 +508,7 @@ void PlayerMinus::Update( float fDeltaTime )
/* Cache any newly-used note skins. Normally, the only new skins cached now are /* Cache any newly-used note skins. Normally, the only new skins cached now are
* when we're adding course modifiers at the start of a song. If this is spending * when we're adding course modifiers at the start of a song. If this is spending
* time loading skins in the middle of a song, something is wrong. */ * time loading skins in the middle of a song, something is wrong. */
if( m_pNoteField )
m_pNoteField->CacheAllUsedNoteSkins(); m_pNoteField->CacheAllUsedNoteSkins();
ActorFrame::Update( fDeltaTime ); ActorFrame::Update( fDeltaTime );
@@ -512,6 +535,7 @@ void PlayerMinus::ApplyWaitingTransforms()
GAMESTATE->SetNoteSkinForBeatRange( m_pPlayerState, po.m_sNoteSkin, fStartBeat, fEndBeat ); GAMESTATE->SetNoteSkinForBeatRange( m_pPlayerState, po.m_sNoteSkin, fStartBeat, fEndBeat );
NoteDataUtil::TransformNoteData( m_NoteData, po, GAMESTATE->GetCurrentStyle()->m_StepsType, fStartBeat, fEndBeat ); NoteDataUtil::TransformNoteData( m_NoteData, po, GAMESTATE->GetCurrentStyle()->m_StepsType, fStartBeat, fEndBeat );
if( m_pNoteField )
m_pNoteField->CopyRange( m_NoteData, BeatToNoteRow(fStartBeat), BeatToNoteRow(fEndBeat), BeatToNoteRow(fStartBeat) ); m_pNoteField->CopyRange( m_NoteData, BeatToNoteRow(fStartBeat), BeatToNoteRow(fEndBeat), BeatToNoteRow(fStartBeat) );
} }
m_pPlayerState->m_ModsToApply.clear(); m_pPlayerState->m_ModsToApply.clear();
@@ -519,6 +543,9 @@ void PlayerMinus::ApplyWaitingTransforms()
void PlayerMinus::DrawPrimitives() void PlayerMinus::DrawPrimitives()
{ {
if( m_pNoteField == NULL )
return;
// TODO: Remove use of PlayerNumber. // TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
@@ -673,7 +700,7 @@ void PlayerMinus::Step( int col, RageTimer tm )
// TODO: Remove use of PlayerNumber. // TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && g_CurStageStats.bFailed[pn] ) // Oni dead if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && g_CurStageStats.m_player[pn].bFailed ) // Oni dead
return; // do nothing return; // do nothing
//LOG->Trace( "PlayerMinus::HandlePlayerStep()" ); //LOG->Trace( "PlayerMinus::HandlePlayerStep()" );
@@ -745,9 +772,12 @@ void PlayerMinus::Step( int col, RageTimer tm )
if( m_pCombinedLifeMeter ) if( m_pCombinedLifeMeter )
m_pCombinedLifeMeter->ChangeLifeMine( pn ); m_pCombinedLifeMeter->ChangeLifeMine( pn );
if( m_pNoteField )
{
m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
m_pNoteField->DidTapNote( col, score, false ); m_pNoteField->DidTapNote( col, score, false );
} }
}
break; break;
case TapNote::attack: case TapNote::attack:
@@ -778,6 +808,7 @@ void PlayerMinus::Step( int col, RageTimer tm )
if( tn.type == TapNote::attack ) if( tn.type == TapNote::attack )
{ {
m_NoteData.SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField m_NoteData.SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
if( m_pNoteField )
m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
} }
} }
@@ -840,10 +871,13 @@ void PlayerMinus::Step( int col, RageTimer tm )
if( m_pCombinedLifeMeter ) if( m_pCombinedLifeMeter )
m_pCombinedLifeMeter->ChangeLifeMine( pn ); m_pCombinedLifeMeter->ChangeLifeMine( pn );
if( m_pNoteField )
{
m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
m_pNoteField->DidTapNote( col, score, false ); m_pNoteField->DidTapNote( col, score, false );
} }
} }
}
/* AI will generate misses here. Don't handle a miss like a regular note because /* AI will generate misses here. Don't handle a miss like a regular note because
* we want the judgment animation to appear delayed. Instead, return early if * we want the judgment animation to appear delayed. Instead, return early if
@@ -880,6 +914,7 @@ void PlayerMinus::Step( int col, RageTimer tm )
if( tn.type == TapNote::attack ) if( tn.type == TapNote::attack )
{ {
m_NoteData.SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField m_NoteData.SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
if( m_pNoteField )
m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
} }
} }
@@ -912,7 +947,7 @@ void PlayerMinus::Step( int col, RageTimer tm )
// TODO: Remove use of PlayerNumber. // TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
g_CurStageStats.iTotalError[pn] += ms_error; g_CurStageStats.m_player[pn].iTotalError += ms_error;
if (!m_pPlayerState->m_PlayerOptions.m_fBlind) if (!m_pPlayerState->m_PlayerOptions.m_fBlind)
m_ProTimingDisplay.SetJudgment( ms_error, score ); m_ProTimingDisplay.SetJudgment( ms_error, score );
} }
@@ -969,10 +1004,12 @@ void PlayerMinus::Step( int col, RageTimer tm )
m_iDCState = AS2D_FEVER; // super celebrate time :) m_iDCState = AS2D_FEVER; // super celebrate time :)
} }
} }
if( m_pNoteField )
m_pNoteField->Step( col, score ); m_pNoteField->Step( col, score );
} }
else else
{ {
if( m_pNoteField )
m_pNoteField->Step( col, TNS_NONE ); m_pNoteField->Step( col, TNS_NONE );
} }
@@ -1046,17 +1083,22 @@ void PlayerMinus::OnRowCompletelyJudged( int iIndexThatWasSteppedOn )
// If the score is great or better, remove the note from the screen to // If the score is great or better, remove the note from the screen to
// indicate success. (Or always if blind is on.) // indicate success. (Or always if blind is on.)
if( score >= TNS_GREAT || m_pPlayerState->m_PlayerOptions.m_fBlind ) if( score >= TNS_GREAT || m_pPlayerState->m_PlayerOptions.m_fBlind )
if( m_pNoteField )
m_pNoteField->SetTapNote(c, iIndexThatWasSteppedOn, TAP_EMPTY); m_pNoteField->SetTapNote(c, iIndexThatWasSteppedOn, TAP_EMPTY);
// show the ghost arrow for this column // show the ghost arrow for this column
if (m_pPlayerState->m_PlayerOptions.m_fBlind) if (m_pPlayerState->m_PlayerOptions.m_fBlind)
{
if( m_pNoteField )
m_pNoteField->DidTapNote( c, TNS_MARVELOUS, false ); m_pNoteField->DidTapNote( c, TNS_MARVELOUS, false );
}
else else
{ {
// TODO: Remove use of PlayerNumber. // TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
bool bBright = g_CurStageStats.iCurCombo[pn]>(int)BRIGHT_GHOST_COMBO_THRESHOLD; bool bBright = g_CurStageStats.m_player[pn].iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD;
if( m_pNoteField )
m_pNoteField->DidTapNote( c, score, bBright ); m_pNoteField->DidTapNote( c, score, bBright );
} }
} }
@@ -1118,7 +1160,7 @@ void PlayerMinus::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds )
// TODO: Remove use of PlayerNumber. // TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
g_CurStageStats.iTotalError[pn] += MAX_PRO_TIMING_ERROR; g_CurStageStats.m_player[pn].iTotalError += MAX_PRO_TIMING_ERROR;
m_ProTimingDisplay.SetJudgment( MAX_PRO_TIMING_ERROR, TNS_MISS ); m_ProTimingDisplay.SetJudgment( MAX_PRO_TIMING_ERROR, TNS_MISS );
} }
} }
@@ -1219,12 +1261,15 @@ void PlayerMinus::RandomizeNotes( int iNoteRow )
m_NoteData.SetTapNote( t, iNewNoteRow, t2 ); m_NoteData.SetTapNote( t, iNewNoteRow, t2 );
m_NoteData.SetTapNote( iSwapWith, iNewNoteRow, t1 ); m_NoteData.SetTapNote( iSwapWith, iNewNoteRow, t1 );
if( m_pNoteField )
{
const TapNote nft1 = m_pNoteField->GetTapNote( t, iNewNoteRow ); const TapNote nft1 = m_pNoteField->GetTapNote( t, iNewNoteRow );
const TapNote nft2 = m_pNoteField->GetTapNote( iSwapWith, iNewNoteRow ); const TapNote nft2 = m_pNoteField->GetTapNote( iSwapWith, iNewNoteRow );
m_pNoteField->SetTapNote( t, iNewNoteRow, nft2 ); m_pNoteField->SetTapNote( t, iNewNoteRow, nft2 );
m_pNoteField->SetTapNote( iSwapWith, iNewNoteRow, nft1 ); m_pNoteField->SetTapNote( iSwapWith, iNewNoteRow, nft1 );
} }
} }
}
void PlayerMinus::HandleTapRowScore( unsigned row ) void PlayerMinus::HandleTapRowScore( unsigned row )
{ {
@@ -1247,18 +1292,18 @@ void PlayerMinus::HandleTapRowScore( unsigned row )
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
/* Update miss combo, and handle "combo stopped" messages. */ /* Update miss combo, and handle "combo stopped" messages. */
int &iCurCombo = g_CurStageStats.iCurCombo[pn]; int &iCurCombo = g_CurStageStats.m_player[pn].iCurCombo;
switch( scoreOfLastTap ) switch( scoreOfLastTap )
{ {
case TNS_MARVELOUS: case TNS_MARVELOUS:
case TNS_PERFECT: case TNS_PERFECT:
case TNS_GREAT: case TNS_GREAT:
g_CurStageStats.iCurMissCombo[pn] = 0; g_CurStageStats.m_player[pn].iCurMissCombo = 0;
SCREENMAN->PostMessageToTopScreen( SM_MissComboAborted, 0 ); SCREENMAN->PostMessageToTopScreen( SM_MissComboAborted, 0 );
break; break;
case TNS_MISS: case TNS_MISS:
++g_CurStageStats.iCurMissCombo[pn]; ++g_CurStageStats.m_player[pn].iCurMissCombo;
m_iDCState = AS2D_MISS; // update dancing 2d characters that may have missed a note m_iDCState = AS2D_MISS; // update dancing 2d characters that may have missed a note
case TNS_GOOD: case TNS_GOOD:
case TNS_BOO: case TNS_BOO:
@@ -1272,14 +1317,14 @@ void PlayerMinus::HandleTapRowScore( unsigned row )
} }
/* The score keeper updates the hit combo. Remember the old combo for handling announcers. */ /* The score keeper updates the hit combo. Remember the old combo for handling announcers. */
const int iOldCombo = g_CurStageStats.iCurCombo[pn]; const int iOldCombo = g_CurStageStats.m_player[pn].iCurCombo;
if(m_pPrimaryScoreKeeper) if(m_pPrimaryScoreKeeper)
m_pPrimaryScoreKeeper->HandleTapRowScore(scoreOfLastTap, iNumTapsInRow ); m_pPrimaryScoreKeeper->HandleTapRowScore(scoreOfLastTap, iNumTapsInRow );
if(m_pSecondaryScoreKeeper) if(m_pSecondaryScoreKeeper)
m_pSecondaryScoreKeeper->HandleTapRowScore(scoreOfLastTap, iNumTapsInRow ); m_pSecondaryScoreKeeper->HandleTapRowScore(scoreOfLastTap, iNumTapsInRow );
m_Combo.SetCombo( g_CurStageStats.iCurCombo[pn], g_CurStageStats.iCurMissCombo[pn] ); m_Combo.SetCombo( g_CurStageStats.m_player[pn].iCurCombo, g_CurStageStats.m_player[pn].iCurMissCombo );
#define CROSSED( x ) (iOldCombo<x && iCurCombo>=x) #define CROSSED( x ) (iOldCombo<x && iCurCombo>=x)
if ( CROSSED(100) ) if ( CROSSED(100) )
@@ -1307,16 +1352,18 @@ void PlayerMinus::HandleTapRowScore( unsigned row )
#undef CROSSED #undef CROSSED
// new max combo // new max combo
g_CurStageStats.iMaxCombo[pn] = max(g_CurStageStats.iMaxCombo[pn], iCurCombo); g_CurStageStats.m_player[pn].iMaxCombo = max(g_CurStageStats.m_player[pn].iMaxCombo, iCurCombo);
/* Use the real current beat, not the beat we've been passed. That's because we /* Use the real current beat, not the beat we've been passed. That's because we
* want to record the current life/combo to the current time; eg. if it's a MISS, * want to record the current life/combo to the current time; eg. if it's a MISS,
* the beat we're registering is in the past, but the life is changing now. */ * the beat we're registering is in the past, but the life is changing now. */
g_CurStageStats.UpdateComboList( pn, g_CurStageStats.fAliveSeconds[pn], false ); g_CurStageStats.m_player[pn].UpdateComboList( g_CurStageStats.m_player[pn].fAliveSeconds, false );
float life = -1; float life = -1;
if( m_pLifeMeter ) if( m_pLifeMeter )
{
life = m_pLifeMeter->GetLife(); life = m_pLifeMeter->GetLife();
}
else if( m_pCombinedLifeMeter ) else if( m_pCombinedLifeMeter )
{ {
life = GAMESTATE->m_fTugLifePercentP1; life = GAMESTATE->m_fTugLifePercentP1;
@@ -1324,12 +1371,12 @@ void PlayerMinus::HandleTapRowScore( unsigned row )
life = 1.0f - life; life = 1.0f - life;
} }
if( life != -1 ) if( life != -1 )
g_CurStageStats.SetLifeRecordAt( pn, life, g_CurStageStats.fAliveSeconds[pn] ); g_CurStageStats.m_player[pn].SetLifeRecordAt( life, g_CurStageStats.m_player[pn].fAliveSeconds );
if (m_pScoreDisplay) if (m_pScoreDisplay)
m_pScoreDisplay->SetScore(g_CurStageStats.iScore[pn]); m_pScoreDisplay->SetScore(g_CurStageStats.m_player[pn].iScore);
if (m_pSecondaryScoreDisplay) if (m_pSecondaryScoreDisplay)
m_pSecondaryScoreDisplay->SetScore(g_CurStageStats.iScore[pn]); m_pSecondaryScoreDisplay->SetScore(g_CurStageStats.m_player[pn].iScore);
if( m_pLifeMeter ) { if( m_pLifeMeter ) {
m_pLifeMeter->ChangeLife( scoreOfLastTap ); m_pLifeMeter->ChangeLife( scoreOfLastTap );
@@ -1364,9 +1411,9 @@ void PlayerMinus::HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tapScor
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
if (m_pScoreDisplay) if (m_pScoreDisplay)
m_pScoreDisplay->SetScore(g_CurStageStats.iScore[pn]); m_pScoreDisplay->SetScore(g_CurStageStats.m_player[pn].iScore);
if (m_pSecondaryScoreDisplay) if (m_pSecondaryScoreDisplay)
m_pSecondaryScoreDisplay->SetScore(g_CurStageStats.iScore[pn]); m_pSecondaryScoreDisplay->SetScore(g_CurStageStats.m_player[pn].iScore);
if( m_pLifeMeter ) if( m_pLifeMeter )
{ {
@@ -1387,6 +1434,7 @@ float PlayerMinus::GetMaxStepDistanceSeconds()
void PlayerMinus::FadeToFail() void PlayerMinus::FadeToFail()
{ {
if( m_pNoteField )
m_pNoteField->FadeToFail(); m_pNoteField->FadeToFail();
} }
+35
View File
@@ -10,6 +10,41 @@
struct PlayerState struct PlayerState
{ {
PlayerState()
{
m_PlayerNumber = PLAYER_INVALID;
Reset();
}
void Reset()
{
m_CurrentPlayerOptions.Init();
m_PlayerOptions.Init();
m_StoredPlayerOptions.Init();
m_BeatToNoteSkin.clear();
m_fLastDrawnBeat = -100;
m_HealthState = ALIVE;
m_PlayerController = PC_HUMAN;
m_iCpuSkill = 5;
m_iLastPositiveSumOfAttackLevels = 0;
m_fSecondsUntilAttacksPhasedOut = 0;
m_bAttackBeganThisUpdate = false;
m_bAttackEndedThisUpdate = false;
m_ActiveAttacks.clear();
m_ModsToApply.clear();
m_fSuperMeter = 0; // between 0 and NUM_ATTACK_LEVELS
m_fSuperMeterGrowthScale = 1;
for( int i=0; i<NUM_INVENTORY_SLOTS; i++ )
m_Inventory[i].MakeBlank();
}
// TODO: Remove use of PlayerNumber. All data about the player should live // TODO: Remove use of PlayerNumber. All data about the player should live
// in PlayerState and callers should not use PlayerNumber to index into // in PlayerState and callers should not use PlayerNumber to index into
// GameState. // GameState.
+1 -1
View File
@@ -43,7 +43,7 @@ void ScoreDisplayOni::Update( float fDelta )
float fSecsIntoPlay = 0; float fSecsIntoPlay = 0;
if( GAMESTATE->IsPlayerEnabled(pn) ) if( GAMESTATE->IsPlayerEnabled(pn) )
fSecsIntoPlay = g_CurStageStats.fAliveSeconds[pn]; fSecsIntoPlay = g_CurStageStats.m_player[pn].fAliveSeconds;
m_text.SetText( SecondsToMMSSMsMs(fSecsIntoPlay) ); m_text.SetText( SecondsToMMSSMsMs(fSecsIntoPlay) );
} }
+20 -18
View File
@@ -66,7 +66,7 @@ ScoreKeeperMAX2::ScoreKeeperMAX2( const vector<Song*>& apSongs, const vector<Ste
// TODO: Move StageStats numbers into PlayerState. // TODO: Move StageStats numbers into PlayerState.
{ {
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
g_CurStageStats.iPossibleDancePoints[pn] = iTotalPossibleDancePoints; g_CurStageStats.m_player[pn].iPossibleDancePoints = iTotalPossibleDancePoints;
} }
@@ -206,7 +206,7 @@ void ScoreKeeperMAX2::AddScore( TapNoteScore score )
{ {
// TODO: Move StageStats numbers into PlayerState. // TODO: Move StageStats numbers into PlayerState.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber; PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
int &iScore = g_CurStageStats.iScore[pn]; int &iScore = g_CurStageStats.m_player[pn].iScore;
/* /*
http://www.aaroninjapan.com/ddr2.html http://www.aaroninjapan.com/ddr2.html
@@ -266,7 +266,7 @@ void ScoreKeeperMAX2::AddScore( TapNoteScore score )
const int B = m_iMaxPossiblePoints/10; const int B = m_iMaxPossiblePoints/10;
// Don't use a multiplier if the player has failed // Don't use a multiplier if the player has failed
if( g_CurStageStats.bFailedEarlier[pn] ) if( g_CurStageStats.m_player[pn].bFailedEarlier )
{ {
iScore += p; iScore += p;
// make score evenly divisible by 5 // make score evenly divisible by 5
@@ -279,8 +279,8 @@ void ScoreKeeperMAX2::AddScore( TapNoteScore score )
else else
{ {
iScore += GetScore(p, B, sum, m_iTapNotesHit); iScore += GetScore(p, B, sum, m_iTapNotesHit);
const int &iCurrentCombo = g_CurStageStats.iCurCombo[pn]; const int &iCurrentCombo = g_CurStageStats.m_player[pn].iCurCombo;
g_CurStageStats.iBonus[pn] += m_ComboBonusFactor[score] * iCurrentCombo; g_CurStageStats.m_player[pn].iBonus += m_ComboBonusFactor[score] * iCurrentCombo;
} }
/* Subtract the maximum this step could have been worth from the bonus. */ /* Subtract the maximum this step could have been worth from the bonus. */
@@ -288,7 +288,7 @@ void ScoreKeeperMAX2::AddScore( TapNoteScore score )
if ( m_iTapNotesHit == m_iNumTapsAndHolds && score >= TNS_PERFECT ) if ( m_iTapNotesHit == m_iNumTapsAndHolds && score >= TNS_PERFECT )
{ {
if (!g_CurStageStats.bFailedEarlier[pn]) if (!g_CurStageStats.m_player[pn].bFailedEarlier)
iScore += m_iPointBonus; iScore += m_iPointBonus;
if ( m_bIsLastSongInCourse ) if ( m_bIsLastSongInCourse )
{ {
@@ -320,8 +320,8 @@ void ScoreKeeperMAX2::HandleTapScore( TapNoteScore score )
if( score == TNS_HIT_MINE ) if( score == TNS_HIT_MINE )
{ {
if( m_pPlayerState->m_HealthState != PlayerState::DEAD ) if( m_pPlayerState->m_HealthState != PlayerState::DEAD )
g_CurStageStats.iActualDancePoints[pn] += TapNoteScoreToDancePoints( TNS_HIT_MINE ); g_CurStageStats.m_player[pn].iActualDancePoints += TapNoteScoreToDancePoints( TNS_HIT_MINE );
g_CurStageStats.iTapNoteScores[pn][TNS_HIT_MINE] += 1; g_CurStageStats.m_player[pn].iTapNoteScores[TNS_HIT_MINE] += 1;
} }
} }
@@ -334,9 +334,9 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa
// Update dance points. // Update dance points.
if( m_pPlayerState->m_HealthState != PlayerState::DEAD ) if( m_pPlayerState->m_HealthState != PlayerState::DEAD )
g_CurStageStats.iActualDancePoints[pn] += TapNoteScoreToDancePoints( scoreOfLastTap ); g_CurStageStats.m_player[pn].iActualDancePoints += TapNoteScoreToDancePoints( scoreOfLastTap );
// update judged row totals // update judged row totals
g_CurStageStats.iTapNoteScores[pn][scoreOfLastTap] += 1; g_CurStageStats.m_player[pn].iTapNoteScores[scoreOfLastTap] += 1;
// //
// Regular combo // Regular combo
@@ -367,7 +367,7 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa
TapNoteScore MinScoreToContinueCombo = GAMESTATE->m_PlayMode == PLAY_MODE_ONI? TNS_PERFECT:TNS_GREAT; TapNoteScore MinScoreToContinueCombo = GAMESTATE->m_PlayMode == PLAY_MODE_ONI? TNS_PERFECT:TNS_GREAT;
if( scoreOfLastTap >= MinScoreToContinueCombo ) if( scoreOfLastTap >= MinScoreToContinueCombo )
g_CurStageStats.iCurCombo[pn] += ComboCountIfHit; g_CurStageStats.m_player[pn].iCurCombo += ComboCountIfHit;
AddScore( scoreOfLastTap ); // only score once per row AddScore( scoreOfLastTap ); // only score once per row
@@ -409,8 +409,8 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa
// TODO: Remove indexing with PlayerNumber // TODO: Remove indexing with PlayerNumber
NSMAN->ReportScore(pn, scoreOfLastTap, NSMAN->ReportScore(pn, scoreOfLastTap,
g_CurStageStats.iScore[pn], g_CurStageStats.m_player[pn].iScore,
g_CurStageStats.iCurCombo[pn]); g_CurStageStats.m_player[pn].iCurCombo);
} }
@@ -421,15 +421,17 @@ void ScoreKeeperMAX2::HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tap
// update dance points totals // update dance points totals
if( m_pPlayerState->m_HealthState != PlayerState::DEAD ) if( m_pPlayerState->m_HealthState != PlayerState::DEAD )
g_CurStageStats.iActualDancePoints[pn] += HoldNoteScoreToDancePoints( holdScore ); g_CurStageStats.m_player[pn].iActualDancePoints += HoldNoteScoreToDancePoints( holdScore );
g_CurStageStats.iHoldNoteScores[pn][holdScore] ++; g_CurStageStats.m_player[pn].iHoldNoteScores[holdScore] ++;
if( holdScore == HNS_OK ) if( holdScore == HNS_OK )
AddScore( TNS_MARVELOUS ); AddScore( TNS_MARVELOUS );
NSMAN->ReportScore(pn, holdScore+7, NSMAN->ReportScore(
g_CurStageStats.iScore[pn], pn,
g_CurStageStats.iCurCombo[pn]); holdScore+7,
g_CurStageStats.m_player[pn].iScore,
g_CurStageStats.m_player[pn].iCurCombo );
} }
+22 -22
View File
@@ -151,8 +151,8 @@ ScreenEnding::ScreenEnding( CString sClassName ) : ScreenAttract( sClassName, fa
GAMESTATE->m_pCurCourse = SONGMAN->GetRandomCourse(); GAMESTATE->m_pCurCourse = SONGMAN->GetRandomCourse();
GAMESTATE->m_pCurSteps[PLAYER_1] = GAMESTATE->m_pCurSong->GetAllSteps()[0]; GAMESTATE->m_pCurSteps[PLAYER_1] = GAMESTATE->m_pCurSong->GetAllSteps()[0];
GAMESTATE->m_pCurSteps[PLAYER_2] = GAMESTATE->m_pCurSong->GetAllSteps()[0]; GAMESTATE->m_pCurSteps[PLAYER_2] = GAMESTATE->m_pCurSong->GetAllSteps()[0];
g_CurStageStats.vpSteps[PLAYER_1].push_back( GAMESTATE->m_pCurSteps[PLAYER_1] ); g_CurStageStats.m_player[PLAYER_1].vpSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_1] );
g_CurStageStats.vpSteps[PLAYER_2].push_back( GAMESTATE->m_pCurSteps[PLAYER_2] ); g_CurStageStats.m_player[PLAYER_2].vpSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.m_fScrollSpeed = 2; GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_pPlayerState[PLAYER_2]->m_PlayerOptions.m_fScrollSpeed = 2; GAMESTATE->m_pPlayerState[PLAYER_2]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_iCurrentStageIndex = 0; GAMESTATE->m_iCurrentStageIndex = 0;
@@ -162,29 +162,29 @@ ScreenEnding::ScreenEnding( CString sClassName ) : ScreenAttract( sClassName, fa
for( float f = 0; f < 100.0f; f += 1.0f ) for( float f = 0; f < 100.0f; f += 1.0f )
{ {
float fP1 = fmodf(f/100*4+.3f,1); float fP1 = fmodf(f/100*4+.3f,1);
g_CurStageStats.SetLifeRecordAt( PLAYER_1, fP1, f ); g_CurStageStats.m_player[PLAYER_1].SetLifeRecordAt( fP1, f );
g_CurStageStats.SetLifeRecordAt( PLAYER_2, 1-fP1, f ); g_CurStageStats.m_player[PLAYER_2].SetLifeRecordAt( 1-fP1, f );
} }
g_CurStageStats.iActualDancePoints[PLAYER_1] = rand()%3; g_CurStageStats.m_player[PLAYER_1].iActualDancePoints = rand()%3;
g_CurStageStats.iPossibleDancePoints[PLAYER_1] = 2; g_CurStageStats.m_player[PLAYER_1].iPossibleDancePoints = 2;
g_CurStageStats.iActualDancePoints[PLAYER_2] = rand()%2; g_CurStageStats.m_player[PLAYER_2].iActualDancePoints = rand()%2;
g_CurStageStats.iPossibleDancePoints[PLAYER_2] = 1; g_CurStageStats.m_player[PLAYER_2].iPossibleDancePoints = 1;
g_CurStageStats.iCurCombo[PLAYER_1] = 0; g_CurStageStats.m_player[PLAYER_1].iCurCombo = 0;
g_CurStageStats.UpdateComboList( PLAYER_1, 0, false ); g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 0, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 1; g_CurStageStats.m_player[PLAYER_1].iCurCombo = 1;
g_CurStageStats.UpdateComboList( PLAYER_1, 1, false ); g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 1, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 50; g_CurStageStats.m_player[PLAYER_1].iCurCombo = 50;
g_CurStageStats.UpdateComboList( PLAYER_1, 25, false ); g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 25, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 250; g_CurStageStats.m_player[PLAYER_1].iCurCombo = 250;
g_CurStageStats.UpdateComboList( PLAYER_1, 100, false ); g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 100, false );
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_MARVELOUS] = rand()%2; g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_MARVELOUS] = rand()%2;
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_PERFECT] = rand()%2; g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_PERFECT] = rand()%2;
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_GREAT] = rand()%2; g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_GREAT] = rand()%2;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_MARVELOUS] = rand()%2; g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_MARVELOUS] = rand()%2;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_PERFECT] = rand()%2; g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_PERFECT] = rand()%2;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_GREAT] = rand()%2; g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_GREAT] = rand()%2;
g_vPlayedStageStats.clear(); g_vPlayedStageStats.clear();
} }
+82 -82
View File
@@ -112,8 +112,8 @@ void ScreenEvaluation::Init()
GAMESTATE->m_pCurCourse = SONGMAN->GetRandomCourse(); GAMESTATE->m_pCurCourse = SONGMAN->GetRandomCourse();
GAMESTATE->m_pCurSteps[PLAYER_1] = GAMESTATE->m_pCurSong->GetAllSteps()[0]; GAMESTATE->m_pCurSteps[PLAYER_1] = GAMESTATE->m_pCurSong->GetAllSteps()[0];
GAMESTATE->m_pCurSteps[PLAYER_2] = GAMESTATE->m_pCurSong->GetAllSteps()[0]; GAMESTATE->m_pCurSteps[PLAYER_2] = GAMESTATE->m_pCurSong->GetAllSteps()[0];
g_CurStageStats.vpSteps[PLAYER_1].push_back( GAMESTATE->m_pCurSteps[PLAYER_1] ); g_CurStageStats.m_player[PLAYER_1].vpSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_1] );
g_CurStageStats.vpSteps[PLAYER_2].push_back( GAMESTATE->m_pCurSteps[PLAYER_2] ); g_CurStageStats.m_player[PLAYER_2].vpSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.m_fScrollSpeed = 2; GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_pPlayerState[PLAYER_2]->m_PlayerOptions.m_fScrollSpeed = 2; GAMESTATE->m_pPlayerState[PLAYER_2]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_iCurrentStageIndex = 0; GAMESTATE->m_iCurrentStageIndex = 0;
@@ -123,47 +123,47 @@ void ScreenEvaluation::Init()
for( float f = 0; f < 100.0f; f += 1.0f ) for( float f = 0; f < 100.0f; f += 1.0f )
{ {
float fP1 = fmodf(f/100*4+.3f,1); float fP1 = fmodf(f/100*4+.3f,1);
g_CurStageStats.SetLifeRecordAt( PLAYER_1, fP1, f ); g_CurStageStats.m_player[PLAYER_1].SetLifeRecordAt( fP1, f );
g_CurStageStats.SetLifeRecordAt( PLAYER_2, 1-fP1, f ); g_CurStageStats.m_player[PLAYER_2].SetLifeRecordAt( 1-fP1, f );
} }
g_CurStageStats.iActualDancePoints[PLAYER_1] = rand()%3; g_CurStageStats.m_player[PLAYER_1].iActualDancePoints = rand()%3;
g_CurStageStats.iPossibleDancePoints[PLAYER_1] = 2; g_CurStageStats.m_player[PLAYER_1].iPossibleDancePoints = 2;
g_CurStageStats.iActualDancePoints[PLAYER_2] = rand()%2; g_CurStageStats.m_player[PLAYER_2].iActualDancePoints = rand()%2;
g_CurStageStats.iPossibleDancePoints[PLAYER_2] = 1; g_CurStageStats.m_player[PLAYER_2].iPossibleDancePoints = 1;
g_CurStageStats.iCurCombo[PLAYER_1] = 0; g_CurStageStats.m_player[PLAYER_1].iCurCombo = 0;
g_CurStageStats.UpdateComboList( PLAYER_1, 0, false ); g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 0, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 1; g_CurStageStats.m_player[PLAYER_1].iCurCombo = 1;
g_CurStageStats.UpdateComboList( PLAYER_1, 1, false ); g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 1, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 50; g_CurStageStats.m_player[PLAYER_1].iCurCombo = 50;
g_CurStageStats.UpdateComboList( PLAYER_1, 25, false ); g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 25, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 250; g_CurStageStats.m_player[PLAYER_1].iCurCombo = 250;
g_CurStageStats.UpdateComboList( PLAYER_1, 100, false ); g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 100, false );
if( rand()%2 ) if( rand()%2 )
{ {
g_CurStageStats.iCurCombo[PLAYER_1] = rand()%11000; g_CurStageStats.m_player[PLAYER_1].iCurCombo = rand()%11000;
g_CurStageStats.UpdateComboList( PLAYER_1, 110, false ); g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 110, false );
} }
g_CurStageStats.iCurCombo[PLAYER_2] = 0; g_CurStageStats.m_player[PLAYER_2].iCurCombo = 0;
g_CurStageStats.UpdateComboList( PLAYER_2, 0, false ); g_CurStageStats.m_player[PLAYER_2].UpdateComboList( 0, false );
g_CurStageStats.iCurCombo[PLAYER_2] = 1; g_CurStageStats.m_player[PLAYER_2].iCurCombo = 1;
g_CurStageStats.UpdateComboList( PLAYER_2, 1, false ); g_CurStageStats.m_player[PLAYER_2].UpdateComboList( 1, false );
g_CurStageStats.iCurCombo[PLAYER_2] = 50; g_CurStageStats.m_player[PLAYER_2].iCurCombo = 50;
g_CurStageStats.UpdateComboList( PLAYER_2, 25, false ); g_CurStageStats.m_player[PLAYER_2].UpdateComboList( 25, false );
g_CurStageStats.iCurCombo[PLAYER_2] = 250; g_CurStageStats.m_player[PLAYER_2].iCurCombo = 250;
g_CurStageStats.UpdateComboList( PLAYER_2, 100, false ); g_CurStageStats.m_player[PLAYER_2].UpdateComboList( 100, false );
if( rand()%2 ) if( rand()%2 )
{ {
g_CurStageStats.iCurCombo[PLAYER_2] = rand()%11000; g_CurStageStats.m_player[PLAYER_2].iCurCombo = rand()%11000;
g_CurStageStats.UpdateComboList( PLAYER_2, 110, false ); g_CurStageStats.m_player[PLAYER_2].UpdateComboList( 110, false );
} }
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_MARVELOUS] = rand()%3; g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_MARVELOUS] = rand()%3;
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_PERFECT] = rand()%3; g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_PERFECT] = rand()%3;
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_GREAT] = rand()%3; g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_GREAT] = rand()%3;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_MARVELOUS] = rand()%3; g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_MARVELOUS] = rand()%3;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_PERFECT] = rand()%3; g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_PERFECT] = rand()%3;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_GREAT] = rand()%3; g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_GREAT] = rand()%3;
g_vPlayedStageStats.clear(); g_vPlayedStageStats.clear();
} }
@@ -205,7 +205,7 @@ void ScreenEvaluation::Init()
ASSERT(0); ASSERT(0);
} }
LOG->Trace( "total error: %i, %i", stageStats.iTotalError[0], stageStats.iTotalError[1] ); LOG->Trace( "total error: %i, %i", stageStats.m_player[PLAYER_1].iTotalError, stageStats.m_player[PLAYER_2].iTotalError );
/* /*
// //
@@ -229,7 +229,7 @@ void ScreenEvaluation::Init()
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
{ {
if( GAMESTATE->IsPlayerEnabled(p) ) if( GAMESTATE->IsPlayerEnabled(p) )
grade[p] = stageStats.GetGrade( p ); grade[p] = stageStats.m_player[p].GetGrade();
else else
grade[p] = GRADE_FAILED; grade[p] = GRADE_FAILED;
@@ -238,8 +238,8 @@ void ScreenEvaluation::Init()
const int ScoreBonuses[] = { 10000000, 10000000, 1000000, 100000, 10000, 1000, 100 }; const int ScoreBonuses[] = { 10000000, 10000000, 1000000, 100000, 10000, 1000, 100 };
if( grade[p] < (int) ARRAYSIZE(ScoreBonuses) ) if( grade[p] < (int) ARRAYSIZE(ScoreBonuses) )
{ {
g_CurStageStats.iBonus[p] += ScoreBonuses[(int)grade[p] ]; g_CurStageStats.m_player[p].iBonus += ScoreBonuses[(int)grade[p] ];
stageStats.iBonus[p] += ScoreBonuses[(int)grade[p] ]; stageStats.m_player[p].iBonus += ScoreBonuses[(int)grade[p] ];
} }
} }
} }
@@ -536,14 +536,14 @@ void ScreenEvaluation::Init()
for( int r=0; r<NUM_SHOWN_RADAR_CATEGORIES; r++ ) // foreach line for( int r=0; r<NUM_SHOWN_RADAR_CATEGORIES; r++ ) // foreach line
{ {
m_sprPossibleBar[p][r].Load( THEME->GetPathToG(ssprintf("ScreenEvaluation bar possible p%d",p+1)) ); m_sprPossibleBar[p][r].Load( THEME->GetPathToG(ssprintf("ScreenEvaluation bar possible p%d",p+1)) );
m_sprPossibleBar[p][r].SetWidth( m_sprPossibleBar[p][r].GetUnzoomedWidth() * stageStats.radarPossible[p][r] ); m_sprPossibleBar[p][r].SetWidth( m_sprPossibleBar[p][r].GetUnzoomedWidth() * stageStats.m_player[p].radarPossible[r] );
m_sprPossibleBar[p][r].SetName( ssprintf("BarPossible%dP%d",r+1,p+1) ); m_sprPossibleBar[p][r].SetName( ssprintf("BarPossible%dP%d",r+1,p+1) );
SET_XY_AND_ON_COMMAND( m_sprPossibleBar[p][r] ); SET_XY_AND_ON_COMMAND( m_sprPossibleBar[p][r] );
this->AddChild( &m_sprPossibleBar[p][r] ); this->AddChild( &m_sprPossibleBar[p][r] );
m_sprActualBar[p][r].Load( THEME->GetPathToG(ssprintf("ScreenEvaluation bar actual p%d",p+1)) ); m_sprActualBar[p][r].Load( THEME->GetPathToG(ssprintf("ScreenEvaluation bar actual p%d",p+1)) );
// should be out of the possible bar, not actual (whatever value that is at) // should be out of the possible bar, not actual (whatever value that is at)
m_sprActualBar[p][r].SetWidth( m_sprPossibleBar[p][r].GetUnzoomedWidth() * stageStats.radarActual[p][r] ); m_sprActualBar[p][r].SetWidth( m_sprPossibleBar[p][r].GetUnzoomedWidth() * stageStats.m_player[p].radarActual[r] );
float value = (float)100 * m_sprActualBar[p][r].GetUnzoomedWidth() / m_sprPossibleBar[p][r].GetUnzoomedWidth(); float value = (float)100 * m_sprActualBar[p][r].GetUnzoomedWidth() / m_sprPossibleBar[p][r].GetUnzoomedWidth();
LOG->Trace("Radar bar %d of 5 - %f percent", r, value); LOG->Trace("Radar bar %d of 5 - %f percent", r, value);
@@ -552,7 +552,7 @@ void ScreenEvaluation::Init()
SET_XY_AND_ON_COMMAND( m_sprActualBar[p][r] ); SET_XY_AND_ON_COMMAND( m_sprActualBar[p][r] );
// .99999 is fairly close to 1.00, so we use that // .99999 is fairly close to 1.00, so we use that
if( stageStats.radarActual[p][r] > 0.99999f ) if( stageStats.m_player[p].radarActual[r] > 0.99999f )
m_sprActualBar[p][r].RunCommands( BAR_ACTUAL_MAX_COMMAND ); m_sprActualBar[p][r].RunCommands( BAR_ACTUAL_MAX_COMMAND );
this->AddChild( &m_sprActualBar[p][r] ); this->AddChild( &m_sprActualBar[p][r] );
} }
@@ -575,7 +575,7 @@ void ScreenEvaluation::Init()
m_textSurvivedNumber[p].SetShadowLength( 0 ); m_textSurvivedNumber[p].SetShadowLength( 0 );
// curewater: edited the "# stages cleared" text so it deducts one if you failed. // curewater: edited the "# stages cleared" text so it deducts one if you failed.
// Should be accurate, but I'm not sure if its "standard" that (bool)true = 1. (assumption) // Should be accurate, but I'm not sure if its "standard" that (bool)true = 1. (assumption)
m_textSurvivedNumber[p].SetText( ssprintf("%02d", stageStats.iSongsPlayed[p] - (int)stageStats.bFailed[p]) ); m_textSurvivedNumber[p].SetText( ssprintf("%02d", stageStats.m_player[p].iSongsPlayed - (int)stageStats.m_player[p].bFailed) );
m_textSurvivedNumber[p].SetName( ssprintf("SurvivedNumberP%d",p+1) ); m_textSurvivedNumber[p].SetName( ssprintf("SurvivedNumberP%d",p+1) );
SET_XY_AND_ON_COMMAND( m_textSurvivedNumber[p] ); SET_XY_AND_ON_COMMAND( m_textSurvivedNumber[p] );
this->AddChild( &m_textSurvivedNumber[p] ); this->AddChild( &m_textSurvivedNumber[p] );
@@ -634,15 +634,15 @@ void ScreenEvaluation::Init()
int iValue; int iValue;
switch( l ) switch( l )
{ {
case marvelous: iValue = stageStats.iTapNoteScores[p][TNS_MARVELOUS]; break; case marvelous: iValue = stageStats.m_player[p].iTapNoteScores[TNS_MARVELOUS]; break;
case perfect: iValue = stageStats.iTapNoteScores[p][TNS_PERFECT]; break; case perfect: iValue = stageStats.m_player[p].iTapNoteScores[TNS_PERFECT]; break;
case great: iValue = stageStats.iTapNoteScores[p][TNS_GREAT]; break; case great: iValue = stageStats.m_player[p].iTapNoteScores[TNS_GREAT]; break;
case good: iValue = stageStats.iTapNoteScores[p][TNS_GOOD]; break; case good: iValue = stageStats.m_player[p].iTapNoteScores[TNS_GOOD]; break;
case boo: iValue = stageStats.iTapNoteScores[p][TNS_BOO]; break; case boo: iValue = stageStats.m_player[p].iTapNoteScores[TNS_BOO]; break;
case miss: iValue = stageStats.iTapNoteScores[p][TNS_MISS]; break; case miss: iValue = stageStats.m_player[p].iTapNoteScores[TNS_MISS]; break;
case ok: iValue = stageStats.iHoldNoteScores[p][HNS_OK]; break; case ok: iValue = stageStats.m_player[p].iHoldNoteScores[HNS_OK]; break;
case max_combo: iValue = stageStats.GetMaxCombo(p).cnt; break; case max_combo: iValue = stageStats.m_player[p].GetMaxCombo().cnt; break;
case error: iValue = stageStats.iTotalError[p]; break; case error: iValue = stageStats.m_player[p].iTotalError; break;
default: iValue = 0; ASSERT(0); default: iValue = 0; ASSERT(0);
} }
@@ -677,8 +677,8 @@ void ScreenEvaluation::Init()
RADAR_NUM_JUMPS, RADAR_NUM_HOLDS, RADAR_NUM_MINES, RADAR_NUM_HANDS RADAR_NUM_JUMPS, RADAR_NUM_HOLDS, RADAR_NUM_MINES, RADAR_NUM_HANDS
}; };
const int ind = indeces[l]; const int ind = indeces[l];
const int iActual = (int) roundf(stageStats.radarActual[p][ind]); const int iActual = (int) roundf(stageStats.m_player[p].radarActual[ind]);
const int iPossible = (int) roundf(stageStats.radarPossible[p][ind]); const int iPossible = (int) roundf(stageStats.m_player[p].radarPossible[ind]);
m_textStatsText[l][p].SetText( ssprintf("%3d/%3d",iActual,iPossible) ); m_textStatsText[l][p].SetText( ssprintf("%3d/%3d",iActual,iPossible) );
} }
@@ -701,7 +701,7 @@ void ScreenEvaluation::Init()
m_textScore[p].SetDiffuse( PlayerToColor(p) ); m_textScore[p].SetDiffuse( PlayerToColor(p) );
m_textScore[p].SetName( ssprintf("ScoreNumberP%d",p+1) ); m_textScore[p].SetName( ssprintf("ScoreNumberP%d",p+1) );
SET_XY_AND_ON_COMMAND( m_textScore[p] ); SET_XY_AND_ON_COMMAND( m_textScore[p] );
m_textScore[p].SetText( ssprintf("%*.0i", NUM_SCORE_DIGITS, stageStats.iScore[p]) ); m_textScore[p].SetText( ssprintf("%*.0i", NUM_SCORE_DIGITS, stageStats.m_player[p].iScore) );
this->AddChild( &m_textScore[p] ); this->AddChild( &m_textScore[p] );
} }
} }
@@ -717,9 +717,9 @@ void ScreenEvaluation::Init()
{ {
int iTotalScore=0; int iTotalScore=0;
for( unsigned i=0; i<g_vPlayedStageStats.size(); i++ ) for( unsigned i=0; i<g_vPlayedStageStats.size(); i++ )
iTotalScore += g_vPlayedStageStats[i].iScore[p]; iTotalScore += g_vPlayedStageStats[i].m_player[p].iScore;
//iTotalScore += stageStats.iScore[p]; //iTotalScore += stageStats.m_player[p].iScore;
m_textTotalScore[p].LoadFromFont( THEME->GetPathF(m_sName, "totalscore") ); m_textTotalScore[p].LoadFromFont( THEME->GetPathF(m_sName, "totalscore") );
m_textTotalScore[p].SetShadowLength( 0 ); m_textTotalScore[p].SetShadowLength( 0 );
@@ -749,7 +749,7 @@ void ScreenEvaluation::Init()
m_textTime[p].SetDiffuse( PlayerToColor(p) ); m_textTime[p].SetDiffuse( PlayerToColor(p) );
m_textTime[p].SetName( ssprintf("TimeNumberP%d",p+1) ); m_textTime[p].SetName( ssprintf("TimeNumberP%d",p+1) );
SET_XY_AND_ON_COMMAND( m_textTime[p] ); SET_XY_AND_ON_COMMAND( m_textTime[p] );
m_textTime[p].SetText( SecondsToMMSSMsMs(stageStats.fAliveSeconds[p]) ); m_textTime[p].SetText( SecondsToMMSSMsMs(stageStats.m_player[p].fAliveSeconds) );
this->AddChild( &m_textTime[p] ); this->AddChild( &m_textTime[p] );
} }
} }
@@ -927,18 +927,18 @@ void ScreenEvaluation::CommitScores(
HighScore &hs = m_HighScore[p]; HighScore &hs = m_HighScore[p];
hs.sName = RANKING_TO_FILL_IN_MARKER[p]; hs.sName = RANKING_TO_FILL_IN_MARKER[p];
hs.grade = stageStats.GetGrade( p ); hs.grade = stageStats.m_player[p].GetGrade();
hs.iScore = stageStats.iScore[p]; hs.iScore = stageStats.m_player[p].iScore;
hs.fPercentDP = stageStats.GetPercentDancePoints( p ); hs.fPercentDP = stageStats.m_player[p].GetPercentDancePoints();
hs.fSurviveSeconds = stageStats.fAliveSeconds[p]; hs.fSurviveSeconds = stageStats.m_player[p].fAliveSeconds;
hs.sModifiers = GAMESTATE->m_pPlayerState[p]->m_PlayerOptions.GetString(); hs.sModifiers = GAMESTATE->m_pPlayerState[p]->m_PlayerOptions.GetString();
hs.dateTime = DateTime::GetNowDateTime(); hs.dateTime = DateTime::GetNowDateTime();
hs.sPlayerGuid = PROFILEMAN->IsUsingProfile(p) ? PROFILEMAN->GetProfile(p)->m_sGuid : CString(""); hs.sPlayerGuid = PROFILEMAN->IsUsingProfile(p) ? PROFILEMAN->GetProfile(p)->m_sGuid : CString("");
hs.sMachineGuid = PROFILEMAN->GetMachineProfile()->m_sGuid; hs.sMachineGuid = PROFILEMAN->GetMachineProfile()->m_sGuid;
hs.iProductID = PREFSMAN->m_iProductID; hs.iProductID = PREFSMAN->m_iProductID;
memcpy( hs.iTapNoteScores, stageStats.iTapNoteScores[p], sizeof(hs.iTapNoteScores) ); memcpy( hs.iTapNoteScores, stageStats.m_player[p].iTapNoteScores, sizeof(hs.iTapNoteScores) );
memcpy( hs.iHoldNoteScores, stageStats.iHoldNoteScores[p], sizeof(hs.iHoldNoteScores) ); memcpy( hs.iHoldNoteScores, stageStats.m_player[p].iHoldNoteScores, sizeof(hs.iHoldNoteScores) );
hs.radarValues = stageStats.radarActual[p]; hs.radarValues = stageStats.m_player[p].radarActual;
StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
@@ -947,7 +947,7 @@ void ScreenEvaluation::CommitScores(
case stage: case stage:
{ {
// don't save scores for a failed song // don't save scores for a failed song
if( stageStats.bFailed[p] ) if( stageStats.m_player[p].bFailed )
continue; continue;
ASSERT( pSteps ); ASSERT( pSteps );
@@ -959,7 +959,7 @@ void ScreenEvaluation::CommitScores(
case summary: case summary:
{ {
// don't save scores if any stage was failed // don't save scores if any stage was failed
if( stageStats.bFailed[p] ) if( stageStats.m_player[p].bFailed )
continue; continue;
int iAverageMeter = stageStats.GetAverageMeter(p); int iAverageMeter = stageStats.GetAverageMeter(p);
@@ -1055,23 +1055,23 @@ void ScreenEvaluation::CommitScores(
// don't give per-difficutly awards if using easy mods // don't give per-difficutly awards if using easy mods
if( !GAMESTATE->IsDisqualified(p) ) if( !GAMESTATE->IsDisqualified(p) )
{ {
if( stageStats.FullComboOfScore( p, TNS_GREAT ) ) if( stageStats.m_player[p].FullComboOfScore( TNS_GREAT ) )
vPdas.push_back( AWARD_FULL_COMBO_GREATS ); vPdas.push_back( AWARD_FULL_COMBO_GREATS );
if( stageStats.SingleDigitsOfScore( p, TNS_GREAT ) ) if( stageStats.m_player[p].SingleDigitsOfScore( TNS_GREAT ) )
vPdas.push_back( AWARD_SINGLE_DIGIT_GREATS ); vPdas.push_back( AWARD_SINGLE_DIGIT_GREATS );
if( stageStats.FullComboOfScore( p, TNS_PERFECT ) ) if( stageStats.m_player[p].FullComboOfScore( TNS_PERFECT ) )
vPdas.push_back( AWARD_FULL_COMBO_PERFECTS ); vPdas.push_back( AWARD_FULL_COMBO_PERFECTS );
if( stageStats.SingleDigitsOfScore( p, TNS_PERFECT ) ) if( stageStats.m_player[p].SingleDigitsOfScore( TNS_PERFECT ) )
vPdas.push_back( AWARD_SINGLE_DIGIT_PERFECTS ); vPdas.push_back( AWARD_SINGLE_DIGIT_PERFECTS );
if( stageStats.FullComboOfScore( p, TNS_MARVELOUS ) ) if( stageStats.m_player[p].FullComboOfScore( TNS_MARVELOUS ) )
vPdas.push_back( AWARD_FULL_COMBO_MARVELOUSES ); vPdas.push_back( AWARD_FULL_COMBO_MARVELOUSES );
if( stageStats.OneOfScore( p, TNS_GREAT ) ) if( stageStats.m_player[p].OneOfScore( TNS_GREAT ) )
vPdas.push_back( AWARD_ONE_GREAT ); vPdas.push_back( AWARD_ONE_GREAT );
if( stageStats.OneOfScore( p, TNS_PERFECT ) ) if( stageStats.m_player[p].OneOfScore( TNS_PERFECT ) )
vPdas.push_back( AWARD_ONE_PERFECT ); vPdas.push_back( AWARD_ONE_PERFECT );
float fPercentGreats = stageStats.GetPercentageOfTaps(p, TNS_GREAT); float fPercentGreats = stageStats.m_player[p].GetPercentageOfTaps( TNS_GREAT );
if( fPercentGreats >= 0.8f ) if( fPercentGreats >= 0.8f )
vPdas.push_back( AWARD_GREATS_80_PERCENT ); vPdas.push_back( AWARD_GREATS_80_PERCENT );
if( fPercentGreats >= 0.9f ) if( fPercentGreats >= 0.9f )
@@ -1091,8 +1091,8 @@ void ScreenEvaluation::CommitScores(
LOG->Trace( "done with per difficulty awards" ); LOG->Trace( "done with per difficulty awards" );
// DO give peak combo awards if using easy mods // DO give peak combo awards if using easy mods
int iComboAtStartOfStage = stageStats.GetComboAtStartOfStage( p ); int iComboAtStartOfStage = stageStats.m_player[p].GetComboAtStartOfStage();
int iPeakCombo = stageStats.GetMaxCombo(p).cnt; int iPeakCombo = stageStats.m_player[p].GetMaxCombo().cnt;
FOREACH_PeakComboAward( pca ) FOREACH_PeakComboAward( pca )
{ {
@@ -1307,7 +1307,7 @@ void ScreenEvaluation::Update( float fDeltaTime )
FOREACH_EnabledPlayer( p ) FOREACH_EnabledPlayer( p )
{ {
if( g_CurStageStats.iBonus[p] == 0 ) if( g_CurStageStats.m_player[p].iBonus == 0 )
continue; continue;
if( GAMESTATE->IsCourseMode() ) if( GAMESTATE->IsCourseMode() )
@@ -1317,16 +1317,16 @@ void ScreenEvaluation::Update( float fDeltaTime )
if( RageTimer::GetTimeSinceStart() - m_fScreenCreateTime < 1.5f ) if( RageTimer::GetTimeSinceStart() - m_fScreenCreateTime < 1.5f )
continue; continue;
int increment = g_CurStageStats.iBonus[p]/10; int increment = g_CurStageStats.m_player[p].iBonus/10;
/* XXX: What's this supposed to do? If i < 1, then min(i, 1024) is i ... */ /* XXX: What's this supposed to do? If i < 1, then min(i, 1024) is i ... */
if( increment < 1 ) if( increment < 1 )
increment = min( 1024, g_CurStageStats.iBonus[p] ); increment = min( 1024, g_CurStageStats.m_player[p].iBonus );
g_CurStageStats.iBonus[p] -= increment; g_CurStageStats.m_player[p].iBonus -= increment;
g_CurStageStats.iScore[p] += increment; g_CurStageStats.m_player[p].iScore += increment;
if( SHOW_SCORE_AREA ) if( SHOW_SCORE_AREA )
m_textScore[p].SetText( ssprintf("%*.0i", NUM_SCORE_DIGITS, g_CurStageStats.iScore[p]) ); m_textScore[p].SetText( ssprintf("%*.0i", NUM_SCORE_DIGITS, g_CurStageStats.m_player[p].iScore) );
} }
} }
+16 -16
View File
@@ -140,24 +140,24 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
for( int z = 0; z < 3; ++z ) for( int z = 0; z < 3; ++z )
{ {
ss.vpSongs.push_back( SONGMAN->GetRandomSong() ); ss.vpSongs.push_back( SONGMAN->GetRandomSong() );
ss.iPossibleDancePoints[PLAYER_1] = 100; ss.m_player[PLAYER_1].iPossibleDancePoints = 100;
ss.iActualDancePoints[PLAYER_1] = 100; ss.m_player[PLAYER_1].iActualDancePoints = 100;
ss.iScore[PLAYER_1] = 100; ss.m_player[PLAYER_1].iScore = 100;
ss.iPossibleDancePoints[PLAYER_2] = 100; ss.m_player[PLAYER_2].iPossibleDancePoints = 100;
ss.iActualDancePoints[PLAYER_2] = 100; ss.m_player[PLAYER_2].iActualDancePoints = 100;
ss.iScore[PLAYER_2] = 100; ss.m_player[PLAYER_2].iScore = 100;
ASSERT( ss.vpSongs[0]->GetAllSteps().size() ); ASSERT( ss.vpSongs[0]->GetAllSteps().size() );
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
{ {
ss.vpSteps[p].push_back( ss.vpSongs[0]->GetAllSteps()[0] ); ss.m_player[p].vpSteps.push_back( ss.vpSongs[0]->GetAllSteps()[0] );
GAMESTATE->m_pCurSteps[p] = ss.vpSteps[p][0]; GAMESTATE->m_pCurSteps[p] = ss.m_player[p].vpSteps[0];
ss.iPossibleDancePoints[p] = 1000; ss.m_player[p].iPossibleDancePoints = 1000;
ss.iActualDancePoints[p] = 985; ss.m_player[p].iActualDancePoints = 985;
HighScore hs; HighScore hs;
hs.grade = GRADE_TIER_3; hs.grade = GRADE_TIER_3;
hs.fPercentDP = ss.GetPercentDancePoints(p); hs.fPercentDP = ss.m_player[p].GetPercentDancePoints();
hs.iScore = ss.iScore[p]; hs.iScore = ss.m_player[p].iScore;
StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
int a, b; int 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 );
@@ -311,14 +311,14 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S
{ {
StageStats &ss = g_vPlayedStageStats[i]; StageStats &ss = g_vPlayedStageStats[i];
Song* pSong = ss.vpSongs[0]; Song* pSong = ss.vpSongs[0];
Steps* pSteps = ss.vpSteps[p][0]; Steps* pSteps = ss.m_player[p].vpSteps[0];
Course* pCourse = GAMESTATE->m_pCurCourse; Course* pCourse = GAMESTATE->m_pCurCourse;
Trail* pTrail = GAMESTATE->m_pCurTrail[p]; Trail* pTrail = GAMESTATE->m_pCurTrail[p];
int iHighScoreIndex = -1; // -1 means "out of ranking" int iHighScoreIndex = -1; // -1 means "out of ranking"
Grade grade = ss.GetGrade( p ); Grade grade = ss.m_player[p].GetGrade();
int iScore = ss.iScore[p]; int iScore = ss.m_player[p].iScore;
float fPercentDP = ss.GetPercentDancePoints( p ); float fPercentDP = ss.m_player[p].GetPercentDancePoints();
// If this is a SHOW_NEVER song, then it's probably a training. // If this is a SHOW_NEVER song, then it's probably a training.
// Don't show a high score // Don't show a high score
+2 -2
View File
@@ -804,11 +804,11 @@ void SongManager::RevertFromDisk( Song *pSong, bool bAllowNotesLoss )
{ {
CONVERT_STEPS_POINTER( GAMESTATE->m_pCurSteps[p] ); CONVERT_STEPS_POINTER( GAMESTATE->m_pCurSteps[p] );
FOREACH( Steps*, g_CurStageStats.vpSteps[p], pSteps ) FOREACH( Steps*, g_CurStageStats.m_player[p].vpSteps, pSteps )
CONVERT_STEPS_POINTER( *pSteps ); CONVERT_STEPS_POINTER( *pSteps );
FOREACH( StageStats, g_vPlayedStageStats, ss ) FOREACH( StageStats, g_vPlayedStageStats, ss )
FOREACH( Steps*, ss->vpSteps[p], pSteps ) FOREACH( Steps*, ss->m_player[p].vpSteps, pSteps )
CONVERT_STEPS_POINTER( *pSteps ); CONVERT_STEPS_POINTER( *pSteps );
} }
} }
+192 -190
View File
@@ -12,130 +12,78 @@
StageStats g_CurStageStats; StageStats g_CurStageStats;
vector<StageStats> g_vPlayedStageStats; vector<StageStats> g_vPlayedStageStats;
void StageStats::Init() void PlayerStageStats::Init()
{ {
playMode = PLAY_MODE_INVALID; vpSteps.clear();
pStyle = NULL; fAliveSeconds = 0;
vpSongs.clear(); bFailed = bFailedEarlier = false;
StageType = STAGE_INVALID; iPossibleDancePoints = iActualDancePoints = 0;
fGameplaySeconds = 0; iCurCombo = iMaxCombo = iCurMissCombo = iScore = iBonus = 0;
fSecondsBeforeFail = 0;
iSongsPassed = iSongsPlayed = 0;
iTotalError = 0;
FOREACH_PlayerNumber( p ) ZERO( iTapNoteScores );
{ ZERO( iHoldNoteScores );
vpSteps[p].clear(); radarPossible.Zero();
fAliveSeconds[p] = 0; radarActual.Zero();
bFailed[p] = bFailedEarlier[p] = false;
iPossibleDancePoints[p] = iActualDancePoints[p] = 0;
iCurCombo[p] = iMaxCombo[p] = iCurMissCombo[p] = iScore[p] = iBonus[p] = 0;
fSecondsBeforeFail[p] = 0;
iSongsPassed[p] = iSongsPlayed[p] = 0;
iTotalError[p] = 0;
ZERO( iTapNoteScores[p] ); fFirstSecond = 999999;
ZERO( iHoldNoteScores[p] ); fLastSecond = 0;
radarPossible[p].Zero();
radarActual[p].Zero();
fFirstSecond[p] = 999999;
fLastSecond[p] = 0;
}
} }
void StageStats::AssertValid( PlayerNumber pn ) const void PlayerStageStats::AddStats( const PlayerStageStats& other )
{ {
if( vpSongs[0] ) FOREACH_CONST( Steps*, other.vpSteps, s )
CHECKPOINT_M( vpSongs[0]->GetFullTranslitTitle() ); vpSteps.push_back( *s );
ASSERT( vpSteps[pn][0] ); fAliveSeconds += other.fAliveSeconds;
ASSERT_M( playMode < NUM_PLAY_MODES, ssprintf("playmode %i", playMode) ); bFailed |= other.bFailed;
ASSERT( pStyle != NULL ); bFailedEarlier |= other.bFailedEarlier;
ASSERT_M( vpSteps[pn][0]->GetDifficulty() < NUM_DIFFICULTIES, ssprintf("difficulty %i", vpSteps[pn][0]->GetDifficulty()) ); iPossibleDancePoints += other.iPossibleDancePoints;
ASSERT( vpSongs.size() == vpSteps[pn].size() ); iActualDancePoints += other.iActualDancePoints;
}
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 )
{
ASSERT( !other.vpSongs.empty() );
FOREACH_CONST( Song*, other.vpSongs, s )
vpSongs.push_back( *s );
StageType = STAGE_INVALID; // meaningless
memset( fAliveSeconds, 0, sizeof(fAliveSeconds) ); // why not accumulate? -Chris
fGameplaySeconds += other.fGameplaySeconds;
FOREACH_PlayerNumber( p )
{
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];
iPossibleDancePoints[p] += other.iPossibleDancePoints[p];
iActualDancePoints[p] += other.iActualDancePoints[p];
for( int t=0; t<NUM_TAP_NOTE_SCORES; t++ ) for( int t=0; t<NUM_TAP_NOTE_SCORES; t++ )
iTapNoteScores[p][t] += other.iTapNoteScores[p][t]; iTapNoteScores[t] += other.iTapNoteScores[t];
for( int h=0; h<NUM_HOLD_NOTE_SCORES; h++ ) for( int h=0; h<NUM_HOLD_NOTE_SCORES; h++ )
iHoldNoteScores[p][h] += other.iHoldNoteScores[p][h]; iHoldNoteScores[h] += other.iHoldNoteScores[h];
iCurCombo[p] += other.iCurCombo[p]; iCurCombo += other.iCurCombo;
iMaxCombo[p] += other.iMaxCombo[p]; iMaxCombo += other.iMaxCombo;
iCurMissCombo[p] += other.iCurMissCombo[p]; iCurMissCombo += other.iCurMissCombo;
iScore[p] += other.iScore[p]; iScore += other.iScore;
radarPossible[p] += other.radarPossible[p]; radarPossible += other.radarPossible;
radarActual[p] += other.radarActual[p]; radarActual += other.radarActual;
fSecondsBeforeFail[p] += other.fSecondsBeforeFail[p]; fSecondsBeforeFail += other.fSecondsBeforeFail;
iSongsPassed[p] += other.iSongsPassed[p]; iSongsPassed += other.iSongsPassed;
iSongsPlayed[p] += other.iSongsPlayed[p]; iSongsPlayed += other.iSongsPlayed;
iTotalError[p] += other.iTotalError[p]; iTotalError += other.iTotalError;
const float fOtherFirstSecond = other.fFirstSecond[p] + fLastSecond[p]; const float fOtherFirstSecond = other.fFirstSecond + fLastSecond;
const float fOtherLastSecond = other.fLastSecond[p] + fLastSecond[p]; const float fOtherLastSecond = other.fLastSecond + fLastSecond;
fLastSecond[p] = fOtherLastSecond; fLastSecond = fOtherLastSecond;
map<float,float>::const_iterator it; map<float,float>::const_iterator it;
for( it = other.fLifeRecord[p].begin(); it != other.fLifeRecord[p].end(); ++it ) for( it = other.fLifeRecord.begin(); it != other.fLifeRecord.end(); ++it )
{ {
const float pos = it->first; const float pos = it->first;
const float life = it->second; const float life = it->second;
fLifeRecord[p][fOtherFirstSecond+pos] = life; fLifeRecord[fOtherFirstSecond+pos] = life;
} }
for( unsigned i=0; i<other.ComboList[p].size(); ++i ) for( unsigned i=0; i<other.ComboList.size(); ++i )
{ {
const Combo_t &combo = other.ComboList[p][i]; const Combo_t &combo = other.ComboList[i];
Combo_t newcombo(combo); Combo_t newcombo(combo);
newcombo.fStartSecond += fOtherFirstSecond; newcombo.fStartSecond += fOtherFirstSecond;
ComboList[p].push_back( newcombo ); ComboList.push_back( newcombo );
} }
/* Merge identical combos. This normally only happens in course mode, when a combo /* Merge identical combos. This normally only happens in course mode, when a combo
* continues between songs. */ * continues between songs. */
for( unsigned i=1; i<ComboList[p].size(); ++i ) for( unsigned i=1; i<ComboList.size(); ++i )
{ {
Combo_t &prevcombo = ComboList[p][i-1]; Combo_t &prevcombo = ComboList[i-1];
Combo_t &combo = ComboList[p][i]; Combo_t &combo = ComboList[i];
const float PrevComboEnd = prevcombo.fStartSecond + prevcombo.fSizeSeconds; const float PrevComboEnd = prevcombo.fStartSecond + prevcombo.fSizeSeconds;
const float ThisComboStart = combo.fStartSecond; const float ThisComboStart = combo.fStartSecond;
if( fabsf(PrevComboEnd - ThisComboStart) > 0.001 ) if( fabsf(PrevComboEnd - ThisComboStart) > 0.001 )
@@ -144,17 +92,14 @@ void StageStats::AddStats( const StageStats& other )
/* These are really the same combo. */ /* These are really the same combo. */
prevcombo.fSizeSeconds += combo.fSizeSeconds; prevcombo.fSizeSeconds += combo.fSizeSeconds;
prevcombo.cnt += combo.cnt; prevcombo.cnt += combo.cnt;
ComboList[p].erase( ComboList[p].begin()+i ); ComboList.erase( ComboList.begin()+i );
--i; --i;
} }
} }
}
Grade StageStats::GetGrade( PlayerNumber pn ) const Grade PlayerStageStats::GetGrade() const
{ {
ASSERT( GAMESTATE->IsPlayerEnabled(pn) ); // shouldn't be calling this is player isn't joined! if( bFailedEarlier )
if( bFailedEarlier[pn] )
return GRADE_FAILED; return GRADE_FAILED;
/* XXX: This entire calculation should be in ScoreKeeper, but final evaluation /* XXX: This entire calculation should be in ScoreKeeper, but final evaluation
@@ -177,8 +122,8 @@ Grade StageStats::GetGrade( PlayerNumber pn ) const
case TNS_MARVELOUS: iTapScoreValue = PREFSMAN->m_iGradeWeightMarvelous; break; case TNS_MARVELOUS: iTapScoreValue = PREFSMAN->m_iGradeWeightMarvelous; break;
default: FAIL_M( ssprintf("%i", tns) ); break; default: FAIL_M( ssprintf("%i", tns) ); break;
} }
Actual += iTapNoteScores[pn][tns] * iTapScoreValue; Actual += iTapNoteScores[tns] * iTapScoreValue;
Possible += iTapNoteScores[pn][tns] * PREFSMAN->m_iGradeWeightMarvelous; Possible += iTapNoteScores[tns] * PREFSMAN->m_iGradeWeightMarvelous;
} }
FOREACH_HoldNoteScore( hns ) FOREACH_HoldNoteScore( hns )
@@ -191,8 +136,8 @@ Grade StageStats::GetGrade( PlayerNumber pn ) const
case HNS_OK: iHoldScoreValue = PREFSMAN->m_iGradeWeightOK; break; case HNS_OK: iHoldScoreValue = PREFSMAN->m_iGradeWeightOK; break;
default: FAIL_M( ssprintf("%i", hns) ); break; default: FAIL_M( ssprintf("%i", hns) ); break;
} }
Actual += iHoldNoteScores[pn][hns] * iHoldScoreValue; Actual += iHoldNoteScores[hns] * iHoldScoreValue;
Possible += iHoldNoteScores[pn][hns] * PREFSMAN->m_iGradeWeightOK; Possible += iHoldNoteScores[hns] * PREFSMAN->m_iGradeWeightOK;
} }
LOG->Trace( "GetGrade: Actual: %f, Possible: %f", Actual, Possible ); LOG->Trace( "GetGrade: Actual: %f, Possible: %f", Actual, Possible );
@@ -213,23 +158,23 @@ Grade StageStats::GetGrade( PlayerNumber pn ) const
LOG->Trace( "GetGrade: Grade: %s, %i", GradeToString(grade).c_str(), PREFSMAN->m_bGradeTier02IsAllPerfects ); LOG->Trace( "GetGrade: Grade: %s, %i", GradeToString(grade).c_str(), PREFSMAN->m_bGradeTier02IsAllPerfects );
if( PREFSMAN->m_bGradeTier02IsAllPerfects ) if( PREFSMAN->m_bGradeTier02IsAllPerfects )
{ {
if( iTapNoteScores[pn][TNS_MARVELOUS] > 0 && if( iTapNoteScores[TNS_MARVELOUS] > 0 &&
iTapNoteScores[pn][TNS_PERFECT] == 0 && iTapNoteScores[TNS_PERFECT] == 0 &&
iTapNoteScores[pn][TNS_GREAT] == 0 && iTapNoteScores[TNS_GREAT] == 0 &&
iTapNoteScores[pn][TNS_GOOD] == 0 && iTapNoteScores[TNS_GOOD] == 0 &&
iTapNoteScores[pn][TNS_BOO] == 0 && iTapNoteScores[TNS_BOO] == 0 &&
iTapNoteScores[pn][TNS_MISS] == 0 && iTapNoteScores[TNS_MISS] == 0 &&
iTapNoteScores[pn][TNS_HIT_MINE] == 0 && iTapNoteScores[TNS_HIT_MINE] == 0 &&
iHoldNoteScores[pn][HNS_NG] == 0 ) iHoldNoteScores[HNS_NG] == 0 )
return GRADE_TIER_1; return GRADE_TIER_1;
if( iTapNoteScores[pn][TNS_PERFECT] > 0 && if( iTapNoteScores[TNS_PERFECT] > 0 &&
iTapNoteScores[pn][TNS_GREAT] == 0 && iTapNoteScores[TNS_GREAT] == 0 &&
iTapNoteScores[pn][TNS_GOOD] == 0 && iTapNoteScores[TNS_GOOD] == 0 &&
iTapNoteScores[pn][TNS_BOO] == 0 && iTapNoteScores[TNS_BOO] == 0 &&
iTapNoteScores[pn][TNS_MISS] == 0 && iTapNoteScores[TNS_MISS] == 0 &&
iTapNoteScores[pn][TNS_HIT_MINE] == 0 && iTapNoteScores[TNS_HIT_MINE] == 0 &&
iHoldNoteScores[pn][HNS_NG] == 0 ) iHoldNoteScores[HNS_NG] == 0 )
return GRADE_TIER_2; return GRADE_TIER_2;
return max( grade, GRADE_TIER_3 ); return max( grade, GRADE_TIER_3 );
@@ -238,87 +183,144 @@ Grade StageStats::GetGrade( PlayerNumber pn ) const
return grade; return grade;
} }
void StageStats::Init()
{
playMode = PLAY_MODE_INVALID;
pStyle = NULL;
vpSongs.clear();
StageType = STAGE_INVALID;
fGameplaySeconds = 0;
}
void StageStats::AssertValid( PlayerNumber pn ) const
{
if( vpSongs[0] )
CHECKPOINT_M( vpSongs[0]->GetFullTranslitTitle() );
ASSERT( m_player[pn].vpSteps[0] );
ASSERT_M( playMode < NUM_PLAY_MODES, ssprintf("playmode %i", playMode) );
ASSERT( pStyle != NULL );
ASSERT_M( m_player[pn].vpSteps[0]->GetDifficulty() < NUM_DIFFICULTIES, ssprintf("difficulty %i", m_player[pn].vpSteps[0]->GetDifficulty()) );
ASSERT( vpSongs.size() == m_player[pn].vpSteps.size() );
}
int StageStats::GetAverageMeter( PlayerNumber pn ) const
{
int iTotalMeter = 0;
int iTotalCount = 0;
ASSERT( vpSongs.size() == m_player[pn].vpSteps.size() );
for( unsigned i=0; i<vpSongs.size(); i++ )
{
Song* pSong = vpSongs[i];
Steps* pSteps = m_player[pn].vpSteps[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 )
{
ASSERT( !other.vpSongs.empty() );
FOREACH_CONST( Song*, other.vpSongs, s )
vpSongs.push_back( *s );
StageType = STAGE_INVALID; // meaningless
fGameplaySeconds += other.fGameplaySeconds;
FOREACH_PlayerNumber( p )
{
m_player[p].AddStats( other.m_player[p] );
}
}
bool StageStats::OnePassed() const bool StageStats::OnePassed() const
{ {
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
if( GAMESTATE->IsHumanPlayer(p) && !bFailed[p] ) if( GAMESTATE->IsHumanPlayer(p) && !m_player[p].bFailed )
return true; return true;
return false; return false;
} }
bool StageStats::AllFailed() const bool StageStats::AllFailed() const
{ {
FOREACH_PlayerNumber( pn ) FOREACH_EnabledPlayer( pn )
if( GAMESTATE->IsPlayerEnabled(pn) ) if( !m_player[pn].bFailed )
if( !bFailed[pn] )
return false; return false;
return true; return true;
} }
bool StageStats::AllFailedEarlier() const bool StageStats::AllFailedEarlier() const
{ {
FOREACH_PlayerNumber( p ) FOREACH_EnabledPlayer( p )
if( GAMESTATE->IsPlayerEnabled(p) && !bFailedEarlier[p] ) if( !m_player[p].bFailedEarlier )
return false; return false;
return true; return true;
} }
float StageStats::GetPercentDancePoints( PlayerNumber pn ) const float PlayerStageStats::GetPercentDancePoints() const
{ {
if( iPossibleDancePoints[pn] == 0 ) if( iPossibleDancePoints == 0 )
return 0; // div/0 return 0; // div/0
if( iActualDancePoints[pn] == iPossibleDancePoints[pn] ) if( iActualDancePoints == iPossibleDancePoints )
return 1; // correct for rounding error return 1; // correct for rounding error
/* This can happen in battle, with transform attacks. */ /* This can happen in battle, with transform attacks. */
//ASSERT_M( iActualDancePoints[pn] <= iPossibleDancePoints[pn], ssprintf("%i/%i", iActualDancePoints[pn], iPossibleDancePoints[pn]) ); //ASSERT_M( iActualDancePoints <= iPossibleDancePoints, ssprintf("%i/%i", iActualDancePoints, iPossibleDancePoints) );
float fPercentDancePoints = iActualDancePoints[pn] / (float)iPossibleDancePoints[pn]; float fPercentDancePoints = iActualDancePoints / (float)iPossibleDancePoints;
return fPercentDancePoints; return fPercentDancePoints;
} }
void StageStats::SetLifeRecordAt( PlayerNumber pn, float fLife, float fSecond ) void PlayerStageStats::SetLifeRecordAt( float fLife, float fSecond )
{ {
if( fSecond < 0 ) if( fSecond < 0 )
return; return;
fFirstSecond[pn] = min( fSecond, fFirstSecond[pn] ); fFirstSecond = min( fSecond, fFirstSecond );
fLastSecond[pn] = max( fSecond, fLastSecond[pn] ); fLastSecond = max( fSecond, fLastSecond );
//LOG->Trace( "fLastSecond = %f", fLastSecond[pn] ); //LOG->Trace( "fLastSecond = %f", fLastSecond );
if( !fLifeRecord[pn].empty() ) if( !fLifeRecord.empty() )
{ {
const float old = GetLifeRecordAt( pn, fSecond ); const float old = GetLifeRecordAt( fSecond );
if( fabsf(old-fSecond) < 0.001f ) if( fabsf(old-fSecond) < 0.001f )
return; /* no change */ return; /* no change */
} }
fLifeRecord[pn][fSecond] = fLife; fLifeRecord[fSecond] = fLife;
} }
float StageStats::GetLifeRecordAt( PlayerNumber pn, float fSecond ) const float PlayerStageStats::GetLifeRecordAt( float fSecond ) const
{ {
/* Find the first element whose key is not less than k. */ /* Find the first element whose key is not less than k. */
map<float,float>::const_iterator it = fLifeRecord[pn].lower_bound( fSecond ); map<float,float>::const_iterator it = fLifeRecord.lower_bound( fSecond );
/* Find the first element whose key is less than k. */ /* Find the first element whose key is less than k. */
if( it != fLifeRecord[pn].begin() ) if( it != fLifeRecord.begin() )
--it; --it;
return it->second; return it->second;
} }
float StageStats::GetLifeRecordLerpAt( PlayerNumber pn, float fSecond ) const float PlayerStageStats::GetLifeRecordLerpAt( float fSecond ) const
{ {
/* Find the first element whose key is not less than k. */ /* Find the first element whose key is not less than k. */
map<float,float>::const_iterator later = fLifeRecord[pn].lower_bound( fSecond ); map<float,float>::const_iterator later = fLifeRecord.lower_bound( fSecond );
/* Find the first element whose key is less than k. */ /* Find the first element whose key is less than k. */
map<float,float>::const_iterator earlier = later; map<float,float>::const_iterator earlier = later;
if( earlier != fLifeRecord[pn].begin() ) if( earlier != fLifeRecord.begin() )
--earlier; --earlier;
if( earlier->first == later->first ) if( earlier->first == later->first )
@@ -330,39 +332,39 @@ float StageStats::GetLifeRecordLerpAt( PlayerNumber pn, float fSecond ) const
} }
void StageStats::GetLifeRecord( PlayerNumber pn, float *fLifeOut, int iNumSamples ) const void PlayerStageStats::GetLifeRecord( float *fLifeOut, int iNumSamples ) const
{ {
for( int i = 0; i < iNumSamples; ++i ) for( int i = 0; i < iNumSamples; ++i )
{ {
float from = SCALE( i, 0, (float)iNumSamples, fFirstSecond[pn], fLastSecond[pn] ); float from = SCALE( i, 0, (float)iNumSamples, fFirstSecond, fLastSecond );
fLifeOut[i] = GetLifeRecordLerpAt( pn, from ); fLifeOut[i] = GetLifeRecordLerpAt( from );
} }
} }
/* If "rollover" is true, we're being called before gameplay begins, so we can record /* If "rollover" is true, we're being called before gameplay begins, so we can record
* the amount of the first combo that comes from the previous song. */ * the amount of the first combo that comes from the previous song. */
void StageStats::UpdateComboList( PlayerNumber pn, float fSecond, bool rollover ) void PlayerStageStats::UpdateComboList( float fSecond, bool rollover )
{ {
if( fSecond < 0 ) if( fSecond < 0 )
return; return;
if( !rollover ) if( !rollover )
{ {
fFirstSecond[pn] = min( fSecond, fFirstSecond[pn] ); fFirstSecond = min( fSecond, fFirstSecond );
fLastSecond[pn] = max( fSecond, fLastSecond[pn] ); fLastSecond = max( fSecond, fLastSecond );
//LOG->Trace( "fLastSecond = %f", fLastSecond[pn] ); //LOG->Trace( "fLastSecond = %f", fLastSecond );
} }
int cnt = iCurCombo[pn]; int cnt = iCurCombo;
if( !cnt ) if( !cnt )
return; /* no combo */ return; /* no combo */
if( ComboList[pn].size() == 0 || ComboList[pn].back().cnt >= cnt ) if( ComboList.size() == 0 || ComboList.back().cnt >= cnt )
{ {
/* If the previous combo (if any) starts on -9999, then we rolled over some /* If the previous combo (if any) starts on -9999, then we rolled over some
* combo, but missed the first step. Remove it. */ * combo, but missed the first step. Remove it. */
if( ComboList[pn].size() && ComboList[pn].back().fStartSecond == -9999 ) if( ComboList.size() && ComboList.back().fStartSecond == -9999 )
ComboList[pn].erase( ComboList[pn].begin()+ComboList[pn].size()-1, ComboList[pn].end() ); ComboList.erase( ComboList.begin()+ComboList.size()-1, ComboList.end() );
/* This is a new combo. */ /* This is a new combo. */
Combo_t NewCombo; Combo_t NewCombo;
@@ -374,10 +376,10 @@ void StageStats::UpdateComboList( PlayerNumber pn, float fSecond, bool rollover
NewCombo.fStartSecond = -9999; NewCombo.fStartSecond = -9999;
else else
NewCombo.fStartSecond = fSecond; NewCombo.fStartSecond = fSecond;
ComboList[pn].push_back( NewCombo ); ComboList.push_back( NewCombo );
} }
Combo_t &combo = ComboList[pn].back(); Combo_t &combo = ComboList.back();
combo.fSizeSeconds = fSecond - combo.fStartSecond; combo.fSizeSeconds = fSecond - combo.fStartSecond;
combo.cnt = cnt; combo.cnt = cnt;
if( !rollover && combo.fStartSecond == -9999 ) if( !rollover && combo.fStartSecond == -9999 )
@@ -389,82 +391,82 @@ void StageStats::UpdateComboList( PlayerNumber pn, float fSecond, bool rollover
/* This returns the largest combo contained within the song, as if /* This returns the largest combo contained within the song, as if
* m_bComboContinuesBetweenSongs is turned off. */ * m_bComboContinuesBetweenSongs is turned off. */
StageStats::Combo_t StageStats::GetMaxCombo( PlayerNumber pn ) const PlayerStageStats::Combo_t PlayerStageStats::GetMaxCombo() const
{ {
if( ComboList[pn].size() == 0 ) if( ComboList.size() == 0 )
return Combo_t(); return Combo_t();
int m = 0; int m = 0;
for( unsigned i = 1; i < ComboList[pn].size(); ++i ) for( unsigned i = 1; i < ComboList.size(); ++i )
{ {
if( ComboList[pn][i].cnt > ComboList[pn][m].cnt ) if( ComboList[i].cnt > ComboList[m].cnt )
m = i; m = i;
} }
return ComboList[pn][m]; return ComboList[m];
} }
int StageStats::GetComboAtStartOfStage( PlayerNumber pn ) const int PlayerStageStats::GetComboAtStartOfStage() const
{ {
if( ComboList[pn].empty() ) if( ComboList.empty() )
return 0; return 0;
else else
return ComboList[pn][0].rollover; return ComboList[0].rollover;
} }
bool StageStats::FullComboOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const bool PlayerStageStats::FullComboOfScore( TapNoteScore tnsAllGreaterOrEqual ) const
{ {
ASSERT( tnsAllGreaterOrEqual >= TNS_GREAT ); ASSERT( tnsAllGreaterOrEqual >= TNS_GREAT );
ASSERT( tnsAllGreaterOrEqual <= TNS_MARVELOUS ); ASSERT( tnsAllGreaterOrEqual <= TNS_MARVELOUS );
if( iHoldNoteScores[pn][HNS_NG] > 0 ) if( iHoldNoteScores[HNS_NG] > 0 )
return false; return false;
for( int i=TNS_MISS; i<tnsAllGreaterOrEqual; i++ ) for( int i=TNS_MISS; i<tnsAllGreaterOrEqual; i++ )
{ {
if( iTapNoteScores[pn][i] > 0 ) if( iTapNoteScores[i] > 0 )
return false; return false;
} }
return true; return true;
} }
bool StageStats::SingleDigitsOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const bool PlayerStageStats::SingleDigitsOfScore( TapNoteScore tnsAllGreaterOrEqual ) const
{ {
return FullComboOfScore( pn, tnsAllGreaterOrEqual ) && return FullComboOfScore( tnsAllGreaterOrEqual ) &&
iTapNoteScores[pn][tnsAllGreaterOrEqual] < 10; iTapNoteScores[tnsAllGreaterOrEqual] < 10;
} }
bool StageStats::OneOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const bool PlayerStageStats::OneOfScore( TapNoteScore tnsAllGreaterOrEqual ) const
{ {
return FullComboOfScore( pn, tnsAllGreaterOrEqual ) && return FullComboOfScore( tnsAllGreaterOrEqual ) &&
iTapNoteScores[pn][tnsAllGreaterOrEqual] == 1; iTapNoteScores[tnsAllGreaterOrEqual] == 1;
} }
int StageStats::GetTotalTaps( PlayerNumber pn ) const int PlayerStageStats::GetTotalTaps() const
{ {
int iTotalTaps = 0; int iTotalTaps = 0;
for( int i=TNS_MISS; i<NUM_TAP_NOTE_SCORES; i++ ) for( int i=TNS_MISS; i<NUM_TAP_NOTE_SCORES; i++ )
{ {
iTotalTaps += iTapNoteScores[pn][i]; iTotalTaps += iTapNoteScores[i];
} }
return iTotalTaps; return iTotalTaps;
} }
float StageStats::GetPercentageOfTaps( PlayerNumber pn, TapNoteScore tns ) const float PlayerStageStats::GetPercentageOfTaps( TapNoteScore tns ) const
{ {
int iTotalTaps = 0; int iTotalTaps = 0;
for( int i=TNS_MISS; i<NUM_TAP_NOTE_SCORES; i++ ) for( int i=TNS_MISS; i<NUM_TAP_NOTE_SCORES; i++ )
{ {
iTotalTaps += iTapNoteScores[pn][i]; iTotalTaps += iTapNoteScores[i];
} }
return iTapNoteScores[pn][tns] / (float)iTotalTaps; return iTapNoteScores[tns] / (float)iTotalTaps;
} }
static Grade GetBestGrade() static Grade GetBestGrade()
{ {
Grade g = NUM_GRADES; Grade g = NUM_GRADES;
FOREACH_EnabledPlayer( pn ) FOREACH_EnabledPlayer( pn )
g = min( g, g_CurStageStats.GetGrade( pn ) ); g = min( g, g_CurStageStats.m_player[pn].GetGrade() );
return g; return g;
} }
@@ -472,7 +474,7 @@ static Grade GetWorstGrade()
{ {
Grade g = GRADE_TIER_1; Grade g = GRADE_TIER_1;
FOREACH_EnabledPlayer( pn ) FOREACH_EnabledPlayer( pn )
g = max( g, g_CurStageStats.GetGrade( pn ) ); g = max( g, g_CurStageStats.m_player[pn].GetGrade() );
return g; return g;
} }
@@ -481,9 +483,9 @@ LuaFunction_NoArgs( GetStagesPlayed, (int) g_vPlayedStageStats.size() );
LuaFunction_NoArgs( GetBestGrade, GetBestGrade() ); LuaFunction_NoArgs( GetBestGrade, GetBestGrade() );
LuaFunction_NoArgs( GetWorstGrade, GetWorstGrade() ); LuaFunction_NoArgs( GetWorstGrade, GetWorstGrade() );
LuaFunction_NoArgs( OnePassed, g_CurStageStats.OnePassed() ); LuaFunction_NoArgs( OnePassed, g_CurStageStats.OnePassed() );
LuaFunction_PlayerNumber( FullCombo, g_CurStageStats.FullCombo(pn) ) LuaFunction_PlayerNumber( FullCombo, g_CurStageStats.m_player[pn].FullCombo() )
LuaFunction_PlayerNumber( MaxCombo, g_CurStageStats.GetMaxCombo(pn).cnt ) LuaFunction_PlayerNumber( MaxCombo, g_CurStageStats.m_player[pn].GetMaxCombo().cnt )
LuaFunction_PlayerNumber( GetGrade, g_CurStageStats.GetGrade(pn) ) LuaFunction_PlayerNumber( GetGrade, g_CurStageStats.m_player[pn].GetGrade() )
LuaFunction_Str( Grade, StringToGrade(str) ); LuaFunction_Str( Grade, StringToGrade(str) );
const StageStats *GetStageStatsN( int n ) const StageStats *GetStageStatsN( int n )
@@ -503,7 +505,7 @@ Grade GetGrade( int n, PlayerNumber pn )
const StageStats *pStats = GetStageStatsN( n ); const StageStats *pStats = GetStageStatsN( n );
if( pStats == NULL ) if( pStats == NULL )
return GRADE_NO_DATA; return GRADE_NO_DATA;
return pStats->GetGrade( pn ); return pStats->m_player[pn].GetGrade();
} }
bool OneGotGrade( int n, Grade g ) bool OneGotGrade( int n, Grade g )
@@ -524,7 +526,7 @@ Grade GetFinalGrade( PlayerNumber pn )
return GRADE_NO_DATA; return GRADE_NO_DATA;
StageStats stats; StageStats stats;
GAMESTATE->GetFinalEvalStats( stats ); GAMESTATE->GetFinalEvalStats( stats );
return stats.GetGrade( pn ); return stats.m_player[pn].GetGrade();
} }
LuaFunction_PlayerNumber( GetFinalGrade, GetFinalGrade(pn) ); LuaFunction_PlayerNumber( GetFinalGrade, GetFinalGrade(pn) );
@@ -535,7 +537,7 @@ Grade GetBestFinalGrade()
GAMESTATE->GetFinalEvalStats( stats ); GAMESTATE->GetFinalEvalStats( stats );
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
if( GAMESTATE->IsHumanPlayer(p) ) if( GAMESTATE->IsHumanPlayer(p) )
top_grade = min( top_grade, stats.GetGrade(p) ); top_grade = min( top_grade, stats.m_player[p].GetGrade() );
return top_grade; return top_grade;
} }
LuaFunction_NoArgs( GetBestFinalGrade, GetBestFinalGrade() ); LuaFunction_NoArgs( GetBestFinalGrade, GetBestFinalGrade() );
+65 -51
View File
@@ -12,59 +12,48 @@ class Song;
class Steps; class Steps;
class Style; class Style;
struct StageStats struct PlayerStageStats
{ {
StageStats() { Init(); } PlayerStageStats() { Init(); }
void Init(); void Init();
void AssertValid( PlayerNumber pn ) const; void AddStats( const PlayerStageStats& other ); // accumulate
void AddStats( const StageStats& other ); // accumulate Grade GetGrade() const;
Grade GetGrade( PlayerNumber pn ) const; float GetPercentDancePoints() const;
bool OnePassed() const; vector<Steps*> vpSteps;
bool AllFailed() const; float fAliveSeconds; // how far into the music did they last before failing? Updated by Gameplay, scaled by music rate.
bool AllFailedEarlier() const;
float GetPercentDancePoints( PlayerNumber pn ) const;
PlayMode playMode;
const Style* pStyle;
vector<Song*> vpSongs;
enum { STAGE_INVALID, STAGE_NORMAL, STAGE_EXTRA, STAGE_EXTRA2 } StageType;
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.
/* Set if the player actually failed at any point during the song. This is always /* Set if the player actually failed at any point during the song. This is always
* false in FAIL_OFF. If recovery is enabled and two players are playing, * false in FAIL_OFF. If recovery is enabled and two players are playing,
* this is only set if both players were failing at the same time. */ * this is only set if both players were failing at the same time. */
bool bFailed[NUM_PLAYERS]; bool bFailed;
/* This indicates whether the player bottomed out his bar/ran out of lives at some /* This indicates whether the player bottomed out his bar/ran out of lives at some
* point during the song. It's set in all fail modes. */ * point during the song. It's set in all fail modes. */
bool bFailedEarlier[NUM_PLAYERS]; bool bFailedEarlier;
int iPossibleDancePoints[NUM_PLAYERS]; int iPossibleDancePoints;
int iActualDancePoints[NUM_PLAYERS]; int iActualDancePoints;
int iTapNoteScores[NUM_PLAYERS][NUM_TAP_NOTE_SCORES]; int iTapNoteScores[NUM_TAP_NOTE_SCORES];
int iHoldNoteScores[NUM_PLAYERS][NUM_HOLD_NOTE_SCORES]; int iHoldNoteScores[NUM_HOLD_NOTE_SCORES];
int iCurCombo[NUM_PLAYERS]; int iCurCombo;
int iMaxCombo[NUM_PLAYERS]; int iMaxCombo;
int iCurMissCombo[NUM_PLAYERS]; int iCurMissCombo;
int iScore[NUM_PLAYERS]; int iScore;
int iBonus[NUM_PLAYERS]; // bonus to be added on screeneval int iBonus; // bonus to be added on screeneval
RadarValues radarPossible[NUM_PLAYERS]; // filled in by ScreenGameplay on start of notes RadarValues radarPossible; // filled in by ScreenGameplay on start of notes
RadarValues radarActual[NUM_PLAYERS]; RadarValues radarActual;
float fSecondsBeforeFail[NUM_PLAYERS]; // -1 means didn't/hasn't failed float fSecondsBeforeFail; // -1 means didn't/hasn't failed
/* The number of songs played and passed, respectively. */ /* The number of songs played and passed, respectively. */
int iSongsPassed[NUM_PLAYERS]; int iSongsPassed;
int iSongsPlayed[NUM_PLAYERS]; int iSongsPlayed;
int iTotalError[NUM_PLAYERS]; int iTotalError;
map<float,float> fLifeRecord[NUM_PLAYERS]; map<float,float> fLifeRecord;
void SetLifeRecordAt( PlayerNumber pn, float fLife, float fSecond ); void SetLifeRecordAt( float fLife, float fSecond );
void GetLifeRecord( PlayerNumber pn, float *fLifeOut, int iNumSamples ) const; void GetLifeRecord( float *fLifeOut, int iNumSamples ) const;
float GetLifeRecordAt( PlayerNumber pn, float fSecond ) const; float GetLifeRecordAt( float fSecond ) const;
float GetLifeRecordLerpAt( PlayerNumber pn, float fSecond ) const; float GetLifeRecordLerpAt( float fSecond ) const;
struct Combo_t struct Combo_t
{ {
@@ -85,18 +74,43 @@ struct StageStats
Combo_t(): fStartSecond(0), fSizeSeconds(0), cnt(0), rollover(0) { } Combo_t(): fStartSecond(0), fSizeSeconds(0), cnt(0), rollover(0) { }
bool IsZero() const { return fStartSecond < 0; } bool IsZero() const { return fStartSecond < 0; }
}; };
vector<Combo_t> ComboList[NUM_PLAYERS]; vector<Combo_t> ComboList;
float fFirstSecond[NUM_PLAYERS], fLastSecond[NUM_PLAYERS]; float fFirstSecond;
float fLastSecond;
int GetComboAtStartOfStage( PlayerNumber pn ) const; int GetComboAtStartOfStage() const;
bool FullComboOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const; bool FullComboOfScore( TapNoteScore tnsAllGreaterOrEqual ) const;
bool FullCombo( PlayerNumber pn ) const { return FullComboOfScore(pn,TNS_GREAT); } bool FullCombo() const { return FullComboOfScore(TNS_GREAT); }
bool SingleDigitsOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const; bool SingleDigitsOfScore( TapNoteScore tnsAllGreaterOrEqual ) const;
bool OneOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const; bool OneOfScore( TapNoteScore tnsAllGreaterOrEqual ) const;
int GetTotalTaps( PlayerNumber pn ) const; int GetTotalTaps() const;
float GetPercentageOfTaps( PlayerNumber pn, TapNoteScore tns ) const; float GetPercentageOfTaps( TapNoteScore tns ) const;
void UpdateComboList( PlayerNumber pn, float fSecond, bool rollover ); void UpdateComboList( float fSecond, bool rollover );
Combo_t GetMaxCombo( PlayerNumber pn ) const; Combo_t GetMaxCombo() const;
};
struct StageStats
{
StageStats() { Init(); }
void Init();
void AssertValid( PlayerNumber pn ) const;
void AddStats( const StageStats& other ); // accumulate
bool OnePassed() const;
bool AllFailed() const;
bool AllFailedEarlier() const;
int GetAverageMeter( PlayerNumber pn ) const;
PlayMode playMode;
const Style* pStyle;
vector<Song*> vpSongs;
enum { STAGE_INVALID, STAGE_NORMAL, STAGE_EXTRA, STAGE_EXTRA2 } StageType;
float fGameplaySeconds; // how many seconds before gameplay ended. Updated by Gameplay, not scaled by music rate.
PlayerStageStats m_player[NUM_PLAYERS];
}; };
/* /*