You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
4.4 KiB
137 lines
4.4 KiB
//========= 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 |