//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= // // Purpose: // //============================================================================= #include "cbase.h" #include "hintmessage.h" #include "hintsystem.h" #include "usermessages.h" #ifdef GAME_DLL #include "util.h" #endif // NOTE: This has to be the last file included! #include "tier0/memdbgon.h" //-------------------------------------------------------------------------------------------------------- /** * Simple utility function to allocate memory and duplicate a string */ inline char *CloneString( const char *str ) { char *cloneStr = new char [ strlen(str)+1 ]; strcpy( cloneStr, str ); return cloneStr; } extern int gmsgHudText; enum { HMQ_SIZE = 8 }; // Maximum number of messages queue can hold // If the limit is reached, no more can be // added. //-------------------------------------------------------------------------------------------------------------- CHintMessage::CHintMessage( const char * hintString, CUtlVector< const char * > * args, float duration ) { m_hintString = hintString; m_duration = duration; if ( args ) { for ( int i=0; iCount(); ++i ) { m_args.AddToTail( CloneString( (*args)[i] ) ); } } } //-------------------------------------------------------------------------------------------------------------- CHintMessage::~CHintMessage() { for ( int i=0; i * args ) const { if ( FStrEq( hintString, m_hintString ) ) { if ( !args && !m_args.Count() ) { return true; } if ( !args ) return false; if ( args->Count() != m_args.Count() ) return false; for ( int i=0; iCount(); ++i ) { if ( !FStrEq( (*args)[i], m_args[i] ) ) { return false; } } } return false; } //-------------------------------------------------------------------------------------------------------------- void CHintMessage::Send( CBasePlayer * client ) { if ( !client ) return; #ifdef GAME_DLL // Custom hint text sending to allow for arguments. This is OK because the client has a custom // message parser for hint text that can read the arguments. CSingleUserRecipientFilter user( (CBasePlayer *)client ); user.MakeReliable(); // client can handle 1 string only CCSUsrMsg_HintText msg; msg.set_text( m_hintString ); SendUserMessage( user, CS_UM_HintText, msg ); #endif } //-------------------------------------------------------------------------------------------------------------- CHintMessageQueue::CHintMessageQueue( CBasePlayer *pPlayer ) { m_pPlayer = pPlayer; } //-------------------------------------------------------------------------------------------------------------- void CHintMessageQueue::Reset() { m_tmMessageEnd = 0; for ( int i=0; icurtime > m_tmMessageEnd ) { if ( m_messages.Count() ) { CHintMessage *msg = m_messages[0]; m_tmMessageEnd = gpGlobals->curtime + msg->GetDuration(); msg->Send( m_pPlayer ); delete msg; m_messages.Remove( 0 ); } } } //-------------------------------------------------------------------------------------------------------------- bool CHintMessageQueue::AddMessage( const char* message, float duration, CUtlVector< const char * > * args ) { if ( !m_pPlayer ) return false; for ( int i=0; iIsEquivalent( message, args ) ) { return true; } } // 'message' is not copied, so the pointer must remain valid forever CHintMessage *msg = new CHintMessage( message, args, duration ); m_messages.AddToTail( msg ); return true; } //-------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - //----------------------------------------------------------------------------- CHintMessageTimers::CHintMessageTimers( CHintSystem *pSystem, CHintMessageQueue *pQueue ) { m_pHintSystem = pSystem; m_pQueue = pQueue; } //----------------------------------------------------------------------------- // Purpose: Clear out all registered timers //----------------------------------------------------------------------------- void CHintMessageTimers::Reset() { for ( int i=0; itimer.Expired() ) { if ( m_pHintSystem->TimerShouldFire( m_Timers[i]->iHintID ) ) { //Warning("TIMER FIRED: %s\n", m_pszHintMessages[m_Timers[i]->iHintID] ); m_pHintSystem->HintMessage( m_Timers[i]->iHintID ); // Remove and return. No reason to bring up multiple hints. RemoveTimer( m_Timers[i]->iHintID ); return; } else { // Push the timer out again m_Timers[i]->timer.Start(); } } } } //----------------------------------------------------------------------------- // Purpose: Register a new timer that the system should should keep track of. // Input : iHintID - The ID of the hint message // timer_duration - the total time the timer should run for until it fires the hint message // message_duration - the duration passed into the hint message system when the hint fires // args - the arguments passed into the hint message system when the hint fires //----------------------------------------------------------------------------- void CHintMessageTimers::AddTimer( int iHintID, float timer_duration, float message_duration, CUtlVector< const char * > * args ) { if ( GetTimerIndex(iHintID) != m_Timers.InvalidIndex() ) return; // 'message' is not copied, so the pointer must remain valid forever hintmessagetime_t *newTimer = new hintmessagetime_t( timer_duration ); newTimer->iHintID = iHintID; newTimer->flMessageDuration = message_duration; if ( args ) { for ( int i=0; iCount(); ++i ) { newTimer->args.AddToTail( CloneString( (*args)[i] ) ); } } m_Timers.AddToTail( newTimer ); //Warning("TIMER ADDED: %s\n", m_pszHintMessages[iHintID] ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHintMessageTimers::RemoveTimer( int iHintID ) { int iIndex = GetTimerIndex(iHintID); if ( iIndex != m_Timers.InvalidIndex() ) { //Warning("TIMER REMOVED: %s\n", m_pszHintMessages[iHintID] ); m_Timers.Remove( iIndex ); } } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHintMessageTimers::StartTimer( int iHintID ) { int iIndex = GetTimerIndex(iHintID); if ( iIndex != m_Timers.InvalidIndex() ) { //Warning("TIMER STARTED: %s\n", m_pszHintMessages[iHintID] ); m_Timers[iIndex]->timer.Start(); } } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHintMessageTimers::StopTimer( int iHintID ) { int iIndex = GetTimerIndex(iHintID); if ( iIndex != m_Timers.InvalidIndex() ) { //Warning("TIMER STOPPED: %s\n", m_pszHintMessages[iHintID] ); m_Timers[iIndex]->timer.Stop(); } } //----------------------------------------------------------------------------- // Purpose: Return the index of the hint message in the timer list, if any //----------------------------------------------------------------------------- int CHintMessageTimers::GetTimerIndex( int iHintID ) { for ( int i = 0; i < m_Timers.Count(); i++ ) { if ( m_Timers[i]->iHintID == iHintID ) return i; } return m_Timers.InvalidIndex(); }