summaryrefslogtreecommitdiff
path: root/game/server/tf/tf_achievementdata.h
diff options
context:
space:
mode:
Diffstat (limited to 'game/server/tf/tf_achievementdata.h')
-rw-r--r--game/server/tf/tf_achievementdata.h137
1 files changed, 137 insertions, 0 deletions
diff --git a/game/server/tf/tf_achievementdata.h b/game/server/tf/tf_achievementdata.h
new file mode 100644
index 0000000..7c596e4
--- /dev/null
+++ b/game/server/tf/tf_achievementdata.h
@@ -0,0 +1,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 \ No newline at end of file