2004-02-08 18:25:30 +00:00
#ifndef Profile_H
#define Profile_H
/*
-----------------------------------------------------------------------------
Class: Profile
Desc: Player data that persists between sessions. Can be stored on a local
disk or on a memory card.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "GameConstantsAndTypes.h"
#include "Style.h"
2004-02-09 06:26:13 +00:00
#include "Grade.h"
#include <map>
2004-02-22 08:16:49 +00:00
#include <set>
2004-02-10 09:42:01 +00:00
#include "XmlFile.h"
#include "HighScore.h"
2004-02-22 20:44:33 +00:00
#include "TimeConstants.h"
2004-04-18 18:42:42 +00:00
#include "SongUtil.h" // for SongID
#include "StepsUtil.h" // for StepsID
2004-02-09 06:26:13 +00:00
2004-02-22 02:15:34 +00:00
//
// Current file versions
//
const CString STATS_XML = "Stats.xml" ;
const CString EDITABLE_INI = "Editable.ini" ;
// Editable data is an INI because the default INI file association on Windows
// systems will open the ini file in an editor. The default association for
// XML will open in IE. Users have a much better chance of discovering how to
// edit this data if they don't have to fight against the file associations.
const CString DONT_SHARE_SIG = "DontShare.sig" ;
// The "don't share" file is something that the user should always keep private.
// They can safely share STATS_XML with STATS_XML's signature so that others
// can authenticate the STATS_XML data. However, others can't copy that data
// to their own profile for use in the game unless they also have the "don't
// share" file. DontShare contains a piece of information that we can
// construct using STATS_XML but the user can't construct using STATS_XML.
// The file contains a signature of the STATS_XML's signature.
const CString PUBLIC_KEY_FILE = "public.key" ;
const CString SCREENSHOTS_SUBDIR = "Screenshots/" ;
const CString EDITS_SUBDIR = "Edits/" ;
#define REASONABLE_EDITABLE_INI_SIZE_BYTES 2*1000 // 2KB
#define REASONABLE_STATS_XML_SIZE_BYTES 5*1000*1000 // 5MB
2004-02-10 09:42:01 +00:00
class Song ;
2004-02-09 06:26:13 +00:00
class Steps ;
class Course ;
2004-02-10 09:42:01 +00:00
class Profile
2004-02-09 06:26:13 +00:00
{
2004-02-10 09:42:01 +00:00
public :
Profile ()
2004-02-09 06:26:13 +00:00
{
2004-02-10 09:42:01 +00:00
InitAll ();
2004-02-08 18:25:30 +00:00
}
2004-02-10 09:42:01 +00:00
//
// smart accessors
//
2004-02-16 05:35:06 +00:00
CString GetDisplayName () const ;
2004-02-22 20:58:39 +00:00
CString GetDisplayTotalCaloriesBurned () const ;
2004-02-22 08:16:49 +00:00
int GetTotalNumSongsPlayed () const ;
int GetTotalNumSongsPassed () const ;
2004-03-11 06:31:30 +00:00
int GetTotalHighScoreDancePointsForStepsType ( StepsType st ) const ;
2004-02-10 09:42:01 +00:00
static CString GetProfileDisplayNameFromDir ( CString sDir );
2004-02-10 10:06:34 +00:00
int GetSongNumTimesPlayed ( const Song * pSong ) const ;
2004-04-18 18:42:42 +00:00
int GetSongNumTimesPlayed ( const SongID & songID ) const ;
2004-02-22 23:29:13 +00:00
void AddStepTotals ( int iNumTapsAndHolds , int iNumJumps , int iNumHolds , int iNumMines , int iNumHands );
2004-02-08 18:25:30 +00:00
2004-02-19 03:19:41 +00:00
//
// Editable data
//
CString m_sDisplayName ;
2004-02-22 02:15:34 +00:00
CString m_sLastUsedHighScoreName ; // this doesn't really belong in "editable", but we need it in the smaller editable file so that it can be ready quickly.
2004-02-23 04:53:02 +00:00
int m_iWeightPounds ;
2004-02-19 03:19:41 +00:00
2004-02-10 09:42:01 +00:00
//
// General data
//
2004-04-18 05:46:43 +00:00
CString m_sGuid ;
2004-02-08 18:25:30 +00:00
bool m_bUsingProfileDefaultModifiers ;
CString m_sDefaultModifiers ;
2004-03-12 08:31:40 +00:00
SortOrder m_SortOrder ;
2004-03-25 09:54:28 +00:00
Difficulty m_LastDifficulty ;
CourseDifficulty m_LastCourseDifficulty ;
Song * m_pLastSong ;
2004-02-08 18:25:30 +00:00
int m_iTotalPlays ;
int m_iTotalPlaySeconds ;
int m_iTotalGameplaySeconds ;
int m_iCurrentCombo ;
2004-02-22 21:23:04 +00:00
float m_fTotalCaloriesBurned ;
2004-02-22 08:16:49 +00:00
int m_iTotalDancePoints ;
int m_iNumExtraStagesPassed ;
int m_iNumExtraStagesFailed ;
int m_iNumToasties ;
2004-02-22 19:54:59 +00:00
int m_iTotalTapsAndHolds ;
int m_iTotalJumps ;
int m_iTotalHolds ;
int m_iTotalMines ;
int m_iTotalHands ;
2004-02-22 08:16:49 +00:00
set < int > m_UnlockedSongs ;
2004-04-18 05:46:43 +00:00
mutable CString m_sLastPlayedMachineGuid ; // mutable because we overwrite this on save, and I don't want to remove const from the whole save chain. -Chris
2004-02-08 18:25:30 +00:00
int m_iNumSongsPlayedByPlayMode [ NUM_PLAY_MODES ];
int m_iNumSongsPlayedByStyle [ NUM_STYLES ];
int m_iNumSongsPlayedByDifficulty [ NUM_DIFFICULTIES ];
int m_iNumSongsPlayedByMeter [ MAX_METER + 1 ];
2004-02-22 08:16:49 +00:00
int m_iNumSongsPassedByPlayMode [ NUM_PLAY_MODES ];
int m_iNumSongsPassedByGrade [ NUM_GRADES ];
2004-02-09 06:26:13 +00:00
//
2004-04-18 18:42:42 +00:00
// Song high scores
2004-02-09 06:26:13 +00:00
//
struct HighScoresForASteps
{
HighScoreList hs ;
};
2004-04-18 18:42:42 +00:00
struct HighScoresForASong
{
std :: map < StepsID , HighScoresForASteps > m_StepsHighScores ;
};
std :: map < SongID , HighScoresForASong > m_SongHighScores ;
2004-02-09 06:26:13 +00:00
2004-04-18 18:42:42 +00:00
void AddStepsHighScore ( const Song * pSong , const Steps * pSteps , HighScore hs , int & iIndexOut );
const HighScoreList & GetStepsHighScoreList ( const Song * pSong , const Steps * pSteps ) const ;
HighScoreList & GetStepsHighScoreList ( const Song * pSong , const Steps * pSteps );
int GetStepsNumTimesPlayed ( const Song * pSong , const Steps * pSteps ) const ;
void IncrementStepsPlayCount ( const Song * pSong , const Steps * pSteps );
2004-02-09 06:26:13 +00:00
//
// Course high scores
//
// struct was a typedef'd array of HighScores, but VC6 freaks out
// in processing the templates for map::operator[].
struct HighScoresForACourse
{
2004-02-22 06:04:01 +00:00
HighScoreList hs [ NUM_STEPS_TYPES ][ NUM_COURSE_DIFFICULTIES ];
2004-02-09 06:26:13 +00:00
};
std :: map < const Course * , HighScoresForACourse > m_CourseHighScores ;
2004-02-22 06:04:01 +00:00
void AddCourseHighScore ( const Course * pCourse , StepsType st , CourseDifficulty cd , HighScore hs , int & iIndexOut );
HighScoreList & GetCourseHighScoreList ( const Course * pCourse , StepsType st , CourseDifficulty cd );
const HighScoreList & GetCourseHighScoreList ( const Course * pCourse , StepsType st , CourseDifficulty cd ) const ;
2004-02-09 06:26:13 +00:00
int GetCourseNumTimesPlayed ( const Course * pCourse ) const ;
2004-02-22 06:04:01 +00:00
void IncrementCoursePlayCount ( const Course * pCourse , StepsType st , CourseDifficulty cd );
2004-02-09 06:26:13 +00:00
//
// Category high scores
//
HighScoreList m_CategoryHighScores [ NUM_STEPS_TYPES ][ NUM_RANKING_CATEGORIES ];
void AddCategoryHighScore ( StepsType st , RankingCategory rc , HighScore hs , int & iIndexOut );
HighScoreList & GetCategoryHighScoreList ( StepsType st , RankingCategory rc );
2004-02-10 10:06:34 +00:00
const HighScoreList & GetCategoryHighScoreList ( StepsType st , RankingCategory rc ) const ;
2004-02-10 09:42:01 +00:00
int GetCategoryNumTimesPlayed ( StepsType st ) const ;
2004-02-09 06:26:13 +00:00
void IncrementCategoryPlayCount ( StepsType st , RankingCategory rc );
2004-02-10 09:42:01 +00:00
2004-02-17 01:16:57 +00:00
//
// Screenshot Data
//
struct Screenshot
{
2004-03-14 17:49:38 +00:00
CString sFileName ; // no directory part - just the file name
CString sMD5 ; // MD5 hash of the screenshot file
time_t time ; // return value of time() when screenshot was taken
2004-04-18 05:46:43 +00:00
CString sMachineGuid ; // where this screenshot was taken
2004-02-17 01:16:57 +00:00
};
vector < Screenshot > m_vScreenshots ;
void AddScreenshot ( Screenshot screenshot );
2004-02-22 05:04:11 +00:00
int GetNextScreenshotIndex () { return m_vScreenshots . size (); }
2004-02-17 01:16:57 +00:00
2004-02-22 23:29:13 +00:00
//
// Calorie Data
//
// Why track calories in a map, and not in a static sized array like
// Bookkeeping? The machine's clock is not guaranteed to be set correctly.
// If calorie array is in a static sized array, playing on a machine with
// a mis-set clock could wipe out all your past data. With this scheme,
// the worst that could happen is that playing on a mis-set machine will
// insert some garbage entries into the map.
struct Day
{
int iDayInYear ; // 0-365
int iYear ; // e.g. 2004
bool operator == ( const Day & other ) const { return iDayInYear == other . iDayInYear && iYear == other . iYear ; }
bool operator < ( const Day & other ) const
{
if ( iYear < other . iYear )
return true ;
if ( iYear > other . iYear )
return false ;
else
return iDayInYear < other . iDayInYear ;
}
};
map < Day , float > m_mapDayToCaloriesBurned ;
float GetCaloriesBurnedForDay ( Day day ) const ;
2004-02-17 01:16:57 +00:00
2004-03-07 04:34:49 +00:00
//
// Awards
//
struct AwardRecord
{
time_t first ;
time_t last ;
int iCount ; // num times achieved
AwardRecord () { Unset (); }
bool IsSet () const { return iCount > 0 ; }
void Set ( time_t t ) { if ( iCount == 0 ) first = t ; last = t ; iCount ++ ; }
void Unset () { iCount = 0 ; first = - 1 ; last = - 1 ; }
XNode * CreateNode () const ;
void LoadFromNode ( const XNode * pNode );
};
AwardRecord m_PerDifficultyAwards [ NUM_STEPS_TYPES ][ NUM_DIFFICULTIES ][ NUM_PER_DIFFICULTY_AWARDS ];
AwardRecord m_PeakComboAwards [ NUM_PEAK_COMBO_AWARDS ];
void AddPerDifficultyAward ( StepsType st , Difficulty dc , PerDifficultyAward pda );
void AddPeakComboAward ( PeakComboAward pca );
bool HasPerDifficultyAward ( StepsType st , Difficulty dc , PerDifficultyAward pda );
bool HasPeakComboAward ( PeakComboAward pca );
2004-02-10 09:42:01 +00:00
//
// Init'ing
//
void InitAll ()
{
2004-02-19 03:19:41 +00:00
InitEditableData ();
2004-02-10 09:42:01 +00:00
InitGeneralData ();
InitSongScores ();
InitCourseScores ();
InitCategoryScores ();
2004-02-17 01:16:57 +00:00
InitScreenshotData ();
2004-02-22 23:29:13 +00:00
InitCalorieData ();
2004-03-07 04:34:49 +00:00
InitAwards ();
2004-02-10 09:42:01 +00:00
}
2004-02-19 03:19:41 +00:00
void InitEditableData ();
2004-02-10 09:42:01 +00:00
void InitGeneralData ();
void InitSongScores ();
void InitCourseScores ();
void InitCategoryScores ();
2004-02-17 01:16:57 +00:00
void InitScreenshotData ();
2004-02-22 23:29:13 +00:00
void InitCalorieData ();
2004-03-07 04:34:49 +00:00
void InitAwards ();
2004-02-10 09:42:01 +00:00
//
// Loading and saving
//
2004-02-19 03:19:41 +00:00
bool LoadAllFromDir ( CString sDir ); // return false on
2004-02-15 04:47:32 +00:00
bool SaveAllToDir ( CString sDir ) const ;
2004-02-10 09:42:01 +00:00
2004-02-19 03:19:41 +00:00
void LoadProfileDataFromDirSM390a12 ( CString sDir );
2004-02-10 09:42:01 +00:00
void LoadSongScoresFromDirSM390a12 ( CString sDir );
void LoadCourseScoresFromDirSM390a12 ( CString sDir );
void LoadCategoryScoresFromDirSM390a12 ( CString sDir );
2004-02-19 03:19:41 +00:00
2004-02-22 02:15:34 +00:00
void LoadEditableDataFromDir ( CString sDir );
2004-02-19 03:19:41 +00:00
void LoadGeneralDataFromNode ( const XNode * pNode );
void LoadSongScoresFromNode ( const XNode * pNode );
void LoadCourseScoresFromNode ( const XNode * pNode );
void LoadCategoryScoresFromNode ( const XNode * pNode );
void LoadScreenshotDataFromNode ( const XNode * pNode );
2004-02-22 23:29:13 +00:00
void LoadCalorieDataFromNode ( const XNode * pNode );
2004-03-07 04:34:49 +00:00
void LoadAwardsFromNode ( const XNode * pNode );
2004-02-19 03:19:41 +00:00
2004-02-22 02:15:34 +00:00
void SaveEditableDataToDir ( CString sDir ) const ;
2004-02-19 03:19:41 +00:00
XNode * SaveGeneralDataCreateNode () const ;
XNode * SaveSongScoresCreateNode () const ;
XNode * SaveCourseScoresCreateNode () const ;
XNode * SaveCategoryScoresCreateNode () const ;
XNode * SaveScreenshotDataCreateNode () const ;
2004-02-22 23:29:13 +00:00
XNode * SaveCalorieDataCreateNode () const ;
2004-03-07 04:34:49 +00:00
XNode * SaveAwardsCreateNode () const ;
2004-02-19 03:19:41 +00:00
void DeleteProfileDataFromDirSM390a12 ( CString sDir ) const ;
void DeleteSongScoresFromDirSM390a12 ( CString sDir ) const ;
void DeleteCourseScoresFromDirSM390a12 ( CString sDir ) const ;
2004-02-10 10:06:34 +00:00
void DeleteCategoryScoresFromDirSM390a12 ( CString sDir ) const ;
2004-02-10 09:42:01 +00:00
2004-02-10 10:06:34 +00:00
void SaveStatsWebPageToDir ( CString sDir ) const ;
2004-02-16 05:35:06 +00:00
void SaveMachinePublicKeyToDir ( CString sDir ) const ;
2004-02-08 18:25:30 +00:00
};
#endif