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
|