//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef ROPE_H #define ROPE_H #ifdef _WIN32 #pragma once #endif #include "baseentity.h" #include "positionwatcher.h" class CRopeKeyframe : public CBaseEntity, public IPositionWatcher { DECLARE_CLASS( CRopeKeyframe, CBaseEntity ); public: DECLARE_SERVERCLASS(); DECLARE_DATADESC(); CRopeKeyframe(); virtual ~CRopeKeyframe(); // Create a rope and attach it to two entities. // Attachment points on the entities are optional. static CRopeKeyframe* Create( CBaseEntity *pStartEnt, CBaseEntity *pEndEnt, int iStartAttachment=0, int iEndAttachment=0, int ropeWidth = 2, const char *pMaterialName = "cable/cable.vmt", // Note: whoever creates the rope must // use PrecacheModel for whatever material // it specifies here. int numSegments = 5 ); static CRopeKeyframe* CreateWithSecondPointDetached( CBaseEntity *pStartEnt, int iStartAttachment = 0, // must be 0 if you don't want to use a specific model attachment. int ropeLength = 20, int ropeWidth = 2, const char *pMaterialName = "cable/cable.vmt", // Note: whoever creates the rope // use PrecacheModel for whatever material // it specifies here. int numSegments = 5, bool bInitialHang = false ); bool SetupHangDistance( float flHangDist ); void ActivateStartDirectionConstraints( bool bEnable ); void ActivateEndDirectionConstraints( bool bEnable ); // Shakes all ropes near vCenter. The higher flMagnitude is, the larger the shake will be. static void ShakeRopes( const Vector &vCenter, float flRadius, float flMagnitude ); // CBaseEntity overrides. public: // don't cross transitions virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } virtual void Activate(); virtual void Precache(); virtual int OnTakeDamage( const CTakeDamageInfo &info ); virtual bool KeyValue( const char *szKeyName, const char *szValue ); void PropagateForce(CBaseEntity *pActivator, CBaseEntity *pCaller, CBaseEntity *pFirstLink, float x, float y, float z); // Once-off length recalculation void RecalculateLength( void ); // Kill myself when I next come to rest void DieAtNextRest( void ); virtual int UpdateTransmitState(void); virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways ); virtual void SetParent( CBaseEntity *pParentEntity, int iAttachment ); // Input functions. public: void InputSetScrollSpeed( inputdata_t &inputdata ); void InputSetForce( inputdata_t &inputdata ); void InputBreak( inputdata_t &inputdata ); public: bool Break( void ); void DetachPoint( int iPoint ); void EndpointsChanged(); // By default, ropes don't collide with the world. Call this to enable it. void EnableCollision(); // Toggle wind. void EnableWind( bool bEnable ); // Unless this is called during initialization, the caller should have done // PrecacheModel on whatever material they specify in here. void SetMaterial( const char *pName ); CBaseEntity* GetEndPoint() { return m_hEndPoint.Get(); } int GetEndAttachment() { return m_iStartAttachment; }; void SetStartPoint( CBaseEntity *pStartPoint, int attachment = 0 ); void SetEndPoint( CBaseEntity *pEndPoint, int attachment = 0 ); // See ROPE_PLAYER_WPN_ATTACH for info. void EnablePlayerWeaponAttach( bool bAttach ); // IPositionWatcher virtual void NotifyPositionChanged( CBaseEntity *pEntity ); private: void SetAttachmentPoint( CBaseHandle &hOutEnt, short &iOutAttachment, CBaseEntity *pEnt, int iAttachment ); // This is normally called by Activate but if you create the rope at runtime, // you must call it after you have setup its variables. void Init(); // These work just like the client-side versions. bool GetEndPointPos2( CBaseEntity *pEnt, int iAttachment, Vector &v ); bool GetEndPointPos( int iPt, Vector &v ); void UpdateBBox( bool bForceRelink ); public: CNetworkVar( int, m_RopeFlags ); // Combination of ROPE_ defines in rope_shared.h string_t m_iNextLinkName; CNetworkVar( int, m_Slack ); CNetworkVar( float, m_Width ); CNetworkVar( float, m_TextureScale ); CNetworkVar( int, m_nSegments ); // Number of segments. CNetworkVar( bool, m_bConstrainBetweenEndpoints ); string_t m_strRopeMaterialModel; CNetworkVar( int, m_iRopeMaterialModelIndex ); // Index of sprite model with the rope's material. // Number of subdivisions in between segments. CNetworkVar( int, m_Subdiv ); //EHANDLE m_hNextLink; CNetworkVar( int, m_RopeLength ); // Rope length at startup, used to calculate tension. CNetworkVar( int, m_fLockedPoints ); bool m_bCreatedFromMapFile; // set to false when creating at runtime CNetworkVar( float, m_flScrollSpeed ); private: // Used to detect changes. bool m_bStartPointValid; bool m_bEndPointValid; CNetworkHandle( CBaseEntity, m_hStartPoint ); // StartPoint/EndPoint are entities CNetworkHandle( CBaseEntity, m_hEndPoint ); CNetworkVar( short, m_iStartAttachment ); // StartAttachment/EndAttachment are attachment points. CNetworkVar( short, m_iEndAttachment ); }; #endif // ROPE_H