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.

481 lines
18 KiB

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