Team Fortress 2 Source Code as on 22/4/2020
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.

136 lines
4.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. //=============================================================================
  4. #ifndef TF_ACHIEVEMENT_DATA_H
  5. #define TF_ACHIEVEMENT_DATA_H
  6. #pragma once
  7. #include "UtlSortVector.h"
  8. #define MAX_ACHIEVEMENT_HISTORY_SLOTS 4
  9. #define MAX_ACHIEVEMENT_DAMAGE_HISTORY_SLOTS 128
  10. //=============================================================================
  11. // Custom class to manage lists of history events. Maintains a prioritized list of
  12. // events, but includes two extra features:
  13. // - Maximum size of the number of entries in the queue.
  14. // - Ensures each associated-entity in the entries appears only once in the queue.
  15. template <class T, class LessFunc, int maxSize>
  16. class CHistoryVector : public CUtlSortVector<T, LessFunc>
  17. {
  18. public:
  19. CHistoryVector()
  20. {
  21. }
  22. void InsertHistory( T const &element )
  23. {
  24. LessFunc less;
  25. // Make sure it's not in the list already
  26. for ( int i = 0; i < this->Count(); i++ )
  27. {
  28. if ( less.HistoryMatch( this->Element(i), element ) )
  29. {
  30. this->Remove( i );
  31. break;
  32. }
  33. }
  34. CUtlSortVector<T, LessFunc>::Insert( element );
  35. // Remove the oldest entry if we're over max size
  36. if ( this->Count() > maxSize )
  37. {
  38. this->Remove( this->Count()-1 );
  39. }
  40. }
  41. };
  42. //=============================================================================
  43. // Data stored in players for achievement handling
  44. struct EntityHistory_t
  45. {
  46. EHANDLE hEntity;
  47. EHANDLE hObject;
  48. float flTimeDamage;
  49. };
  50. struct EntityDamageHistory_t : public EntityHistory_t
  51. {
  52. int nDamageAmount;
  53. };
  54. class CEntityHistoryLess
  55. {
  56. public:
  57. bool Less( const EntityHistory_t &dmg1, const EntityHistory_t &dmg2, void *pCtx )
  58. {
  59. return (dmg1.flTimeDamage > dmg2.flTimeDamage);
  60. }
  61. bool HistoryMatch( const EntityHistory_t &dmg1, const EntityHistory_t &dmg2 )
  62. {
  63. return (dmg1.hEntity == dmg2.hEntity);
  64. }
  65. };
  66. // Allow duplicate (source) entries with this type; HistoryMatch always returns false
  67. class CEntityDamageHistoryLess
  68. {
  69. public:
  70. bool Less( const EntityDamageHistory_t &dmg1, const EntityDamageHistory_t &dmg2, void *pCtx )
  71. {
  72. return ( dmg2.flTimeDamage < dmg1.flTimeDamage );
  73. }
  74. bool HistoryMatch( const EntityDamageHistory_t &dmg1, const EntityDamageHistory_t &dmg2 )
  75. {
  76. return false;
  77. }
  78. };
  79. // Achievement Tracking container
  80. class CAchievementData
  81. {
  82. public:
  83. void ClearHistories( void )
  84. {
  85. aDamagers.RemoveAll();
  86. aDamageEvents.RemoveAll();
  87. aTargets.RemoveAll();
  88. aSentryDamagers.RemoveAll();
  89. aPushers.RemoveAll();
  90. }
  91. void AddDamagerToHistory( EHANDLE hDamager );
  92. EntityHistory_t *GetDamagerHistory( int i ) { if (i >= aDamagers.Count()) return NULL; return &aDamagers[i]; }
  93. int CountDamagersWithinTime( float flTime );
  94. bool IsDamagerInHistory( CBaseEntity *pTarget, float flTimeWindow );
  95. void DumpDamagers( void );
  96. // Capture the last 64 damage events - duplicates allowed
  97. void AddDamageEventToHistory( EHANDLE hAttacker, float flDmgAmount = 0.f );
  98. EntityDamageHistory_t *GetDamageEventHistory( int i ) { if ( i >= aDamageEvents.Count() ) return NULL; return &aDamageEvents[i]; }
  99. int GetDamageEventHistoryCount( void ) { return aDamageEvents.Count(); }
  100. bool IsEntityInDamageEventHistory( CBaseEntity *pEntity, float flTimeWindow );
  101. int GetAmountForDamagerInEventHistory( CBaseEntity *pEntity, float flTimeWindow );
  102. void AddTargetToHistory( EHANDLE hTarget );
  103. bool IsTargetInHistory( CBaseEntity *pTarget, float flTimeWindow );
  104. EntityHistory_t *GetTargetHistory( int i ) { if (i >= aTargets.Count()) return NULL; return &aTargets[i]; }
  105. int CountTargetsWithinTime( float flTime );
  106. void AddSentryDamager( EHANDLE hDamager, EHANDLE hObject );
  107. EntityHistory_t *IsSentryDamagerInHistory( CBaseEntity *pDamager, float flTimeWindow );
  108. void AddPusherToHistory( EHANDLE hPlayer );
  109. bool IsPusherInHistory( CBaseEntity *pPlayer, float flTimeWindow );
  110. private:
  111. CHistoryVector< EntityHistory_t, CEntityHistoryLess, MAX_ACHIEVEMENT_HISTORY_SLOTS > aDamagers;
  112. CHistoryVector< EntityDamageHistory_t, CEntityDamageHistoryLess, MAX_ACHIEVEMENT_DAMAGE_HISTORY_SLOTS > aDamageEvents; // Duplicates allowed
  113. CHistoryVector< EntityHistory_t, CEntityHistoryLess, MAX_ACHIEVEMENT_HISTORY_SLOTS > aTargets;
  114. CHistoryVector< EntityHistory_t, CEntityHistoryLess, MAX_ACHIEVEMENT_HISTORY_SLOTS > aSentryDamagers;
  115. CHistoryVector< EntityHistory_t, CEntityHistoryLess, MAX_ACHIEVEMENT_HISTORY_SLOTS > aPushers;
  116. };
  117. #endif