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.

676 lines
22 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Bot radio chatter system
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. // Author: Michael S. Booth ([email protected]), 2003
  8. #ifndef CS_BOT_CHATTER_H
  9. #define CS_BOT_CHATTER_H
  10. #pragma warning( disable : 4786 ) // long STL names get truncated in browse info.
  11. #include "nav_mesh.h"
  12. #include "cs_gamestate.h"
  13. class CCSBot;
  14. class BotChatterInterface;
  15. #define MAX_PLACES_PER_MAP 64
  16. typedef unsigned int PlaceCriteria;
  17. typedef unsigned int CountCriteria;
  18. #define UNDEFINED_COUNT 0xFFFF
  19. #define COUNT_CURRENT_ENEMIES 0xFF // use the number of enemies we see right when we speak
  20. #define COUNT_MANY 4 // equal to or greater than this is "many"
  21. #define UNDEFINED_SUBJECT (-1)
  22. /// @todo Make Place a class with member fuctions for this
  23. bool GetRandomSpotAtPlace( Place place, Vector *pPos );
  24. //----------------------------------------------------------------------------------------------------
  25. /**
  26. * A meme is a unit information that bots use to
  27. * transmit information to each other via the radio
  28. */
  29. class BotMeme
  30. {
  31. public:
  32. void Transmit( CCSBot *sender ) const; ///< transmit meme to other bots
  33. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const = 0; ///< cause the given bot to act on this meme
  34. };
  35. //----------------------------------------------------------------------------------------------------
  36. class BotHelpMeme : public BotMeme
  37. {
  38. public:
  39. BotHelpMeme( Place place = UNDEFINED_PLACE )
  40. {
  41. m_place = place;
  42. }
  43. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
  44. private:
  45. Place m_place; ///< where the help is needed
  46. };
  47. //----------------------------------------------------------------------------------------------------
  48. class BotBombsiteStatusMeme : public BotMeme
  49. {
  50. public:
  51. enum StatusType { CLEAR, PLANTED };
  52. BotBombsiteStatusMeme( int zoneIndex, StatusType status )
  53. {
  54. m_zoneIndex = zoneIndex;
  55. m_status = status;
  56. }
  57. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
  58. private:
  59. int m_zoneIndex; ///< the bombsite
  60. StatusType m_status; ///< whether it is cleared or the bomb is there (planted)
  61. };
  62. //----------------------------------------------------------------------------------------------------
  63. class BotBombStatusMeme : public BotMeme
  64. {
  65. public:
  66. BotBombStatusMeme( CSGameState::BombState state, const Vector &pos )
  67. {
  68. m_state = state;
  69. m_pos = pos;
  70. }
  71. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
  72. private:
  73. CSGameState::BombState m_state;
  74. Vector m_pos;
  75. };
  76. //----------------------------------------------------------------------------------------------------
  77. class BotFollowMeme : public BotMeme
  78. {
  79. public:
  80. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
  81. };
  82. //----------------------------------------------------------------------------------------------------
  83. class BotDefendHereMeme : public BotMeme
  84. {
  85. public:
  86. BotDefendHereMeme( const Vector &pos )
  87. {
  88. m_pos = pos;
  89. }
  90. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
  91. private:
  92. Vector m_pos;
  93. };
  94. //----------------------------------------------------------------------------------------------------
  95. class BotWhereBombMeme : public BotMeme
  96. {
  97. public:
  98. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
  99. };
  100. //----------------------------------------------------------------------------------------------------
  101. class BotRequestReportMeme : public BotMeme
  102. {
  103. public:
  104. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
  105. };
  106. //----------------------------------------------------------------------------------------------------
  107. class BotAllHostagesGoneMeme : public BotMeme
  108. {
  109. public:
  110. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
  111. };
  112. //----------------------------------------------------------------------------------------------------
  113. class BotHostageBeingTakenMeme : public BotMeme
  114. {
  115. public:
  116. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
  117. };
  118. //----------------------------------------------------------------------------------------------------
  119. class BotHeardNoiseMeme : public BotMeme
  120. {
  121. public:
  122. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
  123. };
  124. //----------------------------------------------------------------------------------------------------
  125. class BotWarnSniperMeme : public BotMeme
  126. {
  127. public:
  128. virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
  129. };
  130. //----------------------------------------------------------------------------------------------------
  131. enum BotStatementType
  132. {
  133. REPORT_VISIBLE_ENEMIES,
  134. REPORT_ENEMY_ACTION,
  135. REPORT_MY_CURRENT_TASK,
  136. REPORT_MY_INTENTION,
  137. REPORT_CRITICAL_EVENT,
  138. REPORT_REQUEST_HELP,
  139. REPORT_REQUEST_INFORMATION,
  140. REPORT_ROUND_END,
  141. REPORT_MY_PLAN,
  142. REPORT_INFORMATION,
  143. REPORT_EMOTE,
  144. REPORT_ACKNOWLEDGE, ///< affirmative or negative
  145. REPORT_ENEMIES_REMAINING,
  146. REPORT_FRIENDLY_FIRE,
  147. REPORT_KILLED_FRIEND,
  148. REPORT_ENEMY_LOST,
  149. NUM_BOT_STATEMENT_TYPES
  150. };
  151. //----------------------------------------------------------------------------------------------------
  152. //----------------------------------------------------------------------------------------------------
  153. /**
  154. * BotSpeakables are the smallest unit of bot chatter.
  155. * They represent a specific wav file of a phrase, and the criteria for which it is useful
  156. */
  157. class BotSpeakable
  158. {
  159. public:
  160. BotSpeakable();
  161. ~BotSpeakable();
  162. char *m_phrase;
  163. float m_duration;
  164. PlaceCriteria m_place;
  165. CountCriteria m_count;
  166. };
  167. typedef CUtlVector< BotSpeakable * > BotSpeakableVector;
  168. typedef CUtlVector< BotSpeakableVector * > BotVoiceBankVector;
  169. //----------------------------------------------------------------------------------------------------
  170. /**
  171. * The BotPhrase class is a collection of Speakables associated with a name, ID, and criteria
  172. */
  173. class BotPhrase
  174. {
  175. public:
  176. char *GetSpeakable( int bankIndex, float *duration = NULL ) const; ///< return a random speakable and its duration in seconds that meets the current criteria
  177. // NOTE: Criteria must be set just before the GetSpeakable() call, since they are shared among all bots
  178. void ClearCriteria( void ) const;
  179. void SetPlaceCriteria( PlaceCriteria place ) const; ///< all returned phrases must have this place criteria
  180. void SetCountCriteria( CountCriteria count ) const; ///< all returned phrases must have this count criteria
  181. void SetCriteriaSet( AI_CriteriaSet &criteria ) const;
  182. const char *GetName( void ) const { return m_name; }
  183. const unsigned int GetPlace( void ) const { return m_place; }
  184. RadioType GetRadioEquivalent( void ) const { return m_radioEvent; } ///< return equivalent "standard radio" event
  185. bool IsImportant( void ) const { return m_isImportant; } ///< return true if this phrase is part of an important statement
  186. bool IsPlace( void ) const { return m_isPlace; }
  187. void Randomize( void ); ///< randomly shuffle the speakable order
  188. PlaceCriteria GetPlaceCriteria( void ) const { return m_placeCriteria; }
  189. CountCriteria GetCountCriteria( void ) const { return m_countCriteria; }
  190. AI_CriteriaSet &GetCriteriaSet( void ) const { return m_contexts; }
  191. private:
  192. friend class BotPhraseManager;
  193. BotPhrase( bool isPlace );
  194. ~BotPhrase();
  195. char *m_name;
  196. Place m_place;
  197. bool m_isPlace; ///< true if this is a Place phrase
  198. RadioType m_radioEvent; ///< equivalent radio event
  199. bool m_isImportant; ///< mission-critical statement
  200. mutable BotVoiceBankVector m_voiceBank; ///< array of voice banks (arrays of speakables)
  201. CUtlVector< int > m_count; ///< number of speakables
  202. mutable CUtlVector< int > m_index; ///< index of next speakable to return
  203. int m_numVoiceBanks; ///< number of voice banks that have been initialized
  204. void InitVoiceBank( int bankIndex ); ///< sets up the vector of voice banks for the first bankIndex voice banks
  205. mutable PlaceCriteria m_placeCriteria;
  206. mutable CountCriteria m_countCriteria;
  207. mutable AI_CriteriaSet m_contexts;
  208. };
  209. typedef CUtlVector<BotPhrase *> BotPhraseList;
  210. inline void BotPhrase::ClearCriteria( void ) const
  211. {
  212. m_placeCriteria = ANY_PLACE;
  213. m_countCriteria = UNDEFINED_COUNT;
  214. }
  215. inline void BotPhrase::SetPlaceCriteria( PlaceCriteria place ) const
  216. {
  217. m_placeCriteria = place;
  218. }
  219. inline void BotPhrase::SetCountCriteria( CountCriteria count ) const
  220. {
  221. m_countCriteria = count;
  222. }
  223. inline void BotPhrase::SetCriteriaSet( AI_CriteriaSet &criteria ) const
  224. {
  225. m_contexts.Reset();
  226. m_contexts.Merge( &criteria );
  227. }
  228. enum BotChatterOutputType
  229. {
  230. BOT_CHATTER_RADIO,
  231. BOT_CHATTER_VOICE
  232. };
  233. typedef CUtlVector<BotChatterOutputType> BotOutputList;
  234. //----------------------------------------------------------------------------------------------------
  235. /**
  236. * The BotPhraseManager is a singleton that provides an interface to all BotPhrase collections
  237. */
  238. class BotPhraseManager
  239. {
  240. public:
  241. BotPhraseManager( void );
  242. ~BotPhraseManager();
  243. bool Initialize( const char *filename, int bankIndex ); ///< initialize phrase system from database file for a specific voice bank (0 is the default voice bank)
  244. void OnRoundRestart( void ); ///< invoked when round resets
  245. void OnMapChange( void ); ///< invoked when map changes
  246. void Reset( void );
  247. const BotPhrase *GetPhrase( const char *name ) const; ///< given a name, return the associated phrase collection
  248. const BotPhrase *GetPainPhrase( void ) const { return m_painPhrase; } ///< optimization, replaces a static pointer to the phrase
  249. const BotPhrase *GetAgreeWithPlanPhrase( void ) const { return m_agreeWithPlanPhrase; } ///< optimization, replaces a static pointer to the phrase
  250. const BotPhrase *GetPlace( const char *name ) const; ///< given a name, return the associated Place phrase collection
  251. const BotPhrase *GetPlace( unsigned int id ) const; ///< given an id, return the associated Place phrase collection
  252. const BotPhraseList *GetPlaceList( void ) const { return &m_placeList; }
  253. float GetPlaceStatementInterval( Place where ) const; ///< return time last statement of given type was emitted by a teammate for the given place
  254. void ResetPlaceStatementInterval( Place where ); ///< set time of last statement of given type was emitted by a teammate for the given place
  255. BotChatterOutputType GetOutputType( int voiceBank ) const;
  256. private:
  257. BotPhraseList m_list; ///< master list of all phrase collections
  258. BotPhraseList m_placeList; ///< master list of all Place phrases
  259. BotOutputList m_output;
  260. const BotPhrase *m_painPhrase;
  261. const BotPhrase *m_agreeWithPlanPhrase;
  262. struct PlaceTimeInfo
  263. {
  264. Place placeID;
  265. IntervalTimer timer;
  266. };
  267. mutable PlaceTimeInfo m_placeStatementHistory[ MAX_PLACES_PER_MAP ];
  268. mutable int m_placeCount;
  269. int FindPlaceIndex( Place where ) const;
  270. };
  271. inline int BotPhraseManager::FindPlaceIndex( Place where ) const
  272. {
  273. for( int i=0; i<m_placeCount; ++i )
  274. if (m_placeStatementHistory[i].placeID == where)
  275. return i;
  276. // no such place - allocate it
  277. if (m_placeCount < MAX_PLACES_PER_MAP)
  278. {
  279. m_placeStatementHistory[ m_placeCount ].placeID = where;
  280. m_placeStatementHistory[ m_placeCount ].timer.Invalidate();
  281. ++m_placeCount;
  282. return m_placeCount-1;
  283. }
  284. // place directory is full
  285. return -1;
  286. }
  287. /**
  288. * Return time last statement of given type was emitted by a teammate for the given place
  289. */
  290. inline float BotPhraseManager::GetPlaceStatementInterval( Place place ) const
  291. {
  292. int index = FindPlaceIndex( place );
  293. if (index < 0)
  294. return 999999.9f;
  295. if (index >= m_placeCount)
  296. return 999999.9f;
  297. return m_placeStatementHistory[ index ].timer.GetElapsedTime();
  298. }
  299. /**
  300. * Set time of last statement of given type was emitted by a teammate for the given place
  301. */
  302. inline void BotPhraseManager::ResetPlaceStatementInterval( Place place )
  303. {
  304. int index = FindPlaceIndex( place );
  305. if (index < 0)
  306. return;
  307. if (index >= m_placeCount)
  308. return;
  309. // update entry
  310. m_placeStatementHistory[ index ].timer.Reset();
  311. }
  312. extern BotPhraseManager *TheBotPhrases;
  313. //----------------------------------------------------------------------------------------------------
  314. /**
  315. * Statements are meaningful collections of phrases
  316. */
  317. class BotStatement
  318. {
  319. public:
  320. BotStatement( BotChatterInterface *chatter, BotStatementType type, float expireDuration );
  321. ~BotStatement();
  322. BotChatterInterface *GetChatter( void ) const { return m_chatter; }
  323. CCSBot *GetOwner( void ) const;
  324. BotStatementType GetType( void ) const { return m_type; } ///< return the type of statement this is
  325. bool IsImportant( void ) const; ///< return true if this statement is "important" and not personality chatter
  326. bool HasSubject( void ) const { return (m_subject == UNDEFINED_SUBJECT) ? false : true; }
  327. void SetSubject( int playerID ) { m_subject = playerID; } ///< who this statement is about
  328. int GetSubject( void ) const { return m_subject; } ///< who this statement is about
  329. bool HasPlace( void ) const { return (GetPlace()) ? true : false; }
  330. Place GetPlace( void ) const; ///< if this statement refers to a specific place, return that place
  331. void SetPlace( Place where ) { m_place = where; } ///< explicitly set place
  332. bool HasCount( void ) const; ///< return true if this statement has an associated count
  333. bool IsRedundant( const BotStatement *say ) const; ///< return true if this statement is the same as the given one
  334. bool IsObsolete( void ) const; ///< return true if this statement is no longer appropriate to say
  335. void Convert( const BotStatement *say ); ///< possibly change what were going to say base on what teammate is saying
  336. void AppendPhrase( const BotPhrase *phrase );
  337. void SetStartTime( float timestamp ) { m_startTime = timestamp; } ///< define the earliest time this statement can be spoken
  338. float GetStartTime( void ) const { return m_startTime; }
  339. enum ConditionType
  340. {
  341. IS_IN_COMBAT,
  342. RADIO_SILENCE,
  343. ENEMIES_REMAINING,
  344. NUM_CONDITIONS
  345. };
  346. void AddCondition( ConditionType condition ); ///< conditions must be true for the statement to be spoken
  347. bool IsValid( void ) const; ///< verify all attached conditions
  348. enum ContextType
  349. {
  350. CURRENT_ENEMY_COUNT,
  351. REMAINING_ENEMY_COUNT,
  352. SHORT_DELAY,
  353. LONG_DELAY,
  354. ACCUMULATE_ENEMIES_DELAY
  355. };
  356. void AppendPhrase( ContextType contextPhrase ); ///< special phrases that depend on the context
  357. bool Update( void ); ///< emit statement over time, return false if statement is done
  358. bool IsSpeaking( void ) const { return m_isSpeaking; } ///< return true if this statement is currently being spoken
  359. float GetTimestamp( void ) const { return m_timestamp; } ///< get time statement was created (but not necessarily started talking)
  360. void AttachMeme( BotMeme *meme ); ///< attach a meme to this statement, to be transmitted to other friendly bots when spoken
  361. private:
  362. friend class BotChatterInterface;
  363. BotChatterInterface *m_chatter; ///< the chatter system this statement is part of
  364. BotStatement *m_next, *m_prev; ///< linked list hooks
  365. BotStatementType m_type; ///< what kind of statement this is
  366. int m_subject; ///< who this subject is about
  367. Place m_place; ///< explicit place - note some phrases have implicit places as well
  368. BotMeme *m_meme; ///< a statement can only have a single meme for now
  369. float m_timestamp; ///< time when message was created
  370. float m_startTime; ///< the earliest time this statement can be spoken
  371. float m_expireTime; ///< time when this statement is no longer valid
  372. float m_speakTimestamp; ///< time when message began being spoken
  373. bool m_isSpeaking; ///< true if this statement is current being spoken
  374. float m_nextTime; ///< time for next phrase to begin
  375. enum { MAX_BOT_PHRASES = 4 };
  376. struct
  377. {
  378. bool isPhrase;
  379. union
  380. {
  381. const BotPhrase *phrase;
  382. ContextType context;
  383. };
  384. }
  385. m_statement[ MAX_BOT_PHRASES ];
  386. enum { MAX_BOT_CONDITIONS = 4 };
  387. ConditionType m_condition[ MAX_BOT_CONDITIONS ]; ///< conditions that must be true for the statement to be said
  388. int m_conditionCount;
  389. int m_index; ///< m_index refers to the phrase currently being spoken, or -1 if we havent started yet
  390. int m_count;
  391. };
  392. //----------------------------------------------------------------------------------------------------
  393. /**
  394. * This class defines the interface to the bot radio chatter system
  395. */
  396. class BotChatterInterface
  397. {
  398. public:
  399. BotChatterInterface( CCSBot *me );
  400. virtual ~BotChatterInterface();
  401. void Reset( void ); ///< reset to initial state
  402. void Update( void ); ///< process ongoing chatter
  403. /// invoked when event occurs in the game (some events have NULL entities)
  404. void OnDeath( void ); ///< invoked when we die
  405. enum VerbosityType
  406. {
  407. NORMAL, ///< full chatter
  408. MINIMAL, ///< only scenario-critical events
  409. RADIO, ///< use the standard radio instead
  410. OFF ///< no chatter at all
  411. };
  412. VerbosityType GetVerbosity( void ) const; ///< return our current level of verbosity
  413. CCSBot *GetOwner( void ) const { return m_me; }
  414. bool IsTalking( void ) const; ///< return true if we are currently talking
  415. float GetRadioSilenceDuration( void ); ///< return time since any teammate said anything
  416. void ResetRadioSilenceDuration( void );
  417. enum { MUST_ADD = 1 };
  418. void AddStatement( BotStatement *statement, bool mustAdd = false ); ///< register a statement for speaking
  419. void RemoveStatement( BotStatement *statement ); ///< remove a statement
  420. BotStatement *GetActiveStatement( void ); ///< returns the statement that is being spoken, or is next to be spoken if no-one is speaking now
  421. BotStatement *GetStatement( void ) const; ///< returns our current statement, or NULL if we aren't speaking
  422. int GetPitch( void ) const { return m_pitch; }
  423. //-- things the bots can say ---------------------------------------------------------------------
  424. void Say( const char *phraseName, float lifetime = 3.0f, float delay = 0.0f );
  425. void AnnouncePlan( const char *phraseName, Place where );
  426. void Affirmative( void );
  427. void Negative( void );
  428. virtual void EnemySpotted( void ); ///< report enemy sightings
  429. virtual void KilledMyEnemy( int victimID );
  430. virtual void EnemiesRemaining( void );
  431. void SpottedSniper( void );
  432. void FriendSpottedSniper( void );
  433. void Clear( Place where );
  434. void ReportIn( void ); ///< ask for current situation
  435. void ReportingIn( void ); ///< report current situation
  436. virtual bool NeedBackup( void );
  437. void PinnedDown( void );
  438. void Scared( void );
  439. void HeardNoise( const Vector &pos );
  440. void FriendHeardNoise( void );
  441. void TheyPickedUpTheBomb( void );
  442. void GoingToPlantTheBomb( Place where );
  443. void BombsiteClear( int zoneIndex );
  444. void FoundPlantedBomb( int zoneIndex );
  445. void PlantingTheBomb( Place where );
  446. void SpottedBomber( CBasePlayer *bomber );
  447. void SpottedLooseBomb( CBaseEntity *bomb );
  448. void GuardingLooseBomb( CBaseEntity *bomb );
  449. void RequestBombLocation( void );
  450. #define IS_PLAN true
  451. void GuardingHostages( Place where, bool isPlan = false );
  452. void GuardingHostageEscapeZone( bool isPlan = false );
  453. void HostagesBeingTaken( void );
  454. void HostagesTaken( void );
  455. void TalkingToHostages( void );
  456. void EscortingHostages( void );
  457. void HostageDown( void );
  458. void GuardingBombsite( Place where );
  459. virtual void CelebrateWin( void );
  460. void Encourage( const char *phraseName, float repeatInterval = 10.0f, float lifetime = 3.0f ); ///< "encourage" the player to do the scenario
  461. void KilledFriend( void );
  462. void FriendlyFire( const char *pDmgType );
  463. void DoPhoenixHeavyWakeTaunt( void );
  464. bool SeesAtLeastOneEnemy( void ) const { return m_seeAtLeastOneEnemy; }
  465. private:
  466. BotStatement *m_statementList; ///< list of all active/pending messages for this bot
  467. void ReportEnemies( void ); ///< track nearby enemy count and generate enemy activity statements
  468. bool ShouldSpeak( void ) const; ///< return true if we speaking makes sense now
  469. CCSBot *m_me; ///< the bot this chatter is for
  470. bool m_seeAtLeastOneEnemy;
  471. float m_timeWhenSawFirstEnemy;
  472. bool m_reportedEnemies;
  473. bool m_requestedBombLocation; ///< true if we already asked where the bomb has been planted
  474. int m_pitch;
  475. static IntervalTimer m_radioSilenceInterval[ 2 ]; ///< one timer for each team
  476. IntervalTimer m_needBackupInterval;
  477. IntervalTimer m_spottedBomberInterval;
  478. IntervalTimer m_scaredInterval;
  479. IntervalTimer m_planInterval;
  480. CountdownTimer m_spottedLooseBombTimer;
  481. CountdownTimer m_heardNoiseTimer;
  482. CountdownTimer m_escortingHostageTimer;
  483. CountdownTimer m_warnSniperTimer;
  484. static CountdownTimer m_encourageTimer; ///< timer to know when we can "encourage" the human player again - shared by all bots
  485. CountdownTimer m_heavyTauntTimer;
  486. };
  487. inline BotChatterInterface::VerbosityType BotChatterInterface::GetVerbosity( void ) const
  488. {
  489. const char *string = cv_bot_chatter.GetString();
  490. if (string == NULL)
  491. return NORMAL;
  492. if (string[0] == 'm' || string[0] == 'M')
  493. return MINIMAL;
  494. if (string[0] == 'r' || string[0] == 'R')
  495. return RADIO;
  496. if (string[0] == 'o' || string[0] == 'O')
  497. return OFF;
  498. return NORMAL;
  499. }
  500. inline bool BotChatterInterface::IsTalking( void ) const
  501. {
  502. if (m_statementList)
  503. return m_statementList->IsSpeaking();
  504. return false;
  505. }
  506. inline BotStatement *BotChatterInterface::GetStatement( void ) const
  507. {
  508. return m_statementList;
  509. }
  510. inline void BotChatterInterface::Say( const char *phraseName, float lifetime, float delay )
  511. {
  512. BotStatement *say = new BotStatement( this, REPORT_MY_INTENTION, lifetime );
  513. say->AppendPhrase( TheBotPhrases->GetPhrase( phraseName ) );
  514. if (delay > 0.0f)
  515. say->SetStartTime( gpGlobals->curtime + delay );
  516. AddStatement( say );
  517. }
  518. // In player vs bot game modes, have the bots chatter about what they're doing to the players
  519. class BotChatterCoop : public BotChatterInterface
  520. {
  521. typedef BotChatterInterface BaseClass;
  522. public:
  523. BotChatterCoop( CCSBot *me );
  524. virtual void KilledMyEnemy( int nVictimID ) OVERRIDE;
  525. virtual void EnemiesRemaining( void ) OVERRIDE;
  526. virtual void CelebrateWin( void ) OVERRIDE;
  527. virtual void EnemySpotted( void ) OVERRIDE;
  528. };
  529. #endif // CS_BOT_CHATTER_H