summaryrefslogtreecommitdiff
path: root/game/client/tf/tf_tips.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/tf_tips.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/tf/tf_tips.cpp')
-rw-r--r--game/client/tf/tf_tips.cpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/game/client/tf/tf_tips.cpp b/game/client/tf/tf_tips.cpp
new file mode 100644
index 0000000..479c5d6
--- /dev/null
+++ b/game/client/tf/tf_tips.cpp
@@ -0,0 +1,320 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Rich Presence support
+//
+//=====================================================================================//
+
+#include "cbase.h"
+#include "tf_tips.h"
+#include "tier3/tier3.h"
+#include <vgui/ILocalize.h>
+#include "cdll_util.h"
+#include "fmtstr.h"
+#include "tf_gamerules.h"
+#include "tf_hud_statpanel.h"
+#include "filesystem.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: constructor
+//-----------------------------------------------------------------------------
+CTFTips::CTFTips() : CAutoGameSystem( "CTFTips" )
+{
+ Q_memset( m_iTipCount, 0, sizeof( m_iTipCount ) );
+ m_iTipCountAll = 0;
+ m_iCurrentClassTip = 0;
+ m_bInited = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Initializer
+//-----------------------------------------------------------------------------
+bool CTFTips::Init()
+{
+ if ( !m_bInited )
+ {
+ // count how many tips there are for each class and in total
+ m_iTipCountAll = 0;
+ for ( int iClass = TF_FIRST_NORMAL_CLASS; iClass <= TF_LAST_NORMAL_CLASS; iClass++ )
+ {
+ // tip count per class is stored in resource file
+ wchar_t *wzTipCount = g_pVGuiLocalize->Find( CFmtStr( "Tip_%d_Count", iClass ) );
+ int iClassTipCount = wzTipCount ? _wtoi( wzTipCount ) : 0;
+ m_iTipCount[iClass] = iClassTipCount;
+ m_iTipCountAll += iClassTipCount;
+
+ m_iArenaTipCount = g_pVGuiLocalize->Find( "Tip_arena_Count" ) ? _wtoi( g_pVGuiLocalize->Find( "Tip_arena_Count" ) ) : 0;
+ }
+
+ // Captain Canteen mascot parts!
+ m_CaptainCanteenBody.RemoveAll();
+ m_CaptainCanteenMisc.RemoveAll();
+ m_CaptainCanteenHat.RemoveAll();
+
+ KeyValues *kv = new KeyValues( "cpncntn" );
+ KeyValues::AutoDelete autodelete_key( kv );
+
+ if ( kv->LoadFromFile( g_pFullFileSystem, "scripts/cpncntn.txt", "MOD" ) )
+ {
+ for ( KeyValues *pSubKey = kv->GetFirstTrueSubKey(); pSubKey; pSubKey = pSubKey->GetNextTrueSubKey() )
+ {
+ // Figure out which bucket it goes in
+ CUtlVector< CaptainCanteenAsset_t > *pAssetBucket = NULL;
+
+ if ( V_stricmp( pSubKey->GetName(), "body" ) == 0 )
+ {
+ pAssetBucket = &m_CaptainCanteenBody;
+ }
+ else if ( V_stricmp( pSubKey->GetName(), "misc" ) == 0 )
+ {
+ pAssetBucket = &m_CaptainCanteenMisc;
+ }
+ else if ( V_stricmp( pSubKey->GetName(), "hat" ) == 0 )
+ {
+ pAssetBucket = &m_CaptainCanteenHat;
+ }
+
+ if ( pAssetBucket )
+ {
+ // Added more assets to that bucket
+ for ( KeyValues *pAssetKey = pSubKey->GetFirstSubKey(); pAssetKey; pAssetKey = pAssetKey->GetNextKey() )
+ {
+ int nNewAsset = pAssetBucket->AddToTail();
+ V_strncpy( (*pAssetBucket)[ nNewAsset ].szImage, pAssetKey->GetName(), sizeof( (*pAssetBucket)[ nNewAsset ].szImage ) );
+ (*pAssetBucket)[ nNewAsset ].flRarity = ( 1.0f / pAssetKey->GetFloat() );
+ }
+ }
+ }
+ }
+
+ m_bInited = true;
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns a random tip, selected from tips for all classes,
+// fills in iClassUsed with the class the tip is for
+//-----------------------------------------------------------------------------
+const wchar_t *CTFTips::GetRandomTip( int &iClassUsed )
+{
+ Init();
+
+ // Chance of reminding players about the Abuse Reporter.
+ // The chance is very high for the first 20 hours of play since newbies get picked on a lot.
+ int abuseHintChance = 3;
+
+ if ( CTFStatPanel::GetTotalHoursPlayed() < 20.0f )
+ {
+ abuseHintChance = 33;
+ }
+
+ if ( RandomInt( 1, 100 ) <= abuseHintChance )
+ {
+ iClassUsed = RandomInt( TF_FIRST_NORMAL_CLASS, TF_LAST_NORMAL_CLASS );
+ return GetAbuseReportTip();
+ }
+
+ // pick a random tip
+ int iTip = RandomInt( 0, m_iTipCountAll-1 );
+ // walk through each class until we find the class this tip lands in
+ for ( int iClass = TF_FIRST_NORMAL_CLASS; iClass <= TF_LAST_NORMAL_CLASS; iClass++ )
+ {
+ Assert( iTip >= 0 );
+ int iClassTipCount = m_iTipCount[iClass];
+ if ( iTip < iClassTipCount )
+ {
+ iClassUsed = iClass;
+
+ // return the tip
+ return GetTip( iClass, iTip+1 );
+ }
+ iTip -= iClassTipCount;
+ }
+ Assert( false ); // shouldn't hit this
+
+ iClassUsed = TF_CLASS_UNDEFINED;
+ return L"";
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns the next tip for specified class
+//-----------------------------------------------------------------------------
+const wchar_t *CTFTips::GetNextClassTip( int iClass )
+{
+ int iTipClass = TF_CLASS_UNDEFINED;
+
+ // OK to call this function with TF_CLASS_UNDEFINED or TF_CLASS_RANDOM, just return a random tip for any class in that case
+ if ( iClass < TF_FIRST_NORMAL_CLASS || iClass > TF_LAST_NORMAL_CLASS )
+ return GetRandomTip( iTipClass );
+
+ if ( TFGameRules() && TFGameRules()->IsInArenaMode() == true )
+ {
+ return GetArenaTip();
+ }
+
+ int iClassTipCount = m_iTipCount[iClass];
+ Assert( 0 != iClassTipCount );
+ if ( 0 == iClassTipCount )
+ return L"";
+ // wrap the tip index to the valid range for this class
+ if ( m_iCurrentClassTip >= iClassTipCount )
+ {
+ m_iCurrentClassTip %= iClassTipCount;
+ }
+
+ // return the tip
+ const wchar_t *wzTip = GetTip( iClass, m_iCurrentClassTip+1 );
+ m_iCurrentClassTip++;
+
+ return wzTip;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns specified tip index for arena
+//-----------------------------------------------------------------------------
+const wchar_t *CTFTips::GetArenaTip( void )
+{
+ int iClassTipCount = m_iArenaTipCount;
+ Assert( 0 != iClassTipCount );
+
+ if ( 0 == iClassTipCount )
+ return L"";
+
+ // wrap the tip index to the valid range for this class
+ if ( m_iCurrentClassTip >= iClassTipCount )
+ {
+ m_iCurrentClassTip %= iClassTipCount;
+ }
+
+ // return the tip
+ const wchar_t *wzFmt = g_pVGuiLocalize->Find( CFmtStr( "#Tip_arena_%d", m_iCurrentClassTip+1 ) );
+ static wchar_t wzTip[512] = L"";
+
+ // replace any commands with their bound keys
+ UTIL_ReplaceKeyBindings( wzFmt, 0, wzTip, sizeof( wzTip ) );
+
+ m_iCurrentClassTip++;
+
+ return wzTip;
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns specified tip index for specified class
+//-----------------------------------------------------------------------------
+const wchar_t *CTFTips::GetTip( int iClass, int iTip )
+{
+ static wchar_t wzTip[512] = L"";
+
+ // get the tip
+ const wchar_t *wzFmt = g_pVGuiLocalize->Find( CFmtStr( "#Tip_%d_%d", iClass, iTip ) );
+ // replace any commands with their bound keys
+ UTIL_ReplaceKeyBindings( wzFmt, 0, wzTip, sizeof( wzTip ) );
+
+ return wzTip;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns tip about using the Abuse Reporter
+//-----------------------------------------------------------------------------
+const wchar_t *CTFTips::GetAbuseReportTip( void )
+{
+ static wchar_t wzAbuseTip[512] = L"";
+
+ // replace any commands with their bound keys
+ const wchar_t *wzFmt = g_pVGuiLocalize->Find( "Tip_Abuse_Report" );
+ UTIL_ReplaceKeyBindings( wzFmt, 0, wzAbuseTip, sizeof( wzAbuseTip ) );
+
+ return wzAbuseTip;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns tip related to MvM
+//-----------------------------------------------------------------------------
+const wchar_t *CTFTips::GetRandomMvMTip( int &iClassUsed )
+{
+ Init();
+
+ static wchar_t wzMvMTip[512] = L"";
+ static int iPrevMvMClass = -1;
+
+ iClassUsed = RandomInt( TF_FIRST_NORMAL_CLASS, TF_LAST_NORMAL_CLASS );
+
+ if ( iClassUsed == iPrevMvMClass )
+ {
+ iClassUsed = ( iClassUsed + 1 ) % TF_LAST_NORMAL_CLASS;
+ }
+ iPrevMvMClass = iClassUsed;
+
+ // Get Tip Count
+ CFmtStr fmtTipCount("Tip_MvM_%d_Count", iClassUsed );
+ int iMvMTipCount = g_pVGuiLocalize->Find( fmtTipCount ) ? _wtoi( g_pVGuiLocalize->Find( fmtTipCount ) ) : 1;
+
+ int iTip = RandomInt( 1, iMvMTipCount );
+
+ // replace any commands with their bound keys
+ const wchar_t *wzFmt = g_pVGuiLocalize->Find( CFmtStr( "#Tip_MvM_%d_%d", iClassUsed, iTip ) );
+ UTIL_ReplaceKeyBindings( wzFmt, 0, wzMvMTip, sizeof( wzMvMTip ) );
+
+ iPrevMvMClass = iClassUsed;
+ return wzMvMTip;
+}
+
+void CTFTips::GetRandomCaptainCanteenImages( const char **ppchBody, const char **ppchMisc, const char **ppchHat )
+{
+ // Select and copy over all 3 parts
+ *ppchBody = GetRandomCaptainCanteenAsset( &m_CaptainCanteenBody );
+ *ppchMisc = GetRandomCaptainCanteenAsset( &m_CaptainCanteenMisc );
+ *ppchHat = GetRandomCaptainCanteenAsset( &m_CaptainCanteenHat );
+}
+
+const char *CTFTips::GetRandomCaptainCanteenAsset( CUtlVector< CaptainCanteenAsset_t > *pAssetBucket )
+{
+ // If there's nothing in the bucket, bail out
+ if ( pAssetBucket->Count() <= 0 )
+ {
+ return "";
+ }
+
+ if ( pAssetBucket->Count() == 1 )
+ {
+ // Easy out if there's only 1 choice
+ return (*pAssetBucket)[ 0 ].szImage;
+ }
+
+ // Get the total scale of selection possibilities
+ float flSelectionTotal = 0.0f;
+
+ for ( int i = 0; i < pAssetBucket->Count(); ++i )
+ {
+ flSelectionTotal += (*pAssetBucket)[ i ].flRarity;
+ }
+
+ if ( flSelectionTotal > 0.0f )
+ {
+ // Pick a number from 0 to 1
+ float flRand = RandomFloat();
+
+ // Loop through to figure out which asset we've chosen
+ float flCurrentPosition = 0.0f;
+
+ for ( int i = 0; i < pAssetBucket->Count(); ++i )
+ {
+ flCurrentPosition += (*pAssetBucket)[ i ].flRarity / flSelectionTotal;
+
+ if ( flRand <= flCurrentPosition )
+ {
+ // We landed on this random asset
+ return (*pAssetBucket)[ i ].szImage;
+ }
+ }
+ }
+
+ // Something went wrong... just return the first choice
+ return (*pAssetBucket)[ 0 ].szImage;
+}
+
+
+// global instance
+CTFTips g_TFTips; \ No newline at end of file