Store unlock data in a more fundamental form in the profile, and derive

the special values as needed.  Centralize most of it in GameState::EndGame.
This commit is contained in:
Glenn Maynard
2004-02-22 08:16:49 +00:00
parent 066826e421
commit 802e1a6758
10 changed files with 228 additions and 207 deletions
+26
View File
@@ -245,6 +245,19 @@ void GameState::EndGame()
pMachineProfile->m_iNumSongsPlayedByStyle[ss.style]++;
pMachineProfile->m_iNumSongsPlayedByDifficulty[ss.pSteps[p]->GetDifficulty()]++;
pMachineProfile->m_iNumSongsPlayedByMeter[iMeter]++;
pMachineProfile->m_iTotalDancePoints += ss.iActualDancePoints[p];
if( ss.StageType == StageStats::STAGE_EXTRA || ss.StageType == StageStats::STAGE_EXTRA2 )
{
if( ss.bFailed[p] )
++pMachineProfile->m_iNumExtraStagesFailed;
else
++pMachineProfile->m_iNumExtraStagesPassed;
}
if( !ss.bFailed[p] )
{
pMachineProfile->m_iNumSongsPassedByPlayMode[ss.playMode]++;
pMachineProfile->m_iNumSongsPassedByGrade[ss.GetGrade((PlayerNumber)p)]++;
}
if( pPlayerProfile )
{
@@ -252,6 +265,19 @@ void GameState::EndGame()
pPlayerProfile->m_iNumSongsPlayedByStyle[ss.style]++;
pPlayerProfile->m_iNumSongsPlayedByDifficulty[ss.pSteps[p]->GetDifficulty()]++;
pPlayerProfile->m_iNumSongsPlayedByMeter[iMeter]++;
pPlayerProfile->m_iTotalDancePoints += ss.iActualDancePoints[p];
if( ss.StageType == StageStats::STAGE_EXTRA || ss.StageType == StageStats::STAGE_EXTRA2 )
{
if( ss.bFailed[p] )
++pPlayerProfile->m_iNumExtraStagesFailed;
else
++pPlayerProfile->m_iNumExtraStagesPassed;
}
if( !ss.bFailed[p] )
{
pPlayerProfile->m_iNumSongsPassedByPlayMode[ss.playMode]++;
pPlayerProfile->m_iNumSongsPassedByGrade[ss.GetGrade((PlayerNumber)p)]++;
}
}
}
+74 -1
View File
@@ -72,6 +72,11 @@ void Profile::InitGeneralData()
m_iTotalGameplaySeconds = 0;
m_iCurrentCombo = 0;
m_fCaloriesBurned = 0;
m_iTotalDancePoints = 0;
m_iNumExtraStagesPassed = 0;
m_iNumExtraStagesFailed = 0;
m_iNumToasties = 0;
m_UnlockedSongs.clear();
m_sLastMachinePlayed = "";
int i;
@@ -83,6 +88,8 @@ void Profile::InitGeneralData()
m_iNumSongsPlayedByDifficulty[i] = 0;
for( i=0; i<MAX_METER+1; i++ )
m_iNumSongsPlayedByMeter[i] = 0;
ZERO( m_iNumSongsPassedByPlayMode );
ZERO( m_iNumSongsPassedByGrade );
}
void Profile::InitSongScores()
@@ -125,7 +132,7 @@ CString Profile::GetDisplayCaloriesBurned()
return ssprintf("%iCal",m_fCaloriesBurned);
}
int Profile::GetTotalNumSongsPlayed()
int Profile::GetTotalNumSongsPlayed() const
{
int iTotal = 0;
for( int i=0; i<NUM_PLAY_MODES; i++ )
@@ -133,6 +140,14 @@ int Profile::GetTotalNumSongsPlayed()
return iTotal;
}
int Profile::GetTotalNumSongsPassed() const
{
int iTotal = 0;
for( int i=0; i<NUM_PLAY_MODES; i++ )
iTotal += m_iNumSongsPassedByPlayMode[i];
return iTotal;
}
CString Profile::GetProfileDisplayNameFromDir( CString sDir )
{
Profile profile;
@@ -478,6 +493,16 @@ XNode* Profile::SaveGeneralDataCreateNode() const
pGeneralDataNode->AppendChild( "CurrentCombo", m_iCurrentCombo );
pGeneralDataNode->AppendChild( "CaloriesBurned", m_fCaloriesBurned );
pGeneralDataNode->AppendChild( "LastMachinePlayed", m_sLastMachinePlayed );
pGeneralDataNode->AppendChild( "TotalDancePoints", m_iTotalDancePoints );
pGeneralDataNode->AppendChild( "NumExtraStagesPassed", m_iNumExtraStagesPassed );
pGeneralDataNode->AppendChild( "NumExtraStagesFailed", m_iNumExtraStagesFailed );
pGeneralDataNode->AppendChild( "NumToasties", m_iNumToasties );
{
XNode* pUnlockedSongs = pGeneralDataNode->AppendChild("UnlockedSongs");
for( set<int>::const_iterator it = m_UnlockedSongs.begin(); it != m_UnlockedSongs.end(); ++it )
pUnlockedSongs->AppendChild( ssprintf("%i", *it) );
}
{
XNode* pNumSongsPlayedByPlayMode = pGeneralDataNode->AppendChild("NumSongsPlayedByPlayMode");
@@ -528,6 +553,26 @@ XNode* Profile::SaveGeneralDataCreateNode() const
}
}
{
XNode* pNumSongsPassedByGrade = pGeneralDataNode->AppendChild("NumSongsPassedByGrade");
FOREACH_Grade( g )
{
if( !m_iNumSongsPassedByGrade[g] )
continue;
pNumSongsPassedByGrade->AppendChild( GradeToString(g), m_iNumSongsPassedByGrade[g] );
}
}
{
XNode* pNumSongsPassedByPlayMode = pGeneralDataNode->AppendChild("NumSongsPassedByPlayMode");
FOREACH_PlayMode( pm )
{
/* Don't save unplayed PlayModes. */
if( !m_iNumSongsPassedByPlayMode[pm] )
continue;
pNumSongsPassedByPlayMode->AppendChild( PlayModeToString(pm), m_iNumSongsPassedByPlayMode[pm] );
}
}
return pGeneralDataNode;
}
@@ -575,6 +620,19 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode )
pNode->GetChildValue( "CurrentCombo", m_iCurrentCombo );
pNode->GetChildValue( "CaloriesBurned", m_fCaloriesBurned );
pNode->GetChildValue( "LastMachinePlayed", m_sLastMachinePlayed );
pNode->GetChildValue( "TotalDancePoints", m_iTotalDancePoints );
pNode->GetChildValue( "NumExtraStagesPassed", m_iNumExtraStagesPassed );
pNode->GetChildValue( "NumExtraStagesFailed", m_iNumExtraStagesFailed );
pNode->GetChildValue( "NumToasties", m_iNumToasties );
{
XNode* pUnlockedSongs = pNode->GetChild("UnlockedSongs");
if( pUnlockedSongs )
{
FOREACH_Node( pUnlockedSongs, song )
m_UnlockedSongs.insert( atoi(song->name) );
}
}
{
XNode* pNumSongsPlayedByPlayMode = pNode->GetChild("NumSongsPlayedByPlayMode");
@@ -623,6 +681,21 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode )
for( int i=0; i<MAX_METER+1; i++ )
pNumSongsPlayedByMeter->GetChildValue( ssprintf("Meter%d",i), m_iNumSongsPlayedByMeter[i] );
}
{
XNode* pNumSongsPassedByGrade = pNode->GetChild("NumSongsPassedByGrade");
if( pNumSongsPassedByGrade )
FOREACH_Grade( g )
pNumSongsPassedByGrade->GetChildValue( GradeToString(g), m_iNumSongsPassedByGrade[g] );
}
{
XNode* pNumSongsPassedByPlayMode = pNode->GetChild("NumSongsPassedByPlayMode");
if( pNumSongsPassedByPlayMode )
FOREACH_PlayMode( pm )
pNumSongsPassedByPlayMode->GetChildValue( PlayModeToString(pm), m_iNumSongsPassedByPlayMode[pm] );
}
}
+10 -1
View File
@@ -16,6 +16,7 @@
#include "Style.h"
#include "Grade.h"
#include <map>
#include <set>
#include "XmlFile.h"
#include "HighScore.h"
@@ -66,7 +67,8 @@ public:
//
CString GetDisplayName() const;
CString GetDisplayCaloriesBurned();
int GetTotalNumSongsPlayed();
int GetTotalNumSongsPlayed() const;
int GetTotalNumSongsPassed() const;
static CString GetProfileDisplayNameFromDir( CString sDir );
int GetSongNumTimesPlayed( const Song* pSong ) const;
@@ -87,11 +89,18 @@ public:
int m_iTotalGameplaySeconds;
int m_iCurrentCombo;
int m_fCaloriesBurned;
int m_iTotalDancePoints;
int m_iNumExtraStagesPassed;
int m_iNumExtraStagesFailed;
int m_iNumToasties;
set<int> m_UnlockedSongs;
mutable CString m_sLastMachinePlayed; // mutable because we overwrite this on save, and I don't want to remove const from the whole save chain. -Chris
int m_iNumSongsPlayedByPlayMode[NUM_PLAY_MODES];
int m_iNumSongsPlayedByStyle[NUM_STYLES];
int m_iNumSongsPlayedByDifficulty[NUM_DIFFICULTIES];
int m_iNumSongsPlayedByMeter[MAX_METER+1];
int m_iNumSongsPassedByPlayMode[NUM_PLAY_MODES];
int m_iNumSongsPassedByGrade[NUM_GRADES];
//
+9
View File
@@ -426,6 +426,15 @@ const Profile* ProfileManager::GetProfile( ProfileSlot slot ) const
}
}
//
// General
//
void ProfileManager::IncrementToastiesCount( PlayerNumber pn )
{
if( PROFILEMAN->IsUsingProfile(pn) )
++PROFILEMAN->GetProfile(pn)->m_iNumToasties;
++PROFILEMAN->GetMachineProfile()->m_iNumToasties;
}
//
// Song stats
+6
View File
@@ -37,6 +37,12 @@ public:
bool LoadProfileFromMemoryCard( PlayerNumber pn );
bool SaveProfile( PlayerNumber pn ) const;
void UnloadProfile( PlayerNumber pn );
//
// General data
//
void IncrementToastiesCount( PlayerNumber pn );
//
// High scores
+2 -2
View File
@@ -18,12 +18,12 @@
#include "ScreenGameplay.h"
#include "GameState.h"
#include "Course.h"
#include "UnlockSystem.h"
#include "SDL_utils.h"
#include "SongManager.h"
#include "NoteDataUtil.h"
#include "RageLog.h"
#include "StageStats.h"
#include "ProfileManager.h"
ScoreKeeperMAX2::ScoreKeeperMAX2( const vector<Song*>& apSongs, const vector<Steps*>& apNotes_, const vector<AttackArray> &asModifiers, PlayerNumber pn_ ):
@@ -391,7 +391,7 @@ void ScoreKeeperMAX2::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa
if( m_iCurToastyCombo==250 && !GAMESTATE->m_bDemonstrationOrJukebox )
{
SCREENMAN->PostMessageToTopScreen( SM_PlayToasty, 0 );
UNLOCKMAN->UnlockToasty();
PROFILEMAN->IncrementToastiesCount( m_PlayerNumber );
}
break;
default:
-28
View File
@@ -219,34 +219,6 @@ void ScreenEvaluation::Init()
}
for( p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
continue; // skip
switch( m_Type )
{
case stage:
// update unlock data
UNLOCKMAN->UnlockClearStage();
UNLOCKMAN->UnlockAddAP( grade[p] );
UNLOCKMAN->UnlockAddSP( grade[p] );
UNLOCKMAN->UnlockAddDP( (float)stageStats.iActualDancePoints[p] );
// if it's extra stage, update # passed stages
if ( (GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() ) &&
grade[p] > GRADE_FAILED )
UNLOCKMAN->UnlockClearExtraStage();
break;
case course:
UNLOCKMAN->UnlockAddDP( (float) stageStats.iActualDancePoints[p] );
UNLOCKMAN->UnlockAddAP( (float) stageStats.iSongsPassed[p] );
UNLOCKMAN->UnlockAddSP( (float) stageStats.iSongsPassed[p] );
break;
}
}
//
// update persistent statistics
//
-3
View File
@@ -2135,9 +2135,6 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
ASSERT( fMaxSurviveSeconds > 0 );
m_textSurviveTime.SetText( "TIME: " + SecondsToTime(fMaxSurviveSeconds) );
SET_XY_AND_ON_COMMAND( m_textSurviveTime );
// Increment update failed extra stage count.
UNLOCKMAN->UnlockFailExtraStage();
}
// Feels hackish. Feel free to make cleaner.
+97 -155
View File
@@ -21,6 +21,7 @@
#include "GameState.h"
#include "IniFile.h"
#include "MsdFile.h"
#include "ProfileManager.h"
UnlockSystem* UNLOCKMAN = NULL; // global and accessable from anywhere in our program
@@ -43,12 +44,6 @@ UnlockSystem::UnlockSystem()
UNLOCKMAN = this;
Load();
memset( m_fScores, 0, sizeof(m_fScores) );
ReadValues(); // in case its ever accessed,
// we want the values to be available
WriteValues(); // create if it does not exist
}
void UnlockSystem::UnlockSong( const Song *song )
@@ -140,14 +135,97 @@ UnlockEntry::UnlockEntry()
m_pCourse = NULL;
}
static float GetArcadePoints( const Profile *pProfile )
{
float fAP = 0;
FOREACH_Grade(g)
{
switch(g)
{
case GRADE_TIER_1:
case GRADE_TIER_2: fAP += 9 * pProfile->m_iNumSongsPassedByGrade[g]; break;
default: fAP += 1 * pProfile->m_iNumSongsPassedByGrade[g]; break;
case GRADE_FAILED:
case GRADE_NO_DATA:
; // no points
break;
}
}
FOREACH_PlayMode(pm)
{
switch(pm)
{
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
fAP += pProfile->m_iNumSongsPlayedByPlayMode[pm];
break;
}
}
return fAP;
}
static float GetSongPoints( const Profile *pProfile )
{
float fSP = 0;
FOREACH_Grade(g)
{
switch( g )
{
case GRADE_TIER_1:/*AAAA*/ fSP += 20 * pProfile->m_iNumSongsPassedByGrade[g]; break;
case GRADE_TIER_2:/*AAA*/ fSP += 10* pProfile->m_iNumSongsPassedByGrade[g]; break;
case GRADE_TIER_3:/*AA*/ fSP += 5* pProfile->m_iNumSongsPassedByGrade[g]; break;
case GRADE_TIER_4:/*A*/ fSP += 4* pProfile->m_iNumSongsPassedByGrade[g]; break;
case GRADE_TIER_5:/*B*/ fSP += 3* pProfile->m_iNumSongsPassedByGrade[g]; break;
case GRADE_TIER_6:/*C*/ fSP += 2* pProfile->m_iNumSongsPassedByGrade[g]; break;
case GRADE_TIER_7:/*D*/ fSP += 1* pProfile->m_iNumSongsPassedByGrade[g]; break;
case GRADE_FAILED:
case GRADE_NO_DATA:
; // no points
break;
}
}
FOREACH_PlayMode(pm)
{
switch(pm)
{
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
fSP += pProfile->m_iNumSongsPlayedByPlayMode[pm];
break;
}
}
return fSP;
}
void UnlockSystem::GetPoints( const Profile *pProfile, float fScores[NUM_UNLOCK_TYPES] ) const
{
fScores[UNLOCK_ARCADE_POINTS] = GetArcadePoints( pProfile );
fScores[UNLOCK_SONG_POINTS] = GetSongPoints( pProfile );
fScores[UNLOCK_DANCE_POINTS] = (float) pProfile->m_iTotalDancePoints;
fScores[UNLOCK_CLEARED] = (float) pProfile->GetTotalNumSongsPassed();
}
bool UnlockEntry::IsLocked() const
{
float fScores[NUM_UNLOCK_TYPES];
UNLOCKMAN->GetPoints( PROFILEMAN->GetMachineProfile(), fScores );
for( int i = 0; i < NUM_UNLOCK_TYPES; ++i )
if( m_fRequired[i] && UNLOCKMAN->m_fScores[i] >= m_fRequired[i] )
if( m_fRequired[i] && fScores[i] >= m_fRequired[i] )
return false;
if( m_iCode != -1 && UNLOCKMAN->m_UnlockedCodes.find(m_iCode) != UNLOCKMAN->m_UnlockedCodes.end() )
if( m_iCode != -1 && PROFILEMAN->GetMachineProfile()->m_UnlockedSongs.find(m_iCode) != PROFILEMAN->GetMachineProfile()->m_UnlockedSongs.end() )
return false;
return true;
@@ -239,7 +317,7 @@ bool UnlockSystem::Load()
current.m_iCode = (int) val;
if( unlock_type == "RO" )
{
m_UnlockedCodes.insert( (int)val );
current.m_iCode = (int)val;
m_RouletteCodes.insert( (int)val );
}
}
@@ -271,14 +349,17 @@ bool UnlockSystem::Load()
float UnlockSystem::PointsUntilNextUnlock( UnlockType t ) const
{
float fScores[NUM_UNLOCK_TYPES];
UNLOCKMAN->GetPoints( PROFILEMAN->GetMachineProfile(), fScores );
float fSmallestPoints = 400000000; // or an arbitrarily large value
for( unsigned a=0; a<m_SongEntries.size(); a++ )
if( m_SongEntries[a].m_fRequired[t] > m_fScores[t] )
if( m_SongEntries[a].m_fRequired[t] > fScores[t] )
fSmallestPoints = min( fSmallestPoints, m_SongEntries[a].m_fRequired[t] );
if( fSmallestPoints == 400000000 )
return 0; // no match found
return fSmallestPoints - m_fScores[t];
return fSmallestPoints - fScores[t];
}
/* Update the song pointer. Only call this when it's likely to have changed,
@@ -304,154 +385,15 @@ void UnlockSystem::UpdateSongs()
}
}
bool UnlockSystem::ReadValues()
{
IniFile data;
data.SetPath( MEMCARD_PATH );
if( !data.ReadFile() )
return false;
for( int i = 0; i < NUM_UNLOCK_TYPES; ++i )
data.GetValue( "Unlock", g_UnlockNames[i], m_fScores[i] );
m_UnlockedCodes.clear();
CString s;
if( data.GetValue( "Unlock", "UnlockedCodes", s ) )
{
vector<CString> sCodes;
split( s, ",", sCodes, true );
for( unsigned c = 0; c < sCodes.size(); ++c )
{
const int n = atoi( sCodes[c] );
m_UnlockedCodes.insert( n );
}
}
return true;
}
bool UnlockSystem::WriteValues() const
{
IniFile data;
data.SetPath( MEMCARD_PATH );
for( int i = 0; i < NUM_UNLOCK_TYPES; ++i )
data.SetValue( "Unlock", g_UnlockNames[i], m_fScores[i] );
vector<CString> sCodes;
for( set<int>::const_iterator it = m_UnlockedCodes.begin(); it != m_UnlockedCodes.end(); ++it )
sCodes.push_back( ssprintf("%i", *it) );
const CString list = join( ",", sCodes );
data.SetValue( "Unlock", "UnlockedCodes", list );
data.WriteFile();
return true;
}
void UnlockSystem::UnlockAddAP(float credit)
{
ReadValues();
m_fScores[UNLOCK_ARCADE_POINTS] += credit;
WriteValues();
}
void UnlockSystem::UnlockAddAP(Grade grade)
{
ReadValues();
switch( grade )
{
case GRADE_FAILED:
; // no points
break;
case GRADE_TIER_1:
case GRADE_TIER_2:
m_fScores[UNLOCK_ARCADE_POINTS] += 9;
break;
case GRADE_NO_DATA:
ASSERT(0);
break;
default:
m_fScores[UNLOCK_ARCADE_POINTS] += 1;
break;
}
WriteValues();
}
void UnlockSystem::UnlockAddDP(float credit)
{
ReadValues();
// we don't want to ever take away dance points
if( credit > 0 )
m_fScores[UNLOCK_DANCE_POINTS] += credit;
WriteValues();
}
void UnlockSystem::UnlockAddSP(float credit)
{
ReadValues();
m_fScores[UNLOCK_SONG_POINTS] += credit;
WriteValues();
}
void UnlockSystem::UnlockAddSP( Grade grade )
{
ReadValues();
// TODO: move these to PREFS
switch( grade )
{
case GRADE_TIER_1:/*AAAA*/ m_fScores[UNLOCK_SONG_POINTS] += 20; break;
case GRADE_TIER_2:/*AAA*/ m_fScores[UNLOCK_SONG_POINTS] += 10; break;
case GRADE_TIER_3:/*AA*/ m_fScores[UNLOCK_SONG_POINTS] += 5; break;
case GRADE_TIER_4:/*A*/ m_fScores[UNLOCK_SONG_POINTS] += 4; break;
case GRADE_TIER_5:/*B*/ m_fScores[UNLOCK_SONG_POINTS] += 3; break;
case GRADE_TIER_6:/*C*/ m_fScores[UNLOCK_SONG_POINTS] += 2; break;
case GRADE_TIER_7:/*D*/ m_fScores[UNLOCK_SONG_POINTS] += 1; break;
}
WriteValues();
}
void UnlockSystem::UnlockClearExtraStage()
{
ReadValues();
++m_fScores[UNLOCK_EXTRA_CLEARED];
WriteValues();
}
void UnlockSystem::UnlockFailExtraStage()
{
ReadValues();
++m_fScores[UNLOCK_EXTRA_FAILED];
WriteValues();
}
void UnlockSystem::UnlockClearStage()
{
ReadValues();
++m_fScores[UNLOCK_CLEARED];
WriteValues();
}
void UnlockSystem::UnlockToasty()
{
ReadValues();
++m_fScores[UNLOCK_TOASTY];
WriteValues();
}
void UnlockSystem::UnlockCode( int num )
{
ReadValues();
m_UnlockedCodes.insert( num );
WriteValues();
FOREACH_PlayerNumber( pn )
if( PROFILEMAN->IsUsingProfile(pn) )
PROFILEMAN->GetProfile(pn)->m_UnlockedSongs.insert( num );
PROFILEMAN->GetMachineProfile()->m_UnlockedSongs.insert( num );
}
int UnlockSystem::GetNumUnlocks() const
+4 -17
View File
@@ -17,6 +17,7 @@
*/
class Song;
class Profile;
enum UnlockType
{
@@ -73,17 +74,6 @@ public:
void UpdateSongs();
// functions that add to values
void UnlockAddAP(Grade credit);
void UnlockAddAP(float credit);
void UnlockAddDP(float credit);
void UnlockAddSP(Grade credit);
void UnlockAddSP(float credit);
void UnlockClearExtraStage();
void UnlockFailExtraStage();
void UnlockClearStage();
void UnlockToasty();
void UnlockCode( int num );
// unlocks the song's code
@@ -94,18 +84,15 @@ public:
// All locked songs are stored here
vector<UnlockEntry> m_SongEntries;
void GetPoints( const Profile *pProfile, float fScores[NUM_UNLOCK_TYPES] ) const;
private:
// read and write unlocks
// read unlocks
bool Load();
bool ReadValues();
bool WriteValues() const;
UnlockEntry *FindSong( const Song *pSong );
UnlockEntry *FindCourse( const Course *pCourse );
// unlock values, cached
float m_fScores[NUM_UNLOCK_TYPES];
set<int> m_UnlockedCodes;
set<int> m_RouletteCodes; // "codes" which are available in roulette and which unlock if rouletted
};