diff options
Diffstat (limited to 'game/server/ai_sentence.h')
| -rw-r--r-- | game/server/ai_sentence.h | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/game/server/ai_sentence.h b/game/server/ai_sentence.h new file mode 100644 index 0000000..8099fce --- /dev/null +++ b/game/server/ai_sentence.h @@ -0,0 +1,172 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef AI_SENTENCE_H +#define AI_SENTENCE_H + +#include "ai_component.h" +#include "ai_basenpc.h" +#include "SoundEmitterSystem/isoundemittersystembase.h" + + +//----------------------------------------------------------------------------- +// Sentence helper class used by humanoids sometimes. To use: +// 1) Include it into the leaf class +// 2) Use DEFINE_EMBEDDED to save/load its state +// 3) Call Init in the CreateComponents method +// 4) Use Speak() when it's time to speak +// 5) Add m_Sentences.UpdateSentenceQueue(); to the PrescheduleThink method of an NPC +// to get queued sentence support working +//----------------------------------------------------------------------------- +enum SentenceCriteria_t +{ + SENTENCE_CRITERIA_ALWAYS = 0, + SENTENCE_CRITERIA_NORMAL, // Obeys gag rules + SENTENCE_CRITERIA_IN_SQUAD, + SENTENCE_CRITERIA_SQUAD_LEADER, +}; + +enum SentencePriority_t +{ + SENTENCE_PRIORITY_INVALID = -1, + SENTENCE_PRIORITY_NORMAL = 0, + SENTENCE_PRIORITY_MEDIUM = 1, + SENTENCE_PRIORITY_HIGH = 2, +}; + + +//----------------------------------------------------------------------------- +// This is the met of the class +//----------------------------------------------------------------------------- +abstract_class CAI_SentenceBase : public CAI_Component +{ + DECLARE_CLASS_NOBASE( CAI_SentenceBase ); + DECLARE_SIMPLE_DATADESC(); + +public: + CAI_SentenceBase(); + + void SetVoicePitch( int voicePitch ); + int GetVoicePitch() const; + + // Check for queued-up-sentences + speak them + void UpdateSentenceQueue(); + + // Returns the sentence index played, which can be used to determine + // the sentence length of time using engine->SentenceLength + int Speak( const char *pSentence, SentencePriority_t nSoundPriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t nCriteria = SENTENCE_CRITERIA_IN_SQUAD ); + + // Returns the sentence index played, which can be used to determine + // the sentence length of time using engine->SentenceLength. If the sentence + // was queued, then -1 is returned, which is the same result as if the sound wasn't played + int SpeakQueued( const char *pSentence, SentencePriority_t nSoundPriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t nCriteria = SENTENCE_CRITERIA_IN_SQUAD ); + + // Clears the sentence queue + void ClearQueue(); + +protected: + virtual float GetVolume() = 0; + virtual soundlevel_t GetSoundLevel() = 0; + +private: + // Speech criteria + bool MatchesCriteria( SentenceCriteria_t nCriteria ); + + // Play the actual sentence + int PlaySentence( const char *pSentence ); + + // Debug output + void SentenceMsg( const char *pStatus, const char *pSentence ); + + int m_voicePitch; + int m_nQueuedSentenceIndex; + float m_flQueueTimeout; + int m_nQueueSoundPriority; +}; + + +//----------------------------------------------------------------------------- +// NOTE: This is a template class so each user has a different set of globals +//----------------------------------------------------------------------------- +template< class NPC_CLASS > +class CAI_Sentence : public CAI_SentenceBase +{ + DECLARE_CLASS_NOFRIEND( CAI_Sentence, CAI_SentenceBase ); + +public: + void Init( NPC_CLASS *pOuter, const char *pGameSound ); + +protected: + virtual float GetVolume() { return m_sentenceVolume; } + virtual soundlevel_t GetSoundLevel() { return m_sentenceSoundlevel; } + +private: + static float m_sentenceVolume; + static soundlevel_t m_sentenceSoundlevel; + static int m_voicePitchMin; + static int m_voicePitchMax; +}; + + +//----------------------------------------------------------------------------- +// Voice pitch +//----------------------------------------------------------------------------- +inline void CAI_SentenceBase::SetVoicePitch( int voicePitch ) +{ + m_voicePitch = voicePitch; +} + +inline int CAI_SentenceBase::GetVoicePitch() const +{ + return m_voicePitch; +} + + +//----------------------------------------------------------------------------- +// Set up the class's sentence information +//----------------------------------------------------------------------------- +template< class NPC_CLASS > +void CAI_Sentence< NPC_CLASS >::Init( NPC_CLASS *pOuter, const char *pGameSound ) +{ + SetOuter( pOuter ); + + if ( m_voicePitchMin <= 0 || m_voicePitchMax <= 0 ) + { + // init the sentence parameters using a dummy gamesounds entry + CSoundParameters params; + if ( GetOuter()->GetParametersForSound( pGameSound, params, NULL ) ) + { + m_sentenceVolume = params.volume; + m_sentenceSoundlevel = params.soundlevel; + m_voicePitchMin = params.pitchlow; + m_voicePitchMax = params.pitchhigh; + } + } + + // Select a voice pitch + if ( random->RandomInt(0,1) ) + { + SetVoicePitch( random->RandomInt( m_voicePitchMin, m_voicePitchMax ) ); + } + else + { + SetVoicePitch( 100 ); + } +} + + +//----------------------------------------------------------------------------- +// Global instantiation +//----------------------------------------------------------------------------- +template< class NPC_CLASS > float CAI_Sentence< NPC_CLASS >::m_sentenceVolume = 1.0f; +template< class NPC_CLASS > soundlevel_t CAI_Sentence< NPC_CLASS >::m_sentenceSoundlevel = SNDLVL_NORM; +template< class NPC_CLASS > int CAI_Sentence< NPC_CLASS >::m_voicePitchMin = 0; +template< class NPC_CLASS > int CAI_Sentence< NPC_CLASS >::m_voicePitchMax = 0; + + + +#endif // AI_SENTENCE_H |