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.

440 lines
15 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef PROPS_H
  8. #define PROPS_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "props_shared.h"
  13. #include "baseanimating.h"
  14. #include "physics_bone_follower.h"
  15. #include "player_pickup.h"
  16. #include "positionwatcher.h"
  17. //=============================================================================================================
  18. // PROP TYPES
  19. //=============================================================================================================
  20. //-----------------------------------------------------------------------------
  21. // Purpose:
  22. //-----------------------------------------------------------------------------
  23. class CBaseProp : public CBaseAnimating
  24. {
  25. DECLARE_CLASS( CBaseProp, CBaseAnimating );
  26. public:
  27. void Spawn( void );
  28. void Precache( void );
  29. void Activate( void );
  30. bool KeyValue( const char *szKeyName, const char *szValue );
  31. void CalculateBlockLOS( void );
  32. int ParsePropData( void );
  33. void DrawDebugGeometryOverlays( void );
  34. // Don't treat as a live target
  35. virtual bool IsAlive( void ) { return false; }
  36. virtual bool OverridePropdata() { return true; }
  37. };
  38. //-----------------------------------------------------------------------------
  39. // Purpose:
  40. //-----------------------------------------------------------------------------
  41. class CBreakableProp : public CBaseProp, public IBreakableWithPropData, public CDefaultPlayerPickupVPhysics
  42. {
  43. public:
  44. CBreakableProp();
  45. DECLARE_CLASS( CBreakableProp, CBaseProp );
  46. DECLARE_SERVERCLASS();
  47. DECLARE_DATADESC();
  48. virtual void Spawn();
  49. virtual void Precache();
  50. virtual float GetAutoAimRadius() { return 24.0f; }
  51. void BreakablePropTouch( CBaseEntity *pOther );
  52. virtual int OnTakeDamage( const CTakeDamageInfo &info );
  53. void Event_Killed( const CTakeDamageInfo &info );
  54. void Break( CBaseEntity *pBreaker, const CTakeDamageInfo &info );
  55. void BreakThink( void );
  56. void AnimateThink( void );
  57. virtual void PlayPuntSound();
  58. void InputBreak( inputdata_t &inputdata );
  59. void InputAddHealth( inputdata_t &inputdata );
  60. void InputRemoveHealth( inputdata_t &inputdata );
  61. void InputSetHealth( inputdata_t &inputdata );
  62. int GetNumBreakableChunks( void ) { return m_iNumBreakableChunks; }
  63. virtual bool OverridePropdata() { return false; }
  64. virtual IPhysicsObject *GetRootPhysicsObjectForBreak();
  65. bool PropDataOverrodeBlockLOS( void ) { return m_bBlockLOSSetByPropData; }
  66. bool PropDataOverrodeAIWalkable( void ) { return m_bIsWalkableSetByPropData; }
  67. virtual bool HasPreferredCarryAnglesForPlayer( CBasePlayer *pPlayer )
  68. {
  69. if ( HasInteraction( PROPINTER_PHYSGUN_LAUNCH_SPIN_Z ) )
  70. return true;
  71. return false;
  72. }
  73. virtual QAngle PreferredCarryAngles( void ) { return m_preferredCarryAngles; }
  74. virtual void Ignite( float flFlameLifetime, bool bNPCOnly, float flSize = 0.0f, bool bCalledByLevelDesigner = false );
  75. // Specific interactions
  76. void HandleFirstCollisionInteractions( int index, gamevcollisionevent_t *pEvent );
  77. void HandleInteractionStick( int index, gamevcollisionevent_t *pEvent );
  78. void StickAtPosition( const Vector &stickPosition, const Vector &savePosition, const QAngle &saveAngles );
  79. // Disable auto fading under dx7 or when level fades are specified
  80. void DisableAutoFade();
  81. public:
  82. COutputEvent m_OnBreak;
  83. COutputFloat m_OnHealthChanged;
  84. COutputEvent m_OnTakeDamage;
  85. float m_impactEnergyScale;
  86. int m_iMinHealthDmg;
  87. QAngle m_preferredCarryAngles;
  88. public:
  89. // IBreakableWithPropData
  90. void SetDmgModBullet( float flDmgMod ) { m_flDmgModBullet = flDmgMod; }
  91. void SetDmgModClub( float flDmgMod ) { m_flDmgModClub = flDmgMod; }
  92. void SetDmgModExplosive( float flDmgMod ) { m_flDmgModExplosive = flDmgMod; }
  93. float GetDmgModBullet( void ) { return m_flDmgModBullet; }
  94. float GetDmgModClub( void ) { return m_flDmgModClub; }
  95. float GetDmgModExplosive( void ) { return m_flDmgModExplosive; }
  96. void SetExplosiveRadius( float flRadius ) { m_explodeRadius = flRadius; }
  97. void SetExplosiveDamage( float flDamage ) { m_explodeDamage = flDamage; }
  98. float GetExplosiveRadius( void ) { return m_explodeRadius; }
  99. float GetExplosiveDamage( void ) { return m_explodeDamage; }
  100. void SetPhysicsDamageTable( string_t iszTableName ) { m_iszPhysicsDamageTableName = iszTableName; }
  101. string_t GetPhysicsDamageTable( void ) { return m_iszPhysicsDamageTableName; }
  102. void SetBreakableModel( string_t iszModel ) { m_iszBreakableModel = iszModel; }
  103. string_t GetBreakableModel( void ) { return m_iszBreakableModel; }
  104. void SetBreakableSkin( int iSkin ) { m_iBreakableSkin = iSkin; }
  105. int GetBreakableSkin( void ) { return m_iBreakableSkin; }
  106. void SetBreakableCount( int iCount ) { m_iBreakableCount = iCount; }
  107. int GetBreakableCount( void ) { return m_iBreakableCount; }
  108. void SetMaxBreakableSize( int iSize ) { m_iMaxBreakableSize = iSize; }
  109. int GetMaxBreakableSize( void ) { return m_iMaxBreakableSize; }
  110. void SetPropDataBlocksLOS( bool bBlocksLOS ) { m_bBlockLOSSetByPropData = true; SetBlocksLOS( bBlocksLOS ); }
  111. void SetPropDataIsAIWalkable( bool b ) { m_bIsWalkableSetByPropData = true; SetAIWalkable( b ); }
  112. void SetBasePropData( string_t iszBase ) { m_iszBasePropData = iszBase; }
  113. string_t GetBasePropData( void ) { return m_iszBasePropData; }
  114. void SetInteraction( propdata_interactions_t Interaction ) { m_iInteractions |= (1 << Interaction); }
  115. void RemoveInteraction( propdata_interactions_t Interaction ) { m_iInteractions &= ~(1 << Interaction); }
  116. bool HasInteraction( propdata_interactions_t Interaction ) { return ( m_iInteractions & (1 << Interaction) ) != 0; }
  117. void SetMultiplayerBreakMode( mp_break_t mode ) { m_mpBreakMode = mode; }
  118. mp_break_t GetMultiplayerBreakMode( void ) const { return m_mpBreakMode; }
  119. // derived by multiplayer phys props:
  120. virtual void SetPhysicsMode(int iMode) {}
  121. virtual int GetPhysicsMode() { return PHYSICS_MULTIPLAYER_SOLID; }
  122. // Copy fade from another breakable prop
  123. void CopyFadeFrom( CBreakableProp *pSource );
  124. protected:
  125. bool UpdateHealth( int iNewHealth, CBaseEntity *pActivator );
  126. virtual void OnBreak( const Vector &vecVelocity, const AngularImpulse &angVel, CBaseEntity *pBreaker ) {}
  127. protected:
  128. unsigned int m_createTick;
  129. float m_flPressureDelay;
  130. EHANDLE m_hBreaker;
  131. PerformanceMode_t m_PerformanceMode;
  132. // Prop data storage
  133. float m_flDmgModBullet;
  134. float m_flDmgModClub;
  135. float m_flDmgModExplosive;
  136. string_t m_iszPhysicsDamageTableName;
  137. string_t m_iszBreakableModel;
  138. int m_iBreakableSkin;
  139. int m_iBreakableCount;
  140. int m_iMaxBreakableSize;
  141. string_t m_iszBasePropData;
  142. int m_iInteractions;
  143. float m_explodeDamage;
  144. float m_explodeRadius;
  145. string_t m_iszBreakModelMessage;
  146. // Count of how many pieces we'll break into, custom or generic
  147. int m_iNumBreakableChunks;
  148. void SetEnableMotionPosition( const Vector &position, const QAngle &angles );
  149. bool GetEnableMotionPosition( Vector *pPosition, QAngle *pAngles );
  150. void ClearEnableMotionPosition();
  151. private:
  152. CBaseEntity *FindEnableMotionFixup();
  153. public:
  154. virtual bool OnAttemptPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
  155. virtual void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
  156. virtual void OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t reason );
  157. virtual AngularImpulse PhysGunLaunchAngularImpulse();
  158. virtual CBasePlayer *HasPhysicsAttacker( float dt );
  159. #ifdef HL2_EPISODIC
  160. void CreateFlare( float flLifetime );
  161. #endif //HL2_EPISODIC
  162. protected:
  163. void SetPhysicsAttacker( CBasePlayer *pEntity, float flTime );
  164. void CheckRemoveRagdolls();
  165. private:
  166. void InputEnablePhyscannonPickup( inputdata_t &inputdata );
  167. void InputDisablePhyscannonPickup( inputdata_t &inputdata );
  168. void InputEnablePuntSound( inputdata_t &inputdata ) { m_bUsePuntSound = true; }
  169. void InputDisablePuntSound( inputdata_t &inputdata ) { m_bUsePuntSound = false; }
  170. // Prevents fade scale from happening
  171. void ForceFadeScaleToAlwaysVisible();
  172. void RampToDefaultFadeScale();
  173. private:
  174. enum PhysgunState_t
  175. {
  176. PHYSGUN_MUST_BE_DETACHED = 0,
  177. PHYSGUN_IS_DETACHING,
  178. PHYSGUN_CAN_BE_GRABBED,
  179. PHYSGUN_ANIMATE_ON_PULL,
  180. PHYSGUN_ANIMATE_IS_ANIMATING,
  181. PHYSGUN_ANIMATE_FINISHED,
  182. PHYSGUN_ANIMATE_IS_PRE_ANIMATING,
  183. PHYSGUN_ANIMATE_IS_POST_ANIMATING,
  184. };
  185. CHandle<CBasePlayer> m_hPhysicsAttacker;
  186. float m_flLastPhysicsInfluenceTime;
  187. bool m_bBlockLOSSetByPropData;
  188. bool m_bIsWalkableSetByPropData;
  189. bool m_bOriginalBlockLOS; // BlockLOS state before physgun pickup
  190. char m_nPhysgunState; // Ripped-off state
  191. COutputEvent m_OnPhysCannonDetach; // We've ripped it off!
  192. COutputEvent m_OnPhysCannonAnimatePreStarted; // Started playing the pre-pull animation
  193. COutputEvent m_OnPhysCannonAnimatePullStarted; // Player started the pull anim
  194. COutputEvent m_OnPhysCannonAnimatePostStarted; // Started playing the post-pull animation
  195. COutputEvent m_OnPhysCannonPullAnimFinished; // We've had our pull anim finished, or the post-pull has finished if there is one
  196. float m_flDefaultFadeScale; // Things may temporarily change the fade scale, but this is its steady-state condition
  197. mp_break_t m_mpBreakMode;
  198. EHANDLE m_hLastAttacker; // Last attacker that harmed me.
  199. EHANDLE m_hFlareEnt;
  200. string_t m_iszPuntSound;
  201. bool m_bUsePuntSound;
  202. };
  203. // Spawnflags
  204. #define SF_DYNAMICPROP_USEHITBOX_FOR_RENDERBOX 64
  205. #define SF_DYNAMICPROP_NO_VPHYSICS 128
  206. #define SF_DYNAMICPROP_DISABLE_COLLISION 256
  207. //-----------------------------------------------------------------------------
  208. // Purpose:
  209. //-----------------------------------------------------------------------------
  210. class CDynamicProp : public CBreakableProp, public IPositionWatcher
  211. {
  212. DECLARE_CLASS( CDynamicProp, CBreakableProp );
  213. public:
  214. DECLARE_SERVERCLASS();
  215. DECLARE_DATADESC();
  216. CDynamicProp();
  217. void Spawn( void );
  218. bool CreateVPhysics( void );
  219. void CreateBoneFollowers();
  220. void UpdateOnRemove( void );
  221. void AnimThink( void );
  222. void PropSetSequence( int nSequence );
  223. void OnRestore( void );
  224. bool OverridePropdata( void );
  225. void HandleAnimEvent( animevent_t *pEvent );
  226. // baseentity - watch dynamic hierarchy updates
  227. virtual void SetParent( CBaseEntity* pNewParent, int iAttachment = -1 );
  228. bool TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace );
  229. // breakable prop
  230. virtual IPhysicsObject *GetRootPhysicsObjectForBreak();
  231. // IPositionWatcher
  232. virtual void NotifyPositionChanged( CBaseEntity *pEntity );
  233. // Input handlers
  234. void InputSetAnimation( inputdata_t &inputdata );
  235. void InputSetDefaultAnimation( inputdata_t &inputdata );
  236. void InputTurnOn( inputdata_t &inputdata );
  237. void InputTurnOff( inputdata_t &inputdata );
  238. void InputDisableCollision( inputdata_t &inputdata );
  239. void InputEnableCollision( inputdata_t &inputdata );
  240. void InputSetPlaybackRate( inputdata_t &inputdata );
  241. COutputEvent m_pOutputAnimBegun;
  242. COutputEvent m_pOutputAnimOver;
  243. string_t m_iszDefaultAnim;
  244. int m_iGoalSequence;
  245. int m_iTransitionDirection;
  246. // Random animations
  247. bool m_bRandomAnimator;
  248. float m_flNextRandAnim;
  249. float m_flMinRandAnimTime;
  250. float m_flMaxRandAnimTime;
  251. short m_nPendingSequence;
  252. bool m_bStartDisabled;
  253. bool m_bDisableBoneFollowers;
  254. CNetworkVar( bool, m_bUseHitboxesForRenderBox );
  255. protected:
  256. void FinishSetSequence( int nSequence );
  257. void PropSetAnim( const char *szAnim );
  258. void BoneFollowerHierarchyChanged();
  259. // Contained Bone Follower manager
  260. CBoneFollowerManager m_BoneFollowerManager;
  261. };
  262. //-----------------------------------------------------------------------------
  263. // Purpose:
  264. //-----------------------------------------------------------------------------
  265. DECLARE_AUTO_LIST( IPhysicsPropAutoList );
  266. class CPhysicsProp : public CBreakableProp, public IPhysicsPropAutoList
  267. {
  268. DECLARE_CLASS( CPhysicsProp, CBreakableProp );
  269. DECLARE_SERVERCLASS();
  270. public:
  271. ~CPhysicsProp();
  272. CPhysicsProp( void )
  273. {
  274. }
  275. void Spawn( void );
  276. void Precache();
  277. bool CreateVPhysics( void );
  278. bool OverridePropdata( void );
  279. virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
  280. virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
  281. void InputWake( inputdata_t &inputdata );
  282. void InputSleep( inputdata_t &inputdata );
  283. void InputEnableMotion( inputdata_t &inputdata );
  284. void InputDisableMotion( inputdata_t &inputdata );
  285. void InputDisableFloating( inputdata_t &inputdata );
  286. void EnableMotion( void );
  287. bool CanBePickedUpByPhyscannon( void );
  288. void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
  289. void OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t reason );
  290. bool GetPropDataAngles( const char *pKeyName, QAngle &vecAngles );
  291. float GetCarryDistanceOffset( void );
  292. int ObjectCaps();
  293. void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
  294. void GetMassCenter( Vector *pMassCenter );
  295. float GetMass() const;
  296. void ClearFlagsThink( void );
  297. virtual int OnTakeDamage( const CTakeDamageInfo &info );
  298. int DrawDebugTextOverlays(void);
  299. bool IsGib();
  300. DECLARE_DATADESC();
  301. // Specific interactions
  302. void HandleAnyCollisionInteractions( int index, gamevcollisionevent_t *pEvent );
  303. string_t GetPhysOverrideScript( void ) { return m_iszOverrideScript; }
  304. float GetMassScale( void ) { return m_massScale; }
  305. private:
  306. // Compute impulse to apply to the enabled entity.
  307. void ComputeEnablingImpulse( int index, gamevcollisionevent_t *pEvent );
  308. COutputEvent m_MotionEnabled;
  309. COutputEvent m_OnAwakened;
  310. COutputEvent m_OnPhysGunPickup;
  311. COutputEvent m_OnPhysGunPunt;
  312. COutputEvent m_OnPhysGunOnlyPickup;
  313. COutputEvent m_OnPhysGunDrop;
  314. COutputEvent m_OnPlayerUse;
  315. COutputEvent m_OnPlayerPickup;
  316. COutputEvent m_OnOutOfWorld;
  317. float m_massScale;
  318. float m_inertiaScale;
  319. int m_damageType;
  320. string_t m_iszOverrideScript;
  321. int m_damageToEnableMotion;
  322. float m_flForceToEnableMotion;
  323. bool m_bThrownByPlayer;
  324. bool m_bFirstCollisionAfterLaunch;
  325. protected:
  326. CNetworkVar( bool, m_bAwake );
  327. };
  328. // An interface so that objects parented to props can receive collision interaction events.
  329. enum parentCollisionInteraction_t
  330. {
  331. COLLISIONINTER_PARENT_FIRST_IMPACT = 1,
  332. };
  333. abstract_class IParentPropInteraction
  334. {
  335. public:
  336. virtual void OnParentCollisionInteraction( parentCollisionInteraction_t eType, int index, gamevcollisionevent_t *pEvent ) = 0;
  337. virtual void OnParentPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reason ) = 0;
  338. };
  339. // Used by prop_physics_create and the server benchmark.
  340. // pModelName should not include the "models/" prefix.
  341. CPhysicsProp* CreatePhysicsProp( const char *pModelName, const Vector &vTraceStart, const Vector &vTraceEnd, const IHandleEntity *pTraceIgnore, bool bRequireVCollide, const char *pClassName="physics_prop" );
  342. bool UTIL_CreateScaledPhysObject( CBaseAnimating *pInstance, float flScale );
  343. float GetBreakableDamage( const CTakeDamageInfo &inputInfo, IBreakableWithPropData *pProp = NULL );
  344. int PropBreakablePrecacheAll( string_t modelName );
  345. extern ConVar func_breakdmg_bullet;
  346. extern ConVar func_breakdmg_club;
  347. extern ConVar func_breakdmg_explosive;
  348. #endif // PROPS_H