Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef AI_SENTENCE_H
  8. #define AI_SENTENCE_H
  9. #include "ai_component.h"
  10. #include "ai_basenpc.h"
  11. #include "SoundEmitterSystem/isoundemittersystembase.h"
  12. //-----------------------------------------------------------------------------
  13. // Sentence helper class used by humanoids sometimes. To use:
  14. // 1) Include it into the leaf class
  15. // 2) Use DEFINE_EMBEDDED to save/load its state
  16. // 3) Call Init in the CreateComponents method
  17. // 4) Use Speak() when it's time to speak
  18. // 5) Add m_Sentences.UpdateSentenceQueue(); to the PrescheduleThink method of an NPC
  19. // to get queued sentence support working
  20. //-----------------------------------------------------------------------------
  21. enum SentenceCriteria_t
  22. {
  23. SENTENCE_CRITERIA_ALWAYS = 0,
  24. SENTENCE_CRITERIA_NORMAL, // Obeys gag rules
  25. SENTENCE_CRITERIA_IN_SQUAD,
  26. SENTENCE_CRITERIA_SQUAD_LEADER,
  27. };
  28. enum SentencePriority_t
  29. {
  30. SENTENCE_PRIORITY_INVALID = -1,
  31. SENTENCE_PRIORITY_NORMAL = 0,
  32. SENTENCE_PRIORITY_MEDIUM = 1,
  33. SENTENCE_PRIORITY_HIGH = 2,
  34. };
  35. //-----------------------------------------------------------------------------
  36. // This is the met of the class
  37. //-----------------------------------------------------------------------------
  38. abstract_class CAI_SentenceBase : public CAI_Component
  39. {
  40. DECLARE_CLASS_NOBASE( CAI_SentenceBase );
  41. DECLARE_SIMPLE_DATADESC();
  42. public:
  43. CAI_SentenceBase();
  44. void SetVoicePitch( int voicePitch );
  45. int GetVoicePitch() const;
  46. // Check for queued-up-sentences + speak them
  47. void UpdateSentenceQueue();
  48. // Returns the sentence index played, which can be used to determine
  49. // the sentence length of time using engine->SentenceLength
  50. int Speak( const char *pSentence, SentencePriority_t nSoundPriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t nCriteria = SENTENCE_CRITERIA_IN_SQUAD );
  51. // Returns the sentence index played, which can be used to determine
  52. // the sentence length of time using engine->SentenceLength. If the sentence
  53. // was queued, then -1 is returned, which is the same result as if the sound wasn't played
  54. int SpeakQueued( const char *pSentence, SentencePriority_t nSoundPriority = SENTENCE_PRIORITY_NORMAL, SentenceCriteria_t nCriteria = SENTENCE_CRITERIA_IN_SQUAD );
  55. // Clears the sentence queue
  56. void ClearQueue();
  57. protected:
  58. virtual float GetVolume() = 0;
  59. virtual soundlevel_t GetSoundLevel() = 0;
  60. private:
  61. // Speech criteria
  62. bool MatchesCriteria( SentenceCriteria_t nCriteria );
  63. // Play the actual sentence
  64. int PlaySentence( const char *pSentence );
  65. // Debug output
  66. void SentenceMsg( const char *pStatus, const char *pSentence );
  67. int m_voicePitch;
  68. int m_nQueuedSentenceIndex;
  69. float m_flQueueTimeout;
  70. int m_nQueueSoundPriority;
  71. };
  72. //-----------------------------------------------------------------------------
  73. // NOTE: This is a template class so each user has a different set of globals
  74. //-----------------------------------------------------------------------------
  75. template< class NPC_CLASS >
  76. class CAI_Sentence : public CAI_SentenceBase
  77. {
  78. DECLARE_CLASS_NOFRIEND( CAI_Sentence, CAI_SentenceBase );
  79. public:
  80. void Init( NPC_CLASS *pOuter, const char *pGameSound );
  81. protected:
  82. virtual float GetVolume() { return m_sentenceVolume; }
  83. virtual soundlevel_t GetSoundLevel() { return m_sentenceSoundlevel; }
  84. private:
  85. static float m_sentenceVolume;
  86. static soundlevel_t m_sentenceSoundlevel;
  87. static int m_voicePitchMin;
  88. static int m_voicePitchMax;
  89. };
  90. //-----------------------------------------------------------------------------
  91. // Voice pitch
  92. //-----------------------------------------------------------------------------
  93. inline void CAI_SentenceBase::SetVoicePitch( int voicePitch )
  94. {
  95. m_voicePitch = voicePitch;
  96. }
  97. inline int CAI_SentenceBase::GetVoicePitch() const
  98. {
  99. return m_voicePitch;
  100. }
  101. //-----------------------------------------------------------------------------
  102. // Set up the class's sentence information
  103. //-----------------------------------------------------------------------------
  104. template< class NPC_CLASS >
  105. void CAI_Sentence< NPC_CLASS >::Init( NPC_CLASS *pOuter, const char *pGameSound )
  106. {
  107. SetOuter( pOuter );
  108. if ( m_voicePitchMin <= 0 || m_voicePitchMax <= 0 )
  109. {
  110. // init the sentence parameters using a dummy gamesounds entry
  111. CSoundParameters params;
  112. if ( GetOuter()->GetParametersForSound( pGameSound, params, NULL ) )
  113. {
  114. m_sentenceVolume = params.volume;
  115. m_sentenceSoundlevel = params.soundlevel;
  116. m_voicePitchMin = params.pitchlow;
  117. m_voicePitchMax = params.pitchhigh;
  118. }
  119. }
  120. // Select a voice pitch
  121. if ( random->RandomInt(0,1) )
  122. {
  123. SetVoicePitch( random->RandomInt( m_voicePitchMin, m_voicePitchMax ) );
  124. }
  125. else
  126. {
  127. SetVoicePitch( 100 );
  128. }
  129. }
  130. //-----------------------------------------------------------------------------
  131. // Global instantiation
  132. //-----------------------------------------------------------------------------
  133. template< class NPC_CLASS > float CAI_Sentence< NPC_CLASS >::m_sentenceVolume = 1.0f;
  134. template< class NPC_CLASS > soundlevel_t CAI_Sentence< NPC_CLASS >::m_sentenceSoundlevel = SNDLVL_NORM;
  135. template< class NPC_CLASS > int CAI_Sentence< NPC_CLASS >::m_voicePitchMin = 0;
  136. template< class NPC_CLASS > int CAI_Sentence< NPC_CLASS >::m_voicePitchMax = 0;
  137. #endif // AI_SENTENCE_H