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.

171 lines
5.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Tracker for War Data on a player
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "tf_gc_server.h"
  9. #include "tf_wartracker.h"
  10. #include "tf_gcmessages.pb.h"
  11. #include "tf_player.h"
  12. #include "gcsdk/gcconstants.h"
  13. #include "tf_gamerules.h"
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. #define WAR_ASSIST_POINTS 1
  17. #define WAR_KILL_POINTS 2
  18. #define WAR_WIN_POINTS 20
  19. #ifdef STAGING_ONLY
  20. ConVar tf_commit_every_war_point( "tf_commit_every_war_point", "0" );
  21. #endif
  22. CTFWarTrackerManager* GetWarTrackerManager()
  23. {
  24. static CTFWarTrackerManager trackerManager;
  25. return &trackerManager;
  26. }
  27. CTFWarTrackerManager::CTFWarTrackerManager()
  28. {}
  29. CSOTrackerManager::SOTrackerMap_t::KeyType_t CTFWarTrackerManager::GetKeyForObjectTracker( const CSharedObject* pItem, CSteamID steamIDOwner )
  30. {
  31. return steamIDOwner.ConvertToUint64();
  32. }
  33. #ifdef GAME_DLL
  34. void CTFWarTrackerManager::SendMessageForCommit( const ::google::protobuf::Message* pProtoMessage ) const
  35. {
  36. GCSDK::CProtoBufMsg< CGCMsgGC_War_IndividualUpdate > msg( k_EMsgGC_War_IndividualUpdate );
  37. msg.Body() = *assert_cast< const CGCMsgGC_War_IndividualUpdate* >( pProtoMessage );
  38. GCClientSystem()->BSendMessage( msg );
  39. }
  40. #endif
  41. CFmtStr CTFWarTrackerManager::GetDebugObjectDescription( const CSharedObject* pItem ) const
  42. {
  43. const CWarData* pWarData = assert_cast< const CWarData* >( pItem );
  44. const CWarDefinition* pWarDef = GetItemSchema()->GetWarDefinitionByIndex( pWarData->Obj().war_id() );
  45. const CWarDefinition::CWarSideDefinition_t* pSide = pWarDef->GetSide( pWarData->Obj().affiliation() );
  46. return CFmtStr( "%s: Side: %s Points: %d", pWarDef->GetDefName(), pSide->m_pszLocalizedName, pWarData->Obj().points_scored() );
  47. }
  48. CBaseSOTracker* CTFWarTrackerManager::AllocateNewTracker( const CSharedObject* pItem, CSteamID steamIDOwner, CSOTrackerManager* pManager ) const
  49. {
  50. return new CTFWarTracker( pItem, steamIDOwner, pManager );
  51. }
  52. ::google::protobuf::Message* CTFWarTrackerManager::AllocateNewProtoMessage() const
  53. {
  54. return new CGCMsgGC_War_IndividualUpdate();
  55. }
  56. void CTFWarTrackerManager::OnCommitRecieved( const ::google::protobuf::Message* pProtoMsg )
  57. {
  58. // ...
  59. }
  60. bool CTFWarTrackerManager::ShouldTrackObject( const CSteamID & steamIDOwner, const CSharedObject *pObject ) const
  61. {
  62. // We only want war data!
  63. if ( pObject->GetTypeID() != CWarData::k_nTypeID )
  64. return false;
  65. #ifdef CLIENT_DLL
  66. if ( steamapicontext()->SteamUser()->GetSteamID() != steamIDOwner )
  67. return false;
  68. #endif
  69. const CWarData* pWarData = assert_cast< const CWarData* >( pObject );
  70. const CWarDefinition* pWarDef = GetItemSchema()->GetWarDefinitionByIndex( pWarData->Obj().war_id() );
  71. // Needs to be for a real war!
  72. if ( !pWarDef )
  73. return false;
  74. if ( !pWarDef->IsActive() )
  75. return false;
  76. // Needs to be for a valid side!
  77. if ( !pWarDef->IsValidSide( pWarData->Obj().affiliation() ) )
  78. return false;
  79. return true;
  80. }
  81. int CTFWarTrackerManager::CompareRecords( const ::google::protobuf::Message* pNewProtoMsg, const ::google::protobuf::Message* pExistingProtoMsg ) const
  82. {
  83. const CGCMsgGC_War_IndividualUpdate* pNew = assert_cast< const CGCMsgGC_War_IndividualUpdate* >( pNewProtoMsg );
  84. const CGCMsgGC_War_IndividualUpdate* pExisting = assert_cast< const CGCMsgGC_War_IndividualUpdate* >( pExistingProtoMsg );
  85. return pNew->score() - pExisting->score();
  86. }
  87. CTFWarTracker::CTFWarTracker( const CSharedObject* pItem, CSteamID SteamIDOwner, CSOTrackerManager* pManager )
  88. : CBaseSOTracker( pItem, SteamIDOwner, pManager )
  89. {
  90. m_ProtoData.Clear();
  91. m_ProtoData.set_steam_id( SteamIDOwner.ConvertToUint64() );
  92. ListenForGameEvent( "player_score_changed" );
  93. }
  94. //-----------------------------------------------------------------------------
  95. // Purpose: Send to the GC our points scored for Team Spy or Team Engy
  96. //-----------------------------------------------------------------------------
  97. void CTFWarTracker::CommitChangesToDB()
  98. {
  99. // Nothing to update!
  100. if ( m_ProtoData.score() == 0 )
  101. return;
  102. m_pManager->AddCommitRecord( &m_ProtoData, GetOwnerSteamID().ConvertToUint64(), false );
  103. // Reset! We're adding to our score on the GC, not setting it
  104. m_ProtoData.set_score( 0 );
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose: Listen for player deaths and give points if the player we're tracking
  108. // kills someone on the other team
  109. //-----------------------------------------------------------------------------
  110. void CTFWarTracker::FireGameEvent( IGameEvent *pEvent )
  111. {
  112. // Only score points in competitive
  113. if ( !TFGameRules()->IsCompetitiveMode() )
  114. return;
  115. const char *pszName = pEvent->GetName();
  116. // You get a point when you kill, or assist in a kill, while in a comp game
  117. if( FStrEq( pszName, "player_score_changed" ) )
  118. {
  119. const CTFPlayer *pScorer = ToTFPlayer( UTIL_PlayerByIndex( pEvent->GetInt( "player" ) ) );
  120. const CTFPlayer *pOwner = GetTrackedPlayer();
  121. if ( pScorer != pOwner )
  122. return;
  123. int nDelta = pEvent->GetInt( "delta", 0 );
  124. // Only take positive changes
  125. if ( nDelta <= 0 )
  126. return;
  127. m_ProtoData.set_score( m_ProtoData.score() + nDelta );
  128. }
  129. #ifdef STAGING_ONLY
  130. if ( tf_commit_every_war_point.GetBool() )
  131. {
  132. CommitChangesToDB();
  133. }
  134. #endif
  135. }