Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

Profile.h

Go to the documentation of this file.
00001 /* Profile - Player data that persists between sessions. Can be stored on a local disk or on a memory card. */ 00002 00003 #ifndef Profile_H 00004 #define Profile_H 00005 00006 #include "GameConstantsAndTypes.h" 00007 #include "Grade.h" 00008 #include <map> 00009 #include <set> 00010 #include "HighScore.h" 00011 #include "DateTime.h" 00012 #include "SongUtil.h" // for SongID 00013 #include "StepsUtil.h" // for StepsID 00014 #include "CourseUtil.h" // for CourseID 00015 #include "TrailUtil.h" // for TrailID 00016 #include "StyleUtil.h" // for StyleID 00017 00018 struct XNode; 00019 00020 // 00021 // Current file versions 00022 // 00023 const CString STATS_XML = "Stats.xml"; 00024 00025 const CString EDITABLE_INI = "Editable.ini"; 00026 // Editable data is an INI because the default INI file association on Windows 00027 // systems will open the ini file in an editor. The default association for 00028 // XML will open in IE. Users have a much better chance of discovering how to 00029 // edit this data if they don't have to fight against the file associations. 00030 00031 const CString DONT_SHARE_SIG = "DontShare.sig"; 00032 // The "don't share" file is something that the user should always keep private. 00033 // They can safely share STATS_XML with STATS_XML's signature so that others 00034 // can authenticate the STATS_XML data. However, others can't copy that data 00035 // to their own profile for use in the game unless they also have the "don't 00036 // share" file. DontShare contains a piece of information that we can 00037 // construct using STATS_XML but the user can't construct using STATS_XML. 00038 // The file contains a signature of the STATS_XML's signature. 00039 00040 const CString PUBLIC_KEY_FILE = "public.key"; 00041 const CString SCREENSHOTS_SUBDIR = "Screenshots/"; 00042 const CString EDITS_SUBDIR = "Edits/"; 00043 const CString LASTGOOD_SUBDIR = "LastGood/"; 00044 00045 class Style; 00046 00047 class Song; 00048 class Steps; 00049 class Course; 00050 class Game; 00051 00052 class Profile 00053 { 00054 public: 00055 Profile() 00056 { 00057 InitAll(); 00058 } 00059 00060 // 00061 // smart accessors 00062 // 00063 CString GetDisplayName() const; 00064 CString GetDisplayTotalCaloriesBurned() const; 00065 CString GetDisplayTotalCaloriesBurnedToday() const; 00066 int GetTotalNumSongsPlayed() const; 00067 int GetTotalNumSongsPassed() const; 00068 float GetSongsPossible( StepsType st, Difficulty dc ) const; 00069 float GetCoursesPossible( StepsType st, CourseDifficulty cd ) const; 00070 float GetSongsActual( StepsType st, Difficulty dc ) const; 00071 float GetCoursesActual( StepsType st, CourseDifficulty cd ) const; 00072 float GetSongsPercentComplete( StepsType st, Difficulty dc ) const; 00073 float GetCoursesPercentComplete( StepsType st, CourseDifficulty cd ) const; 00074 static CString GetProfileDisplayNameFromDir( CString sDir ); 00075 int GetSongNumTimesPlayed( const Song* pSong ) const; 00076 int GetSongNumTimesPlayed( const SongID& songID ) const; 00077 bool GetDefaultModifiers( const Game* pGameType, CString &sModifiersOut ) const; 00078 void SetDefaultModifiers( const Game* pGameType, const CString &sModifiers ); 00079 00080 void AddStepTotals( int iNumTapsAndHolds, int iNumJumps, int iNumHolds, int iNumMines, int iNumHands ); 00081 00082 bool IsMachine() const; 00083 00084 // 00085 // Editable data 00086 // 00087 CString m_sDisplayName; 00088 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. 00089 int m_iWeightPounds; 00090 00091 // 00092 // General data 00093 // 00094 CString m_sGuid; 00095 map<CString,CString> m_sDefaultModifiers; 00096 SortOrder m_SortOrder; 00097 Difficulty m_LastDifficulty; 00098 CourseDifficulty m_LastCourseDifficulty; 00099 SongID m_lastSong; 00100 CourseID m_lastCourse; 00101 int m_iTotalPlays; 00102 int m_iTotalPlaySeconds; 00103 int m_iTotalGameplaySeconds; 00104 int m_iCurrentCombo; 00105 float m_fTotalCaloriesBurned; 00106 int m_iTotalDancePoints; 00107 int m_iNumExtraStagesPassed; 00108 int m_iNumExtraStagesFailed; 00109 int m_iNumToasties; 00110 int m_iTotalTapsAndHolds; 00111 int m_iTotalJumps; 00112 int m_iTotalHolds; 00113 int m_iTotalMines; 00114 int m_iTotalHands; 00115 set<int> m_UnlockedSongs; 00116 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 00117 mutable DateTime m_LastPlayedDate; 00118 int m_iNumSongsPlayedByPlayMode[NUM_PLAY_MODES]; 00119 map<StyleID,int> m_iNumSongsPlayedByStyle; 00120 int m_iNumSongsPlayedByDifficulty[NUM_DIFFICULTIES]; 00121 int m_iNumSongsPlayedByMeter[MAX_METER+1]; 00122 int m_iNumStagesPassedByPlayMode[NUM_PLAY_MODES]; 00123 int m_iNumStagesPassedByGrade[NUM_GRADES]; 00124 00125 // 00126 // Song high scores 00127 // 00128 struct HighScoresForASteps 00129 { 00130 HighScoreList hs; 00131 }; 00132 struct HighScoresForASong 00133 { 00134 std::map<StepsID,HighScoresForASteps> m_StepsHighScores; 00135 }; 00136 std::map<SongID,HighScoresForASong> m_SongHighScores; 00137 00138 void AddStepsHighScore( const Song* pSong, const Steps* pSteps, HighScore hs, int &iIndexOut ); 00139 const HighScoreList& GetStepsHighScoreList( const Song* pSong, const Steps* pSteps ) const; 00140 HighScoreList& GetStepsHighScoreList( const Song* pSong, const Steps* pSteps ); 00141 int GetStepsNumTimesPlayed( const Song* pSong, const Steps* pSteps ) const; 00142 void IncrementStepsPlayCount( const Song* pSong, const Steps* pSteps ); 00143 void GetGrades( const Song* pSong, StepsType st, int iCounts[NUM_GRADES] ) const; 00144 00145 00146 // 00147 // Course high scores 00148 // 00149 // struct was a typedef'd array of HighScores, but VC6 freaks out 00150 // in processing the templates for map::operator[]. 00151 struct HighScoresForATrail 00152 { 00153 HighScoreList hs; 00154 }; 00155 struct HighScoresForACourse 00156 { 00157 std::map<TrailID,HighScoresForATrail> m_TrailHighScores; 00158 }; 00159 std::map<CourseID,HighScoresForACourse> m_CourseHighScores; 00160 00161 void AddCourseHighScore( const Course* pCourse, const Trail* pTrail, HighScore hs, int &iIndexOut ); 00162 HighScoreList& GetCourseHighScoreList( const Course* pCourse, const Trail* pTrail ); 00163 const HighScoreList& GetCourseHighScoreList( const Course* pCourse, const Trail* pTrail ) const; 00164 int GetCourseNumTimesPlayed( const Course* pCourse ) const; 00165 int GetCourseNumTimesPlayed( const CourseID& courseID ) const; 00166 void IncrementCoursePlayCount( const Course* pCourse, const Trail* pTrail ); 00167 00168 00169 // 00170 // Category high scores 00171 // 00172 HighScoreList m_CategoryHighScores[NUM_STEPS_TYPES][NUM_RANKING_CATEGORIES]; 00173 00174 void AddCategoryHighScore( StepsType st, RankingCategory rc, HighScore hs, int &iIndexOut ); 00175 HighScoreList& GetCategoryHighScoreList( StepsType st, RankingCategory rc ); 00176 const HighScoreList& GetCategoryHighScoreList( StepsType st, RankingCategory rc ) const; 00177 int GetCategoryNumTimesPlayed( StepsType st ) const; 00178 void IncrementCategoryPlayCount( StepsType st, RankingCategory rc ); 00179 00180 00181 // 00182 // Screenshot Data 00183 // 00184 vector<Screenshot> m_vScreenshots; 00185 void AddScreenshot( const Screenshot &screenshot ); 00186 int GetNextScreenshotIndex() { return m_vScreenshots.size(); } 00187 00188 00189 // 00190 // Calorie Data 00191 // 00192 // Why track calories in a map, and not in a static sized array like 00193 // Bookkeeping? The machine's clock is not guaranteed to be set correctly. 00194 // If calorie array is in a static sized array, playing on a machine with 00195 // a mis-set clock could wipe out all your past data. With this scheme, 00196 // the worst that could happen is that playing on a mis-set machine will 00197 // insert some garbage entries into the map. 00198 map<DateTime,float> m_mapDayToCaloriesBurned; 00199 float GetCaloriesBurnedForDay( DateTime day ) const; 00200 00201 00202 // 00203 // RecentSongScores 00204 // 00205 struct HighScoreForASongAndSteps 00206 { 00207 StepsID stepsID; 00208 SongID songID; 00209 HighScore hs; 00210 00211 HighScoreForASongAndSteps() { Unset(); } 00212 void Unset() { stepsID.Unset(); songID.Unset(); hs.Unset(); } 00213 00214 XNode* CreateNode() const; 00215 void LoadFromNode( const XNode* pNode ); 00216 }; 00217 vector<HighScoreForASongAndSteps> m_vRecentStepsScores; 00218 void AddStepsRecentScore( const Song* pSong, const Steps* pSteps, HighScore hs ); 00219 00220 // 00221 // RecentCourseScores 00222 // 00223 struct HighScoreForACourseAndTrail 00224 { 00225 CourseID courseID; 00226 TrailID trailID; 00227 HighScore hs; 00228 00229 HighScoreForACourseAndTrail() { Unset(); } 00230 void Unset() { courseID.Unset(); hs.Unset(); } 00231 00232 XNode* CreateNode() const; 00233 void LoadFromNode( const XNode* pNode ); 00234 }; 00235 vector<HighScoreForACourseAndTrail> m_vRecentCourseScores; 00236 void AddCourseRecentScore( const Course* pCourse, const Trail* pTrail, HighScore hs ); 00237 00238 // 00239 // Init'ing 00240 // 00241 void InitAll() 00242 { 00243 InitEditableData(); 00244 InitGeneralData(); 00245 InitSongScores(); 00246 InitCourseScores(); 00247 InitCategoryScores(); 00248 InitScreenshotData(); 00249 InitCalorieData(); 00250 InitRecentSongScores(); 00251 InitRecentCourseScores(); 00252 } 00253 void InitEditableData(); 00254 void InitGeneralData(); 00255 void InitSongScores(); 00256 void InitCourseScores(); 00257 void InitCategoryScores(); 00258 void InitScreenshotData(); 00259 void InitCalorieData(); 00260 void InitRecentSongScores(); 00261 void InitRecentCourseScores(); 00262 00263 // 00264 // Loading and saving 00265 // 00266 enum LoadResult { success, failed_no_profile, failed_tampered }; 00267 LoadResult LoadAllFromDir( CString sDir, bool bRequireSignature ); 00268 bool SaveAllToDir( CString sDir, bool bSignData ) const; 00269 00270 void LoadEditableDataFromDir( CString sDir ); 00271 LoadResult LoadStatsXmlFromNode( const XNode* pNode ); 00272 void LoadGeneralDataFromNode( const XNode* pNode ); 00273 void LoadSongScoresFromNode( const XNode* pNode ); 00274 void LoadCourseScoresFromNode( const XNode* pNode ); 00275 void LoadCategoryScoresFromNode( const XNode* pNode ); 00276 void LoadScreenshotDataFromNode( const XNode* pNode ); 00277 void LoadCalorieDataFromNode( const XNode* pNode ); 00278 void LoadRecentSongScoresFromNode( const XNode* pNode ); 00279 void LoadRecentCourseScoresFromNode( const XNode* pNode ); 00280 00281 void SaveEditableDataToDir( CString sDir ) const; 00282 bool SaveStatsXmlToDir( CString sDir, bool bSignData ) const; 00283 XNode* SaveStatsXmlCreateNode() const; 00284 XNode* SaveGeneralDataCreateNode() const; 00285 XNode* SaveSongScoresCreateNode() const; 00286 XNode* SaveCourseScoresCreateNode() const; 00287 XNode* SaveCategoryScoresCreateNode() const; 00288 XNode* SaveScreenshotDataCreateNode() const; 00289 XNode* SaveCalorieDataCreateNode() const; 00290 XNode* SaveRecentSongScoresCreateNode() const; 00291 XNode* SaveRecentCourseScoresCreateNode() const; 00292 00293 XNode* SaveCoinDataCreateNode() const; 00294 00295 void SaveStatsWebPageToDir( CString sDir ) const; 00296 void SaveMachinePublicKeyToDir( CString sDir ) const; 00297 00298 static bool CreateNewProfile( CString sProfileDir, CString sName ); 00299 static void BackupToDir( CString sFromDir, CString sToDir ); 00300 00301 private: 00302 const HighScoresForASong *GetHighScoresForASong( const SongID& songID ) const; 00303 const HighScoresForACourse *GetHighScoresForACourse( const CourseID& courseID ) const; 00304 }; 00305 00306 00307 #endif 00308 00309 /* 00310 * (c) 2001-2004 Chris Danford 00311 * All rights reserved. 00312 * 00313 * Permission is hereby granted, free of charge, to any person obtaining a 00314 * copy of this software and associated documentation files (the 00315 * "Software"), to deal in the Software without restriction, including 00316 * without limitation the rights to use, copy, modify, merge, publish, 00317 * distribute, and/or sell copies of the Software, and to permit persons to 00318 * whom the Software is furnished to do so, provided that the above 00319 * copyright notice(s) and this permission notice appear in all copies of 00320 * the Software and that both the above copyright notice(s) and this 00321 * permission notice appear in supporting documentation. 00322 * 00323 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00324 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00325 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF 00326 * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS 00327 * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT 00328 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 00329 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 00330 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00331 * PERFORMANCE OF THIS SOFTWARE. 00332 */

Generated on Thu Jan 27 20:57:27 2005 for StepMania by doxygen 1.3.7