|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: NPC that drives vehicles
//
//=============================================================================//
#ifndef NPC_VEHICLEDRIVER_H
#define NPC_VEHICLEDRIVER_H
#ifdef _WIN32
#pragma once
#endif
#include "ai_basenpc.h"
class CPropVehicleDriveable;
//------------------------------------
// Spawnflags
//------------------------------------
#define SF_VEHICLEDRIVER_INACTIVE (1 << 16)
//=========================================================
// Custom schedules
//=========================================================
enum { SCHED_VEHICLEDRIVER_INACTIVE = LAST_SHARED_SCHEDULE, SCHED_VEHICLEDRIVER_COMBAT_WAIT, SCHED_VEHICLEDRIVER_DRIVE_PATH,
LAST_VEHICLEDRIVER_SCHED, };
//=========================================================
// Custom tasks
//=========================================================
enum { TASK_VEHICLEDRIVER_GET_PATH = LAST_SHARED_TASK,
LAST_VEHICLEDRIVER_TASK, };
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CVehicleWaypoint { public: CVehicleWaypoint( Vector &pPrevPoint, Vector &pCurPoint, Vector &pNextPoint, Vector &pNextNextPoint ) { splinePoints[0] = pPrevPoint; splinePoints[1] = pCurPoint; splinePoints[2] = pNextPoint; splinePoints[3] = pNextNextPoint;
RecalculateSpline(); }
void RecalculateSpline( void ) { planeWaypoint.normal = (splinePoints[2] - splinePoints[1]); VectorNormalize( planeWaypoint.normal ); planeWaypoint.type = PLANE_ANYZ; planeWaypoint.dist = DotProduct( planeWaypoint.normal, splinePoints[2] ); planeWaypoint.signbits = SignbitsForPlane(&planeWaypoint); // TODO: Use the vehicle's absbox
iInitialPlaneSide = BoxOnPlaneSide( -Vector(32,32,32), Vector(32,32,32), &planeWaypoint );
// Hackily calculate a length for the spline. Subdivide & measure.
flSplineLength = 0; Vector vecPrev = splinePoints[1]; const int iDivs = 10; for ( int i = 1; i <= iDivs; i++ ) { Vector vecCurr; float flT = (float)i / (float)iDivs; Catmull_Rom_Spline( splinePoints[0], splinePoints[1], splinePoints[2], splinePoints[3], flT, vecCurr ); flSplineLength += (vecCurr - vecPrev).Length(); vecPrev = vecCurr; } }
Vector GetPointAt( float flT ) { Vector vecCurr(0,0,0); Catmull_Rom_Spline( splinePoints[0], splinePoints[1], splinePoints[2], splinePoints[3], flT, vecCurr ); return vecCurr; }
Vector GetTangentAt( float flT ) { Vector vecCurr(0,0,0); Catmull_Rom_Spline_Tangent( splinePoints[0], splinePoints[1], splinePoints[2], splinePoints[3], flT, vecCurr ); return vecCurr; }
float GetLength( void ) { return flSplineLength; }
public: int iInitialPlaneSide; float flSplineLength; Vector splinePoints[4]; cplane_t planeWaypoint; };
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CNPC_VehicleDriver : public CAI_BaseNPC { DECLARE_CLASS( CNPC_VehicleDriver, CAI_BaseNPC ); public: DECLARE_DATADESC(); DEFINE_CUSTOM_AI;
CNPC_VehicleDriver( void ); ~CNPC_VehicleDriver( void );
virtual void Spawn( void ); virtual void Precache( void ); virtual void Activate( void ); virtual void OnRestore(); virtual void UpdateOnRemove( void ); // AI
void UpdateEfficiency( bool bInPVS ) { SetEfficiency( ( GetSleepState() != AISS_AWAKE ) ? AIE_DORMANT : AIE_NORMAL ); SetMoveEfficiency( AIME_NORMAL ); } virtual void PrescheduleThink( void ); virtual int TranslateSchedule( int scheduleType ); virtual int SelectSchedule( void ); virtual void StartTask( const Task_t *pTask ); virtual void RunTask( const Task_t *pTask ); virtual void GatherEnemyConditions( CBaseEntity *pEnemy ); virtual int RangeAttack1Conditions( float flDot, float flDist ); virtual int RangeAttack2Conditions( float flDot, float flDist );
// Driving
virtual void DriveVehicle( void ); virtual bool OverrideMove( float flInterval ); bool OverridePathMove( float flInterval ); void CalculatePostPoints( void ); bool WaypointReached( void ); float GetDefaultNavGoalTolerance(); void RecalculateSpeeds( void ); void ClearWaypoints( void ); void CheckForTeleport( void );
int BloodColor( void ) { return DONT_BLEED; }
#ifdef HL2_DLL
Class_T Classify( void ) { return CLASS_METROPOLICE; } #else
Class_T Classify( void ) { return CLASS_NONE; } #endif
Disposition_t IRelationType( CBaseEntity *pTarget );
// Inputs
void InputSetDriversMaxSpeed( inputdata_t &inputdata ); void InputSetDriversMinSpeed( inputdata_t &inputdata ); void InputStartForward( inputdata_t &inputdata ); void InputStop( inputdata_t &inputdata ); void InputStartFiring( inputdata_t &inputdata ); void InputStopFiring( inputdata_t &inputdata ); void InputGotoPathCorner( inputdata_t &inputdata );
public: string_t m_iszVehicleName; IServerVehicle *m_pVehicleInterface; EHANDLE m_hVehicleEntity;
// Path driving
CVehicleWaypoint *m_Waypoints[2]; CVehicleWaypoint *m_pCurrentWaypoint; CVehicleWaypoint *m_pNextWaypoint; Vector m_vecDesiredVelocity; Vector m_vecDesiredPosition; Vector m_vecPrevPoint; Vector m_vecPrevPrevPoint; Vector m_vecPostPoint; Vector m_vecPostPostPoint; float m_flDistanceAlongSpline; float m_flDriversMaxSpeed; float m_flDriversMinSpeed;
// Speed
float m_flMaxSpeed; // Maximum speed this driver will go
float m_flGoalSpeed; // Desired speed
float m_flInitialSpeed; float m_flSteering; };
#endif // NPC_VEHICLEDRIVER_H
|