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.
254 lines
7.8 KiB
254 lines
7.8 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $Workfile: $ |
|
// $Date: $ |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#ifndef TALKNPC_H |
|
#define TALKNPC_H |
|
|
|
#ifdef POSIX |
|
#undef time |
|
#include <time.h> |
|
#endif |
|
|
|
#ifndef _XBOX |
|
#undef min |
|
#undef max |
|
#pragma warning(push) |
|
#include <set> |
|
#pragma warning(pop) |
|
#endif |
|
|
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
// the include <set> monkey's with the MAX() define, unbreak it |
|
#undef MINMAX_H |
|
#include "minmax.h" |
|
|
|
#include "ai_playerally.h" |
|
|
|
#include "soundflags.h" |
|
|
|
#include "ai_task.h" |
|
#include "ai_schedule.h" |
|
#include "ai_default.h" |
|
#include "ai_speech.h" |
|
#include "ai_basenpc.h" |
|
#include "ai_behavior.h" |
|
#include "ai_behavior_follow.h" |
|
|
|
#include "tier0/memdbgon.h" |
|
|
|
//========================================================= |
|
// Talking NPC base class |
|
// Used for scientists and barneys |
|
//========================================================= |
|
|
|
#define TLK_CFRIENDS 4 |
|
|
|
//============================================================================= |
|
// >> CNPCSimpleTalker |
|
//============================================================================= |
|
|
|
#define MONOLOGNAME_LEN 16 // sentence names passed as monolog may be no longer than this. |
|
#define AI_SP_START_MONOLOG '~' |
|
#define AI_SP_MONOLOG_LINE '@' |
|
|
|
class CNPCSimpleTalker; |
|
|
|
class CNPCSimpleTalkerExpresser : public CAI_ComponentWithOuter<CNPCSimpleTalker, CAI_Expresser> |
|
{ |
|
public: |
|
CNPCSimpleTalkerExpresser( CNPCSimpleTalker *pOuter ) |
|
: CAI_ComponentWithOuter<CNPCSimpleTalker, CAI_Expresser>( pOuter ) |
|
{ |
|
EndMonolog(); |
|
} |
|
|
|
virtual int SpeakRawSentence( const char *pszSentence, float delay, float volume = VOL_NORM, soundlevel_t soundlevel = SNDLVL_TALKING, CBaseEntity *pListener = NULL ); |
|
|
|
// -------------------------------- |
|
// |
|
// Monologue operations |
|
// |
|
|
|
bool HasMonolog( void ) { return m_iMonologIndex != -1; }; |
|
void BeginMonolog( char *pszSentenceName, CBaseEntity *pListener ); |
|
void EndMonolog( void ); |
|
void SpeakMonolog( void ); |
|
|
|
void SuspendMonolog( float flInterval ); |
|
void ResumeMonolog( void ); |
|
|
|
CBaseEntity *GetMonologueTarget() { return m_hMonologTalkTarget.Get(); } |
|
|
|
// -------------------------------- |
|
// |
|
// Monologue data |
|
// |
|
char m_szMonologSentence[MONOLOGNAME_LEN]; // The name of the sentence group for the monolog I'm speaking. |
|
int m_iMonologIndex; // Which sentence from the group I should be speaking. |
|
bool m_fMonologSuspended; |
|
EHANDLE m_hMonologTalkTarget; // Who I'm trying to deliver my monolog to. |
|
|
|
DECLARE_SIMPLE_DATADESC(); |
|
}; |
|
|
|
//------------------------------------- |
|
|
|
class CNPCSimpleTalker : public CAI_PlayerAlly |
|
{ |
|
DECLARE_CLASS( CNPCSimpleTalker, CAI_PlayerAlly ); |
|
public: |
|
void Precache( void ); |
|
virtual bool KeyValue( const char *szKeyName, const char *szValue ); |
|
|
|
virtual CAI_Expresser *CreateExpresser() { return new CNPCSimpleTalkerExpresser(this); } |
|
|
|
virtual void StartFollowing( CBaseEntity *pLeader ) { m_FollowBehavior.SetFollowTarget( pLeader ); DeferSchedulingToBehavior( &m_FollowBehavior ); } |
|
virtual void StopFollowing( ) { m_FollowBehavior.SetFollowTarget( NULL ); DeferSchedulingToBehavior( NULL ); } |
|
CBaseEntity *GetFollowTarget( void ) { return m_FollowBehavior.GetFollowTarget(); } |
|
|
|
virtual void OnChangeRunningBehavior( CAI_BehaviorBase *pOldBehavior, CAI_BehaviorBase *pNewBehavior ); |
|
bool OnBehaviorChangeStatus( CAI_BehaviorBase *pBehavior, bool fCanFinishSchedule ); |
|
|
|
int PlayScriptedSentence( const char *pszSentence, float delay, float volume, soundlevel_t soundlevel, bool bConcurrent, CBaseEntity *pListener ); |
|
virtual void FollowerUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); |
|
void Event_Killed( const CTakeDamageInfo &info ); |
|
int OnTakeDamage_Alive( const CTakeDamageInfo &info ); |
|
|
|
bool CreateBehaviors() |
|
{ |
|
AddBehavior( &m_FollowBehavior ); |
|
return BaseClass::CreateBehaviors(); |
|
} |
|
|
|
void BuildScheduleTestBits( void ); |
|
void PrescheduleThink( void ); |
|
virtual int SelectSchedule( void ); |
|
virtual int SelectNonCombatSpeechSchedule(); |
|
void StartTask( const Task_t *pTask ); |
|
void RunTask( const Task_t *pTask ); |
|
void HandleAnimEvent( animevent_t *pEvent ); |
|
Activity NPC_TranslateActivity( Activity newActivity ); |
|
|
|
virtual void OnStartingFollow( CBaseEntity *pTarget ); |
|
virtual void OnStoppingFollow( CBaseEntity *pTarget ); |
|
|
|
virtual void DeferAllIdleSpeech( float flDelay, CAI_BaseNPC *pIgnore = NULL ); |
|
bool ShouldSpeakRandom( int iChance, float flModifier ); |
|
|
|
// For following |
|
virtual void DeclineFollowing( void ) {} |
|
void LimitFollowers( CBaseEntity *pPlayer, int maxFollowers ); |
|
|
|
float GetUseTime() const { return m_useTime; } |
|
|
|
//========================================================= |
|
// TalkNPC schedules |
|
//========================================================= |
|
enum |
|
{ |
|
SCHED_TALKER_IDLE_RESPONSE = BaseClass::NEXT_SCHEDULE, |
|
SCHED_TALKER_IDLE_SPEAK, |
|
SCHED_TALKER_IDLE_HELLO, |
|
SCHED_TALKER_IDLE_STOP_SHOOTING, |
|
SCHED_TALKER_IDLE_WATCH_CLIENT, |
|
SCHED_TALKER_IDLE_WATCH_CLIENT_STARE, |
|
SCHED_TALKER_IDLE_EYE_CONTACT, |
|
SCHED_TALKER_BETRAYED, |
|
|
|
// !ALWAYS LAST! |
|
NEXT_SCHEDULE, |
|
}; |
|
|
|
//========================================================= |
|
// TalkNPC tasks |
|
//========================================================= |
|
enum |
|
{ |
|
TASK_TALKER_RESPOND = BaseClass::NEXT_TASK, // say my response |
|
TASK_TALKER_SPEAK, // question or remark |
|
TASK_TALKER_HELLO, // Try to say hello to player |
|
TASK_TALKER_BETRAYED, // Player killed an ally |
|
TASK_TALKER_HEADRESET, // reset head position |
|
TASK_TALKER_STOPSHOOTING, // tell player to stop shooting friend |
|
TASK_TALKER_STARE, // let the player know I know he's staring at me. |
|
TASK_TALKER_LOOK_AT_CLIENT,// faces player if not moving and not talking and in idle. |
|
TASK_TALKER_CLIENT_STARE, // same as look at client, but says something if the player stares. |
|
TASK_TALKER_EYECONTACT, // maintain eyecontact with person who I'm talking to |
|
TASK_TALKER_IDEALYAW, // set ideal yaw to face who I'm talking to |
|
TASK_FIND_LOCK_HINTNODE_HEALTH, // Find & lock a nearby healthkit hintnode to heal myself at |
|
TASK_TALKER_WAIT_FOR_SEMAPHORE, |
|
|
|
// !ALWAYS LAST! |
|
NEXT_TASK, |
|
}; |
|
|
|
//private: |
|
virtual bool IsValidSpeechTarget( int flags, CBaseEntity *pEntity ); |
|
|
|
CBaseEntity *FindNearestFriend(bool fPlayer); |
|
|
|
bool IsOkToSpeak( void ); |
|
|
|
void SayHelloToPlayer( CBaseEntity *pPlayer ); |
|
virtual bool CanSayHello( void ); |
|
virtual int FIdleHello( void ); |
|
|
|
// Inputs |
|
void InputIdleRespond( inputdata_t &inputdata ); |
|
|
|
// Conversations / communication |
|
void IdleRespond( void ); |
|
int FIdleSpeak( void ); |
|
void FIdleSpeakWhileMoving( void ); |
|
int FIdleStare( void ); |
|
bool SpeakQuestionFriend( CBaseEntity *pFriend ); |
|
bool SpeakAnswerFriend( CBaseEntity *pFriend ); |
|
void TrySmellTalk( void ); |
|
|
|
virtual void SetAnswerQuestion( CNPCSimpleTalker *pSpeaker ); |
|
|
|
bool ShouldSuspendMonolog( void ); |
|
bool ShouldResumeMonolog( void ); |
|
void OnResumeMonolog() { Speak( TLK_RESUME ); } |
|
|
|
int m_nSpeak; // number of times initiated talking |
|
float m_flNextIdleSpeechTime; |
|
|
|
static char *m_szFriends[TLK_CFRIENDS]; // array of friend names |
|
CBaseEntity *EnumFriends( CBaseEntity *pentPrevious, int listNumber, bool bTrace ); |
|
|
|
virtual int FriendNumber( int arrayNumber ) { return arrayNumber; } |
|
void ShutUpFriends( void ); |
|
void AlertFriends( CBaseEntity *pKiller ); |
|
|
|
string_t m_iszUse; // Custom +USE sentence group (follow) |
|
string_t m_iszUnUse; // Custom +USE sentence group (stop following) |
|
|
|
protected: |
|
CAI_FollowBehavior m_FollowBehavior; |
|
float m_useTime; // Don't allow +USE until this time |
|
|
|
//--------------------------------- |
|
|
|
DECLARE_DATADESC(); |
|
#ifndef _XBOX |
|
DEFINE_CUSTOM_AI; |
|
#else |
|
public: |
|
DEFINE_CUSTOM_AI; |
|
private: |
|
#endif |
|
}; |
|
|
|
#include "tier0/memdbgoff.h" |
|
|
|
#endif //TALKNPC_H
|
|
|