-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathNextBotLocomotionInterface.h
335 lines (263 loc) · 12 KB
/
NextBotLocomotionInterface.h
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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
// NextBotLocomotionInterface.h
// NextBot interface for movement through the environment
// Author: Michael Booth, April 2005
//========= Copyright Valve Corporation, All rights reserved. ============//
#ifndef _NEXT_BOT_LOCOMOTION_INTERFACE_H_
#define _NEXT_BOT_LOCOMOTION_INTERFACE_H_
#include "NextBotComponentInterface.h"
class Path;
class INextBot;
class CNavLadder;
//----------------------------------------------------------------------------------------------------------------
/**
* The interface encapsulating *how* a bot moves through the world (walking? flying? etc)
*/
class ILocomotion : public INextBotComponent
{
public:
ILocomotion( INextBot *bot );
virtual ~ILocomotion();
virtual void Reset( void ); // (EXTEND) reset to initial state
virtual void Update( void ); // (EXTEND) update internal state
//
// The primary locomotive method
// Depending on the physics of the bot's motion, it may not actually
// reach the given position precisely.
// The 'weight' can be used to combine multiple Approach() calls within
// a single frame into a single goal (ie: weighted average)
//
virtual void Approach( const Vector &goalPos, float goalWeight = 1.0f ); // (EXTEND) move directly towards the given position
//
// Move the bot to the precise given position immediately,
// updating internal state as needed
// Collision resolution is done to prevent interpenetration, which may prevent
// the bot from reaching the given position. If no collisions occur, the
// bot will be at the given position when this method returns.
//
virtual void DriveTo( const Vector &pos ); // (EXTEND) Move the bot to the precise given position immediately,
//
// Locomotion modifiers
//
virtual bool ClimbUpToLedge( const Vector &landingGoal, const Vector &landingForward, const CBaseEntity *obstacle ) { return true; } // initiate a jump to an adjacent high ledge, return false if climb can't start
virtual void JumpAcrossGap( const Vector &landingGoal, const Vector &landingForward ) { } // initiate a jump across an empty volume of space to far side
virtual void Jump( void ) { } // initiate a simple undirected jump in the air
virtual bool IsClimbingOrJumping( void ) const; // is jumping in any form
virtual bool IsClimbingUpToLedge( void ) const; // is climbing up to a high ledge
virtual bool IsJumpingAcrossGap( void ) const; // is jumping across a gap to the far side
virtual bool IsScrambling( void ) const; // is in the middle of a complex action (climbing a ladder, climbing a ledge, jumping, etc) that shouldn't be interrupted
virtual void Run( void ) { } // set desired movement speed to running
virtual void Walk( void ) { } // set desired movement speed to walking
virtual void Stop( void ) { } // set desired movement speed to stopped
virtual bool IsRunning( void ) const;
virtual void SetDesiredSpeed( float speed ) { } // set desired speed for locomotor movement
virtual float GetDesiredSpeed( void ) const; // returns the current desired speed
virtual void SetSpeedLimit( float speed ) { } // set maximum speed bot can reach, regardless of desired speed
virtual float GetSpeedLimit( void ) const { return 1000.0f; } // get maximum speed bot can reach, regardless of desired speed
virtual bool IsOnGround( void ) const; // return true if standing on something
virtual void OnLeaveGround( CBaseEntity *ground ) { } // invoked when bot leaves ground for any reason
virtual void OnLandOnGround( CBaseEntity *ground ) { } // invoked when bot lands on the ground after being in the air
virtual CBaseEntity *GetGround( void ) const; // return the current ground entity or NULL if not on the ground
virtual const Vector &GetGroundNormal( void ) const; // surface normal of the ground we are in contact with
virtual float GetGroundSpeed( void ) const; // return current world space speed in XY plane
virtual const Vector &GetGroundMotionVector( void ) const; // return unit vector in XY plane describing our direction of motion - even if we are currently not moving
virtual void ClimbLadder( const CNavLadder *ladder, const CNavArea *dismountGoal ) { } // climb the given ladder to the top and dismount
virtual void DescendLadder( const CNavLadder *ladder, const CNavArea *dismountGoal ) { } // descend the given ladder to the bottom and dismount
virtual bool IsUsingLadder( void ) const; // we are moving to get on, ascending/descending, and/or dismounting a ladder
virtual bool IsAscendingOrDescendingLadder( void ) const; // we are actually on the ladder right now, either climbing up or down
virtual bool IsAbleToAutoCenterOnLadder( void ) const { return false; }
virtual void FaceTowards( const Vector &target ) { } // rotate body to face towards "target"
virtual void SetDesiredLean( const QAngle &lean ) { }
virtual const QAngle &GetDesiredLean( void ) const;
//
// Locomotion information
//
virtual bool IsAbleToJumpAcrossGaps( void ) const; // return true if this bot can jump across gaps in its path
virtual bool IsAbleToClimb( void ) const; // return true if this bot can climb arbitrary geometry it encounters
virtual const Vector &GetFeet( void ) const; // return position of "feet" - the driving point where the bot contacts the ground
virtual float GetStepHeight( void ) const; // if delta Z is greater than this, we have to jump to get up
virtual float GetMaxJumpHeight( void ) const; // return maximum height of a jump
virtual float GetDeathDropHeight( void ) const; // distance at which we will die if we fall
virtual float GetRunSpeed( void ) const; // get maximum running speed
virtual float GetWalkSpeed( void ) const; // get maximum walking speed
virtual float GetMaxAcceleration( void ) const; // return maximum acceleration of locomotor
virtual float GetMaxDeceleration( void ) const; // return maximum deceleration of locomotor
virtual const Vector &GetVelocity( void ) const; // return current world space velocity
virtual float GetSpeed( void ) const; // return current world space speed (magnitude of velocity)
virtual const Vector &GetMotionVector( void ) const; // return unit vector describing our direction of motion - even if we are currently not moving
virtual bool IsAreaTraversable( const CNavArea *baseArea ) const; // return true if given area can be used for navigation
virtual float GetTraversableSlopeLimit( void ) const; // return Z component of unit normal of steepest traversable slope
// return true if the given entity can be ignored during locomotion
enum TraverseWhenType
{
IMMEDIATELY, // the entity will not block our motion - we'll carry right through
EVENTUALLY // the entity will block us until we spend effort to open/destroy it
};
/**
* Return true if this locomotor could potentially move along the line given.
* If false is returned, fraction of walkable ray is returned in 'fraction'
*/
virtual bool IsPotentiallyTraversable( const Vector &from, const Vector &to, TraverseWhenType when = EVENTUALLY, float *fraction = NULL ) const;
/**
* Return true if there is a possible "gap" that will need to be jumped over
* If true is returned, fraction of ray before gap is returned in 'fraction'
*/
virtual bool HasPotentialGap( const Vector &from, const Vector &to, float *fraction = NULL ) const;
// return true if there is a "gap" here when moving in the given direction
virtual bool IsGap( const Vector &pos, const Vector &forward ) const;
virtual bool IsEntityTraversable( CBaseEntity *obstacle, TraverseWhenType when = EVENTUALLY ) const;
//
// Stuck state. If the locomotor cannot make progress, it becomes "stuck" and can only leave
// this stuck state by successfully moving and becoming un-stuck.
//
virtual bool IsStuck( void ) const; // return true if bot is stuck
virtual float GetStuckDuration( void ) const; // return how long we've been stuck
virtual void ClearStuckStatus( const char *reason = "" ); // reset stuck status to un-stuck
virtual bool IsAttemptingToMove( void ) const; // return true if we have tried to Approach() or DriveTo() very recently
void TraceHull( const Vector& start, const Vector& end, const Vector &mins, const Vector &maxs, unsigned int fMask, ITraceFilter *pFilter, trace_t *pTrace ) const;
/**
* Should we collide with this entity?
*/
virtual bool ShouldCollideWith( const CBaseEntity *object ) const { return true; }
protected:
virtual void AdjustPosture( const Vector &moveGoal );
virtual void StuckMonitor( void );
private:
Vector m_motionVector;
Vector m_groundMotionVector;
float m_speed;
float m_groundSpeed;
// stuck monitoring
bool m_isStuck; // if true, we are stuck
IntervalTimer m_stuckTimer; // how long we've been stuck
CountdownTimer m_stillStuckTimer; // for resending stuck events
Vector m_stuckPos; // where we got stuck
IntervalTimer m_moveRequestTimer;
};
inline bool ILocomotion::IsAbleToJumpAcrossGaps( void ) const
{
return true;
}
inline bool ILocomotion::IsAbleToClimb( void ) const
{
return true;
}
inline bool ILocomotion::IsAttemptingToMove( void ) const
{
return m_moveRequestTimer.HasStarted() && m_moveRequestTimer.GetElapsedTime() < 0.25f;
}
inline bool ILocomotion::IsScrambling( void ) const
{
return !IsOnGround() || IsClimbingOrJumping() || IsAscendingOrDescendingLadder();
}
inline bool ILocomotion::IsClimbingOrJumping( void ) const
{
return false;
}
inline bool ILocomotion::IsClimbingUpToLedge( void ) const
{
return false;
}
inline bool ILocomotion::IsJumpingAcrossGap( void ) const
{
return false;
}
inline bool ILocomotion::IsRunning( void ) const
{
return false;
}
inline float ILocomotion::GetDesiredSpeed( void ) const
{
return 0.0f;
}
inline bool ILocomotion::IsOnGround( void ) const
{
return false;
}
inline CBaseEntity *ILocomotion::GetGround( void ) const
{
return NULL;
}
inline const Vector &ILocomotion::GetGroundNormal( void ) const
{
return vec3_origin;
}
inline float ILocomotion::GetGroundSpeed( void ) const
{
return m_groundSpeed;
}
inline const Vector & ILocomotion::GetGroundMotionVector( void ) const
{
return m_groundMotionVector;
}
inline bool ILocomotion::IsUsingLadder( void ) const
{
return false;
}
inline bool ILocomotion::IsAscendingOrDescendingLadder( void ) const
{
return false;
}
inline const QAngle &ILocomotion::GetDesiredLean( void ) const
{
return vec3_angle;
}
inline float ILocomotion::GetStepHeight( void ) const
{
return 0.0f;
}
inline float ILocomotion::GetMaxJumpHeight( void ) const
{
return 0.0f;
}
inline float ILocomotion::GetDeathDropHeight( void ) const
{
return 0.0f;
}
inline float ILocomotion::GetRunSpeed( void ) const
{
return 0.0f;
}
inline float ILocomotion::GetWalkSpeed( void ) const
{
return 0.0f;
}
inline float ILocomotion::GetMaxAcceleration( void ) const
{
return 0.0f;
}
inline float ILocomotion::GetMaxDeceleration( void ) const
{
return 0.0f;
}
inline const Vector &ILocomotion::GetVelocity( void ) const
{
return vec3_origin;
}
inline float ILocomotion::GetSpeed( void ) const
{
return m_speed;
}
inline const Vector & ILocomotion::GetMotionVector( void ) const
{
return m_motionVector;
}
inline float ILocomotion::GetTraversableSlopeLimit( void ) const
{
return 0.6;
}
inline bool ILocomotion::IsStuck( void ) const
{
return m_isStuck;
}
inline float ILocomotion::GetStuckDuration( void ) const
{
return ( IsStuck() ) ? m_stuckTimer.GetElapsedTime() : 0.0f;
}
inline void ILocomotion::TraceHull( const Vector& start, const Vector& end, const Vector &mins, const Vector &maxs, unsigned int fMask, ITraceFilter *pFilter, trace_t *pTrace ) const
{
// VPROF_BUDGET( "ILocomotion::TraceHull", "TraceHull" );
Ray_t ray;
ray.Init( start, end, mins, maxs );
enginetrace->TraceRay( ray, fMask, pFilter, pTrace );
}
#endif // _NEXT_BOT_LOCOMOTION_INTERFACE_H_