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