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.

159 lines
5.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef PUSHENTITY_H
  7. #define PUSHENTITY_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "movetype_push.h"
  12. //-----------------------------------------------------------------------------
  13. // Purpose: Keeps track of original positions of any entities that are being possibly pushed
  14. // and handles restoring positions for those objects if the push is aborted
  15. //-----------------------------------------------------------------------------
  16. class CPhysicsPushedEntities
  17. {
  18. public:
  19. DECLARE_CLASS_NOBASE( CPhysicsPushedEntities );
  20. CPhysicsPushedEntities( void );
  21. // Purpose: Tries to rotate an entity hierarchy, returns the blocker if any
  22. CBaseEntity *PerformRotatePush( CBaseEntity *pRoot, float movetime );
  23. // Purpose: Tries to linearly push an entity hierarchy, returns the blocker if any
  24. CBaseEntity *PerformLinearPush( CBaseEntity *pRoot, float movetime );
  25. int CountMovedEntities() { return m_rgMoved.Count(); }
  26. void StoreMovedEntities( physicspushlist_t &list );
  27. void BeginPush( CBaseEntity *pRootEntity );
  28. protected:
  29. // describes the per-frame incremental motion of a rotating MOVETYPE_PUSH
  30. struct RotatingPushMove_t
  31. {
  32. Vector origin;
  33. matrix3x4_t startLocalToWorld;
  34. matrix3x4_t endLocalToWorld;
  35. QAngle amove; // delta orientation
  36. };
  37. // Pushers + their original positions also (for touching triggers)
  38. struct PhysicsPusherInfo_t
  39. {
  40. CBaseEntity *m_pEntity;
  41. Vector m_vecStartAbsOrigin;
  42. };
  43. // Pushed entities + various state related to them being pushed
  44. struct PhysicsPushedInfo_t
  45. {
  46. CBaseEntity *m_pEntity;
  47. Vector m_vecStartAbsOrigin;
  48. trace_t m_Trace;
  49. bool m_bBlocked;
  50. bool m_bPusherIsGround;
  51. };
  52. // Adds the specified entity to the list
  53. void AddEntity( CBaseEntity *ent );
  54. // If a move fails, restores all entities to their original positions
  55. void RestoreEntities( );
  56. // Compute the direction to move the rotation blocker
  57. void ComputeRotationalPushDirection( CBaseEntity *pBlocker, const RotatingPushMove_t &rotPushMove, Vector *pMove, CBaseEntity *pRoot );
  58. // Speculatively checks to see if all entities in this list can be pushed
  59. bool SpeculativelyCheckPush( PhysicsPushedInfo_t &info, const Vector &vecAbsPush, bool bRotationalPush );
  60. // Speculatively checks to see if all entities in this list can be pushed
  61. virtual bool SpeculativelyCheckRotPush( const RotatingPushMove_t &rotPushMove, CBaseEntity *pRoot );
  62. // Speculatively checks to see if all entities in this list can be pushed
  63. virtual bool SpeculativelyCheckLinearPush( const Vector &vecAbsPush );
  64. // Registers a blockage
  65. CBaseEntity *RegisterBlockage();
  66. // Some fixup for objects pushed by rotating objects
  67. virtual void FinishRotPushedEntity( CBaseEntity *pPushedEntity, const RotatingPushMove_t &rotPushMove );
  68. // Commits the speculative movement
  69. void FinishPush( bool bIsRotPush = false, const RotatingPushMove_t *pRotPushMove = NULL );
  70. // Generates a list of all entities potentially blocking all pushers
  71. void GenerateBlockingEntityList();
  72. void GenerateBlockingEntityListAddBox( const Vector &vecMoved );
  73. // Purpose: Gets a list of all entities hierarchically attached to the root
  74. void SetupAllInHierarchy( CBaseEntity *pParent );
  75. // Unlink + relink the pusher list so we can actually do the push
  76. void UnlinkPusherList( int *pPusherHandles );
  77. void RelinkPusherList( int *pPusherHandles );
  78. // Causes all entities in the list to touch triggers from their prev position
  79. void FinishPushers();
  80. // Purpose: Rotates the root entity, fills in the pushmove structure
  81. void RotateRootEntity( CBaseEntity *pRoot, float movetime, RotatingPushMove_t &rotation );
  82. // Purpose: Linearly moves the root entity
  83. void LinearlyMoveRootEntity( CBaseEntity *pRoot, float movetime, Vector *pAbsPushVector );
  84. bool IsPushedPositionValid( CBaseEntity *pBlocker );
  85. protected:
  86. CUtlVector<PhysicsPusherInfo_t> m_rgPusher;
  87. CUtlVector<PhysicsPushedInfo_t> m_rgMoved;
  88. int m_nBlocker;
  89. bool m_bIsUnblockableByPlayer;
  90. Vector m_rootPusherStartLocalOrigin;
  91. QAngle m_rootPusherStartLocalAngles;
  92. float m_rootPusherStartLocaltime;
  93. float m_flMoveTime;
  94. friend class CPushBlockerEnum;
  95. };
  96. class CTraceFilterPushMove : public CTraceFilterSimple
  97. {
  98. DECLARE_CLASS( CTraceFilterPushMove, CTraceFilterSimple );
  99. public:
  100. CTraceFilterPushMove( CBaseEntity *pEntity, int nCollisionGroup )
  101. : CTraceFilterSimple( pEntity, nCollisionGroup )
  102. {
  103. m_pRootParent = pEntity->GetRootMoveParent();
  104. }
  105. bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask )
  106. {
  107. Assert( dynamic_cast<CBaseEntity*>(pHandleEntity) );
  108. CBaseEntity *pTestEntity = static_cast<CBaseEntity*>(pHandleEntity);
  109. if ( UTIL_EntityHasMatchingRootParent( m_pRootParent, pTestEntity ) )
  110. return false;
  111. if ( pTestEntity->GetMoveType() == MOVETYPE_VPHYSICS &&
  112. pTestEntity->VPhysicsGetObject() && pTestEntity->VPhysicsGetObject()->IsMoveable() )
  113. return false;
  114. return BaseClass::ShouldHitEntity( pHandleEntity, contentsMask );
  115. }
  116. private:
  117. CBaseEntity *m_pRootParent;
  118. };
  119. extern CPhysicsPushedEntities *g_pPushedEntities;
  120. #endif // PUSHENTITY_H