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
|
// NextBotPlayerLocomotion.h
// Locomotor for CBasePlayer derived bots
// Author: Michael Booth, November 2005
//========= Copyright Valve Corporation, All rights reserved. ============//
#ifndef _NEXT_BOT_PLAYER_LOCOMOTION_H_
#define _NEXT_BOT_PLAYER_LOCOMOTION_H_
#include "NextBot.h"
#include "NextBotLocomotionInterface.h"
#include "Path/NextBotPathFollow.h"
class CBasePlayer;
//--------------------------------------------------------------------------------------------------
/**
* Basic player locomotion implementation
*/
class PlayerLocomotion : public ILocomotion
{
public:
DECLARE_CLASS( PlayerLocomotion, ILocomotion );
PlayerLocomotion( INextBot *bot );
virtual ~PlayerLocomotion() { }
virtual void Reset( void ); // reset 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,
//
// ILocomotion modifiers
//
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 void SetMinimumSpeedLimit( float limit ); // speed cannot drop below this
virtual void SetMaximumSpeedLimit( float limit ); // speed cannot rise above this
virtual bool IsOnGround( void ) const; // return true if standing on something
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 bool IsAbleToAutoCenterOnLadder( void ) const;
virtual void FaceTowards( const Vector &target ); // rotate body to face towards "target"
virtual void SetDesiredLean( const QAngle &lean ) { }
virtual const QAngle &GetDesiredLean( void ) const { static QAngle junk; return junk; }
//
// ILocomotion information
//
virtual const Vector &GetFeet( void ) const; // return position of "feet" - point below centroid of bot at feet level
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
protected:
virtual void AdjustPosture( const Vector &moveGoal );
private:
CBasePlayer *m_player; // the player we are locomoting
mutable bool m_isJumping;
CountdownTimer m_jumpTimer;
bool m_isClimbingUpToLedge;
bool m_isJumpingAcrossGap;
Vector m_landingGoal;
bool m_hasLeftTheGround;
float m_desiredSpeed;
float m_minSpeedLimit;
float m_maxSpeedLimit;
bool TraverseLadder( void ); // when climbing/descending a ladder
enum LadderState
{
NO_LADDER, // not using a ladder
APPROACHING_ASCENDING_LADDER,
APPROACHING_DESCENDING_LADDER,
ASCENDING_LADDER,
DESCENDING_LADDER,
DISMOUNTING_LADDER_TOP,
DISMOUNTING_LADDER_BOTTOM,
};
LadderState m_ladderState;
LadderState ApproachAscendingLadder( void );
LadderState ApproachDescendingLadder( void );
LadderState AscendLadder( void );
LadderState DescendLadder( void );
LadderState DismountLadderTop( void );
LadderState DismountLadderBottom( void );
const CNavLadder *m_ladderInfo;
const CNavArea *m_ladderDismountGoal;
CountdownTimer m_ladderTimer; // a "give up" timer if things go awry
bool IsClimbPossible( INextBot *me, const CBaseEntity *obstacle ) const;
};
inline float PlayerLocomotion::GetStepHeight( void ) const
{
return 18.0f;
}
inline float PlayerLocomotion::GetMaxJumpHeight( void ) const
{
return 57.0f;
}
inline float PlayerLocomotion::GetDeathDropHeight( void ) const
{
return 200.0f;
}
inline float PlayerLocomotion::GetMaxAcceleration( void ) const
{
return 100.0f;
}
inline float PlayerLocomotion::GetMaxDeceleration( void ) const
{
return 200.0f;
}
inline void PlayerLocomotion::Run( void )
{
m_desiredSpeed = GetRunSpeed();
}
inline void PlayerLocomotion::Walk( void )
{
m_desiredSpeed = GetWalkSpeed();
}
inline void PlayerLocomotion::Stop( void )
{
m_desiredSpeed = 0.0f;
}
inline bool PlayerLocomotion::IsRunning( void ) const
{
return true;
}
inline void PlayerLocomotion::SetDesiredSpeed( float speed )
{
m_desiredSpeed = speed;
}
inline float PlayerLocomotion::GetDesiredSpeed( void ) const
{
return clamp( m_desiredSpeed, m_minSpeedLimit, m_maxSpeedLimit );
}
inline void PlayerLocomotion::SetMinimumSpeedLimit( float limit )
{
m_minSpeedLimit = limit;
}
inline void PlayerLocomotion::SetMaximumSpeedLimit( float limit )
{
m_maxSpeedLimit = limit;
}
inline bool PlayerLocomotion::IsAbleToAutoCenterOnLadder( void ) const
{
return IsUsingLadder() && (m_ladderState == ASCENDING_LADDER || m_ladderState == DESCENDING_LADDER);
}
inline bool PlayerLocomotion::IsAscendingOrDescendingLadder( void ) const
{
switch( m_ladderState )
{
case ASCENDING_LADDER:
case DESCENDING_LADDER:
case DISMOUNTING_LADDER_TOP:
case DISMOUNTING_LADDER_BOTTOM:
return true;
default:
// Explicitly handle the default so that clang knows not to warn us.
// warning: enumeration values 'NO_LADDER', 'APPROACHING_ASCENDING_LADDER', and 'APPROACHING_DESCENDING_LADDER' not handled in switch [-Wswitch-enum]
break;
}
return false;
}
#endif // _NEXT_BOT_PLAYER_LOCOMOTION_H_
|