2004-05-31 21:55:14 +00:00
/* Profile - Player data that persists between sessions. Can be stored on a local disk or on a memory card. */
2004-02-08 18:25:30 +00:00
#ifndef Profile_H
#define Profile_H
#include "GameConstantsAndTypes.h"
2004-02-09 06:26:13 +00:00
#include "Grade.h"
#include <map>
2004-02-22 08:16:49 +00:00
#include <set>
2005-04-28 02:39:43 +00:00
#include <deque>
2004-02-10 09:42:01 +00:00
#include "HighScore.h"
2004-07-12 06:39:13 +00:00
#include "DateTime.h"
2004-04-18 18:42:42 +00:00
#include "SongUtil.h" // for SongID
#include "StepsUtil.h" // for StepsID
2004-04-18 19:36:42 +00:00
#include "CourseUtil.h" // for CourseID
2004-05-23 09:17:10 +00:00
#include "TrailUtil.h" // for TrailID
2004-07-17 21:49:32 +00:00
#include "StyleUtil.h" // for StyleID
2005-02-16 02:46:43 +00:00
#include "LuaReference.h" // for LuaData
2004-02-22 02:15:34 +00:00
2004-05-22 01:35:08 +00:00
struct XNode ;
2005-02-15 23:13:18 +00:00
struct lua_State ;
2005-07-13 19:11:24 +00:00
class Character ;
2004-05-22 01:35:08 +00:00
2004-02-22 02:15:34 +00:00
//
// Current file versions
//
2005-06-09 04:03:08 +00:00
extern const CString STATS_XML ;
extern const CString EDITABLE_INI ;
2004-02-22 02:15:34 +00:00
// 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.
2005-06-09 04:03:08 +00:00
extern const CString DONT_SHARE_SIG ;
2004-02-22 02:15:34 +00:00
// 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.
2005-06-09 04:03:08 +00:00
extern const CString PUBLIC_KEY_FILE ;
extern const CString SCREENSHOTS_SUBDIR ;
2005-07-31 05:41:32 +00:00
extern const CString EDIT_STEPS_SUBDIR ;
extern const CString EDIT_COURSES_SUBDIR ;
2005-06-09 04:03:08 +00:00
extern const CString LASTGOOD_SUBDIR ;
2004-02-22 02:15:34 +00:00
2005-07-13 19:11:24 +00:00
const unsigned int PROFILE_MAX_DISPLAY_NAME_LENGTH = 12 ;
2004-06-28 07:26:00 +00:00
class Style ;
2004-02-22 02:15:34 +00:00
2004-02-10 09:42:01 +00:00
class Song ;
2004-02-09 06:26:13 +00:00
class Steps ;
class Course ;
2004-11-14 05:24:37 +00:00
class Game ;
2004-02-09 06:26:13 +00:00
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
//
2005-07-13 18:49:49 +00:00
CString GetDisplayNameOrHighScoreName () const ;
2005-07-13 19:11:24 +00:00
Character * GetCharacter () const ;
2005-02-15 23:13:18 +00:00
CString GetDisplayTotalCaloriesBurned () const ; // remove me and use Lua instead
CString GetDisplayTotalCaloriesBurnedToday () const ; // remove me and use Lua instead
2005-06-15 01:59:40 +00:00
int GetCalculatedWeightPounds () const ; // returns a default value if m_iWeightPounds isn't set
2005-02-15 23:13:18 +00:00
float GetCaloriesBurnedToday () const ;
2004-02-22 08:16:49 +00:00
int GetTotalNumSongsPassed () const ;
2005-03-31 02:03:00 +00:00
int GetTotalStepsWithTopGrade ( StepsType st , Difficulty d , Grade g ) const ;
int GetTotalTrailsWithTopGrade ( StepsType st , CourseDifficulty d , Grade g ) const ;
2004-08-15 01:36:33 +00:00
float GetSongsPossible ( StepsType st , Difficulty dc ) const ;
float GetCoursesPossible ( StepsType st , CourseDifficulty cd ) const ;
float GetSongsActual ( StepsType st , Difficulty dc ) const ;
float GetCoursesActual ( StepsType st , CourseDifficulty cd ) const ;
2004-07-12 00:10:28 +00:00
float GetSongsPercentComplete ( StepsType st , Difficulty dc ) const ;
float GetCoursesPercentComplete ( StepsType st , CourseDifficulty cd ) const ;
2005-03-31 06:12:26 +00:00
float GetSongsAndCoursesPercentCompleteAllDifficulties ( StepsType st ) const ;
2004-11-14 05:24:37 +00:00
bool GetDefaultModifiers ( const Game * pGameType , CString & sModifiersOut ) const ;
void SetDefaultModifiers ( const Game * pGameType , const CString & sModifiers );
2005-02-21 06:59:50 +00:00
bool IsCodeUnlocked ( int iCode ) const ;
2005-08-05 04:20:46 +00:00
Song * GetMostPopularSong () const ;
Course * GetMostPopularCourse () const ;
2004-02-22 23:29:13 +00:00
2005-04-25 11:42:19 +00:00
void AddStepTotals ( int iNumTapsAndHolds , int iNumJumps , int iNumHolds , int iNumRolls , int iNumMines , int iNumHands , float fCaloriesBurned );
2004-02-08 18:25:30 +00:00
2004-05-28 04:46:43 +00:00
bool IsMachine () const ;
2004-02-19 03:19:41 +00:00
//
// Editable data
//
CString m_sDisplayName ;
2005-08-14 02:00:27 +00:00
CString m_sCharacterID ;
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.
2005-02-15 22:08:42 +00:00
int m_iWeightPounds ; // 0 == not set
2004-02-19 03:19:41 +00:00
2004-02-10 09:42:01 +00:00
//
// General data
//
2005-03-22 10:33:06 +00:00
static CString MakeGuid ();
2004-04-18 05:46:43 +00:00
CString m_sGuid ;
2004-11-14 05:24:37 +00:00
map < CString , 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 ;
2004-08-14 06:41:24 +00:00
SongID m_lastSong ;
CourseID m_lastCourse ;
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 ;
2005-02-17 19:36:10 +00:00
GoalType m_GoalType ;
2005-02-15 22:08:42 +00:00
int m_iGoalCalories ;
2005-02-16 20:24:57 +00:00
int m_iGoalSeconds ;
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 ;
2005-04-25 11:42:19 +00:00
int m_iTotalRolls ;
2004-02-22 19:54:59 +00:00
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-07-18 21:54:19 +00:00
mutable DateTime m_LastPlayedDate ;
2005-02-23 22:52:03 +00:00
/* These stats count twice in the machine profile if two players are playing;
* that's the only approach that makes sense for ByDifficulty and ByMeter. */
2004-02-08 18:25:30 +00:00
int m_iNumSongsPlayedByPlayMode [ NUM_PLAY_MODES ];
2004-07-17 21:49:32 +00:00
map < StyleID , int > m_iNumSongsPlayedByStyle ;
2004-02-08 18:25:30 +00:00
int m_iNumSongsPlayedByDifficulty [ NUM_DIFFICULTIES ];
int m_iNumSongsPlayedByMeter [ MAX_METER + 1 ];
2005-02-23 22:52:03 +00:00
/* This stat counts once per song, even if two players are active. */
2005-02-23 22:59:56 +00:00
int m_iNumTotalSongsPlayed ;
2004-08-30 06:07:14 +00:00
int m_iNumStagesPassedByPlayMode [ NUM_PLAY_MODES ];
2005-08-14 11:38:31 +00:00
int m_iNumStagesPassedByGrade [ NUM_Grade ];
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
{
2005-04-25 09:03:24 +00:00
HighScoreList hsl ;
2004-02-09 06:26:13 +00:00
};
2004-04-18 18:42:42 +00:00
struct HighScoresForASong
{
std :: map < StepsID , HighScoresForASteps > m_StepsHighScores ;
2005-08-05 04:20:46 +00:00
int GetNumTimesPlayed () const ;
2004-04-18 18:42:42 +00:00
};
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 );
2005-08-14 11:38:31 +00:00
void GetGrades ( const Song * pSong , StepsType st , int iCounts [ NUM_Grade ] ) const ;
2005-04-25 22:44:32 +00:00
int GetSongNumTimesPlayed ( const Song * pSong ) const ;
int GetSongNumTimesPlayed ( const SongID & songID ) const ;
DateTime GetSongLastPlayedDateTime ( const Song * pSong ) const ;
2005-09-12 06:21:30 +00:00
bool HasPassedAnyStepsInSong ( const Song * pSong ) const ;
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[].
2004-05-23 09:17:10 +00:00
struct HighScoresForATrail
{
2005-04-25 09:03:24 +00:00
HighScoreList hsl ;
2004-05-23 09:17:10 +00:00
};
2004-02-09 06:26:13 +00:00
struct HighScoresForACourse
{
2004-05-23 09:17:10 +00:00
std :: map < TrailID , HighScoresForATrail > m_TrailHighScores ;
2005-08-05 04:20:46 +00:00
int GetNumTimesPlayed () const ;
2004-02-09 06:26:13 +00:00
};
2004-04-18 19:36:42 +00:00
std :: map < CourseID , HighScoresForACourse > m_CourseHighScores ;
2004-02-09 06:26:13 +00:00
2004-05-23 09:17:10 +00:00
void AddCourseHighScore ( const Course * pCourse , const Trail * pTrail , HighScore hs , int & iIndexOut );
HighScoreList & GetCourseHighScoreList ( const Course * pCourse , const Trail * pTrail );
const HighScoreList & GetCourseHighScoreList ( const Course * pCourse , const Trail * pTrail ) const ;
2004-02-09 06:26:13 +00:00
int GetCourseNumTimesPlayed ( const Course * pCourse ) const ;
2004-04-18 19:36:42 +00:00
int GetCourseNumTimesPlayed ( const CourseID & courseID ) const ;
2005-04-25 22:44:32 +00:00
DateTime GetCourseLastPlayedDateTime ( const Course * pCourse ) const ;
2004-05-23 09:17:10 +00:00
void IncrementCoursePlayCount ( const Course * pCourse , const Trail * pTrail );
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
//
vector < Screenshot > m_vScreenshots ;
2004-06-12 07:01:07 +00:00
void AddScreenshot ( const 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.
2005-06-18 03:45:16 +00:00
struct Calories
{
Calories () { fCals = 0 ; }
float fCals ;
};
map < DateTime , Calories > m_mapDayToCaloriesBurned ;
2004-07-12 06:39:13 +00:00
float GetCaloriesBurnedForDay ( DateTime day ) const ;
2004-02-17 01:16:57 +00:00
2004-03-07 04:34:49 +00:00
2004-04-22 07:59:42 +00:00
//
2004-05-08 10:12:10 +00:00
// RecentSongScores
2004-04-22 07:59:42 +00:00
//
struct HighScoreForASongAndSteps
{
StepsID stepsID ;
SongID songID ;
HighScore hs ;
HighScoreForASongAndSteps () { Unset (); }
void Unset () { stepsID . Unset (); songID . Unset (); hs . Unset (); }
XNode * CreateNode () const ;
void LoadFromNode ( const XNode * pNode );
};
2005-04-28 02:39:43 +00:00
deque < HighScoreForASongAndSteps > m_vRecentStepsScores ;
2004-05-08 10:12:10 +00:00
void AddStepsRecentScore ( const Song * pSong , const Steps * pSteps , HighScore hs );
2004-04-22 22:01:38 +00:00
2005-08-03 03:23:52 +00:00
StepsType GetLastPlayedStepsType () const ;
2004-04-22 22:01:38 +00:00
//
2004-05-08 10:12:10 +00:00
// RecentCourseScores
2004-04-22 22:01:38 +00:00
//
2004-07-11 23:17:01 +00:00
struct HighScoreForACourseAndTrail
2004-04-22 22:01:38 +00:00
{
CourseID courseID ;
2004-05-23 09:17:10 +00:00
TrailID trailID ;
2004-04-22 22:01:38 +00:00
HighScore hs ;
2004-07-11 23:17:01 +00:00
HighScoreForACourseAndTrail () { Unset (); }
2004-04-22 22:01:38 +00:00
void Unset () { courseID . Unset (); hs . Unset (); }
XNode * CreateNode () const ;
void LoadFromNode ( const XNode * pNode );
};
2005-08-03 03:23:52 +00:00
deque < HighScoreForACourseAndTrail > m_vRecentCourseScores ; // add to back, erase from front
2004-05-23 09:17:10 +00:00
void AddCourseRecentScore ( const Course * pCourse , const Trail * pTrail , HighScore hs );
2004-04-22 07:59:42 +00:00
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-05-08 10:12:10 +00:00
InitRecentSongScores ();
InitRecentCourseScores ();
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-05-08 10:12:10 +00:00
void InitRecentSongScores ();
void InitRecentCourseScores ();
2004-02-10 09:42:01 +00:00
//
// Loading and saving
//
2005-08-13 06:59:27 +00:00
ProfileLoadResult LoadAllFromDir ( CString sDir , bool bRequireSignature );
2004-04-20 00:07:17 +00:00
bool SaveAllToDir ( CString sDir , bool bSignData ) const ;
2004-02-10 09:42:01 +00:00
2005-08-13 06:59:27 +00:00
ProfileLoadResult LoadEditableDataFromDir ( CString sDir );
ProfileLoadResult LoadStatsXmlFromNode ( const XNode * pNode , bool bIgnoreEditable = true );
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-05-08 10:12:10 +00:00
void LoadRecentSongScoresFromNode ( const XNode * pNode );
void LoadRecentCourseScoresFromNode ( 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-10-06 08:39:38 +00:00
bool SaveStatsXmlToDir ( CString sDir , bool bSignData ) const ;
2004-12-22 03:49:55 +00:00
XNode * SaveStatsXmlCreateNode () 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-05-08 10:12:10 +00:00
XNode * SaveRecentSongScoresCreateNode () const ;
XNode * SaveRecentCourseScoresCreateNode () const ;
2004-02-19 03:19:41 +00:00
2004-07-31 03:24:15 +00:00
XNode * SaveCoinDataCreateNode () const ;
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-05-02 00:08:42 +00:00
2005-09-29 00:33:22 +00:00
static void MoveBackupToDir ( CString sFromDir , CString sToDir );
2004-10-06 08:54:37 +00:00
2005-02-15 23:13:18 +00:00
// Lua
void PushSelf ( lua_State * L );
2005-02-16 02:46:43 +00:00
LuaData m_SavedLuaData ;
2005-02-15 23:13:18 +00:00
2004-05-02 00:08:42 +00:00
private :
const HighScoresForASong * GetHighScoresForASong ( const SongID & songID ) const ;
2004-05-23 09:17:10 +00:00
const HighScoresForACourse * GetHighScoresForACourse ( const CourseID & courseID ) const ;
2004-02-08 18:25:30 +00:00
};
#endif
2004-05-31 21:55:14 +00:00
/*
* (c) 2001-2004 Chris Danford
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/