diff options
Diffstat (limited to 'game/shared/tf/tf_mapinfo.cpp')
| -rw-r--r-- | game/shared/tf/tf_mapinfo.cpp | 849 |
1 files changed, 849 insertions, 0 deletions
diff --git a/game/shared/tf/tf_mapinfo.cpp b/game/shared/tf/tf_mapinfo.cpp new file mode 100644 index 0000000..dad3d0b --- /dev/null +++ b/game/shared/tf/tf_mapinfo.cpp @@ -0,0 +1,849 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= +#include "cbase.h" + +#include "tf_mapinfo.h" +#include <filesystem.h> +#include "GameEventListener.h" +#include "econ_item_system.h" +#include "tf_item_inventory.h" +#include "econ_contribution.h" +#include "tf_duel_summary.h" +#include "gc_clientsystem.h" +#include "tf_duckleaderboard.h" +#include "tf_gamerules.h" +#include "tf_matchmaking_shared.h" + +#ifdef CLIENT_DLL + #include "hud_macros.h" +#endif // CLIENT_DLL + +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> + +#ifdef CLIENT_DLL +ConVar tf_duck_upload_rate( "tf_duck_upload_rate", "2400", FCVAR_DEVELOPMENTONLY ); // Make this DevOnly At ship and 60 seconds +#endif + +const char *g_szLadderLeaderboardNames[] = +{ + "tf2_ladder_6v6", + "tf2_ladder_public", + "tf2_ladder_9v9", + "tf2_ladder_12v12", +}; +COMPILE_TIME_ASSERT( ARRAYSIZE( g_szLadderLeaderboardNames ) == LADDER_LEADERBOARDS_MAX ); + +void __MsgFunc_EOTLDuckEvent( bf_read &msg ); + +//----------------------------------------------------------------------------- +int SortLeaderboardVec( LeaderboardEntry_t * const *p1, LeaderboardEntry_t * const *p2 ) +{ + return ( *p2 )->m_nScore - ( *p1 )->m_nScore; +} +//----------------------------------------------------------------------------- + +static void RetrieveLeaderboardEntries( LeaderboardScoresDownloaded_t &scores, CUtlVector< LeaderboardEntry_t* > &entries ) +{ + entries.PurgeAndDeleteElements(); + entries.EnsureCapacity( scores.m_cEntryCount ); + for ( int i = 0; i < scores.m_cEntryCount; ++i ) + { + LeaderboardEntry_t *leaderboardEntry = new LeaderboardEntry_t; + if ( steamapicontext->SteamUserStats()->GetDownloadedLeaderboardEntry( scores.m_hSteamLeaderboardEntries, i, leaderboardEntry, NULL, 0 ) ) + { + entries.AddToTail( leaderboardEntry ); + } + } +} + + +CLeaderboardInfo::CLeaderboardInfo( const char *pLeaderboardName ) +{ + m_pLeaderboardName = pLeaderboardName ? V_strdup( pLeaderboardName ) : NULL; + memset( &findLeaderboardResults, 0, sizeof( findLeaderboardResults ) ); + iNumLeaderboardEntries = 0; + m_kLeaderboardType = kMapLeaderboard; + m_iMyScore = 0; + m_bHasPendingUpdate = false; + m_bLeaderboardFound = false; +} + +CLeaderboardInfo::~CLeaderboardInfo() +{ + downloadedLeaderboardScoresGlobal.PurgeAndDeleteElements(); + downloadedLeaderboardScoresGlobalAroundUser.PurgeAndDeleteElements(); + downloadedLeaderboardScoresFriends.PurgeAndDeleteElements(); + delete m_pLeaderboardName; +} + +void CLeaderboardInfo::RetrieveLeaderboardData() +{ + if ( steamapicontext && steamapicontext->SteamUserStats() ) + { + if ( m_kLeaderboardType == kMapLeaderboard ) + { + SteamAPICall_t apicall = steamapicontext->SteamUserStats()->FindLeaderboard( CFmtStr( "contributions_%s", m_pLeaderboardName ) ); + findLeaderboardCallback.Set( apicall, this, &CLeaderboardInfo::OnFindLeaderboard ); + } + else if ( m_kLeaderboardType == kDuckLeaderboard || m_kLeaderboardType == kDuckStat ) + { + SteamAPICall_t apicall = steamapicontext->SteamUserStats()->FindLeaderboard( m_pLeaderboardName ); + findLeaderboardCallback.Set( apicall, this, &CLeaderboardInfo::OnFindLeaderboard ); + } + else if ( m_kLeaderboardType == kLadderLeaderboard ) + { + SteamAPICall_t apicall = steamapicontext->SteamUserStats()->FindLeaderboard( m_pLeaderboardName ); + findLeaderboardCallback.Set( apicall, this, &CLeaderboardInfo::OnFindLeaderboard ); + } + } +} + +bool CLeaderboardInfo::DownloadLeaderboardData() +{ + if ( !findLeaderboardResults.m_bLeaderboardFound ) + return false; + + if ( m_kLeaderboardType == kMapLeaderboard ) + { + SteamAPICall_t apicall = steamapicontext->SteamUserStats()->DownloadLeaderboardEntries( findLeaderboardResults.m_hSteamLeaderboard, k_ELeaderboardDataRequestGlobal, 1, 5 ); + downloadLeaderboardCallbackGlobal.Set( apicall, this, &CLeaderboardInfo::OnLeaderboardScoresDownloadedGlobal ); + apicall = steamapicontext->SteamUserStats()->DownloadLeaderboardEntries( findLeaderboardResults.m_hSteamLeaderboard, k_ELeaderboardDataRequestGlobalAroundUser, -2, 2 ); + downloadLeaderboardCallbackGlobalAroundUser.Set( apicall, this, &CLeaderboardInfo::OnLeaderboardScoresDownloadedGlobalAroundUser ); + apicall = steamapicontext->SteamUserStats()->DownloadLeaderboardEntries( findLeaderboardResults.m_hSteamLeaderboard, k_ELeaderboardDataRequestFriends, 1, 5 ); + downloadLeaderboardCallbackFriends.Set( apicall, this, &CLeaderboardInfo::OnLeaderboardScoresDownloadedFriends ); + return true; + } + + if ( m_kLeaderboardType == kDuckLeaderboard ) + { + SteamAPICall_t apicall = steamapicontext->SteamUserStats()->DownloadLeaderboardEntries( findLeaderboardResults.m_hSteamLeaderboard, k_ELeaderboardDataRequestFriends, -6, 6 ); + downloadLeaderboardCallbackFriends.Set( apicall, this, &CLeaderboardInfo::OnLeaderboardScoresDownloadedFriends ); + return true; + } + + if ( m_kLeaderboardType == kDuckStat ) + { + SteamAPICall_t apicall = steamapicontext->SteamUserStats()->DownloadLeaderboardEntries( findLeaderboardResults.m_hSteamLeaderboard, k_ELeaderboardDataRequestFriends, 0, 0 ); + downloadLeaderboardCallbackFriends.Set( apicall, this, &CLeaderboardInfo::OnLeaderboardScoresDownloadedFriends ); + return true; + } + + if ( m_kLeaderboardType == kLadderLeaderboard ) + { + SteamAPICall_t apicall = steamapicontext->SteamUserStats()->DownloadLeaderboardEntries( findLeaderboardResults.m_hSteamLeaderboard, k_ELeaderboardDataRequestGlobal, 1, 100 ); + downloadLeaderboardCallbackGlobal.Set( apicall, this, &CLeaderboardInfo::OnLeaderboardScoresDownloadedGlobal ); + apicall = steamapicontext->SteamUserStats()->DownloadLeaderboardEntries( findLeaderboardResults.m_hSteamLeaderboard, k_ELeaderboardDataRequestFriends, -45, 45 ); + downloadLeaderboardCallbackFriends.Set( apicall, this, &CLeaderboardInfo::OnLeaderboardScoresDownloadedFriends ); + return true; + } + + return false; +} + +void CLeaderboardInfo::OnFindLeaderboard( LeaderboardFindResult_t *pResult, bool bIOFailure ) +{ + findLeaderboardResults = *pResult; +} + +void CLeaderboardInfo::OnLeaderboardScoresDownloadedGlobal( LeaderboardScoresDownloaded_t *pResult, bool bIOFailure ) +{ + RetrieveLeaderboardEntries( *pResult, downloadedLeaderboardScoresGlobal ); + iNumLeaderboardEntries = steamapicontext->SteamUserStats()->GetLeaderboardEntryCount( findLeaderboardResults.m_hSteamLeaderboard ); +} + +void CLeaderboardInfo::OnLeaderboardScoresDownloadedGlobalAroundUser( LeaderboardScoresDownloaded_t *pResult, bool bIOFailure ) +{ + RetrieveLeaderboardEntries( *pResult, downloadedLeaderboardScoresGlobalAroundUser ); +} + +void CLeaderboardInfo::OnLeaderboardScoresDownloadedFriends( LeaderboardScoresDownloaded_t *pResult, bool bIOFailure ) +{ + RetrieveLeaderboardEntries( *pResult, downloadedLeaderboardScoresFriends ); + iNumLeaderboardEntries = steamapicontext->SteamUserStats()->GetLeaderboardEntryCount( findLeaderboardResults.m_hSteamLeaderboard ); + CSteamID localID; + if ( steamapicontext && steamapicontext->SteamUser() ) + { + localID = steamapicontext->SteamUser()->GetSteamID(); + } + + FOR_EACH_VEC( downloadedLeaderboardScoresFriends, i ) + { + if ( downloadedLeaderboardScoresFriends[i]->m_steamIDUser == localID ) + { + if ( m_iMyScore < downloadedLeaderboardScoresFriends[i]->m_nScore ) + { + // First update on finding the leaderboard, any gotten kills need to add to accumulate + if ( m_bLeaderboardFound == false ) + { + if ( m_iMyScore > 0 ) + { + m_bHasPendingUpdate = true; + } + m_iMyScore += downloadedLeaderboardScoresFriends[i]->m_nScore; + } + else + { + m_iMyScore = downloadedLeaderboardScoresFriends[i]->m_nScore; + } + } + + // Use My Saved Score + downloadedLeaderboardScoresFriends[i]->m_nScore = m_iMyScore; + } + } + + downloadedLeaderboardScoresFriends.Sort( &SortLeaderboardVec ); + + m_bLeaderboardFound = true; +} + +void CLeaderboardInfo::SetMyScore( int score ) +{ + m_iMyScore = score; + + if ( !m_bLeaderboardFound ) + return; + + // Update my leaderboard and resort + iNumLeaderboardEntries = steamapicontext->SteamUserStats()->GetLeaderboardEntryCount( findLeaderboardResults.m_hSteamLeaderboard ); + CSteamID localID; + if ( steamapicontext && steamapicontext->SteamUser() ) + { + localID = steamapicontext->SteamUser()->GetSteamID(); + } + + FOR_EACH_VEC( downloadedLeaderboardScoresFriends, i ) + { + if ( downloadedLeaderboardScoresFriends[i]->m_steamIDUser == localID ) + { + if ( m_iMyScore > downloadedLeaderboardScoresFriends[i]->m_nScore ) + { + // Use My Saved Score + downloadedLeaderboardScoresFriends[i]->m_nScore = m_iMyScore; + downloadedLeaderboardScoresFriends.Sort( &SortLeaderboardVec ); + break; + } + } + } + +} + +//----------------------------------------------------------------------------- +class CMapInfoContainer : public CAutoGameSystemPerFrame, public CGameEventListener +{ +public: + + CMapInfoContainer() + { + memset( &m_findDuelLeaderboardResults, 0, sizeof( m_findDuelLeaderboardResults ) ); + m_flNextUpdateDuckScoreTime = Plat_FloatTime() + 10.0f; +#ifdef CLIENT_DLL + m_flNextDuckScoresUploadTime = Plat_FloatTime() + tf_duck_upload_rate.GetFloat(); +#endif + m_flNextLadderUpdateTime = Plat_FloatTime() + 10.f; + } + + virtual char const *Name() + { + return "CMapInfoContainer"; + } + + ~CMapInfoContainer() + { + m_vecMapInfos.PurgeAndDeleteElements(); + m_downloadedDuelLeaderboardScores_GlobalAroundUser.PurgeAndDeleteElements(); + m_downloadedDuelLeaderboardScores_Friends.PurgeAndDeleteElements(); + + // For ducks + m_vecDuckInfo.PurgeAndDeleteElements(); + // Ladders + m_vecLadderLeaderboards.PurgeAndDeleteElements(); + } + +#ifdef CLIENT_DLL + + virtual void LevelShutdownPreEntity() + { + // upload scores on level leave + //DuckUploadPendingScores(); + } + + // Gets called each frame + virtual void Update( float frametime ) + { + if ( m_flNextUpdateDuckScoreTime > 0 && m_flNextUpdateDuckScoreTime < Plat_FloatTime() ) + { + if ( DownloadDuckLeaderboard() ) + { + m_flNextUpdateDuckScoreTime = -1.0f; + } + } + + if ( m_flNextLadderUpdateTime > 0.f && m_flNextLadderUpdateTime < Plat_FloatTime() ) + { + if ( DownloadLadderLeaderboard() ) + { + m_flNextLadderUpdateTime = -1.f; + } + } + + // Duck Journal is off, no longer uploading + //if ( m_flNextDuckScoresUploadTime < Plat_FloatTime() ) + //{ + // // Hard limit the rate players can update scores + // float flNextUpdateTime = tf_duck_upload_rate.GetFloat(); + // if ( DuckUploadPendingScores() ) + // { + // // Request new score + // m_flNextUpdateDuckScoreTime = Plat_FloatTime() + 10.0f; + // } + // // 4x as long if you don't have a Duck Journal + // C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); + // if ( pPlayer ) + // { + // static CSchemaAttributeDefHandle pAttr_DuckLevelBadge( "duck badge level" ); + // if ( pAttr_DuckLevelBadge ) + // { + // CTFWearable *pActionItem = pPlayer->GetEquippedWearableForLoadoutSlot( LOADOUT_POSITION_ACTION ); + // // Don't care about the level, just if the attribute is found + // if ( pActionItem && FindAttribute( pActionItem->GetAttributeContainer()->GetItem(), pAttr_DuckLevelBadge ) ) + // { + // flNextUpdateTime *= 0.5f; + // } + // } + // } + // m_flNextDuckScoresUploadTime = Plat_FloatTime() + flNextUpdateTime; + //} + } +#endif // CLIENT_DLL + + //----------------------------------------------------------------------------- + // for duels + void DownloadDuelLeaderboard() + { + if ( m_findDuelLeaderboardResults.m_bLeaderboardFound ) + { + // and start downloading the leaderboards + // friends + SteamAPICall_t apicall = steamapicontext->SteamUserStats()->DownloadLeaderboardEntries( m_findDuelLeaderboardResults.m_hSteamLeaderboard, k_ELeaderboardDataRequestFriends, 1, 10 ); + m_downloadLeaderboardCallback_Friends.Set( apicall, this, &CMapInfoContainer::OnDuelLeaderboardScoresDownloaded_Friends ); + // global around user + apicall = steamapicontext->SteamUserStats()->DownloadLeaderboardEntries( m_findDuelLeaderboardResults.m_hSteamLeaderboard, k_ELeaderboardDataRequestGlobalAroundUser, -4, 5 ); + m_downloadLeaderboardCallback_GlobalAroundUser.Set( apicall, this, &CMapInfoContainer::OnDuelLeaderboardScoresDownloaded_GlobalAroundUser ); + } + } + + void OnFindDuelLeaderboard( LeaderboardFindResult_t *pResult, bool bIOFailure ) + { + m_findDuelLeaderboardResults = *pResult; + DownloadDuelLeaderboard(); + } + + void OnDuelLeaderboardScoresDownloaded_GlobalAroundUser( LeaderboardScoresDownloaded_t *pResult, bool bIOFailure ) + { + RetrieveLeaderboardEntries( *pResult, m_downloadedDuelLeaderboardScores_GlobalAroundUser ); + } + + void OnDuelLeaderboardScoresDownloaded_Friends( LeaderboardScoresDownloaded_t *pResult, bool bIOFailure ) + { + RetrieveLeaderboardEntries( *pResult, m_downloadedDuelLeaderboardScores_Friends ); + } + + // ************************************************************************************************************************** + bool DownloadLadderLeaderboard() + { + bool bDownloading = false; + FOR_EACH_VEC( m_vecLadderLeaderboards, i ) + { + bDownloading |= m_vecLadderLeaderboards[i]->DownloadLeaderboardData(); + } + return bDownloading; + } + + CLeaderboardInfo *GetLadderLeaderboard( const char *pszName ) + { + FOR_EACH_VEC( m_vecLadderLeaderboards, i ) + { + CLeaderboardInfo *pInfo = m_vecLadderLeaderboards[i]; + if ( pszName && pInfo && !V_strcmp( pszName, pInfo->GetLeaderboardName() ) ) + { + return pInfo; + } + } + + return NULL; + } + + // ************************************************************************************************************************** + bool DownloadDuckLeaderboard() + { + bool bDownloading = false; + FOR_EACH_VEC( m_vecDuckInfo, i ) + { + bDownloading |= m_vecDuckInfo[i]->DownloadLeaderboardData(); + } + return bDownloading; + } + + CLeaderboardInfo *GetDuckLeaderboard( const char* kName ) + { + FOR_EACH_VEC( m_vecDuckInfo, i ) + { + CLeaderboardInfo *pInfo = m_vecDuckInfo[i]; + if ( strstr( kName, pInfo->GetLeaderboardName() ) != NULL ) + { + return pInfo; + } + } + + return NULL; + } + + bool DuckUploadPendingScores() + { + return false; + + //CSteamID localID; + + //if ( !steamapicontext || !steamapicontext->SteamUser() ) + // return false; + + //localID = steamapicontext->SteamUser()->GetSteamID(); + + //bool bUpdatedScores = false; + //for ( int i = 0; i < DUCK_NUM_LEADERBOARDS; ++i ) + //{ + // CLeaderboardInfo *pLeaderboard = GetDuckLeaderboard( g_szDuckLeaderboardNames[i] ); + // + // if ( pLeaderboard && pLeaderboard->IsLeaderboardFound() && pLeaderboard->HasPendingUpdate() ) + // { + // pLeaderboard->SetHasPendingUpdate( false ); + // bUpdatedScores = true; + + // int iScoreCheck = RandomInt( INT_MAX / 2, INT_MAX ); + // // Tell the GC to update our duck contribution + // GCSDK::CProtoBufMsg<CGCMsgGC_PlayerDuckLeaderboard_IndividualUpdate> msg( k_EMsgGC_DuckLeaderboard_IndividualUpdate ); + // msg.Body().set_score( pLeaderboard->GetMyScore() ); + // msg.Body().set_type( i ); + + // MD5Context_t md5Context; + // MD5Init( &md5Context ); + // + // AccountID_t unAccountId = localID.GetAccountID(); + // int nScore = pLeaderboard->GetMyScore(); + + // MD5Update( &md5Context, static_cast<const uint8 *>( (void *)&unAccountId ), sizeof( unAccountId ) ); + // MD5Update( &md5Context, static_cast<const uint8 *>( (void *)&nScore ), sizeof( nScore ) ); + // MD5Update( &md5Context, static_cast<const uint8 *>( (void *)&i ), sizeof( i ) ); + // MD5Update( &md5Context, static_cast<const uint8 *>( (void *)&TF_DUCK_ID ), sizeof( TF_DUCK_ID ) ); + // MD5Update( &md5Context, static_cast<const uint8 *>( (void *)&iScoreCheck ), sizeof( iScoreCheck ) ); + // + // MD5Value_t md5Result; + // MD5Final( &md5Result.bits[0], &md5Context ); + // msg.Body().set_score_id( &md5Result.bits[0], MD5_DIGEST_LENGTH ); + // msg.Body().set_score_check( iScoreCheck ); + // GCClientSystem()->BSendMessage( msg ); + // } + //} + //return bUpdatedScores; + } + + void DuckUpdateScore( int iIncrement, EDuckLeaderboardTypes kLeaderboard ) + { + // Get Current Score + CLeaderboardInfo *pLeaderboard = GetDuckLeaderboard( g_szDuckLeaderboardNames[kLeaderboard] ); + int iCurrentScore = pLeaderboard->GetMyScore(); + int iNewScore = iCurrentScore + iIncrement; + +#ifdef CLIENT_DLL + int iOldLevel = iCurrentScore / DUCK_XP_SCALE; + int iNewLevel = iNewScore / DUCK_XP_SCALE; + + if ( iNewLevel > iOldLevel ) + { + IGameEvent *event = gameeventmanager->CreateEvent( "duck_xp_level_up" ); + if ( event ) + { + event->SetInt( "level", iNewLevel ); + gameeventmanager->FireEventClientSide( event ); + } + } +#endif + + // Set my new score + pLeaderboard->SetMyScore( iNewScore ); + pLeaderboard->SetHasPendingUpdate( true ); + } + + //----------------------------------------------------------------------------- + virtual bool Init() + { + ListenForGameEvent( "item_schema_initialized" ); +#ifdef CLIENT_DLL + HOOK_MESSAGE( EOTLDuckEvent ); +#endif // CLIENT_DLL + return true; + } + + virtual void FireGameEvent( IGameEvent *event ) + { + if ( Q_strcmp( event->GetName(), "item_schema_initialized" ) != 0 ) + return; + + for ( int i = 0; i < GetItemSchema()->GetMapCount(); i++ ) + { + CLeaderboardInfo *pInfo = new CLeaderboardInfo( GetItemSchema()->GetMasterMapDefByIndex( i )->pszMapName ); + pInfo->m_kLeaderboardType = kMapLeaderboard; + m_vecMapInfos.AddToTail( pInfo ); + + const MapDef_t *pMapDef = GetItemSchema()->GetMasterMapDefByName( pInfo->GetLeaderboardName() ); + if ( pMapDef && pMapDef->IsCommunityMap() ) + { + // retrieve leaderboard info + pInfo->RetrieveLeaderboardData(); + } + } + + // find duel leaderboards + if ( steamapicontext && steamapicontext->SteamUserStats() ) + { + SteamAPICall_t apicall = steamapicontext->SteamUserStats()->FindLeaderboard( "duel_wins" ); + m_findLeaderboardCallback.Set( apicall, this, &CMapInfoContainer::OnFindDuelLeaderboard ); + } + + // find duck leaderboards + for ( int i = 0; i < DUCK_NUM_LEADERBOARDS; i++ ) + { + CLeaderboardInfo *pInfo = new CLeaderboardInfo( g_szDuckLeaderboardNames[ i ] ); + pInfo->m_kLeaderboardType = i == 0 ? kDuckLeaderboard : kDuckStat; + m_vecDuckInfo.AddToTail( pInfo ); + + // retrieve leaderboard info + pInfo->RetrieveLeaderboardData(); + } + + // Ladder + for ( int i = 0; i < LADDER_LEADERBOARDS_MAX; i++ ) + { + CLeaderboardInfo *pInfo = new CLeaderboardInfo( g_szLadderLeaderboardNames[i] ); + pInfo->m_kLeaderboardType = kLadderLeaderboard; + m_vecLadderLeaderboards.AddToTail( pInfo ); + + // retrieve leaderboard info + pInfo->RetrieveLeaderboardData(); + } + } + +public: + + CUtlVector< CLeaderboardInfo* > m_vecMapInfos; + // for duels + CCallResult< CMapInfoContainer, LeaderboardFindResult_t > m_findLeaderboardCallback; + CCallResult< CMapInfoContainer, LeaderboardScoresDownloaded_t > m_downloadLeaderboardCallback_GlobalAroundUser; + CCallResult< CMapInfoContainer, LeaderboardScoresDownloaded_t > m_downloadLeaderboardCallback_Friends; + LeaderboardFindResult_t m_findDuelLeaderboardResults; + CUtlVector< LeaderboardEntry_t* > m_downloadedDuelLeaderboardScores_GlobalAroundUser; + CUtlVector< LeaderboardEntry_t* > m_downloadedDuelLeaderboardScores_Friends; + + // For ducks + CUtlVector< CLeaderboardInfo* > m_vecDuckInfo; + float m_flNextUpdateDuckScoreTime; + float m_flNextDuckScoresUploadTime; + + // Ladders + CUtlVector< CLeaderboardInfo* > m_vecLadderLeaderboards; + float m_flNextLadderUpdateTime; +}; +CMapInfoContainer gMapInfoContainer; + +static CLeaderboardInfo *FindMapInfo( const char *pMapName ) +{ + FOR_EACH_VEC( gMapInfoContainer.m_vecMapInfos, i ) + { + CLeaderboardInfo *pInfo = gMapInfoContainer.m_vecMapInfos[i]; + if ( strstr( pMapName, pInfo->GetLeaderboardName() ) != NULL ) + return pInfo; + } + return NULL; +} + +//----------------------------------------------------------------------------- + +bool Leaderboards_GetDuelWins( CUtlVector< LeaderboardEntry_t* > &scores, bool bGlobal ) +{ + if ( gMapInfoContainer.m_findDuelLeaderboardResults.m_bLeaderboardFound ) + { + if ( bGlobal ) + { + scores = gMapInfoContainer.m_downloadedDuelLeaderboardScores_GlobalAroundUser; + } + else + { + scores = gMapInfoContainer.m_downloadedDuelLeaderboardScores_Friends; + } + return true; + } + return false; +} +//----------------------------------------------------------------------------- +// DUCKS +void Leaderboards_GetDuckLeaderboardSteamIDs( CUtlVector< AccountID_t > &vecIds ) +{ + vecIds.RemoveAll(); + FOR_EACH_VEC( gMapInfoContainer.m_vecDuckInfo, i ) + { + FOR_EACH_VEC( gMapInfoContainer.m_vecDuckInfo[i]->downloadedLeaderboardScoresFriends, iEntry ) + { + vecIds.AddToHead( gMapInfoContainer.m_vecDuckInfo[i]->downloadedLeaderboardScoresFriends[iEntry]->m_steamIDUser.GetAccountID() ); + } + } +} + +bool Leaderboards_GetDuckLeaderboard( CUtlVector< LeaderboardEntry_t* > &scores, const char* kName ) +{ + CLeaderboardInfo *pLeaderboard = gMapInfoContainer.GetDuckLeaderboard( kName ); + if ( pLeaderboard && pLeaderboard->IsLeaderboardFound() ) + { + scores = pLeaderboard->downloadedLeaderboardScoresFriends; + return true; + } + return false; +} + +int Leaderboards_GetDuckLeaderboardTotalEntryCount( const char* kName ) +{ + CLeaderboardInfo *pLeaderboard = gMapInfoContainer.GetDuckLeaderboard( kName ); + if ( pLeaderboard ) + { + return pLeaderboard->iNumLeaderboardEntries; + } + return 0; +} + +//----------------------------------------------------------------------------- +// DUCK Collected Message from Server +void __MsgFunc_EOTLDuckEvent( bf_read &msg ) +{ +#ifdef CLIENT_DLL + CBasePlayer *pLocalPlayer = CBasePlayer::GetLocalPlayer(); + if ( !pLocalPlayer ) + return; + + if ( TFGameRules() && TFGameRules()->HaveCheatsBeenEnabledDuringLevel() ) + return; + + // IsCreated, ID of Creator, ID of Victim, Count, IsGolden + int iIsCreated = (int)msg.ReadByte(); + int iCreatorId = (int)msg.ReadByte(); + int iVictimId = (int)msg.ReadByte(); + int iToucherId = (int)msg.ReadByte(); + int iDuckTeam = (int)msg.ReadByte(); + int iCount = (int)msg.ReadByte(); + int iDuckFlags = (int)msg.ReadByte(); + + iDuckTeam = 0; + iVictimId = 0; + //iDuckFlags = 0; + + CBasePlayer *pCreator = UTIL_PlayerByIndex( iCreatorId ); + //CBasePlayer *pVictim = UTIL_PlayerByIndex( iVictimId ); + CBasePlayer *pToucher = UTIL_PlayerByIndex( iToucherId ); + + if ( !pCreator ) + { + iDuckFlags |= DUCK_FLAG_OBJECTIVE; + } + // If you were picked up, you need a toucher + if ( iIsCreated == 0 && pToucher ) + { + // if I picked them up + if ( pToucher == pLocalPlayer ) + { + // Offense + if ( pCreator && pCreator->GetTeamNumber() == pLocalPlayer->GetTeamNumber() ) + { + gMapInfoContainer.DuckUpdateScore( iCount, TF_DUCK_SCORING_PERSONAL_PICKUP_OFFENSE ); + gMapInfoContainer.DuckUpdateScore( iCount * DUCK_XP_WEIGHT_OFFENSE, TF_DUCK_SCORING_OVERALL_RATING ); + } + //defense + else if ( pCreator && pCreator->GetTeamNumber() != pLocalPlayer->GetTeamNumber() ) + { + gMapInfoContainer.DuckUpdateScore( iCount, TF_DUCK_SCORING_PERSONAL_PICKUP_DEFENDED ); + gMapInfoContainer.DuckUpdateScore( iCount * DUCK_XP_WEIGHT_DEFENSE, TF_DUCK_SCORING_OVERALL_RATING ); + } + + // objective + if ( iDuckFlags & DUCK_FLAG_OBJECTIVE ) + { + gMapInfoContainer.DuckUpdateScore( iCount, TF_DUCK_SCORING_PERSONAL_PICKUP_OBJECTIVE ); + gMapInfoContainer.DuckUpdateScore( iCount* DUCK_XP_WEIGHT_OBJECTIVE, TF_DUCK_SCORING_OVERALL_RATING ); + } + + // bonus + if ( iDuckFlags & DUCK_FLAG_BONUS ) + { + gMapInfoContainer.DuckUpdateScore( iCount, TF_DUCK_SCORING_PERSONAL_BONUS_PICKUP ); + gMapInfoContainer.DuckUpdateScore( iCount* DUCK_XP_WEIGHT_BONUS, TF_DUCK_SCORING_OVERALL_RATING ); + } + } + // Teammate picks up a duck I made + else if ( pCreator && pCreator == pLocalPlayer && pCreator->GetTeamNumber() == pToucher->GetTeamNumber() ) + { + gMapInfoContainer.DuckUpdateScore( iCount, TF_DUCK_SCORING_TEAM_PICKUP_MY_DUCKS ); + gMapInfoContainer.DuckUpdateScore( iCount * DUCK_XP_WEIGHT_TEAMMATE, TF_DUCK_SCORING_OVERALL_RATING ); + } + } + // Duck Created + else if ( iIsCreated != 0 ) + { + // If this is the same as local player + if ( pLocalPlayer == pCreator ) + { + gMapInfoContainer.DuckUpdateScore( iCount, TF_DUCK_SCORING_PERSONAL_GENERATION ); + gMapInfoContainer.DuckUpdateScore( iCount * DUCK_XP_WEIGHT_GENERATION, TF_DUCK_SCORING_OVERALL_RATING ); + } + } + +#endif +} +//----------------------------------------------------------------------------- + +void Leaderboards_Refresh() +{ + gMapInfoContainer.DownloadDuelLeaderboard(); + gMapInfoContainer.DownloadDuckLeaderboard(); + gMapInfoContainer.DownloadLadderLeaderboard(); +} + +void MapInfo_RefreshLeaderboard( const char *pMapName ) +{ + CLeaderboardInfo *pInfo = FindMapInfo( pMapName ); + if ( pInfo ) + { + pInfo->DownloadLeaderboardData(); + } +} + +bool MapInfo_GetLeaderboardInfo( const char *pMapName, CUtlVector< LeaderboardEntry_t* > &scores, int &iNumLeaderboardEntries, uint32 unMinScores ) +{ + CLeaderboardInfo *pInfo = FindMapInfo( pMapName ); + if ( pInfo && pInfo->findLeaderboardResults.m_bLeaderboardFound ) + { + if ( (uint32)pInfo->downloadedLeaderboardScoresFriends.Count() >= unMinScores ) + { + scores = pInfo->downloadedLeaderboardScoresFriends; + } + else if ( (uint32)pInfo->downloadedLeaderboardScoresGlobalAroundUser.Count() >= unMinScores ) + { + scores = pInfo->downloadedLeaderboardScoresGlobalAroundUser; + } + else + { + scores = pInfo->downloadedLeaderboardScoresGlobal; + } + iNumLeaderboardEntries = pInfo->iNumLeaderboardEntries; + return true; + } + return false; +} + +static const char *FindMapNameForContributionDefinitionIndex( item_definition_index_t unContribDefIndex ) +{ + for ( int i = 0; i < GetItemSchema()->GetMapCount(); i++ ) + { + const MapDef_t* pMapDef = GetItemSchema()->GetMasterMapDefByIndex( i ); + if ( pMapDef->mapStampDef && pMapDef->mapStampDef->GetDefinitionIndex() == unContribDefIndex ) + return pMapDef->pszMapName; + } + return NULL; +} + +bool MapInfo_DidPlayerDonate( uint32 unAccountID, const char *pLevelName ) +{ + if ( steamapicontext == NULL || steamapicontext->SteamUser() == NULL ) + return false; + + CSteamID localSteamID = steamapicontext->SteamUser()->GetSteamID(); + CSteamID steamID = localSteamID; + steamID.SetAccountID( unAccountID ); + + GCSDK::CGCClientSharedObjectCache *pSOCache = GCClientSystem()->GetSOCache( steamID ); + if ( pSOCache == NULL ) + return false; + + GCSDK::CGCClientSharedObjectTypeCache *pTypeCache = pSOCache->FindTypeCache( CTFMapContribution::k_nTypeID ); + if ( pTypeCache == NULL ) + return false; + + char pchBaseMapName[ MAX_PATH ]; + Q_FileBase( pLevelName, pchBaseMapName, sizeof(pchBaseMapName) ); + + for ( uint32 i = 0; i < pTypeCache->GetCount(); ++i ) + { + CTFMapContribution *pMapContribution = (CTFMapContribution*)( pTypeCache->GetObject( i ) ); + + const char *pszMapName = FindMapNameForContributionDefinitionIndex( pMapContribution->Obj().def_index() ); + if ( pszMapName && FStrEq( pszMapName, pchBaseMapName ) ) + return true; + } + return false; +} + +int MapInfo_GetDonationAmount( uint32 unAccountID, const char *pLevelName ) +{ + if ( steamapicontext == NULL || steamapicontext->SteamUser() == NULL ) + return 0; + + CSteamID localSteamID = steamapicontext->SteamUser()->GetSteamID(); + CSteamID steamID = localSteamID; + steamID.SetAccountID( unAccountID ); + + GCSDK::CGCClientSharedObjectCache *pSOCache = GCClientSystem()->GetSOCache( steamID ); + if ( pSOCache == NULL ) + return 0; + + GCSDK::CGCClientSharedObjectTypeCache *pTypeCache = pSOCache->FindTypeCache( CTFMapContribution::k_nTypeID ); + if ( pTypeCache == NULL ) + return 0; + + char pchBaseMapName[ MAX_PATH ]; + Q_FileBase( pLevelName, pchBaseMapName, sizeof(pchBaseMapName) ); + + for ( uint32 i = 0; i < pTypeCache->GetCount(); ++i ) + { + CTFMapContribution *pMapContribution = (CTFMapContribution*)( pTypeCache->GetObject( i ) ); + + const char *pszMapName = FindMapNameForContributionDefinitionIndex( pMapContribution->Obj().def_index() ); + if ( pszMapName && FStrEq( pszMapName, pchBaseMapName ) ) + return pMapContribution->Obj().contribution_level(); + } + return 0; +} + +//----------------------------------------------------------------------------- +// Ladders +//----------------------------------------------------------------------------- +bool Leaderboards_GetLadderLeaderboard( CUtlVector< LeaderboardEntry_t* > &scores, const char *pszName, bool bGlobal ) +{ + CLeaderboardInfo *pLeaderboard = gMapInfoContainer.GetLadderLeaderboard( pszName ); + if ( pLeaderboard && pLeaderboard->IsLeaderboardFound() ) + { + scores = bGlobal ? pLeaderboard->downloadedLeaderboardScoresGlobal : pLeaderboard->downloadedLeaderboardScoresFriends; + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void Leaderboards_LadderRefresh( void ) +{ + gMapInfoContainer.DownloadLadderLeaderboard(); +} |