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.
494 lines
18 KiB
494 lines
18 KiB
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#ifndef AI_PLAYERALLY_H |
|
#define AI_PLAYERALLY_H |
|
|
|
#include "utlmap.h" |
|
#include "simtimer.h" |
|
#include "AI_Criteria.h" |
|
#include "ai_baseactor.h" |
|
#include "ai_speechfilter.h" |
|
#include "stdstring.h" |
|
|
|
#if defined( _WIN32 ) |
|
#pragma once |
|
#endif |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
#define TLK_ANSWER "TLK_ANSWER" |
|
#define TLK_ANSWER_HELLO "TLK_ANSWER_HELLO" |
|
#define TLK_QUESTION "TLK_QUESTION" |
|
#define TLK_IDLE "TLK_IDLE" |
|
#define TLK_STARE "TLK_STARE" |
|
#define TLK_LOOK "TLK_LOOK" // player looking at player for a second |
|
#define TLK_USE "TLK_USE" |
|
#define TLK_STARTFOLLOW "TLK_STARTFOLLOW" |
|
#define TLK_STOPFOLLOW "TLK_STOPFOLLOW" |
|
#define TLK_JOINPLAYER "TLK_JOINPLAYER" |
|
#define TLK_STOP "TLK_STOP" |
|
#define TLK_NOSHOOT "TLK_NOSHOOT" |
|
#define TLK_HELLO "TLK_HELLO" |
|
#define TLK_PHELLO "TLK_PHELLO" |
|
#define TLK_HELLO_NPC "TLK_HELLO_NPC" |
|
#define TLK_PIDLE "TLK_PIDLE" |
|
#define TLK_PQUESTION "TLK_PQUESTION" |
|
#define TLK_PLHURT1 "TLK_PLHURT1" |
|
#define TLK_PLHURT2 "TLK_PLHURT2" |
|
#define TLK_PLHURT3 "TLK_PLHURT3" |
|
#define TLK_PLHURT "TLK_PLHURT" |
|
#define TLK_PLPUSH "TLK_PLPUSH" |
|
#define TLK_PLRELOAD "TLK_PLRELOAD" |
|
#define TLK_SMELL "TLK_SMELL" |
|
#define TLK_SHOT "TLK_SHOT" |
|
#define TLK_WOUND "TLK_WOUND" |
|
#define TLK_MORTAL "TLK_MORTAL" |
|
#define TLK_DANGER "TLK_DANGER" |
|
#define TLK_SEE_COMBINE "TLK_SEE_COMBINE" |
|
#define TLK_ENEMY_DEAD "TLK_ENEMY_DEAD" |
|
#define TLK_ALYX_ENEMY_DEAD "TLK_ALYX_ENEMY_DEAD" |
|
#define TLK_SELECTED "TLK_SELECTED" // selected by player in command mode. |
|
#define TLK_COMMANDED "TLK_COMMANDED" // received orders from player in command mode |
|
#define TLK_COMMAND_FAILED "TLK_COMMAND_FAILED" |
|
#define TLK_DENY_COMMAND "TLK_DENY_COMMAND" // designer has asked this NPC to politely deny player commands to move the squad |
|
#define TLK_BETRAYED "TLK_BETRAYED" // player killed an ally in front of me. |
|
#define TLK_ALLY_KILLED "TLK_ALLY_KILLED" // witnessed an ally die some other way. |
|
#define TLK_ATTACKING "TLK_ATTACKING" // about to fire my weapon at a target |
|
#define TLK_HEAL "TLK_HEAL" // healing someone |
|
#define TLK_GIVEAMMO "TLK_GIVEAMMO" // giving ammo to someone |
|
#define TLK_DEATH "TLK_DEATH" // Death rattle |
|
#define TLK_HELP_ME "TLK_HELP_ME" // call out to the player for help |
|
#define TLK_PLYR_PHYSATK "TLK_PLYR_PHYSATK" // Player's attacked me with a thrown physics object |
|
#define TLK_NEWWEAPON "TLK_NEWWEAPON" |
|
#define TLK_PLDEAD "TLK_PLDEAD" |
|
#define TLK_HIDEANDRELOAD "TLK_HIDEANDRELOAD" |
|
#define TLK_STARTCOMBAT "TLK_STARTCOMBAT" |
|
#define TLK_WATCHOUT "TLK_WATCHOUT" |
|
#define TLK_MOBBED "TLK_MOBBED" |
|
#define TLK_MANY_ENEMIES "TLK_MANY_ENEMIES" |
|
#define TLK_FLASHLIGHT_ILLUM "TLK_FLASHLIGHT_ILLUM" |
|
#define TLK_FLASHLIGHT_ON "TLK_FLASHLIGHT_ON" // player turned on flashlight |
|
#define TLK_FLASHLIGHT_OFF "TLK_FLASHLIGHT_OFF" // player turned off flashlight |
|
#define TLK_DARKNESS_LOSTPLAYER "TLK_DARKNESS_LOSTPLAYER" |
|
#define TLK_DARKNESS_FOUNDPLAYER "TLK_DARKNESS_FOUNDPLAYER" |
|
#define TLK_DARKNESS_UNKNOWN_WOUND "TLK_DARKNESS_UNKNOWN_WOUND" |
|
#define TLK_DARKNESS_HEARDSOUND "TLK_DARKNESS_HEARDSOUND" |
|
#define TLK_DARKNESS_LOSTENEMY_BY_FLASHLIGHT "TLK_DARKNESS_LOSTENEMY_BY_FLASHLIGHT" |
|
#define TLK_DARKNESS_LOSTENEMY_BY_FLASHLIGHT_EXPIRED "TLK_DARKNESS_LOSTENEMY_BY_FLASHLIGHT_EXPIRED" |
|
#define TLK_DARKNESS_FOUNDENEMY_BY_FLASHLIGHT "TLK_DARKNESS_FOUNDENEMY_BY_FLASHLIGHT" |
|
#define TLK_DARKNESS_FLASHLIGHT_EXPIRED "TLK_DARKNESS_FLASHLIGHT_EXPIRED" // flashlight expired while not in combat |
|
#define TLK_DARKNESS_ENEMY_IN_DARKNESS "TLK_DARKNESS_ENEMY_IN_DARKNESS" // have an enemy, but it's in the darkness |
|
#define TLK_SPOTTED_INCOMING_HEADCRAB "TLK_SPOTTED_INCOMING_HEADCRAB" |
|
#define TLK_CANT_INTERACT_NOW "TLK_CANT_INTERACT_NOW" // to busy to interact with an object the player is holding up to me |
|
#define TLK_ALLY_IN_BARNACLE "TLK_ALLY_IN_BARNACLE" // Barnacle is lifting my buddy! |
|
#define TLK_SELF_IN_BARNACLE "TLK_SELF_IN_BARNACLE" // I was grabbed by a barnacle! |
|
#define TLK_FOUNDPLAYER "TLK_FOUNDPLAYER" |
|
#define TLK_PLAYER_KILLED_NPC "TLK_PLAYER_KILLED_NPC" |
|
#define TLK_ENEMY_BURNING "TLK_ENEMY_BURNING" |
|
#define TLK_SPOTTED_ZOMBIE_WAKEUP "TLK_SPOTTED_ZOMBIE_WAKEUP" |
|
#define TLK_SPOTTED_HEADCRAB_LEAVING_ZOMBIE "TLK_SPOTTED_HEADCRAB_LEAVING_ZOMBIE" |
|
#define TLK_DANGER_ZOMBINE_GRENADE "TLK_DANGER_ZOMBINE_GRENADE" |
|
#define TLK_BALLSOCKETED "TLK_BALLSOCKETED" |
|
|
|
// Vehicle passenger |
|
#define TLK_PASSENGER_WARN_COLLISION "TLK_PASSENGER_WARN_COLLISION" // About to collide with something |
|
#define TLK_PASSENGER_IMPACT "TLK_PASSENGER_IMPACT" // Just hit something |
|
#define TLK_PASSENGER_OVERTURNED "TLK_PASSENGER_OVERTURNED" // Vehicle has just overturned |
|
#define TLK_PASSENGER_REQUEST_UPRIGHT "TLK_PASSENGER_REQUEST_UPRIGHT" // Vehicle needs to be put upright |
|
#define TLK_PASSENGER_ERRATIC_DRIVING "TLK_PASSENGER_ERRATIC_DRIVING" // Vehicle is moving erratically |
|
#define TLK_PASSENGER_VEHICLE_STARTED "TLK_PASSENGER_VEHICLE_STARTED" // Vehicle has started moving |
|
#define TLK_PASSENGER_VEHICLE_STOPPED "TLK_PASSENGER_VEHICLE_STOPPED" // Vehicle has stopped moving |
|
#define TLK_PASSENGER_BEGIN_ENTRANCE "TLK_PASSENGER_BEGIN_ENTRANCE" // Passenger started entering |
|
#define TLK_PASSENGER_FINISH_ENTRANCE "TLK_PASSENGER_FINISH_ENTRANCE" // Passenger finished entering (is in seat) |
|
#define TLK_PASSENGER_BEGIN_EXIT "TLK_PASSENGER_BEGIN_EXIT" // Passenger started exiting |
|
#define TLK_PASSENGER_FINISH_EXIT "TLK_PASSENGER_FINISH_EXIT" // Passenger finished exiting (seat is vacated) |
|
#define TLK_PASSENGER_PLAYER_ENTERED "TLK_PASSENGER_PLAYER_ENTERED" // Player entered the vehicle |
|
#define TLK_PASSENGER_PLAYER_EXITED "TLK_PASSENGER_PLAYER_EXITED" // Player exited the vehicle |
|
#define TLK_PASSENGER_NEW_RADAR_CONTACT "TLK_PASSENGER_NEW_RADAR_CONTACT" // Noticed a brand new contact on the radar |
|
#define TLK_PASSENGER_PUNTED "TLK_PASSENGER_PUNTED" // The player has punted us while we're sitting in the vehicle |
|
|
|
// Vortigaunt |
|
#define TLK_VORTIGAUNT_DISPEL "TLK_VORTIGAUNT_DISPEL" // Dispel attack starting |
|
|
|
// resume is "as I was saying..." or "anyhow..." |
|
#define TLK_RESUME "TLK_RESUME" |
|
|
|
// tourguide stuff below |
|
#define TLK_TGSTAYPUT "TLK_TGSTAYPUT" |
|
#define TLK_TGFIND "TLK_TGFIND" |
|
#define TLK_TGSEEK "TLK_TGSEEK" |
|
#define TLK_TGLOSTYOU "TLK_TGLOSTYOU" |
|
#define TLK_TGCATCHUP "TLK_TGCATCHUP" |
|
#define TLK_TGENDTOUR "TLK_TGENDTOUR" |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
#define TALKRANGE_MIN 500.0 // don't talk to anyone farther away than this |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
#define TALKER_STARE_DIST 128 // anyone closer than this and looking at me is probably staring at me. |
|
|
|
#define TALKER_DEFER_IDLE_SPEAK_MIN 10 |
|
#define TALKER_DEFER_IDLE_SPEAK_MAX 20 |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
class CAI_PlayerAlly; |
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// CLASS: CAI_AllySpeechManager |
|
// |
|
//----------------------------------------------------------------------------- |
|
|
|
enum ConceptCategory_t |
|
{ |
|
SPEECH_IDLE, |
|
SPEECH_IMPORTANT, |
|
SPEECH_PRIORITY, |
|
|
|
SPEECH_NUM_CATEGORIES |
|
}; |
|
|
|
struct ConceptCategoryInfo_t |
|
{ |
|
float minGlobalDelay; |
|
float maxGlobalDelay; |
|
float minPersonalDelay; |
|
float maxPersonalDelay; |
|
}; |
|
|
|
enum AIConceptFlags_t |
|
{ |
|
AICF_DEFAULT = 0, |
|
AICF_SPEAK_ONCE = 0x01, |
|
AICF_PROPAGATE_SPOKEN = 0x02, |
|
AICF_TARGET_PLAYER = 0x04, |
|
AICF_QUESTION = 0x08, |
|
AICF_ANSWER = 0x10, |
|
}; |
|
|
|
struct ConceptInfo_t |
|
{ |
|
AIConcept_t concept; |
|
ConceptCategory_t category; |
|
float minGlobalCategoryDelay; |
|
float maxGlobalCategoryDelay; |
|
float minPersonalCategoryDelay; |
|
float maxPersonalCategoryDelay; |
|
float minConceptDelay; |
|
float maxConceptDelay; |
|
int flags; |
|
}; |
|
|
|
//------------------------------------- |
|
|
|
class CAI_AllySpeechManager : public CLogicalEntity |
|
{ |
|
DECLARE_CLASS( CAI_AllySpeechManager, CLogicalEntity ); |
|
public: |
|
CAI_AllySpeechManager(); |
|
~CAI_AllySpeechManager(); |
|
|
|
void Spawn(); |
|
|
|
void AddCustomConcept( const ConceptInfo_t &conceptInfo ); |
|
ConceptCategoryInfo_t *GetConceptCategoryInfo( ConceptCategory_t category ); |
|
ConceptInfo_t *GetConceptInfo( AIConcept_t concept ); |
|
void OnSpokeConcept( CAI_PlayerAlly *pPlayerAlly, AIConcept_t concept, AI_Response *response ); |
|
|
|
void SetCategoryDelay( ConceptCategory_t category, float minDelay, float maxDelay = 0.0 ); |
|
bool CategoryDelayExpired( ConceptCategory_t category ); |
|
bool ConceptDelayExpired( AIConcept_t concept ); |
|
|
|
private: |
|
|
|
CSimpleSimTimer m_ConceptCategoryTimers[SPEECH_NUM_CATEGORIES]; |
|
|
|
CUtlMap<string_t, CSimpleSimTimer, char> m_ConceptTimers; |
|
|
|
friend CAI_AllySpeechManager *GetAllySpeechManager(); |
|
static CAI_AllySpeechManager *gm_pSpeechManager; |
|
|
|
DECLARE_DATADESC(); |
|
}; |
|
|
|
//------------------------------------- |
|
|
|
CAI_AllySpeechManager *GetAllySpeechManager(); |
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// CLASS: CAI_PlayerAlly |
|
// |
|
//----------------------------------------------------------------------------- |
|
|
|
class CAI_AllySpeechManager; |
|
|
|
enum AISpeechTargetSearchFlags_t |
|
{ |
|
AIST_PLAYERS = (1<<0), |
|
AIST_NPCS = (1<<1), |
|
AIST_IGNORE_RELATIONSHIP = (1<<2), |
|
AIST_ANY_QUALIFIED = (1<<3), |
|
AIST_FACING_TARGET = (1<<4), |
|
}; |
|
|
|
struct AISpeechSelection_t |
|
{ |
|
AISpeechSelection_t() |
|
: response() |
|
{ |
|
} |
|
|
|
void Set( AIConcept_t newConcept, AI_Response &nuResponse, CBaseEntity *pTarget = NULL ) |
|
{ |
|
response = nuResponse; |
|
concept = newConcept; |
|
hSpeechTarget = pTarget; |
|
} |
|
|
|
// Use in a specific case where the response has already been set. |
|
void Set( AIConcept_t newConcept, CBaseEntity *pTarget ) |
|
{ |
|
Assert( !response.IsEmpty() ); |
|
concept = newConcept; |
|
hSpeechTarget = pTarget; |
|
} |
|
|
|
std::string concept; |
|
AI_Response response; |
|
EHANDLE hSpeechTarget; |
|
}; |
|
|
|
//------------------------------------- |
|
|
|
class CAI_PlayerAlly : public CAI_BaseActor |
|
{ |
|
DECLARE_CLASS( CAI_PlayerAlly, CAI_BaseActor ); |
|
|
|
public: |
|
//--------------------------------- |
|
|
|
int ObjectCaps( void ) { return UsableNPCObjectCaps(BaseClass::ObjectCaps()); } |
|
void TalkInit( void ); |
|
|
|
//--------------------------------- |
|
// Behavior |
|
//--------------------------------- |
|
void GatherConditions( void ); |
|
void GatherEnemyConditions( CBaseEntity *pEnemy ); |
|
void OnStateChange( NPC_STATE OldState, NPC_STATE NewState ); |
|
void PrescheduleThink( void ); |
|
int SelectSchedule( void ); |
|
int SelectNonCombatSpeech( AISpeechSelection_t *pSelection ); |
|
virtual int SelectNonCombatSpeechSchedule(); |
|
int TranslateSchedule( int scheduleType ); |
|
void OnStartSchedule( int scheduleType ); |
|
void StartTask( const Task_t *pTask ); |
|
void RunTask( const Task_t *pTask ); |
|
void TaskFail( AI_TaskFailureCode_t ); |
|
void TaskFail( const char *pszGeneralFailText ) { BaseClass::TaskFail( pszGeneralFailText ); } |
|
void ClearTransientConditions(); |
|
void Touch( CBaseEntity *pOther ); |
|
|
|
//--------------------------------- |
|
// Combat |
|
//--------------------------------- |
|
void OnKilledNPC( CBaseCombatCharacter *pKilled ); |
|
|
|
//--------------------------------- |
|
// Damage handling |
|
//--------------------------------- |
|
void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr ); |
|
int OnTakeDamage_Alive( const CTakeDamageInfo &info ); |
|
int TakeHealth( float flHealth, int bitsDamageType ); |
|
void Event_Killed( const CTakeDamageInfo &info ); |
|
bool CreateVPhysics(); |
|
|
|
//--------------------------------- |
|
|
|
virtual void PainSound( const CTakeDamageInfo &info ); |
|
|
|
//--------------------------------- |
|
// Speech & Acting |
|
//--------------------------------- |
|
CBaseEntity *EyeLookTarget( void ); // Override to look at talk target |
|
CBaseEntity *FindNamedEntity( const char *pszName, IEntityFindFilter *pFilter = NULL ); |
|
|
|
CBaseEntity *FindSpeechTarget( int flags ); |
|
virtual bool IsValidSpeechTarget( int flags, CBaseEntity *pEntity ); |
|
|
|
CBaseEntity *GetSpeechTarget() { return m_hTalkTarget.Get(); } |
|
void SetSpeechTarget( CBaseEntity *pSpeechTarget ) { m_hTalkTarget = pSpeechTarget; } |
|
|
|
void SetSpeechFilter( CAI_SpeechFilter *pFilter ) { m_hSpeechFilter = pFilter; } |
|
CAI_SpeechFilter *GetSpeechFilter( void ) { return m_hSpeechFilter; } |
|
|
|
//--------------------------------- |
|
|
|
virtual bool SelectIdleSpeech( AISpeechSelection_t *pSelection ); |
|
virtual bool SelectAlertSpeech( AISpeechSelection_t *pSelection ); |
|
|
|
virtual bool SelectInterjection(); |
|
virtual bool SelectPlayerUseSpeech(); |
|
|
|
//--------------------------------- |
|
|
|
virtual bool SelectQuestionAndAnswerSpeech( AISpeechSelection_t *pSelection ); |
|
virtual void PostSpeakDispatchResponse( AIConcept_t concept, AI_Response *response ); |
|
bool SelectQuestionFriend( CBaseEntity *pFriend, AISpeechSelection_t *pSelection ); |
|
bool SelectAnswerFriend( CBaseEntity *pFriend, AISpeechSelection_t *pSelection, bool bRespondingToHello ); |
|
|
|
//--------------------------------- |
|
|
|
bool SelectSpeechResponse( AIConcept_t concept, const char *pszModifiers, CBaseEntity *pTarget, AISpeechSelection_t *pSelection ); |
|
void SetPendingSpeech( AIConcept_t concept, AI_Response *pResponse ); |
|
void ClearPendingSpeech(); |
|
bool HasPendingSpeech() { return !m_PendingConcept.empty(); } |
|
|
|
//--------------------------------- |
|
|
|
bool CanPlaySentence( bool fDisregardState ); |
|
int PlayScriptedSentence( const char *pszSentence, float delay, float volume, soundlevel_t soundlevel, bool bConcurrent, CBaseEntity *pListener ); |
|
|
|
//--------------------------------- |
|
|
|
void DeferAllIdleSpeech( float flDelay = -1, CAI_BaseNPC *pIgnore = NULL ); |
|
|
|
//--------------------------------- |
|
|
|
bool IsOkToSpeak( ConceptCategory_t category, bool fRespondingToPlayer = false ); |
|
|
|
//--------------------------------- |
|
|
|
bool IsOkToSpeak( void ); |
|
bool IsOkToCombatSpeak( void ); |
|
virtual bool IsOkToSpeakInResponseToPlayer( void ); |
|
|
|
bool ShouldSpeakRandom( AIConcept_t concept, int iChance ); |
|
bool IsAllowedToSpeak( AIConcept_t concept, bool bRespondingToPlayer = false ); |
|
virtual bool SpeakIfAllowed( AIConcept_t concept, const char *modifiers = NULL, bool bRespondingToPlayer = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0 ); |
|
void ModifyOrAppendCriteria( AI_CriteriaSet& set ); |
|
|
|
//--------------------------------- |
|
|
|
float GetTimePlayerStaring() { return ( m_flTimePlayerStartStare != 0 ) ? gpGlobals->curtime - m_flTimePlayerStartStare : 0; } |
|
|
|
//--------------------------------- |
|
// NPC Event Response System |
|
virtual bool CanRespondToEvent( const char *ResponseConcept ); |
|
virtual bool RespondedTo( const char *ResponseConcept, bool bForce, bool bCancelScene ); |
|
|
|
//--------------------------------- |
|
|
|
void OnSpokeConcept( AIConcept_t concept, AI_Response *response ); |
|
void OnStartSpeaking(); |
|
|
|
// Inputs |
|
virtual void InputIdleRespond( inputdata_t &inputdata ) {}; |
|
void InputSpeakResponseConcept( inputdata_t &inputdata ); |
|
virtual bool SpeakMapmakerInterruptConcept( string_t iszConcept ); |
|
|
|
void DisplayDeathMessage( void ); |
|
virtual const char *GetDeathMessageText( void ) { return "GAMEOVER_ALLY"; } |
|
void InputMakeGameEndAlly( inputdata_t &inputdata ); |
|
void InputMakeRegularAlly( inputdata_t &inputdata ); |
|
void InputAnswerQuestion( inputdata_t &inputdata ); |
|
void InputAnswerQuestionHello( inputdata_t &inputdata ); |
|
void InputEnableSpeakWhileScripting( inputdata_t &inputdata ); |
|
void InputDisableSpeakWhileScripting( inputdata_t &inputdata ); |
|
|
|
void AnswerQuestion( CAI_PlayerAlly *pQuestioner, int iQARandomNum, bool bAnsweringHello ); |
|
|
|
protected: |
|
|
|
#ifdef HL2_DLL |
|
// Health regeneration for friendly allies |
|
virtual bool ShouldRegenerateHealth( void ) { return ( Classify() == CLASS_PLAYER_ALLY_VITAL ); } |
|
#endif |
|
|
|
inline bool CanSpeakWhileScripting(); |
|
|
|
// Whether we are a vital ally (useful for wrting Classify() for classes that are only sometimes vital, |
|
// such as the Lone Vort in Ep2.) The usual means by which any other function should determine if a character |
|
// is vital is to determine Classify() == CLASS_PLAYER_ALLY_VITAL. Do not use this function outside that |
|
// context. |
|
inline bool IsGameEndAlly( void ) { return m_bGameEndAlly; } |
|
|
|
//----------------------------------------------------- |
|
// Conditions, Schedules, Tasks |
|
//----------------------------------------------------- |
|
enum |
|
{ |
|
SCHED_TALKER_SPEAK_PENDING_IDLE = BaseClass::NEXT_SCHEDULE, |
|
SCHED_TALKER_SPEAK_PENDING_ALERT, |
|
SCHED_TALKER_SPEAK_PENDING_COMBAT, |
|
NEXT_SCHEDULE, |
|
|
|
TASK_TALKER_SPEAK_PENDING = BaseClass::NEXT_TASK, |
|
NEXT_TASK, |
|
|
|
COND_TALKER_CLIENTUNSEEN = BaseClass::NEXT_CONDITION, |
|
COND_TALKER_PLAYER_DEAD, |
|
COND_TALKER_PLAYER_STARING, |
|
NEXT_CONDITION |
|
}; |
|
|
|
private: |
|
void SetCategoryDelay( ConceptCategory_t category, float minDelay, float maxDelay = 0.0 ) { m_ConceptCategoryTimers[category].Set( minDelay, maxDelay ); } |
|
bool CategoryDelayExpired( ConceptCategory_t category ) { return m_ConceptCategoryTimers[category].Expired(); } |
|
|
|
friend class CAI_AllySpeechManager; |
|
|
|
//--------------------------------- |
|
|
|
AI_Response m_PendingResponse; |
|
std::string m_PendingConcept; |
|
float m_TimePendingSet; |
|
|
|
//--------------------------------- |
|
|
|
EHANDLE m_hTalkTarget; // who to look at while talking |
|
float m_flNextRegenTime; |
|
float m_flTimePlayerStartStare; |
|
EHANDLE m_hPotentialSpeechTarget; // NPC to tell the response rules about when trying to find a response to talk to them with |
|
float m_flNextIdleSpeechTime; |
|
int m_iQARandomNumber; |
|
|
|
//--------------------------------- |
|
|
|
CSimpleSimTimer m_ConceptCategoryTimers[3]; |
|
|
|
//--------------------------------- |
|
|
|
CHandle<CAI_SpeechFilter> m_hSpeechFilter; |
|
|
|
bool m_bGameEndAlly; |
|
bool m_bCanSpeakWhileScripting; // Allows mapmakers to override NPC_STATE_SCRIPT or IsScripting() for responses. |
|
|
|
float m_flTimeLastRegen; // Last time I regenerated a bit of health. |
|
float m_flHealthAccumulator; // Counterpart to the damage accumulator in CBaseCombatCharacter. So ally health regeneration is accurate over time. |
|
|
|
#ifdef _XBOX |
|
protected: |
|
#endif |
|
DECLARE_DATADESC(); |
|
protected: |
|
DEFINE_CUSTOM_AI; |
|
}; |
|
|
|
|
|
bool CAI_PlayerAlly::CanSpeakWhileScripting() |
|
{ |
|
return m_bCanSpeakWhileScripting; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
#endif // AI_PLAYERALLY_H
|
|
|