From 39ed87570bdb2f86969d4be821c94b722dc71179 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Wed, 26 Jun 2013 15:22:04 -0700 Subject: First version of the SOurce SDK 2013 --- mp/src/game/shared/hintsystem.cpp | 323 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 323 insertions(+) create mode 100644 mp/src/game/shared/hintsystem.cpp (limited to 'mp/src/game/shared/hintsystem.cpp') diff --git a/mp/src/game/shared/hintsystem.cpp b/mp/src/game/shared/hintsystem.cpp new file mode 100644 index 00000000..34f4d7bd --- /dev/null +++ b/mp/src/game/shared/hintsystem.cpp @@ -0,0 +1,323 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" +#include "hintsystem.h" +#include "hintmessage.h" + +#ifdef GAME_DLL +#else + #include +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef CLIENT_DLL +ConVar cl_showhelp( "cl_showhelp", "1", FCVAR_USERINFO | FCVAR_ARCHIVE, "Set to 0 to not show on-screen help" ); +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CHintSystem::CHintSystem( void ) +{ + Init( NULL, 0, NULL ); + m_pHintMessageQueue = NULL; + m_pHintMessageTimers = NULL; + m_flLastHintPlayedAt = 0; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CHintSystem::~CHintSystem( void ) +{ + if ( m_pHintMessageTimers ) + { + delete m_pHintMessageTimers; + m_pHintMessageTimers = NULL; + } + + if ( m_pHintMessageQueue ) + { + delete m_pHintMessageQueue; + m_pHintMessageQueue = NULL; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHintSystem::Init( CBasePlayer *pPlayer, int iMaxHintTypes, const char **pszHintStrings ) +{ + m_pPlayer = pPlayer; + m_bShowHints = true; + + m_HintHistory.Resize( iMaxHintTypes ); + m_HintHistory.ClearAll(); + + m_pszHintMessages = pszHintStrings; + + if ( m_pPlayer ) + { + m_pHintMessageQueue = new CHintMessageQueue( m_pPlayer ); + m_pHintMessageTimers = new CHintMessageTimers( this, m_pHintMessageQueue ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHintSystem::Update( void ) +{ + if ( m_pHintMessageQueue ) + { + m_pHintMessageQueue->Update(); + } + if ( m_pHintMessageTimers ) + { + m_pHintMessageTimers->Update(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Displays a hint message to the player +// Input : hint - enum'd hint to show +// bForce - always play this hint even if they have seen it before +//----------------------------------------------------------------------------- +bool CHintSystem::HintMessage( int hint, bool bForce /* = false */, bool bOnlyIfClear /* = false */ ) +{ + Assert( m_pPlayer ); + Assert( hint < m_HintHistory.GetNumBits() ); + + // Not really an optimal solution, but saves us querying the hud element, + // which wouldn't be easy with derived versions in different mods. + if ( bOnlyIfClear && (gpGlobals->curtime - m_flLastHintPlayedAt < 11 ) ) + return false; + + if ( bForce || !HasPlayedHint(hint) ) + { + PlayedAHint(); + HintMessage( m_pszHintMessages[hint] ); + m_HintHistory.Set(hint); + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: Displays a hint message to the player +// Input : *pMessage - +//----------------------------------------------------------------------------- +void CHintSystem::HintMessage( const char *pMessage ) +{ + Assert( m_pPlayer ); + +#ifdef GAME_DLL + // On the server, we send it down to the queue who sends it to the client + if ( !m_pPlayer->IsNetClient() || !m_pHintMessageQueue ) + return; + + if ( !m_bShowHints ) + return; + + m_pHintMessageQueue->AddMessage( pMessage ); +#else + // On the client, we just send it straight to the hint hud element + if ( cl_showhelp.GetBool() ) + { + IGameEvent *event = gameeventmanager->CreateEvent( "player_hintmessage" ); + if ( event ) + { + event->SetString( "hintmessage", pMessage ); + gameeventmanager->FireEventClientSide( event ); + } + } +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Clear out the existing timers, and register new ones for any +// hints that haven't been displayed yet. +//----------------------------------------------------------------------------- +void CHintSystem::ResetHints( void ) +{ + if ( !m_pHintMessageTimers ) + return; + + m_pHintMessageTimers->Reset(); + + // Readd registered hints + for (int i = 0; i < m_RegisteredResetHints.Count(); i++ ) + { + ReAddHintTimerIfNotDisplayed( m_RegisteredResetHints[i].iHintID, m_RegisteredResetHints[i].flTimer ); + } + + // Reset our queue + if ( m_pHintMessageQueue ) + { + m_pHintMessageQueue->Reset(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Call this to add a hint message that should be re-added +// everytime we're reset, if it hasn't been displayed yet. +//----------------------------------------------------------------------------- +void CHintSystem::RegisterHintTimer( int iHintID, float flTimerDuration, bool bOnlyIfClear /* = false */, HintTimerCallback pfnCallback ) +{ + Assert( m_pPlayer ); + Assert( iHintID < m_HintHistory.GetNumBits() ); + + onresethints_t newHint; + newHint.iHintID = iHintID; + newHint.flTimer = flTimerDuration; + newHint.bOnlyIfClear = bOnlyIfClear; + newHint.pfnCallback = pfnCallback; + m_RegisteredResetHints.AddToTail( newHint ); +} + +//----------------------------------------------------------------------------- +// Purpose: If the hint hasn't been displayed, start a timer for it +//----------------------------------------------------------------------------- +void CHintSystem::ReAddHintTimerIfNotDisplayed( int iHintID, float flTimerDuration ) +{ + Assert( iHintID < m_HintHistory.GetNumBits() ); + if ( m_HintHistory[iHintID] == 0 ) + { + m_pHintMessageTimers->AddTimer( iHintID, flTimerDuration ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHintSystem::StartHintTimer( int iHintID ) +{ + Assert( m_pPlayer ); + Assert( iHintID < m_HintHistory.GetNumBits() ); + Assert(m_pHintMessageTimers); + m_pHintMessageTimers->StartTimer( iHintID ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHintSystem::StopHintTimer( int iHintID ) +{ + Assert( m_pPlayer ); + Assert( iHintID < m_HintHistory.GetNumBits() ); + Assert(m_pHintMessageTimers); + m_pHintMessageTimers->StopTimer( iHintID ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHintSystem::ResetHintTimers( void ) +{ + Assert( m_pPlayer ); + Assert(m_pHintMessageTimers); + m_pHintMessageTimers->Reset(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHintSystem::RemoveHintTimer( int iHintID ) +{ + Assert( m_pPlayer ); + Assert( iHintID < m_HintHistory.GetNumBits() ); + Assert(m_pHintMessageTimers); + m_pHintMessageTimers->RemoveTimer( iHintID ); + + // Mark us as having heard this hint + m_HintHistory.Set(iHintID); +} + +//----------------------------------------------------------------------------- +// Purpose: See if there's a callback registered for the specified hint. +// If so, see if it wants to allow the hint to fire. +//----------------------------------------------------------------------------- +bool CHintSystem::TimerShouldFire( int iHintID ) +{ + for (int i = 0; i < m_RegisteredResetHints.Count(); i++ ) + { + if ( m_RegisteredResetHints[i].iHintID != iHintID ) + continue; + + if ( m_RegisteredResetHints[i].bOnlyIfClear && HintIsCurrentlyVisible() ) + return false; + + if ( m_RegisteredResetHints[i].pfnCallback ) + return m_RegisteredResetHints[i].pfnCallback( m_pPlayer ); + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CHintSystem::ShouldShowHints( void ) +{ +#ifdef GAME_DLL + return m_bShowHints; +#else + return cl_showhelp.GetBool(); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHintSystem::PlayedAHint( void ) +{ + m_flLastHintPlayedAt = gpGlobals->curtime; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CHintSystem::HasPlayedHint( int iHintID ) +{ + Assert( m_pPlayer ); + Assert( iHintID < m_HintHistory.GetNumBits() ); + return ( m_HintHistory[iHintID] > 0 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHintSystem::SetHintPlayed( int iHintID ) +{ + Assert( m_pPlayer ); + Assert( iHintID < m_HintHistory.GetNumBits() ); + m_HintHistory.Set(iHintID); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void HintClear( void ) +{ +#ifdef CLIENT_DLL + C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); +#else + CBasePlayer* pPlayer = UTIL_GetCommandClient(); +#endif + if ( pPlayer && pPlayer->Hints() ) + { + pPlayer->Hints()->ClearHintHistory(); + } +} +#ifdef CLIENT_DLL +ConCommand cl_clearhinthistory( "cl_clearhinthistory", HintClear, "Clear memory of client side hints displayed to the player." ); +#else +ConCommand sv_clearhinthistory( "sv_clearhinthistory", HintClear, "Clear memory of server side hints displayed to the player." ); +#endif \ No newline at end of file -- cgit v1.2.3