Counter Strike : Global Offensive Source Code
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.

491 lines
18 KiB

  1. //========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef AI_PLAYERALLY_H
  7. #define AI_PLAYERALLY_H
  8. #include "utlmap.h"
  9. #include "simtimer.h"
  10. #include "ai_criteria.h"
  11. #include "ai_baseactor.h"
  12. #include "ai_speechfilter.h"
  13. #include "stdstring.h"
  14. #if defined( _WIN32 )
  15. #pragma once
  16. #endif
  17. //-----------------------------------------------------------------------------
  18. #define TLK_ANSWER "TLK_ANSWER"
  19. #define TLK_ANSWER_HELLO "TLK_ANSWER_HELLO"
  20. #define TLK_QUESTION "TLK_QUESTION"
  21. #define TLK_IDLE "TLK_IDLE"
  22. #define TLK_STARE "TLK_STARE"
  23. #define TLK_LOOK "TLK_LOOK" // player looking at player for a second
  24. #define TLK_USE "TLK_USE"
  25. #define TLK_STARTFOLLOW "TLK_STARTFOLLOW"
  26. #define TLK_STOPFOLLOW "TLK_STOPFOLLOW"
  27. #define TLK_JOINPLAYER "TLK_JOINPLAYER"
  28. #define TLK_STOP "TLK_STOP"
  29. #define TLK_NOSHOOT "TLK_NOSHOOT"
  30. #define TLK_HELLO "TLK_HELLO"
  31. #define TLK_PHELLO "TLK_PHELLO"
  32. #define TLK_HELLO_NPC "TLK_HELLO_NPC"
  33. #define TLK_PIDLE "TLK_PIDLE"
  34. #define TLK_PQUESTION "TLK_PQUESTION"
  35. #define TLK_PLHURT1 "TLK_PLHURT1"
  36. #define TLK_PLHURT2 "TLK_PLHURT2"
  37. #define TLK_PLHURT3 "TLK_PLHURT3"
  38. #define TLK_PLHURT "TLK_PLHURT"
  39. #define TLK_PLPUSH "TLK_PLPUSH"
  40. #define TLK_PLRELOAD "TLK_PLRELOAD"
  41. #define TLK_SMELL "TLK_SMELL"
  42. #define TLK_SHOT "TLK_SHOT"
  43. #define TLK_WOUND "TLK_WOUND"
  44. #define TLK_MORTAL "TLK_MORTAL"
  45. #define TLK_DANGER "TLK_DANGER"
  46. #define TLK_SEE_COMBINE "TLK_SEE_COMBINE"
  47. #define TLK_ENEMY_DEAD "TLK_ENEMY_DEAD"
  48. #define TLK_ALYX_ENEMY_DEAD "TLK_ALYX_ENEMY_DEAD"
  49. #define TLK_SELECTED "TLK_SELECTED" // selected by player in command mode.
  50. #define TLK_COMMANDED "TLK_COMMANDED" // received orders from player in command mode
  51. #define TLK_COMMAND_FAILED "TLK_COMMAND_FAILED"
  52. #define TLK_DENY_COMMAND "TLK_DENY_COMMAND" // designer has asked this NPC to politely deny player commands to move the squad
  53. #define TLK_BETRAYED "TLK_BETRAYED" // player killed an ally in front of me.
  54. #define TLK_ALLY_KILLED "TLK_ALLY_KILLED" // witnessed an ally die some other way.
  55. #define TLK_ATTACKING "TLK_ATTACKING" // about to fire my weapon at a target
  56. #define TLK_HEAL "TLK_HEAL" // healing someone
  57. #define TLK_GIVEAMMO "TLK_GIVEAMMO" // giving ammo to someone
  58. #define TLK_DEATH "TLK_DEATH" // Death rattle
  59. #define TLK_HELP_ME "TLK_HELP_ME" // call out to the player for help
  60. #define TLK_PLYR_PHYSATK "TLK_PLYR_PHYSATK" // Player's attacked me with a thrown physics object
  61. #define TLK_NEWWEAPON "TLK_NEWWEAPON"
  62. #define TLK_PLDEAD "TLK_PLDEAD"
  63. #define TLK_HIDEANDRELOAD "TLK_HIDEANDRELOAD"
  64. #define TLK_STARTCOMBAT "TLK_STARTCOMBAT"
  65. #define TLK_WATCHOUT "TLK_WATCHOUT"
  66. #define TLK_MOBBED "TLK_MOBBED"
  67. #define TLK_MANY_ENEMIES "TLK_MANY_ENEMIES"
  68. #define TLK_FLASHLIGHT_ILLUM "TLK_FLASHLIGHT_ILLUM"
  69. #define TLK_FLASHLIGHT_ON "TLK_FLASHLIGHT_ON" // player turned on flashlight
  70. #define TLK_FLASHLIGHT_OFF "TLK_FLASHLIGHT_OFF" // player turned off flashlight
  71. #define TLK_DARKNESS_LOSTPLAYER "TLK_DARKNESS_LOSTPLAYER"
  72. #define TLK_DARKNESS_FOUNDPLAYER "TLK_DARKNESS_FOUNDPLAYER"
  73. #define TLK_DARKNESS_UNKNOWN_WOUND "TLK_DARKNESS_UNKNOWN_WOUND"
  74. #define TLK_DARKNESS_HEARDSOUND "TLK_DARKNESS_HEARDSOUND"
  75. #define TLK_DARKNESS_LOSTENEMY_BY_FLASHLIGHT "TLK_DARKNESS_LOSTENEMY_BY_FLASHLIGHT"
  76. #define TLK_DARKNESS_LOSTENEMY_BY_FLASHLIGHT_EXPIRED "TLK_DARKNESS_LOSTENEMY_BY_FLASHLIGHT_EXPIRED"
  77. #define TLK_DARKNESS_FOUNDENEMY_BY_FLASHLIGHT "TLK_DARKNESS_FOUNDENEMY_BY_FLASHLIGHT"
  78. #define TLK_DARKNESS_FLASHLIGHT_EXPIRED "TLK_DARKNESS_FLASHLIGHT_EXPIRED" // flashlight expired while not in combat
  79. #define TLK_DARKNESS_ENEMY_IN_DARKNESS "TLK_DARKNESS_ENEMY_IN_DARKNESS" // have an enemy, but it's in the darkness
  80. #define TLK_SPOTTED_INCOMING_HEADCRAB "TLK_SPOTTED_INCOMING_HEADCRAB"
  81. #define TLK_CANT_INTERACT_NOW "TLK_CANT_INTERACT_NOW" // to busy to interact with an object the player is holding up to me
  82. #define TLK_ALLY_IN_BARNACLE "TLK_ALLY_IN_BARNACLE" // Barnacle is lifting my buddy!
  83. #define TLK_SELF_IN_BARNACLE "TLK_SELF_IN_BARNACLE" // I was grabbed by a barnacle!
  84. #define TLK_FOUNDPLAYER "TLK_FOUNDPLAYER"
  85. #define TLK_PLAYER_KILLED_NPC "TLK_PLAYER_KILLED_NPC"
  86. #define TLK_ENEMY_BURNING "TLK_ENEMY_BURNING"
  87. #define TLK_SPOTTED_ZOMBIE_WAKEUP "TLK_SPOTTED_ZOMBIE_WAKEUP"
  88. #define TLK_SPOTTED_HEADCRAB_LEAVING_ZOMBIE "TLK_SPOTTED_HEADCRAB_LEAVING_ZOMBIE"
  89. #define TLK_DANGER_ZOMBINE_GRENADE "TLK_DANGER_ZOMBINE_GRENADE"
  90. #define TLK_BALLSOCKETED "TLK_BALLSOCKETED"
  91. // Vehicle passenger
  92. #define TLK_PASSENGER_WARN_COLLISION "TLK_PASSENGER_WARN_COLLISION" // About to collide with something
  93. #define TLK_PASSENGER_IMPACT "TLK_PASSENGER_IMPACT" // Just hit something
  94. #define TLK_PASSENGER_OVERTURNED "TLK_PASSENGER_OVERTURNED" // Vehicle has just overturned
  95. #define TLK_PASSENGER_REQUEST_UPRIGHT "TLK_PASSENGER_REQUEST_UPRIGHT" // Vehicle needs to be put upright
  96. #define TLK_PASSENGER_ERRATIC_DRIVING "TLK_PASSENGER_ERRATIC_DRIVING" // Vehicle is moving erratically
  97. #define TLK_PASSENGER_VEHICLE_STARTED "TLK_PASSENGER_VEHICLE_STARTED" // Vehicle has started moving
  98. #define TLK_PASSENGER_VEHICLE_STOPPED "TLK_PASSENGER_VEHICLE_STOPPED" // Vehicle has stopped moving
  99. #define TLK_PASSENGER_BEGIN_ENTRANCE "TLK_PASSENGER_BEGIN_ENTRANCE" // Passenger started entering
  100. #define TLK_PASSENGER_FINISH_ENTRANCE "TLK_PASSENGER_FINISH_ENTRANCE" // Passenger finished entering (is in seat)
  101. #define TLK_PASSENGER_BEGIN_EXIT "TLK_PASSENGER_BEGIN_EXIT" // Passenger started exiting
  102. #define TLK_PASSENGER_FINISH_EXIT "TLK_PASSENGER_FINISH_EXIT" // Passenger finished exiting (seat is vacated)
  103. #define TLK_PASSENGER_PLAYER_ENTERED "TLK_PASSENGER_PLAYER_ENTERED" // Player entered the vehicle
  104. #define TLK_PASSENGER_PLAYER_EXITED "TLK_PASSENGER_PLAYER_EXITED" // Player exited the vehicle
  105. #define TLK_PASSENGER_NEW_RADAR_CONTACT "TLK_PASSENGER_NEW_RADAR_CONTACT" // Noticed a brand new contact on the radar
  106. #define TLK_PASSENGER_PUNTED "TLK_PASSENGER_PUNTED" // The player has punted us while we're sitting in the vehicle
  107. // Vortigaunt
  108. #define TLK_VORTIGAUNT_DISPEL "TLK_VORTIGAUNT_DISPEL" // Dispel attack starting
  109. // resume is "as I was saying..." or "anyhow..."
  110. #define TLK_RESUME "TLK_RESUME"
  111. // tourguide stuff below
  112. #define TLK_TGSTAYPUT "TLK_TGSTAYPUT"
  113. #define TLK_TGFIND "TLK_TGFIND"
  114. #define TLK_TGSEEK "TLK_TGSEEK"
  115. #define TLK_TGLOSTYOU "TLK_TGLOSTYOU"
  116. #define TLK_TGCATCHUP "TLK_TGCATCHUP"
  117. #define TLK_TGENDTOUR "TLK_TGENDTOUR"
  118. //-----------------------------------------------------------------------------
  119. #define TALKRANGE_MIN 500.0 // don't talk to anyone farther away than this
  120. //-----------------------------------------------------------------------------
  121. #define TALKER_STARE_DIST 128 // anyone closer than this and looking at me is probably staring at me.
  122. #define TALKER_DEFER_IDLE_SPEAK_MIN 10
  123. #define TALKER_DEFER_IDLE_SPEAK_MAX 20
  124. //-----------------------------------------------------------------------------
  125. class CAI_PlayerAlly;
  126. //-----------------------------------------------------------------------------
  127. //
  128. // CLASS: CAI_AllySpeechManager
  129. //
  130. //-----------------------------------------------------------------------------
  131. enum ConceptCategory_t
  132. {
  133. SPEECH_IDLE,
  134. SPEECH_IMPORTANT,
  135. SPEECH_PRIORITY,
  136. SPEECH_NUM_CATEGORIES
  137. };
  138. struct ConceptCategoryInfo_t
  139. {
  140. float minGlobalDelay;
  141. float maxGlobalDelay;
  142. float minPersonalDelay;
  143. float maxPersonalDelay;
  144. };
  145. enum AIConceptFlags_t
  146. {
  147. AICF_DEFAULT = 0,
  148. AICF_SPEAK_ONCE = 0x01,
  149. AICF_PROPAGATE_SPOKEN = 0x02,
  150. AICF_TARGET_PLAYER = 0x04,
  151. AICF_QUESTION = 0x08,
  152. AICF_ANSWER = 0x10,
  153. };
  154. struct ConceptInfo_t
  155. {
  156. AIConcept_t concept;
  157. ConceptCategory_t category;
  158. float minGlobalCategoryDelay;
  159. float maxGlobalCategoryDelay;
  160. float minPersonalCategoryDelay;
  161. float maxPersonalCategoryDelay;
  162. float minConceptDelay;
  163. float maxConceptDelay;
  164. int flags;
  165. };
  166. //-------------------------------------
  167. class CAI_AllySpeechManager : public CLogicalEntity
  168. {
  169. DECLARE_CLASS( CAI_AllySpeechManager, CLogicalEntity );
  170. public:
  171. CAI_AllySpeechManager();
  172. ~CAI_AllySpeechManager();
  173. void Spawn();
  174. void AddCustomConcept( const ConceptInfo_t &conceptInfo );
  175. ConceptCategoryInfo_t *GetConceptCategoryInfo( ConceptCategory_t category );
  176. ConceptInfo_t *GetConceptInfo( AIConcept_t concept );
  177. void OnSpokeConcept( CAI_PlayerAlly *pPlayerAlly, AIConcept_t concept, AI_Response *response );
  178. void SetCategoryDelay( ConceptCategory_t category, float minDelay, float maxDelay = 0.0 );
  179. bool CategoryDelayExpired( ConceptCategory_t category );
  180. bool ConceptDelayExpired( AIConcept_t concept );
  181. private:
  182. CSimpleSimTimer m_ConceptCategoryTimers[SPEECH_NUM_CATEGORIES];
  183. CUtlMap<string_t, CSimpleSimTimer, char> m_ConceptTimers;
  184. friend CAI_AllySpeechManager *GetAllySpeechManager();
  185. static CAI_AllySpeechManager *gm_pSpeechManager;
  186. DECLARE_DATADESC();
  187. };
  188. //-------------------------------------
  189. CAI_AllySpeechManager *GetAllySpeechManager();
  190. //-----------------------------------------------------------------------------
  191. //
  192. // CLASS: CAI_PlayerAlly
  193. //
  194. //-----------------------------------------------------------------------------
  195. class CAI_AllySpeechManager;
  196. enum AISpeechTargetSearchFlags_t
  197. {
  198. AIST_PLAYERS = (1<<0),
  199. AIST_NPCS = (1<<1),
  200. AIST_IGNORE_RELATIONSHIP = (1<<2),
  201. AIST_ANY_QUALIFIED = (1<<3),
  202. AIST_FACING_TARGET = (1<<4),
  203. };
  204. struct AISpeechSelection_t
  205. {
  206. AISpeechSelection_t()
  207. : response()
  208. {
  209. }
  210. void Set( AIConcept_t newConcept, AI_Response &nuResponse, CBaseEntity *pTarget = NULL )
  211. {
  212. response = nuResponse;
  213. concept = newConcept;
  214. hSpeechTarget = pTarget;
  215. }
  216. // Use in a specific case where the response has already been set.
  217. void Set( AIConcept_t newConcept, CBaseEntity *pTarget )
  218. {
  219. Assert( !response.IsEmpty() );
  220. concept = newConcept;
  221. hSpeechTarget = pTarget;
  222. }
  223. std::string concept;
  224. AI_Response response;
  225. EHANDLE hSpeechTarget;
  226. };
  227. //-------------------------------------
  228. class CAI_PlayerAlly : public CAI_BaseActor
  229. {
  230. DECLARE_CLASS( CAI_PlayerAlly, CAI_BaseActor );
  231. public:
  232. //---------------------------------
  233. int ObjectCaps( void ) { return UsableNPCObjectCaps(BaseClass::ObjectCaps()); }
  234. void TalkInit( void );
  235. //---------------------------------
  236. // Behavior
  237. //---------------------------------
  238. void GatherConditions( void );
  239. void GatherEnemyConditions( CBaseEntity *pEnemy );
  240. void OnStateChange( NPC_STATE OldState, NPC_STATE NewState );
  241. void PrescheduleThink( void );
  242. int SelectSchedule( void );
  243. int SelectNonCombatSpeech( AISpeechSelection_t *pSelection );
  244. virtual int SelectNonCombatSpeechSchedule();
  245. int TranslateSchedule( int scheduleType );
  246. void OnStartSchedule( int scheduleType );
  247. void StartTask( const Task_t *pTask );
  248. void RunTask( const Task_t *pTask );
  249. void TaskFail( AI_TaskFailureCode_t );
  250. void TaskFail( const char *pszGeneralFailText ) { BaseClass::TaskFail( pszGeneralFailText ); }
  251. void ClearTransientConditions();
  252. void Touch( CBaseEntity *pOther );
  253. //---------------------------------
  254. // Combat
  255. //---------------------------------
  256. void OnKilledNPC( CBaseCombatCharacter *pKilled );
  257. //---------------------------------
  258. // Damage handling
  259. //---------------------------------
  260. void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr );
  261. int OnTakeDamage_Alive( const CTakeDamageInfo &info );
  262. int TakeHealth( float flHealth, int bitsDamageType );
  263. void Event_Killed( const CTakeDamageInfo &info );
  264. bool CreateVPhysics();
  265. //---------------------------------
  266. virtual void PainSound( const CTakeDamageInfo &info );
  267. //---------------------------------
  268. // Speech & Acting
  269. //---------------------------------
  270. CBaseEntity *EyeLookTarget( void ); // Override to look at talk target
  271. CBaseEntity *FindNamedEntity( const char *pszName, IEntityFindFilter *pFilter = NULL );
  272. CBaseEntity *FindSpeechTarget( int flags );
  273. virtual bool IsValidSpeechTarget( int flags, CBaseEntity *pEntity );
  274. CBaseEntity *GetSpeechTarget() { return m_hTalkTarget.Get(); }
  275. void SetSpeechTarget( CBaseEntity *pSpeechTarget ) { m_hTalkTarget = pSpeechTarget; }
  276. void SetSpeechFilter( CAI_SpeechFilter *pFilter ) { m_hSpeechFilter = pFilter; }
  277. CAI_SpeechFilter *GetSpeechFilter( void ) { return m_hSpeechFilter; }
  278. //---------------------------------
  279. virtual bool SelectIdleSpeech( AISpeechSelection_t *pSelection );
  280. virtual bool SelectAlertSpeech( AISpeechSelection_t *pSelection );
  281. virtual bool SelectInterjection();
  282. virtual bool SelectPlayerUseSpeech();
  283. //---------------------------------
  284. virtual bool SelectQuestionAndAnswerSpeech( AISpeechSelection_t *pSelection );
  285. virtual void PostSpeakDispatchResponse( AIConcept_t concept, AI_Response *response );
  286. bool SelectQuestionFriend( CBaseEntity *pFriend, AISpeechSelection_t *pSelection );
  287. bool SelectAnswerFriend( CBaseEntity *pFriend, AISpeechSelection_t *pSelection, bool bRespondingToHello );
  288. //---------------------------------
  289. bool SelectSpeechResponse( AIConcept_t concept, const char *pszModifiers, CBaseEntity *pTarget, AISpeechSelection_t *pSelection );
  290. void SetPendingSpeech( AIConcept_t concept, AI_Response *pResponse );
  291. void ClearPendingSpeech();
  292. bool HasPendingSpeech() { return !m_PendingConcept.empty(); }
  293. //---------------------------------
  294. bool CanPlaySentence( bool fDisregardState );
  295. int PlayScriptedSentence( const char *pszSentence, float delay, float volume, soundlevel_t soundlevel, bool bConcurrent, CBaseEntity *pListener );
  296. //---------------------------------
  297. void DeferAllIdleSpeech( float flDelay = -1, CAI_BaseNPC *pIgnore = NULL );
  298. //---------------------------------
  299. bool IsOkToSpeak( ConceptCategory_t category, bool fRespondingToPlayer = false );
  300. //---------------------------------
  301. bool IsOkToSpeak( void );
  302. bool IsOkToCombatSpeak( void );
  303. virtual bool IsOkToSpeakInResponseToPlayer( void );
  304. bool ShouldSpeakRandom( AIConcept_t concept, int iChance );
  305. bool IsAllowedToSpeak( AIConcept_t concept, bool bRespondingToPlayer = false );
  306. virtual bool SpeakIfAllowed( AIConcept_t concept, const char *modifiers = NULL, bool bRespondingToPlayer = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0 );
  307. void ModifyOrAppendCriteria( AI_CriteriaSet& set );
  308. //---------------------------------
  309. float GetTimePlayerStaring() { return ( m_flTimePlayerStartStare != 0 ) ? gpGlobals->curtime - m_flTimePlayerStartStare : 0; }
  310. //---------------------------------
  311. // NPC Event Response System
  312. virtual bool CanRespondToEvent( const char *ResponseConcept );
  313. virtual bool RespondedTo( const char *ResponseConcept, bool bForce, bool bCancelScene );
  314. //---------------------------------
  315. void OnSpokeConcept( AIConcept_t concept, AI_Response *response );
  316. void OnStartSpeaking();
  317. // Inputs
  318. virtual void InputIdleRespond( inputdata_t &inputdata ) {};
  319. void InputSpeakResponseConcept( inputdata_t &inputdata );
  320. virtual bool SpeakMapmakerInterruptConcept( string_t iszConcept );
  321. void DisplayDeathMessage( void );
  322. virtual const char *GetDeathMessageText( void ) { return "GAMEOVER_ALLY"; }
  323. void InputMakeGameEndAlly( inputdata_t &inputdata );
  324. void InputMakeRegularAlly( inputdata_t &inputdata );
  325. void InputAnswerQuestion( inputdata_t &inputdata );
  326. void InputAnswerQuestionHello( inputdata_t &inputdata );
  327. void InputEnableSpeakWhileScripting( inputdata_t &inputdata );
  328. void InputDisableSpeakWhileScripting( inputdata_t &inputdata );
  329. void AnswerQuestion( CAI_PlayerAlly *pQuestioner, int iQARandomNum, bool bAnsweringHello );
  330. protected:
  331. #ifdef HL2_DLL
  332. // Health regeneration for friendly allies
  333. virtual bool ShouldRegenerateHealth( void ) { return ( Classify() == CLASS_PLAYER_ALLY_VITAL ); }
  334. #endif
  335. inline bool CanSpeakWhileScripting();
  336. // Whether we are a vital ally (useful for wrting Classify() for classes that are only sometimes vital,
  337. // such as the Lone Vort in Ep2.) The usual means by which any other function should determine if a character
  338. // is vital is to determine Classify() == CLASS_PLAYER_ALLY_VITAL. Do not use this function outside that
  339. // context.
  340. inline bool IsGameEndAlly( void ) { return m_bGameEndAlly; }
  341. //-----------------------------------------------------
  342. // Conditions, Schedules, Tasks
  343. //-----------------------------------------------------
  344. enum
  345. {
  346. SCHED_TALKER_SPEAK_PENDING_IDLE = BaseClass::NEXT_SCHEDULE,
  347. SCHED_TALKER_SPEAK_PENDING_ALERT,
  348. SCHED_TALKER_SPEAK_PENDING_COMBAT,
  349. NEXT_SCHEDULE,
  350. TASK_TALKER_SPEAK_PENDING = BaseClass::NEXT_TASK,
  351. NEXT_TASK,
  352. COND_TALKER_CLIENTUNSEEN = BaseClass::NEXT_CONDITION,
  353. COND_TALKER_PLAYER_DEAD,
  354. COND_TALKER_PLAYER_STARING,
  355. NEXT_CONDITION
  356. };
  357. private:
  358. void SetCategoryDelay( ConceptCategory_t category, float minDelay, float maxDelay = 0.0 ) { m_ConceptCategoryTimers[category].Set( minDelay, maxDelay ); }
  359. bool CategoryDelayExpired( ConceptCategory_t category ) { return m_ConceptCategoryTimers[category].Expired(); }
  360. friend class CAI_AllySpeechManager;
  361. //---------------------------------
  362. AI_Response m_PendingResponse;
  363. std::string m_PendingConcept;
  364. float m_TimePendingSet;
  365. //---------------------------------
  366. EHANDLE m_hTalkTarget; // who to look at while talking
  367. float m_flNextRegenTime;
  368. float m_flTimePlayerStartStare;
  369. EHANDLE m_hPotentialSpeechTarget; // NPC to tell the response rules about when trying to find a response to talk to them with
  370. float m_flNextIdleSpeechTime;
  371. int m_iQARandomNumber;
  372. //---------------------------------
  373. CSimpleSimTimer m_ConceptCategoryTimers[3];
  374. //---------------------------------
  375. CHandle<CAI_SpeechFilter> m_hSpeechFilter;
  376. bool m_bGameEndAlly;
  377. bool m_bCanSpeakWhileScripting; // Allows mapmakers to override NPC_STATE_SCRIPT or IsScripting() for responses.
  378. float m_flTimeLastRegen; // Last time I regenerated a bit of health.
  379. float m_flHealthAccumulator; // Counterpart to the damage accumulator in CBaseCombatCharacter. So ally health regeneration is accurate over time.
  380. DECLARE_DATADESC();
  381. protected:
  382. DEFINE_CUSTOM_AI;
  383. };
  384. bool CAI_PlayerAlly::CanSpeakWhileScripting()
  385. {
  386. return m_bCanSpeakWhileScripting;
  387. }
  388. //-----------------------------------------------------------------------------
  389. #endif // AI_PLAYERALLY_H