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.

187 lines
5.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef OBSTACLE_PUSHAWAY_H
  7. #define OBSTACLE_PUSHAWAY_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "props_shared.h"
  12. #ifndef CLIENT_DLL
  13. #include "func_breakablesurf.h"
  14. #include "BasePropDoor.h"
  15. #include "doors.h"
  16. #endif // CLIENT_DLL
  17. //--------------------------------------------------------------------------------------------------------------
  18. bool IsPushAwayEntity( CBaseEntity *pEnt );
  19. bool IsPushableEntity( CBaseEntity *pEnt );
  20. //--------------------------------------------------------------------------------------------------------------
  21. #ifndef CLIENT_DLL
  22. bool IsBreakableEntity( CBaseEntity *pEnt );
  23. #endif // !CLIENT_DLL
  24. //--------------------------------------------------------------------------------------------------------------
  25. class CPushAwayEnumerator : public IPartitionEnumerator
  26. {
  27. public:
  28. // Forced constructor
  29. CPushAwayEnumerator(CBaseEntity **ents, int nMaxEnts)
  30. {
  31. m_nAlreadyHit = 0;
  32. m_AlreadyHit = ents;
  33. m_nMaxHits = nMaxEnts;
  34. }
  35. // Actual work code
  36. virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity )
  37. {
  38. #ifdef CLIENT_DLL
  39. CBaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( pHandleEntity->GetRefEHandle() );
  40. #else
  41. CBaseEntity *pEnt = gEntList.GetBaseEntity( pHandleEntity->GetRefEHandle() );
  42. #endif // CLIENT_DLL
  43. if ( IsPushAwayEntity( pEnt ) && m_nAlreadyHit < m_nMaxHits )
  44. {
  45. m_AlreadyHit[m_nAlreadyHit] = pEnt;
  46. m_nAlreadyHit++;
  47. }
  48. return ITERATION_CONTINUE;
  49. }
  50. public:
  51. CBaseEntity **m_AlreadyHit;
  52. int m_nAlreadyHit;
  53. int m_nMaxHits;
  54. };
  55. #ifndef CLIENT_DLL
  56. //--------------------------------------------------------------------------------------------------------------
  57. /**
  58. * This class will collect breakable objects in a volume. Physics props that can be damaged, func_breakable*, etc
  59. * are all collected by this class.
  60. */
  61. class CBotBreakableEnumerator : public CPushAwayEnumerator
  62. {
  63. public:
  64. CBotBreakableEnumerator(CBaseEntity **ents, int nMaxEnts) : CPushAwayEnumerator(ents, nMaxEnts)
  65. {
  66. }
  67. virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity )
  68. {
  69. CBaseEntity *pEnt = gEntList.GetBaseEntity( pHandleEntity->GetRefEHandle() );
  70. if ( !IsBreakableEntity( pEnt ) )
  71. return ITERATION_CONTINUE;
  72. // ignore breakables parented to doors
  73. if ( pEnt->GetParent() &&
  74. ( FClassnameIs( pEnt->GetParent(), "func_door*" ) ||
  75. FClassnameIs( pEnt, "prop_door*" ) ) )
  76. return ITERATION_CONTINUE;
  77. if ( m_nAlreadyHit < m_nMaxHits )
  78. {
  79. m_AlreadyHit[m_nAlreadyHit] = pEnt;
  80. m_nAlreadyHit++;
  81. }
  82. return ITERATION_CONTINUE;
  83. }
  84. };
  85. //--------------------------------------------------------------------------------------------------------------
  86. /**
  87. * This class will collect door objects in a volume.
  88. */
  89. class CBotDoorEnumerator : public CPushAwayEnumerator
  90. {
  91. public:
  92. CBotDoorEnumerator(CBaseEntity **ents, int nMaxEnts) : CPushAwayEnumerator(ents, nMaxEnts)
  93. {
  94. }
  95. virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity )
  96. {
  97. CBaseEntity *pEnt = gEntList.GetBaseEntity( pHandleEntity->GetRefEHandle() );
  98. if ( pEnt == NULL )
  99. return ITERATION_CONTINUE;
  100. if ( ( pEnt->ObjectCaps() & FCAP_IMPULSE_USE ) == 0 )
  101. {
  102. return ITERATION_CONTINUE;
  103. }
  104. if ( FClassnameIs( pEnt, "func_door*" ) )
  105. {
  106. CBaseDoor *door = dynamic_cast<CBaseDoor *>(pEnt);
  107. if ( !door )
  108. {
  109. return ITERATION_CONTINUE;
  110. }
  111. if ( door->m_toggle_state == TS_GOING_UP || door->m_toggle_state == TS_GOING_DOWN )
  112. {
  113. return ITERATION_CONTINUE;
  114. }
  115. }
  116. else if ( FClassnameIs( pEnt, "prop_door*" ) )
  117. {
  118. CBasePropDoor *door = dynamic_cast<CBasePropDoor *>(pEnt);
  119. if ( !door )
  120. {
  121. return ITERATION_CONTINUE;
  122. }
  123. if ( door->IsDoorOpening() || door->IsDoorClosing() )
  124. {
  125. return ITERATION_CONTINUE;
  126. }
  127. }
  128. else
  129. {
  130. return ITERATION_CONTINUE;
  131. }
  132. if ( m_nAlreadyHit < m_nMaxHits )
  133. {
  134. m_AlreadyHit[m_nAlreadyHit] = pEnt;
  135. m_nAlreadyHit++;
  136. }
  137. return ITERATION_CONTINUE;
  138. }
  139. };
  140. //--------------------------------------------------------------------------------------------------------------
  141. /**
  142. * Returns an entity that matches the filter that is along the line segment
  143. */
  144. CBaseEntity * CheckForEntitiesAlongSegment( const Vector &start, const Vector &end, const Vector &mins, const Vector &maxs, CPushAwayEnumerator *enumerator );
  145. #endif // CLIENT_DLL
  146. //--------------------------------------------------------------------------------------------------------------
  147. // Retrieves physics objects near pPushingEntity
  148. void AvoidPushawayProps( CBaseCombatCharacter *pPlayer, CUserCmd *pCmd );
  149. int GetPushawayEnts( CBaseCombatCharacter *pPushingEntity, CBaseEntity **ents, int nMaxEnts, float flPlayerExpand, int PartitionMask, CPushAwayEnumerator *enumerator = NULL );
  150. //--------------------------------------------------------------------------------------------------------------
  151. // Pushes physics objects away from the entity
  152. void PerformObstaclePushaway( CBaseCombatCharacter *pPushingEntity );
  153. #endif // OBSTACLE_PUSHAWAY_H