Counter Strike : Global Offensive Source Code
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.

484 lines
13 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: A base class for model-based doors. The exact movement required to
  4. // open or close the door is not dictated by this class, only that
  5. // the door has open, closed, opening, and closing states.
  6. //
  7. // Doors must satisfy these requirements:
  8. //
  9. // - Derived classes must support being opened by NPCs.
  10. // - Never autoclose in the face of a player.
  11. // - Never close into an NPC.
  12. //
  13. //=============================================================================//
  14. #ifndef BASEPROPDOOR_H
  15. #define BASEPROPDOOR_H
  16. #ifdef _WIN32
  17. #pragma once
  18. #endif
  19. #include "props.h"
  20. #include "locksounds.h"
  21. #include "entityoutput.h"
  22. #include "entityblocker.h"
  23. extern ConVar g_debug_doors;
  24. struct opendata_t
  25. {
  26. Vector vecStandPos; // Where the NPC should stand.
  27. Vector vecFaceDir; // What direction the NPC should face.
  28. Activity eActivity; // What activity the NPC should play.
  29. };
  30. abstract_class CBasePropDoor : public CDynamicProp
  31. {
  32. public:
  33. DECLARE_CLASS( CBasePropDoor, CDynamicProp );
  34. DECLARE_SERVERCLASS();
  35. CBasePropDoor( void );
  36. void Spawn();
  37. void Precache();
  38. void Activate();
  39. int ObjectCaps();
  40. virtual bool IsAbleToCloseAreaPortals( void ) const;
  41. void HandleAnimEvent( animevent_t *pEvent );
  42. // Base class services.
  43. // Do not make the functions in this block virtual!!
  44. // {
  45. inline bool IsDoorOpen();
  46. inline bool IsDoorAjar();
  47. inline bool IsDoorOpening();
  48. inline bool IsDoorClosed();
  49. inline bool IsDoorClosing();
  50. inline bool IsDoorBlocked() const;
  51. inline bool IsNPCOpening(CAI_BaseNPC *pNPC);
  52. inline bool IsPlayerOpening();
  53. inline bool IsOpener(CBaseEntity *pEnt);
  54. virtual bool IsDoorLocked() { return m_bLocked; }
  55. bool NPCOpenDoor(CAI_BaseNPC *pNPC);
  56. bool TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace );
  57. // }
  58. // Implement these in your leaf class.
  59. // {
  60. virtual bool DoorCanClose( bool bAutoClose ) { return true; }
  61. virtual bool DoorCanOpen( void ) { return true; }
  62. virtual void GetNPCOpenData(CAI_BaseNPC *pNPC, opendata_t &opendata) = 0;
  63. virtual float GetOpenInterval(void) = 0;
  64. enum DoorExtent_t
  65. {
  66. DOOR_EXTENT_OPEN = 1,
  67. DOOR_EXTENT_CLOSED = 2,
  68. };
  69. virtual void ComputeDoorExtent( Extent *extent, unsigned int extentType ) = 0; // extent contains the volume encompassing by the door in the specified states
  70. // }
  71. protected:
  72. enum DoorState_t
  73. {
  74. DOOR_STATE_CLOSED = 0,
  75. DOOR_STATE_OPENING,
  76. DOOR_STATE_OPEN,
  77. DOOR_STATE_CLOSING,
  78. DOOR_STATE_AJAR,
  79. };
  80. // dvs: FIXME: make these private
  81. void DoorClose();
  82. CBasePropDoor *GetMaster( void ) { return m_hMaster; }
  83. bool HasSlaves( void ) { return ( m_hDoorList.Count() > 0 ); }
  84. inline void SetDoorState( DoorState_t eDoorState );
  85. virtual void CalcDoorSounds();
  86. float m_flAutoReturnDelay; // How many seconds to wait before automatically closing, -1 never closes automatically.
  87. CUtlVector< CHandle< CBasePropDoor > > m_hDoorList; // List of doors linked to us
  88. inline CBaseEntity *GetActivator();
  89. int m_nHardwareType;
  90. // Called when the door becomes fully closed.
  91. virtual void OnDoorClosed() {}
  92. private:
  93. // Implement these in your leaf class.
  94. // {
  95. // Called when the door becomes fully open.
  96. virtual void OnDoorOpened() {}
  97. // Called to tell the door to start opening.
  98. virtual void BeginOpening(CBaseEntity *pOpenAwayFrom) = 0;
  99. // Called to tell the door to start closing.
  100. virtual void BeginClosing( void ) = 0;
  101. // Called when blocked to tell the door to stop moving.
  102. virtual void DoorStop( void ) = 0;
  103. // Called when blocked to tell the door to continue moving.
  104. virtual void DoorResume( void ) = 0;
  105. // Called to send the door instantly to its spawn positions.
  106. virtual void DoorTeleportToSpawnPosition() = 0;
  107. // }
  108. protected:
  109. void UpdateAreaPortals( bool bOpen );
  110. void DisableAreaPortalThink( void );
  111. virtual void Lock();
  112. virtual void Unlock();
  113. private:
  114. // Main entry points for the door base behaviors.
  115. // Do not make the functions in this block virtual!!
  116. // {
  117. bool DoorActivate();
  118. void DoorOpen( CBaseEntity *pOpenAwayFrom );
  119. void OpenIfUnlocked(CBaseEntity *pActivator, CBaseEntity *pOpenAwayFrom);
  120. void DoorOpenMoveDone();
  121. void DoorCloseMoveDone();
  122. void DoorAutoCloseThink();
  123. void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
  124. void OnUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
  125. inline bool WillAutoReturn() { return m_flAutoReturnDelay != -1; }
  126. void StartBlocked(CBaseEntity *pOther);
  127. void OnStartBlocked( CBaseEntity *pOther );
  128. void MasterStartBlocked( CBaseEntity *pOther );
  129. void Blocked(CBaseEntity *pOther);
  130. void EndBlocked(void);
  131. void OnEndBlocked( void );
  132. // Input handlers
  133. void InputClose(inputdata_t &inputdata);
  134. void InputLock(inputdata_t &inputdata);
  135. void InputOpen(inputdata_t &inputdata);
  136. void InputOpenAwayFrom(inputdata_t &inputdata);
  137. void InputToggle(inputdata_t &inputdata);
  138. void InputUnlock(inputdata_t &inputdata);
  139. void SetDoorBlocker( CBaseEntity *pBlocker );
  140. void SetMaster( CBasePropDoor *pMaster ) { m_hMaster = pMaster; }
  141. DoorState_t m_eDoorState; // Holds whether the door is open, closed, opening, or closing.
  142. locksound_t m_ls; // The sounds the door plays when being locked, unlocked, etc.
  143. EHANDLE m_hActivator;
  144. EHANDLE m_hBlocker; // Entity blocking the door currently
  145. bool m_bFirstBlocked; // Marker for being the first door (in a group) to be blocked (needed for motion control)
  146. protected:
  147. bool m_bLocked; // True if the door is locked.
  148. bool m_bForceClosed; // True if this door must close no matter what.
  149. string_t m_SoundMoving;
  150. string_t m_SoundOpen;
  151. string_t m_SoundClose;
  152. int m_nPhysicsMaterial;
  153. // dvs: FIXME: can we remove m_flSpeed from CBaseEntity?
  154. //float m_flSpeed; // Rotation speed when opening or closing in degrees per second.
  155. DECLARE_DATADESC();
  156. string_t m_SlaveName;
  157. CHandle< CBasePropDoor > m_hMaster;
  158. static void RegisterPrivateActivities();
  159. // Outputs
  160. COutputEvent m_OnBlockedClosing; // Triggered when the door becomes blocked while closing.
  161. COutputEvent m_OnBlockedOpening; // Triggered when the door becomes blocked while opening.
  162. COutputEvent m_OnUnblockedClosing; // Triggered when the door becomes unblocked while closing.
  163. COutputEvent m_OnUnblockedOpening; // Triggered when the door becomes unblocked while opening.
  164. COutputEvent m_OnFullyClosed; // Triggered when the door reaches the fully closed position.
  165. COutputEvent m_OnFullyOpen; // Triggered when the door reaches the fully open position.
  166. COutputEvent m_OnClose; // Triggered when the door is told to close.
  167. COutputEvent m_OnOpen; // Triggered when the door is told to open.
  168. COutputEvent m_OnLockedUse; // Triggered when the user tries to open a locked door.
  169. };
  170. void CBasePropDoor::SetDoorState( DoorState_t eDoorState )
  171. {
  172. m_eDoorState = eDoorState;
  173. }
  174. bool CBasePropDoor::IsDoorOpen()
  175. {
  176. return m_eDoorState == DOOR_STATE_OPEN;
  177. }
  178. bool CBasePropDoor::IsDoorAjar()
  179. {
  180. return ( m_eDoorState == DOOR_STATE_AJAR );
  181. }
  182. bool CBasePropDoor::IsDoorOpening()
  183. {
  184. return m_eDoorState == DOOR_STATE_OPENING;
  185. }
  186. bool CBasePropDoor::IsDoorClosed()
  187. {
  188. return m_eDoorState == DOOR_STATE_CLOSED;
  189. }
  190. bool CBasePropDoor::IsDoorClosing()
  191. {
  192. return m_eDoorState == DOOR_STATE_CLOSING;
  193. }
  194. CBaseEntity *CBasePropDoor::GetActivator()
  195. {
  196. return m_hActivator;
  197. }
  198. bool CBasePropDoor::IsDoorBlocked() const
  199. {
  200. return ( m_hBlocker != NULL );
  201. }
  202. bool CBasePropDoor::IsNPCOpening( CAI_BaseNPC *pNPC )
  203. {
  204. return ( pNPC == ( CAI_BaseNPC * )GetActivator() );
  205. }
  206. inline bool CBasePropDoor::IsPlayerOpening()
  207. {
  208. return ( GetActivator() && GetActivator()->IsPlayer() );
  209. }
  210. inline bool CBasePropDoor::IsOpener(CBaseEntity *pEnt)
  211. {
  212. return ( GetActivator() == pEnt );
  213. }
  214. //===============================================
  215. // Rotating prop door
  216. //===============================================
  217. // Check directions for door movement
  218. enum doorCheck_e
  219. {
  220. DOOR_CHECK_FORWARD, // Door's forward opening direction
  221. DOOR_CHECK_BACKWARD, // Door's backward opening direction
  222. DOOR_CHECK_FULL, // Door's complete movement volume
  223. };
  224. enum PropDoorRotatingSpawnPos_t
  225. {
  226. DOOR_SPAWN_CLOSED = 0,
  227. DOOR_SPAWN_OPEN_FORWARD,
  228. DOOR_SPAWN_OPEN_BACK,
  229. DOOR_SPAWN_AJAR,
  230. };
  231. enum PropDoorRotatingOpenDirection_e
  232. {
  233. DOOR_ROTATING_OPEN_BOTH_WAYS = 0,
  234. DOOR_ROTATING_OPEN_FORWARD,
  235. DOOR_ROTATING_OPEN_BACKWARD,
  236. };
  237. class CPropDoorRotating : public CBasePropDoor
  238. {
  239. DECLARE_CLASS( CPropDoorRotating, CBasePropDoor );
  240. public:
  241. ~CPropDoorRotating();
  242. int DrawDebugTextOverlays( void );
  243. void Spawn( void );
  244. void MoveDone( void );
  245. void BeginOpening( CBaseEntity *pOpenAwayFrom );
  246. void BeginClosing( void );
  247. void OnRestore( void );
  248. void DoorTeleportToSpawnPosition();
  249. void GetNPCOpenData( CAI_BaseNPC *pNPC, opendata_t &opendata );
  250. void DoorClose( void );
  251. bool DoorCanClose( bool bAutoClose );
  252. void DoorOpen( CBaseEntity *pOpenAwayFrom );
  253. void OnDoorOpened();
  254. void OnDoorClosed();
  255. void DoorResume( void );
  256. void DoorStop( void );
  257. float GetOpenInterval();
  258. bool OverridePropdata() { return true; }
  259. void InputSetSpeed( inputdata_t &inputdata );
  260. virtual void ComputeDoorExtent( Extent *extent, unsigned int extentType ); // extent contains the volume encompassing open + closed states
  261. virtual int UpdateTransmitState() { return SetTransmitState( FL_EDICT_ALWAYS ); }
  262. DECLARE_DATADESC();
  263. DECLARE_SERVERCLASS();
  264. private:
  265. bool IsHingeOnLeft();
  266. void AngularMove( const QAngle &vecDestAngle, float flSpeed );
  267. void CalculateDoorVolume( QAngle closedAngles, QAngle openAngles, Vector *destMins, Vector *destMaxs );
  268. bool CheckDoorClear( doorCheck_e state );
  269. doorCheck_e GetOpenState( void );
  270. void InputSetRotationDistance( inputdata_t &inputdata ); // Set the degree difference between open and closed
  271. void InputMoveToRotationDistance( inputdata_t &inputdata ); // Set the degree difference between open and closed and move to open
  272. void CalcOpenAngles( void ); // Subroutine to setup the m_angRotation QAngles based on the m_flDistance variable
  273. Vector m_vecAxis; // The axis of rotation.
  274. float m_flDistance; // How many degrees we rotate between open and closed.
  275. PropDoorRotatingSpawnPos_t m_eSpawnPosition;
  276. PropDoorRotatingOpenDirection_e m_eOpenDirection;
  277. QAngle m_angRotationAjar; // Angles to spawn at if we are set to spawn ajar.
  278. QAngle m_angRotationClosed; // Our angles when we are fully closed.
  279. QAngle m_angRotationOpenForward; // Our angles when we are fully open towards our forward vector.
  280. QAngle m_angRotationOpenBack; // Our angles when we are fully open away from our forward vector.
  281. QAngle m_angGoal;
  282. Vector m_vecForwardBoundsMin;
  283. Vector m_vecForwardBoundsMax;
  284. Vector m_vecBackBoundsMin;
  285. Vector m_vecBackBoundsMax;
  286. COutputEvent m_OnRotationDone; // Triggered when we finish rotating.
  287. CHandle<CEntityBlocker> m_hDoorBlocker;
  288. };
  289. //--------------------------------------------------------------------------------------------------------
  290. class CPropDoorRotatingBreakable : public CPropDoorRotating
  291. {
  292. DECLARE_CLASS( CPropDoorRotatingBreakable, CPropDoorRotating );
  293. public:
  294. DECLARE_DATADESC();
  295. virtual void Spawn( void );
  296. virtual void Precache( void );
  297. virtual void UpdateOnRemove( void );
  298. void PrecacheBreakables( void );
  299. virtual int OnTakeDamage( const CTakeDamageInfo &info );
  300. virtual void Event_Killed( const CTakeDamageInfo &info );
  301. void InputSetRotationDistance( inputdata_t &inputdata );
  302. void InputSetUnbreakable( inputdata_t &inputdata );
  303. void InputSetBreakable( inputdata_t &inputdata );
  304. virtual bool IsAbleToCloseAreaPortals( void ) const;
  305. virtual int DrawDebugTextOverlays( void );
  306. bool IsBreakable( void ) { return m_bBreakable; }
  307. virtual void Lock();
  308. virtual void Unlock();
  309. virtual void OnDoorOpened( void )
  310. {
  311. UnblockNav();
  312. BaseClass::OnDoorOpened();
  313. }
  314. virtual void OnDoorClosed( void )
  315. {
  316. BaseClass::OnDoorClosed();
  317. }
  318. bool operator()( CNavArea *area ); // functor that blocks areas in our extent
  319. static bool CalculateBlocked( bool *pResultByTeam, const Vector &vecMins, const Vector &vecMaxs );
  320. private:
  321. void UpdateBlocked( bool bBlocked );
  322. void BlockNav( void );
  323. void UnblockNav( void );
  324. // void BlockNavArea( bool blocked )
  325. // {
  326. // /**
  327. // * MSB: I'm commenting this out, because we can't use BLOCKED for this,
  328. // * since *nothing* can path thru a blocked area - SurvivorBots, population
  329. // * algorithms, etc.
  330. // * However, something like "closed door" might be useful to flag here
  331. // * in the future.
  332. // *
  333. //
  334. // if ( blocked )
  335. // {
  336. // CNavArea *area = TheNavMesh->GetNavArea( WorldSpaceCenter() );
  337. // if ( area )
  338. // {
  339. // area->Block();
  340. // m_blockedNavAreaID = area->GetID();
  341. // }
  342. // }
  343. // else
  344. // {
  345. // if ( m_blockedNavAreaID > 0 )
  346. // {
  347. // CNavArea *area = TheNavMesh->GetNavAreaByID( m_blockedNavAreaID );
  348. // if ( area )
  349. // {
  350. // area->UpdateBlocked( true ); // give it a chance to stay blocked by something else
  351. // }
  352. // }
  353. // }
  354. // */
  355. // }
  356. int m_blockedNavAreaID;
  357. bool m_bBreakable;
  358. bool m_isAbleToCloseAreaPortals;
  359. int m_currentDamageState;
  360. int m_blockedTeamNumber;
  361. bool m_isBlockingNav[MAX_NAV_TEAMS];
  362. CUtlVector< string_t > m_damageStates;
  363. };
  364. #endif // BASEPROPDOOR_H