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.

645 lines
21 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef NPC_STRIDER_H
  7. #define NPC_STRIDER_H
  8. #include "ai_blended_movement.h"
  9. #include "ai_pathfinder.h"
  10. #include "ai_navigator.h"
  11. #include "ai_utils.h"
  12. #include "smoke_trail.h"
  13. #include "physics_bone_follower.h"
  14. #include "physics_prop_ragdoll.h"
  15. #if defined( _WIN32 )
  16. #pragma once
  17. #endif
  18. #include "tier0/memdbgon.h"
  19. class CNPC_Strider;
  20. class CNPC_Bullseye;
  21. class CStriderMinigun;
  22. //-----------------------------------------------------------------------------
  23. //
  24. // Support for moving Strider air nodes to the correct Z for the Strider
  25. // regardless of Hammer placement
  26. //
  27. //-----------------------------------------------------------------------------
  28. class CAI_Network;
  29. class CAI_Node;
  30. struct StriderMinigunViewcone_t;
  31. struct AI_EnemyInfo_t;
  32. void AdjustStriderNodePosition( CAI_Network *pNetwork, CAI_Node *pNode );
  33. //-----------------------------------------------------------------------------
  34. //
  35. // Strider Minigun
  36. //
  37. //-----------------------------------------------------------------------------
  38. abstract_class IMinigunHost
  39. {
  40. public:
  41. virtual void ShootMinigun( const Vector *pTarget, float aimError, const Vector &vecSpread = vec3_origin ) = 0;
  42. virtual void UpdateMinigunControls( float &yaw, float &pitch ) = 0;
  43. virtual void GetViewCone( StriderMinigunViewcone_t &cone ) = 0;
  44. virtual void NewTarget() = 0;
  45. virtual void OnMinigunStartShooting( CBaseEntity *pTarget ) = 0;
  46. virtual void OnMinigunStopShooting( CBaseEntity *pTarget ) = 0;
  47. virtual CAI_BaseNPC *GetEntity() = 0;
  48. };
  49. abstract_class IStriderMinigunHost : public IMinigunHost
  50. {
  51. public:
  52. virtual float GetMinigunRateOfFire() = 0;
  53. virtual float GetMinigunOnTargetTime() = 0;
  54. virtual float GetMinigunShootDuration() = 0;
  55. virtual float GetMinigunShootDowntime() = 0;
  56. virtual float GetMinigunShootVariation() = 0;
  57. };
  58. //-----------------------------------------------------------------------------
  59. //
  60. // npc_strider
  61. //
  62. //-----------------------------------------------------------------------------
  63. const int NUM_STRIDER_IK_TARGETS = 6;
  64. //---------------------------------------------------------
  65. class CNPC_Strider : public CAI_BlendingHost<CAI_BaseNPC>,
  66. public IStriderMinigunHost
  67. {
  68. DECLARE_CLASS( CNPC_Strider, CAI_BaseNPC );
  69. DECLARE_SERVERCLASS();
  70. public:
  71. CNPC_Strider();
  72. ~CNPC_Strider();
  73. //---------------------------------
  74. void Precache();
  75. void Spawn();
  76. bool CreateVPhysics();
  77. void InitBoneFollowers( void );
  78. void PostNPCInit();
  79. void Activate();
  80. void UpdateOnRemove();
  81. void InitBoneControllers();
  82. void OnRestore();
  83. Class_T Classify();
  84. bool ShouldAttractAutoAim( CBaseEntity *pAimingEnt );
  85. virtual float GetAutoAimRadius() { return 80.0f; }
  86. int DrawDebugTextOverlays();
  87. void UpdateEfficiency( bool bInPVS ) { SetEfficiency( ( GetSleepState() != AISS_AWAKE ) ? AIE_DORMANT : AIE_NORMAL ); SetMoveEfficiency( AIME_NORMAL ); }
  88. virtual bool ShouldProbeCollideAgainstEntity( CBaseEntity *pEntity );
  89. //---------------------------------
  90. virtual Vector GetNodeViewOffset() { return BaseClass::GetDefaultEyeOffset(); }
  91. Vector EyePosition();
  92. const Vector & GetViewOffset();
  93. Vector EyePositionCrouched() { return GetAbsOrigin() - Vector( 0, 0, 330 ); }
  94. //---------------------------------
  95. // CBaseAnimating
  96. void CalculateIKLocks( float currentTime );
  97. float GetIdealAccel() const { return GetIdealSpeed(); }
  98. //---------------------------------
  99. // Behavior
  100. //---------------------------------
  101. void NPCThink();
  102. void PrescheduleThink();
  103. void GatherConditions();
  104. void CheckFlinches() {} // Strider handles on own
  105. void GatherHeightConditions( const Vector &vTestPos, CBaseEntity *pEntity );
  106. void OnStateChange( NPC_STATE oldState, NPC_STATE newState );
  107. void BuildScheduleTestBits();
  108. int SelectSchedule();
  109. int TranslateSchedule( int scheduleType );
  110. void StartTask( const Task_t *pTask );
  111. void RunTask( const Task_t *pTask );
  112. bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt );
  113. void HandleAnimEvent( animevent_t *pEvent );
  114. Disposition_t IRelationType( CBaseEntity *pTarget );
  115. void AddEntityRelationship( CBaseEntity *pEntity, Disposition_t nDisposition, int nPriority );
  116. bool ScheduledMoveToGoalEntity( int scheduleType, CBaseEntity *pGoalEntity, Activity movementActivity );
  117. bool ScheduledFollowPath( int scheduleType, CBaseEntity *pPathStart, Activity movementActivity );
  118. //---------------------------------
  119. // Inputs
  120. //---------------------------------
  121. void InputSetMinigunTime( inputdata_t &inputdata );
  122. void InputSetMinigunTarget( inputdata_t &inputdata );
  123. void InputDisableMinigun( inputdata_t &inputdata );
  124. void InputEnableMinigun( inputdata_t &inputdata );
  125. void InputSetCannonTarget( inputdata_t &inputdata );
  126. void InputFlickRagdoll( inputdata_t &inputdata );
  127. void InputDisableCollisionWith( inputdata_t &inputdata );
  128. void InputEnableCollisionWith( inputdata_t &inputdata );
  129. void InputCrouch( inputdata_t &inputdata );
  130. void InputCrouchInstantly( inputdata_t &inputdata );
  131. void InputStand( inputdata_t &inputdata );
  132. void InputSetHeight( inputdata_t &inputdata );
  133. void InputSetTargetPath( inputdata_t &inputdata );
  134. void InputClearTargetPath( inputdata_t &inputdata );
  135. void InputDisableCrouchWalk( inputdata_t &inputdata );
  136. void InputEnableCrouchWalk( inputdata_t &inputdata );
  137. void InputEnableAggressiveBehavior( inputdata_t &inputdata );
  138. void InputDisableAggressiveBehavior( inputdata_t &inputdata );
  139. void InputStopShootingMinigunForSeconds( inputdata_t &inputdata );
  140. void InputDisableCrouch( inputdata_t &inputdata );
  141. void InputDisableMoveToLOS( inputdata_t &inputdata );
  142. void InputExplode( inputdata_t &inputdata );
  143. void InputScaleGroundSpeed( inputdata_t &inputdata );
  144. //---------------------------------
  145. // Combat
  146. //---------------------------------
  147. bool HasPass() { return m_PlayerFreePass.HasPass(); }
  148. bool FVisible( CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL );
  149. Vector BodyTarget( const Vector &posSrc, bool bNoisy );
  150. bool IsValidEnemy( CBaseEntity *pTarget );
  151. bool UpdateEnemyMemory( CBaseEntity *pEnemy, const Vector &position, CBaseEntity *pInformer = NULL );
  152. float StriderEnemyDistance( CBaseEntity *pEnemy );
  153. bool FCanCheckAttacks();
  154. int RangeAttack2Conditions( float flDot, float flDist );
  155. int MeleeAttack1Conditions( float flDot, float flDist );
  156. int MeleeAttack2Conditions( float flDot, float flDist );
  157. bool WeaponLOSCondition(const Vector &ownerPos, const Vector &targetPos, bool bSetConditions);
  158. bool CurrentWeaponLOSCondition(const Vector &targetPos, bool bSetConditions);
  159. bool IsValidShootPosition ( const Vector &vecCoverLocation, CAI_Node *pNode, CAI_Hint const *pHint );
  160. bool TestShootPosition(const Vector &vecShootPos, const Vector &targetPos );
  161. Vector Weapon_ShootPosition();
  162. void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType );
  163. void DoImpactEffect( trace_t &tr, int nDamageType );
  164. void DoMuzzleFlash( void );
  165. bool CanShootThrough( const trace_t &tr, const Vector &vecTarget );
  166. void CreateFocus();
  167. CNPC_Bullseye * GetFocus();
  168. bool GetWeaponLosZ( const Vector &vOrigin, float minZ, float maxZ, float increment, CBaseEntity *pTarget, float *pResult );
  169. //---------------------------------
  170. // Sounds & speech
  171. //---------------------------------
  172. void AlertSound();
  173. void PainSound( const CTakeDamageInfo &info );
  174. void DeathSound( const CTakeDamageInfo &info );
  175. void HuntSound();
  176. //---------------------------------
  177. // Damage handling
  178. //---------------------------------
  179. void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
  180. int OnTakeDamage_Alive( const CTakeDamageInfo &info );
  181. int TakeDamageFromCombineBall( const CTakeDamageInfo &info );
  182. void Event_Killed( const CTakeDamageInfo &info );
  183. void RagdollDeathEffect( CRagdollProp *pRagdoll, float flDuration );
  184. bool BecomeRagdoll( const CTakeDamageInfo &info, const Vector &forceVector );
  185. void StartSmoking();
  186. void StopSmoking( float flDelay = 0.1 );
  187. bool IsSmoking() { return m_hSmoke != NULL; }
  188. void Explode();
  189. //---------------------------------
  190. // Posture
  191. //---------------------------------
  192. float GetMaxHeightModel() const { return 500.0; }
  193. float GetMaxHeight() const { return 490.0; }
  194. float GetMinHeight() const { return 200.0; }
  195. float GetHeightRange() const { return GetMaxHeight() - GetMinHeight(); }
  196. void SetHeight( float h );
  197. float GetHeight() { return GetPoseParameter( gm_BodyHeightPoseParam ); }
  198. void SetIdealHeight( float h );
  199. void SetAbsIdealHeight( float z );
  200. float GetIdealHeight() { return m_idealHeight; }
  201. Vector GetAdjustedOrigin() { Vector result = GetAbsOrigin(); result.z -= GetMaxHeightModel() - GetHeight(); return result; }
  202. bool IsInCrouchedPosture() { return GetIdealHeight() < GetMaxHeight() * .5; }
  203. bool IsInStandingPosture() { return !IsInCrouchedPosture(); }
  204. bool IsStriderCrouching();
  205. bool IsStriderStanding();
  206. void SetupGlobalModelData();
  207. virtual bool CanBecomeServerRagdoll( void ) { return false; }
  208. //---------------------------------
  209. // Navigation & Movement
  210. //---------------------------------
  211. class CNavigator : public CAI_ComponentWithOuter<CNPC_Strider, CAI_Navigator>
  212. {
  213. typedef CAI_ComponentWithOuter<CNPC_Strider, CAI_Navigator> BaseClass;
  214. public:
  215. CNavigator( CNPC_Strider *pOuter )
  216. : BaseClass( pOuter )
  217. {
  218. }
  219. void MoveCalcBaseGoal( AILocalMoveGoal_t *pMoveGoal );
  220. bool MoveUpdateWaypoint( AIMoveResult_t *pResult );
  221. bool DoFindPathToPos();
  222. bool ShouldOptimizeInitialPathSegment( AI_Waypoint_t *pFirstWaypoint );
  223. bool GetStoppingPath( CAI_WaypointList *pClippedWaypoints );
  224. };
  225. class CPathfinder : public CAI_Pathfinder
  226. {
  227. typedef CAI_Pathfinder BaseClass;
  228. public:
  229. CPathfinder( CNPC_Strider *pOuter ) : BaseClass( pOuter ) {}
  230. virtual bool CanUseLocalNavigation() { return false; }
  231. };
  232. friend class CNavigator;
  233. friend void AdjustStriderNodePosition( CAI_Network *pNetwork, CAI_Node *pNode );
  234. bool OverrideMove( float flInterval );
  235. void MaintainTurnActivity( void );
  236. bool IsUnusableNode(int iNodeID, CAI_Hint *pHint); // Override for special NPC behavior
  237. void TranslateNavGoal( CBaseEntity *pEnemy, Vector &chasePosition );
  238. bool HasPendingTargetPath();
  239. void SetTargetPath();
  240. float GetDefaultNavGoalTolerance();
  241. void OnMovementComplete();
  242. float GetSequenceGroundSpeed( CStudioHdr *pStudioHdr, int iSequence );
  243. float MaxYawSpeed();
  244. CAI_Navigator * CreateNavigator() { return new CNavigator( this ); }
  245. CAI_Pathfinder *CreatePathfinder() { return new CPathfinder( this ); }
  246. //---------------------------------
  247. // Minigun
  248. //---------------------------------
  249. void ShootMinigun( const Vector *pTarget, float aimError, const Vector &vecSpread = vec3_origin );
  250. void UpdateMinigunControls( float &yaw, float &pitch );
  251. void GetViewCone( StriderMinigunViewcone_t &cone );
  252. void NewTarget() { m_flTargetAcquiredTime = gpGlobals->curtime; }
  253. void OnMinigunStartShooting( CBaseEntity *pTarget ) {};
  254. void OnMinigunStopShooting( CBaseEntity *pTarget );
  255. float GetMinigunRateOfFire();
  256. float GetMinigunOnTargetTime();
  257. float GetMinigunShootDuration();
  258. float GetMinigunShootDowntime();
  259. float GetMinigunShootVariation();
  260. CAI_BaseNPC * GetEntity() { return this; }
  261. bool IsUsingAggressiveBehavior() { return m_bUseAggressiveBehavior; }
  262. //---------------------------------
  263. // Cannon
  264. //---------------------------------
  265. Vector CannonPosition();
  266. CBaseEntity * GetCannonTarget();
  267. bool HasCannonTarget() const;
  268. bool IsCannonTarget( CBaseEntity *pTarget ) const;
  269. bool AimCannonAt( CBaseEntity *pEntity, float flInterval );
  270. void FireCannon();
  271. void CannonHitThink();
  272. //---------------------------------
  273. // Collision handling
  274. //---------------------------------
  275. void VPhysicsShadowCollision( int index, gamevcollisionevent_t *pEvent );
  276. bool TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace );
  277. // Conservative collision volumes
  278. static float gm_strideLength;
  279. #ifdef HL2_EPISODIC
  280. void StriderBusterAttached( CBaseEntity *pAttached );
  281. void StriderBusterDetached( CBaseEntity *pAttached );
  282. #endif // HL2_EPISODIC
  283. public:
  284. //---------------------------------
  285. // Misc
  286. //---------------------------------
  287. bool CarriedByDropship();
  288. void CarriedThink();
  289. //---------------------------------
  290. // Foot handling
  291. //---------------------------------
  292. Vector LeftFootHit( float eventtime );
  293. Vector RightFootHit( float eventtime );
  294. Vector BackFootHit( float eventtime );
  295. void StompHit( int followerBoneIndex );
  296. void FootFX( const Vector &origin );
  297. Vector CalculateStompHitPosition( CBaseEntity *pEnemy );
  298. bool IsLegBoneFollower( CBoneFollower *pFollower );
  299. CBoneFollower *GetBoneFollowerByIndex( int nIndex );
  300. int GetBoneFollowerIndex( CBoneFollower *pFollower );
  301. protected:
  302. // Because the strider is a leaf class, we can use
  303. // static variables to store this information, and save some memory.
  304. // Should the strider end up having inheritors, their activate may
  305. // stomp these numbers, in which case you should make these ordinary members
  306. // again.
  307. //
  308. // The strider also caches some pose parameters in SetupGlobalModelData().
  309. static int m_poseMiniGunYaw, m_poseMiniGunPitch;
  310. static bool m_sbStaticPoseParamsLoaded;
  311. virtual void PopulatePoseParameters( void );
  312. private:
  313. bool ShouldExplodeFromDamage( const CTakeDamageInfo &info );
  314. bool m_bExploding;
  315. //-----------------------------------------------------
  316. // Conditions, Schedules, Tasks
  317. //-----------------------------------------------------
  318. enum
  319. {
  320. SCHED_STRIDER_RANGE_ATTACK1 = BaseClass::NEXT_SCHEDULE,
  321. SCHED_STRIDER_RANGE_ATTACK2, // Immolator
  322. SCHED_STRIDER_CROUCH,
  323. SCHED_STRIDER_STAND,
  324. SCHED_STRIDER_DODGE,
  325. SCHED_STRIDER_STOMPL,
  326. SCHED_STRIDER_STOMPR,
  327. SCHED_STRIDER_FLICKL,
  328. SCHED_STRIDER_FLICKR,
  329. SCHED_STRIDER_HUNT,
  330. SCHED_STRIDER_DIE,
  331. SCHED_STRIDER_ATTACK_CANNON_TARGET,
  332. SCHED_STRIDER_CHASE_ENEMY,
  333. SCHED_STRIDER_COMBAT_FACE,
  334. SCHED_STRIDER_AGGRESSIVE_COMBAT_STAND,
  335. SCHED_STRIDER_ESTABLISH_LINE_OF_FIRE_CANNON,
  336. SCHED_STRIDER_FALL_TO_GROUND,
  337. TASK_STRIDER_AIM = BaseClass::NEXT_TASK,
  338. TASK_STRIDER_DODGE,
  339. TASK_STRIDER_STOMP,
  340. TASK_STRIDER_BREAKDOWN,
  341. TASK_STRIDER_START_MOVING,
  342. TASK_STRIDER_REFRESH_HUNT_PATH,
  343. TASK_STRIDER_GET_PATH_TO_CANNON_TARGET,
  344. TASK_STRIDER_FACE_CANNON_TARGET,
  345. TASK_STRIDER_SET_HEIGHT,
  346. TASK_STRIDER_GET_PATH_TO_CANNON_LOS,
  347. TASK_STRIDER_SET_CANNON_HEIGHT,
  348. TASK_STRIDER_FIRE_CANNON,
  349. TASK_STRIDER_FALL_TO_GROUND,
  350. COND_STRIDER_DO_FLICK = BaseClass::NEXT_CONDITION,
  351. COND_TRACK_PATH_GO,
  352. COND_STRIDER_SHOULD_CROUCH,
  353. COND_STRIDER_SHOULD_STAND,
  354. COND_STRIDER_MINIGUN_SHOOTING,
  355. COND_STRIDER_MINIGUN_NOT_SHOOTING,
  356. COND_STRIDER_HAS_CANNON_TARGET,
  357. COND_STRIDER_ENEMY_UPDATED,
  358. COND_STRIDER_HAS_LOS_Z,
  359. };
  360. string_t m_iszStriderBusterName;
  361. string_t m_iszMagnadeClassname;
  362. string_t m_iszHunterClassname;
  363. CStriderMinigun *m_pMinigun;
  364. int m_miniGunAmmo;
  365. int m_miniGunDirectAmmo;
  366. float m_nextShootTime;
  367. float m_nextStompTime;
  368. float m_ragdollTime;
  369. float m_miniGunShootDuration;
  370. float m_aimYaw;
  371. float m_aimPitch;
  372. Vector m_blastHit;
  373. Vector m_blastNormal;
  374. CNetworkVector( m_vecHitPos );
  375. CNetworkArray( Vector, m_vecIKTarget, NUM_STRIDER_IK_TARGETS );
  376. CRandSimTimer m_PostureAnimationTimer;
  377. EHANDLE m_hRagdoll;
  378. EHANDLE m_hCannonTarget;
  379. CSimpleSimTimer m_AttemptCannonLOSTimer;
  380. float m_flSpeedScale;
  381. float m_flTargetSpeedScale;
  382. CSimpleSimTimer m_LowZCorrectionTimer;
  383. // Contained Bone Follower manager
  384. CBoneFollowerManager m_BoneFollowerManager;
  385. int m_BodyTargetBone;
  386. bool m_bDisableBoneFollowers;
  387. int m_iVisibleEnemies;
  388. float m_flTargetAcquiredTime;
  389. bool m_bCrouchLocked; // Designer made the strider crouch. Don't let the AI stand him up.
  390. bool m_bNoCrouchWalk;
  391. bool m_bDontCrouch;
  392. bool m_bNoMoveToLOS;
  393. bool m_bFastCrouch;
  394. bool m_bMinigunEnabled; // If false, minigun disabled by level designer until further notice.
  395. float m_idealHeight;
  396. float m_HeightVelocity;
  397. // FIXME: move to a base class to handle turning for blended movement derived characters
  398. float m_prevYaw;
  399. float m_doTurn;
  400. float m_doLeft;
  401. float m_doRight;
  402. float m_flNextTurnAct;
  403. string_t m_strTrackName;
  404. EHANDLE m_hFocus;
  405. float m_flTimeLastAlertSound;
  406. float m_flTimeNextHuntSound;
  407. bool m_bUseAggressiveBehavior;
  408. float m_flTimePlayerMissileDetected;
  409. EHANDLE m_hPlayersMissile;
  410. bool m_bMinigunUseDirectFire;
  411. CHandle<SmokeTrail> m_hSmoke;
  412. CSimpleSimTimer m_EnemyUpdatedTimer;
  413. CAI_FreePass m_PlayerFreePass;
  414. #ifdef HL2_EPISODIC
  415. CUtlVector< EHANDLE > m_hAttachedBusters; // List of busters attached to us
  416. #endif // HL2_EPISODIC
  417. static float gm_zCannonDist;
  418. static float gm_zMinigunDist;
  419. static Vector gm_vLocalRelativePositionCannon;
  420. static Vector gm_vLocalRelativePositionMinigun;
  421. static int gm_YawControl;
  422. static int gm_PitchControl;
  423. static int gm_CannonAttachment;
  424. static int gm_BodyHeightPoseParam;
  425. DEFINE_CUSTOM_AI;
  426. DECLARE_DATADESC();
  427. };
  428. //-----------------------------------------------------------------------------
  429. //---------------------------------------------------------
  430. enum StriderMinigunPeg_t
  431. {
  432. MINIGUN_PEGGED_DONT_CARE = 0,
  433. MINIGUN_PEGGED_UP,
  434. MINIGUN_PEGGED_DOWN,
  435. MINIGUN_PEGGED_LEFT,
  436. MINIGUN_PEGGED_RIGHT,
  437. };
  438. //---------------------------------------------------------
  439. struct StriderMinigunViewcone_t
  440. {
  441. Vector origin;
  442. Vector axis;
  443. float cosAngle;
  444. float length;
  445. };
  446. //---------------------------------------------------------
  447. struct StriderMinigunAnimController_t
  448. {
  449. float current;
  450. float target;
  451. float rate;
  452. void Update( float dt, bool approach = true )
  453. {
  454. if( approach )
  455. {
  456. current = Approach( target, current, rate * dt );
  457. }
  458. else
  459. {
  460. current = target;
  461. }
  462. }
  463. void Random( float minTarget, float maxTarget, float minRate, float maxRate )
  464. {
  465. target = random->RandomFloat( minTarget, maxTarget );
  466. rate = random->RandomFloat( minRate, maxRate );
  467. }
  468. };
  469. //---------------------------------------------------------
  470. class CStriderMinigun
  471. {
  472. public:
  473. DECLARE_DATADESC();
  474. void Init();
  475. void SetTarget( IStriderMinigunHost *pHost, CBaseEntity *pTarget, bool bOverrideEnemy = false );
  476. CBaseEntity *GetTarget() { return m_hTarget.Get(); }
  477. void Think( IStriderMinigunHost *pHost, float dt );
  478. void SetState( int newState );
  479. bool ShouldFindTarget( IMinigunHost *pHost );
  480. void AimAtPoint( IStriderMinigunHost *pHost, const Vector &vecPoint, bool bSnap = false );
  481. void AimAtTarget( IStriderMinigunHost *pHost, CBaseEntity *pTarget, bool bSnap = false );
  482. void ShootAtTarget( IStriderMinigunHost *pHost, CBaseEntity *pTarget, float shootTime );
  483. void StartShooting( IStriderMinigunHost *pHost, CBaseEntity *pTarget, float duration );
  484. void ExtendShooting( float timeExtend );
  485. void SetShootDuration( float duration );
  486. void StopShootingForSeconds( IStriderMinigunHost *pHost, CBaseEntity *pTarget, float duration );
  487. bool IsPegged( int dir = MINIGUN_PEGGED_DONT_CARE );
  488. bool CanStartShooting( IStriderMinigunHost *pHost, CBaseEntity *pTargetEnt );
  489. float GetBurstTimeRemaining() { return m_burstTime - gpGlobals->curtime; }
  490. void RecordShotOnTarget() { m_iOnTargetShots++; }
  491. void ClearOnTarget() { m_iOnTargetShots = 0; }
  492. bool IsOnTarget( int numShots = 0 ) { return ( numShots == 0 ) ? (m_iOnTargetShots > 0) : (m_iOnTargetShots >= numShots); }
  493. void Enable( IMinigunHost *pHost, bool enable );
  494. float GetAimError();
  495. enum minigunstates_t
  496. {
  497. MINIGUN_OFF = 0,
  498. MINIGUN_SHOOTING = 1,
  499. };
  500. int GetState() { return m_minigunState; }
  501. bool IsShooting() { return GetState() == MINIGUN_SHOOTING; }
  502. private:
  503. bool m_enable;
  504. int m_minigunState;
  505. float m_nextBulletTime; // Minigun is shooting, when can I fire my next bullet?
  506. float m_burstTime; // If firing, how long till done? If not, how long till I can?
  507. float m_nextTwitchTime;
  508. int m_randomState;
  509. EHANDLE m_hTarget;
  510. StriderMinigunAnimController_t m_yaw;
  511. StriderMinigunAnimController_t m_pitch;
  512. bool m_bWarnedAI;
  513. float m_shootDuration;
  514. Vector m_vecAnchor; // A burst starts here and goes to the target's orgin.
  515. bool m_bOverrideEnemy; // The minigun wants something other than the Strider's enemy as a target right now.
  516. Vector m_vecLastTargetPos; // Last place minigun saw the target.
  517. int m_iOnTargetShots;
  518. };
  519. class CSparkTrail : public CPointEntity
  520. {
  521. DECLARE_CLASS( CSparkTrail, CPointEntity );
  522. void Spawn( void );
  523. void SparkThink( void );
  524. virtual void Precache();
  525. DECLARE_DATADESC();
  526. };
  527. #include "tier0/memdbgoff.h"
  528. #endif // NPC_STRIDER_H
  529. //=============================================================================