mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-19 20:16:10 +08:00
First version of the SOurce SDK 2013
This commit is contained in:
296
game/shared/hintmessage.cpp
Normal file
296
game/shared/hintmessage.cpp
Normal file
@ -0,0 +1,296 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hintmessage.h"
|
||||
#include "hintsystem.h"
|
||||
|
||||
#ifdef GAME_DLL
|
||||
#include "util.h"
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* 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; i<args->Count(); ++i )
|
||||
{
|
||||
m_args.AddToTail( CloneString( (*args)[i] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
CHintMessage::~CHintMessage()
|
||||
{
|
||||
for ( int i=0; i<m_args.Count(); ++i )
|
||||
{
|
||||
delete[] m_args[i];
|
||||
}
|
||||
m_args.RemoveAll();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
bool CHintMessage::IsEquivalent( const char *hintString, CUtlVector< const char * > * 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; i<args->Count(); ++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
|
||||
UserMessageBegin( user, "HintText" );
|
||||
WRITE_STRING( m_hintString );
|
||||
MessageEnd();
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
CHintMessageQueue::CHintMessageQueue( CBasePlayer *pPlayer )
|
||||
{
|
||||
m_pPlayer = pPlayer;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
void CHintMessageQueue::Reset()
|
||||
{
|
||||
m_tmMessageEnd = 0;
|
||||
for ( int i=0; i<m_messages.Count(); ++i )
|
||||
{
|
||||
delete m_messages[i];
|
||||
}
|
||||
m_messages.RemoveAll();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
void CHintMessageQueue::Update()
|
||||
{
|
||||
if ( !m_pPlayer )
|
||||
return;
|
||||
|
||||
// test this - send the message as soon as it is ready,
|
||||
// just stomp the old message
|
||||
//if ( gpGlobals->curtime > 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; i<m_messages.Count(); ++i )
|
||||
{
|
||||
// weed out duplicates
|
||||
if ( m_messages[i]->IsEquivalent( 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; i<m_Timers.Count(); ++i )
|
||||
{
|
||||
delete m_Timers[i];
|
||||
}
|
||||
m_Timers.RemoveAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check & fire any timers that should fire based on their duration.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHintMessageTimers::Update()
|
||||
{
|
||||
if ( !m_pHintSystem )
|
||||
return;
|
||||
|
||||
for ( int i = 0; i < m_Timers.Count(); i++ )
|
||||
{
|
||||
if ( m_Timers[i]->timer.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; i<args->Count(); ++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();
|
||||
}
|
Reference in New Issue
Block a user