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
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=============================================================================
#ifndef TF_ACHIEVEMENT_DATA_H
#define TF_ACHIEVEMENT_DATA_H
#pragma once
#include "UtlSortVector.h"
#define MAX_ACHIEVEMENT_HISTORY_SLOTS 4
#define MAX_ACHIEVEMENT_DAMAGE_HISTORY_SLOTS 128
//=============================================================================
// Custom class to manage lists of history events. Maintains a prioritized list of
// events, but includes two extra features:
// - Maximum size of the number of entries in the queue.
// - Ensures each associated-entity in the entries appears only once in the queue.
template <class T, class LessFunc, int maxSize>
class CHistoryVector : public CUtlSortVector<T, LessFunc>
{
public:
CHistoryVector()
{
}
void InsertHistory( T const &element )
{
LessFunc less;
// Make sure it's not in the list already
for ( int i = 0; i < this->Count(); i++ )
{
if ( less.HistoryMatch( this->Element(i), element ) )
{
this->Remove( i );
break;
}
}
CUtlSortVector<T, LessFunc>::Insert( element );
// Remove the oldest entry if we're over max size
if ( this->Count() > maxSize )
{
this->Remove( this->Count()-1 );
}
}
};
//=============================================================================
// Data stored in players for achievement handling
struct EntityHistory_t
{
EHANDLE hEntity;
EHANDLE hObject;
float flTimeDamage;
};
struct EntityDamageHistory_t : public EntityHistory_t
{
int nDamageAmount;
};
class CEntityHistoryLess
{
public:
bool Less( const EntityHistory_t &dmg1, const EntityHistory_t &dmg2, void *pCtx )
{
return (dmg1.flTimeDamage > dmg2.flTimeDamage);
}
bool HistoryMatch( const EntityHistory_t &dmg1, const EntityHistory_t &dmg2 )
{
return (dmg1.hEntity == dmg2.hEntity);
}
};
// Allow duplicate (source) entries with this type; HistoryMatch always returns false
class CEntityDamageHistoryLess
{
public:
bool Less( const EntityDamageHistory_t &dmg1, const EntityDamageHistory_t &dmg2, void *pCtx )
{
return ( dmg2.flTimeDamage < dmg1.flTimeDamage );
}
bool HistoryMatch( const EntityDamageHistory_t &dmg1, const EntityDamageHistory_t &dmg2 )
{
return false;
}
};
// Achievement Tracking container
class CAchievementData
{
public:
void ClearHistories( void )
{
aDamagers.RemoveAll();
aDamageEvents.RemoveAll();
aTargets.RemoveAll();
aSentryDamagers.RemoveAll();
aPushers.RemoveAll();
}
void AddDamagerToHistory( EHANDLE hDamager );
EntityHistory_t *GetDamagerHistory( int i ) { if (i >= aDamagers.Count()) return NULL; return &aDamagers[i]; }
int CountDamagersWithinTime( float flTime );
bool IsDamagerInHistory( CBaseEntity *pTarget, float flTimeWindow );
void DumpDamagers( void );
// Capture the last 64 damage events - duplicates allowed
void AddDamageEventToHistory( EHANDLE hAttacker, float flDmgAmount = 0.f );
EntityDamageHistory_t *GetDamageEventHistory( int i ) { if ( i >= aDamageEvents.Count() ) return NULL; return &aDamageEvents[i]; }
int GetDamageEventHistoryCount( void ) { return aDamageEvents.Count(); }
bool IsEntityInDamageEventHistory( CBaseEntity *pEntity, float flTimeWindow );
int GetAmountForDamagerInEventHistory( CBaseEntity *pEntity, float flTimeWindow );
void AddTargetToHistory( EHANDLE hTarget );
bool IsTargetInHistory( CBaseEntity *pTarget, float flTimeWindow );
EntityHistory_t *GetTargetHistory( int i ) { if (i >= aTargets.Count()) return NULL; return &aTargets[i]; }
int CountTargetsWithinTime( float flTime );
void AddSentryDamager( EHANDLE hDamager, EHANDLE hObject );
EntityHistory_t *IsSentryDamagerInHistory( CBaseEntity *pDamager, float flTimeWindow );
void AddPusherToHistory( EHANDLE hPlayer );
bool IsPusherInHistory( CBaseEntity *pPlayer, float flTimeWindow );
private:
CHistoryVector< EntityHistory_t, CEntityHistoryLess, MAX_ACHIEVEMENT_HISTORY_SLOTS > aDamagers;
CHistoryVector< EntityDamageHistory_t, CEntityDamageHistoryLess, MAX_ACHIEVEMENT_DAMAGE_HISTORY_SLOTS > aDamageEvents; // Duplicates allowed
CHistoryVector< EntityHistory_t, CEntityHistoryLess, MAX_ACHIEVEMENT_HISTORY_SLOTS > aTargets;
CHistoryVector< EntityHistory_t, CEntityHistoryLess, MAX_ACHIEVEMENT_HISTORY_SLOTS > aSentryDamagers;
CHistoryVector< EntityHistory_t, CEntityHistoryLess, MAX_ACHIEVEMENT_HISTORY_SLOTS > aPushers;
};
#endif
|