-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathNextBotGroundLocomotion.h
More file actions
274 lines (198 loc) · 10.5 KB
/
NextBotGroundLocomotion.h
File metadata and controls
274 lines (198 loc) · 10.5 KB
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
//========= Copyright Valve Corporation, All rights reserved. ============//
// NextBotGroundLocomotion.h
// Basic ground-based movement for NextBotCombatCharacters
// Author: Michael Booth, February 2009
// Note: This is a refactoring of ZombieBotLocomotion from L4D
#ifndef NEXT_BOT_GROUND_LOCOMOTION_H
#define NEXT_BOT_GROUND_LOCOMOTION_H
#include "NextBotLocomotionInterface.h"
#include "nav_mesh.h"
class NextBotCombatCharacter;
//----------------------------------------------------------------------------------------------------------------
/**
* Basic ground-based movement for NextBotCombatCharacters.
* This locomotor resolves collisions and assumes a ground-based bot under the influence of gravity.
*/
class NextBotGroundLocomotion : public ILocomotion
{
public:
DECLARE_CLASS( NextBotGroundLocomotion, ILocomotion );
NextBotGroundLocomotion( INextBot *bot );
virtual ~NextBotGroundLocomotion();
virtual void Reset( void ); // reset locomotor to initial state
virtual void Update( void ); // update internal state
virtual void Approach( const Vector &pos, float goalWeight = 1.0f ); // move directly towards the given position
virtual void DriveTo( const Vector &pos ); // Move the bot to the precise given position immediately,
virtual bool ClimbUpToLedge( const Vector &landingGoal, const Vector &landingForward, const CBaseEntity *obstacle ); // 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 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 float GetSpeedLimit( void ) const; // 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 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;
virtual bool IsAscendingOrDescendingLadder( void ) const; // we are actually on the ladder right now, either climbing up or down
virtual void FaceTowards( const Vector &target ); // rotate body to face towards "target"
virtual void SetDesiredLean( const QAngle &lean );
virtual const QAngle &GetDesiredLean( void ) const;
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 &GetAcceleration( void ) const; // return current world space acceleration
virtual void SetAcceleration( const Vector &accel ); // set world space acceleration
virtual const Vector &GetVelocity( void ) const; // return current world space velocity
virtual void SetVelocity( const Vector &vel ); // set world space velocity
virtual void OnMoveToSuccess( const Path *path ); // invoked when an bot reaches its MoveTo goal
virtual void OnMoveToFailure( const Path *path, MoveToFailureType reason ); // invoked when an bot fails to reach a MoveTo goal
private:
void UpdatePosition( const Vector &newPos ); // move to newPos, resolving any collisions along the way
void UpdateGroundConstraint( void ); // keep ground solid
Vector ResolveCollisionV0( Vector from, Vector to, int recursionLimit );
Vector ResolveZombieCollisions( const Vector &pos ); // push away zombies that are interpenetrating
Vector ResolveCollision( const Vector &from, const Vector &to, int recursionLimit ); // check for collisions along move
bool DetectCollision( trace_t *pTrace, int &nDestructionAllowed, const Vector &from, const Vector &to, const Vector &vecMins, const Vector &vecMaxs );
void ApplyAccumulatedApproach( void );
bool DidJustJump( void ) const; // return true if we just started a jump
bool TraverseLadder( void ); // return true if we are climbing a ladder
virtual float GetGravity( void ) const; // return gravity force acting on bot
virtual float GetFrictionForward( void ) const; // return magnitude of forward friction
virtual float GetFrictionSideways( void ) const; // return magnitude of lateral friction
virtual float GetMaxYawRate( void ) const; // return max rate of yaw rotation
private:
NextBotCombatCharacter *m_nextBot;
Vector m_priorPos; // last update's position
Vector m_lastValidPos; // last valid position (not interpenetrating)
Vector m_acceleration;
Vector m_velocity;
float m_desiredSpeed; // speed bot wants to be moving
float m_actualSpeed; // actual speed bot is moving
float m_maxRunSpeed;
float m_forwardLean;
float m_sideLean;
QAngle m_desiredLean;
bool m_isJumping; // if true, we have jumped and have not yet hit the ground
bool m_isJumpingAcrossGap; // if true, we have jumped across a gap and have not yet hit the ground
EHANDLE m_ground; // have to manage this ourselves, since MOVETYPE_CUSTOM always NULLs out GetGroundEntity()
Vector m_groundNormal; // surface normal of the ground we are in contact with
bool m_isClimbingUpToLedge; // true if we are jumping up to an adjacent ledge
Vector m_ledgeJumpGoalPos;
bool m_isUsingFullFeetTrace; // true if we're in the air and tracing the lowest StepHeight in ResolveCollision
const CNavLadder *m_ladder; // ladder we are currently climbing/descending
const CNavArea *m_ladderDismountGoal; // the area we enter when finished with our ladder move
bool m_isGoingUpLadder; // if false, we're going down
CountdownTimer m_inhibitObstacleAvoidanceTimer; // when active, turn off path following feelers
CountdownTimer m_wiggleTimer; // for wiggling
NavRelativeDirType m_wiggleDirection;
mutable Vector m_eyePos; // for use with GetEyes(), etc.
Vector m_moveVector; // the direction of our motion in XY plane
float m_moveYaw; // global yaw of movement direction
Vector m_accumApproachVectors; // weighted sum of Approach() calls since last update
float m_accumApproachWeights;
bool m_bRecomputePostureOnCollision;
CountdownTimer m_ignorePhysicsPropTimer; // if active, don't collide with physics props (because we got stuck in one)
EHANDLE m_ignorePhysicsProp; // which prop to ignore
};
inline float NextBotGroundLocomotion::GetGravity( void ) const
{
return 1000.0f;
}
inline float NextBotGroundLocomotion::GetFrictionForward( void ) const
{
return 0.0f;
}
inline float NextBotGroundLocomotion::GetFrictionSideways( void ) const
{
return 3.0f;
}
inline float NextBotGroundLocomotion::GetMaxYawRate( void ) const
{
return 250.0f;
}
inline CBaseEntity *NextBotGroundLocomotion::GetGround( void ) const
{
return m_ground;
}
inline const Vector &NextBotGroundLocomotion::GetGroundNormal( void ) const
{
return m_groundNormal;
}
inline void NextBotGroundLocomotion::SetDesiredLean( const QAngle &lean )
{
m_desiredLean = lean;
}
inline const QAngle &NextBotGroundLocomotion::GetDesiredLean( void ) const
{
return m_desiredLean;
}
inline void NextBotGroundLocomotion::SetDesiredSpeed( float speed )
{
m_desiredSpeed = speed;
}
inline float NextBotGroundLocomotion::GetDesiredSpeed( void ) const
{
return m_desiredSpeed;
}
inline bool NextBotGroundLocomotion::IsClimbingOrJumping( void ) const
{
return m_isJumping;
}
inline bool NextBotGroundLocomotion::IsClimbingUpToLedge( void ) const
{
return m_isClimbingUpToLedge;
}
inline bool NextBotGroundLocomotion::IsJumpingAcrossGap( void ) const
{
return m_isJumpingAcrossGap;
}
inline bool NextBotGroundLocomotion::IsRunning( void ) const
{
/// @todo Rethink interface to distinguish actual state vs desired state (do we want to be running, or are we actually at running speed right now)
return m_actualSpeed > 0.9f * GetRunSpeed();
}
inline float NextBotGroundLocomotion::GetStepHeight( void ) const
{
return 18.0f;
}
inline float NextBotGroundLocomotion::GetMaxJumpHeight( void ) const
{
return 180.0f; // 120.0f; // 84.0f; // 58.0f;
}
inline float NextBotGroundLocomotion::GetDeathDropHeight( void ) const
{
return 200.0f;
}
inline float NextBotGroundLocomotion::GetRunSpeed( void ) const
{
return 150.0f;
}
inline float NextBotGroundLocomotion::GetWalkSpeed( void ) const
{
return 75.0f;
}
inline float NextBotGroundLocomotion::GetMaxAcceleration( void ) const
{
return 500.0f;
}
inline float NextBotGroundLocomotion::GetMaxDeceleration( void ) const
{
return 500.0f;
}
#endif // NEXT_BOT_GROUND_LOCOMOTION_H