forked from hitmen047/Source-PlusPlus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathai_blended_movement.h
260 lines (192 loc) · 6.89 KB
/
ai_blended_movement.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
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef AI_BLENDED_MOVEMENT_H
#define AI_BLENDED_MOVEMENT_H
#include "ai_basenpc.h"
#include "ai_motor.h"
#include "ai_navigator.h"
struct AI_Waypoint_t;
//-----------------------------------------------------------------------------
// CLASS: CAI_BlendedMotor
//
// Purpose: Home of fancy human animation transition code
//
//-----------------------------------------------------------------------------
class CAI_BlendedMotor : public CAI_Motor
{
typedef CAI_Motor BaseClass;
public:
CAI_BlendedMotor( CAI_BaseNPC *pOuter )
: BaseClass( pOuter )
{
m_iPrimaryLayer = -1;
m_nPrimarySequence = ACT_INVALID;
m_iSecondaryLayer = -1;
m_nSecondarySequence = ACT_INVALID;
m_flSecondaryWeight = 0.0f;
m_nSavedGoalActivity = ACT_INVALID;
m_nSavedTranslatedGoalActivity = ACT_INVALID;
m_nGoalSequence = ACT_INVALID;
m_nPrevMovementSequence = ACT_INVALID;
m_nInteriorSequence = ACT_INVALID;
m_bDeceleratingToGoal = false;
m_flStartCycle = 0.0f;
m_flPredictiveSpeedAdjust = 1.0f;
m_flReactiveSpeedAdjust = 1.0f;
m_vecPrevOrigin1.Init();
m_vecPrevOrigin2.Init();
m_prevYaw = 0.0f;
m_doTurn = 0.0f;
m_doLeft = 0.0f;
m_doRight = 0.0f;
m_flNextTurnAct = 0.0f;
}
void MoveClimbStart( const Vector &climbDest, const Vector &climbDir, float climbDist, float yaw );
void MoveJumpStart( const Vector &velocity );
void ResetMoveCalculations();
void MoveStart();
void ResetGoalSequence();
void MoveStop();
void MovePaused();
void MoveContinue();
float OverrideMaxYawSpeed( Activity activity );
void UpdateYaw( int speed );
void RecalculateYawSpeed();
bool IsDeceleratingToGoal() const { return m_bDeceleratingToGoal; }
float GetMoveScriptTotalTime();
void MaintainTurnActivity( void );
bool AddTurnGesture( float flYD );
private:
AIMotorMoveResult_t MoveGroundExecute( const AILocalMoveGoal_t &move, AIMoveTrace_t *pTraceResult );
AIMotorMoveResult_t MoveFlyExecute( const AILocalMoveGoal_t &move, AIMoveTrace_t *pTraceResult );
// --------------------------------
void BuildMoveScript( const AILocalMoveGoal_t &move, AIMoveTrace_t *pTraceResult );
void BuildVelocityScript( const AILocalMoveGoal_t &move );
void InsertSlowdown( float distToObstruction, float idealAccel, bool bAlwaysSlowdown );
int BuildTurnScript( int i, int j );
void BuildTurnScript( const AILocalMoveGoal_t &move );
int BuildInsertNode( int i, float flTime );
Activity GetTransitionActivity( void );
// --------------------------------
// helpers to simplify code
float GetCycle() { return GetOuter()->GetCycle(); }
int AddLayeredSequence( int sequence, int iPriority ) { return GetOuter()->AddLayeredSequence( sequence, iPriority ); }
void SetLayerWeight( int iLayer, float flWeight ) { GetOuter()->SetLayerWeight( iLayer, flWeight ); }
void SetLayerPlaybackRate( int iLayer, float flPlaybackRate ) { GetOuter()->SetLayerPlaybackRate( iLayer, flPlaybackRate ); }
void SetLayerNoRestore( int iLayer, bool bNoRestore ) { GetOuter()->SetLayerNoRestore( iLayer, bNoRestore ); }
void SetLayerCycle( int iLayer, float flCycle ) { GetOuter()->SetLayerCycle( iLayer, flCycle ); }
void SetLayerCycle( int iLayer, float flCycle, float flPrevCycle ) { GetOuter()->SetLayerCycle( iLayer, flCycle, flPrevCycle ); }
void RemoveLayer( int iLayer, float flKillRate, float flKillDelay ) { GetOuter()->RemoveLayer( iLayer, flKillRate, flKillDelay ); }
// --------------------------------
struct AI_Movementscript_t
{
public:
AI_Movementscript_t( )
{
Init( );
};
void Init( void )
{
memset( this, 0, sizeof(*this) );
};
float flTime; // time till next entry
float flElapsedTime; // time since first entry
float flDist; // distance to next entry
float flMaxVelocity;
// float flVelocity;
float flYaw;
float flAngularVelocity;
bool bLooping;
int nFlags;
AI_Waypoint_t *pWaypoint;
public:
AI_Movementscript_t *pNext;
AI_Movementscript_t *pPrev;
Vector vecLocation;
};
//---------------------------------
CUtlVector<AI_Movementscript_t> m_scriptMove;
CUtlVector<AI_Movementscript_t> m_scriptTurn;
//---------------------------------
bool m_bDeceleratingToGoal;
int m_iPrimaryLayer;
int m_iSecondaryLayer;
int m_nPrimarySequence;
int m_nSecondarySequence;
float m_flSecondaryWeight;
Activity m_nSavedGoalActivity;
Activity m_nSavedTranslatedGoalActivity;
int m_nGoalSequence;
int m_nPrevMovementSequence;
int m_nInteriorSequence;
float m_flStartCycle;
float m_flCurrRate;
float m_flPredictiveSpeedAdjust; // predictive speed adjust from probing slope
float m_flReactiveSpeedAdjust; // reactive speed adjust when slope movement detected
Vector m_vecPrevOrigin1;
Vector m_vecPrevOrigin2;
//---------------------------------
float m_flNextTurnGesture; // next time for large turn gesture
//---------------------------------
float m_prevYaw;
float m_doTurn;
float m_doLeft;
float m_doRight;
float m_flNextTurnAct; // next time for small turn gesture
float GetMoveScriptDist( float &flNewSpeed );
float GetMoveScriptYaw( void );
void SetMoveScriptAnim( float flNewSpeed );
int GetInteriorSequence( int fromSequence );
DECLARE_SIMPLE_DATADESC();
};
//-----------------------------------------------------------------------------
// CLASS: CAI_BlendingHost
//
// Purpose: Bridge to the home of fancy human animation transition code
//
//-----------------------------------------------------------------------------
template <class BASE_NPC>
class CAI_BlendingHost : public BASE_NPC
{
DECLARE_CLASS_NOFRIEND( CAI_BlendingHost, BASE_NPC );
public:
const CAI_BlendedMotor *GetBlendedMotor() const { return assert_cast<const CAI_BlendedMotor *>(this->GetMotor()); }
CAI_BlendedMotor * GetBlendedMotor() { return assert_cast<CAI_BlendedMotor *>(this->GetMotor()); }
CAI_Motor *CreateMotor()
{
MEM_ALLOC_CREDIT();
return new CAI_BlendedMotor( this );
}
CAI_Navigator *CreateNavigator()
{
CAI_Navigator *pNavigator = BaseClass::CreateNavigator();
pNavigator->SetValidateActivitySpeed( false );
return pNavigator;
}
float MaxYawSpeed( void )
{
float override = GetBlendedMotor()->OverrideMaxYawSpeed( this->GetActivity() );
if ( override != -1 )
return override;
return BaseClass::MaxYawSpeed();
}
float GetTimeToNavGoal()
{
float result = GetBlendedMotor()->GetMoveScriptTotalTime();
if ( result != -1 )
return result;
return BaseClass::GetTimeToNavGoal();
}
};
//-------------------------------------
// to simplify basic usage:
class CAI_BlendedNPC : public CAI_BlendingHost<CAI_BaseNPC>
{
DECLARE_CLASS( CAI_BlendedNPC, CAI_BlendingHost<CAI_BaseNPC> );
};
//-----------------------------------------------------------------------------
#endif