text: //========= Copyright Valve Corporation, All rights reserved. ============//
  //
  // Purpose: Special handling for hl2 usable ladders
  //
  //=============================================================================//
  
  #include "gamemovement.h"
  #include "func_ladder.h"
  
  #if defined( CLIENT_DLL )
  
  #include "c_basehlplayer.h"
  #define CHL2_Player C_BaseHLPlayer
  #else
  
  #include "hl2_player.h"
  
  #endif
  
  struct LadderMove_t;
  class CInfoLadderDismount;
  
  struct NearbyDismount_t
  {
  	CInfoLadderDismount		*dismount;
  	float					distSqr;
  };
  
  //-----------------------------------------------------------------------------
  // Purpose: HL2 specific movement code
  //-----------------------------------------------------------------------------
  class CHL2GameMovement : public CGameMovement
  {
  	typedef CGameMovement BaseClass;
  public:
  
  	CHL2GameMovement();
  
  // Overrides
  	virtual void FullLadderMove();
  	virtual bool LadderMove( void );
  	virtual bool OnLadder( trace_t &trace );
  	virtual int GetCheckInterval( IntervalType_t type );
  	virtual void	SetGroundEntity( trace_t *pm );
  	virtual bool CanAccelerate( void );
  
  	#ifdef SecobMod__USE_CSS_LADDERS
  		virtual unsigned int PlayerSolidMask( bool brushOnly = false );
  	#endif //SecobMod__USE_CSS_LADDERS
  
  private:
  
  	// See if we are pressing use near a ladder "mount" point and if so, latch us onto the ladder
  	bool		CheckLadderAutoMount( CFuncLadder *ladder, const Vector& bestOrigin );
  
  	bool		CheckLadderAutoMountCone( CFuncLadder *ladder, const Vector& bestOrigin, float maxAngleDelta, float maxDistToLadder );
  	bool		CheckLadderAutoMountEndPoint(CFuncLadder *ladder, const Vector& bestOrigin );
  
  
  	bool		LookingAtLadder( CFuncLadder *ladder );
  
  	// Are we forcing the user's position to a new spot
  	bool		IsForceMoveActive();
  	// Start forcing player position
  	void		StartForcedMove( bool mounting, float transit_speed, const Vector& goalpos, CFuncLadder *ladder );
  	// Returns false when finished
  	bool		ContinueForcedMove();
  
  	// Given a list of nearby ladders, find the best ladder and the "mount" origin
  	void		Findladder( float maxdist, CFuncLadder **ppLadder, Vector& ladderOrigin, const CFuncLadder *skipLadder );
  
  	// Debounce the +USE key
  	void		SwallowUseKey();
  
  	// Returns true if the player will auto-exit the ladder via a dismount node
  	bool		ExitLadderViaDismountNode( CFuncLadder *ladder, bool strict, bool useAlternate = false );
  	void		GetSortedDismountNodeList( const Vector &org, float radius, CFuncLadder *ladder, CUtlRBTree< NearbyDismount_t, int >& list );
  
  	LadderMove_t *GetLadderMove();
  	CHL2_Player	*GetHL2Player();
  
  	void		SetLadder( CFuncLadder *ladder );
  	CFuncLadder *GetLadder();
  };
  
  
  //-----------------------------------------------------------------------------
  // Purpose: 
  //-----------------------------------------------------------------------------
  inline CHL2_Player	*CHL2GameMovement::GetHL2Player()
  {
  	return static_cast< CHL2_Player * >( player );
  }
  
  //-----------------------------------------------------------------------------
  // Purpose: 
  // Output : inline LadderMove*
  //-----------------------------------------------------------------------------
  inline LadderMove_t *CHL2GameMovement::GetLadderMove()
  {
  	CHL2_Player *p = GetHL2Player();
  	if ( !p )
  	{
  		return NULL;
  	}
  	return p->GetLadderMove();
  }
  
  //-----------------------------------------------------------------------------
  // Purpose: 
  // Input  : *ladder - 
  //-----------------------------------------------------------------------------
  inline void CHL2GameMovement::SetLadder( CFuncLadder *ladder )
  {
  	CFuncLadder* oldLadder = GetLadder();
  
  	if ( !ladder && oldLadder )
  	{
  		oldLadder->PlayerGotOff( GetHL2Player() );
  	}
  
  
  	GetHL2Player()->m_HL2Local.m_hLadder.Set( ladder );
  }
  
  //-----------------------------------------------------------------------------
  // Purpose: 
  // Output : CFuncLadder
  //-----------------------------------------------------------------------------
  inline CFuncLadder *CHL2GameMovement::GetLadder()
  {
  	return static_cast<CFuncLadder*>( static_cast<CBaseEntity *>( GetHL2Player()->m_HL2Local.m_hLadder.Get() ) );
  }
  