cleanup of statistics, saving of high scores
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
Fix
|
||||
/////////////////////////
|
||||
|
||||
change space so gray arrows aren't so small
|
||||
|
||||
groove radar goes wild when random selected
|
||||
|
||||
take out "it's a new record"
|
||||
|
||||
@@ -50,7 +50,6 @@ Course::Course()
|
||||
{
|
||||
m_MemCardScores[i][j][k].iDancePoints = 0;
|
||||
m_MemCardScores[i][j][k].fSurviveTime = 0;
|
||||
m_MemCardScores[i][j][k].sName = "STEP";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,10 +301,91 @@ int Course::GetNumStages() const
|
||||
return entries.size();
|
||||
}
|
||||
|
||||
|
||||
bool Course::IsNewMachineRecord( PlayerNumber pn, int iDancePoints, float fSurviveTime ) const // return true if this would be a new machine record
|
||||
{
|
||||
for( int i=0; i<NUM_HIGH_SCORE_LINES; i++ )
|
||||
{
|
||||
const MachineScore& hs = m_MachineScores[GAMESTATE->m_CurStyle][GAMESTATE->m_PreferredDifficulty[pn]][i];
|
||||
if( iDancePoints > hs.iDancePoints )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct MachineScoreAndPlayerNumber : public Course::MachineScore
|
||||
{
|
||||
PlayerNumber pn;
|
||||
|
||||
static int CompareDescending( const MachineScoreAndPlayerNumber &hs1, const MachineScoreAndPlayerNumber &hs2 )
|
||||
{
|
||||
if( hs1.iDancePoints > hs2.iDancePoints ) return -1;
|
||||
else if( hs1.iDancePoints == hs2.iDancePoints ) return 0;
|
||||
else return +1;
|
||||
}
|
||||
static void SortDescending( vector<MachineScoreAndPlayerNumber>& vHSout )
|
||||
{
|
||||
sort( vHSout.begin(), vHSout.end(), CompareDescending );
|
||||
}
|
||||
};
|
||||
|
||||
void Course::AddMachineRecord( int iDancePoints[NUM_PLAYERS], float fSurviveTime[NUM_PLAYERS], int iNewRecordIndexOut[NUM_PLAYERS] ) // set iNewRecordIndex = -1 if not a new record
|
||||
{
|
||||
vector<MachineScoreAndPlayerNumber> vHS;
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
iNewRecordIndexOut[p] = -1;
|
||||
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) )
|
||||
continue; // skip
|
||||
|
||||
MachineScoreAndPlayerNumber hs;
|
||||
hs.iDancePoints = iDancePoints[p];
|
||||
hs.fSurviveTime = fSurviveTime[p];
|
||||
hs.sName = ""; // this must be filled in later!
|
||||
hs.pn = (PlayerNumber)p;
|
||||
vHS.push_back( hs );
|
||||
}
|
||||
|
||||
// Sort descending before inserting.
|
||||
// This guarantees that a high score will not switch poitions on us when we later insert scores for the other player
|
||||
MachineScoreAndPlayerNumber::SortDescending( vHS );
|
||||
|
||||
for( unsigned i=0; i<vHS.size(); i++ )
|
||||
{
|
||||
MachineScoreAndPlayerNumber& newHS = vHS[i];
|
||||
MachineScore* machineScores = m_MachineScores[GAMESTATE->m_CurStyle][GAMESTATE->m_PreferredDifficulty[newHS.pn]];
|
||||
for( int i=0; i<NUM_HIGH_SCORE_LINES; i++ )
|
||||
{
|
||||
if( newHS.iDancePoints > machineScores[i].iDancePoints )
|
||||
{
|
||||
// We found the insert point. Shift down.
|
||||
for( int j=i+1; j<NUM_HIGH_SCORE_LINES; j++ )
|
||||
machineScores[j] = machineScores[j-1];
|
||||
// insert
|
||||
machineScores[i] = newHS;
|
||||
iNewRecordIndexOut[newHS.pn] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Course::AddMemCardRecord( PlayerNumber pn, int iDancePoints, float fSurviveTime ) // return true if new record
|
||||
{
|
||||
MemCardScore& hs = m_MemCardScores[GAMESTATE->m_CurStyle][GAMESTATE->m_PreferredDifficulty[pn]][pn];
|
||||
if( iDancePoints > hs.iDancePoints )
|
||||
{
|
||||
hs.iDancePoints = iDancePoints;
|
||||
hs.fSurviveTime = fSurviveTime;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Sorting stuff
|
||||
//
|
||||
|
||||
static int CompareCoursePointersByDifficulty(const Course* pCourse1, const Course* pCourse2)
|
||||
{
|
||||
return pCourse1->GetNumStages() < pCourse2->GetNumStages();
|
||||
|
||||
+14
-4
@@ -60,14 +60,24 @@ public:
|
||||
// Statistics
|
||||
int m_iNumTimesPlayed;
|
||||
|
||||
struct HighScore
|
||||
struct MachineScore
|
||||
{
|
||||
int iDancePoints;
|
||||
float fSurviveTime;
|
||||
CString sName;
|
||||
};
|
||||
HighScore m_MachineScores[NUM_STYLES][NUM_DIFFICULTIES][NUM_HIGH_SCORE_LINES]; // sorted highest to lowest by iDancePoints
|
||||
HighScore m_MemCardScores[NUM_STYLES][NUM_DIFFICULTIES][NUM_PLAYERS];
|
||||
} m_MachineScores[NUM_STYLES][NUM_DIFFICULTIES][NUM_HIGH_SCORE_LINES]; // sorted highest to lowest by iDancePoints
|
||||
|
||||
bool IsNewMachineRecord( PlayerNumber pn, int iDancePoints, float fSurviveTime ) const; // return true if this is would be a new machine record
|
||||
void AddMachineRecord( int iDancePoints[NUM_PLAYERS], float fSurviveTime[NUM_PLAYERS], int iNewRecordIndexOut[NUM_PLAYERS] ); // set iNewRecordIndex = -1 if not a new record
|
||||
|
||||
struct MemCardScore
|
||||
{
|
||||
int iDancePoints;
|
||||
float fSurviveTime;
|
||||
} m_MemCardScores[NUM_STYLES][NUM_DIFFICULTIES][NUM_PLAYERS];
|
||||
|
||||
bool AddMemCardRecord( PlayerNumber pn, int iDancePoints, float fSurviveTime ); // return true if this is a new record
|
||||
|
||||
|
||||
private:
|
||||
void Shuffle();
|
||||
|
||||
@@ -55,3 +55,15 @@ RageColor PlayerToColor( int p )
|
||||
{
|
||||
return PlayerToColor( (PlayerNumber)p );
|
||||
}
|
||||
|
||||
|
||||
HighScoreCategory AverageMeterToHighScoreCategory( float fAverageMeter )
|
||||
{
|
||||
if( fAverageMeter <= 3 ) return CATEGORY_A;
|
||||
else if( fAverageMeter <= 6 ) return CATEGORY_B;
|
||||
else if( fAverageMeter <= 9 ) return CATEGORY_C;
|
||||
else return CATEGORY_D;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -116,9 +116,9 @@ enum SongSortOrder {
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////
|
||||
//
|
||||
// Scoring stuff
|
||||
///////////////////////////
|
||||
//
|
||||
|
||||
enum TapNoteScore {
|
||||
TNS_NONE,
|
||||
@@ -174,16 +174,19 @@ inline int HoldNoteScoreToDancePoints( HoldNoteScore hns )
|
||||
|
||||
|
||||
//
|
||||
// High Score types
|
||||
// High Score stuff
|
||||
//
|
||||
enum SongHighScoreCategory
|
||||
enum HighScoreCategory
|
||||
{
|
||||
CATEGORY_A, // 1-3 meter per song avg.
|
||||
CATEGORY_B, // 4-6 meter per song avg.
|
||||
CATEGORY_C, // 7-9 meter per song avg.
|
||||
CATEGORY_D, // 10+ meter per song avg.
|
||||
CATEGORY_D, // 10+ meter per song avg. // doesn't count extra stage!
|
||||
NUM_HIGH_SCORE_CATEGORIES
|
||||
};
|
||||
|
||||
HighScoreCategory AverageMeterToHighScoreCategory( float fAverageMeter );
|
||||
|
||||
const int NUM_HIGH_SCORE_LINES = 5;
|
||||
|
||||
#endif
|
||||
|
||||
+31
-151
@@ -67,68 +67,18 @@ void GameState::Reset()
|
||||
m_bDemonstration = false;
|
||||
m_iCurrentStageIndex = 0;
|
||||
|
||||
|
||||
m_pCurSong = NULL;
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
m_pCurNotes[p] = NULL;
|
||||
m_pCurCourse = NULL;
|
||||
|
||||
|
||||
m_fMusicSeconds = 0;
|
||||
m_fSongBeat = 0;
|
||||
m_fCurBPS = 0;
|
||||
m_bFreeze = 0;
|
||||
|
||||
|
||||
m_apSongsPlayed.clear();
|
||||
|
||||
m_iSongsIntoCourse = 0;
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
m_fSecondsBeforeFail[p] = -1;
|
||||
m_iSongsBeforeFail[p] = 0;
|
||||
}
|
||||
|
||||
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
int s;
|
||||
|
||||
m_iPossibleDancePoints[p] = 0;
|
||||
m_iActualDancePoints[p] = 0;
|
||||
for( s=0; s<NUM_TAP_NOTE_SCORES; s++ )
|
||||
m_TapNoteScores[p][s] = 0;
|
||||
for( s=0; s<NUM_HOLD_NOTE_SCORES; s++ )
|
||||
m_HoldNoteScores[p][s] = 0;
|
||||
m_iMaxCombo[p] = 0;
|
||||
m_fScore[p] = 0;
|
||||
|
||||
for( int r=0; r<NUM_RADAR_VALUES; r++ )
|
||||
{
|
||||
m_fRadarPossible[p][r] = 0;
|
||||
m_fRadarActual[p][r] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
int s;
|
||||
|
||||
m_iAccumPossibleDancePoints[p] = 0;
|
||||
m_iAccumActualDancePoints[p] = 0;
|
||||
for( s=0; s<NUM_TAP_NOTE_SCORES; s++ )
|
||||
m_AccumTapNoteScores[p][s] = 0;
|
||||
for( s=0; s<NUM_HOLD_NOTE_SCORES; s++ )
|
||||
m_AccumHoldNoteScores[p][s] = 0;
|
||||
m_iAccumMaxCombo[p] = 0;
|
||||
m_fAccumScore[p] = 0;
|
||||
for( int r=0; r<NUM_RADAR_VALUES; r++ )
|
||||
{
|
||||
m_fAccumRadarPossible[p][r] = 0;
|
||||
m_fAccumRadarActual[p][r] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
m_CurStageStats = StageStats();
|
||||
m_vPassedStageStats.clear();
|
||||
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
m_PlayerOptions[p] = PlayerOptions();
|
||||
@@ -143,65 +93,6 @@ void GameState::ResetMusicStatistics()
|
||||
m_bFreeze = false;
|
||||
}
|
||||
|
||||
void GameState::AccumulateStageStatistics()
|
||||
{
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
int s;
|
||||
|
||||
m_iAccumPossibleDancePoints[p] += m_iPossibleDancePoints[p];
|
||||
m_iAccumActualDancePoints[p] += m_iActualDancePoints[p];
|
||||
for( s=0; s<NUM_TAP_NOTE_SCORES; s++ )
|
||||
m_AccumTapNoteScores[p][s] += m_TapNoteScores[p][s];
|
||||
for( s=0; s<NUM_HOLD_NOTE_SCORES; s++ )
|
||||
m_AccumHoldNoteScores[p][s] += m_HoldNoteScores[p][s];
|
||||
m_iAccumMaxCombo[p] += m_iMaxCombo[p];
|
||||
m_fAccumScore[p] += m_fScore[p];
|
||||
for( int r=0; r<NUM_RADAR_VALUES; r++ )
|
||||
{
|
||||
m_fAccumRadarPossible[p][r] = m_fRadarPossible[p][r];
|
||||
m_fAccumRadarActual[p][r] = m_fRadarActual[p][r];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameState::ResetStageStatistics()
|
||||
{
|
||||
m_iSongsIntoCourse = 0;
|
||||
|
||||
switch( m_PlayMode )
|
||||
{
|
||||
case PLAY_MODE_NONSTOP:
|
||||
case PLAY_MODE_ONI:
|
||||
case PLAY_MODE_ENDLESS:
|
||||
m_apSongsPlayed.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
int s;
|
||||
|
||||
m_iSongsBeforeFail[p] = 0;
|
||||
m_fSecondsBeforeFail[p] = -1;
|
||||
|
||||
m_iPossibleDancePoints[p] = 0;
|
||||
m_iActualDancePoints[p] = 0;
|
||||
for( s=0; s<NUM_TAP_NOTE_SCORES; s++ )
|
||||
m_TapNoteScores[p][s] = 0;
|
||||
for( s=0; s<NUM_HOLD_NOTE_SCORES; s++ )
|
||||
m_HoldNoteScores[p][s] = 0;
|
||||
m_iMaxCombo[p] = 0;
|
||||
m_fScore[p] = 0;
|
||||
for( int r=0; r<NUM_RADAR_VALUES; r++ )
|
||||
{
|
||||
m_fRadarPossible[p][r] = 0;
|
||||
m_fRadarActual[p][r] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int GameState::GetStageIndex()
|
||||
{
|
||||
return m_iCurrentStageIndex;
|
||||
@@ -299,38 +190,11 @@ bool GameState::IsPlayerEnabled( PlayerNumber pn )
|
||||
}
|
||||
}
|
||||
|
||||
float GameState::GetElapsedSeconds()
|
||||
{
|
||||
switch( m_PlayMode )
|
||||
{
|
||||
case PLAY_MODE_ARCADE:
|
||||
return max( 0, m_fMusicSeconds );
|
||||
case PLAY_MODE_ONI:
|
||||
case PLAY_MODE_ENDLESS:
|
||||
{
|
||||
float fSecondsTotal = 0;
|
||||
for( unsigned i=0; i<m_apSongsPlayed.size(); i++ )
|
||||
fSecondsTotal += m_apSongsPlayed[i]->m_fMusicLengthSeconds;
|
||||
fSecondsTotal += max( 0, m_fMusicSeconds );
|
||||
return fSecondsTotal;
|
||||
}
|
||||
default:
|
||||
ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float GameState::GetPlayerSurviveTime( PlayerNumber pn )
|
||||
{
|
||||
if( m_fSecondsBeforeFail[pn] == -1 ) // haven't failed yet
|
||||
return GetElapsedSeconds();
|
||||
else
|
||||
return m_fSecondsBeforeFail[pn];
|
||||
}
|
||||
|
||||
Grade GameState::GetCurrentGrade( PlayerNumber pn )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled(pn) || GAMESTATE->m_fSecondsBeforeFail[pn] != -1 )
|
||||
ASSERT( GAMESTATE->IsPlayerEnabled(pn) ); // should be calling this is player isn't joined!
|
||||
|
||||
if( m_CurStageStats.bFailed[pn] )
|
||||
return GRADE_E;
|
||||
|
||||
/* Based on the percentage of your total "Dance Points" to the maximum
|
||||
@@ -344,19 +208,19 @@ Grade GameState::GetCurrentGrade( PlayerNumber pn )
|
||||
* Less - D
|
||||
* Fail - E
|
||||
*/
|
||||
float fPercentDancePoints = m_iActualDancePoints[pn] / (float)m_iPossibleDancePoints[pn];
|
||||
fPercentDancePoints = max( fPercentDancePoints, 0 );
|
||||
LOG->Trace( "iActualDancePoints: %i", m_iActualDancePoints[pn] );
|
||||
LOG->Trace( "iPossibleDancePoints: %i", m_iPossibleDancePoints[pn] );
|
||||
float fPercentDancePoints = m_CurStageStats.iActualDancePoints[pn] / (float)m_CurStageStats.iPossibleDancePoints[pn];
|
||||
fPercentDancePoints = max( 0, fPercentDancePoints );
|
||||
LOG->Trace( "iActualDancePoints: %i", m_CurStageStats.iActualDancePoints[pn] );
|
||||
LOG->Trace( "iPossibleDancePoints: %i", m_CurStageStats.iPossibleDancePoints[pn] );
|
||||
LOG->Trace( "fPercentDancePoints: %f", fPercentDancePoints );
|
||||
|
||||
// check for "AAAA"
|
||||
if( m_TapNoteScores[pn][TNS_MARVELOUS] > 0 &&
|
||||
m_TapNoteScores[pn][TNS_PERFECT] == 0 &&
|
||||
m_TapNoteScores[pn][TNS_GREAT] == 0 &&
|
||||
m_TapNoteScores[pn][TNS_GOOD] == 0 &&
|
||||
m_TapNoteScores[pn][TNS_BOO] == 0 &&
|
||||
m_TapNoteScores[pn][TNS_MISS] == 0 )
|
||||
if( m_CurStageStats.iTapNoteScores[pn][TNS_MARVELOUS] > 0 &&
|
||||
m_CurStageStats.iTapNoteScores[pn][TNS_PERFECT] == 0 &&
|
||||
m_CurStageStats.iTapNoteScores[pn][TNS_GREAT] == 0 &&
|
||||
m_CurStageStats.iTapNoteScores[pn][TNS_GOOD] == 0 &&
|
||||
m_CurStageStats.iTapNoteScores[pn][TNS_BOO] == 0 &&
|
||||
m_CurStageStats.iTapNoteScores[pn][TNS_MISS] == 0 )
|
||||
return GRADE_AAAA;
|
||||
|
||||
if ( fPercentDancePoints == 1.00 ) return GRADE_AAA;
|
||||
@@ -366,3 +230,19 @@ Grade GameState::GetCurrentGrade( PlayerNumber pn )
|
||||
else if( fPercentDancePoints >= 0.45 ) return GRADE_C;
|
||||
else return GRADE_D;
|
||||
}
|
||||
|
||||
bool GameState::HasEarnedExtraStage()
|
||||
{
|
||||
if( (GAMESTATE->IsFinalStage() || GAMESTATE->IsExtraStage()) )
|
||||
{
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) )
|
||||
continue; // skip
|
||||
|
||||
if( GAMESTATE->m_pCurNotes[p]->GetDifficulty()==DIFFICULTY_HARD && GetCurrentGrade((PlayerNumber)p)==GRADE_AA )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
+18
-56
@@ -17,6 +17,7 @@
|
||||
#include "Game.h"
|
||||
#include "Style.h"
|
||||
#include "Grade.h"
|
||||
#include "StageStats.h"
|
||||
|
||||
|
||||
class Song;
|
||||
@@ -39,13 +40,13 @@ public:
|
||||
Game m_CurGame;
|
||||
Style m_CurStyle;
|
||||
bool m_bPlayersCanJoin; // true if it's not too late for a player to join - this only has an effect on the credits message
|
||||
bool m_bSideIsJoined[2]; // left side, right side
|
||||
int m_iCoins;
|
||||
PlayerNumber m_MasterPlayerNumber;
|
||||
bool m_bSideIsJoined[NUM_PLAYERS]; // left side, right side
|
||||
int m_iCoins; // not "credits"
|
||||
PlayerNumber m_MasterPlayerNumber; // used in Styles where one player controls both sides
|
||||
int GetNumSidesJoined()
|
||||
{
|
||||
int iNumSidesJoined = 0;
|
||||
for( int c=0; c<2; c++ )
|
||||
for( int c=0; c<NUM_PLAYERS; c++ )
|
||||
if( m_bSideIsJoined[c] )
|
||||
iNumSidesJoined++; // left side, and right side
|
||||
return iNumSidesJoined;
|
||||
@@ -58,11 +59,11 @@ public:
|
||||
bool IsPlayerEnabled( PlayerNumber pn );
|
||||
bool IsPlayerEnabled( int p ) { return IsPlayerEnabled( (PlayerNumber)p ); }; // for those too lasy to cast all those p's to a PlayerNumber
|
||||
|
||||
CString m_sLoadingMessage;
|
||||
CString m_sPreferredGroup;
|
||||
CString m_sLoadingMessage; // used in loading screen
|
||||
CString m_sPreferredGroup; // "ALL MUSIC" denotes no preferred group
|
||||
Difficulty m_PreferredDifficulty[NUM_PLAYERS];
|
||||
SongSortOrder m_SongSortOrder; // used by MusicWheel
|
||||
PlayMode m_PlayMode;
|
||||
PlayMode m_PlayMode; // many screen display different info depending on this value
|
||||
bool m_bEditing; // NoteField does special stuff when this is true
|
||||
bool m_bDemonstration; // ScreenGameplay does special stuff when this is true
|
||||
int m_iCurrentStageIndex; // incremented on Eval screen
|
||||
@@ -83,7 +84,7 @@ public:
|
||||
|
||||
|
||||
//
|
||||
// Music statistic: Arcade: the current stage (one song). Oni/Endles: a single song in a course
|
||||
// Music statistics: Arcade: the current stage (one song). Oni/Endles: a single song in a course
|
||||
//
|
||||
// Let a lot of classes access this info here so the don't have to keep their own copies.
|
||||
//
|
||||
@@ -95,55 +96,16 @@ public:
|
||||
void ResetMusicStatistics(); // Call this when it's time to play a new song. Clears the values above.
|
||||
|
||||
//
|
||||
// Stage Statistics: Arcade: for the current stage (one song). Oni/Endless: for current course (multiple songs)
|
||||
// Stage Statistics:
|
||||
// Arcade: for the current stage (one song).
|
||||
// Nonstop/Oni/Endless: for current course (which usually contains multiple songs)
|
||||
//
|
||||
int m_iPossibleDancePoints[NUM_PLAYERS];
|
||||
int m_iActualDancePoints[NUM_PLAYERS];
|
||||
int m_TapNoteScores[NUM_PLAYERS][NUM_TAP_NOTE_SCORES];
|
||||
int m_HoldNoteScores[NUM_PLAYERS][NUM_HOLD_NOTE_SCORES];
|
||||
int m_iMaxCombo[NUM_PLAYERS];
|
||||
float m_fScore[NUM_PLAYERS];
|
||||
float m_fRadarPossible[NUM_PLAYERS][NUM_RADAR_VALUES]; // filled in by ScreenGameplay on end of notes
|
||||
float m_fRadarActual[NUM_PLAYERS][NUM_RADAR_VALUES]; // filled in by ScreenGameplay on end of notes
|
||||
|
||||
float GetElapsedSeconds(); // Arcade: time into current song. Oni/Endless: time into current course
|
||||
StageStats m_CurStageStats; // current stage (not necessarily passed if Extra Stage)
|
||||
vector<StageStats> m_vPassedStageStats; // Only useful in Arcade for final evaluation
|
||||
// A song is only inserted here if at least one player passed.
|
||||
// StageStats are added by the Evaluation screen
|
||||
Grade GetCurrentGrade( PlayerNumber pn ); // grade so far
|
||||
|
||||
Grade GetCurrentGrade( PlayerNumber pn );
|
||||
|
||||
int m_iSongsIntoCourse; // In Arcade, this value is meaningless.
|
||||
// In Oni and Endless, this is the number of songs played in the current course.
|
||||
int m_iSongsBeforeFail[NUM_PLAYERS]; // In Arcade, this value is meaningless.
|
||||
// In Oni and Endless, this is the number of songs played before failing.
|
||||
float m_fSecondsBeforeFail[NUM_PLAYERS];// -1 means not yet failed
|
||||
// In Arcade, is the time into the current stage before failing.
|
||||
// In Oni and Endless this is the time into the current course before failing
|
||||
|
||||
float GetPlayerSurviveTime( PlayerNumber pn ); // Returns time player has survived
|
||||
|
||||
void AccumulateStageStatistics(); // Call this before clearing values. Accumulate values above into the Session values below.
|
||||
void ResetStageStatistics(); // Clears the values above
|
||||
|
||||
|
||||
//
|
||||
// Session Statistics: Arcade: 3 songs. Oni/Endless: one course.
|
||||
//
|
||||
vector<Song*> m_apSongsPlayed; // an array of completed songs.
|
||||
// This is useful for the final evaluation screen,
|
||||
// and used to calculate the time into a course
|
||||
|
||||
// Only used in final evaluation screen in play mode Arcade.
|
||||
// Before being displayed, these values should be normalized by dividing by number of stages
|
||||
int m_iAccumPossibleDancePoints[NUM_PLAYERS];
|
||||
int m_iAccumActualDancePoints[NUM_PLAYERS];
|
||||
int m_AccumTapNoteScores[NUM_PLAYERS][NUM_TAP_NOTE_SCORES];
|
||||
int m_AccumHoldNoteScores[NUM_PLAYERS][NUM_HOLD_NOTE_SCORES];
|
||||
int m_iAccumMaxCombo[NUM_PLAYERS];
|
||||
float m_fAccumScore[NUM_PLAYERS];
|
||||
float m_fAccumRadarPossible[NUM_PLAYERS][NUM_RADAR_VALUES];
|
||||
float m_fAccumRadarActual[NUM_PLAYERS][NUM_RADAR_VALUES];
|
||||
|
||||
|
||||
// Session statistics are cleared by calling Reset()
|
||||
|
||||
PlayerOptions m_PlayerOptions[NUM_PLAYERS]; // The currently active options
|
||||
PlayerOptions m_SelectedOptions[NUM_PLAYERS]; // Keep track of player-selected options for
|
||||
@@ -151,7 +113,7 @@ public:
|
||||
SongOptions m_SongOptions;
|
||||
|
||||
|
||||
vector<CString> m_asNetworkNames;
|
||||
bool HasEarnedExtraStage();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
virtual void Load( PlayerNumber pn ) { m_PlayerNumber = pn; }
|
||||
virtual void Update( float fDeltaTime ) { ActorFrame::Update(fDeltaTime); };
|
||||
|
||||
virtual void SongEnded() {};
|
||||
virtual void OnSongEnded() {};
|
||||
/* Change life after receiving a tap note grade. This *is* called for
|
||||
* the head of hold notes. */
|
||||
virtual void ChangeLife( TapNoteScore score ) = 0;
|
||||
|
||||
@@ -83,7 +83,7 @@ void LifeMeterBattery::Load( PlayerNumber pn )
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void LifeMeterBattery::SongEnded()
|
||||
void LifeMeterBattery::OnSongEnded()
|
||||
{
|
||||
if( m_bFailedEarlier )
|
||||
return;
|
||||
@@ -145,8 +145,8 @@ void LifeMeterBattery::ChangeLife( HoldNoteScore score, TapNoteScore tscore )
|
||||
|
||||
void LifeMeterBattery::OnDancePointsChange()
|
||||
{
|
||||
int iActualDancePoints = GAMESTATE->m_iActualDancePoints[m_PlayerNumber];
|
||||
int iPossibleDancePoints = GAMESTATE->m_iPossibleDancePoints[m_PlayerNumber];
|
||||
int iActualDancePoints = GAMESTATE->m_CurStageStats.iActualDancePoints[m_PlayerNumber];
|
||||
int iPossibleDancePoints = GAMESTATE->m_CurStageStats.iPossibleDancePoints[m_PlayerNumber];
|
||||
iPossibleDancePoints = max( 1, iPossibleDancePoints );
|
||||
float fPercentDancePoints = iActualDancePoints / (float)iPossibleDancePoints + 0.00001f; // correct for rounding errors
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
|
||||
virtual void Update( float fDeltaTime );
|
||||
|
||||
virtual void SongEnded();
|
||||
virtual void OnSongEnded();
|
||||
virtual void ChangeLife( TapNoteScore score );
|
||||
virtual void ChangeLife( HoldNoteScore score, TapNoteScore tscore );
|
||||
virtual void OnDancePointsChange(); // look in GAMESTATE and update the display
|
||||
|
||||
@@ -52,7 +52,7 @@ Notes::Notes()
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
m_MemCardScores[p].grade = GRADE_NO_DATA;
|
||||
m_MemCardScores[p].iScore = 0;
|
||||
m_MemCardScores[p].fScore = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,11 +313,11 @@ void Notes::SetRadarValue(int r, float val)
|
||||
m_fRadarValues[r] = val;
|
||||
}
|
||||
|
||||
bool Notes::AddMemCardScore( PlayerNumber pn, Grade grade, int iScore ) // return true if new high score
|
||||
bool Notes::AddMemCardRecord( PlayerNumber pn, Grade grade, float fScore ) // return true if new high score
|
||||
{
|
||||
if( iScore > m_MemCardScores[pn].iScore )
|
||||
if( fScore > m_MemCardScores[pn].fScore )
|
||||
{
|
||||
m_MemCardScores[pn].iScore = iScore;
|
||||
m_MemCardScores[pn].fScore = fScore;
|
||||
m_MemCardScores[pn].grade = grade;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -52,14 +52,13 @@ public:
|
||||
// High scores;
|
||||
int m_iNumTimesPlayed;
|
||||
|
||||
struct HighScore
|
||||
struct MemCardScore
|
||||
{
|
||||
Grade grade;
|
||||
int iScore;
|
||||
};
|
||||
HighScore m_MemCardScores[NUM_PLAYERS];
|
||||
float fScore;
|
||||
} m_MemCardScores[NUM_PLAYERS];
|
||||
|
||||
bool AddMemCardScore( PlayerNumber pn, Grade grade, int iScore ); // return true if new high score
|
||||
bool AddMemCardRecord( PlayerNumber pn, Grade grade, float fScore ); // return true if new high score
|
||||
|
||||
|
||||
void TidyUpData();
|
||||
|
||||
@@ -136,7 +136,7 @@ void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDi
|
||||
|
||||
// copy note data
|
||||
this->CopyAll( pNoteData );
|
||||
if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && GAMESTATE->m_fSecondsBeforeFail[m_PlayerNumber] != -1 ) // Oni dead
|
||||
if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && GAMESTATE->m_CurStageStats.bFailed ) // Oni dead
|
||||
this->ClearAll();
|
||||
|
||||
/* The editor reuses Players ... so we really need to make sure everything
|
||||
@@ -341,7 +341,7 @@ void Player::DrawPrimitives()
|
||||
|
||||
void Player::Step( int col )
|
||||
{
|
||||
if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && GAMESTATE->m_fSecondsBeforeFail[m_PlayerNumber] != -1 ) // Oni dead
|
||||
if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && GAMESTATE->m_CurStageStats.bFailed[m_PlayerNumber] ) // Oni dead
|
||||
return; // do nothing
|
||||
|
||||
//LOG->Trace( "Player::HandlePlayerStep()" );
|
||||
@@ -518,7 +518,7 @@ void Player::OnRowDestroyed( int iIndexThatWasSteppedOn )
|
||||
{
|
||||
HandleNoteScore( score, iNumNotesInThisRow ); // update score
|
||||
m_Combo.UpdateScore( score, iNumNotesInThisRow );
|
||||
GAMESTATE->m_iMaxCombo[m_PlayerNumber] = max( GAMESTATE->m_iMaxCombo[m_PlayerNumber], m_Combo.GetCurrentCombo() );
|
||||
GAMESTATE->m_CurStageStats.iMaxCombo[m_PlayerNumber] = max( GAMESTATE->m_CurStageStats.iMaxCombo[m_PlayerNumber], m_Combo.GetCurrentCombo() );
|
||||
}
|
||||
|
||||
// update the judgement, score, and life
|
||||
@@ -616,7 +616,7 @@ void Player::HandleNoteScore( TapNoteScore score, int iNumTapsInRow )
|
||||
m_ScoreKeeper->HandleNoteScore(score, iNumTapsInRow);
|
||||
|
||||
if (m_pScore)
|
||||
m_pScore->SetScore(GAMESTATE->m_fScore[m_PlayerNumber]);
|
||||
m_pScore->SetScore(GAMESTATE->m_CurStageStats.fScore[m_PlayerNumber]);
|
||||
|
||||
if( m_pLifeMeter ) {
|
||||
m_pLifeMeter->ChangeLife( score );
|
||||
@@ -636,7 +636,7 @@ void Player::HandleHoldNoteScore( HoldNoteScore score, TapNoteScore TapNoteScore
|
||||
}
|
||||
|
||||
if (m_pScore)
|
||||
m_pScore->SetScore(GAMESTATE->m_fScore[m_PlayerNumber]);
|
||||
m_pScore->SetScore(GAMESTATE->m_CurStageStats.fScore[m_PlayerNumber]);
|
||||
|
||||
if( m_pLifeMeter ) {
|
||||
if( score == HNS_NG ) {
|
||||
|
||||
@@ -54,11 +54,11 @@ PrefsManager::PrefsManager()
|
||||
m_iNumArcadeStages = 3;
|
||||
m_bAutoPlay = false;
|
||||
m_fJudgeWindowScale = 1.0f;
|
||||
m_fJudgeWindowMarvelousSeconds = 0.023f;
|
||||
m_fJudgeWindowPerfectSeconds = 0.043f;
|
||||
m_fJudgeWindowGreatSeconds = 0.086f;
|
||||
m_fJudgeWindowGoodSeconds = 0.129f;
|
||||
m_fJudgeWindowBooSeconds = 0.172f;
|
||||
m_fJudgeWindowMarvelousSeconds = 0.025f;
|
||||
m_fJudgeWindowPerfectSeconds = 0.05f;
|
||||
m_fJudgeWindowGreatSeconds = 0.10f;
|
||||
m_fJudgeWindowGoodSeconds = 0.15f;
|
||||
m_fJudgeWindowBooSeconds = 0.2f;
|
||||
m_fLifeDifficultyScale = 1.0f;
|
||||
m_iMovieDecodeMS = 2;
|
||||
m_bUseBGIfNoBanner = false;
|
||||
@@ -119,9 +119,11 @@ void PrefsManager::ReadGlobalPrefsFromDisk( bool bSwitchToLastPlayedGame )
|
||||
ini.GetValueI( "Options", "NumArcadeStages", m_iNumArcadeStages );
|
||||
ini.GetValueB( "Options", "AutoPlay", m_bAutoPlay );
|
||||
ini.GetValueF( "Options", "JudgeWindowScale", m_fJudgeWindowScale );
|
||||
ini.GetValueF( "Options", "JudgeWindowMarvelousSeconds",m_fJudgeWindowMarvelousSeconds );
|
||||
ini.GetValueF( "Options", "JudgeWindowPerfectSeconds", m_fJudgeWindowPerfectSeconds );
|
||||
ini.GetValueF( "Options", "JudgeWindowGreatSeconds", m_fJudgeWindowGreatSeconds );
|
||||
ini.GetValueF( "Options", "JudgeWindowGoodSeconds", m_fJudgeWindowGoodSeconds );
|
||||
ini.GetValueF( "Options", "JudgeWindowBooSeconds", m_fJudgeWindowBooSeconds );
|
||||
ini.GetValueF( "Options", "LifeDifficultyScale", m_fLifeDifficultyScale );
|
||||
ini.GetValueI( "Options", "MovieDecodeMS", m_iMovieDecodeMS );
|
||||
ini.GetValueB( "Options", "UseBGIfNoBanner", m_bUseBGIfNoBanner );
|
||||
@@ -184,9 +186,11 @@ void PrefsManager::SaveGlobalPrefsToDisk()
|
||||
ini.SetValueI( "Options", "NumArcadeStages", m_iNumArcadeStages );
|
||||
ini.SetValueB( "Options", "AutoPlay", m_bAutoPlay );
|
||||
ini.SetValueF( "Options", "JudgeWindowScale", m_fJudgeWindowScale );
|
||||
ini.SetValueF( "Options", "JudgeWindowMarvelousSeconds",m_fJudgeWindowMarvelousSeconds );
|
||||
ini.SetValueF( "Options", "JudgeWindowPerfectSeconds", m_fJudgeWindowPerfectSeconds );
|
||||
ini.SetValueF( "Options", "JudgeWindowGreatSeconds", m_fJudgeWindowGreatSeconds );
|
||||
ini.SetValueF( "Options", "JudgeWindowGoodSeconds", m_fJudgeWindowGoodSeconds );
|
||||
ini.SetValueF( "Options", "JudgeWindowBooSeconds", m_fJudgeWindowBooSeconds );
|
||||
ini.SetValueF( "Options", "LifeDifficultyScale", m_fLifeDifficultyScale );
|
||||
ini.SetValueI( "Options", "MovieDecodeMS", m_iMovieDecodeMS );
|
||||
ini.SetValueB( "Options", "UseBGIfNoBanner", m_bUseBGIfNoBanner );
|
||||
|
||||
@@ -50,7 +50,7 @@ void ScoreDisplayOni::Draw()
|
||||
{
|
||||
float fSecsIntoPlay;
|
||||
if( GAMESTATE->IsPlayerEnabled(m_PlayerNumber) )
|
||||
fSecsIntoPlay = GAMESTATE->GetPlayerSurviveTime(m_PlayerNumber);
|
||||
fSecsIntoPlay = GAMESTATE->m_CurStageStats.fAliveSeconds[m_PlayerNumber];
|
||||
else
|
||||
fSecsIntoPlay = 0;
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ void ScoreKeeperMAX2::AddScore( TapNoteScore score )
|
||||
|
||||
ASSERT(m_lScore >= 0);
|
||||
|
||||
GAMESTATE->m_fScore[m_PlayerNumber] = m_lScore * m_fScoreMultiplier;
|
||||
GAMESTATE->m_CurStageStats.fScore[m_PlayerNumber] = m_lScore * m_fScoreMultiplier;
|
||||
}
|
||||
|
||||
void ScoreKeeperMAX2::HandleNoteScore( TapNoteScore score, int iNumTapsInRow )
|
||||
@@ -52,8 +52,8 @@ void ScoreKeeperMAX2::HandleNoteScore( TapNoteScore score, int iNumTapsInRow )
|
||||
ASSERT( iNumTapsInRow >= 1 );
|
||||
|
||||
// update dance points for Oni lifemeter
|
||||
GAMESTATE->m_iActualDancePoints[m_PlayerNumber] += iNumTapsInRow * TapNoteScoreToDancePoints( score );
|
||||
GAMESTATE->m_TapNoteScores[m_PlayerNumber][score] += iNumTapsInRow;
|
||||
GAMESTATE->m_CurStageStats.iActualDancePoints[m_PlayerNumber] += iNumTapsInRow * TapNoteScoreToDancePoints( score );
|
||||
GAMESTATE->m_CurStageStats.iTapNoteScores[m_PlayerNumber][score] += iNumTapsInRow;
|
||||
|
||||
/*
|
||||
A single step's points are calculated as follows:
|
||||
@@ -100,8 +100,8 @@ void ScoreKeeperMAX2::HandleNoteScore( TapNoteScore score, int iNumTapsInRow )
|
||||
void ScoreKeeperMAX2::HandleHoldNoteScore( HoldNoteScore score, TapNoteScore TapNoteScore )
|
||||
{
|
||||
// update dance points totals
|
||||
GAMESTATE->m_HoldNoteScores[m_PlayerNumber][score] ++;
|
||||
GAMESTATE->m_iActualDancePoints[m_PlayerNumber] += HoldNoteScoreToDancePoints( score );
|
||||
GAMESTATE->m_CurStageStats.iHoldNoteScores[m_PlayerNumber][score] ++;
|
||||
GAMESTATE->m_CurStageStats.iActualDancePoints[m_PlayerNumber] += HoldNoteScoreToDancePoints( score );
|
||||
|
||||
if( score == HNS_OK )
|
||||
AddScore( TNS_PERFECT );
|
||||
|
||||
+128
-151
@@ -115,12 +115,9 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
{
|
||||
LOG->Trace( "ScreenEvaluation::ScreenEvaluation()" );
|
||||
|
||||
int l, p; // for counting
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// Set m_ResultMode. This enum will make our life easier later when we init different pieces depending on context.
|
||||
///////////////////////////
|
||||
//
|
||||
// Set m_ResultMode. This enum will make our life easier later when we init different pieces.
|
||||
//
|
||||
switch( GAMESTATE->m_PlayMode )
|
||||
{
|
||||
case PLAY_MODE_ARCADE:
|
||||
@@ -129,54 +126,42 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
case PLAY_MODE_NONSTOP:
|
||||
case PLAY_MODE_ONI:
|
||||
case PLAY_MODE_ENDLESS:
|
||||
m_ResultMode = RM_ONI;
|
||||
m_ResultMode = RM_COURSE;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// Figure out which statistics we're going to display
|
||||
///////////////////////////
|
||||
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 iMaxCombo[NUM_PLAYERS];
|
||||
float fScore[NUM_PLAYERS];
|
||||
float fPossibleRadarValues[NUM_PLAYERS][NUM_RADAR_CATEGORIES];
|
||||
float fActualRadarValues[NUM_PLAYERS][NUM_RADAR_CATEGORIES];
|
||||
|
||||
//
|
||||
// Figure out which statistics and songs we're going to display
|
||||
//
|
||||
StageStats stageStats;
|
||||
vector<Song*> vSongsToShow;
|
||||
switch( m_ResultMode )
|
||||
{
|
||||
case RM_ARCADE_SUMMARY:
|
||||
COPY( iPossibleDancePoints, GAMESTATE->m_iAccumPossibleDancePoints );
|
||||
COPY( iActualDancePoints, GAMESTATE->m_iAccumActualDancePoints );
|
||||
COPY( iTapNoteScores, GAMESTATE->m_AccumTapNoteScores );
|
||||
COPY( iHoldNoteScores, GAMESTATE->m_AccumHoldNoteScores );
|
||||
COPY( iMaxCombo, GAMESTATE->m_iAccumMaxCombo );
|
||||
COPY( fScore, GAMESTATE->m_fAccumScore );
|
||||
COPY( fPossibleRadarValues, GAMESTATE->m_fAccumRadarPossible );
|
||||
COPY( fActualRadarValues, GAMESTATE->m_fAccumRadarActual );
|
||||
{
|
||||
// Show stats only for the latest 3 normal songs + passed extra stages
|
||||
int iNumSongsToThrowAway = max( 0, PREFSMAN->m_iNumArcadeStages-3 );
|
||||
for( unsigned i=iNumSongsToThrowAway; i<GAMESTATE->m_vPassedStageStats.size(); i++ )
|
||||
{
|
||||
stageStats += GAMESTATE->m_vPassedStageStats[i];
|
||||
vSongsToShow.push_back( GAMESTATE->m_vPassedStageStats[i].pSong );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RM_ARCADE_STAGE:
|
||||
case RM_ONI:
|
||||
COPY( iPossibleDancePoints, GAMESTATE->m_iPossibleDancePoints );
|
||||
COPY( iActualDancePoints, GAMESTATE->m_iActualDancePoints );
|
||||
COPY( iTapNoteScores, GAMESTATE->m_TapNoteScores );
|
||||
COPY( iHoldNoteScores, GAMESTATE->m_HoldNoteScores );
|
||||
COPY( iMaxCombo, GAMESTATE->m_iMaxCombo );
|
||||
COPY( fScore, GAMESTATE->m_fScore );
|
||||
COPY( fPossibleRadarValues, GAMESTATE->m_fRadarPossible );
|
||||
COPY( fActualRadarValues, GAMESTATE->m_fRadarActual );
|
||||
case RM_COURSE:
|
||||
stageStats = GAMESTATE->m_CurStageStats;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
//
|
||||
// Init the song banners depending on m_ResultMode
|
||||
///////////////////////////
|
||||
// EZ2 should hide these things by placing them off screen with theme metrics
|
||||
//
|
||||
switch( m_ResultMode )
|
||||
{
|
||||
case RM_ARCADE_STAGE:
|
||||
@@ -205,31 +190,23 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
break;
|
||||
case RM_ARCADE_SUMMARY:
|
||||
{
|
||||
// crop down to 3
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
for( unsigned i=0; i<vSongsToShow.size(); i++ )
|
||||
{
|
||||
if( GAMESTATE->m_apSongsPlayed.size() > STAGES_TO_SHOW_IN_SUMMARY )
|
||||
GAMESTATE->m_apSongsPlayed.erase( GAMESTATE->m_apSongsPlayed.begin(), GAMESTATE->m_apSongsPlayed.begin() + (GAMESTATE->m_apSongsPlayed.size() - STAGES_TO_SHOW_IN_SUMMARY) );
|
||||
}
|
||||
|
||||
const unsigned iSongsToShow = GAMESTATE->m_apSongsPlayed.size();
|
||||
ASSERT( iSongsToShow > 0 );
|
||||
|
||||
for( unsigned i=0; i<iSongsToShow; i++ )
|
||||
{
|
||||
m_BannerWithFrame[i].LoadFromSong( GAMESTATE->m_apSongsPlayed[i] );
|
||||
float fBannerOffset = i - (iSongsToShow-1)/2.0f;
|
||||
m_BannerWithFrame[i].LoadFromSong( vSongsToShow[i] );
|
||||
float fBannerOffset = i - (vSongsToShow.size()-1)/2.0f;
|
||||
m_BannerWithFrame[i].SetXY( BANNER_X + fBannerOffset*32, BANNER_Y + fBannerOffset*16 );
|
||||
m_BannerWithFrame[i].SetZoom( 0.70f );
|
||||
this->AddChild( &m_BannerWithFrame[i] );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RM_ONI:
|
||||
case RM_COURSE:
|
||||
m_BannerWithFrame[0].LoadFromCourse( GAMESTATE->m_pCurCourse );
|
||||
m_BannerWithFrame[0].SetXY( BANNER_X, BANNER_Y );
|
||||
this->AddChild( &m_BannerWithFrame[0] );
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -243,7 +220,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
);
|
||||
this->AddChild( &m_Menu );
|
||||
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) ) // If EZ2 wants to hide this graphic, place it somewhere off screen using theme metrics
|
||||
continue; // skip
|
||||
@@ -256,19 +233,16 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Calculate grades
|
||||
//
|
||||
Grade grade[NUM_PLAYERS];
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) || GAMESTATE->m_fSecondsBeforeFail[p] != -1 )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) || GAMESTATE->m_CurStageStats.bFailed[p] )
|
||||
grade[p] = GRADE_E;
|
||||
continue;
|
||||
}
|
||||
grade[p] = GAMESTATE->GetCurrentGrade( (PlayerNumber)p );
|
||||
else
|
||||
grade[p] = GAMESTATE->GetCurrentGrade( (PlayerNumber)p );
|
||||
}
|
||||
|
||||
Grade max_grade = GRADE_NO_DATA;
|
||||
@@ -276,52 +250,53 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
max_grade = max( max_grade, grade[p] );
|
||||
|
||||
|
||||
////////////////////////
|
||||
//
|
||||
// update persistent statistics
|
||||
////////////////////////
|
||||
//
|
||||
bool bNewRecord[NUM_PLAYERS];
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
bNewRecord[p] = false;
|
||||
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
memset( bNewRecord, 0, sizeof(bNewRecord) );
|
||||
m_bGoToNameEntry = false;
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) )
|
||||
continue;
|
||||
|
||||
if( grade[p] == GRADE_E )
|
||||
continue;
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) || grade[p] == GRADE_E )
|
||||
continue; // can't be a new record
|
||||
|
||||
switch( m_ResultMode )
|
||||
{
|
||||
case RM_ARCADE_STAGE:
|
||||
Notes* pNotes = GAMESTATE->m_pCurNotes[p];
|
||||
if( SONGMAN->IsUsingMemoryCard((PlayerNumber)p) )
|
||||
bNewRecord[p] = pNotes->AddMemCardScore( (PlayerNumber)p, grade[p], (int)fScore[p] );
|
||||
{
|
||||
Notes* pNotes = GAMESTATE->m_pCurNotes[p];
|
||||
if( SONGMAN->IsUsingMemoryCard((PlayerNumber)p) )
|
||||
bNewRecord[p] = pNotes->AddMemCardRecord( (PlayerNumber)p, grade[p], stageStats.fScore[p] );
|
||||
}
|
||||
break;
|
||||
case RM_ARCADE_SUMMARY:
|
||||
{
|
||||
float fAverageMeter = stageStats.iMeter[p] / (float)PREFSMAN->m_iNumArcadeStages; // intentional: doesn't count extra stage
|
||||
HighScoreCategory hsc = AverageMeterToHighScoreCategory( fAverageMeter );
|
||||
m_bGoToNameEntry |= SONGMAN->IsNewMachineRecord( hsc, stageStats.fScore[p] );
|
||||
}
|
||||
break;
|
||||
case RM_COURSE:
|
||||
{
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
pCourse->IsNewMachineRecord( (PlayerNumber)p, stageStats.iActualDancePoints[p], stageStats.fAliveSeconds[p] );
|
||||
m_bGoToNameEntry |= true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
m_bTryExtraStage =
|
||||
GAMESTATE->HasEarnedExtraStage() &&
|
||||
m_ResultMode==RM_ARCADE_STAGE &&
|
||||
!PREFSMAN->m_bEventMode;
|
||||
|
||||
|
||||
m_bTryExtraStage = false;
|
||||
if( (GAMESTATE->IsFinalStage() || GAMESTATE->IsExtraStage()) && m_ResultMode==RM_ARCADE_STAGE )
|
||||
{
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
|
||||
continue; // skip
|
||||
|
||||
if( GAMESTATE->m_pCurNotes[p]->GetDifficulty() == DIFFICULTY_HARD && grade[p] >= GRADE_AA )
|
||||
m_bTryExtraStage = true;
|
||||
}
|
||||
}
|
||||
if( PREFSMAN->m_bEventMode )
|
||||
m_bTryExtraStage = false;
|
||||
|
||||
|
||||
/////////////////////////////////
|
||||
//
|
||||
// Init ResultMode-specific displays
|
||||
/////////////////////////////////
|
||||
//
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
|
||||
@@ -331,7 +306,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
|
||||
switch( m_ResultMode )
|
||||
{
|
||||
case RM_ONI:
|
||||
case RM_COURSE:
|
||||
{
|
||||
m_sprPercentFrame[p].Load( THEME->GetPathTo("Graphics","evaluation percent frame") );
|
||||
m_sprPercentFrame[p].StopAnimating();
|
||||
@@ -356,8 +331,8 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
m_textOniPercentSmall[p].SetEffectGlowing( 1.0f );
|
||||
this->AddChild( &m_textOniPercentSmall[p] );
|
||||
|
||||
iPossibleDancePoints[p] = max( 1, iPossibleDancePoints[p] );
|
||||
float fPercentDancePoints = iActualDancePoints[p] / (float)iPossibleDancePoints[p] + 0.0001f; // correct for rounding errors
|
||||
stageStats.iPossibleDancePoints[p] = max( 1, stageStats.iPossibleDancePoints[p] );
|
||||
float fPercentDancePoints = stageStats.iActualDancePoints[p] / (float)stageStats.iPossibleDancePoints[p] + 0.0001f; // correct for rounding errors
|
||||
fPercentDancePoints = max( fPercentDancePoints, 0 );
|
||||
int iPercentDancePointsLarge = int(fPercentDancePoints*100);
|
||||
int iPercentDancePointsSmall = int( (fPercentDancePoints*100 - int(fPercentDancePoints*100)) * 10 );
|
||||
@@ -374,7 +349,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
m_textSongsSurvived[p].LoadFromNumbers( THEME->GetPathTo("Numbers","evaluation stage numbers") );
|
||||
m_textSongsSurvived[p].TurnShadowOff();
|
||||
m_textSongsSurvived[p].SetXY( SONGS_SURVIVED_X(p), SONGS_SURVIVED_Y );
|
||||
m_textSongsSurvived[p].SetText( ssprintf("%02d", GAMESTATE->m_iSongsBeforeFail[p]) );
|
||||
m_textSongsSurvived[p].SetText( ssprintf("%02d", stageStats.iSongsPassed[p]+1) );
|
||||
this->AddChild( &m_textSongsSurvived[p] );
|
||||
}
|
||||
break;
|
||||
@@ -405,42 +380,41 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
m_sprBonusFrame[p].SetXY( BONUS_X(p), BONUS_Y );
|
||||
this->AddChild( &m_sprBonusFrame[p] );
|
||||
|
||||
for( int l=0; l<NUM_RADAR_VALUES; l++ ) // foreach line
|
||||
for( int r=0; r<NUM_RADAR_VALUES; r++ ) // foreach line
|
||||
{
|
||||
m_sprPossibleBar[p][l].Load( THEME->GetPathTo("Graphics","evaluation bars possible 1x2") );
|
||||
m_sprPossibleBar[p][l].SetState( p );
|
||||
m_sprPossibleBar[p][l].SetHorizAlign( Actor::align_left );
|
||||
m_sprPossibleBar[p][l].SetX( BAR_BASE_X(p) );
|
||||
m_sprPossibleBar[p][l].SetY( BAR_START_Y + BAR_SPACING_Y*l );
|
||||
m_sprPossibleBar[p][l].SetRotation( BAR_ROTATION(p) );
|
||||
m_sprPossibleBar[p][l].SetZoomX( 0 );
|
||||
m_sprPossibleBar[p][l].ZoomToHeight( BAR_HEIGHT );
|
||||
m_sprPossibleBar[p][l].BeginTweening( 0.2f + l*0.1f ); // sleep
|
||||
m_sprPossibleBar[p][l].BeginTweening( 0.5f ); // tween
|
||||
m_sprPossibleBar[p][l].SetTweenZoomToWidth( BAR_WIDTH*fPossibleRadarValues[p][l] );
|
||||
this->AddChild( &m_sprPossibleBar[p][l] );
|
||||
m_sprPossibleBar[p][r].Load( THEME->GetPathTo("Graphics","evaluation bars possible 1x2") );
|
||||
m_sprPossibleBar[p][r].SetState( p );
|
||||
m_sprPossibleBar[p][r].SetHorizAlign( Actor::align_left );
|
||||
m_sprPossibleBar[p][r].SetX( BAR_BASE_X(p) );
|
||||
m_sprPossibleBar[p][r].SetY( BAR_START_Y + BAR_SPACING_Y*r );
|
||||
m_sprPossibleBar[p][r].SetRotation( BAR_ROTATION(p) );
|
||||
m_sprPossibleBar[p][r].SetZoomX( 0 );
|
||||
m_sprPossibleBar[p][r].ZoomToHeight( BAR_HEIGHT );
|
||||
m_sprPossibleBar[p][r].BeginTweening( 0.2f + r*0.1f ); // sleep
|
||||
m_sprPossibleBar[p][r].BeginTweening( 0.5f ); // tween
|
||||
m_sprPossibleBar[p][r].SetTweenZoomToWidth( BAR_WIDTH*stageStats.fRadarPossible[p][r] );
|
||||
this->AddChild( &m_sprPossibleBar[p][r] );
|
||||
|
||||
m_sprActualBar[p][l].Load( THEME->GetPathTo("Graphics","evaluation bars actual 1x2") );
|
||||
m_sprActualBar[p][l].SetState( p );
|
||||
m_sprActualBar[p][l].StopAnimating();
|
||||
m_sprActualBar[p][l].SetHorizAlign( Actor::align_left );
|
||||
m_sprActualBar[p][l].SetX( BAR_BASE_X(p) );
|
||||
m_sprActualBar[p][l].SetY( BAR_START_Y + BAR_SPACING_Y*l );
|
||||
m_sprActualBar[p][l].SetRotation( BAR_ROTATION(p) );
|
||||
m_sprActualBar[p][l].SetZoomX( 0 );
|
||||
m_sprActualBar[p][l].ZoomToHeight( BAR_HEIGHT );
|
||||
m_sprActualBar[p][l].BeginTweening( 1.0f + l*0.2f ); // sleep
|
||||
m_sprActualBar[p][l].BeginTweening( 1.0f ); // tween
|
||||
m_sprActualBar[p][l].SetTweenZoomToWidth( BAR_WIDTH*fActualRadarValues[p][l] );
|
||||
if( fActualRadarValues[p][l] == fPossibleRadarValues[p][l] )
|
||||
m_sprActualBar[p][l].SetEffectGlowing();
|
||||
this->AddChild( &m_sprActualBar[p][l] );
|
||||
m_sprActualBar[p][r].Load( THEME->GetPathTo("Graphics","evaluation bars actual 1x2") );
|
||||
m_sprActualBar[p][r].SetState( p );
|
||||
m_sprActualBar[p][r].StopAnimating();
|
||||
m_sprActualBar[p][r].SetHorizAlign( Actor::align_left );
|
||||
m_sprActualBar[p][r].SetX( BAR_BASE_X(p) );
|
||||
m_sprActualBar[p][r].SetY( BAR_START_Y + BAR_SPACING_Y*r );
|
||||
m_sprActualBar[p][r].SetRotation( BAR_ROTATION(p) );
|
||||
m_sprActualBar[p][r].SetZoomX( 0 );
|
||||
m_sprActualBar[p][r].ZoomToHeight( BAR_HEIGHT );
|
||||
m_sprActualBar[p][r].BeginTweening( 1.0f + r*0.2f ); // sleep
|
||||
m_sprActualBar[p][r].BeginTweening( 1.0f ); // tween
|
||||
m_sprActualBar[p][r].SetTweenZoomToWidth( BAR_WIDTH*stageStats.fRadarActual[p][r] );
|
||||
if( stageStats.fRadarActual[p][r] == stageStats.fRadarPossible[p][r] )
|
||||
m_sprActualBar[p][r].SetEffectGlowing();
|
||||
this->AddChild( &m_sprActualBar[p][r] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Chris: If EZ2 wants to hide these things, place them off screen using theme metrics
|
||||
if( bNewRecord[p] )
|
||||
{
|
||||
m_sprNewRecord[p].Load( THEME->GetPathTo("Graphics","evaluation new record") );
|
||||
@@ -450,12 +424,12 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
//
|
||||
// Init non-ResultMode specific displays.
|
||||
// Do this after Result-specific displays so that the text will draw on top of
|
||||
// the bonus frame.
|
||||
//////////////////////////
|
||||
for( l=0; l<NUM_JUDGE_LINES; l++ )
|
||||
//
|
||||
for( int l=0; l<NUM_JUDGE_LINES; l++ )
|
||||
{
|
||||
// EZ2 should hide these things by placing them off screen with theme metrics
|
||||
m_sprJudgeLabels[l].Load( THEME->GetPathTo("Graphics","evaluation judge labels 1x8") );
|
||||
@@ -467,7 +441,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
}
|
||||
|
||||
m_sprScoreLabel.Load( THEME->GetPathTo("Graphics","evaluation score labels") );
|
||||
m_sprScoreLabel.SetState( m_ResultMode==RM_ONI ? 1 : 0 );
|
||||
m_sprScoreLabel.SetState( m_ResultMode==RM_COURSE ? 1 : 0 );
|
||||
m_sprScoreLabel.StopAnimating();
|
||||
m_sprScoreLabel.SetXY( SCORE_LABELS_X, SCORE_Y );
|
||||
m_sprScoreLabel.SetZoom( 1.0f );
|
||||
@@ -483,26 +457,26 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
{
|
||||
m_textJudgeNumbers[l][p].LoadFromNumbers( THEME->GetPathTo("Numbers","evaluation judge numbers") );
|
||||
m_textJudgeNumbers[l][p].TurnShadowOff();
|
||||
m_textJudgeNumbers[l][p].SetXY( JUDGE_X(m_ResultMode==RM_ONI,p,l), JUDGE_Y(l) );
|
||||
m_textJudgeNumbers[l][p].SetXY( JUDGE_X(m_ResultMode==RM_COURSE,p,l), JUDGE_Y(l) );
|
||||
m_textJudgeNumbers[l][p].SetZoom( 1.0f );
|
||||
m_textJudgeNumbers[l][p].SetDiffuse( PlayerToColor(p) );
|
||||
this->AddChild( &m_textJudgeNumbers[l][p] );
|
||||
}
|
||||
|
||||
m_textJudgeNumbers[0][p].SetText( ssprintf("%4d", iTapNoteScores[p][TNS_MARVELOUS]) );
|
||||
m_textJudgeNumbers[1][p].SetText( ssprintf("%4d", iTapNoteScores[p][TNS_PERFECT]) );
|
||||
m_textJudgeNumbers[2][p].SetText( ssprintf("%4d", iTapNoteScores[p][TNS_GREAT]) );
|
||||
m_textJudgeNumbers[3][p].SetText( ssprintf("%4d", iTapNoteScores[p][TNS_GOOD]) );
|
||||
m_textJudgeNumbers[4][p].SetText( ssprintf("%4d", iTapNoteScores[p][TNS_BOO]) );
|
||||
m_textJudgeNumbers[5][p].SetText( ssprintf("%4d", iTapNoteScores[p][TNS_MISS]) );
|
||||
m_textJudgeNumbers[6][p].SetText( ssprintf("%4d", iHoldNoteScores[p][HNS_OK]) );
|
||||
m_textJudgeNumbers[7][p].SetText( ssprintf("%4d", iMaxCombo[p]) );
|
||||
m_textJudgeNumbers[0][p].SetText( ssprintf("%4d", stageStats.iTapNoteScores[p][TNS_MARVELOUS]) );
|
||||
m_textJudgeNumbers[1][p].SetText( ssprintf("%4d", stageStats.iTapNoteScores[p][TNS_PERFECT]) );
|
||||
m_textJudgeNumbers[2][p].SetText( ssprintf("%4d", stageStats.iTapNoteScores[p][TNS_GREAT]) );
|
||||
m_textJudgeNumbers[3][p].SetText( ssprintf("%4d", stageStats.iTapNoteScores[p][TNS_GOOD]) );
|
||||
m_textJudgeNumbers[4][p].SetText( ssprintf("%4d", stageStats.iTapNoteScores[p][TNS_BOO]) );
|
||||
m_textJudgeNumbers[5][p].SetText( ssprintf("%4d", stageStats.iTapNoteScores[p][TNS_MISS]) );
|
||||
m_textJudgeNumbers[6][p].SetText( ssprintf("%4d", stageStats.iHoldNoteScores[p][HNS_OK]) );
|
||||
m_textJudgeNumbers[7][p].SetText( ssprintf("%4d", stageStats.iMaxCombo[p]) );
|
||||
|
||||
|
||||
if( m_ResultMode==RM_ONI )
|
||||
m_ScoreDisplay[p].SetText( SecondsToTime(GAMESTATE->GetPlayerSurviveTime( (PlayerNumber)p )) );
|
||||
if( m_ResultMode==RM_COURSE )
|
||||
m_ScoreDisplay[p].SetText( SecondsToTime(stageStats.fAliveSeconds[p]) );
|
||||
else
|
||||
m_ScoreDisplay[p].SetScore( fScore[p] );
|
||||
m_ScoreDisplay[p].SetScore( stageStats.fScore[p] );
|
||||
}
|
||||
|
||||
|
||||
@@ -546,7 +520,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
||||
ASSERT(0); // invalid grade
|
||||
}
|
||||
break;
|
||||
case RM_ONI:
|
||||
case RM_COURSE:
|
||||
case RM_ARCADE_SUMMARY:
|
||||
switch( max_grade )
|
||||
{
|
||||
@@ -594,7 +568,7 @@ void ScreenEvaluation::TweenOnScreen()
|
||||
|
||||
float fOriginalX, fOriginalY;
|
||||
|
||||
for( i=0; i<STAGES_TO_SHOW_IN_SUMMARY; i++ )
|
||||
for( i=0; i<MAX_SONGS_TO_SHOW; i++ )
|
||||
{
|
||||
fOriginalY = m_BannerWithFrame[i].GetY();
|
||||
m_BannerWithFrame[i].SetY( fOriginalY + SCREEN_HEIGHT );
|
||||
@@ -695,7 +669,7 @@ void ScreenEvaluation::TweenOffScreen()
|
||||
{
|
||||
int i, p;
|
||||
|
||||
for( i=0; i<STAGES_TO_SHOW_IN_SUMMARY; i++ )
|
||||
for( i=0; i<MAX_SONGS_TO_SHOW; i++ )
|
||||
m_BannerWithFrame[i].FadeOff( 0, "foldy", MENU_ELEMENTS_TWEEN_TIME );
|
||||
|
||||
m_textStage.FadeOff( 0, "foldy", MENU_ELEMENTS_TWEEN_TIME );
|
||||
@@ -797,12 +771,16 @@ void ScreenEvaluation::HandleScreenMessage( const ScreenMessage SM )
|
||||
|
||||
void ScreenEvaluation::MenuLeft( PlayerNumber pn )
|
||||
{
|
||||
m_Grades[pn].SettleQuickly();
|
||||
// What is the purpose of this? I keep my feet on the pads and
|
||||
// was wondering why the grades weren't spinning. -Chris
|
||||
//m_Grades[pn].SettleQuickly();
|
||||
}
|
||||
|
||||
void ScreenEvaluation::MenuRight( PlayerNumber pn )
|
||||
{
|
||||
m_Grades[pn].SettleQuickly();
|
||||
// What is the purpose of this? I keep my feet on the pads and
|
||||
// was wondering why the grades weren't spinning. -Chris
|
||||
//m_Grades[pn].SettleQuickly();
|
||||
}
|
||||
|
||||
void ScreenEvaluation::MenuBack( PlayerNumber pn )
|
||||
@@ -851,9 +829,8 @@ void ScreenEvaluation::MenuStart( PlayerNumber pn )
|
||||
m_Menu.TweenOffScreenToBlack( SM_GoToMusicScroll, false );
|
||||
}
|
||||
|
||||
//
|
||||
// Increment the stage counter.
|
||||
//
|
||||
GAMESTATE->m_iCurrentStageIndex++;
|
||||
GAMESTATE->m_iCurrentStageIndex++; // Increment the stage counter.
|
||||
|
||||
GAMESTATE->m_vPassedStageStats.push_back( GAMESTATE->m_CurStageStats ); // Save this stage's stats
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
|
||||
const int NUM_JUDGE_LINES = 8; // marvelous, perfect, great, good, boo, miss, ok, max_combo
|
||||
const int STAGES_TO_SHOW_IN_SUMMARY = 3; // only show the latest three stages in a summary
|
||||
const int MAX_SONGS_TO_SHOW = 5; // In summary, we show last 3 stages, plus extra stages if passed
|
||||
|
||||
|
||||
class ScreenEvaluation : public Screen
|
||||
@@ -42,12 +42,12 @@ public:
|
||||
virtual void MenuStart( PlayerNumber pn );
|
||||
|
||||
protected:
|
||||
enum ResultMode { RM_ARCADE_STAGE, RM_ARCADE_SUMMARY, RM_ONI };
|
||||
enum ResultMode { RM_ARCADE_STAGE, RM_ARCADE_SUMMARY, RM_COURSE };
|
||||
ResultMode m_ResultMode;
|
||||
|
||||
MenuElements m_Menu;
|
||||
|
||||
BannerWithFrame m_BannerWithFrame[STAGES_TO_SHOW_IN_SUMMARY];
|
||||
BannerWithFrame m_BannerWithFrame[MAX_SONGS_TO_SHOW];
|
||||
BitmapText m_textStage;
|
||||
DifficultyIcon m_DifficultyIcon[NUM_PLAYERS];
|
||||
|
||||
@@ -78,6 +78,8 @@ protected:
|
||||
|
||||
Sprite m_sprNewRecord[NUM_PLAYERS];
|
||||
|
||||
bool m_bGoToNameEntry;
|
||||
|
||||
bool m_bTryExtraStage;
|
||||
Sprite m_sprTryExtraStage;
|
||||
};
|
||||
|
||||
@@ -116,10 +116,9 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
|
||||
SOUNDMAN->StopMusic();
|
||||
|
||||
|
||||
/* It's OK to operate on GAMESTATE here, but not in the constructor */
|
||||
GAMESTATE->ResetStageStatistics(); // clear values
|
||||
GAMESTATE->m_CurStageStats = StageStats(); // clear values
|
||||
|
||||
// Update possible dance points
|
||||
// Fill in m_CurStageStats
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) )
|
||||
@@ -129,14 +128,20 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
|
||||
switch( GAMESTATE->m_PlayMode )
|
||||
{
|
||||
case PLAY_MODE_ARCADE:
|
||||
GAMESTATE->m_CurStageStats.pSong = GAMESTATE->m_pCurSong;
|
||||
GAMESTATE->m_CurStageStats.iMeter[p] = GAMESTATE->m_pCurNotes[p]->GetMeter();
|
||||
|
||||
GAMESTATE->m_pCurNotes[p]->GetNoteData( ¬edata );
|
||||
GAMESTATE->m_iPossibleDancePoints[p] = notedata.GetPossibleDancePoints();
|
||||
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] = notedata.GetPossibleDancePoints();
|
||||
break;
|
||||
case PLAY_MODE_NONSTOP:
|
||||
case PLAY_MODE_ONI:
|
||||
case PLAY_MODE_ENDLESS:
|
||||
{
|
||||
GAMESTATE->m_iPossibleDancePoints[p] = 0;
|
||||
GAMESTATE->m_CurStageStats.pSong = NULL;
|
||||
GAMESTATE->m_CurStageStats.iMeter[p] = 0;
|
||||
|
||||
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] = 0;
|
||||
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
vector<Song*> apSongs;
|
||||
@@ -146,9 +151,10 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
|
||||
|
||||
for( unsigned i=0; i<apNotes.size(); i++ )
|
||||
{
|
||||
GAMESTATE->m_CurStageStats.iMeter[p] += apNotes[i]->GetMeter();
|
||||
apNotes[i]->GetNoteData( ¬edata );
|
||||
int iPossibleDancePoints = notedata.GetPossibleDancePoints();
|
||||
GAMESTATE->m_iPossibleDancePoints[p] += iPossibleDancePoints;
|
||||
GAMESTATE->m_CurStageStats.iPossibleDancePoints[p] += iPossibleDancePoints;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -499,7 +505,7 @@ bool ScreenGameplay::IsLastSong()
|
||||
CStringArray asModifiers;
|
||||
pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes, asModifiers, true );
|
||||
|
||||
return unsigned(GAMESTATE->m_iSongsIntoCourse) >= apSongs.size(); // there are no more songs left
|
||||
return unsigned(GAMESTATE->m_CurStageStats.iSongsPassed) >= apSongs.size(); // there are no more songs left
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -523,9 +529,9 @@ void ScreenGameplay::LoadNextSong( bool bFirstLoad )
|
||||
int p;
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
m_textCourseSongNumber[p].SetText( ssprintf("%d", GAMESTATE->m_iSongsBeforeFail[p]+1) );
|
||||
m_textCourseSongNumber[p].SetText( ssprintf("%d", GAMESTATE->m_CurStageStats.iSongsPassed[p]+1) );
|
||||
// If it's the first song, record the options the player selected for later.
|
||||
if (GAMESTATE->m_iSongsIntoCourse == 0)
|
||||
if( GAMESTATE->m_CurStageStats.iSongsPassed[p] == 0 )
|
||||
GAMESTATE->m_SelectedOptions[p] = GAMESTATE->m_PlayerOptions[p];
|
||||
}
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
@@ -535,7 +541,10 @@ void ScreenGameplay::LoadNextSong( bool bFirstLoad )
|
||||
|
||||
pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes, asModifiers, true );
|
||||
|
||||
int iPlaySongIndex = GAMESTATE->m_iSongsIntoCourse;
|
||||
int iPlaySongIndex = 0;
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
if( GAMESTATE->IsPlayerEnabled(p) )
|
||||
iPlaySongIndex = max( iPlaySongIndex, GAMESTATE->m_CurStageStats.iSongsPassed[p] );
|
||||
iPlaySongIndex %= apSongs.size();
|
||||
|
||||
GAMESTATE->m_pCurSong = apSongs[iPlaySongIndex];
|
||||
@@ -572,7 +581,7 @@ void ScreenGameplay::LoadNextSong( bool bFirstLoad )
|
||||
m_sprOniGameOver[p].SetY( SCREEN_TOP - m_sprOniGameOver[p].GetZoomedHeight()/2 );
|
||||
m_sprOniGameOver[p].SetDiffuse( RageColor(1,1,1,0) ); // 0 alpha so we don't waste time drawing while not visible
|
||||
|
||||
if( GAMESTATE->m_SongOptions.m_LifeType == SongOptions::LIFE_BATTERY && GAMESTATE->m_fSecondsBeforeFail[p] != -1 ) // already failed
|
||||
if( GAMESTATE->m_SongOptions.m_LifeType==SongOptions::LIFE_BATTERY && GAMESTATE->m_CurStageStats.bFailed[p] ) // already failed
|
||||
ShowOniGameOver((PlayerNumber)p);
|
||||
|
||||
|
||||
@@ -732,6 +741,13 @@ void ScreenGameplay::Update( float fDeltaTime )
|
||||
{
|
||||
case STATE_DANCING:
|
||||
|
||||
//
|
||||
// Update players' alive time
|
||||
//
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
if( GAMESTATE->IsPlayerEnabled(p) )
|
||||
GAMESTATE->m_CurStageStats.fAliveSeconds[p] += fDeltaTime;
|
||||
|
||||
//
|
||||
// Check for end of song
|
||||
//
|
||||
@@ -758,8 +774,8 @@ void ScreenGameplay::Update( float fDeltaTime )
|
||||
// check for individual fail
|
||||
for ( pn=0; pn<NUM_PLAYERS; pn++ )
|
||||
{
|
||||
if ( m_pLifeMeter[pn]->IsFailing() && GAMESTATE->m_fSecondsBeforeFail[pn] == -1)
|
||||
GAMESTATE->m_fSecondsBeforeFail[pn] = GAMESTATE->GetElapsedSeconds();
|
||||
if ( m_pLifeMeter[pn]->IsFailing() && !GAMESTATE->m_CurStageStats.bFailed[pn] )
|
||||
GAMESTATE->m_CurStageStats.bFailed[pn] = true; // fail
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -769,19 +785,19 @@ void ScreenGameplay::Update( float fDeltaTime )
|
||||
else m_Background.TurnDangerOff();
|
||||
|
||||
// check for individual fail
|
||||
for( pn=0; pn<NUM_PLAYERS; pn++ ) {
|
||||
for( pn=0; pn<NUM_PLAYERS; pn++ )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled(pn) )
|
||||
continue;
|
||||
if( !m_pLifeMeter[pn]->IsFailing())
|
||||
continue; /* hasn't failed */
|
||||
|
||||
if( GAMESTATE->m_fSecondsBeforeFail[pn] != -1 )
|
||||
continue; /* isn't failing */
|
||||
if( GAMESTATE->m_CurStageStats.bFailed[pn] )
|
||||
continue; /* failed and is already dead */
|
||||
|
||||
if( !AllFailedEarlier() ) // if not the last one to fail
|
||||
{
|
||||
// kill them!
|
||||
GAMESTATE->m_fSecondsBeforeFail[pn] = GAMESTATE->GetElapsedSeconds();
|
||||
GAMESTATE->m_CurStageStats.bFailed[pn] = true;
|
||||
m_soundOniDie.PlayRandom();
|
||||
ShowOniGameOver((PlayerNumber)pn);
|
||||
m_Player[pn].Init(); // remove all notes and scoring
|
||||
@@ -1169,38 +1185,29 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
|
||||
for( int r=0; r<NUM_RADAR_CATEGORIES; r++ )
|
||||
{
|
||||
RadarCategory rc = (RadarCategory)r;
|
||||
GAMESTATE->m_fRadarPossible[p][r] = NoteDataUtil::GetRadarValue( m_Player[p], rc, GAMESTATE->m_pCurSong->m_fMusicLengthSeconds );
|
||||
GAMESTATE->m_fRadarActual[p][r] = m_Player[p].GetActualRadarValue( rc, GAMESTATE->m_pCurSong->m_fMusicLengthSeconds );
|
||||
GAMESTATE->m_CurStageStats.fRadarPossible[p][r] = NoteDataUtil::GetRadarValue( m_Player[p], rc, GAMESTATE->m_pCurSong->m_fMusicLengthSeconds );
|
||||
GAMESTATE->m_CurStageStats.fRadarActual[p][r] = m_Player[p].GetActualRadarValue( rc, GAMESTATE->m_pCurSong->m_fMusicLengthSeconds );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GAMESTATE->m_apSongsPlayed.push_back( GAMESTATE->m_pCurSong );
|
||||
GAMESTATE->m_iSongsIntoCourse++;
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
if( GAMESTATE->IsPlayerEnabled(p) )
|
||||
if( !m_pLifeMeter[p]->FailedEarlier() )
|
||||
GAMESTATE->m_iSongsBeforeFail[p]++;
|
||||
|
||||
if( GAMESTATE->IsPlayerEnabled(p) && !GAMESTATE->m_CurStageStats.bFailed[p] )
|
||||
GAMESTATE->m_CurStageStats.iSongsPassed[p]++;
|
||||
|
||||
if( !IsLastSong() )
|
||||
{
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
if( GAMESTATE->IsPlayerEnabled(p) )
|
||||
if( !m_pLifeMeter[p]->FailedEarlier() )
|
||||
m_pLifeMeter[p]->SongEnded(); // let the oni life meter give them back a life
|
||||
|
||||
if( GAMESTATE->IsPlayerEnabled(p) && !GAMESTATE->m_CurStageStats.bFailed[p] )
|
||||
m_pLifeMeter[p]->OnSongEnded(); // give a little life back between stages
|
||||
m_OniFade.CloseWipingRight( SM_BeginLoadingNextSong );
|
||||
}
|
||||
else // IsLastSong
|
||||
{
|
||||
if( m_DancingState == STATE_OUTRO ) // gameplay already ended
|
||||
return; // ignore
|
||||
|
||||
m_DancingState = STATE_OUTRO;
|
||||
|
||||
GAMESTATE->AccumulateStageStatistics(); // accumulate values for final evaluation
|
||||
|
||||
if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_END_OF_SONG && AllFailedEarlier() )
|
||||
{
|
||||
this->SendScreenMessage( SM_BeginFailed, 0 );
|
||||
@@ -1210,23 +1217,10 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
|
||||
m_StarWipe.CloseWipingRight( SM_None );
|
||||
|
||||
// do they deserve an extra stage?
|
||||
|
||||
bool bTryExtraStage = false;
|
||||
if( (GAMESTATE->IsFinalStage() || GAMESTATE->IsExtraStage()) )
|
||||
{
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
|
||||
continue; // skip
|
||||
|
||||
if( GAMESTATE->m_pCurNotes[p]->GetDifficulty() == DIFFICULTY_HARD && GAMESTATE->GetCurrentGrade((PlayerNumber)p) >= GRADE_AA )
|
||||
bTryExtraStage = true;
|
||||
}
|
||||
}
|
||||
bool bTryExtraStage = GAMESTATE->HasEarnedExtraStage();
|
||||
if( PREFSMAN->m_bEventMode )
|
||||
bTryExtraStage = false;
|
||||
|
||||
|
||||
if( bTryExtraStage )
|
||||
{
|
||||
this->SendScreenMessage( SM_ShowTryExtraStage, 1 );
|
||||
@@ -1458,11 +1452,11 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
|
||||
// show the survive time if extra stage
|
||||
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
||||
{
|
||||
float fMaxSurviveSeconds = -1;
|
||||
float fMaxSurviveSeconds = 0;
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
if( GAMESTATE->IsPlayerEnabled(p) )
|
||||
fMaxSurviveSeconds = max( fMaxSurviveSeconds, GAMESTATE->GetPlayerSurviveTime((PlayerNumber)p) );
|
||||
ASSERT( fMaxSurviveSeconds != -1 );
|
||||
fMaxSurviveSeconds = max( fMaxSurviveSeconds, GAMESTATE->m_CurStageStats.fAliveSeconds[p] );
|
||||
ASSERT( fMaxSurviveSeconds > 0 );
|
||||
m_textSurviveTime.SetText( "TIME " + SecondsToTime(fMaxSurviveSeconds) );
|
||||
m_textSurviveTime.BeginTweening( 0.3f ); // sleep
|
||||
m_textSurviveTime.BeginTweening( 0.3f ); // fade in
|
||||
|
||||
@@ -701,7 +701,7 @@ void ScreenSelectMusic::AfterNotesChange( PlayerNumber pn )
|
||||
Notes* m_pNotes = GAMESTATE->m_pCurNotes[pn];
|
||||
|
||||
if( m_pNotes && SONGMAN->IsUsingMemoryCard(pn) )
|
||||
m_HighScore[pn].SetScore( (float)m_pNotes->m_MemCardScores[pn].iScore );
|
||||
m_HighScore[pn].SetScore( m_pNotes->m_MemCardScores[pn].fScore );
|
||||
|
||||
m_DifficultyIcon[pn].SetFromNotes( pn, pNotes );
|
||||
if( pNotes && pNotes->IsAutogen() )
|
||||
|
||||
+126
-43
@@ -30,6 +30,8 @@ SongManager* SONGMAN = NULL; // global and accessable from anywhere in our progr
|
||||
|
||||
const CString CATEGORY_TOP_SCORE_FILE = "CategoryTopScores.dat";
|
||||
const CString COURSE_TOP_SCORE_FILE = "CourseTopScores.dat";
|
||||
const int CATEGORY_TOP_SCORE_VERSION = 1;
|
||||
const int COURSE_TOP_SCORE_VERSION = 1;
|
||||
|
||||
|
||||
#define NUM_GROUP_COLORS THEME->GetMetricI("SongManager","NumGroupColors")
|
||||
@@ -210,7 +212,7 @@ void SongManager::InitMachineScoresFromDisk()
|
||||
for( int j=0; j<NUM_HIGH_SCORE_CATEGORIES; j++ )
|
||||
for( int k=0; k<NUM_HIGH_SCORE_LINES; k++ )
|
||||
{
|
||||
m_MachineScores[i][j][k].iScore = 573000;
|
||||
m_MachineScores[i][j][k].fScore = 573000;
|
||||
m_MachineScores[i][j][k].sName = "STEP";
|
||||
}
|
||||
}
|
||||
@@ -218,51 +220,62 @@ void SongManager::InitMachineScoresFromDisk()
|
||||
// Read category top scores
|
||||
{
|
||||
FILE* fp = fopen( CATEGORY_TOP_SCORE_FILE, "r" );
|
||||
|
||||
for( int i=0; i<NUM_STYLES; i++ )
|
||||
for( int j=0; j<NUM_HIGH_SCORE_CATEGORIES; j++ )
|
||||
for( int k=0; k<NUM_HIGH_SCORE_LINES; k++ )
|
||||
if( fp && !feof(fp) )
|
||||
{
|
||||
char szName[256];
|
||||
fscanf(fp, "%d %[^\n]\n", &m_MachineScores[i][j][k].iScore, szName);
|
||||
m_MachineScores[i][j][k].sName = szName;
|
||||
}
|
||||
|
||||
if( fp )
|
||||
{
|
||||
int version;
|
||||
fscanf(fp, "%d\n", &version );
|
||||
if( version == CATEGORY_TOP_SCORE_VERSION )
|
||||
{
|
||||
for( int i=0; i<NUM_STYLES; i++ )
|
||||
for( int j=0; j<NUM_HIGH_SCORE_CATEGORIES; j++ )
|
||||
for( int k=0; k<NUM_HIGH_SCORE_LINES; k++ )
|
||||
if( fp && !feof(fp) )
|
||||
{
|
||||
char szName[256];
|
||||
fscanf(fp, "%f %[^\n]\n", &m_MachineScores[i][j][k].fScore, szName);
|
||||
m_MachineScores[i][j][k].sName = szName;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
// Read course top scores
|
||||
{
|
||||
FILE* fp = fopen( COURSE_TOP_SCORE_FILE, "r" );
|
||||
|
||||
while( fp && !feof(fp) )
|
||||
{
|
||||
char szPath[256];
|
||||
fscanf(fp, "%s\n", szPath);
|
||||
Course* pCourse = GetCourseFromPath( szPath );
|
||||
|
||||
for( int i=0; i<NUM_STYLES; i++ )
|
||||
for( int j=0; j<NUM_HIGH_SCORE_CATEGORIES; j++ )
|
||||
for( int k=0; k<NUM_HIGH_SCORE_LINES; k++ )
|
||||
if( fp && !feof(fp) )
|
||||
{
|
||||
int iDancePoints;
|
||||
float fSurviveTime;
|
||||
char szName[256];
|
||||
fscanf(fp, "%d %f %[^\n]\n", &iDancePoints, &fSurviveTime, szName);
|
||||
if( pCourse )
|
||||
{
|
||||
pCourse->m_MachineScores[i][j][k].iDancePoints = iDancePoints;
|
||||
pCourse->m_MachineScores[i][j][k].fSurviveTime = fSurviveTime;
|
||||
pCourse->m_MachineScores[i][j][k].sName = szName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( fp )
|
||||
{
|
||||
int version;
|
||||
fscanf(fp, "%d\n", &version );
|
||||
if( version == COURSE_TOP_SCORE_VERSION )
|
||||
{
|
||||
while( fp && !feof(fp) )
|
||||
{
|
||||
char szPath[256];
|
||||
fscanf(fp, "%s\n", szPath);
|
||||
Course* pCourse = GetCourseFromPath( szPath );
|
||||
|
||||
for( int i=0; i<NUM_STYLES; i++ )
|
||||
for( int j=0; j<NUM_HIGH_SCORE_CATEGORIES; j++ )
|
||||
for( int k=0; k<NUM_HIGH_SCORE_LINES; k++ )
|
||||
if( fp && !feof(fp) )
|
||||
{
|
||||
int iDancePoints;
|
||||
float fSurviveTime;
|
||||
char szName[256];
|
||||
fscanf(fp, "%d %f %[^\n]\n", &iDancePoints, &fSurviveTime, szName);
|
||||
if( pCourse )
|
||||
{
|
||||
pCourse->m_MachineScores[i][j][k].iDancePoints = iDancePoints;
|
||||
pCourse->m_MachineScores[i][j][k].fSurviveTime = fSurviveTime;
|
||||
pCourse->m_MachineScores[i][j][k].sName = szName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,15 +284,16 @@ void SongManager::SaveMachineScoresToDisk()
|
||||
// Write category top scores
|
||||
{
|
||||
FILE* fp = fopen( CATEGORY_TOP_SCORE_FILE, "w" );
|
||||
|
||||
for( int i=0; i<NUM_STYLES; i++ )
|
||||
for( int j=0; j<NUM_HIGH_SCORE_CATEGORIES; j++ )
|
||||
for( int k=0; k<NUM_HIGH_SCORE_LINES; k++ )
|
||||
if( fp )
|
||||
fprintf(fp, "%d %s\n", m_MachineScores[i][j][k].iScore, m_MachineScores[i][j][k].sName.c_str());
|
||||
|
||||
if( fp )
|
||||
{
|
||||
fprintf(fp,"%d",CATEGORY_TOP_SCORE_VERSION);
|
||||
for( int i=0; i<NUM_STYLES; i++ )
|
||||
for( int j=0; j<NUM_HIGH_SCORE_CATEGORIES; j++ )
|
||||
for( int k=0; k<NUM_HIGH_SCORE_LINES; k++ )
|
||||
if( fp )
|
||||
fprintf(fp, "%f %s\n", m_MachineScores[i][j][k].fScore, m_MachineScores[i][j][k].sName.c_str());
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
// Write course top scores
|
||||
@@ -288,6 +302,7 @@ void SongManager::SaveMachineScoresToDisk()
|
||||
|
||||
if( fp )
|
||||
{
|
||||
fprintf(fp,"%d",COURSE_TOP_SCORE_VERSION);
|
||||
for( unsigned i=0; i<m_pCourses.size(); i++ ) // foreach course
|
||||
{
|
||||
Course* pCourse = m_pCourses[i];
|
||||
@@ -616,3 +631,71 @@ bool SongManager::IsUsingMemoryCard( PlayerNumber pn )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SongManager::IsNewMachineRecord( HighScoreCategory hsc, float fScore ) const // return true if this is would be a new machine record
|
||||
{
|
||||
for( int i=0; i<NUM_HIGH_SCORE_LINES; i++ )
|
||||
{
|
||||
const MachineScore& hs = m_MachineScores[GAMESTATE->m_CurStyle][hsc][i];
|
||||
if( fScore > hs.fScore )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct MachineScoreAndPlayerNumber : public SongManager::MachineScore
|
||||
{
|
||||
PlayerNumber pn;
|
||||
|
||||
static int CompareDescending( const MachineScoreAndPlayerNumber &hs1, const MachineScoreAndPlayerNumber &hs2 )
|
||||
{
|
||||
if( hs1.fScore > hs2.fScore ) return -1;
|
||||
else if( hs1.fScore == hs2.fScore ) return 0;
|
||||
else return +1;
|
||||
}
|
||||
static void SortDescending( vector<MachineScoreAndPlayerNumber>& vHSout )
|
||||
{
|
||||
sort( vHSout.begin(), vHSout.end(), CompareDescending );
|
||||
}
|
||||
};
|
||||
|
||||
void SongManager::AddMachineRecord( HighScoreCategory hsc, float fScore[NUM_PLAYERS], int iNewRecordIndexOut[NUM_PLAYERS] ) // set iNewRecordIndex = -1 if not a new record
|
||||
{
|
||||
vector<MachineScoreAndPlayerNumber> vHS;
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
iNewRecordIndexOut[p] = -1;
|
||||
|
||||
if( !GAMESTATE->IsPlayerEnabled(p) )
|
||||
continue; // skip
|
||||
|
||||
MachineScoreAndPlayerNumber hs;
|
||||
hs.fScore = fScore[p];
|
||||
hs.sName = ""; // this must be filled in later!
|
||||
hs.pn = (PlayerNumber)p;
|
||||
vHS.push_back( hs );
|
||||
}
|
||||
|
||||
// Sort descending before inserting.
|
||||
// This guarantees that a high score will not switch poitions on us when we later insert scores for the other player
|
||||
MachineScoreAndPlayerNumber::SortDescending( vHS );
|
||||
|
||||
for( unsigned i=0; i<vHS.size(); i++ )
|
||||
{
|
||||
MachineScoreAndPlayerNumber& newHS = vHS[i];
|
||||
MachineScore* machineScores = m_MachineScores[GAMESTATE->m_CurStyle][GAMESTATE->m_PreferredDifficulty[newHS.pn]];
|
||||
for( int i=0; i<NUM_HIGH_SCORE_LINES; i++ )
|
||||
{
|
||||
if( newHS.fScore > machineScores[i].fScore )
|
||||
{
|
||||
// We found the insert point. Shift down.
|
||||
for( int j=i+1; j<NUM_HIGH_SCORE_LINES; j++ )
|
||||
machineScores[j] = machineScores[j-1];
|
||||
// insert
|
||||
machineScores[i] = newHS;
|
||||
iNewRecordIndexOut[newHS.pn] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,18 +71,24 @@ public:
|
||||
//
|
||||
// High scores
|
||||
//
|
||||
struct HighScore
|
||||
{
|
||||
int iScore;
|
||||
CString sName;
|
||||
};
|
||||
HighScore m_MachineScores[NUM_STYLES][NUM_HIGH_SCORE_CATEGORIES][NUM_HIGH_SCORE_LINES];
|
||||
|
||||
void InitMachineScoresFromDisk();
|
||||
void SaveMachineScoresToDisk();
|
||||
|
||||
bool MemoryCardIsInserted( PlayerNumber pn );
|
||||
bool IsUsingMemoryCard( PlayerNumber pn );
|
||||
|
||||
void LoadMemoryCardScores( PlayerNumber pn );
|
||||
void SaveMemoryCardScores( PlayerNumber pn );
|
||||
|
||||
struct MachineScore
|
||||
{
|
||||
float fScore;
|
||||
CString sName;
|
||||
} m_MachineScores[NUM_STYLES][NUM_HIGH_SCORE_CATEGORIES][NUM_HIGH_SCORE_LINES];
|
||||
|
||||
bool IsNewMachineRecord( HighScoreCategory hsc, float fScore ) const; // return true if this is would be a new machine record
|
||||
void AddMachineRecord( HighScoreCategory hsc, float fScore[NUM_PLAYERS], int iNewRecordIndexOut[NUM_PLAYERS] ); // set iNewRecordIndex = -1 if not a new record
|
||||
|
||||
protected:
|
||||
void LoadStepManiaSongDir( CString sDir, LoadingWindow *ld );
|
||||
void LoadDWISongDir( CString sDir );
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "stdafx.h"
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Class: StageStats
|
||||
|
||||
Desc: See header.
|
||||
|
||||
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
||||
Chris Danford
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "StageStats.h"
|
||||
|
||||
StageStats::StageStats()
|
||||
{
|
||||
memset( this, 0, sizeof(StageStats) );
|
||||
}
|
||||
|
||||
void StageStats::operator+=( const StageStats& other )
|
||||
{
|
||||
pSong = NULL; // meaningless
|
||||
memset( fAliveSeconds, 0, sizeof(fAliveSeconds) );
|
||||
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
iMeter[p] += other.iMeter[p];
|
||||
fAliveSeconds[p] += other.fAliveSeconds[p];
|
||||
bFailed[p] |= other.bFailed[p];
|
||||
iPossibleDancePoints[p] += other.iPossibleDancePoints[p];
|
||||
iActualDancePoints[p] += other.iPossibleDancePoints[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] += iHoldNoteScores[p][h];
|
||||
iMaxCombo[p] += other.iMaxCombo[p];
|
||||
fScore[p] += other.fScore[p];
|
||||
for( int r=0; r<NUM_RADAR_VALUES; r++ )
|
||||
{
|
||||
fRadarPossible[p][r] += other.fRadarPossible[p][r];
|
||||
fRadarActual[p][r] += other.fRadarActual[p][r];
|
||||
}
|
||||
fSecondsBeforeFail[p] += other.fSecondsBeforeFail[p];
|
||||
iSongsPassed[p] += other.iSongsPassed[p];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef StageStats_H
|
||||
#define StageStats_H
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Class: StageStats
|
||||
|
||||
Desc: Contains statistics for one stage of play - either one song, or a whole course.
|
||||
|
||||
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
||||
Chris Danford
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "GameConstantsAndTypes.h" // for NUM_PLAYERS
|
||||
|
||||
class Song;
|
||||
|
||||
struct StageStats
|
||||
{
|
||||
StageStats();
|
||||
void operator+=( const StageStats& other ); // accumulate
|
||||
|
||||
Song* pSong;
|
||||
int iMeter[NUM_PLAYERS];
|
||||
float fAliveSeconds[NUM_PLAYERS]; // how far into the music did they last before failing? Updated by Gameplay.
|
||||
bool bFailed[NUM_PLAYERS]; // true if they have failed at any point during the song
|
||||
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 iMaxCombo[NUM_PLAYERS];
|
||||
float fScore[NUM_PLAYERS];
|
||||
float fRadarPossible[NUM_PLAYERS][NUM_RADAR_VALUES]; // filled in by ScreenGameplay on start of notes
|
||||
float fRadarActual[NUM_PLAYERS][NUM_RADAR_VALUES]; // filled in by ScreenGameplay on start of notes
|
||||
float fSecondsBeforeFail[NUM_PLAYERS]; // -1 means didn't/hasn't failed
|
||||
int iSongsPassed[NUM_PLAYERS]; // For course, this is the number of songs that the player has passed
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -604,6 +604,12 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||
<File
|
||||
RelativePath="SongOptions.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="StageStats.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="StageStats.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Style.h">
|
||||
</File>
|
||||
|
||||
Reference in New Issue
Block a user