aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/replay/genericclassbased_replay.h
blob: 02c5e705a65651e2d1b958b00f45b455cf79882b (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
//========= Copyright Valve Corporation, All rights reserved. ============//
//=======================================================================================//

#if defined( REPLAY_ENABLED )

#ifndef GENERICCLASSBASED_REPLAY_H
#define GENERICCLASSBASED_REPLAY_H
#ifdef _WIN32
#pragma once
#endif

//----------------------------------------------------------------------------------------

#include "replay/replay.h"
#include "replay/iclientreplaycontext.h"
#include "GameEventListener.h"

// For RoundStats_t
#include "replay/gamedefs.h"

//----------------------------------------------------------------------------------------

extern IClientReplayContext *g_pClientReplayContext;

//----------------------------------------------------------------------------------------

class CGenericClassBasedReplay : public CReplay,
								 public CGameEventListener
{
	typedef CReplay BaseClass;
public:
	CGenericClassBasedReplay();
	~CGenericClassBasedReplay();

	virtual void OnBeginRecording();
	virtual void OnEndRecording();
	virtual void OnComplete();
	virtual bool ShouldAllowDelete() const;
	virtual void OnDelete();

	virtual void FireGameEvent( IGameEvent *pEvent );

	virtual bool Read( KeyValues *pIn );
	virtual void Write( KeyValues *pOut );

	virtual void DumpGameSpecificData() const;

	void SetPlayerClass( int nPlayerClass );
	void SetPlayerTeam( int nPlayerTeam );

	void RecordPlayerDeath( const char *pKillerName, int nKillerClass );

	// Add a new kill to the list
	void AddKill( const char *pPlayerName, int nPlayerClass );

	// Get the player class as a string
	virtual const char *GetPlayerClass() const;

	// Get the player team as a string
	virtual const char *GetPlayerTeam() const = 0;

	// Utility to get the material-friendly player class (demoman->demo, heavyweapons->heavy)
	virtual const char *GetMaterialFriendlyPlayerClass() const;

	// Was there a killer?
	inline bool WasKilled() const { return m_szKillerName[0] != 0; }

	// Get killer name
	const char *GetKillerName() const;

	// Get the killer class, if there was a killer
	const char *GetKillerClass() const;

	int			GetDownloadStatus() const;

	// Kill info
	struct KillData_t
	{
		char	m_szPlayerName[MAX_OSPATH];
		int		m_nPlayerClass;
	};

	inline int GetKillCount() const		{ return m_vecKills.Count(); }
	inline const KillData_t *GetKill( int nKillIndex )	{ return m_vecKills[ nKillIndex ]; }

	// A generic info struct used for dominations, assisted dominations, revenges, assisted revenged...
	// Not all data members are necessarily used
	struct GenericStatInfo_t
	{
		GenericStatInfo_t() : m_nVictimFriendId( 0 ), m_nAssisterFriendId( 0 ) {}
		uint32	m_nVictimFriendId;
		uint32	m_nAssisterFriendId;
	};

	inline int GetDominationCount() const	{ return m_vecDominations.Count(); }
	inline const GenericStatInfo_t *GetDomination( int nIndex ) const	{ return m_vecDominations[ nIndex ]; }

	inline int GetAssisterDominationCount() const	{ return m_vecAssisterDominations.Count(); }
	inline const GenericStatInfo_t *GetAssisterDomination( int nIndex ) const	{ return m_vecAssisterDominations[ nIndex ]; }

	inline int GetRevengeCount() const		{ return m_vecRevenges.Count(); }
	inline const GenericStatInfo_t *GetRevenge( int nIndex ) const	{ return m_vecRevenges[ nIndex ]; }

	inline int GetAssisterRevengeCount() const		{ return m_vecAssisterRevenges.Count(); }
	inline const GenericStatInfo_t *GetAssisterRevenge( int nIndex ) const	{ return m_vecAssisterRevenges[ nIndex ]; }

	RoundStats_t const &GetStats() const	{ return m_lifeStats; }

protected:
	int		m_nPlayerClass;
	int		m_nPlayerTeam;
	int		m_nStatUndefined;

	char	m_szKillerName[ MAX_OSPATH ];
	int		m_nKillerClass;

	virtual bool IsValidClass( int nClass ) const = 0;
	virtual bool IsValidTeam( int iTeam ) const = 0;
	virtual bool GetCurrentStats( RoundStats_t &out ) = 0;
	virtual const char *GetStatString( int iStat ) const = 0;
	virtual const char *GetPlayerClass( int iClass ) const = 0;

	virtual void Update();

	// Domination
	void AddDomination( int nVictimID );
	void AddAssisterDomination( int nVictimID, int nAssiterID );

	void AddRevenge( int nVictimID );
	void AddAssisterRevenge( int nVictimID, int nAssiterID );

	float GetKillScreenshotDelay();

	RoundStats_t	m_refStats;		// Reference stats, used to compute current stats
	RoundStats_t	m_lifeStats;	// Stats for this life, based on reference stats (m_refStats)

private:
	void MedicUpdate();

	bool GetFriendIdFromUserId( int nPlayerIndex, uint32 &nFriendIdOut ) const;	// Get a friend ID based on player index.  Returns true on success
	void AddKillStatFromUserIds( CUtlVector< GenericStatInfo_t * > &vec, int nVictimId, int nAssisterId = 0 );
	void AddKillStatFromFriendIds( CUtlVector< GenericStatInfo_t * > &vec, uint32 nVictimFriendId, uint32 nAssisterFriendId = 0 );
	void WriteKillStatVector( CUtlVector< GenericStatInfo_t * > const &vec, const char *pSubKeyName, const char *pElementKeyName,
							  KeyValues *pRootKey, int nNumMembersToWrite ) const;
	void AddKillStats( CUtlVector< GenericStatInfo_t * > &vecKillStats, KeyValues *pIn, const char *pSubKeyName, int iStatIndex );
	void RecordUpdatedStats();

	CUtlVector< KillData_t * >			m_vecKills;
	CUtlVector< GenericStatInfo_t * >	m_vecDominations;
	CUtlVector< GenericStatInfo_t * >	m_vecAssisterDominations;
	CUtlVector< GenericStatInfo_t * >	m_vecRevenges;
	CUtlVector< GenericStatInfo_t * >	m_vecAssisterRevenges;

	// TODO... dominations, achievements, etc.
};

//----------------------------------------------------------------------------------------

inline CGenericClassBasedReplay *ToGenericClassBasedReplay( CReplay *pClientReplay )
{
	return static_cast< CGenericClassBasedReplay * >( pClientReplay );
}

inline const CGenericClassBasedReplay *ToGenericClassBasedReplay( const CReplay *pClientReplay )
{
	return static_cast< const CGenericClassBasedReplay * >( pClientReplay );
}

inline CGenericClassBasedReplay *GetGenericClassBasedReplay( ReplayHandle_t hReplay )
{
	return ToGenericClassBasedReplay( g_pClientReplayContext->GetReplay( hReplay ) );
}

//----------------------------------------------------------------------------------------

#endif	// GENERICCLASSBASED_REPLAY_H

#endif