aboutsummaryrefslogtreecommitdiff
path: root/sp/src/game/shared/achievementmgr.h
blob: c33261e2d1d826c7557d66ca2b9fc030ccadf08c (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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=============================================================================

#ifndef ACHIEVEMENTMGR_H
#define ACHIEVEMENTMGR_H
#ifdef _WIN32
#pragma once
#endif
#include "baseachievement.h"
#include "GameEventListener.h"
#include "hl2orange.spa.h"
#include "iachievementmgr.h"
#include "utlmap.h"
#ifndef NO_STEAM
#include "steam/steam_api.h"
#endif

#define THINK_CLEAR		-1

class CAchievementMgr : public CAutoGameSystemPerFrame, public CGameEventListener, public IAchievementMgr
{
public:
    //=============================================================================
    // HPE_BEGIN
    // [dwenger] Steam Cloud Support
    //=============================================================================

    enum SteamCloudPersisting
    {
        SteamCloudPersist_Off = 0,
        SteamCloudPersist_On,
    };

	CAchievementMgr( SteamCloudPersisting ePersistToSteamCloud = SteamCloudPersist_Off );

    //=============================================================================
    // HPE_END
    //=============================================================================

	virtual bool Init();
	virtual void PostInit();
	virtual void Shutdown();
	virtual void LevelInitPreEntity();
	virtual void LevelShutdownPreEntity();
	virtual void InitializeAchievements();
	virtual void Update( float frametime );
#ifdef GAME_DLL
	virtual void FrameUpdatePostEntityThink();
#endif

	void OnMapEvent( const char *pchEventName );
	
	// Interfaces exported to other dlls for achievement list queries
	IAchievement* GetAchievementByIndex( int index );
	int GetAchievementCount();

	CBaseAchievement *GetAchievementByID( int iAchievementID );
	CUtlMap<int, CBaseAchievement *> &GetAchievements() { return m_mapAchievement; }

	CBaseAchievement *GetAchievementByName( const char *pchName );
	bool	HasAchieved( const char *pchName );

	void UploadUserData();
	void DownloadUserData();
	void SaveGlobalState( bool bAsync = false );
	void LoadGlobalState();
	void SaveGlobalStateIfDirty( bool bAsync = false );
	void EnsureGlobalStateLoaded();
	void AwardAchievement( int iAchievementID );
	void UpdateAchievement( int iAchievementID, int nData );
	void PreRestoreSavedGame();
	void PostRestoreSavedGame();
	void ResetAchievements();
	void ResetAchievement( int iAchievementID );
	void PrintAchievementStatus();
	float GetLastClassChangeTime() { return m_flLastClassChangeTime; }
	float GetTeamplayStartTime() { return m_flTeamplayStartTime; }
	int	  GetMiniroundsCompleted() { return m_iMiniroundsCompleted; }
	const char *GetMapName() { return m_szMap; }
	void OnAchievementEvent( int iAchievementID, int iCount = 1 );

	void CheckMetaAchievements( void );

	void SetDirty( bool bDirty )
	{
		if (bDirty)
		{
			m_bGlobalStateDirty = true;
			m_bSteamDataDirty = true;
		}
	}
	
	//=============================================================================
	// HPE_END
	//=============================================================================

	bool CheckAchievementsEnabled();
	bool LoggedIntoSteam() 
	{ 
#if !defined(NO_STEAM)
		return ( steamapicontext->SteamUser() && steamapicontext->SteamUserStats() && steamapicontext->SteamUser()->BLoggedOn() ); 
#else
		return false;
#endif
	}
	float GetTimeLastUpload() { return m_flTimeLastSaved; }			// time we last uploaded to Steam

	bool WereCheatsEverOn( void ) { return m_bCheatsEverOn; }

#if !defined(NO_STEAM)
	STEAM_CALLBACK( CAchievementMgr, Steam_OnUserStatsReceived, UserStatsReceived_t, m_CallbackUserStatsReceived );
	STEAM_CALLBACK( CAchievementMgr, Steam_OnUserStatsStored, UserStatsStored_t, m_CallbackUserStatsStored );
#endif

	void SetAchievementThink( CBaseAchievement *pAchievement, float flThinkTime );

private:
	void FireGameEvent( IGameEvent *event );
	void OnKillEvent( CBaseEntity *pVictim, CBaseEntity *pAttacker, CBaseEntity *pInflictor, IGameEvent *event );
	void ResetAchievement_Internal( CBaseAchievement *pAchievement );
	void UpdateStateFromSteam_Internal();

	CUtlMap<int, CBaseAchievement *> m_mapAchievement;					// map of all achievements
	CUtlVector<CBaseAchievement *>	 m_vecAchievement;					// vector of all achievements for accessing by index
	CUtlVector<CBaseAchievement *> m_vecKillEventListeners;				// vector of achievements that are listening for kill events
	CUtlVector<CBaseAchievement *> m_vecMapEventListeners;				// vector of achievements that are listening for map events
	CUtlVector<CBaseAchievement *> m_vecComponentListeners;				// vector of achievements that are listening for components that make up an achievement
	CUtlMap<int, CAchievement_AchievedCount *> m_mapMetaAchievement;				// map of CAchievement_AchievedCount

	struct achievementthink_t
	{
		float			 m_flThinkTime;
		CBaseAchievement *pAchievement;
	};
	CUtlVector<achievementthink_t> m_vecThinkListeners;					// vector of achievements that are actively thinking

	float m_flLevelInitTime;

	float m_flLastClassChangeTime;		// Time when player last changed class
	float m_flTeamplayStartTime;		// Time when player joined a non-spectating team.  Not updated if she switches game teams; cleared if she joins spectator
	float m_iMiniroundsCompleted;		// # of minirounds played since game start (for maps that have minirounds)
	char  m_szMap[MAX_PATH];			// file base of map name, cached since we access it frequently in this form
	bool  m_bGlobalStateDirty;			// do we have interesting state changes that needs to be saved?
	bool  m_bSteamDataDirty;			// do we have changes to upload to Steamworks?
	bool  m_bGlobalStateLoaded;			// have we loaded global state
	bool  m_bCheatsEverOn;				// have cheats ever been turned on in this level
	float m_flTimeLastSaved;			// last time we uploaded to Steam

    //=============================================================================
    // HPE_BEGIN
    // [dwenger] Steam Cloud Support
    //=============================================================================

    bool  m_bPersistToSteamCloud;       // true = persist data to steam cloud

    //=============================================================================
    // HPE_END
    //=============================================================================

    CUtlVector<int> m_AchievementsAwarded;
};

// helper functions
const char *GetModelName( CBaseEntity *pBaseEntity );

#ifdef CLIENT_DLL
bool CalcPlayersOnFriendsList( int iMinPlayers );
bool CalcHasNumClanPlayers( int iClanTeammates );
int	CalcPlayerCount();
int	CalcTeammateCount();
#endif // CLIENT

class IMatchmaking;
extern ConVar	cc_achievement_debug;
extern IMatchmaking *matchmaking;

#ifdef CLIENT_DLL
void MsgFunc_AchievementEvent( bf_read &msg );
#endif // CLIENT_DLL
#endif // ACHIEVEMENTMGR_H