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.

239 lines
6.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef NPC_BARNACLE_H
  7. #define NPC_BARNACLE_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "ai_basenpc.h"
  12. #include "studio.h"
  13. #include "physics_prop_ragdoll.h"
  14. class CNPC_Barnacle;
  15. #define BARNACLE_PULL_SPEED 80
  16. #define BARNACLE_KILL_VICTIM_DELAY 5 // how many seconds after pulling prey in to gib them.
  17. // Tongue
  18. #define BARNACLE_TONGUE_POINTS 8
  19. #define BARNACLE_MIN_PULL_TIME 3.0f
  20. #define NUM_BARNACLE_GIBS 4
  21. #define SF_BARNACLE_CHEAP_DEATH (1<<16) // Don't spawn as many gibs
  22. #define SF_BARNACLE_AMBUSH (1<<17) // Start with tongue retracted and wait for input.
  23. // when true, causes the barnacle's visible tongue to offset
  24. // from the physical one when pulling the player.
  25. #define BARNACLE_USE_TONGUE_OFFSET 1
  26. //-----------------------------------------------------------------------------
  27. // Purpose: This is the entity we place at the top & bottom of the tongue, to create a vphysics spring
  28. //-----------------------------------------------------------------------------
  29. class CBarnacleTongueTip : public CBaseAnimating
  30. {
  31. DECLARE_CLASS( CBarnacleTongueTip, CBaseAnimating );
  32. public:
  33. DECLARE_DATADESC();
  34. virtual void Spawn( void );
  35. virtual void Precache( void );
  36. virtual void UpdateOnRemove( );
  37. virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
  38. virtual int UpdateTransmitState( void );
  39. bool CreateSpring( CBaseAnimating *pTongueRoot );
  40. static CBarnacleTongueTip *CreateTongueTip( CNPC_Barnacle *pBarnacle, CBaseAnimating *pTongueRoot, const Vector &vecOrigin, const QAngle &vecAngles );
  41. static CBarnacleTongueTip *CreateTongueRoot( const Vector &vecOrigin, const QAngle &vecAngles );
  42. IPhysicsSpring *m_pSpring;
  43. private:
  44. CHandle<CNPC_Barnacle> m_hBarnacle;
  45. };
  46. //-----------------------------------------------------------------------------
  47. // Purpose:
  48. //-----------------------------------------------------------------------------
  49. class CNPC_Barnacle : public CAI_BaseNPC
  50. {
  51. DECLARE_CLASS( CNPC_Barnacle, CAI_BaseNPC );
  52. public:
  53. DECLARE_SERVERCLASS();
  54. DECLARE_DATADESC();
  55. CNPC_Barnacle();
  56. ~CNPC_Barnacle();
  57. void Spawn( void );
  58. virtual void Activate( void );
  59. void Precache( void );
  60. Class_T Classify ( void );
  61. virtual void ComputeWorldSpaceSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs );
  62. virtual void HandleAnimEvent( animevent_t *pEvent );
  63. void Event_Killed( const CTakeDamageInfo &info );
  64. int OnTakeDamage_Alive( const CTakeDamageInfo &info );
  65. void PlayerHasIlluminatedNPC( CBasePlayer *pPlayer, float flDot );
  66. // The tongue's vphysics updated
  67. void OnTongueTipUpdated();
  68. private:
  69. void SetAltitude( float flAltitude );
  70. void SpawnDeathGibs( void );
  71. void InitTonguePosition( void );
  72. CBaseEntity* TongueTouchEnt ( float *pflLength );
  73. void BarnacleThink ( void );
  74. void SwallowPrey( void );
  75. void WaitTillDead ( void );
  76. void AttachTongueToTarget( CBaseEntity *pTouchEnt, Vector vecGrabPos );
  77. CRagdollProp *AttachRagdollToTongue( CBaseAnimating *pAnimating );
  78. void RemoveRagdoll( bool bDestroyRagdoll );
  79. void LostPrey( bool bRemoveRagdoll );
  80. void BitePrey( void );
  81. // Updates the tongue length
  82. void UpdateTongue( void );
  83. // Spit out the prey; add physics force!
  84. void SpitPrey();
  85. void SprayBlood();
  86. // What type of enemy do we have?
  87. bool IsEnemyAPlayer();
  88. bool IsEnemyARagdoll();
  89. bool IsEnemyAPhysicsObject();
  90. bool IsEnemyAnNPC();
  91. bool CanPickup( CBaseCombatCharacter *pBCC );
  92. // Allows the ragdoll to settle before biting it
  93. bool WaitForRagdollToSettle( float flBiteZOffset );
  94. // Allows the physics prop to settle before biting it
  95. bool WaitForPhysicsObjectToSettle( float flBiteZOffset );
  96. // Play a scream right before biting
  97. void PlayLiftingScream( float flBiteZOffset );
  98. // Pulls the prey upward toward the mouth
  99. void PullEnemyTorwardsMouth( bool bAdjustEnemyOrigin );
  100. // Lift the prey stuck to our tongue up towards our mouth
  101. void LiftPrey( void );
  102. void LiftPlayer( float flBiteZOffset );
  103. void LiftRagdoll( float flBiteZOffset );
  104. void LiftPhysicsObject( float flBiteZOffset );
  105. void LiftNPC( float flBiteZOffset );
  106. void UpdatePlayerConstraint( void );
  107. void InputDropTongue( inputdata_t &inputdata );
  108. void InputSetDropTongueSpeed( inputdata_t &inputdata );
  109. void DropTongue( void );
  110. #if HL2_EPISODIC
  111. /// Decides whether something should poison the barnacle upon eating
  112. static bool IsPoisonous( CBaseEntity *pVictim );
  113. void InputLetGo( inputdata_t &inputdata );
  114. COutputEHANDLE m_OnGrab, m_OnRelease;
  115. const impactdamagetable_t &GetPhysicsImpactDamageTable( void );
  116. #endif
  117. CNetworkVar( float, m_flAltitude );
  118. int m_cGibs; // barnacle loads up on gibs each time it kills something.
  119. bool m_bLiftingPrey; // true when the prey's on the tongue and being lifted to the mouth
  120. bool m_bSwallowingPrey; // if it's a human, true while the barnacle chews it and swallows it whole.
  121. float m_flDigestFinish; // time at which we've finished digesting something we chewed
  122. float m_flVictimHeight;
  123. int m_iGrabbedBoneIndex;
  124. bool m_bPlayedPullSound;
  125. bool m_bPlayerWasStanding;
  126. static const char *m_szGibNames[NUM_BARNACLE_GIBS];
  127. // Tongue spline points
  128. CNetworkVar( Vector, m_vecRoot );
  129. CNetworkVar( Vector, m_vecTip );
  130. CNetworkVar( Vector, m_vecTipDrawOffset );
  131. // Tongue tip & root
  132. CHandle<CBarnacleTongueTip> m_hTongueRoot;
  133. CHandle<CBarnacleTongueTip> m_hTongueTip;
  134. CHandle<CRagdollProp> m_hRagdoll;
  135. matrix3x4_t m_pRagdollBones[MAXSTUDIOBONES];
  136. IPhysicsConstraint *m_pConstraint;
  137. float m_flRestUnitsAboveGround;
  138. int m_nSpitAttachment;
  139. EHANDLE m_hLastSpitEnemy;
  140. int m_nShakeCount;
  141. float m_flNextBloodTime;
  142. #ifndef _XBOX
  143. int m_nBloodColor;
  144. #endif
  145. Vector m_vecBloodPos;
  146. float m_flBarnaclePullSpeed;
  147. float m_flLocalTimer;
  148. Vector m_vLastEnemyPos;
  149. float m_flLastPull;
  150. CSimpleSimTimer m_StuckTimer;
  151. bool m_bSwallowingBomb;
  152. #ifdef HL2_EPISODIC
  153. bool m_bSwallowingPoison;
  154. #endif
  155. #if BARNACLE_USE_TONGUE_OFFSET
  156. // Static because only one barnacle can be holding the player
  157. // at a time, and because it's not really a big deal if it
  158. // resets to zero after reload.
  159. const static Vector m_svPlayerHeldTipOffset;
  160. #endif
  161. DEFINE_CUSTOM_AI;
  162. };
  163. //-----------------------------------------------------------------------------
  164. // What type of enemy do we have?
  165. //-----------------------------------------------------------------------------
  166. inline bool CNPC_Barnacle::IsEnemyAPlayer()
  167. {
  168. return GetEnemy() && GetEnemy()->IsPlayer();
  169. }
  170. inline bool CNPC_Barnacle::IsEnemyARagdoll()
  171. {
  172. return m_hRagdoll != NULL;
  173. }
  174. inline bool CNPC_Barnacle::IsEnemyAPhysicsObject()
  175. {
  176. return !m_hRagdoll && GetEnemy() && !GetEnemy()->IsPlayer() &&
  177. !GetEnemy()->MyNPCPointer() && (GetEnemy()->GetMoveType() == MOVETYPE_VPHYSICS);
  178. }
  179. inline bool CNPC_Barnacle::IsEnemyAnNPC()
  180. {
  181. return !IsEnemyARagdoll() && (GetEnemy()->MyNPCPointer() != NULL);
  182. }
  183. #endif // NPC_BARNACLE_H