diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf2/c_tf_hintmanager.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/tf2/c_tf_hintmanager.cpp')
| -rw-r--r-- | game/client/tf2/c_tf_hintmanager.cpp | 427 |
1 files changed, 427 insertions, 0 deletions
diff --git a/game/client/tf2/c_tf_hintmanager.cpp b/game/client/tf2/c_tf_hintmanager.cpp new file mode 100644 index 0000000..6aeec17 --- /dev/null +++ b/game/client/tf2/c_tf_hintmanager.cpp @@ -0,0 +1,427 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "c_tf_hintmanager.h" +#include "c_tf_basehint.h" +#include <KeyValues.h> +#include "filesystem.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +// Global off switch for hint system +static ConVar tf2_hintsystem( "tf2_hintsystem", "0", 0, "Enable interface hints in TF2." ); +static C_TFHintManager *g_pHintManager = NULL; + +#define HINT_DISPLAY_STATS_FILE "scripts/hintdisplaystats.txt" + +static float g_flLastEscapeKeyTime = -1.0f; +//----------------------------------------------------------------------------- +// Purpose: Helper to create panel in center and then shift toward right edge of screen +// Input : *panel - +// Output : static void +//----------------------------------------------------------------------------- +static void PositionPanel( C_TFBaseHint *panel ) +{ + int w, h; + panel->GetSize( w, h ); + + int x = ( ScreenWidth() - w ) / 2; + int y = ( ScreenHeight() - h ) / 2; + + panel->SetPos( x, y ); + + panel->SetDesiredPosition( ScreenWidth() - w - 10, y - 75 ); +} + +IMPLEMENT_CLIENTCLASS_DT_NOBASE(C_TFHintManager, DT_TFHintManager, CTFHintManager) +END_RECV_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +C_TFHintManager::C_TFHintManager( void ) +{ + g_pHintManager = this; + + m_pkvHintSystem = new KeyValues( "HintSystem" ); + if ( m_pkvHintSystem ) + { + bool valid = m_pkvHintSystem->LoadFromFile( filesystem, "scripts//hintsystem.txt" ); + if ( !valid ) + { + m_pkvHintSystem->deleteThis(); + m_pkvHintSystem = NULL; + } + } + + m_pkvHintDisplayStats = new KeyValues( "HintDisplayStats" ); + if ( m_pkvHintDisplayStats ) + { + m_pkvHintDisplayStats->LoadFromFile( filesystem, HINT_DISPLAY_STATS_FILE ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : KeyValues +//----------------------------------------------------------------------------- +KeyValues *C_TFHintManager::GetHintKeyValues( void ) +{ + return m_pkvHintSystem; +} + +KeyValues *C_TFHintManager::GetHintDisplayStats( void ) +{ + return m_pkvHintDisplayStats; +} + +void C_TFHintManager::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + // Think right away + if ( updateType == DATA_UPDATE_CREATED ) + SetNextClientThink( 0.0f ); +} + +//----------------------------------------------------------------------------- +// Purpose: Remove complete hints, and activate next highest priority hint +//----------------------------------------------------------------------------- +void C_TFHintManager::ClientThink( void ) +{ + SetNextClientThink( gpGlobals->curtime + 1.0 ); + + int i; + int highestPriority = -1; + C_TFBaseHint *best = NULL; + bool anyVisible = false; + + // See if any of the hints are completed, otherwise, store off the highest priority one + for ( i = m_aHints.Size() - 1; i >= 0; i-- ) + { + C_TFBaseHint *hint = m_aHints[ i ]; + + // See if it should just be deleted + if ( hint && hint->GetCompleted() ) + { + m_aHints.Remove( i ); + delete hint; + continue; + } + + if ( hint->IsVisible() ) + { + anyVisible = true; + } + + if ( !best || ( hint->GetPriority() > highestPriority ) ) + { + highestPriority = hint->GetPriority(); + best = hint; + } + } + + // Last hint finished, show next best one + if ( !anyVisible ) + { + // Now hide all but best one + for ( i = 0; i < m_aHints.Size(); i++ ) + { + C_TFBaseHint *hint = m_aHints[ i ]; + hint->SetVisible( hint == best ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : playerIndex - +// hintID - +// priority - +// entityIndex - +//----------------------------------------------------------------------------- +C_TFBaseHint *C_TFHintManager::AddHint( int hintID, const char *subsection, int entityIndex, int maxduplicates ) +{ + if ( !tf2_hintsystem.GetBool() ) + return NULL; + + // Don't add the same hint more than once unless maxduplicates >= 1 has been specifically requested + int count = CountInstancesOfHintID( hintID ); + if ( count > maxduplicates ) + { + return NULL; + } + + C_TFBaseHint *hint = C_TFBaseHint::CreateHint( hintID, subsection, entityIndex ); + if ( hint ) + { + // Force it to compute it's exact size + hint->PerformLayout(); + + PositionPanel( hint ); + + m_aHints.AddToTail( hint ); + } + + return hint; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_TFHintManager::ClearHints( void ) +{ + for ( int i = 0; i < m_aHints.Size(); i++ ) + { + C_TFBaseHint *hint = m_aHints[ i ]; + delete hint; + } + + m_aHints.RemoveAll(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : playerIndex - +// hintID - +//----------------------------------------------------------------------------- +void C_TFHintManager::CompleteHint( int hintID, bool visibleOnly ) +{ + for ( int i = m_aHints.Size() - 1; i >= 0; i-- ) + { + C_TFBaseHint *hint = m_aHints[ i ]; + if ( !hint ) + continue; + + if ( hint->GetID() != hintID ) + continue; + + if ( visibleOnly && !hint->IsVisible() ) + continue; + + delete hint; + m_aHints.Remove( i ); + return; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : playerIndex - +// hintID - +// Output : Number of instances in list +//----------------------------------------------------------------------------- +int C_TFHintManager::CountInstancesOfHintID( int hintID ) +{ + int c = 0; + for ( int i = m_aHints.Size() - 1; i >= 0; i-- ) + { + C_TFBaseHint *hint = m_aHints[ i ]; + if ( hint && hint->GetID() == hintID ) + { + c++; + } + } + + return c; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : playerIndex - +// Output : int +//----------------------------------------------------------------------------- +int C_TFHintManager::GetCurrentHintID( void ) +{ + for ( int i = m_aHints.Size() - 1; i >= 0; i-- ) + { + C_TFBaseHint *hint = m_aHints[ i ]; + if ( hint && hint->IsVisible() ) + { + return hint->GetID(); + } + } + + return TF_HINT_UNDEFINED; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_TFHintManager::ResetDisplayStats( void ) +{ + if ( !m_pkvHintDisplayStats ) + { + Assert( 0 ); + return; + } + + KeyValues *kv = m_pkvHintDisplayStats->GetFirstSubKey(); + while ( kv ) + { + KeyValues *subKey = kv->GetFirstSubKey(); + if ( subKey && stricmp( subKey->GetName(), "times_shown") ) + { + while ( subKey ) + { + subKey->SetString( "times_shown", "0" ); + subKey = subKey->GetNextKey(); + } + } + else + { + kv->SetString( "times_shown", "0" ); + } + + kv = kv->GetNextKey(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : hintid - +// 100 - +// 1 - +// -1 - +//----------------------------------------------------------------------------- +C_TFBaseHint *CreateGlobalHint( int hintid, const char *subsection /*=NULL*/, int entity /*= -1*/, int maxduplicates /*=0*/ ) +{ + if ( !g_pHintManager ) + { + return NULL; + } + + return g_pHintManager->AddHint( hintid, subsection, entity, maxduplicates ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : hintid - +// 100 - +// 1 - +// -1 - +//----------------------------------------------------------------------------- +C_TFBaseHint *CreateGlobalHint_Panel( vgui::Panel *targetPanel, int hintid, const char *subsection /*=NULL*/, int entity /*= -1*/, int maxduplicates /*=0*/ ) +{ + C_TFBaseHint *hint = CreateGlobalHint( hintid, subsection, entity, maxduplicates ); + if ( hint ) + { + // Find an appropriate position near the panel + hint->SetHintTarget( targetPanel ); + } + return hint; +} + + +//----------------------------------------------------------------------------- +// Purpose: Trap the escape key when a hint is showing +// Output : Returns true if the escape key was swallowed by the hint system +//----------------------------------------------------------------------------- + +// Hitting escape twice withing this amount of seconds will clear all hints pending +#define ENTER_DOUBLETAP_TIME 1.0f + +bool HintSystemEscapeKey( void ) +{ + if ( !g_pHintManager ) + return false; + + int hintID = g_pHintManager->GetCurrentHintID(); + if ( hintID != TF_HINT_UNDEFINED ) + { + bool killall = false; + + float curtime = gpGlobals->curtime; + float dt = curtime - g_flLastEscapeKeyTime; + + if ( dt < ENTER_DOUBLETAP_TIME ) + { + killall = true; + } + + g_flLastEscapeKeyTime = curtime; + + if ( killall ) + { + g_pHintManager->ClearHints(); + } + else + { + g_pHintManager->CompleteHint( hintID, true ); + } + // Swallow the escape key + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : hindid - +//----------------------------------------------------------------------------- +void DestroyGlobalHint( int hintid ) +{ + if ( !g_pHintManager ) + return; + + g_pHintManager->CompleteHint( hintid, false ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : KeyValues +//----------------------------------------------------------------------------- +KeyValues *GetHintKeyValues( void ) +{ + if ( !g_pHintManager ) + return NULL; + + return g_pHintManager->GetHintKeyValues(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : KeyValues +//----------------------------------------------------------------------------- +KeyValues *GetHintDisplayStats( void ) +{ + if ( !g_pHintManager ) + return NULL; + + return g_pHintManager->GetHintDisplayStats(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void ResetDisplayStats( void ) +{ + if ( g_pHintManager ) + { + g_pHintManager->ResetDisplayStats(); + } +} + +static ConCommand tf2_hintreset( "tf2_hintreset", ResetDisplayStats, 0, FCVAR_CHEAT ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +C_TFHintManager::~C_TFHintManager( void ) +{ + ClearHints(); + g_pHintManager = NULL; + m_pkvHintSystem->deleteThis(); + if ( m_pkvHintDisplayStats ) + { + m_pkvHintDisplayStats->SaveToFile( filesystem, HINT_DISPLAY_STATS_FILE ); + } + m_pkvHintDisplayStats->deleteThis(); +}
\ No newline at end of file |