text: //========= Copyright Valve Corporation, All rights reserved. ============//
  //
  // Purpose:
  //
  //=============================================================================
  
  #ifndef AI_BEHAVIOR_PASSENGER_COMPANION_H
  #define AI_BEHAVIOR_PASSENGER_COMPANION_H
  #ifdef _WIN32
  #pragma once
  #endif
  
  #include "ai_behavior_passenger.h"
  
  class CNPC_PlayerCompanion;
  
  struct VehicleAvoidParams_t
  {
      Vector vecStartPos;
      Vector vecGoalPos;
      Vector *pNodePositions;
      int nNumNodes;
      int nDirection;
      int nStartNode;
      int nEndNode;
  };
  
  struct FailPosition_t
  {
      Vector  vecPosition;
      float   flTime;
  
      DECLARE_SIMPLE_DATADESC();
  };
  
  class CAI_PassengerBehaviorCompanion : public CAI_PassengerBehavior
  {
      DECLARE_CLASS( CAI_PassengerBehaviorCompanion, CAI_PassengerBehavior );
      DECLARE_DATADESC()
  
  public:
  
      CAI_PassengerBehaviorCompanion( void );
  
      enum
      {
          // Schedules
          SCHED_PASSENGER_RUN_TO_ENTER_VEHICLE = BaseClass::NEXT_SCHEDULE,
          SCHED_PASSENGER_RUN_TO_ENTER_VEHICLE_FAILED,
          SCHED_PASSENGER_ENTER_VEHICLE_PAUSE,
          SCHED_PASSENGER_RANGE_ATTACK1,
          SCHED_PASSENGER_RELOAD,
          SCHED_PASSENGER_EXIT_STUCK_VEHICLE,
          SCHED_PASSENGER_OVERTURNED,
          SCHED_PASSENGER_IMPACT,
          SCHED_PASSENGER_ENTER_VEHICLE_IMMEDIATELY,
          SCHED_PASSENGER_COWER,
          SCHED_PASSENGER_FIDGET,
          NEXT_SCHEDULE,
  
          // Tasks
          TASK_GET_PATH_TO_VEHICLE_ENTRY_POINT = BaseClass::NEXT_TASK,
          TASK_GET_PATH_TO_NEAR_VEHICLE,
          TASK_PASSENGER_RELOAD,
          TASK_PASSENGER_EXIT_STUCK_VEHICLE,
          TASK_PASSENGER_OVERTURNED,
          TASK_PASSENGER_IMPACT,
          TASK_RUN_TO_VEHICLE_ENTRANCE,
          NEXT_TASK,
  
          // Conditions
  
          COND_PASSENGER_CAN_LEAVE_STUCK_VEHICLE = BaseClass::NEXT_CONDITION,
          COND_PASSENGER_WARN_OVERTURNED,
          COND_PASSENGER_WARN_COLLISION,
          COND_PASSENGER_VEHICLE_MOVED_FROM_MARK,
          COND_PASSENGER_CAN_FIDGET,
          COND_PASSENGER_CAN_ENTER_IMMEDIATELY,
          NEXT_CONDITION,
      };
  
      virtual bool    CanSelectSchedule( void );
      virtual void    Enable( CPropJeepEpisodic *pVehicle, bool bImmediateEnter = false);
      virtual void    GatherConditions( void );
      virtual int     SelectSchedule( void );
      virtual int     SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode );
      virtual void    StartTask( const Task_t *pTask );
      virtual void    RunTask( const Task_t *pTask );
      virtual void    AimGun( void );
      virtual void    EnterVehicle( void );
      virtual void    ExitVehicle( void );
      virtual void    FinishEnterVehicle( void );
      virtual void    FinishExitVehicle( void );
      virtual void    BuildScheduleTestBits( void );
      virtual Activity NPC_TranslateActivity( Activity activity );
      virtual bool    CanExitVehicle( void );
      virtual bool    IsValidEnemy( CBaseEntity *pEntity );
      virtual void    OnUpdateShotRegulator( void );
      virtual bool    IsNavigationUrgent( void );
      virtual bool    IsCurTaskContinuousMove( void );
      virtual bool    IsCrouching( void );
  
  private:
  
      void            SpeakVehicleConditions( void );
      virtual void    OnExitVehicleFailed( void );
  
      bool    CanFidget( void );
      bool    UseRadialRouteToEntryPoint( const Vector &vecEntryPoint );
      float   GetArcToEntryPoint( const Vector &vecCenterPoint, const Vector &vecEntryPoint, bool &bClockwise );
      int     SelectScheduleInsideVehicle( void );
      int     SelectScheduleOutsideVehicle( void );
      bool    FindPathToVehicleEntryPoint( void );
      bool    CanEnterVehicleImmediately( int *pResultSequence, Vector *pResultPos, QAngle *pResultAngles );
      void    EnterVehicleImmediately( void );
  
      // ------------------------------------------
      //  Passenger sensing
      // ------------------------------------------
  
      virtual void    GatherVehicleStateConditions( void );
  
      float   GetVehicleSpeed( void );
      void    GatherVehicleCollisionConditions( const Vector &localVelocity );
  
      // ------------------------------------------
      //  Overturned tracking
      // ------------------------------------------
      void    UpdateStuckStatus( void );
      bool    CanExitAtPosition( const Vector &vecTestPos );
      bool    GetStuckExitPos( Vector *vecResult );
      bool    ExitStuckVehicle( void );
  
      bool            UpdateVehicleEntrancePath( void );
      bool            PointIsWithinEntryFailureRadius( const Vector &vecPosition );
      void            ResetVehicleEntryFailedState( void );
      void            MarkVehicleEntryFailed( const Vector &vecPosition );
      virtual int     FindEntrySequence( bool bNearest = false );
      void            CalculateBodyLean( void );
  
      float   m_flNextJostleTime;
      float   m_flNextOverturnWarning;    // The next time the NPC may complained about being upside-down
      float   m_flOverturnedDuration;     // Amount of time we've been stuck in the vehicle (unable to exit)
      float   m_flUnseenDuration;         // Amount of time we've been hidden from the player's view
  
      float   m_flEnterBeginTime;         // Time the NPC started to try and enter the vehicle
      int     m_nExitAttempts;            // Number of times we've attempted to exit the vehicle but failed
      int     m_nVisibleEnemies;          // Keeps a record of how many enemies I know about
      float   m_flLastLateralLean;        // Our last lean value
  
      CAI_MoveMonitor             m_VehicleMonitor;       // Used to keep track of the vehicle's movement relative to a mark
      CUtlVector<FailPosition_t>  m_FailedEntryPositions; // Used to keep track of the vehicle's movement relative to a mark
  
  protected:
      virtual int SelectTransitionSchedule( void );
  
      void    ExtendFidgetDelay( float flDuration );
      bool    CanPlayJostle( bool bLargeJostle );
  
      float   m_flEntraceUpdateTime;
      float   m_flNextEnterAttempt;
      float   m_flNextFidgetTime;
      CHandle< CNPC_PlayerCompanion > m_hCompanion;
  
      DEFINE_CUSTOM_SCHEDULE_PROVIDER;
  };
  
  #endif // AI_BEHAVIOR_PASSENGER_COMPANION_H
  