Team Fortress 2 Source Code as on 22/4/2020
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.

156 lines
4.4 KiB

  1. //========= Copyright 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 = dynamic_cast<CAchievementMgr *>( engine->GetAchievementMgr() );
  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( pSave->IsAsync() );
  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. IAchievement *pAchievement = pAchievementMgr->GetAchievementByIndex( i );
  42. if ( pAchievement->ShouldSaveWithGame() )
  43. {
  44. nSaveCount++;
  45. }
  46. }
  47. // Write # of saved achievements
  48. pSave->WriteShort( &nSaveCount );
  49. // Write out each achievement
  50. for ( int i = 0; i < iTotalAchievements; i++ )
  51. {
  52. IAchievement *pAchievement = pAchievementMgr->GetAchievementByIndex( i );
  53. if ( pAchievement->ShouldSaveWithGame() )
  54. {
  55. CBaseAchievement *pBaseAchievement = dynamic_cast< CBaseAchievement * >( pAchievement );
  56. if ( pBaseAchievement )
  57. {
  58. short iAchievementID = (short) pBaseAchievement->GetAchievementID();
  59. // write the achievement ID
  60. pSave->WriteShort( &iAchievementID );
  61. // write the achievement data
  62. pSave->WriteAll( pBaseAchievement, pBaseAchievement->GetDataDescMap() );
  63. }
  64. }
  65. }
  66. pSave->EndBlock();
  67. }
  68. //---------------------------------
  69. void WriteSaveHeaders( ISave *pSave )
  70. {
  71. pSave->WriteShort( &ACHIEVEMENT_SAVE_RESTORE_VERSION );
  72. }
  73. //---------------------------------
  74. void ReadRestoreHeaders( IRestore *pRestore )
  75. {
  76. // No reason why any future version shouldn't try to retain backward compatability. The default here is to not do so.
  77. short version;
  78. pRestore->ReadShort( &version );
  79. // only load if version matches and if we are loading a game, not a transition
  80. m_fDoLoad = ( ( version == ACHIEVEMENT_SAVE_RESTORE_VERSION ) &&
  81. ( ( MapLoad_LoadGame == gpGlobals->eLoadType ) || ( MapLoad_NewGame == gpGlobals->eLoadType ) )
  82. );
  83. }
  84. //---------------------------------
  85. void Restore( IRestore *pRestore, bool createPlayers )
  86. {
  87. CAchievementMgr *pAchievementMgr = dynamic_cast<CAchievementMgr *>( engine->GetAchievementMgr() );
  88. if ( !pAchievementMgr )
  89. return;
  90. if ( m_fDoLoad )
  91. {
  92. pAchievementMgr->PreRestoreSavedGame();
  93. pRestore->StartBlock();
  94. // read # of achievements
  95. int nSavedAchievements = pRestore->ReadShort();
  96. while ( nSavedAchievements-- )
  97. {
  98. // read achievement ID
  99. int iAchievementID = pRestore->ReadShort();
  100. // find the corresponding achievement object
  101. CBaseAchievement *pAchievement = pAchievementMgr->GetAchievementByID( iAchievementID );
  102. Assert( pAchievement ); // It's a bug if we don't understand this achievement
  103. if ( pAchievement )
  104. {
  105. // read achievement data
  106. pRestore->ReadAll( pAchievement, pAchievement->GetDataDescMap() );
  107. }
  108. else
  109. {
  110. // if we don't recognize the achievement for some reason, read and discard the data and keep going
  111. CBaseAchievement ignored;
  112. pRestore->ReadAll( &ignored, ignored.GetDataDescMap() );
  113. }
  114. }
  115. pRestore->EndBlock();
  116. pAchievementMgr->PostRestoreSavedGame();
  117. }
  118. }
  119. private:
  120. bool m_fDoLoad;
  121. };
  122. //-----------------------------------------------------------------------------
  123. CAchievementSaveRestoreBlockHandler g_AchievementSaveRestoreBlockHandler;
  124. //-------------------------------------
  125. ISaveRestoreBlockHandler *GetAchievementSaveRestoreBlockHandler()
  126. {
  127. return &g_AchievementSaveRestoreBlockHandler;
  128. }
  129. #endif // GAME_DLL