aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/ai_motor.h
blob: d7f14293b60fccfd96167a81ace3c4fd3a24f45f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//

#ifndef AI_MOTOR_H
#define AI_MOTOR_H

#ifdef _WIN32
#pragma once
#endif

#include "simtimer.h"
#include "ai_component.h"
#include "ai_navtype.h"
#include "ai_movetypes.h"
#include "AI_Interest_Target.h"

//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
enum Navigation_t;
class CAI_PlaneSolver;
class CAI_MoveProbe;
class CAI_Navigator;

#define AI_CALC_YAW_SPEED -1
#define AI_KEEP_YAW_SPEED -2

//-----------------------------------------------------------------------------

float AI_ClampYaw( float yawSpeedPerSec, float current, float target, float time );

//-----------------------------------------------------------------------------
// CAI_Motor
//
// Purpose: Implements the primitive locomotion of AIs. 
//-----------------------------------------------------------------------------

class CAI_Motor : public CAI_Component,
				  public CAI_ProxyMovementSink
{
public:
	CAI_Motor(CAI_BaseNPC *pOuter);
	virtual ~CAI_Motor();

	void Init( IAI_MovementSink *pMovementServices );

	// --------------------------------
	// The current timestep the motor is working on
	// --------------------------------
	float 				GetMoveInterval() 					{ return m_flMoveInterval; }
	float				SetMoveInterval( float flInterval ) { return (m_flMoveInterval = flInterval); }

	// ----------------------------------------------------
	// Translational movement
	// ----------------------------------------------------
	AIMoveResult_t 		MoveNormalExecute( const AILocalMoveGoal_t &move );

	virtual void 		MoveClimbStart( const Vector &climbDest, const Vector &climbDir, float climbDist, float yaw );
	virtual AIMoveResult_t MoveClimbExecute( const Vector &climbDest, const Vector &climbDir, float climbDist, float yaw, int climbNodesLeft );
	virtual void 		MoveClimbStop();

	//---------------------------------


	virtual void 		MoveJumpStart( const Vector &velocity );
	virtual int 		MoveJumpExecute();
	virtual AIMoveResult_t MoveJumpStop();

	virtual void		ResetMoveCalculations();
	virtual	void		MoveStart();
	virtual	void		MoveStop();
	virtual void		MovePaused();
	
	//---------------------------------
	
	float				GetIdealSpeed() const;
	float				GetIdealAccel() const;
	float				GetCurSpeed() const			{ return m_vecVelocity.Length(); }
	const Vector &		GetCurVel() const			{ return m_vecVelocity;			 }

	virtual float		OverrideMaxYawSpeed( Activity activity )	{ return -1; }
	bool				IsDeceleratingToGoal() const				{ return false; }

	//---------------------------------
	// Raw ground step forward to the specifed position
	//

	AIMotorMoveResult_t MoveGroundStep( const Vector &newPos, CBaseEntity *pMoveTarget = NULL, float yaw = -1, bool bAsFarAsCan = true, bool bTestZ = true, AIMoveTrace_t *pTraceResult = NULL );
	
	// ----------------------------------------------------
	// Rotational movement (yaw); goal and speed
	// ----------------------------------------------------
	
	void 				SetYawSpeed( float yawSpeed )		{ m_YawSpeed = yawSpeed; 	}
	float 				GetYawSpeed() const					{ return m_YawSpeed; 		}
	float 				GetIdealYaw() const					{ return m_IdealYaw; 		}
	void 				SetIdealYaw( float idealYaw)		{ m_IdealYaw = idealYaw; 	}
	
	// Set ideal yaw specified as a vector
	void 				SetIdealYaw( const Vector &vecFacing)	{ SetIdealYaw( UTIL_VecToYaw( vecFacing )); }

	// Set ideal yaw based on a specified target
	void 				SetIdealYawToTarget( const Vector &target, float noise = 0.0, float offset = 0.0 );

	// Set the ideal yaw and run the current or specified timestep worth of rotation. Note 
	// it is not correct to call any "update" variant of these methods more
	// than once per think cycle
	void 				SetIdealYawAndUpdate( float idealYaw, float yawSpeed = AI_CALC_YAW_SPEED );
	void 				SetIdealYawAndUpdate( const Vector &vecFacing, float yawSpeed = AI_CALC_YAW_SPEED ) 		{ SetIdealYawAndUpdate( UTIL_VecToYaw( vecFacing ), yawSpeed );	}
	void 				SetIdealYawToTargetAndUpdate( const Vector &target, float yawSpeed = AI_CALC_YAW_SPEED );

	//   Add multiple facing goals while moving/standing still.
	virtual void		AddFacingTarget( CBaseEntity *pTarget, float flImportance, float flDuration, float flRamp = 0.0 );
	virtual void		AddFacingTarget( const Vector &vecPosition, float flImportance, float flDuration, float flRamp = 0.0 );
	virtual void		AddFacingTarget( CBaseEntity *pTarget, const Vector &vecPosition, float flImportance, float flDuration, float flRamp = 0.0 );
	virtual float		GetFacingDirection( Vector &vecDir );

	// Force the heading to the ideal yaw
	void 				SnapYaw()	{ UpdateYaw(360); }

	// Run the current or specified timestep worth of rotation
	virtual	void		UpdateYaw( int speed = -1 );

	// 
	virtual	void 		RecalculateYawSpeed();

	// Returns the difference ( in degrees ) between npc's current yaw and ideal_yaw
	float				DeltaIdealYaw(); 

	// Issues turn gestures when needed due to turning
	virtual	void		MaintainTurnActivity( void ) { };
	virtual bool		AddTurnGesture( float flYD ) { return false; };

	// --------------------------------
	// Move primitives
	// --------------------------------
	virtual float		MinStoppingDist( float flMinResult = 10.0 );	// how far before I can come to a complete stop?
	virtual float		MinCheckDist();		// how far should I look ahead in my route?

	//---------------------------------

	CAI_Navigator		*GetNavigator( void );
	int					SelectWeightedSequence( Activity activity );
	float				GetSequenceGroundSpeed( int iSequence );

	float				CalcIntervalMove();

	// Yaw locking
	bool	IsYawLocked( void ) const { return m_bYawLocked; }
	void	SetYawLocked( bool state ) { m_bYawLocked = state; }

protected:

	//
	// Common services provided by CAI_BaseNPC, Convenience methods to simplify derived code
	//
	CAI_MoveProbe *		GetMoveProbe()										{ return m_pMoveProbe; }
	void 				SetSmoothedVelocity(const Vector &vecVelocity);
	Vector 				GetSmoothedVelocity();
	float				CalcIdealYaw( const Vector &vecTarget );
	float				SetBoneController ( int iController, float flValue );
	float 				GetSequenceMoveYaw( int iSequence );
	void				SetPlaybackRate( float flRate );
	float				GetPlaybackRate(); //get
	float				SetPoseParameter( const char *szName, float flValue );
	float				SetPoseParameter( int iParameter, float flValue );
	float				GetPoseParameter( const char *szName );
	bool				HasPoseParameter( int iSequence, const char *szName );
	bool				HasPoseParameter( int iSequence, int iParameter );
	void				SetMoveType( MoveType_t val, MoveCollide_t moveCollide = MOVECOLLIDE_DEFAULT );
	float				StepHeight() const;
	bool				CanStandOn( CBaseEntity *pSurface ) const;
	
	// ----------------------------------------------------
	// Primitives
	// ----------------------------------------------------
	
	virtual void		MoveFacing( const AILocalMoveGoal_t &move );

	virtual AIMotorMoveResult_t MoveGroundExecute( const AILocalMoveGoal_t &move, AIMoveTrace_t *pTraceResult );
	AIMotorMoveResult_t			MoveGroundExecuteWalk( const AILocalMoveGoal_t &move, float speed, float dist, AIMoveTrace_t *pTraceResult );
	virtual AIMotorMoveResult_t MoveFlyExecute( const AILocalMoveGoal_t &move, AIMoveTrace_t *pTraceResult );
	
protected: // made protected while animation transition details worked out, private:

	// --------------------------------
	void				SetMoveVel(const Vector &velocity)		{ m_vecVelocity = velocity; }
	float				IdealVelocity();		// how fast should I be moving in an ideal state?

	// --------------------------------
	float 				m_flMoveInterval;

	float				m_IdealYaw;
	float				m_YawSpeed;

	Vector				m_vecVelocity;
	Vector				m_vecAngularVelocity;

	// --------------------------------

	int					m_nDismountSequence;
	Vector				m_vecDismount;

	// --------------------------------

	CAI_InterestTarget	m_facingQueue;

	// --------------------------------
	
	CAI_MoveProbe *		m_pMoveProbe;

	bool				m_bYawLocked;

	//---------------------------------
public:
	DECLARE_SIMPLE_DATADESC();
};

//=============================================================================

#endif // AI_MOTOR_H