162 lines
5.5 KiB
C++
162 lines
5.5 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#ifndef AI_SENTENCE_H
|
|
#define AI_SENTENCE_H
|
|
|
|
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
|
#include "ai_basenpc.h"
|
|
#include "ai_component.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
|