Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.7 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #ifdef GAME_DLL
  9. #include "isaverestore.h"
  10. #include "saverestore_utlvector.h"
  11. #include "achievement_saverestore.h"
  12. #include "achievementmgr.h"
  13. #include "baseachievement.h"
  14. #include "utlmap.h"
  15. // memdbgon must be the last include file in a .cpp file!!!
  16. #include "tier0/memdbgon.h"
  17. static short ACHIEVEMENT_SAVE_RESTORE_VERSION = 2;
  18. //-----------------------------------------------------------------------------
  19. class CAchievementSaveRestoreBlockHandler : public CDefSaveRestoreBlockHandler
  20. {
  21. public:
  22. const char *GetBlockName()
  23. {
  24. return "Achievement";
  25. }
  26. //---------------------------------
  27. void Save( ISave *pSave )
  28. {
  29. CAchievementMgr *pAchievementMgr = CAchievementMgr::GetInstance();
  30. if ( !pAchievementMgr )
  31. return;
  32. // save global achievement mgr state to separate file if there have been any changes, so in case of a crash
  33. // the global state is consistent with last save game
  34. pAchievementMgr->SaveGlobalStateIfDirty();
  35. pSave->StartBlock( "Achievements" );
  36. int iTotalAchievements = pAchievementMgr->GetAchievementCount();
  37. short nSaveCount = 0;
  38. // count how many achievements should be saved.
  39. for ( int i = 0; i < iTotalAchievements; i++ )
  40. {
  41. // We only save games in SP games so the assumption of SINGLE_PLAYER_SLOT is valid
  42. IAchievement *pAchievement = pAchievementMgr->GetAchievementByIndex( i, SINGLE_PLAYER_SLOT );
  43. if ( pAchievement->ShouldSaveWithGame() )
  44. {
  45. nSaveCount++;
  46. }
  47. }
  48. // Write # of saved achievements
  49. pSave->WriteShort( &nSaveCount );
  50. // Write out each achievement
  51. for ( int i = 0; i < iTotalAchievements; i++ )
  52. {
  53. // We only save games in SP games so the assumption of SINGLE_PLAYER_SLOT is valid
  54. IAchievement *pAchievement = pAchievementMgr->GetAchievementByIndex( i, SINGLE_PLAYER_SLOT );
  55. if ( pAchievement->ShouldSaveWithGame() )
  56. {
  57. CBaseAchievement *pBaseAchievement = dynamic_cast< CBaseAchievement * >( pAchievement );
  58. if ( pBaseAchievement )
  59. {
  60. short iAchievementID = (short) pBaseAchievement->GetAchievementID();
  61. // write the achievement ID
  62. pSave->WriteShort( &iAchievementID );
  63. // write the achievement data
  64. pSave->WriteAll( pBaseAchievement, pBaseAchievement->GetDataDescMap() );
  65. }
  66. }
  67. }
  68. pSave->EndBlock();
  69. }
  70. //---------------------------------
  71. void WriteSaveHeaders( ISave *pSave )
  72. {
  73. pSave->WriteShort( &ACHIEVEMENT_SAVE_RESTORE_VERSION );
  74. }
  75. //---------------------------------
  76. void ReadRestoreHeaders( IRestore *pRestore )
  77. {
  78. // No reason why any future version shouldn't try to retain backward compatability. The default here is to not do so.
  79. short version;
  80. pRestore->ReadShort( &version );
  81. // only load if version matches and if we are loading a game, not a transition
  82. m_fDoLoad = ( ( version == ACHIEVEMENT_SAVE_RESTORE_VERSION ) &&
  83. ( ( MapLoad_LoadGame == gpGlobals->eLoadType ) || ( MapLoad_NewGame == gpGlobals->eLoadType ) )
  84. );
  85. }
  86. //---------------------------------
  87. void Restore( IRestore *pRestore, bool createPlayers )
  88. {
  89. CAchievementMgr *pAchievementMgr = CAchievementMgr::GetInstance();
  90. if ( !pAchievementMgr )
  91. return;
  92. if ( m_fDoLoad )
  93. {
  94. pAchievementMgr->PreRestoreSavedGame();
  95. pRestore->StartBlock();
  96. // read # of achievements
  97. int nSavedAchievements = pRestore->ReadShort();
  98. while ( nSavedAchievements-- )
  99. {
  100. // read achievement ID
  101. int iAchievementID = pRestore->ReadShort();
  102. // find the corresponding achievement object
  103. // We only save games in SP games so the assumption of SINGLE_PLAYER_SLOT is valid
  104. CBaseAchievement *pAchievement = pAchievementMgr->GetAchievementByID( iAchievementID, SINGLE_PLAYER_SLOT );
  105. Assert( pAchievement ); // It's a bug if we don't understand this achievement
  106. if ( pAchievement )
  107. {
  108. // read achievement data
  109. pRestore->ReadAll( pAchievement, pAchievement->GetDataDescMap() );
  110. }
  111. else
  112. {
  113. // if we don't recognize the achievement for some reason, read and discard the data and keep going
  114. CBaseAchievement ignored;
  115. pRestore->ReadAll( &ignored, ignored.GetDataDescMap() );
  116. }
  117. }
  118. pRestore->EndBlock();
  119. pAchievementMgr->PostRestoreSavedGame();
  120. }
  121. }
  122. private:
  123. bool m_fDoLoad;
  124. };
  125. //-----------------------------------------------------------------------------
  126. CAchievementSaveRestoreBlockHandler g_AchievementSaveRestoreBlockHandler;
  127. //-------------------------------------
  128. ISaveRestoreBlockHandler *GetAchievementSaveRestoreBlockHandler()
  129. {
  130. return &g_AchievementSaveRestoreBlockHandler;
  131. }
  132. #endif // GAME_DLL