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( g_CurStageStats.FullComboOfScore(m_PlayerNumber,TNS_MARVELOUS) )
if( g_CurStageStats.m_player[m_PlayerNumber].FullComboOfScore(TNS_MARVELOUS) )
{
sprLabel.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 );
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 );
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. */
int MaxComboSize = 0;
for( unsigned i = 0; i < s.ComboList[pn].size(); ++i )
MaxComboSize = max( MaxComboSize, s.ComboList[pn][i].GetStageCnt() );
for( unsigned i = 0; i < s.m_player[pn].ComboList.size(); ++i )
MaxComboSize = max( MaxComboSize, s.m_player[pn].ComboList[i].GetStageCnt() );
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 )
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" );
sprite->Load( THEME->GetPathToG(path) );
const float start = SCALE( combo.fStartSecond, s.fFirstSecond[pn], s.fLastSecond[pn], 0.0f, 1.0f );
const float size = SCALE( combo.fSizeSeconds, 0, s.fLastSecond[pn]-s.fFirstSecond[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.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->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 );
}
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 )
continue; /* too small */
@@ -65,8 +65,8 @@ void ComboGraph::Load( CString Path, const StageStats &s, PlayerNumber pn )
text->SetName( "ComboMaxNumber" );
text->LoadFromFont( THEME->GetPathToF(Path) );
const float start = SCALE( combo.fStartSecond, s.fFirstSecond[pn], s.fLastSecond[pn], 0.0f, 1.0f );
const float size = SCALE( combo.fSizeSeconds, 0, s.fLastSecond[pn]-s.fFirstSecond[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.m_player[pn].fLastSecond-s.m_player[pn].fFirstSecond, 0.0f, 1.0f );
const float CenterPercent = start + size/2;
const float CenterXPos = SCALE( CenterPercent, 0.0f, 1.0f, -width/2.0f, width/2.0f );
+15 -13
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 "ConditionalBGA.h"
#include <ctime>
#include "GameState.h"
#include "GameManager.h"
#include "song.h"
#include "GameConstantsAndTypes.h"
#include "RageLog.h"
#include "BGAnimation.h"
#include "ConditionalBGA.h"
#include "ThemeManager.h"
#include "RageUtil.h"
#include "RageFile.h"
@@ -501,7 +502,7 @@ void ConditionalBGA::CheckBgaRequirements(BgaCondInfo info)
bool foundaplayerwithgrade = false;
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");
foundaplayerwithgrade = true;
@@ -524,16 +525,13 @@ void ConditionalBGA::CheckBgaRequirements(BgaCondInfo info)
{
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");
foundavalidgradeforstage = true;
}
LOG->Info("One Valid Grade");
foundavalidgradeforstage = true;
}
}
}
@@ -610,20 +608,24 @@ void ConditionalBGA::CheckBgaRequirements(BgaCondInfo info)
else if(info.cleared == CBGA_CSMAXCOMBO)
{
FOREACH_EnabledPlayer( pn )
if(g_CurStageStats.FullCombo((PlayerNumber)pn))
{
if(g_CurStageStats.m_player[pn].FullCombo())
{
foundclearcond = true;
LOG->Info("MaxCombo Condition");
}
}
}
else if(info.cleared == CBGA_CSBROKECOMBO)
{
FOREACH_EnabledPlayer( pn )
if(!g_CurStageStats.FullCombo((PlayerNumber)pn))
{
if(!g_CurStageStats.m_player[pn].FullCombo())
{
LOG->Info("BrokenCombo Condition");
foundclearcond = true;
}
}
}
valid = foundclearcond;
+2 -1
View File
@@ -4,7 +4,8 @@
#include "PlayerOptions.h"
#include "GameConstantsAndTypes.h"
#include "BGAnimation.h"
//#include "Style.h"
class Style;
enum CBGACLEAREDSTATES
{
+1 -1
View File
@@ -342,7 +342,7 @@ void DancingCharacters::DrawPrimitives()
continue;
}
bool bFailed = g_CurStageStats.bFailed[p];
bool bFailed = g_CurStageStats.m_player[p].bFailed;
bool bDanger = m_bDrawDangerLight;
DISPLAY->SetLighting( true );
+31 -44
View File
@@ -156,7 +156,7 @@ void GameState::Reset()
m_pPosition = new NoteFieldPositioning("Positioning.ini");
FOREACH_PlayerNumber( p )
m_pPlayerState[p]->m_bAttackBeganThisUpdate = false;
m_pPlayerState[p]->Reset();
ResetMusicStatistics();
ResetStageStatistics();
@@ -170,12 +170,6 @@ void GameState::Reset()
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();
FOREACH_PlayerNumber(p)
@@ -200,13 +194,6 @@ void GameState::Reset()
ASSERT( m_pCurCharacters[p] );
}
FOREACH_PlayerNumber(p)
{
m_pPlayerState[p]->m_fSuperMeterGrowthScale = 1;
m_pPlayerState[p]->m_iCpuSkill = 5;
}
LIGHTSMAN->SetLightsMode( LIGHTSMODE_ATTRACT );
ApplyCmdline();
@@ -301,10 +288,10 @@ void AddPlayerStatsToProfile( Profile *pProfile, const StageStats &ss, PlayerNum
StyleID sID;
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++ )
{
Steps *pSteps = ss.vpSteps[pn][i];
Steps *pSteps = ss.m_player[pn].vpSteps[i];
pProfile->m_iNumSongsPlayedByPlayMode[ss.playMode]++;
pProfile->m_iNumSongsPlayedByStyle[sID] ++;
@@ -312,11 +299,11 @@ void AddPlayerStatsToProfile( Profile *pProfile, const StageStats &ss, PlayerNum
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.bFailed[pn] )
if( ss.m_player[pn].bFailed )
++pProfile->m_iNumExtraStagesFailed;
else
++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.
// 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_iNumStagesPassedByGrade[ss.GetGrade(pn)] ++;
pProfile->m_iNumStagesPassedByGrade[ss.m_player[pn].GetGrade()] ++;
}
}
@@ -524,14 +511,17 @@ void GameState::ResetStageStatistics()
{
FOREACH_PlayerNumber( p )
{
Profile* pProfile = PROFILEMAN->GetProfile((PlayerNumber)p);
Profile* pProfile = PROFILEMAN->GetProfile(p);
if( pProfile )
g_CurStageStats.iCurCombo[p] = pProfile->m_iCurrentCombo;
g_CurStageStats.m_player[p].iCurCombo = pProfile->m_iCurrentCombo;
}
}
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 )
{
int iNumTapsAndHolds = (int) g_CurStageStats.radarActual[pn][RADAR_NUM_TAPS_AND_HOLDS];
int iNumJumps = (int) g_CurStageStats.radarActual[pn][RADAR_NUM_JUMPS];
int iNumHolds = (int) g_CurStageStats.radarActual[pn][RADAR_NUM_HOLDS];
int iNumMines = (int) g_CurStageStats.radarActual[pn][RADAR_NUM_MINES];
int iNumHands = (int) g_CurStageStats.radarActual[pn][RADAR_NUM_HANDS];
int iNumTapsAndHolds = (int) g_CurStageStats.m_player[pn].radarActual[RADAR_NUM_TAPS_AND_HOLDS];
int iNumJumps = (int) g_CurStageStats.m_player[pn].radarActual[RADAR_NUM_JUMPS];
int iNumHolds = (int) g_CurStageStats.m_player[pn].radarActual[RADAR_NUM_HOLDS];
int iNumMines = (int) g_CurStageStats.m_player[pn].radarActual[RADAR_NUM_MINES];
int iNumHands = (int) g_CurStageStats.m_player[pn].radarActual[RADAR_NUM_HANDS];
PROFILEMAN->AddStepTotals( pn, iNumTapsAndHolds, iNumJumps, iNumHolds, iNumMines, iNumHands );
}
@@ -684,7 +674,7 @@ void GameState::FinishStage()
pPlayerProfile->m_iTotalGameplaySeconds += iGameplaySeconds;
pPlayerProfile->m_iCurrentCombo =
PREFSMAN->m_bComboContinuesBetweenSongs ?
g_CurStageStats.iCurCombo[p] :
g_CurStageStats.m_player[p].iCurCombo :
0;
}
@@ -787,7 +777,7 @@ int GameState::GetCourseSongIndex() const
/* iSongsPlayed includes the current song, so it's 1-based; subtract one. */
FOREACH_PlayerNumber( p )
if( IsPlayerEnabled(p) )
iSongIndex = max( iSongIndex, g_CurStageStats.iSongsPlayed[p]-1 );
iSongIndex = max( iSongIndex, g_CurStageStats.m_player[p].iSongsPlayed-1 );
return iSongIndex;
}
@@ -985,11 +975,8 @@ bool GameState::HasEarnedExtraStage() const
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 &&
this->m_pCurSteps[p]->GetDifficulty() != DIFFICULTY_CHALLENGE )
continue; /* not hard enough! */
@@ -999,7 +986,7 @@ bool GameState::HasEarnedExtraStage() const
if( PREFSMAN->m_bPickExtraStage && this->IsExtraStage() && !this->m_bAllow2ndExtraStage )
continue;
if( g_CurStageStats.GetGrade((PlayerNumber)p) <= GRADE_TIER_3 )
if( g_CurStageStats.m_player[p].GetGrade() <= GRADE_TIER_3 )
return true;
}
}
@@ -1008,9 +995,9 @@ bool GameState::HasEarnedExtraStage() const
PlayerNumber GameState::GetBestPlayer() const
{
for( int p=PLAYER_1; p<NUM_PLAYERS; p++ )
if( GetStageResult( (PlayerNumber)p ) == RESULT_WIN )
return (PlayerNumber)p;
FOREACH_PlayerNumber( p )
if( GetStageResult(p) == RESULT_WIN )
return p;
return PLAYER_INVALID; // draw
}
@@ -1037,11 +1024,11 @@ StageResult GameState::GetStageResult( PlayerNumber pn ) const
continue;
/* 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;
/* 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 win;
@@ -1081,8 +1068,8 @@ void GameState::GetFinalEvalStats( StageStats& statsOut ) const
{
for( int r = 0; r < RADAR_NUM_TAPS_AND_HOLDS; r++)
{
statsOut.radarPossible[p][r] /= statsOut.vpSongs.size();
statsOut.radarActual[p][r] /= statsOut.vpSongs.size();
statsOut.m_player[p].radarPossible[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;
sas.pSong = g_vPlayedStageStats[i].vpSongs[0];
ASSERT( sas.pSong );
sas.pSteps = g_vPlayedStageStats[i].vpSteps[pn][0];
sas.pSteps = g_vPlayedStageStats[i].m_player[pn].vpSteps[0];
ASSERT( sas.pSteps );
vSongAndSteps.push_back( sas );
}
@@ -1702,7 +1689,7 @@ bool GameState::AllAreDead() const
bool GameState::AllHaveComboOf30OrMoreMisses() const
{
FOREACH_EnabledPlayer( p )
if( g_CurStageStats.iCurMissCombo[p] < 30 )
if( g_CurStageStats.m_player[p].iCurMissCombo < 30 )
return false;
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) );
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++ )
CLAMP( m_DestValues[i], 0.f, 1.f );
UpdateVerts();
+2 -2
View File
@@ -95,10 +95,10 @@ void Inventory::Update( float fDelta )
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
// 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;
m_iLastSeenCombo = g_CurStageStats.iCurCombo[pn];
m_iLastSeenCombo = g_CurStageStats.m_player[pn].iCurCombo;
int iNewCombo = m_iLastSeenCombo;
#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( g_CurStageStats.bFailed[m_PlayerNumber] )
if( g_CurStageStats.m_player[m_PlayerNumber].bFailed )
fDeltaLife = 0;
switch( GAMESTATE->m_SongOptions.m_DrainType )
@@ -432,7 +432,7 @@ void LifeMeterBar::ChangeLife( float fDeltaLife )
CLAMP( m_fLifePercentage, 0, 1 );
if( m_fLifePercentage <= FAIL_THRESHOLD )
g_CurStageStats.bFailedEarlier[m_PlayerNumber] = true;
g_CurStageStats.m_player[m_PlayerNumber].bFailedEarlier = true;
m_fLifeVelocity += fDeltaLife;
}
+4 -4
View File
@@ -64,7 +64,7 @@ void LifeMeterBattery::Load( PlayerNumber pn )
void LifeMeterBattery::OnSongEnded()
{
if( g_CurStageStats.bFailedEarlier[m_PlayerNumber] )
if( g_CurStageStats.m_player[m_PlayerNumber].bFailedEarlier )
return;
if( m_iLivesLeft < GAMESTATE->m_SongOptions.m_iBatteryLives )
@@ -81,7 +81,7 @@ void LifeMeterBattery::OnSongEnded()
void LifeMeterBattery::ChangeLife( TapNoteScore score )
{
if( g_CurStageStats.bFailedEarlier[m_PlayerNumber] )
if( g_CurStageStats.m_player[m_PlayerNumber].bFailedEarlier )
return;
switch( score )
@@ -108,7 +108,7 @@ void LifeMeterBattery::ChangeLife( TapNoteScore score )
ASSERT(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 )
@@ -151,7 +151,7 @@ bool LifeMeterBattery::IsHot() const
bool LifeMeterBattery::IsFailing() const
{
return g_CurStageStats.bFailedEarlier[m_PlayerNumber];
return g_CurStageStats.m_player[m_PlayerNumber].bFailedEarlier;
}
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);
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)
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
* 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. */
const StageStats::Combo_t MaxCombo = g_CurStageStats.GetMaxCombo( pn );
float fComboPercent = SCALE( MaxCombo.fSizeSeconds, 0, g_CurStageStats.fLastSecond[pn]-g_CurStageStats.fFirstSecond[pn], 0.0f, 1.0f );
const PlayerStageStats::Combo_t MaxCombo = g_CurStageStats.m_player[pn].GetMaxCombo();
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 );
}
@@ -308,11 +308,11 @@ float NoteDataWithScoring::GetActualAirRadarValue( float fSongSeconds, PlayerNum
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 )
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 );
}
+2 -2
View File
@@ -64,7 +64,7 @@ void PercentageDisplay::Update( float fDeltaTime )
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 )
return;
@@ -77,7 +77,7 @@ void PercentageDisplay::Refresh()
}
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( fPercentDancePoints, 0.f, 1.f );
+101 -53
View File
@@ -127,7 +127,7 @@ void PlayerMinus::Load(
// init steps
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 )
m_NoteData.CopyAll( noteData );
@@ -137,7 +137,7 @@ void PlayerMinus::Load(
m_Judgment.StopTweening();
// m_Combo.Reset(); // don't reset combos between songs in a course!
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_Judgment.Reset();
@@ -188,9 +188,11 @@ void PlayerMinus::Load(
float fNoteFieldMidde = (GRAY_ARROWS_Y_STANDARD+GRAY_ARROWS_Y_REVERSE)/2;
m_pNoteField->SetY( fNoteFieldMidde );
if( m_pNoteField )
m_pNoteField->SetY( fNoteFieldMidde );
m_fNoteFieldHeight = GRAY_ARROWS_Y_REVERSE-GRAY_ARROWS_Y_STANDARD;
m_pNoteField->Load( &m_NoteData, m_pPlayerState, iStartDrawingAtPixels, iStopDrawingAtPixels, m_fNoteFieldHeight );
if( m_pNoteField )
m_pNoteField->Load( &m_NoteData, m_pPlayerState, iStartDrawingAtPixels, iStopDrawingAtPixels, m_fNoteFieldHeight );
m_ArrowBackdrop.SetPlayer( pn );
const bool bReverse = GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions.GetReversePercentForColumn(0) == 1;
@@ -278,7 +280,8 @@ void PlayerMinus::Update( float fDeltaTime )
const float fSongBeat = GAMESTATE->m_fSongBeat;
const int iSongRow = BeatToNoteRow( fSongBeat );
m_pNoteField->Update( fDeltaTime );
if( m_pNoteField )
m_pNoteField->Update( fDeltaTime );
//
// Update Y positions
@@ -304,12 +307,14 @@ void PlayerMinus::Update( float fDeltaTime )
m_ArrowBackdrop.SetY( fGrayYPos );
// NoteField accounts for reverse on its own now.
// m_pNoteField->SetY( fGrayYPos );
//if( m_pNoteField )
// m_pNoteField->SetY( fGrayYPos );
float fMiniPercent = m_pPlayerState->m_CurrentPlayerOptions.m_fEffects[PlayerOptions::EFFECT_MINI];
float fNoteFieldZoom = 1 - fMiniPercent*0.5f;
float fJudgmentZoom = 1 - fMiniPercent*0.25f;
m_pNoteField->SetZoom( fNoteFieldZoom );
if( m_pNoteField )
m_pNoteField->SetZoom( fNoteFieldZoom );
m_Judgment.SetZoom( fJudgmentZoom );
//
@@ -333,7 +338,8 @@ void PlayerMinus::Update( float fDeltaTime )
bool bIsHoldingButton = INPUTMAPPER->IsButtonDown( GameI );
// TODO: Make this work for non-human-controlled players
if( bIsHoldingButton && !GAMESTATE->m_bDemonstrationOrJukebox && m_pPlayerState->m_PlayerController==PC_HUMAN )
m_pNoteField->SetPressed( col );
if( m_pNoteField )
m_pNoteField->SetPressed( col );
}
//
@@ -344,8 +350,11 @@ void PlayerMinus::Update( float fDeltaTime )
const HoldNote &hn = m_NoteData.GetHoldNote(i);
HoldNoteScore hns = m_NoteData.GetHoldNoteScore(hn);
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
if( m_pNoteField )
{
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
}
if( hns != HNS_NONE ) // if this HoldNote already has a result
@@ -375,15 +384,23 @@ void PlayerMinus::Update( float fDeltaTime )
bIsHoldingButton = true;
// set hold flag so NoteField can do intelligent drawing
m_pNoteField->m_HeldHoldNotes[hn] = bIsHoldingButton && bSteppedOnTapNote;
m_pNoteField->m_ActiveHoldNotes[hn] = bSteppedOnTapNote;
if( m_pNoteField )
{
m_pNoteField->m_HeldHoldNotes[hn] = bIsHoldingButton && bSteppedOnTapNote;
m_pNoteField->m_ActiveHoldNotes[hn] = bSteppedOnTapNote;
}
if( bSteppedOnTapNote )
{
/* This hold note is not judged and we stepped on its head. Update
* iLastHeldRow. */
HoldNoteResult *hnr = m_pNoteField->CreateHoldNoteResult( hn );
hnr->iLastHeldRow = min( iSongRow, hn.iEndRow );
HoldNoteResult *hnr = NULL;
if( m_pNoteField )
{
hnr = m_pNoteField->CreateHoldNoteResult( hn );
hnr->iLastHeldRow = min( iSongRow, hn.iEndRow );
}
hnr = m_NoteData.CreateHoldNoteResult( hn );
hnr->iLastHeldRow = min( iSongRow, hn.iEndRow );
@@ -395,7 +412,8 @@ void PlayerMinus::Update( float fDeltaTime )
// Increase life
fLife = 1;
m_pNoteField->DidHoldNote( hn.iTrack ); // update the "electric ghost" effect
if( m_pNoteField )
m_pNoteField->DidHoldNote( hn.iTrack ); // update the "electric ghost" effect
}
else
{
@@ -422,7 +440,8 @@ void PlayerMinus::Update( float fDeltaTime )
{
fLife = 1;
hns = HNS_OK;
m_pNoteField->DidTapNote( StyleI.col, TNS_PERFECT, true ); // bright ghost flash
if( m_pNoteField )
m_pNoteField->DidTapNote( StyleI.col, TNS_PERFECT, true ); // bright ghost flash
}
if( hns != HNS_NONE )
@@ -436,13 +455,16 @@ void PlayerMinus::Update( float fDeltaTime )
// TODO: Remove use of 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 */
m_ProTimingDisplay.SetJudgment( ms_error, TNS_MISS );
}
m_pNoteField->SetHoldNoteLife(hn, fLife); // update the NoteField display
m_pNoteField->SetHoldNoteScore(hn, hns); // update the NoteField display
if( m_pNoteField )
{
m_pNoteField->SetHoldNoteLife(hn, fLife); // update the NoteField display
m_pNoteField->SetHoldNoteScore(hn, hns); // update the NoteField display
}
m_NoteData.SetHoldNoteLife(hn, fLife);
m_NoteData.SetHoldNoteScore(hn, hns);
@@ -486,7 +508,8 @@ void PlayerMinus::Update( float fDeltaTime )
/* 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
* time loading skins in the middle of a song, something is wrong. */
m_pNoteField->CacheAllUsedNoteSkins();
if( m_pNoteField )
m_pNoteField->CacheAllUsedNoteSkins();
ActorFrame::Update( fDeltaTime );
}
@@ -512,13 +535,17 @@ void PlayerMinus::ApplyWaitingTransforms()
GAMESTATE->SetNoteSkinForBeatRange( m_pPlayerState, po.m_sNoteSkin, fStartBeat, fEndBeat );
NoteDataUtil::TransformNoteData( m_NoteData, po, GAMESTATE->GetCurrentStyle()->m_StepsType, fStartBeat, fEndBeat );
m_pNoteField->CopyRange( m_NoteData, BeatToNoteRow(fStartBeat), BeatToNoteRow(fEndBeat), BeatToNoteRow(fStartBeat) );
if( m_pNoteField )
m_pNoteField->CopyRange( m_NoteData, BeatToNoteRow(fStartBeat), BeatToNoteRow(fEndBeat), BeatToNoteRow(fStartBeat) );
}
m_pPlayerState->m_ModsToApply.clear();
}
void PlayerMinus::DrawPrimitives()
{
if( m_pNoteField == NULL )
return;
// TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
@@ -673,7 +700,7 @@ void PlayerMinus::Step( int col, RageTimer tm )
// TODO: Remove use of 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
//LOG->Trace( "PlayerMinus::HandlePlayerStep()" );
@@ -745,8 +772,11 @@ void PlayerMinus::Step( int col, RageTimer tm )
if( m_pCombinedLifeMeter )
m_pCombinedLifeMeter->ChangeLifeMine( pn );
m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
m_pNoteField->DidTapNote( col, score, false );
if( m_pNoteField )
{
m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
m_pNoteField->DidTapNote( col, score, false );
}
}
break;
@@ -778,7 +808,8 @@ void PlayerMinus::Step( int col, RageTimer tm )
if( tn.type == TapNote::attack )
{
m_NoteData.SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
if( m_pNoteField )
m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
}
}
}
@@ -840,8 +871,11 @@ void PlayerMinus::Step( int col, RageTimer tm )
if( m_pCombinedLifeMeter )
m_pCombinedLifeMeter->ChangeLifeMine( pn );
m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
m_pNoteField->DidTapNote( col, score, false );
if( m_pNoteField )
{
m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
m_pNoteField->DidTapNote( col, score, false );
}
}
}
@@ -880,7 +914,8 @@ void PlayerMinus::Step( int col, RageTimer tm )
if( tn.type == TapNote::attack )
{
m_NoteData.SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
m_pNoteField->SetTapNote(col, iIndexOverlappingNote, TAP_EMPTY); // remove from NoteField
if( m_pNoteField )
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.
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)
m_ProTimingDisplay.SetJudgment( ms_error, score );
}
@@ -969,11 +1004,13 @@ void PlayerMinus::Step( int col, RageTimer tm )
m_iDCState = AS2D_FEVER; // super celebrate time :)
}
}
m_pNoteField->Step( col, score );
if( m_pNoteField )
m_pNoteField->Step( col, score );
}
else
{
m_pNoteField->Step( col, TNS_NONE );
if( m_pNoteField )
m_pNoteField->Step( col, TNS_NONE );
}
/* Search for keyed sounds separately. If we can't find a nearby note, search
@@ -1046,18 +1083,23 @@ void PlayerMinus::OnRowCompletelyJudged( int iIndexThatWasSteppedOn )
// If the score is great or better, remove the note from the screen to
// indicate success. (Or always if blind is on.)
if( score >= TNS_GREAT || m_pPlayerState->m_PlayerOptions.m_fBlind )
m_pNoteField->SetTapNote(c, iIndexThatWasSteppedOn, TAP_EMPTY);
if( m_pNoteField )
m_pNoteField->SetTapNote(c, iIndexThatWasSteppedOn, TAP_EMPTY);
// show the ghost arrow for this column
if (m_pPlayerState->m_PlayerOptions.m_fBlind)
m_pNoteField->DidTapNote( c, TNS_MARVELOUS, false );
{
if( m_pNoteField )
m_pNoteField->DidTapNote( c, TNS_MARVELOUS, false );
}
else
{
// TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
bool bBright = g_CurStageStats.iCurCombo[pn]>(int)BRIGHT_GHOST_COMBO_THRESHOLD;
m_pNoteField->DidTapNote( c, score, bBright );
bool bBright = g_CurStageStats.m_player[pn].iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD;
if( m_pNoteField )
m_pNoteField->DidTapNote( c, score, bBright );
}
}
@@ -1118,7 +1160,7 @@ void PlayerMinus::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds )
// TODO: Remove use of 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 );
}
}
@@ -1219,10 +1261,13 @@ void PlayerMinus::RandomizeNotes( int iNoteRow )
m_NoteData.SetTapNote( t, iNewNoteRow, t2 );
m_NoteData.SetTapNote( iSwapWith, iNewNoteRow, t1 );
const TapNote nft1 = m_pNoteField->GetTapNote( t, iNewNoteRow );
const TapNote nft2 = m_pNoteField->GetTapNote( iSwapWith, iNewNoteRow );
m_pNoteField->SetTapNote( t, iNewNoteRow, nft2 );
m_pNoteField->SetTapNote( iSwapWith, iNewNoteRow, nft1 );
if( m_pNoteField )
{
const TapNote nft1 = m_pNoteField->GetTapNote( t, iNewNoteRow );
const TapNote nft2 = m_pNoteField->GetTapNote( iSwapWith, iNewNoteRow );
m_pNoteField->SetTapNote( t, iNewNoteRow, nft2 );
m_pNoteField->SetTapNote( iSwapWith, iNewNoteRow, nft1 );
}
}
}
@@ -1247,18 +1292,18 @@ void PlayerMinus::HandleTapRowScore( unsigned row )
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
/* Update miss combo, and handle "combo stopped" messages. */
int &iCurCombo = g_CurStageStats.iCurCombo[pn];
int &iCurCombo = g_CurStageStats.m_player[pn].iCurCombo;
switch( scoreOfLastTap )
{
case TNS_MARVELOUS:
case TNS_PERFECT:
case TNS_GREAT:
g_CurStageStats.iCurMissCombo[pn] = 0;
g_CurStageStats.m_player[pn].iCurMissCombo = 0;
SCREENMAN->PostMessageToTopScreen( SM_MissComboAborted, 0 );
break;
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
case TNS_GOOD:
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. */
const int iOldCombo = g_CurStageStats.iCurCombo[pn];
const int iOldCombo = g_CurStageStats.m_player[pn].iCurCombo;
if(m_pPrimaryScoreKeeper)
m_pPrimaryScoreKeeper->HandleTapRowScore(scoreOfLastTap, iNumTapsInRow );
if(m_pSecondaryScoreKeeper)
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)
if ( CROSSED(100) )
@@ -1307,16 +1352,18 @@ void PlayerMinus::HandleTapRowScore( unsigned row )
#undef CROSSED
// 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
* 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. */
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;
if( m_pLifeMeter )
{
life = m_pLifeMeter->GetLife();
}
else if( m_pCombinedLifeMeter )
{
life = GAMESTATE->m_fTugLifePercentP1;
@@ -1324,12 +1371,12 @@ void PlayerMinus::HandleTapRowScore( unsigned row )
life = 1.0f - life;
}
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)
m_pScoreDisplay->SetScore(g_CurStageStats.iScore[pn]);
m_pScoreDisplay->SetScore(g_CurStageStats.m_player[pn].iScore);
if (m_pSecondaryScoreDisplay)
m_pSecondaryScoreDisplay->SetScore(g_CurStageStats.iScore[pn]);
m_pSecondaryScoreDisplay->SetScore(g_CurStageStats.m_player[pn].iScore);
if( m_pLifeMeter ) {
m_pLifeMeter->ChangeLife( scoreOfLastTap );
@@ -1364,9 +1411,9 @@ void PlayerMinus::HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tapScor
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
if (m_pScoreDisplay)
m_pScoreDisplay->SetScore(g_CurStageStats.iScore[pn]);
m_pScoreDisplay->SetScore(g_CurStageStats.m_player[pn].iScore);
if (m_pSecondaryScoreDisplay)
m_pSecondaryScoreDisplay->SetScore(g_CurStageStats.iScore[pn]);
m_pSecondaryScoreDisplay->SetScore(g_CurStageStats.m_player[pn].iScore);
if( m_pLifeMeter )
{
@@ -1387,7 +1434,8 @@ float PlayerMinus::GetMaxStepDistanceSeconds()
void PlayerMinus::FadeToFail()
{
m_pNoteField->FadeToFail();
if( m_pNoteField )
m_pNoteField->FadeToFail();
}
/* XXX: Why's m_NoteField in a separate class, again? Is that still needed? */
+35
View File
@@ -10,6 +10,41 @@
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
// in PlayerState and callers should not use PlayerNumber to index into
// GameState.
+1 -1
View File
@@ -43,7 +43,7 @@ void ScoreDisplayOni::Update( float fDelta )
float fSecsIntoPlay = 0;
if( GAMESTATE->IsPlayerEnabled(pn) )
fSecsIntoPlay = g_CurStageStats.fAliveSeconds[pn];
fSecsIntoPlay = g_CurStageStats.m_player[pn].fAliveSeconds;
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.
{
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.
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
@@ -266,7 +266,7 @@ void ScoreKeeperMAX2::AddScore( TapNoteScore score )
const int B = m_iMaxPossiblePoints/10;
// Don't use a multiplier if the player has failed
if( g_CurStageStats.bFailedEarlier[pn] )
if( g_CurStageStats.m_player[pn].bFailedEarlier )
{
iScore += p;
// make score evenly divisible by 5
@@ -279,8 +279,8 @@ void ScoreKeeperMAX2::AddScore( TapNoteScore score )
else
{
iScore += GetScore(p, B, sum, m_iTapNotesHit);
const int &iCurrentCombo = g_CurStageStats.iCurCombo[pn];
g_CurStageStats.iBonus[pn] += m_ComboBonusFactor[score] * iCurrentCombo;
const int &iCurrentCombo = g_CurStageStats.m_player[pn].iCurCombo;
g_CurStageStats.m_player[pn].iBonus += m_ComboBonusFactor[score] * iCurrentCombo;
}
/* 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 (!g_CurStageStats.bFailedEarlier[pn])
if (!g_CurStageStats.m_player[pn].bFailedEarlier)
iScore += m_iPointBonus;
if ( m_bIsLastSongInCourse )
{
@@ -320,8 +320,8 @@ void ScoreKeeperMAX2::HandleTapScore( TapNoteScore score )
if( score == TNS_HIT_MINE )
{
if( m_pPlayerState->m_HealthState != PlayerState::DEAD )
g_CurStageStats.iActualDancePoints[pn] += TapNoteScoreToDancePoints( TNS_HIT_MINE );
g_CurStageStats.iTapNoteScores[pn][TNS_HIT_MINE] += 1;
g_CurStageStats.m_player[pn].iActualDancePoints += TapNoteScoreToDancePoints( TNS_HIT_MINE );
g_CurStageStats.m_player[pn].iTapNoteScores[TNS_HIT_MINE] += 1;
}
}
@@ -334,9 +334,9 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa
// Update dance points.
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
g_CurStageStats.iTapNoteScores[pn][scoreOfLastTap] += 1;
g_CurStageStats.m_player[pn].iTapNoteScores[scoreOfLastTap] += 1;
//
// 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;
if( scoreOfLastTap >= MinScoreToContinueCombo )
g_CurStageStats.iCurCombo[pn] += ComboCountIfHit;
g_CurStageStats.m_player[pn].iCurCombo += ComboCountIfHit;
AddScore( scoreOfLastTap ); // only score once per row
@@ -409,8 +409,8 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa
// TODO: Remove indexing with PlayerNumber
NSMAN->ReportScore(pn, scoreOfLastTap,
g_CurStageStats.iScore[pn],
g_CurStageStats.iCurCombo[pn]);
g_CurStageStats.m_player[pn].iScore,
g_CurStageStats.m_player[pn].iCurCombo);
}
@@ -421,15 +421,17 @@ void ScoreKeeperMAX2::HandleHoldScore( HoldNoteScore holdScore, TapNoteScore tap
// update dance points totals
if( m_pPlayerState->m_HealthState != PlayerState::DEAD )
g_CurStageStats.iActualDancePoints[pn] += HoldNoteScoreToDancePoints( holdScore );
g_CurStageStats.iHoldNoteScores[pn][holdScore] ++;
g_CurStageStats.m_player[pn].iActualDancePoints += HoldNoteScoreToDancePoints( holdScore );
g_CurStageStats.m_player[pn].iHoldNoteScores[holdScore] ++;
if( holdScore == HNS_OK )
AddScore( TNS_MARVELOUS );
NSMAN->ReportScore(pn, holdScore+7,
g_CurStageStats.iScore[pn],
g_CurStageStats.iCurCombo[pn]);
NSMAN->ReportScore(
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_pCurSteps[PLAYER_1] = 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.vpSteps[PLAYER_2].push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
g_CurStageStats.m_player[PLAYER_1].vpSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_1] );
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_2]->m_PlayerOptions.m_fScrollSpeed = 2;
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 )
{
float fP1 = fmodf(f/100*4+.3f,1);
g_CurStageStats.SetLifeRecordAt( PLAYER_1, fP1, f );
g_CurStageStats.SetLifeRecordAt( PLAYER_2, 1-fP1, f );
g_CurStageStats.m_player[PLAYER_1].SetLifeRecordAt( fP1, f );
g_CurStageStats.m_player[PLAYER_2].SetLifeRecordAt( 1-fP1, f );
}
g_CurStageStats.iActualDancePoints[PLAYER_1] = rand()%3;
g_CurStageStats.iPossibleDancePoints[PLAYER_1] = 2;
g_CurStageStats.iActualDancePoints[PLAYER_2] = rand()%2;
g_CurStageStats.iPossibleDancePoints[PLAYER_2] = 1;
g_CurStageStats.iCurCombo[PLAYER_1] = 0;
g_CurStageStats.UpdateComboList( PLAYER_1, 0, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 1;
g_CurStageStats.UpdateComboList( PLAYER_1, 1, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 50;
g_CurStageStats.UpdateComboList( PLAYER_1, 25, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 250;
g_CurStageStats.UpdateComboList( PLAYER_1, 100, false );
g_CurStageStats.m_player[PLAYER_1].iActualDancePoints = rand()%3;
g_CurStageStats.m_player[PLAYER_1].iPossibleDancePoints = 2;
g_CurStageStats.m_player[PLAYER_2].iActualDancePoints = rand()%2;
g_CurStageStats.m_player[PLAYER_2].iPossibleDancePoints = 1;
g_CurStageStats.m_player[PLAYER_1].iCurCombo = 0;
g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 0, false );
g_CurStageStats.m_player[PLAYER_1].iCurCombo = 1;
g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 1, false );
g_CurStageStats.m_player[PLAYER_1].iCurCombo = 50;
g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 25, false );
g_CurStageStats.m_player[PLAYER_1].iCurCombo = 250;
g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 100, false );
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_MARVELOUS] = rand()%2;
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_PERFECT] = rand()%2;
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_GREAT] = rand()%2;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_MARVELOUS] = rand()%2;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_PERFECT] = rand()%2;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_GREAT] = rand()%2;
g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_MARVELOUS] = rand()%2;
g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_PERFECT] = rand()%2;
g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_GREAT] = rand()%2;
g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_MARVELOUS] = rand()%2;
g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_PERFECT] = rand()%2;
g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_GREAT] = rand()%2;
g_vPlayedStageStats.clear();
}
+82 -82
View File
@@ -112,8 +112,8 @@ void ScreenEvaluation::Init()
GAMESTATE->m_pCurCourse = SONGMAN->GetRandomCourse();
GAMESTATE->m_pCurSteps[PLAYER_1] = GAMESTATE->m_pCurSong->GetAllSteps()[0];
GAMESTATE->m_pCurSteps[PLAYER_2] = GAMESTATE->m_pCurSong->GetAllSteps()[0];
g_CurStageStats.vpSteps[PLAYER_1].push_back( GAMESTATE->m_pCurSteps[PLAYER_1] );
g_CurStageStats.vpSteps[PLAYER_2].push_back( GAMESTATE->m_pCurSteps[PLAYER_2] );
g_CurStageStats.m_player[PLAYER_1].vpSteps.push_back( GAMESTATE->m_pCurSteps[PLAYER_1] );
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_2]->m_PlayerOptions.m_fScrollSpeed = 2;
GAMESTATE->m_iCurrentStageIndex = 0;
@@ -123,47 +123,47 @@ void ScreenEvaluation::Init()
for( float f = 0; f < 100.0f; f += 1.0f )
{
float fP1 = fmodf(f/100*4+.3f,1);
g_CurStageStats.SetLifeRecordAt( PLAYER_1, fP1, f );
g_CurStageStats.SetLifeRecordAt( PLAYER_2, 1-fP1, f );
g_CurStageStats.m_player[PLAYER_1].SetLifeRecordAt( fP1, f );
g_CurStageStats.m_player[PLAYER_2].SetLifeRecordAt( 1-fP1, f );
}
g_CurStageStats.iActualDancePoints[PLAYER_1] = rand()%3;
g_CurStageStats.iPossibleDancePoints[PLAYER_1] = 2;
g_CurStageStats.iActualDancePoints[PLAYER_2] = rand()%2;
g_CurStageStats.iPossibleDancePoints[PLAYER_2] = 1;
g_CurStageStats.iCurCombo[PLAYER_1] = 0;
g_CurStageStats.UpdateComboList( PLAYER_1, 0, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 1;
g_CurStageStats.UpdateComboList( PLAYER_1, 1, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 50;
g_CurStageStats.UpdateComboList( PLAYER_1, 25, false );
g_CurStageStats.iCurCombo[PLAYER_1] = 250;
g_CurStageStats.UpdateComboList( PLAYER_1, 100, false );
g_CurStageStats.m_player[PLAYER_1].iActualDancePoints = rand()%3;
g_CurStageStats.m_player[PLAYER_1].iPossibleDancePoints = 2;
g_CurStageStats.m_player[PLAYER_2].iActualDancePoints = rand()%2;
g_CurStageStats.m_player[PLAYER_2].iPossibleDancePoints = 1;
g_CurStageStats.m_player[PLAYER_1].iCurCombo = 0;
g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 0, false );
g_CurStageStats.m_player[PLAYER_1].iCurCombo = 1;
g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 1, false );
g_CurStageStats.m_player[PLAYER_1].iCurCombo = 50;
g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 25, false );
g_CurStageStats.m_player[PLAYER_1].iCurCombo = 250;
g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 100, false );
if( rand()%2 )
{
g_CurStageStats.iCurCombo[PLAYER_1] = rand()%11000;
g_CurStageStats.UpdateComboList( PLAYER_1, 110, false );
g_CurStageStats.m_player[PLAYER_1].iCurCombo = rand()%11000;
g_CurStageStats.m_player[PLAYER_1].UpdateComboList( 110, false );
}
g_CurStageStats.iCurCombo[PLAYER_2] = 0;
g_CurStageStats.UpdateComboList( PLAYER_2, 0, false );
g_CurStageStats.iCurCombo[PLAYER_2] = 1;
g_CurStageStats.UpdateComboList( PLAYER_2, 1, false );
g_CurStageStats.iCurCombo[PLAYER_2] = 50;
g_CurStageStats.UpdateComboList( PLAYER_2, 25, false );
g_CurStageStats.iCurCombo[PLAYER_2] = 250;
g_CurStageStats.UpdateComboList( PLAYER_2, 100, false );
g_CurStageStats.m_player[PLAYER_2].iCurCombo = 0;
g_CurStageStats.m_player[PLAYER_2].UpdateComboList( 0, false );
g_CurStageStats.m_player[PLAYER_2].iCurCombo = 1;
g_CurStageStats.m_player[PLAYER_2].UpdateComboList( 1, false );
g_CurStageStats.m_player[PLAYER_2].iCurCombo = 50;
g_CurStageStats.m_player[PLAYER_2].UpdateComboList( 25, false );
g_CurStageStats.m_player[PLAYER_2].iCurCombo = 250;
g_CurStageStats.m_player[PLAYER_2].UpdateComboList( 100, false );
if( rand()%2 )
{
g_CurStageStats.iCurCombo[PLAYER_2] = rand()%11000;
g_CurStageStats.UpdateComboList( PLAYER_2, 110, false );
g_CurStageStats.m_player[PLAYER_2].iCurCombo = rand()%11000;
g_CurStageStats.m_player[PLAYER_2].UpdateComboList( 110, false );
}
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_MARVELOUS] = rand()%3;
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_PERFECT] = rand()%3;
g_CurStageStats.iTapNoteScores[PLAYER_1][TNS_GREAT] = rand()%3;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_MARVELOUS] = rand()%3;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_PERFECT] = rand()%3;
g_CurStageStats.iTapNoteScores[PLAYER_2][TNS_GREAT] = rand()%3;
g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_MARVELOUS] = rand()%3;
g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_PERFECT] = rand()%3;
g_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_GREAT] = rand()%3;
g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_MARVELOUS] = rand()%3;
g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_PERFECT] = rand()%3;
g_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_GREAT] = rand()%3;
g_vPlayedStageStats.clear();
}
@@ -205,7 +205,7 @@ void ScreenEvaluation::Init()
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 )
{
if( GAMESTATE->IsPlayerEnabled(p) )
grade[p] = stageStats.GetGrade( p );
grade[p] = stageStats.m_player[p].GetGrade();
else
grade[p] = GRADE_FAILED;
@@ -238,8 +238,8 @@ void ScreenEvaluation::Init()
const int ScoreBonuses[] = { 10000000, 10000000, 1000000, 100000, 10000, 1000, 100 };
if( grade[p] < (int) ARRAYSIZE(ScoreBonuses) )
{
g_CurStageStats.iBonus[p] += ScoreBonuses[(int)grade[p] ];
stageStats.iBonus[p] += ScoreBonuses[(int)grade[p] ];
g_CurStageStats.m_player[p].iBonus += 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
{
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) );
SET_XY_AND_ON_COMMAND( 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)) );
// 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();
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] );
// .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 );
this->AddChild( &m_sprActualBar[p][r] );
}
@@ -575,7 +575,7 @@ void ScreenEvaluation::Init()
m_textSurvivedNumber[p].SetShadowLength( 0 );
// 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)
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) );
SET_XY_AND_ON_COMMAND( m_textSurvivedNumber[p] );
this->AddChild( &m_textSurvivedNumber[p] );
@@ -634,15 +634,15 @@ void ScreenEvaluation::Init()
int iValue;
switch( l )
{
case marvelous: iValue = stageStats.iTapNoteScores[p][TNS_MARVELOUS]; break;
case perfect: iValue = stageStats.iTapNoteScores[p][TNS_PERFECT]; break;
case great: iValue = stageStats.iTapNoteScores[p][TNS_GREAT]; break;
case good: iValue = stageStats.iTapNoteScores[p][TNS_GOOD]; break;
case boo: iValue = stageStats.iTapNoteScores[p][TNS_BOO]; break;
case miss: iValue = stageStats.iTapNoteScores[p][TNS_MISS]; break;
case ok: iValue = stageStats.iHoldNoteScores[p][HNS_OK]; break;
case max_combo: iValue = stageStats.GetMaxCombo(p).cnt; break;
case error: iValue = stageStats.iTotalError[p]; break;
case marvelous: iValue = stageStats.m_player[p].iTapNoteScores[TNS_MARVELOUS]; break;
case perfect: iValue = stageStats.m_player[p].iTapNoteScores[TNS_PERFECT]; break;
case great: iValue = stageStats.m_player[p].iTapNoteScores[TNS_GREAT]; break;
case good: iValue = stageStats.m_player[p].iTapNoteScores[TNS_GOOD]; break;
case boo: iValue = stageStats.m_player[p].iTapNoteScores[TNS_BOO]; break;
case miss: iValue = stageStats.m_player[p].iTapNoteScores[TNS_MISS]; break;
case ok: iValue = stageStats.m_player[p].iHoldNoteScores[HNS_OK]; break;
case max_combo: iValue = stageStats.m_player[p].GetMaxCombo().cnt; break;
case error: iValue = stageStats.m_player[p].iTotalError; break;
default: iValue = 0; ASSERT(0);
}
@@ -677,8 +677,8 @@ void ScreenEvaluation::Init()
RADAR_NUM_JUMPS, RADAR_NUM_HOLDS, RADAR_NUM_MINES, RADAR_NUM_HANDS
};
const int ind = indeces[l];
const int iActual = (int) roundf(stageStats.radarActual[p][ind]);
const int iPossible = (int) roundf(stageStats.radarPossible[p][ind]);
const int iActual = (int) roundf(stageStats.m_player[p].radarActual[ind]);
const int iPossible = (int) roundf(stageStats.m_player[p].radarPossible[ind]);
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].SetName( ssprintf("ScoreNumberP%d",p+1) );
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] );
}
}
@@ -717,9 +717,9 @@ void ScreenEvaluation::Init()
{
int iTotalScore=0;
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].SetShadowLength( 0 );
@@ -749,7 +749,7 @@ void ScreenEvaluation::Init()
m_textTime[p].SetDiffuse( PlayerToColor(p) );
m_textTime[p].SetName( ssprintf("TimeNumberP%d",p+1) );
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] );
}
}
@@ -927,18 +927,18 @@ void ScreenEvaluation::CommitScores(
HighScore &hs = m_HighScore[p];
hs.sName = RANKING_TO_FILL_IN_MARKER[p];
hs.grade = stageStats.GetGrade( p );
hs.iScore = stageStats.iScore[p];
hs.fPercentDP = stageStats.GetPercentDancePoints( p );
hs.fSurviveSeconds = stageStats.fAliveSeconds[p];
hs.grade = stageStats.m_player[p].GetGrade();
hs.iScore = stageStats.m_player[p].iScore;
hs.fPercentDP = stageStats.m_player[p].GetPercentDancePoints();
hs.fSurviveSeconds = stageStats.m_player[p].fAliveSeconds;
hs.sModifiers = GAMESTATE->m_pPlayerState[p]->m_PlayerOptions.GetString();
hs.dateTime = DateTime::GetNowDateTime();
hs.sPlayerGuid = PROFILEMAN->IsUsingProfile(p) ? PROFILEMAN->GetProfile(p)->m_sGuid : CString("");
hs.sMachineGuid = PROFILEMAN->GetMachineProfile()->m_sGuid;
hs.iProductID = PREFSMAN->m_iProductID;
memcpy( hs.iTapNoteScores, stageStats.iTapNoteScores[p], sizeof(hs.iTapNoteScores) );
memcpy( hs.iHoldNoteScores, stageStats.iHoldNoteScores[p], sizeof(hs.iHoldNoteScores) );
hs.radarValues = stageStats.radarActual[p];
memcpy( hs.iTapNoteScores, stageStats.m_player[p].iTapNoteScores, sizeof(hs.iTapNoteScores) );
memcpy( hs.iHoldNoteScores, stageStats.m_player[p].iHoldNoteScores, sizeof(hs.iHoldNoteScores) );
hs.radarValues = stageStats.m_player[p].radarActual;
StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
@@ -947,7 +947,7 @@ void ScreenEvaluation::CommitScores(
case stage:
{
// don't save scores for a failed song
if( stageStats.bFailed[p] )
if( stageStats.m_player[p].bFailed )
continue;
ASSERT( pSteps );
@@ -959,7 +959,7 @@ void ScreenEvaluation::CommitScores(
case summary:
{
// don't save scores if any stage was failed
if( stageStats.bFailed[p] )
if( stageStats.m_player[p].bFailed )
continue;
int iAverageMeter = stageStats.GetAverageMeter(p);
@@ -1055,23 +1055,23 @@ void ScreenEvaluation::CommitScores(
// don't give per-difficutly awards if using easy mods
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 );
if( stageStats.SingleDigitsOfScore( p, TNS_GREAT ) )
if( stageStats.m_player[p].SingleDigitsOfScore( TNS_GREAT ) )
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 );
if( stageStats.SingleDigitsOfScore( p, TNS_PERFECT ) )
if( stageStats.m_player[p].SingleDigitsOfScore( TNS_PERFECT ) )
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 );
if( stageStats.OneOfScore( p, TNS_GREAT ) )
if( stageStats.m_player[p].OneOfScore( TNS_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 );
float fPercentGreats = stageStats.GetPercentageOfTaps(p, TNS_GREAT);
float fPercentGreats = stageStats.m_player[p].GetPercentageOfTaps( TNS_GREAT );
if( fPercentGreats >= 0.8f )
vPdas.push_back( AWARD_GREATS_80_PERCENT );
if( fPercentGreats >= 0.9f )
@@ -1091,8 +1091,8 @@ void ScreenEvaluation::CommitScores(
LOG->Trace( "done with per difficulty awards" );
// DO give peak combo awards if using easy mods
int iComboAtStartOfStage = stageStats.GetComboAtStartOfStage( p );
int iPeakCombo = stageStats.GetMaxCombo(p).cnt;
int iComboAtStartOfStage = stageStats.m_player[p].GetComboAtStartOfStage();
int iPeakCombo = stageStats.m_player[p].GetMaxCombo().cnt;
FOREACH_PeakComboAward( pca )
{
@@ -1307,7 +1307,7 @@ void ScreenEvaluation::Update( float fDeltaTime )
FOREACH_EnabledPlayer( p )
{
if( g_CurStageStats.iBonus[p] == 0 )
if( g_CurStageStats.m_player[p].iBonus == 0 )
continue;
if( GAMESTATE->IsCourseMode() )
@@ -1317,16 +1317,16 @@ void ScreenEvaluation::Update( float fDeltaTime )
if( RageTimer::GetTimeSinceStart() - m_fScreenCreateTime < 1.5f )
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 ... */
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.iScore[p] += increment;
g_CurStageStats.m_player[p].iBonus -= increment;
g_CurStageStats.m_player[p].iScore += increment;
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 )
{
ss.vpSongs.push_back( SONGMAN->GetRandomSong() );
ss.iPossibleDancePoints[PLAYER_1] = 100;
ss.iActualDancePoints[PLAYER_1] = 100;
ss.iScore[PLAYER_1] = 100;
ss.iPossibleDancePoints[PLAYER_2] = 100;
ss.iActualDancePoints[PLAYER_2] = 100;
ss.iScore[PLAYER_2] = 100;
ss.m_player[PLAYER_1].iPossibleDancePoints = 100;
ss.m_player[PLAYER_1].iActualDancePoints = 100;
ss.m_player[PLAYER_1].iScore = 100;
ss.m_player[PLAYER_2].iPossibleDancePoints = 100;
ss.m_player[PLAYER_2].iActualDancePoints = 100;
ss.m_player[PLAYER_2].iScore = 100;
ASSERT( ss.vpSongs[0]->GetAllSteps().size() );
FOREACH_PlayerNumber( p )
{
ss.vpSteps[p].push_back( ss.vpSongs[0]->GetAllSteps()[0] );
GAMESTATE->m_pCurSteps[p] = ss.vpSteps[p][0];
ss.iPossibleDancePoints[p] = 1000;
ss.iActualDancePoints[p] = 985;
ss.m_player[p].vpSteps.push_back( ss.vpSongs[0]->GetAllSteps()[0] );
GAMESTATE->m_pCurSteps[p] = ss.m_player[p].vpSteps[0];
ss.m_player[p].iPossibleDancePoints = 1000;
ss.m_player[p].iActualDancePoints = 985;
HighScore hs;
hs.grade = GRADE_TIER_3;
hs.fPercentDP = ss.GetPercentDancePoints(p);
hs.iScore = ss.iScore[p];
hs.fPercentDP = ss.m_player[p].GetPercentDancePoints();
hs.iScore = ss.m_player[p].iScore;
StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
int 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];
Song* pSong = ss.vpSongs[0];
Steps* pSteps = ss.vpSteps[p][0];
Steps* pSteps = ss.m_player[p].vpSteps[0];
Course* pCourse = GAMESTATE->m_pCurCourse;
Trail* pTrail = GAMESTATE->m_pCurTrail[p];
int iHighScoreIndex = -1; // -1 means "out of ranking"
Grade grade = ss.GetGrade( p );
int iScore = ss.iScore[p];
float fPercentDP = ss.GetPercentDancePoints( p );
Grade grade = ss.m_player[p].GetGrade();
int iScore = ss.m_player[p].iScore;
float fPercentDP = ss.m_player[p].GetPercentDancePoints();
// If this is a SHOW_NEVER song, then it's probably a training.
// 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] );
FOREACH( Steps*, g_CurStageStats.vpSteps[p], pSteps )
FOREACH( Steps*, g_CurStageStats.m_player[p].vpSteps, pSteps )
CONVERT_STEPS_POINTER( *pSteps );
FOREACH( StageStats, g_vPlayedStageStats, ss )
FOREACH( Steps*, ss->vpSteps[p], pSteps )
FOREACH( Steps*, ss->m_player[p].vpSteps, pSteps )
CONVERT_STEPS_POINTER( *pSteps );
}
}
+215 -213
View File
@@ -12,149 +12,94 @@
StageStats g_CurStageStats;
vector<StageStats> g_vPlayedStageStats;
void StageStats::Init()
void PlayerStageStats::Init()
{
playMode = PLAY_MODE_INVALID;
pStyle = NULL;
vpSongs.clear();
StageType = STAGE_INVALID;
fGameplaySeconds = 0;
vpSteps.clear();
fAliveSeconds = 0;
bFailed = bFailedEarlier = false;
iPossibleDancePoints = iActualDancePoints = 0;
iCurCombo = iMaxCombo = iCurMissCombo = iScore = iBonus = 0;
fSecondsBeforeFail = 0;
iSongsPassed = iSongsPlayed = 0;
iTotalError = 0;
FOREACH_PlayerNumber( p )
{
vpSteps[p].clear();
fAliveSeconds[p] = 0;
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 );
ZERO( iHoldNoteScores );
radarPossible.Zero();
radarActual.Zero();
ZERO( iTapNoteScores[p] );
ZERO( iHoldNoteScores[p] );
radarPossible[p].Zero();
radarActual[p].Zero();
fFirstSecond[p] = 999999;
fLastSecond[p] = 0;
}
fFirstSecond = 999999;
fLastSecond = 0;
}
void StageStats::AssertValid( PlayerNumber pn ) const
void PlayerStageStats::AddStats( const PlayerStageStats& other )
{
if( vpSongs[0] )
CHECKPOINT_M( vpSongs[0]->GetFullTranslitTitle() );
ASSERT( vpSteps[pn][0] );
ASSERT_M( playMode < NUM_PLAY_MODES, ssprintf("playmode %i", playMode) );
ASSERT( pStyle != NULL );
ASSERT_M( vpSteps[pn][0]->GetDifficulty() < NUM_DIFFICULTIES, ssprintf("difficulty %i", vpSteps[pn][0]->GetDifficulty()) );
ASSERT( vpSongs.size() == vpSteps[pn].size() );
}
int StageStats::GetAverageMeter( PlayerNumber pn ) const
{
int iTotalMeter = 0;
int iTotalCount = 0;
ASSERT( vpSongs.size() == vpSteps[pn].size() );
for( unsigned i=0; i<vpSongs.size(); i++ )
{
Song* pSong = vpSongs[i];
Steps* pSteps = vpSteps[pn][i];
// weight long and marathon songs
int iWeight = SongManager::GetNumStagesForSong( pSong );
int iMeter = pSteps->GetMeter();
iTotalMeter += iMeter;
iTotalCount += iWeight;
}
return iTotalMeter / iTotalCount; // round down
}
void StageStats::AddStats( const StageStats& other )
{
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
FOREACH_CONST( Steps*, other.vpSteps, s )
vpSteps.push_back( *s );
fAliveSeconds += other.fAliveSeconds;
bFailed |= other.bFailed;
bFailedEarlier |= other.bFailedEarlier;
iPossibleDancePoints += other.iPossibleDancePoints;
iActualDancePoints += other.iActualDancePoints;
fGameplaySeconds += other.fGameplaySeconds;
for( int t=0; t<NUM_TAP_NOTE_SCORES; t++ )
iTapNoteScores[t] += other.iTapNoteScores[t];
for( int h=0; h<NUM_HOLD_NOTE_SCORES; h++ )
iHoldNoteScores[h] += other.iHoldNoteScores[h];
iCurCombo += other.iCurCombo;
iMaxCombo += other.iMaxCombo;
iCurMissCombo += other.iCurMissCombo;
iScore += other.iScore;
radarPossible += other.radarPossible;
radarActual += other.radarActual;
fSecondsBeforeFail += other.fSecondsBeforeFail;
iSongsPassed += other.iSongsPassed;
iSongsPlayed += other.iSongsPlayed;
iTotalError += other.iTotalError;
FOREACH_PlayerNumber( p )
const float fOtherFirstSecond = other.fFirstSecond + fLastSecond;
const float fOtherLastSecond = other.fLastSecond + fLastSecond;
fLastSecond = fOtherLastSecond;
map<float,float>::const_iterator it;
for( it = other.fLifeRecord.begin(); it != other.fLifeRecord.end(); ++it )
{
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++ )
iTapNoteScores[p][t] += other.iTapNoteScores[p][t];
for( int h=0; h<NUM_HOLD_NOTE_SCORES; h++ )
iHoldNoteScores[p][h] += other.iHoldNoteScores[p][h];
iCurCombo[p] += other.iCurCombo[p];
iMaxCombo[p] += other.iMaxCombo[p];
iCurMissCombo[p] += other.iCurMissCombo[p];
iScore[p] += other.iScore[p];
radarPossible[p] += other.radarPossible[p];
radarActual[p] += other.radarActual[p];
fSecondsBeforeFail[p] += other.fSecondsBeforeFail[p];
iSongsPassed[p] += other.iSongsPassed[p];
iSongsPlayed[p] += other.iSongsPlayed[p];
iTotalError[p] += other.iTotalError[p];
const float pos = it->first;
const float life = it->second;
fLifeRecord[fOtherFirstSecond+pos] = life;
}
const float fOtherFirstSecond = other.fFirstSecond[p] + fLastSecond[p];
const float fOtherLastSecond = other.fLastSecond[p] + fLastSecond[p];
fLastSecond[p] = fOtherLastSecond;
for( unsigned i=0; i<other.ComboList.size(); ++i )
{
const Combo_t &combo = other.ComboList[i];
map<float,float>::const_iterator it;
for( it = other.fLifeRecord[p].begin(); it != other.fLifeRecord[p].end(); ++it )
{
const float pos = it->first;
const float life = it->second;
fLifeRecord[p][fOtherFirstSecond+pos] = life;
}
Combo_t newcombo(combo);
newcombo.fStartSecond += fOtherFirstSecond;
ComboList.push_back( newcombo );
}
for( unsigned i=0; i<other.ComboList[p].size(); ++i )
{
const Combo_t &combo = other.ComboList[p][i];
/* Merge identical combos. This normally only happens in course mode, when a combo
* continues between songs. */
for( unsigned i=1; i<ComboList.size(); ++i )
{
Combo_t &prevcombo = ComboList[i-1];
Combo_t &combo = ComboList[i];
const float PrevComboEnd = prevcombo.fStartSecond + prevcombo.fSizeSeconds;
const float ThisComboStart = combo.fStartSecond;
if( fabsf(PrevComboEnd - ThisComboStart) > 0.001 )
continue;
Combo_t newcombo(combo);
newcombo.fStartSecond += fOtherFirstSecond;
ComboList[p].push_back( newcombo );
}
/* Merge identical combos. This normally only happens in course mode, when a combo
* continues between songs. */
for( unsigned i=1; i<ComboList[p].size(); ++i )
{
Combo_t &prevcombo = ComboList[p][i-1];
Combo_t &combo = ComboList[p][i];
const float PrevComboEnd = prevcombo.fStartSecond + prevcombo.fSizeSeconds;
const float ThisComboStart = combo.fStartSecond;
if( fabsf(PrevComboEnd - ThisComboStart) > 0.001 )
continue;
/* These are really the same combo. */
prevcombo.fSizeSeconds += combo.fSizeSeconds;
prevcombo.cnt += combo.cnt;
ComboList[p].erase( ComboList[p].begin()+i );
--i;
}
/* These are really the same combo. */
prevcombo.fSizeSeconds += combo.fSizeSeconds;
prevcombo.cnt += combo.cnt;
ComboList.erase( ComboList.begin()+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[pn] )
if( bFailedEarlier )
return GRADE_FAILED;
/* 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;
default: FAIL_M( ssprintf("%i", tns) ); break;
}
Actual += iTapNoteScores[pn][tns] * iTapScoreValue;
Possible += iTapNoteScores[pn][tns] * PREFSMAN->m_iGradeWeightMarvelous;
Actual += iTapNoteScores[tns] * iTapScoreValue;
Possible += iTapNoteScores[tns] * PREFSMAN->m_iGradeWeightMarvelous;
}
FOREACH_HoldNoteScore( hns )
@@ -191,8 +136,8 @@ Grade StageStats::GetGrade( PlayerNumber pn ) const
case HNS_OK: iHoldScoreValue = PREFSMAN->m_iGradeWeightOK; break;
default: FAIL_M( ssprintf("%i", hns) ); break;
}
Actual += iHoldNoteScores[pn][hns] * iHoldScoreValue;
Possible += iHoldNoteScores[pn][hns] * PREFSMAN->m_iGradeWeightOK;
Actual += iHoldNoteScores[hns] * iHoldScoreValue;
Possible += iHoldNoteScores[hns] * PREFSMAN->m_iGradeWeightOK;
}
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 );
if( PREFSMAN->m_bGradeTier02IsAllPerfects )
{
if( iTapNoteScores[pn][TNS_MARVELOUS] > 0 &&
iTapNoteScores[pn][TNS_PERFECT] == 0 &&
iTapNoteScores[pn][TNS_GREAT] == 0 &&
iTapNoteScores[pn][TNS_GOOD] == 0 &&
iTapNoteScores[pn][TNS_BOO] == 0 &&
iTapNoteScores[pn][TNS_MISS] == 0 &&
iTapNoteScores[pn][TNS_HIT_MINE] == 0 &&
iHoldNoteScores[pn][HNS_NG] == 0 )
if( iTapNoteScores[TNS_MARVELOUS] > 0 &&
iTapNoteScores[TNS_PERFECT] == 0 &&
iTapNoteScores[TNS_GREAT] == 0 &&
iTapNoteScores[TNS_GOOD] == 0 &&
iTapNoteScores[TNS_BOO] == 0 &&
iTapNoteScores[TNS_MISS] == 0 &&
iTapNoteScores[TNS_HIT_MINE] == 0 &&
iHoldNoteScores[HNS_NG] == 0 )
return GRADE_TIER_1;
if( iTapNoteScores[pn][TNS_PERFECT] > 0 &&
iTapNoteScores[pn][TNS_GREAT] == 0 &&
iTapNoteScores[pn][TNS_GOOD] == 0 &&
iTapNoteScores[pn][TNS_BOO] == 0 &&
iTapNoteScores[pn][TNS_MISS] == 0 &&
iTapNoteScores[pn][TNS_HIT_MINE] == 0 &&
iHoldNoteScores[pn][HNS_NG] == 0 )
if( iTapNoteScores[TNS_PERFECT] > 0 &&
iTapNoteScores[TNS_GREAT] == 0 &&
iTapNoteScores[TNS_GOOD] == 0 &&
iTapNoteScores[TNS_BOO] == 0 &&
iTapNoteScores[TNS_MISS] == 0 &&
iTapNoteScores[TNS_HIT_MINE] == 0 &&
iHoldNoteScores[HNS_NG] == 0 )
return GRADE_TIER_2;
return max( grade, GRADE_TIER_3 );
@@ -238,87 +183,144 @@ Grade StageStats::GetGrade( PlayerNumber pn ) const
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
{
FOREACH_PlayerNumber( p )
if( GAMESTATE->IsHumanPlayer(p) && !bFailed[p] )
if( GAMESTATE->IsHumanPlayer(p) && !m_player[p].bFailed )
return true;
return false;
}
bool StageStats::AllFailed() const
{
FOREACH_PlayerNumber( pn )
if( GAMESTATE->IsPlayerEnabled(pn) )
if( !bFailed[pn] )
return false;
FOREACH_EnabledPlayer( pn )
if( !m_player[pn].bFailed )
return false;
return true;
}
bool StageStats::AllFailedEarlier() const
{
FOREACH_PlayerNumber( p )
if( GAMESTATE->IsPlayerEnabled(p) && !bFailedEarlier[p] )
FOREACH_EnabledPlayer( p )
if( !m_player[p].bFailedEarlier )
return false;
return true;
}
float StageStats::GetPercentDancePoints( PlayerNumber pn ) const
float PlayerStageStats::GetPercentDancePoints() const
{
if( iPossibleDancePoints[pn] == 0 )
if( iPossibleDancePoints == 0 )
return 0; // div/0
if( iActualDancePoints[pn] == iPossibleDancePoints[pn] )
if( iActualDancePoints == iPossibleDancePoints )
return 1; // correct for rounding error
/* 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;
}
void StageStats::SetLifeRecordAt( PlayerNumber pn, float fLife, float fSecond )
void PlayerStageStats::SetLifeRecordAt( float fLife, float fSecond )
{
if( fSecond < 0 )
return;
fFirstSecond[pn] = min( fSecond, fFirstSecond[pn] );
fLastSecond[pn] = max( fSecond, fLastSecond[pn] );
//LOG->Trace( "fLastSecond = %f", fLastSecond[pn] );
fFirstSecond = min( fSecond, fFirstSecond );
fLastSecond = max( fSecond, fLastSecond );
//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 )
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. */
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. */
if( it != fLifeRecord[pn].begin() )
if( it != fLifeRecord.begin() )
--it;
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. */
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. */
map<float,float>::const_iterator earlier = later;
if( earlier != fLifeRecord[pn].begin() )
if( earlier != fLifeRecord.begin() )
--earlier;
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 )
{
float from = SCALE( i, 0, (float)iNumSamples, fFirstSecond[pn], fLastSecond[pn] );
fLifeOut[i] = GetLifeRecordLerpAt( pn, from );
float from = SCALE( i, 0, (float)iNumSamples, fFirstSecond, fLastSecond );
fLifeOut[i] = GetLifeRecordLerpAt( from );
}
}
/* 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. */
void StageStats::UpdateComboList( PlayerNumber pn, float fSecond, bool rollover )
void PlayerStageStats::UpdateComboList( float fSecond, bool rollover )
{
if( fSecond < 0 )
return;
if( !rollover )
{
fFirstSecond[pn] = min( fSecond, fFirstSecond[pn] );
fLastSecond[pn] = max( fSecond, fLastSecond[pn] );
//LOG->Trace( "fLastSecond = %f", fLastSecond[pn] );
fFirstSecond = min( fSecond, fFirstSecond );
fLastSecond = max( fSecond, fLastSecond );
//LOG->Trace( "fLastSecond = %f", fLastSecond );
}
int cnt = iCurCombo[pn];
int cnt = iCurCombo;
if( !cnt )
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
* combo, but missed the first step. Remove it. */
if( ComboList[pn].size() && ComboList[pn].back().fStartSecond == -9999 )
ComboList[pn].erase( ComboList[pn].begin()+ComboList[pn].size()-1, ComboList[pn].end() );
if( ComboList.size() && ComboList.back().fStartSecond == -9999 )
ComboList.erase( ComboList.begin()+ComboList.size()-1, ComboList.end() );
/* This is a new combo. */
Combo_t NewCombo;
@@ -374,10 +376,10 @@ void StageStats::UpdateComboList( PlayerNumber pn, float fSecond, bool rollover
NewCombo.fStartSecond = -9999;
else
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.cnt = cnt;
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
* 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();
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;
}
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;
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_MARVELOUS );
if( iHoldNoteScores[pn][HNS_NG] > 0 )
if( iHoldNoteScores[HNS_NG] > 0 )
return false;
for( int i=TNS_MISS; i<tnsAllGreaterOrEqual; i++ )
{
if( iTapNoteScores[pn][i] > 0 )
if( iTapNoteScores[i] > 0 )
return false;
}
return true;
}
bool StageStats::SingleDigitsOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const
bool PlayerStageStats::SingleDigitsOfScore( TapNoteScore tnsAllGreaterOrEqual ) const
{
return FullComboOfScore( pn, tnsAllGreaterOrEqual ) &&
iTapNoteScores[pn][tnsAllGreaterOrEqual] < 10;
return FullComboOfScore( tnsAllGreaterOrEqual ) &&
iTapNoteScores[tnsAllGreaterOrEqual] < 10;
}
bool StageStats::OneOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const
bool PlayerStageStats::OneOfScore( TapNoteScore tnsAllGreaterOrEqual ) const
{
return FullComboOfScore( pn, tnsAllGreaterOrEqual ) &&
iTapNoteScores[pn][tnsAllGreaterOrEqual] == 1;
return FullComboOfScore( tnsAllGreaterOrEqual ) &&
iTapNoteScores[tnsAllGreaterOrEqual] == 1;
}
int StageStats::GetTotalTaps( PlayerNumber pn ) const
int PlayerStageStats::GetTotalTaps() const
{
int iTotalTaps = 0;
for( int i=TNS_MISS; i<NUM_TAP_NOTE_SCORES; i++ )
{
iTotalTaps += iTapNoteScores[pn][i];
iTotalTaps += iTapNoteScores[i];
}
return iTotalTaps;
}
float StageStats::GetPercentageOfTaps( PlayerNumber pn, TapNoteScore tns ) const
float PlayerStageStats::GetPercentageOfTaps( TapNoteScore tns ) const
{
int iTotalTaps = 0;
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()
{
Grade g = NUM_GRADES;
FOREACH_EnabledPlayer( pn )
g = min( g, g_CurStageStats.GetGrade( pn ) );
g = min( g, g_CurStageStats.m_player[pn].GetGrade() );
return g;
}
@@ -472,7 +474,7 @@ static Grade GetWorstGrade()
{
Grade g = GRADE_TIER_1;
FOREACH_EnabledPlayer( pn )
g = max( g, g_CurStageStats.GetGrade( pn ) );
g = max( g, g_CurStageStats.m_player[pn].GetGrade() );
return g;
}
@@ -481,9 +483,9 @@ LuaFunction_NoArgs( GetStagesPlayed, (int) g_vPlayedStageStats.size() );
LuaFunction_NoArgs( GetBestGrade, GetBestGrade() );
LuaFunction_NoArgs( GetWorstGrade, GetWorstGrade() );
LuaFunction_NoArgs( OnePassed, g_CurStageStats.OnePassed() );
LuaFunction_PlayerNumber( FullCombo, g_CurStageStats.FullCombo(pn) )
LuaFunction_PlayerNumber( MaxCombo, g_CurStageStats.GetMaxCombo(pn).cnt )
LuaFunction_PlayerNumber( GetGrade, g_CurStageStats.GetGrade(pn) )
LuaFunction_PlayerNumber( FullCombo, g_CurStageStats.m_player[pn].FullCombo() )
LuaFunction_PlayerNumber( MaxCombo, g_CurStageStats.m_player[pn].GetMaxCombo().cnt )
LuaFunction_PlayerNumber( GetGrade, g_CurStageStats.m_player[pn].GetGrade() )
LuaFunction_Str( Grade, StringToGrade(str) );
const StageStats *GetStageStatsN( int n )
@@ -503,7 +505,7 @@ Grade GetGrade( int n, PlayerNumber pn )
const StageStats *pStats = GetStageStatsN( n );
if( pStats == NULL )
return GRADE_NO_DATA;
return pStats->GetGrade( pn );
return pStats->m_player[pn].GetGrade();
}
bool OneGotGrade( int n, Grade g )
@@ -524,7 +526,7 @@ Grade GetFinalGrade( PlayerNumber pn )
return GRADE_NO_DATA;
StageStats stats;
GAMESTATE->GetFinalEvalStats( stats );
return stats.GetGrade( pn );
return stats.m_player[pn].GetGrade();
}
LuaFunction_PlayerNumber( GetFinalGrade, GetFinalGrade(pn) );
@@ -535,7 +537,7 @@ Grade GetBestFinalGrade()
GAMESTATE->GetFinalEvalStats( stats );
FOREACH_PlayerNumber( 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;
}
LuaFunction_NoArgs( GetBestFinalGrade, GetBestFinalGrade() );
+65 -51
View File
@@ -12,59 +12,48 @@ class Song;
class Steps;
class Style;
struct StageStats
struct PlayerStageStats
{
StageStats() { Init(); }
PlayerStageStats() { Init(); }
void Init();
void AssertValid( PlayerNumber pn ) const;
void AddStats( const StageStats& other ); // accumulate
Grade GetGrade( PlayerNumber pn ) const;
bool OnePassed() const;
bool AllFailed() const;
bool AllFailedEarlier() const;
float GetPercentDancePoints( PlayerNumber pn ) const;
void AddStats( const PlayerStageStats& other ); // accumulate
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.
Grade GetGrade() const;
float GetPercentDancePoints() const;
vector<Steps*> vpSteps;
float fAliveSeconds; // how far into the music did they last before failing? Updated by Gameplay, scaled by music rate.
/* 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,
* 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
* point during the song. It's set in all fail modes. */
bool bFailedEarlier[NUM_PLAYERS];
int iPossibleDancePoints[NUM_PLAYERS];
int iActualDancePoints[NUM_PLAYERS];
int iTapNoteScores[NUM_PLAYERS][NUM_TAP_NOTE_SCORES];
int iHoldNoteScores[NUM_PLAYERS][NUM_HOLD_NOTE_SCORES];
int iCurCombo[NUM_PLAYERS];
int iMaxCombo[NUM_PLAYERS];
int iCurMissCombo[NUM_PLAYERS];
int iScore[NUM_PLAYERS];
int iBonus[NUM_PLAYERS]; // bonus to be added on screeneval
RadarValues radarPossible[NUM_PLAYERS]; // filled in by ScreenGameplay on start of notes
RadarValues radarActual[NUM_PLAYERS];
float fSecondsBeforeFail[NUM_PLAYERS]; // -1 means didn't/hasn't failed
bool bFailedEarlier;
int iPossibleDancePoints;
int iActualDancePoints;
int iTapNoteScores[NUM_TAP_NOTE_SCORES];
int iHoldNoteScores[NUM_HOLD_NOTE_SCORES];
int iCurCombo;
int iMaxCombo;
int iCurMissCombo;
int iScore;
int iBonus; // bonus to be added on screeneval
RadarValues radarPossible; // filled in by ScreenGameplay on start of notes
RadarValues radarActual;
float fSecondsBeforeFail; // -1 means didn't/hasn't failed
/* The number of songs played and passed, respectively. */
int iSongsPassed[NUM_PLAYERS];
int iSongsPlayed[NUM_PLAYERS];
int iTotalError[NUM_PLAYERS];
int iSongsPassed;
int iSongsPlayed;
int iTotalError;
map<float,float> fLifeRecord[NUM_PLAYERS];
void SetLifeRecordAt( PlayerNumber pn, float fLife, float fSecond );
void GetLifeRecord( PlayerNumber pn, float *fLifeOut, int iNumSamples ) const;
float GetLifeRecordAt( PlayerNumber pn, float fSecond ) const;
float GetLifeRecordLerpAt( PlayerNumber pn, float fSecond ) const;
map<float,float> fLifeRecord;
void SetLifeRecordAt( float fLife, float fSecond );
void GetLifeRecord( float *fLifeOut, int iNumSamples ) const;
float GetLifeRecordAt( float fSecond ) const;
float GetLifeRecordLerpAt( float fSecond ) const;
struct Combo_t
{
@@ -85,18 +74,43 @@ struct StageStats
Combo_t(): fStartSecond(0), fSizeSeconds(0), cnt(0), rollover(0) { }
bool IsZero() const { return fStartSecond < 0; }
};
vector<Combo_t> ComboList[NUM_PLAYERS];
float fFirstSecond[NUM_PLAYERS], fLastSecond[NUM_PLAYERS];
vector<Combo_t> ComboList;
float fFirstSecond;
float fLastSecond;
int GetComboAtStartOfStage( PlayerNumber pn ) const;
bool FullComboOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const;
bool FullCombo( PlayerNumber pn ) const { return FullComboOfScore(pn,TNS_GREAT); }
bool SingleDigitsOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const;
bool OneOfScore( PlayerNumber pn, TapNoteScore tnsAllGreaterOrEqual ) const;
int GetTotalTaps( PlayerNumber pn ) const;
float GetPercentageOfTaps( PlayerNumber pn, TapNoteScore tns ) const;
void UpdateComboList( PlayerNumber pn, float fSecond, bool rollover );
Combo_t GetMaxCombo( PlayerNumber pn ) const;
int GetComboAtStartOfStage() const;
bool FullComboOfScore( TapNoteScore tnsAllGreaterOrEqual ) const;
bool FullCombo() const { return FullComboOfScore(TNS_GREAT); }
bool SingleDigitsOfScore( TapNoteScore tnsAllGreaterOrEqual ) const;
bool OneOfScore( TapNoteScore tnsAllGreaterOrEqual ) const;
int GetTotalTaps() const;
float GetPercentageOfTaps( TapNoteScore tns ) const;
void UpdateComboList( float fSecond, bool rollover );
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];
};
/*