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.

1973 lines
58 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef AI_BEHAVIOR_H
  8. #define AI_BEHAVIOR_H
  9. #include "ai_component.h"
  10. #include "ai_basenpc.h"
  11. #include "ai_default.h"
  12. #include "AI_Criteria.h"
  13. #include "networkvar.h"
  14. #ifdef DEBUG
  15. #pragma warning(push)
  16. #include <typeinfo>
  17. #pragma warning(pop)
  18. #pragma warning(disable:4290)
  19. #endif
  20. #if defined( _WIN32 )
  21. #pragma once
  22. #endif
  23. //-----------------------------------------------------------------------------
  24. // CAI_Behavior...
  25. //
  26. // Purpose: The core component that defines a behavior in an NPC by selecting
  27. // schedules and running tasks
  28. //
  29. // Intended to be used as an organizational tool as well as a way
  30. // for various NPCs to share behaviors without sharing an inheritance
  31. // relationship, and without cramming those behaviors into the base
  32. // NPC class.
  33. //-----------------------------------------------------------------------------
  34. //-----------------------------------------------------------------------------
  35. // Purpose: Base class defines interface to behaviors and provides bridging
  36. // methods
  37. //-----------------------------------------------------------------------------
  38. class IBehaviorBackBridge;
  39. //-------------------------------------
  40. abstract_class CAI_BehaviorBase : public CAI_Component
  41. {
  42. DECLARE_CLASS( CAI_BehaviorBase, CAI_Component )
  43. public:
  44. CAI_BehaviorBase(CAI_BaseNPC *pOuter = NULL)
  45. : CAI_Component(pOuter),
  46. m_pBackBridge(NULL)
  47. {
  48. }
  49. virtual const char *GetName() = 0;
  50. virtual bool KeyValue( const char *szKeyName, const char *szValue )
  51. {
  52. return false;
  53. }
  54. bool IsRunning() { Assert( GetOuter() ); return ( GetOuter()->GetRunningBehavior() == this ); }
  55. virtual bool CanSelectSchedule() { return true; }
  56. virtual void BeginScheduleSelection() {}
  57. virtual void EndScheduleSelection() {}
  58. void SetBackBridge( IBehaviorBackBridge *pBackBridge )
  59. {
  60. Assert( m_pBackBridge == NULL || pBackBridge == NULL );
  61. m_pBackBridge = pBackBridge;
  62. }
  63. void BridgePrecache() { Precache(); }
  64. void BridgeSpawn() { Spawn(); }
  65. void BridgeUpdateOnRemove() { UpdateOnRemove(); }
  66. void BridgeEvent_Killed( const CTakeDamageInfo &info ) { Event_Killed( info ); }
  67. void BridgeCleanupOnDeath( CBaseEntity *pCulprit, bool bFireDeathOutput ) { CleanupOnDeath( pCulprit, bFireDeathOutput ); }
  68. void BridgeOnChangeHintGroup( string_t oldGroup, string_t newGroup ) { OnChangeHintGroup( oldGroup, newGroup ); }
  69. void BridgeGatherConditions() { GatherConditions(); }
  70. void BridgePrescheduleThink() { PrescheduleThink(); }
  71. void BridgeOnScheduleChange() { OnScheduleChange(); }
  72. void BridgeOnStartSchedule( int scheduleType );
  73. int BridgeSelectSchedule();
  74. bool BridgeSelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode, int *pResult );
  75. bool BridgeStartTask( const Task_t *pTask );
  76. bool BridgeRunTask( const Task_t *pTask);
  77. bool BridgeAimGun( void );
  78. int BridgeTranslateSchedule( int scheduleType );
  79. bool BridgeGetSchedule( int localScheduleID, CAI_Schedule **ppResult );
  80. bool BridgeTaskName(int taskID, const char **);
  81. Activity BridgeNPC_TranslateActivity( Activity activity );
  82. void BridgeBuildScheduleTestBits() { BuildScheduleTestBits(); }
  83. bool BridgeIsCurTaskContinuousMove( bool *pResult );
  84. void BridgeOnMovementFailed() { OnMovementFailed(); }
  85. void BridgeOnMovementComplete() { OnMovementComplete(); }
  86. float BridgeGetDefaultNavGoalTolerance();
  87. bool BridgeFValidateHintType( CAI_Hint *pHint, bool *pResult );
  88. bool BridgeIsValidEnemy( CBaseEntity *pEnemy );
  89. CBaseEntity *BridgeBestEnemy();
  90. bool BridgeIsValidCover( const Vector &vLocation, CAI_Hint const *pHint );
  91. bool BridgeIsValidShootPosition( const Vector &vLocation, CAI_Node *pNode, CAI_Hint const *pHint );
  92. float BridgeGetMaxTacticalLateralMovement( void );
  93. bool BridgeShouldIgnoreSound( CSound *pSound );
  94. void BridgeOnSeeEntity( CBaseEntity *pEntity );
  95. void BridgeOnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker );
  96. bool BridgeIsInterruptable( void );
  97. bool BridgeIsNavigationUrgent( void );
  98. bool BridgeShouldPlayerAvoid( void );
  99. int BridgeOnTakeDamage_Alive( const CTakeDamageInfo &info );
  100. float BridgeGetReasonableFacingDist( void );
  101. bool BridgeShouldAlwaysThink( bool *pResult );
  102. void BridgeOnChangeActiveWeapon( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon );
  103. void BridgeOnRestore();
  104. virtual bool BridgeSpeakMapmakerInterruptConcept( string_t iszConcept );
  105. bool BridgeCanFlinch( void );
  106. bool BridgeIsCrouching( void );
  107. bool BridgeIsCrouchedActivity( Activity activity );
  108. bool BridgeQueryHearSound( CSound *pSound );
  109. bool BridgeCanRunAScriptedNPCInteraction( bool bForced );
  110. Activity BridgeGetFlinchActivity( bool bHeavyDamage, bool bGesture );
  111. bool BridgeOnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult );
  112. void BridgeModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet );
  113. void BridgeTeleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity );
  114. void BridgeHandleAnimEvent( animevent_t *pEvent );
  115. virtual void GatherConditions();
  116. virtual void GatherConditionsNotActive() { return; } // Override this and your behavior will call this in place of GatherConditions() when your behavior is NOT the active one.
  117. virtual void OnUpdateShotRegulator() {}
  118. virtual CAI_ClassScheduleIdSpace *GetClassScheduleIdSpace();
  119. virtual int DrawDebugTextOverlays( int text_offset );
  120. virtual int Save( ISave &save );
  121. virtual int Restore( IRestore &restore );
  122. static void SaveBehaviors(ISave &save, CAI_BehaviorBase *pCurrentBehavior, CAI_BehaviorBase **ppBehavior, int nBehaviors );
  123. static int RestoreBehaviors(IRestore &restore, CAI_BehaviorBase **ppBehavior, int nBehaviors ); // returns index of "current" behavior, or -1
  124. protected:
  125. int GetNpcState() { return GetOuter()->m_NPCState; }
  126. virtual void Precache() {}
  127. virtual void Spawn() {}
  128. virtual void UpdateOnRemove() {}
  129. virtual void Event_Killed( const CTakeDamageInfo &info ) {}
  130. virtual void CleanupOnDeath( CBaseEntity *pCulprit, bool bFireDeathOutput ) {}
  131. virtual void PrescheduleThink();
  132. virtual void OnScheduleChange();
  133. virtual void OnStartSchedule( int scheduleType );
  134. virtual int SelectSchedule();
  135. virtual int SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode );
  136. virtual void StartTask( const Task_t *pTask );
  137. virtual void RunTask( const Task_t *pTask );
  138. virtual void AimGun( void );
  139. virtual int TranslateSchedule( int scheduleType );
  140. virtual CAI_Schedule *GetSchedule(int schedule);
  141. virtual const char *GetSchedulingErrorName();
  142. virtual void BuildScheduleTestBits() {}
  143. bool IsCurSchedule( int schedId, bool fIdeal = true );
  144. CAI_Hint * GetHintNode() { return GetOuter()->GetHintNode(); }
  145. const CAI_Hint *GetHintNode() const { return GetOuter()->GetHintNode(); }
  146. void SetHintNode( CAI_Hint *pHintNode ) { GetOuter()->SetHintNode( pHintNode ); }
  147. void ClearHintNode( float reuseDelay = 0.0 ) { GetOuter()->ClearHintNode( reuseDelay ); }
  148. protected:
  149. // Used by derived classes to chain a task to a task that might not be the
  150. // one they are currently handling:
  151. void ChainStartTask( int task, float taskData = 0 );
  152. void ChainRunTask( int task, float taskData = 0 );
  153. protected:
  154. virtual Activity NPC_TranslateActivity( Activity activity );
  155. virtual bool IsCurTaskContinuousMove();
  156. virtual void OnMovementFailed() {};
  157. virtual void OnMovementComplete() {};
  158. virtual float GetDefaultNavGoalTolerance();
  159. virtual bool FValidateHintType( CAI_Hint *pHint );
  160. virtual bool IsValidEnemy( CBaseEntity *pEnemy );
  161. virtual CBaseEntity *BestEnemy();
  162. virtual bool IsValidCover( const Vector &vLocation, CAI_Hint const *pHint );
  163. virtual bool IsValidShootPosition( const Vector &vLocation, CAI_Node *pNode, CAI_Hint const *pHint );
  164. virtual float GetMaxTacticalLateralMovement( void );
  165. virtual bool ShouldIgnoreSound( CSound *pSound );
  166. virtual void OnSeeEntity( CBaseEntity *pEntity );
  167. virtual void OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker );
  168. virtual bool IsInterruptable( void );
  169. virtual bool IsNavigationUrgent( void );
  170. virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info );
  171. virtual float GetReasonableFacingDist( void );
  172. virtual bool ShouldPlayerAvoid( void );
  173. virtual bool CanFlinch( void );
  174. virtual bool IsCrouching( void );
  175. virtual bool IsCrouchedActivity( Activity activity );
  176. virtual bool QueryHearSound( CSound *pSound );
  177. virtual bool CanRunAScriptedNPCInteraction( bool bForced );
  178. virtual Activity GetFlinchActivity( bool bHeavyDamage, bool bGesture );
  179. virtual bool OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult );
  180. virtual void ModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet );
  181. virtual void Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity );
  182. virtual void HandleAnimEvent( animevent_t *pEvent );
  183. virtual bool ShouldAlwaysThink();
  184. virtual void OnChangeActiveWeapon( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon ) {};
  185. virtual bool SpeakMapmakerInterruptConcept( string_t iszConcept ) { return false; };
  186. virtual void OnRestore() {};
  187. bool NotifyChangeBehaviorStatus( bool fCanFinishSchedule = false );
  188. bool HaveSequenceForActivity( Activity activity ) { return GetOuter()->HaveSequenceForActivity( activity ); }
  189. //---------------------------------
  190. string_t GetHintGroup() { return GetOuter()->GetHintGroup(); }
  191. void ClearHintGroup() { GetOuter()->ClearHintGroup(); }
  192. void SetHintGroup( string_t name ) { GetOuter()->SetHintGroup( name ); }
  193. virtual void OnChangeHintGroup( string_t oldGroup, string_t newGroup ) {}
  194. //
  195. // These allow derived classes to implement custom schedules
  196. //
  197. static CAI_GlobalScheduleNamespace *GetSchedulingSymbols() { return CAI_BaseNPC::GetSchedulingSymbols(); }
  198. static bool LoadSchedules() { return true; }
  199. virtual bool IsBehaviorSchedule( int scheduleType ) { return false; }
  200. CAI_Navigator * GetNavigator() { return GetOuter()->GetNavigator(); }
  201. CAI_Motor * GetMotor() { return GetOuter()->GetMotor(); }
  202. CAI_TacticalServices * GetTacticalServices() { return GetOuter()->GetTacticalServices(); }
  203. bool m_fOverrode;
  204. IBehaviorBackBridge *m_pBackBridge;
  205. DECLARE_DATADESC();
  206. };
  207. //-----------------------------------------------------------------------------
  208. // Purpose: Template provides provides back bridge to owning class and
  209. // establishes namespace settings
  210. //-----------------------------------------------------------------------------
  211. template <class NPC_CLASS = CAI_BaseNPC, const int ID_SPACE_OFFSET = 100000>
  212. class CAI_Behavior : public CAI_ComponentWithOuter<NPC_CLASS, CAI_BehaviorBase>
  213. {
  214. public:
  215. DECLARE_CLASS_NOFRIEND( CAI_Behavior, NPC_CLASS );
  216. enum
  217. {
  218. NEXT_TASK = ID_SPACE_OFFSET,
  219. NEXT_SCHEDULE = ID_SPACE_OFFSET,
  220. NEXT_CONDITION = ID_SPACE_OFFSET
  221. };
  222. void SetCondition( int condition )
  223. {
  224. if ( condition >= ID_SPACE_OFFSET && condition < ID_SPACE_OFFSET + 10000 ) // it's local to us
  225. condition = GetClassScheduleIdSpace()->ConditionLocalToGlobal( condition );
  226. this->GetOuter()->SetCondition( condition );
  227. }
  228. bool HasCondition( int condition )
  229. {
  230. if ( condition >= ID_SPACE_OFFSET && condition < ID_SPACE_OFFSET + 10000 ) // it's local to us
  231. condition = GetClassScheduleIdSpace()->ConditionLocalToGlobal( condition );
  232. return this->GetOuter()->HasCondition( condition );
  233. }
  234. bool HasInterruptCondition( int condition )
  235. {
  236. if ( condition >= ID_SPACE_OFFSET && condition < ID_SPACE_OFFSET + 10000 ) // it's local to us
  237. condition = GetClassScheduleIdSpace()->ConditionLocalToGlobal( condition );
  238. return this->GetOuter()->HasInterruptCondition( condition );
  239. }
  240. void ClearCondition( int condition )
  241. {
  242. if ( condition >= ID_SPACE_OFFSET && condition < ID_SPACE_OFFSET + 10000 ) // it's local to us
  243. condition = GetClassScheduleIdSpace()->ConditionLocalToGlobal( condition );
  244. this->GetOuter()->ClearCondition( condition );
  245. }
  246. protected:
  247. CAI_Behavior(NPC_CLASS *pOuter = NULL)
  248. : CAI_ComponentWithOuter<NPC_CLASS, CAI_BehaviorBase>(pOuter)
  249. {
  250. }
  251. static CAI_GlobalScheduleNamespace *GetSchedulingSymbols()
  252. {
  253. return NPC_CLASS::GetSchedulingSymbols();
  254. }
  255. virtual CAI_ClassScheduleIdSpace *GetClassScheduleIdSpace()
  256. {
  257. return this->GetOuter()->GetClassScheduleIdSpace();
  258. }
  259. static CAI_ClassScheduleIdSpace &AccessClassScheduleIdSpaceDirect()
  260. {
  261. return NPC_CLASS::AccessClassScheduleIdSpaceDirect();
  262. }
  263. private:
  264. virtual bool IsBehaviorSchedule( int scheduleType ) { return ( scheduleType >= ID_SPACE_OFFSET && scheduleType < ID_SPACE_OFFSET + 10000 ); }
  265. };
  266. //-----------------------------------------------------------------------------
  267. // Purpose: Some bridges a little more complicated to allow behavior to see
  268. // what base class would do or control order in which it's donw
  269. //-----------------------------------------------------------------------------
  270. abstract_class IBehaviorBackBridge
  271. {
  272. public:
  273. virtual void BackBridge_GatherConditions() = 0;
  274. virtual int BackBridge_SelectSchedule() = 0;
  275. virtual int BackBridge_TranslateSchedule( int scheduleType ) = 0;
  276. virtual Activity BackBridge_NPC_TranslateActivity( Activity activity ) = 0;
  277. virtual bool BackBridge_IsValidEnemy(CBaseEntity *pEnemy) = 0;
  278. virtual CBaseEntity* BackBridge_BestEnemy(void) = 0;
  279. virtual bool BackBridge_IsValidCover( const Vector &vLocation, CAI_Hint const *pHint ) = 0;
  280. virtual bool BackBridge_IsValidShootPosition( const Vector &vLocation, CAI_Node *pNode, CAI_Hint const *pHint ) = 0;
  281. virtual float BackBridge_GetMaxTacticalLateralMovement( void ) = 0;
  282. virtual bool BackBridge_ShouldIgnoreSound( CSound *pSound ) = 0;
  283. virtual void BackBridge_OnSeeEntity( CBaseEntity *pEntity ) = 0;
  284. virtual void BackBridge_OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker ) = 0;
  285. virtual bool BackBridge_IsInterruptable( void ) = 0;
  286. virtual bool BackBridge_IsNavigationUrgent( void ) = 0;
  287. virtual bool BackBridge_ShouldPlayerAvoid( void ) = 0;
  288. virtual int BackBridge_OnTakeDamage_Alive( const CTakeDamageInfo &info ) = 0;
  289. virtual float BackBridge_GetDefaultNavGoalTolerance() = 0;
  290. virtual float BackBridge_GetReasonableFacingDist( void ) = 0;
  291. virtual bool BackBridge_CanFlinch( void ) = 0;
  292. virtual bool BackBridge_IsCrouching( void ) = 0;
  293. virtual bool BackBridge_IsCrouchedActivity( Activity activity ) = 0;
  294. virtual bool BackBridge_QueryHearSound( CSound *pSound ) = 0;
  295. virtual bool BackBridge_CanRunAScriptedNPCInteraction( bool bForced ) = 0;
  296. virtual Activity BackBridge_GetFlinchActivity( bool bHeavyDamage, bool bGesture ) = 0;
  297. virtual bool BackBridge_OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult ) = 0;
  298. virtual void BackBridge_ModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet ) = 0;
  299. virtual void BackBridge_Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity ) = 0;
  300. virtual void BackBridge_HandleAnimEvent( animevent_t *pEvent ) = 0;
  301. //-------------------------------------
  302. };
  303. //-----------------------------------------------------------------------------
  304. // Purpose: The common instantiation of the above template
  305. //-----------------------------------------------------------------------------
  306. typedef CAI_Behavior<> CAI_SimpleBehavior;
  307. //-----------------------------------------------------------------------------
  308. // Purpose: Base class for AIs that want to act as a host for CAI_Behaviors
  309. // NPCs aren't required to use this, but probably want to.
  310. //-----------------------------------------------------------------------------
  311. template <class BASE_NPC>
  312. class CAI_BehaviorHost : public BASE_NPC,
  313. private IBehaviorBackBridge
  314. {
  315. public:
  316. DECLARE_CLASS_NOFRIEND( CAI_BehaviorHost, BASE_NPC );
  317. CAI_BehaviorHost()
  318. : m_pCurBehavior(NULL)
  319. {
  320. #ifdef DEBUG
  321. m_fDebugInCreateBehaviors = false;
  322. #endif
  323. }
  324. void CleanupOnDeath( CBaseEntity *pCulprit = NULL, bool bFireDeathOutput = true );
  325. virtual int Save( ISave &save );
  326. virtual int Restore( IRestore &restore );
  327. virtual bool CreateComponents();
  328. // Automatically called during entity construction, derived class calls AddBehavior()
  329. virtual bool CreateBehaviors() { return true; }
  330. // forces movement and sets a new schedule
  331. virtual bool ScheduledMoveToGoalEntity( int scheduleType, CBaseEntity *pGoalEntity, Activity movementActivity );
  332. virtual bool ScheduledFollowPath( int scheduleType, CBaseEntity *pPathStart, Activity movementActivity );
  333. virtual void ForceSelectedGo(CBaseEntity *pPlayer, const Vector &targetPos, const Vector &traceDir, bool bRun);
  334. virtual void ForceSelectedGoRandom(void);
  335. // Bridges
  336. void Precache();
  337. void NPCInit();
  338. void UpdateOnRemove();
  339. void Event_Killed( const CTakeDamageInfo &info );
  340. void GatherConditions();
  341. void PrescheduleThink();
  342. int SelectSchedule();
  343. void KeepRunningBehavior();
  344. int SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode );
  345. void OnScheduleChange();
  346. void OnStartSchedule( int scheduleType );
  347. int TranslateSchedule( int scheduleType );
  348. void StartTask( const Task_t *pTask );
  349. void RunTask( const Task_t *pTask );
  350. void AimGun( void );
  351. CAI_Schedule * GetSchedule(int localScheduleID);
  352. const char * TaskName(int taskID);
  353. void BuildScheduleTestBits();
  354. void OnChangeHintGroup( string_t oldGroup, string_t newGroup );
  355. Activity NPC_TranslateActivity( Activity activity );
  356. bool IsCurTaskContinuousMove();
  357. void OnMovementFailed();
  358. void OnMovementComplete();
  359. bool FValidateHintType( CAI_Hint *pHint );
  360. float GetDefaultNavGoalTolerance();
  361. bool IsValidEnemy(CBaseEntity *pEnemy);
  362. CBaseEntity* BestEnemy(void);
  363. bool IsValidCover( const Vector &vLocation, CAI_Hint const *pHint );
  364. bool IsValidShootPosition( const Vector &vLocation, CAI_Node *pNode, CAI_Hint const *pHint );
  365. float GetMaxTacticalLateralMovement( void );
  366. bool ShouldIgnoreSound( CSound *pSound );
  367. void OnSeeEntity( CBaseEntity *pEntity );
  368. void OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker );
  369. bool IsInterruptable( void );
  370. bool IsNavigationUrgent( void );
  371. bool ShouldPlayerAvoid( void );
  372. int OnTakeDamage_Alive( const CTakeDamageInfo &info );
  373. float GetReasonableFacingDist( void );
  374. bool CanFlinch( void );
  375. bool IsCrouching( void );
  376. bool IsCrouchedActivity( Activity activity );
  377. bool QueryHearSound( CSound *pSound );
  378. bool CanRunAScriptedNPCInteraction( bool bForced );
  379. Activity GetFlinchActivity( bool bHeavyDamage, bool bGesture );
  380. bool OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult );
  381. void HandleAnimEvent( animevent_t *pEvent );
  382. bool ShouldAlwaysThink();
  383. void OnChangeActiveWeapon( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon );
  384. virtual bool SpeakMapmakerInterruptConcept( string_t iszConcept );
  385. void OnRestore();
  386. void ModifyOrAppendCriteria( AI_CriteriaSet& set );
  387. void Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity );
  388. //---------------------------------
  389. virtual bool OnBehaviorChangeStatus( CAI_BehaviorBase *pBehavior, bool fCanFinishSchedule );
  390. virtual void OnChangeRunningBehavior( CAI_BehaviorBase *pOldBehavior, CAI_BehaviorBase *pNewBehavior );
  391. protected:
  392. void AddBehavior( CAI_BehaviorBase *pBehavior );
  393. bool BehaviorSelectSchedule();
  394. virtual bool ShouldBehaviorSelectSchedule( CAI_BehaviorBase *pBehavior ) { return true; }
  395. bool IsRunningBehavior() const;
  396. CAI_BehaviorBase *GetRunningBehavior();
  397. CAI_BehaviorBase *DeferSchedulingToBehavior( CAI_BehaviorBase *pNewBehavior );
  398. void ChangeBehaviorTo( CAI_BehaviorBase *pNewBehavior );
  399. CAI_Schedule * GetNewSchedule();
  400. CAI_Schedule * GetFailSchedule();
  401. private:
  402. void BackBridge_GatherConditions();
  403. int BackBridge_SelectSchedule();
  404. int BackBridge_TranslateSchedule( int scheduleType );
  405. Activity BackBridge_NPC_TranslateActivity( Activity activity );
  406. bool BackBridge_IsValidEnemy(CBaseEntity *pEnemy);
  407. CBaseEntity* BackBridge_BestEnemy(void);
  408. bool BackBridge_IsValidCover( const Vector &vLocation, CAI_Hint const *pHint );
  409. bool BackBridge_IsValidShootPosition( const Vector &vLocation, CAI_Node *pNode, CAI_Hint const *pHint );
  410. float BackBridge_GetMaxTacticalLateralMovement( void );
  411. bool BackBridge_ShouldIgnoreSound( CSound *pSound );
  412. void BackBridge_OnSeeEntity( CBaseEntity *pEntity );
  413. void BackBridge_OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker );
  414. bool BackBridge_IsInterruptable( void );
  415. bool BackBridge_IsNavigationUrgent( void );
  416. bool BackBridge_ShouldPlayerAvoid( void );
  417. int BackBridge_OnTakeDamage_Alive( const CTakeDamageInfo &info );
  418. float BackBridge_GetDefaultNavGoalTolerance();
  419. float BackBridge_GetReasonableFacingDist( void );
  420. bool BackBridge_CanFlinch( void );
  421. bool BackBridge_IsCrouching( void );
  422. bool BackBridge_IsCrouchedActivity( Activity activity );
  423. bool BackBridge_QueryHearSound( CSound *pSound );
  424. bool BackBridge_CanRunAScriptedNPCInteraction( bool bForced );
  425. Activity BackBridge_GetFlinchActivity( bool bHeavyDamage, bool bGesture );
  426. bool BackBridge_OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult );
  427. void BackBridge_ModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet );
  428. void BackBridge_Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity );
  429. void BackBridge_HandleAnimEvent( animevent_t *pEvent );
  430. CAI_BehaviorBase **AccessBehaviors();
  431. int NumBehaviors();
  432. CAI_BehaviorBase * m_pCurBehavior;
  433. CUtlVector<CAI_BehaviorBase *> m_Behaviors;
  434. bool m_bCalledBehaviorSelectSchedule;
  435. #ifdef DEBUG
  436. bool m_fDebugInCreateBehaviors;
  437. #endif
  438. };
  439. //-----------------------------------------------------------------------------
  440. // The first frame a behavior begins schedule selection, it won't have had it's GatherConditions()
  441. // called. To fix this, BeginScheduleSelection() manually calls the new behavior's GatherConditions(),
  442. // but sets this global so that the baseclass GatherConditions() isn't called as well.
  443. extern bool g_bBehaviorHost_PreventBaseClassGatherConditions;
  444. //-----------------------------------------------------------------------------
  445. inline void CAI_BehaviorBase::BridgeOnStartSchedule( int scheduleType )
  446. {
  447. int localId = AI_IdIsGlobal( scheduleType ) ? GetClassScheduleIdSpace()->ScheduleGlobalToLocal( scheduleType ) : scheduleType;
  448. OnStartSchedule( localId );
  449. }
  450. //-------------------------------------
  451. inline int CAI_BehaviorBase::BridgeSelectSchedule()
  452. {
  453. int result = SelectSchedule();
  454. if ( IsBehaviorSchedule( result ) )
  455. return GetClassScheduleIdSpace()->ScheduleLocalToGlobal( result );
  456. return result;
  457. }
  458. //-------------------------------------
  459. inline bool CAI_BehaviorBase::BridgeSelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode, int *pResult )
  460. {
  461. m_fOverrode = true;
  462. int result = SelectFailSchedule( failedSchedule, failedTask, taskFailCode );
  463. if ( m_fOverrode )
  464. {
  465. if ( result != SCHED_NONE )
  466. {
  467. if ( IsBehaviorSchedule( result ) )
  468. *pResult = GetClassScheduleIdSpace()->ScheduleLocalToGlobal( result );
  469. else
  470. *pResult = result;
  471. return true;
  472. }
  473. Warning( "An AI behavior is in control but has no recommended schedule\n" );
  474. }
  475. return false;
  476. }
  477. //-------------------------------------
  478. inline bool CAI_BehaviorBase::BridgeStartTask( const Task_t *pTask )
  479. {
  480. m_fOverrode = true;
  481. StartTask( pTask );
  482. return m_fOverrode;
  483. }
  484. //-------------------------------------
  485. inline bool CAI_BehaviorBase::BridgeRunTask( const Task_t *pTask)
  486. {
  487. m_fOverrode = true;
  488. RunTask( pTask );
  489. return m_fOverrode;
  490. }
  491. //-------------------------------------
  492. inline bool CAI_BehaviorBase::BridgeAimGun( void )
  493. {
  494. m_fOverrode = true;
  495. AimGun();
  496. return m_fOverrode;
  497. }
  498. //-------------------------------------
  499. inline void CAI_BehaviorBase::ChainStartTask( int task, float taskData )
  500. {
  501. Task_t tempTask = { task, taskData };
  502. bool fPrevOverride = m_fOverrode;
  503. GetOuter()->StartTask( (const Task_t *)&tempTask );
  504. m_fOverrode = fPrevOverride;;
  505. }
  506. //-------------------------------------
  507. inline void CAI_BehaviorBase::ChainRunTask( int task, float taskData )
  508. {
  509. Task_t tempTask = { task, taskData };
  510. bool fPrevOverride = m_fOverrode;
  511. GetOuter()->RunTask( (const Task_t *) &tempTask );
  512. m_fOverrode = fPrevOverride;;
  513. }
  514. //-------------------------------------
  515. inline int CAI_BehaviorBase::BridgeTranslateSchedule( int scheduleType )
  516. {
  517. int localId = AI_IdIsGlobal( scheduleType ) ? GetClassScheduleIdSpace()->ScheduleGlobalToLocal( scheduleType ) : scheduleType;
  518. int result = TranslateSchedule( localId );
  519. return result;
  520. }
  521. //-------------------------------------
  522. inline bool CAI_BehaviorBase::BridgeGetSchedule( int localScheduleID, CAI_Schedule **ppResult )
  523. {
  524. *ppResult = GetSchedule( localScheduleID );
  525. return (*ppResult != NULL );
  526. }
  527. //-------------------------------------
  528. inline bool CAI_BehaviorBase::BridgeTaskName( int taskID, const char **ppResult )
  529. {
  530. if ( AI_IdIsLocal( taskID ) )
  531. {
  532. *ppResult = GetSchedulingSymbols()->TaskIdToSymbol( GetClassScheduleIdSpace()->TaskLocalToGlobal( taskID ) );
  533. return (*ppResult != NULL );
  534. }
  535. return false;
  536. }
  537. //-------------------------------------
  538. inline Activity CAI_BehaviorBase::BridgeNPC_TranslateActivity( Activity activity )
  539. {
  540. return NPC_TranslateActivity( activity );
  541. }
  542. //-------------------------------------
  543. inline bool CAI_BehaviorBase::BridgeIsCurTaskContinuousMove( bool *pResult )
  544. {
  545. bool fPrevOverride = m_fOverrode;
  546. m_fOverrode = true;
  547. *pResult = IsCurTaskContinuousMove();
  548. bool result = m_fOverrode;
  549. m_fOverrode = fPrevOverride;
  550. return result;
  551. }
  552. //-------------------------------------
  553. inline bool CAI_BehaviorBase::BridgeFValidateHintType( CAI_Hint *pHint, bool *pResult )
  554. {
  555. bool fPrevOverride = m_fOverrode;
  556. m_fOverrode = true;
  557. *pResult = FValidateHintType( pHint );
  558. bool result = m_fOverrode;
  559. m_fOverrode = fPrevOverride;
  560. return result;
  561. }
  562. //-------------------------------------
  563. inline bool CAI_BehaviorBase::BridgeIsValidEnemy( CBaseEntity *pEnemy )
  564. {
  565. return IsValidEnemy( pEnemy );
  566. }
  567. //-------------------------------------
  568. inline CBaseEntity *CAI_BehaviorBase::BridgeBestEnemy()
  569. {
  570. return BestEnemy();
  571. }
  572. //-------------------------------------
  573. inline bool CAI_BehaviorBase::BridgeIsValidCover( const Vector &vLocation, CAI_Hint const *pHint )
  574. {
  575. return IsValidCover( vLocation, pHint );
  576. }
  577. //-------------------------------------
  578. inline bool CAI_BehaviorBase::BridgeIsValidShootPosition( const Vector &vLocation, CAI_Node *pNode, CAI_Hint const *pHint )
  579. {
  580. return IsValidShootPosition( vLocation, pNode, pHint );
  581. }
  582. //-------------------------------------
  583. inline float CAI_BehaviorBase::BridgeGetMaxTacticalLateralMovement( void )
  584. {
  585. return GetMaxTacticalLateralMovement();
  586. }
  587. //-------------------------------------
  588. inline bool CAI_BehaviorBase::BridgeShouldIgnoreSound( CSound *pSound )
  589. {
  590. return ShouldIgnoreSound( pSound );
  591. }
  592. //-------------------------------------
  593. inline void CAI_BehaviorBase::BridgeOnSeeEntity( CBaseEntity *pEntity )
  594. {
  595. OnSeeEntity( pEntity );
  596. }
  597. //-------------------------------------
  598. inline void CAI_BehaviorBase::BridgeOnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker )
  599. {
  600. OnFriendDamaged( pSquadmate, pAttacker );
  601. }
  602. //-------------------------------------
  603. inline bool CAI_BehaviorBase::BridgeIsInterruptable( void )
  604. {
  605. return IsInterruptable();
  606. }
  607. //-------------------------------------
  608. inline bool CAI_BehaviorBase::BridgeIsNavigationUrgent( void )
  609. {
  610. return IsNavigationUrgent();
  611. }
  612. //-------------------------------------
  613. inline bool CAI_BehaviorBase::BridgeCanFlinch( void )
  614. {
  615. return CanFlinch();
  616. }
  617. //-------------------------------------
  618. inline bool CAI_BehaviorBase::BridgeIsCrouching( void )
  619. {
  620. return IsCrouching();
  621. }
  622. //-------------------------------------
  623. inline bool CAI_BehaviorBase::BridgeIsCrouchedActivity( Activity activity )
  624. {
  625. return IsCrouchedActivity( activity );
  626. }
  627. inline bool CAI_BehaviorBase::BridgeQueryHearSound( CSound *pSound )
  628. {
  629. return QueryHearSound( pSound );
  630. }
  631. //-------------------------------------
  632. inline bool CAI_BehaviorBase::BridgeCanRunAScriptedNPCInteraction( bool bForced )
  633. {
  634. return CanRunAScriptedNPCInteraction( bForced );
  635. }
  636. //-------------------------------------
  637. inline bool CAI_BehaviorBase::BridgeShouldPlayerAvoid( void )
  638. {
  639. return ShouldPlayerAvoid();
  640. }
  641. //-------------------------------------
  642. inline int CAI_BehaviorBase::BridgeOnTakeDamage_Alive( const CTakeDamageInfo &info )
  643. {
  644. return OnTakeDamage_Alive( info );
  645. }
  646. //-------------------------------------
  647. inline float CAI_BehaviorBase::BridgeGetReasonableFacingDist( void )
  648. {
  649. return GetReasonableFacingDist();
  650. }
  651. //-------------------------------------
  652. inline bool CAI_BehaviorBase::BridgeShouldAlwaysThink( bool *pResult )
  653. {
  654. bool fPrevOverride = m_fOverrode;
  655. m_fOverrode = true;
  656. *pResult = ShouldAlwaysThink();
  657. bool result = m_fOverrode;
  658. m_fOverrode = fPrevOverride;
  659. return result;
  660. }
  661. //-------------------------------------
  662. inline void CAI_BehaviorBase::BridgeOnChangeActiveWeapon( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon )
  663. {
  664. OnChangeActiveWeapon( pOldWeapon, pNewWeapon );
  665. }
  666. //-------------------------------------
  667. inline bool CAI_BehaviorBase::BridgeSpeakMapmakerInterruptConcept( string_t iszConcept )
  668. {
  669. return SpeakMapmakerInterruptConcept( iszConcept );
  670. }
  671. //-------------------------------------
  672. inline void CAI_BehaviorBase::BridgeOnRestore()
  673. {
  674. OnRestore();
  675. }
  676. //-------------------------------------
  677. inline float CAI_BehaviorBase::BridgeGetDefaultNavGoalTolerance()
  678. {
  679. return GetDefaultNavGoalTolerance();
  680. }
  681. //-----------------------------------------------------------------------------
  682. inline Activity CAI_BehaviorBase::BridgeGetFlinchActivity( bool bHeavyDamage, bool bGesture )
  683. {
  684. return GetFlinchActivity( bHeavyDamage, bGesture );
  685. }
  686. //-----------------------------------------------------------------------------
  687. inline bool CAI_BehaviorBase::BridgeOnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult )
  688. {
  689. return OnCalcBaseMove( pMoveGoal, distClear, pResult );
  690. }
  691. //-----------------------------------------------------------------------------
  692. inline void CAI_BehaviorBase::BridgeModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet )
  693. {
  694. ModifyOrAppendCriteria( criteriaSet );
  695. }
  696. //-----------------------------------------------------------------------------
  697. inline void CAI_BehaviorBase::BridgeTeleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity )
  698. {
  699. Teleport( newPosition, newAngles, newVelocity );
  700. }
  701. //-----------------------------------------------------------------------------
  702. inline void CAI_BehaviorBase::BridgeHandleAnimEvent( animevent_t *pEvent )
  703. {
  704. HandleAnimEvent( pEvent );
  705. }
  706. //-----------------------------------------------------------------------------
  707. template <class BASE_NPC>
  708. inline void CAI_BehaviorHost<BASE_NPC>::CleanupOnDeath( CBaseEntity *pCulprit, bool bFireDeathOutput )
  709. {
  710. DeferSchedulingToBehavior( NULL );
  711. for( int i = 0; i < m_Behaviors.Count(); i++ )
  712. {
  713. m_Behaviors[i]->BridgeCleanupOnDeath( pCulprit, bFireDeathOutput );
  714. }
  715. BaseClass::CleanupOnDeath( pCulprit, bFireDeathOutput );
  716. }
  717. //-------------------------------------
  718. template <class BASE_NPC>
  719. inline void CAI_BehaviorHost<BASE_NPC>::GatherConditions()
  720. {
  721. // Iterate over behaviors and call GatherConditionsNotActive() on each behavior
  722. // not currently active.
  723. for( int i = 0; i < m_Behaviors.Count(); i++ )
  724. {
  725. if( m_Behaviors[i] != m_pCurBehavior )
  726. {
  727. m_Behaviors[i]->GatherConditionsNotActive();
  728. }
  729. }
  730. if ( m_pCurBehavior )
  731. m_pCurBehavior->BridgeGatherConditions();
  732. else
  733. BaseClass::GatherConditions();
  734. }
  735. //-------------------------------------
  736. template <class BASE_NPC>
  737. inline void CAI_BehaviorHost<BASE_NPC>::BackBridge_GatherConditions()
  738. {
  739. if ( g_bBehaviorHost_PreventBaseClassGatherConditions )
  740. return;
  741. BaseClass::GatherConditions();
  742. }
  743. //-------------------------------------
  744. template <class BASE_NPC>
  745. inline void CAI_BehaviorHost<BASE_NPC>::OnScheduleChange()
  746. {
  747. if ( m_pCurBehavior )
  748. m_pCurBehavior->BridgeOnScheduleChange();
  749. BaseClass::OnScheduleChange();
  750. }
  751. //-------------------------------------
  752. template <class BASE_NPC>
  753. inline void CAI_BehaviorHost<BASE_NPC>::OnStartSchedule( int scheduleType )
  754. {
  755. if ( m_pCurBehavior )
  756. m_pCurBehavior->BridgeOnStartSchedule( scheduleType );
  757. BaseClass::OnStartSchedule( scheduleType );
  758. }
  759. //-------------------------------------
  760. template <class BASE_NPC>
  761. inline int CAI_BehaviorHost<BASE_NPC>::BackBridge_SelectSchedule()
  762. {
  763. return BaseClass::SelectSchedule();
  764. }
  765. //-------------------------------------
  766. template <class BASE_NPC>
  767. inline bool CAI_BehaviorHost<BASE_NPC>::BehaviorSelectSchedule()
  768. {
  769. for ( int i = 0; i < m_Behaviors.Count(); i++ )
  770. {
  771. if ( m_Behaviors[i]->CanSelectSchedule() && ShouldBehaviorSelectSchedule( m_Behaviors[i] ) )
  772. {
  773. DeferSchedulingToBehavior( m_Behaviors[i] );
  774. return true;
  775. }
  776. }
  777. DeferSchedulingToBehavior( NULL );
  778. return false;
  779. }
  780. //-------------------------------------
  781. template <class BASE_NPC>
  782. inline bool CAI_BehaviorHost<BASE_NPC>::IsRunningBehavior() const
  783. {
  784. return ( m_pCurBehavior != NULL );
  785. }
  786. //-------------------------------------
  787. template <class BASE_NPC>
  788. inline CAI_BehaviorBase *CAI_BehaviorHost<BASE_NPC>::GetRunningBehavior()
  789. {
  790. return m_pCurBehavior;
  791. }
  792. //-------------------------------------
  793. template <class BASE_NPC>
  794. inline CAI_Schedule *CAI_BehaviorHost<BASE_NPC>::GetNewSchedule()
  795. {
  796. m_bCalledBehaviorSelectSchedule = false;
  797. CAI_Schedule *pResult = BaseClass::GetNewSchedule();
  798. if ( !m_bCalledBehaviorSelectSchedule && m_pCurBehavior )
  799. DeferSchedulingToBehavior( NULL );
  800. return pResult;
  801. }
  802. //-------------------------------------
  803. template <class BASE_NPC>
  804. inline CAI_Schedule *CAI_BehaviorHost<BASE_NPC>::GetFailSchedule()
  805. {
  806. m_bCalledBehaviorSelectSchedule = false;
  807. CAI_Schedule *pResult = BaseClass::GetFailSchedule();
  808. if ( !m_bCalledBehaviorSelectSchedule && m_pCurBehavior )
  809. DeferSchedulingToBehavior( NULL );
  810. return pResult;
  811. }
  812. //------------------------------------
  813. template <class BASE_NPC>
  814. inline void CAI_BehaviorHost<BASE_NPC>::ChangeBehaviorTo( CAI_BehaviorBase *pNewBehavior )
  815. {
  816. bool change = ( m_pCurBehavior != pNewBehavior );
  817. CAI_BehaviorBase *pOldBehavior = m_pCurBehavior;
  818. m_pCurBehavior = pNewBehavior;
  819. if ( change )
  820. {
  821. if ( m_pCurBehavior )
  822. {
  823. m_pCurBehavior->BeginScheduleSelection();
  824. g_bBehaviorHost_PreventBaseClassGatherConditions = true;
  825. m_pCurBehavior->GatherConditions();
  826. g_bBehaviorHost_PreventBaseClassGatherConditions = false;
  827. }
  828. if ( pOldBehavior )
  829. {
  830. pOldBehavior->EndScheduleSelection();
  831. this->VacateStrategySlot();
  832. }
  833. OnChangeRunningBehavior( pOldBehavior, pNewBehavior );
  834. }
  835. }
  836. //-------------------------------------
  837. template <class BASE_NPC>
  838. inline CAI_BehaviorBase *CAI_BehaviorHost<BASE_NPC>::DeferSchedulingToBehavior( CAI_BehaviorBase *pNewBehavior )
  839. {
  840. CAI_BehaviorBase *pOldBehavior = m_pCurBehavior;
  841. ChangeBehaviorTo( pNewBehavior );
  842. return pOldBehavior;
  843. }
  844. //-------------------------------------
  845. template <class BASE_NPC>
  846. inline int CAI_BehaviorHost<BASE_NPC>::BackBridge_TranslateSchedule( int scheduleType )
  847. {
  848. return BaseClass::TranslateSchedule( scheduleType );
  849. }
  850. //-------------------------------------
  851. template <class BASE_NPC>
  852. inline int CAI_BehaviorHost<BASE_NPC>::TranslateSchedule( int scheduleType )
  853. {
  854. if ( m_pCurBehavior )
  855. {
  856. return m_pCurBehavior->BridgeTranslateSchedule( scheduleType );
  857. }
  858. return BaseClass::TranslateSchedule( scheduleType );
  859. }
  860. //-------------------------------------
  861. template <class BASE_NPC>
  862. inline void CAI_BehaviorHost<BASE_NPC>::PrescheduleThink()
  863. {
  864. BaseClass::PrescheduleThink();
  865. if ( m_pCurBehavior )
  866. m_pCurBehavior->BridgePrescheduleThink();
  867. }
  868. //-------------------------------------
  869. template <class BASE_NPC>
  870. inline int CAI_BehaviorHost<BASE_NPC>::SelectSchedule()
  871. {
  872. m_bCalledBehaviorSelectSchedule = true;
  873. if ( m_pCurBehavior )
  874. {
  875. return m_pCurBehavior->BridgeSelectSchedule();
  876. }
  877. return BaseClass::SelectSchedule();
  878. }
  879. //-------------------------------------
  880. template <class BASE_NPC>
  881. inline void CAI_BehaviorHost<BASE_NPC>::KeepRunningBehavior()
  882. {
  883. if ( m_pCurBehavior )
  884. m_bCalledBehaviorSelectSchedule = true;
  885. }
  886. //-------------------------------------
  887. template <class BASE_NPC>
  888. inline int CAI_BehaviorHost<BASE_NPC>::SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode )
  889. {
  890. m_bCalledBehaviorSelectSchedule = true;
  891. int result = 0;
  892. if ( m_pCurBehavior && m_pCurBehavior->BridgeSelectFailSchedule( failedSchedule, failedTask, taskFailCode, &result ) )
  893. return result;
  894. return BaseClass::SelectFailSchedule( failedSchedule, failedTask, taskFailCode );
  895. }
  896. //-------------------------------------
  897. template <class BASE_NPC>
  898. inline void CAI_BehaviorHost<BASE_NPC>::StartTask( const Task_t *pTask )
  899. {
  900. if ( m_pCurBehavior && m_pCurBehavior->BridgeStartTask( pTask ) )
  901. return;
  902. BaseClass::StartTask( pTask );
  903. }
  904. //-------------------------------------
  905. template <class BASE_NPC>
  906. inline void CAI_BehaviorHost<BASE_NPC>::RunTask( const Task_t *pTask )
  907. {
  908. if ( m_pCurBehavior && m_pCurBehavior->BridgeRunTask( pTask ) )
  909. return;
  910. BaseClass::RunTask( pTask );
  911. }
  912. //-------------------------------------
  913. template <class BASE_NPC>
  914. inline void CAI_BehaviorHost<BASE_NPC>::AimGun( void )
  915. {
  916. if ( m_pCurBehavior && m_pCurBehavior->BridgeAimGun() )
  917. return;
  918. BaseClass::AimGun();
  919. }
  920. //-------------------------------------
  921. template <class BASE_NPC>
  922. inline CAI_Schedule *CAI_BehaviorHost<BASE_NPC>::GetSchedule(int localScheduleID)
  923. {
  924. CAI_Schedule *pResult;
  925. if ( m_pCurBehavior && m_pCurBehavior->BridgeGetSchedule( localScheduleID, &pResult ) )
  926. return pResult;
  927. return BaseClass::GetSchedule( localScheduleID );
  928. }
  929. //-------------------------------------
  930. template <class BASE_NPC>
  931. inline const char *CAI_BehaviorHost<BASE_NPC>::TaskName(int taskID)
  932. {
  933. const char *pszResult = NULL;
  934. if ( m_pCurBehavior && m_pCurBehavior->BridgeTaskName( taskID, &pszResult ) )
  935. return pszResult;
  936. return BaseClass::TaskName( taskID );
  937. }
  938. //-------------------------------------
  939. template <class BASE_NPC>
  940. inline void CAI_BehaviorHost<BASE_NPC>::BuildScheduleTestBits()
  941. {
  942. if ( m_pCurBehavior )
  943. m_pCurBehavior->BridgeBuildScheduleTestBits();
  944. BaseClass::BuildScheduleTestBits();
  945. }
  946. //-------------------------------------
  947. template <class BASE_NPC>
  948. inline void CAI_BehaviorHost<BASE_NPC>::OnChangeHintGroup( string_t oldGroup, string_t newGroup )
  949. {
  950. for( int i = 0; i < m_Behaviors.Count(); i++ )
  951. {
  952. m_Behaviors[i]->BridgeOnChangeHintGroup( oldGroup, newGroup );
  953. }
  954. BaseClass::OnChangeHintGroup( oldGroup, newGroup );
  955. }
  956. //-------------------------------------
  957. template <class BASE_NPC>
  958. inline Activity CAI_BehaviorHost<BASE_NPC>::BackBridge_NPC_TranslateActivity( Activity activity )
  959. {
  960. return BaseClass::NPC_TranslateActivity( activity );
  961. }
  962. //-------------------------------------
  963. template <class BASE_NPC>
  964. inline Activity CAI_BehaviorHost<BASE_NPC>::NPC_TranslateActivity( Activity activity )
  965. {
  966. if ( m_pCurBehavior )
  967. {
  968. return m_pCurBehavior->BridgeNPC_TranslateActivity( activity );
  969. }
  970. return BaseClass::NPC_TranslateActivity( activity );
  971. }
  972. //-------------------------------------
  973. template <class BASE_NPC>
  974. inline bool CAI_BehaviorHost<BASE_NPC>::IsCurTaskContinuousMove()
  975. {
  976. bool result = false;
  977. if ( m_pCurBehavior && m_pCurBehavior->BridgeIsCurTaskContinuousMove( &result ) )
  978. return result;
  979. return BaseClass::IsCurTaskContinuousMove();
  980. }
  981. //-------------------------------------
  982. template <class BASE_NPC>
  983. inline void CAI_BehaviorHost<BASE_NPC>::OnMovementFailed()
  984. {
  985. if ( m_pCurBehavior )
  986. m_pCurBehavior->BridgeOnMovementFailed();
  987. BaseClass::OnMovementFailed();
  988. }
  989. //-------------------------------------
  990. template <class BASE_NPC>
  991. inline void CAI_BehaviorHost<BASE_NPC>::OnMovementComplete()
  992. {
  993. if ( m_pCurBehavior )
  994. m_pCurBehavior->BridgeOnMovementComplete();
  995. BaseClass::OnMovementComplete();
  996. }
  997. //-------------------------------------
  998. template <class BASE_NPC>
  999. inline float CAI_BehaviorHost<BASE_NPC>::GetDefaultNavGoalTolerance()
  1000. {
  1001. if ( m_pCurBehavior )
  1002. return m_pCurBehavior->BridgeGetDefaultNavGoalTolerance();
  1003. return BaseClass::GetDefaultNavGoalTolerance();
  1004. }
  1005. //-------------------------------------
  1006. template <class BASE_NPC>
  1007. inline float CAI_BehaviorHost<BASE_NPC>::BackBridge_GetDefaultNavGoalTolerance()
  1008. {
  1009. return BaseClass::GetDefaultNavGoalTolerance();
  1010. }
  1011. //-------------------------------------
  1012. template <class BASE_NPC>
  1013. inline bool CAI_BehaviorHost<BASE_NPC>::FValidateHintType( CAI_Hint *pHint )
  1014. {
  1015. bool result = false;
  1016. if ( m_pCurBehavior && m_pCurBehavior->BridgeFValidateHintType( pHint, &result ) )
  1017. return result;
  1018. return BaseClass::FValidateHintType( pHint );
  1019. }
  1020. //-------------------------------------
  1021. template <class BASE_NPC>
  1022. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_IsValidEnemy(CBaseEntity *pEnemy)
  1023. {
  1024. return BaseClass::IsValidEnemy( pEnemy );
  1025. }
  1026. //-------------------------------------
  1027. template <class BASE_NPC>
  1028. inline CBaseEntity *CAI_BehaviorHost<BASE_NPC>::BackBridge_BestEnemy(void)
  1029. {
  1030. return BaseClass::BestEnemy();
  1031. }
  1032. //-------------------------------------
  1033. template <class BASE_NPC>
  1034. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_IsValidCover( const Vector &vLocation, CAI_Hint const *pHint )
  1035. {
  1036. return BaseClass::IsValidCover( vLocation, pHint );
  1037. }
  1038. //-------------------------------------
  1039. template <class BASE_NPC>
  1040. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_IsValidShootPosition( const Vector &vLocation, CAI_Node *pNode, CAI_Hint const *pHint )
  1041. {
  1042. return BaseClass::IsValidShootPosition( vLocation, pNode, pHint );
  1043. }
  1044. //-------------------------------------
  1045. template <class BASE_NPC>
  1046. inline float CAI_BehaviorHost<BASE_NPC>::BackBridge_GetMaxTacticalLateralMovement( void )
  1047. {
  1048. return BaseClass::GetMaxTacticalLateralMovement();
  1049. }
  1050. //-------------------------------------
  1051. template <class BASE_NPC>
  1052. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_ShouldIgnoreSound( CSound *pSound )
  1053. {
  1054. return BaseClass::ShouldIgnoreSound( pSound );
  1055. }
  1056. //-------------------------------------
  1057. template <class BASE_NPC>
  1058. inline void CAI_BehaviorHost<BASE_NPC>::BackBridge_OnSeeEntity( CBaseEntity *pEntity )
  1059. {
  1060. BaseClass::OnSeeEntity( pEntity );
  1061. }
  1062. //-------------------------------------
  1063. template <class BASE_NPC>
  1064. inline void CAI_BehaviorHost<BASE_NPC>::BackBridge_OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker )
  1065. {
  1066. BaseClass::OnFriendDamaged( pSquadmate, pAttacker );
  1067. }
  1068. //-------------------------------------
  1069. template <class BASE_NPC>
  1070. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_IsInterruptable( void )
  1071. {
  1072. return BaseClass::IsInterruptable();
  1073. }
  1074. //-------------------------------------
  1075. template <class BASE_NPC>
  1076. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_IsNavigationUrgent( void )
  1077. {
  1078. return BaseClass::IsNavigationUrgent();
  1079. }
  1080. //-------------------------------------
  1081. template <class BASE_NPC>
  1082. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_CanFlinch( void )
  1083. {
  1084. return BaseClass::CanFlinch();
  1085. }
  1086. //-------------------------------------
  1087. template <class BASE_NPC>
  1088. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_IsCrouching( void )
  1089. {
  1090. return BaseClass::IsCrouching();
  1091. }
  1092. //-------------------------------------
  1093. template <class BASE_NPC>
  1094. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_IsCrouchedActivity( Activity activity )
  1095. {
  1096. return BaseClass::IsCrouchedActivity( activity );
  1097. }
  1098. //-------------------------------------
  1099. template <class BASE_NPC>
  1100. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_QueryHearSound( CSound *pSound )
  1101. {
  1102. return BaseClass::QueryHearSound( pSound );
  1103. }
  1104. //-------------------------------------
  1105. template <class BASE_NPC>
  1106. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_CanRunAScriptedNPCInteraction( bool bForced )
  1107. {
  1108. return BaseClass::CanRunAScriptedNPCInteraction( bForced );
  1109. }
  1110. //-------------------------------------
  1111. template <class BASE_NPC>
  1112. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_ShouldPlayerAvoid( void )
  1113. {
  1114. return BaseClass::ShouldPlayerAvoid();
  1115. }
  1116. //-------------------------------------
  1117. template <class BASE_NPC>
  1118. inline int CAI_BehaviorHost<BASE_NPC>::BackBridge_OnTakeDamage_Alive( const CTakeDamageInfo &info )
  1119. {
  1120. return BaseClass::OnTakeDamage_Alive( info );
  1121. }
  1122. //-------------------------------------
  1123. template <class BASE_NPC>
  1124. inline float CAI_BehaviorHost<BASE_NPC>::BackBridge_GetReasonableFacingDist( void )
  1125. {
  1126. return BaseClass::GetReasonableFacingDist();
  1127. }
  1128. //-------------------------------------
  1129. template <class BASE_NPC>
  1130. inline Activity CAI_BehaviorHost<BASE_NPC>::BackBridge_GetFlinchActivity( bool bHeavyDamage, bool bGesture )
  1131. {
  1132. return BaseClass::GetFlinchActivity( bHeavyDamage, bGesture );
  1133. }
  1134. //-------------------------------------
  1135. template <class BASE_NPC>
  1136. inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult )
  1137. {
  1138. return BaseClass::OnCalcBaseMove( pMoveGoal, distClear, pResult );
  1139. }
  1140. //-------------------------------------
  1141. template <class BASE_NPC>
  1142. inline void CAI_BehaviorHost<BASE_NPC>::BackBridge_ModifyOrAppendCriteria( AI_CriteriaSet &criteriaSet )
  1143. {
  1144. BaseClass::ModifyOrAppendCriteria( criteriaSet );
  1145. }
  1146. //-------------------------------------
  1147. template <class BASE_NPC>
  1148. inline void CAI_BehaviorHost<BASE_NPC>::BackBridge_Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity )
  1149. {
  1150. BaseClass::Teleport( newPosition, newAngles, newVelocity );
  1151. }
  1152. //-------------------------------------
  1153. template <class BASE_NPC>
  1154. inline void CAI_BehaviorHost<BASE_NPC>::BackBridge_HandleAnimEvent( animevent_t *pEvent )
  1155. {
  1156. BaseClass::HandleAnimEvent( pEvent );
  1157. }
  1158. //-------------------------------------
  1159. template <class BASE_NPC>
  1160. inline bool CAI_BehaviorHost<BASE_NPC>::IsValidEnemy( CBaseEntity *pEnemy )
  1161. {
  1162. if ( m_pCurBehavior )
  1163. return m_pCurBehavior->BridgeIsValidEnemy( pEnemy );
  1164. return BaseClass::IsValidEnemy( pEnemy );
  1165. }
  1166. //-------------------------------------
  1167. template <class BASE_NPC>
  1168. inline CBaseEntity *CAI_BehaviorHost<BASE_NPC>::BestEnemy()
  1169. {
  1170. if ( m_pCurBehavior )
  1171. return m_pCurBehavior->BridgeBestEnemy();
  1172. return BaseClass::BestEnemy();
  1173. }
  1174. //-------------------------------------
  1175. template <class BASE_NPC>
  1176. inline bool CAI_BehaviorHost<BASE_NPC>::ShouldAlwaysThink()
  1177. {
  1178. bool result = false;
  1179. if ( m_pCurBehavior && m_pCurBehavior->BridgeShouldAlwaysThink( &result ) )
  1180. return result;
  1181. return BaseClass::ShouldAlwaysThink();
  1182. }
  1183. //-------------------------------------
  1184. template <class BASE_NPC>
  1185. inline void CAI_BehaviorHost<BASE_NPC>::OnChangeActiveWeapon( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon )
  1186. {
  1187. for( int i = 0; i < m_Behaviors.Count(); i++ )
  1188. {
  1189. m_Behaviors[i]->BridgeOnChangeActiveWeapon( pOldWeapon, pNewWeapon );
  1190. }
  1191. BaseClass::OnChangeActiveWeapon( pOldWeapon, pNewWeapon );
  1192. }
  1193. //-------------------------------------
  1194. template <class BASE_NPC>
  1195. inline bool CAI_BehaviorHost<BASE_NPC>::SpeakMapmakerInterruptConcept( string_t iszConcept )
  1196. {
  1197. for( int i = 0; i < m_Behaviors.Count(); i++ )
  1198. {
  1199. if ( m_Behaviors[i]->BridgeSpeakMapmakerInterruptConcept( iszConcept ) )
  1200. return true;
  1201. }
  1202. return false;
  1203. }
  1204. //-------------------------------------
  1205. template <class BASE_NPC>
  1206. inline void CAI_BehaviorHost<BASE_NPC>::OnRestore()
  1207. {
  1208. for( int i = 0; i < m_Behaviors.Count(); i++ )
  1209. {
  1210. m_Behaviors[i]->BridgeOnRestore();
  1211. }
  1212. BaseClass::OnRestore();
  1213. }
  1214. //-------------------------------------
  1215. template <class BASE_NPC>
  1216. inline bool CAI_BehaviorHost<BASE_NPC>::IsValidCover( const Vector &vLocation, CAI_Hint const *pHint )
  1217. {
  1218. if ( m_pCurBehavior )
  1219. return m_pCurBehavior->BridgeIsValidCover( vLocation, pHint );
  1220. return BaseClass::IsValidCover( vLocation, pHint );
  1221. }
  1222. //-------------------------------------
  1223. template <class BASE_NPC>
  1224. inline bool CAI_BehaviorHost<BASE_NPC>::IsValidShootPosition( const Vector &vLocation, CAI_Node *pNode, CAI_Hint const *pHint )
  1225. {
  1226. if ( m_pCurBehavior )
  1227. return m_pCurBehavior->BridgeIsValidShootPosition( vLocation, pNode, pHint );
  1228. return BaseClass::IsValidShootPosition( vLocation, pNode, pHint );
  1229. }
  1230. //-------------------------------------
  1231. template <class BASE_NPC>
  1232. inline float CAI_BehaviorHost<BASE_NPC>::GetMaxTacticalLateralMovement( void )
  1233. {
  1234. if ( m_pCurBehavior )
  1235. return m_pCurBehavior->BridgeGetMaxTacticalLateralMovement();
  1236. return BaseClass::GetMaxTacticalLateralMovement();
  1237. }
  1238. //-------------------------------------
  1239. template <class BASE_NPC>
  1240. inline bool CAI_BehaviorHost<BASE_NPC>::ShouldIgnoreSound( CSound *pSound )
  1241. {
  1242. if ( m_pCurBehavior )
  1243. return m_pCurBehavior->BridgeShouldIgnoreSound( pSound );
  1244. return BaseClass::ShouldIgnoreSound( pSound );
  1245. }
  1246. //-------------------------------------
  1247. template <class BASE_NPC>
  1248. inline void CAI_BehaviorHost<BASE_NPC>::OnSeeEntity( CBaseEntity *pEntity )
  1249. {
  1250. if ( m_pCurBehavior )
  1251. return m_pCurBehavior->BridgeOnSeeEntity( pEntity );
  1252. BaseClass::OnSeeEntity( pEntity );
  1253. }
  1254. //-------------------------------------
  1255. template <class BASE_NPC>
  1256. inline void CAI_BehaviorHost<BASE_NPC>::OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker )
  1257. {
  1258. if ( m_pCurBehavior )
  1259. return m_pCurBehavior->BridgeOnFriendDamaged( pSquadmate, pAttacker );
  1260. BaseClass::OnFriendDamaged( pSquadmate, pAttacker );
  1261. }
  1262. //-------------------------------------
  1263. template <class BASE_NPC>
  1264. inline bool CAI_BehaviorHost<BASE_NPC>::IsInterruptable( void )
  1265. {
  1266. if ( m_pCurBehavior )
  1267. return m_pCurBehavior->BridgeIsInterruptable();
  1268. return BaseClass::IsInterruptable();
  1269. }
  1270. //-------------------------------------
  1271. template <class BASE_NPC>
  1272. inline bool CAI_BehaviorHost<BASE_NPC>::IsNavigationUrgent( void )
  1273. {
  1274. if ( m_pCurBehavior )
  1275. return m_pCurBehavior->BridgeIsNavigationUrgent();
  1276. return BaseClass::IsNavigationUrgent();
  1277. }
  1278. //-------------------------------------
  1279. template <class BASE_NPC>
  1280. inline bool CAI_BehaviorHost<BASE_NPC>::CanFlinch( void )
  1281. {
  1282. if ( m_pCurBehavior )
  1283. return m_pCurBehavior->BridgeCanFlinch();
  1284. return BaseClass::CanFlinch();
  1285. }
  1286. //-------------------------------------
  1287. template <class BASE_NPC>
  1288. inline bool CAI_BehaviorHost<BASE_NPC>::IsCrouching( void )
  1289. {
  1290. if ( m_pCurBehavior )
  1291. return m_pCurBehavior->BridgeIsCrouching();
  1292. return BaseClass::IsCrouching();
  1293. }
  1294. //-------------------------------------
  1295. template <class BASE_NPC>
  1296. inline bool CAI_BehaviorHost<BASE_NPC>::IsCrouchedActivity( Activity activity )
  1297. {
  1298. if ( m_pCurBehavior )
  1299. return m_pCurBehavior->BridgeIsCrouchedActivity( activity );
  1300. return BaseClass::IsCrouchedActivity( activity );
  1301. }
  1302. //-------------------------------------
  1303. template <class BASE_NPC>
  1304. inline bool CAI_BehaviorHost<BASE_NPC>::QueryHearSound( CSound *pSound )
  1305. {
  1306. if ( m_pCurBehavior )
  1307. return m_pCurBehavior->BridgeQueryHearSound( pSound );
  1308. return BaseClass::QueryHearSound( pSound );
  1309. }
  1310. //-------------------------------------
  1311. template <class BASE_NPC>
  1312. inline bool CAI_BehaviorHost<BASE_NPC>::CanRunAScriptedNPCInteraction( bool bForced )
  1313. {
  1314. if ( m_pCurBehavior )
  1315. return m_pCurBehavior->BridgeCanRunAScriptedNPCInteraction( bForced );
  1316. return BaseClass::CanRunAScriptedNPCInteraction( bForced );
  1317. }
  1318. //-------------------------------------
  1319. template <class BASE_NPC>
  1320. inline bool CAI_BehaviorHost<BASE_NPC>::ShouldPlayerAvoid( void )
  1321. {
  1322. if ( m_pCurBehavior )
  1323. return m_pCurBehavior->BridgeShouldPlayerAvoid();
  1324. return BaseClass::ShouldPlayerAvoid();
  1325. }
  1326. //-------------------------------------
  1327. template <class BASE_NPC>
  1328. inline int CAI_BehaviorHost<BASE_NPC>::OnTakeDamage_Alive( const CTakeDamageInfo &info )
  1329. {
  1330. if ( m_pCurBehavior )
  1331. return m_pCurBehavior->BridgeOnTakeDamage_Alive( info );
  1332. return BaseClass::OnTakeDamage_Alive( info );
  1333. }
  1334. //-------------------------------------
  1335. template <class BASE_NPC>
  1336. inline float CAI_BehaviorHost<BASE_NPC>::GetReasonableFacingDist( void )
  1337. {
  1338. if ( m_pCurBehavior )
  1339. return m_pCurBehavior->BridgeGetReasonableFacingDist();
  1340. return BaseClass::GetReasonableFacingDist();
  1341. }
  1342. //-------------------------------------
  1343. template <class BASE_NPC>
  1344. inline void CAI_BehaviorHost<BASE_NPC>::Precache()
  1345. {
  1346. BaseClass::Precache();
  1347. for( int i = 0; i < m_Behaviors.Count(); i++ )
  1348. {
  1349. m_Behaviors[i]->BridgePrecache();
  1350. }
  1351. }
  1352. //-------------------------------------
  1353. template <class BASE_NPC>
  1354. inline bool CAI_BehaviorHost<BASE_NPC>::ScheduledMoveToGoalEntity( int scheduleType, CBaseEntity *pGoalEntity, Activity movementActivity )
  1355. {
  1356. // If a behavior is active, we need to stop running it
  1357. ChangeBehaviorTo( NULL );
  1358. return BaseClass::ScheduledMoveToGoalEntity( scheduleType, pGoalEntity, movementActivity );
  1359. }
  1360. //-------------------------------------
  1361. template <class BASE_NPC>
  1362. inline bool CAI_BehaviorHost<BASE_NPC>::ScheduledFollowPath( int scheduleType, CBaseEntity *pPathStart, Activity movementActivity )
  1363. {
  1364. // If a behavior is active, we need to stop running it
  1365. ChangeBehaviorTo( NULL );
  1366. return BaseClass::ScheduledFollowPath( scheduleType, pPathStart, movementActivity );
  1367. }
  1368. //-------------------------------------
  1369. template <class BASE_NPC>
  1370. inline void CAI_BehaviorHost<BASE_NPC>::ForceSelectedGo(CBaseEntity *pPlayer, const Vector &targetPos, const Vector &traceDir, bool bRun)
  1371. {
  1372. // If a behavior is active, we need to stop running it
  1373. ChangeBehaviorTo( NULL );
  1374. BaseClass::ForceSelectedGo(pPlayer, targetPos, traceDir, bRun);
  1375. }
  1376. //-------------------------------------
  1377. template <class BASE_NPC>
  1378. inline void CAI_BehaviorHost<BASE_NPC>::ForceSelectedGoRandom(void)
  1379. {
  1380. // If a behavior is active, we need to stop running it
  1381. ChangeBehaviorTo( NULL );
  1382. BaseClass::ForceSelectedGoRandom();
  1383. }
  1384. //-------------------------------------
  1385. template <class BASE_NPC>
  1386. inline void CAI_BehaviorHost<BASE_NPC>::NPCInit()
  1387. {
  1388. BaseClass::NPCInit();
  1389. for( int i = 0; i < m_Behaviors.Count(); i++ )
  1390. {
  1391. m_Behaviors[i]->BridgeSpawn();
  1392. }
  1393. }
  1394. //-------------------------------------
  1395. template <class BASE_NPC>
  1396. inline void CAI_BehaviorHost<BASE_NPC>::UpdateOnRemove()
  1397. {
  1398. for( int i = 0; i < m_Behaviors.Count(); i++ )
  1399. {
  1400. m_Behaviors[i]->BridgeUpdateOnRemove();
  1401. }
  1402. BaseClass::UpdateOnRemove();
  1403. }
  1404. //-------------------------------------
  1405. template <class BASE_NPC>
  1406. inline void CAI_BehaviorHost<BASE_NPC>::Event_Killed( const CTakeDamageInfo &info )
  1407. {
  1408. for( int i = 0; i < m_Behaviors.Count(); i++ )
  1409. {
  1410. m_Behaviors[i]->BridgeEvent_Killed( info );
  1411. }
  1412. BaseClass::Event_Killed( info );
  1413. }
  1414. //-------------------------------------
  1415. template <class BASE_NPC>
  1416. inline Activity CAI_BehaviorHost<BASE_NPC>::GetFlinchActivity( bool bHeavyDamage, bool bGesture )
  1417. {
  1418. if ( m_pCurBehavior )
  1419. return m_pCurBehavior->BridgeGetFlinchActivity( bHeavyDamage, bGesture );
  1420. return BaseClass::GetFlinchActivity( bHeavyDamage, bGesture );
  1421. }
  1422. //-------------------------------------
  1423. template <class BASE_NPC>
  1424. inline bool CAI_BehaviorHost<BASE_NPC>::OnCalcBaseMove( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult )
  1425. {
  1426. if ( m_pCurBehavior )
  1427. return m_pCurBehavior->BridgeOnCalcBaseMove( pMoveGoal, distClear, pResult );
  1428. return BaseClass::OnCalcBaseMove( pMoveGoal, distClear, pResult );
  1429. }
  1430. //-------------------------------------
  1431. template <class BASE_NPC>
  1432. inline void CAI_BehaviorHost<BASE_NPC>::ModifyOrAppendCriteria( AI_CriteriaSet &criteriaSet )
  1433. {
  1434. BaseClass::ModifyOrAppendCriteria( criteriaSet );
  1435. if ( m_pCurBehavior )
  1436. {
  1437. // Append active behavior name
  1438. criteriaSet.AppendCriteria( "active_behavior", GetRunningBehavior()->GetName() );
  1439. m_pCurBehavior->BridgeModifyOrAppendCriteria( criteriaSet );
  1440. return;
  1441. }
  1442. }
  1443. //-------------------------------------
  1444. template <class BASE_NPC>
  1445. inline void CAI_BehaviorHost<BASE_NPC>::Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity )
  1446. {
  1447. if ( m_pCurBehavior )
  1448. {
  1449. m_pCurBehavior->BridgeTeleport( newPosition, newAngles, newVelocity );
  1450. return;
  1451. }
  1452. BaseClass::Teleport( newPosition, newAngles, newVelocity );
  1453. }
  1454. //-------------------------------------
  1455. template <class BASE_NPC>
  1456. inline void CAI_BehaviorHost<BASE_NPC>::HandleAnimEvent( animevent_t *pEvent )
  1457. {
  1458. if ( m_pCurBehavior )
  1459. return m_pCurBehavior->BridgeHandleAnimEvent( pEvent );
  1460. return BaseClass::HandleAnimEvent( pEvent );
  1461. }
  1462. //-------------------------------------
  1463. template <class BASE_NPC>
  1464. inline bool CAI_BehaviorHost<BASE_NPC>::OnBehaviorChangeStatus( CAI_BehaviorBase *pBehavior, bool fCanFinishSchedule )
  1465. {
  1466. if ( pBehavior == GetRunningBehavior() && !pBehavior->CanSelectSchedule() && !fCanFinishSchedule )
  1467. {
  1468. DeferSchedulingToBehavior( NULL );
  1469. return true;
  1470. }
  1471. return false;
  1472. }
  1473. //-------------------------------------
  1474. template <class BASE_NPC>
  1475. inline void CAI_BehaviorHost<BASE_NPC>::OnChangeRunningBehavior( CAI_BehaviorBase *pOldBehavior, CAI_BehaviorBase *pNewBehavior )
  1476. {
  1477. }
  1478. //-------------------------------------
  1479. template <class BASE_NPC>
  1480. inline void CAI_BehaviorHost<BASE_NPC>::AddBehavior( CAI_BehaviorBase *pBehavior )
  1481. {
  1482. #ifdef DEBUG
  1483. Assert( m_Behaviors.Find( pBehavior ) == m_Behaviors.InvalidIndex() );
  1484. Assert( m_fDebugInCreateBehaviors );
  1485. for ( int i = 0; i < m_Behaviors.Count(); i++)
  1486. {
  1487. Assert( typeid(*m_Behaviors[i]) != typeid(*pBehavior) );
  1488. }
  1489. #endif
  1490. m_Behaviors.AddToTail( pBehavior );
  1491. pBehavior->SetOuter( this );
  1492. pBehavior->SetBackBridge( this );
  1493. }
  1494. //-------------------------------------
  1495. template <class BASE_NPC>
  1496. inline CAI_BehaviorBase **CAI_BehaviorHost<BASE_NPC>::AccessBehaviors()
  1497. {
  1498. if (m_Behaviors.Count())
  1499. return m_Behaviors.Base();
  1500. return NULL;
  1501. }
  1502. //-------------------------------------
  1503. template <class BASE_NPC>
  1504. inline int CAI_BehaviorHost<BASE_NPC>::NumBehaviors()
  1505. {
  1506. return m_Behaviors.Count();
  1507. }
  1508. //-------------------------------------
  1509. template <class BASE_NPC>
  1510. inline int CAI_BehaviorHost<BASE_NPC>::Save( ISave &save )
  1511. {
  1512. int result = BaseClass::Save( save );
  1513. if ( result )
  1514. CAI_BehaviorBase::SaveBehaviors( save, m_pCurBehavior, AccessBehaviors(), NumBehaviors() );
  1515. return result;
  1516. }
  1517. //-------------------------------------
  1518. template <class BASE_NPC>
  1519. inline int CAI_BehaviorHost<BASE_NPC>::Restore( IRestore &restore )
  1520. {
  1521. int result = BaseClass::Restore( restore );
  1522. if ( result )
  1523. {
  1524. int iCurrent = CAI_BehaviorBase::RestoreBehaviors( restore, AccessBehaviors(), NumBehaviors() );
  1525. if ( iCurrent != -1 )
  1526. m_pCurBehavior = AccessBehaviors()[iCurrent];
  1527. else
  1528. m_pCurBehavior = NULL;
  1529. }
  1530. return result;
  1531. }
  1532. //-------------------------------------
  1533. template <class BASE_NPC>
  1534. inline bool CAI_BehaviorHost<BASE_NPC>::CreateComponents()
  1535. {
  1536. if ( BaseClass::CreateComponents() )
  1537. {
  1538. #ifdef DEBUG
  1539. m_fDebugInCreateBehaviors = true;
  1540. #endif
  1541. bool result = CreateBehaviors();
  1542. #ifdef DEBUG
  1543. m_fDebugInCreateBehaviors = false;
  1544. #endif
  1545. return result;
  1546. }
  1547. return false;
  1548. }
  1549. //-----------------------------------------------------------------------------
  1550. #endif // AI_BEHAVIOR_H