summaryrefslogtreecommitdiff
path: root/game/server/NextBot/Player/NextBotPlayerLocomotion.h
blob: 5da72601fbfe792ce68659443f7b0313ba696b92 (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
// 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_