summaryrefslogtreecommitdiff
path: root/game/shared/tf2/tf_shieldshared.h
blob: 52ed30130570b3d7facdcca22e9eb2da664238cd (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
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
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//=============================================================================//

#ifndef TF_SHIELD_SHARED_H
#define TF_SHIELD_SHARED_H
#ifdef _WIN32
#pragma once
#endif

#include "mathlib/mathlib.h"
#include "mathlib/vector.h"
#include "mathlib/vmatrix.h"
#include "utlvector.h"
#include "SheetSimulator.h"
#include "predictable_entity.h"


//-----------------------------------------------------------------------------
// Purpose: Shield (mobile version)
//-----------------------------------------------------------------------------
enum
{
	SHIELD_NUM_HORIZONTAL_POINTS = 8,
	SHIELD_NUM_VERTICAL_POINTS = 8,
	SHIELD_NUM_CONTROL_POINTS = SHIELD_NUM_HORIZONTAL_POINTS * SHIELD_NUM_VERTICAL_POINTS,
	SHIELD_INITIAL_THETA = 135,
	SHIELD_INITIAL_PHI = 90,
	SHIELD_HORIZONTAL_PANEL_COUNT = (SHIELD_NUM_HORIZONTAL_POINTS - 1),
	SHIELD_VERTICAL_PANEL_COUNT = (SHIELD_NUM_VERTICAL_POINTS - 1),
	SHIELD_PANELS_COUNT = (SHIELD_HORIZONTAL_PANEL_COUNT * SHIELD_VERTICAL_PANEL_COUNT),
	SHIELD_VERTEX_BYTES = (SHIELD_NUM_CONTROL_POINTS + 7) >> 3,
	SHIELD_TIME_SUBVISIBIONS = 2
};

//--------------------------------------------------------------------------
// Mobile shield state flags
//--------------------------------------------------------------------------
enum
{
	SHIELD_MOBILE_EMP = 0x1
};


//--------------------------------------------------------------------------
// Shield grenade state
//--------------------------------------------------------------------------
enum
{
	SHIELD_FLAT_EMP = 0x1,
	SHIELD_FLAT_INACTIVE = 0x2
};

enum
{
	SHIELD_FLAT_SHUTDOWN_TIME = 1
};

enum
{
	SHIELD_GRENADE_WIDTH = 150,
	SHIELD_GRENADE_HEIGHT = 150,
};


#define SHIELD_DAMAGE_CHANGE_TIME	1.5f


//-----------------------------------------------------------------------------
// Amount of time it takes to fade the shield in or out due to EMP 
//-----------------------------------------------------------------------------
#define SHIELD_EMP_FADE_TIME 0.7f


//-----------------------------------------------------------------------------
// Amount of time it takes a point to wobble when EMPed
//-----------------------------------------------------------------------------
#define SHIELD_EMP_WOBBLE_TIME 0.1f


//-----------------------------------------------------------------------------
// Methods we must install into the effect
//-----------------------------------------------------------------------------
class IActiveVertList
{
public:
	virtual int		GetActiveVertState( int iVert ) = 0;
	virtual void	SetActiveVertState( int iVert, int bOn ) = 0;
};


class CShieldEffect
{
	DECLARE_CLASS_NOBASE( CShieldEffect );
	DECLARE_PREDICTABLE();

public:
	CShieldEffect();

	void Precache();
	void Spawn(const Vector& currentPosition, const QAngle& currentAngles);

	// Sets the collision group
	void SetCollisionGroup( int group );

	// Computes the opacity....
	float ComputeOpacity( const Vector& pt, const Vector& center ) const;

	// Computes the bounds
	void ComputeBounds( Vector& mins, Vector& maxs );

	// Simulation
	void Simulate( float dt );

	// Sets desired orientation + position
	void SetDesiredOrigin( const Vector& origin );
	void SetDesiredAngles( const QAngle& angles );
	const QAngle& GetDesiredAngles() const;

	// Hooks in active bits...
	void SetActiveVertexList( IActiveVertList *pActiveVerts );

	// Gets a point...
	const Vector& GetPoint( int x, int y ) const;
	const Vector& GetPoint( int i ) const;
	Vector& GetPoint( int i );

	// Computes control points
	void ComputeControlPoints();

	// The current angles (computed by Simulate on the server)
	const QAngle& GetCurrentAngles() const;
	void SetCurrentAngles( const QAngle& angles);

	// The current position (computed by Simulate on the server)
	const Vector& GetCurrentPosition();
	void SetCurrentPosition( const Vector& pos );

	// Compute vertex activity
	void ComputeVertexActivity();

	// Recompute whether the panels are active or not
	void ComputePanelActivity();

	// Is a particular vertex active?
	bool IsVertexActive( int x, int y ) const;

	// Is a particular panel active?
	bool IsPanelActive( int x, int y ) const;

	// Gets a control point (for collision)
	const Vector& GetControlPoint( int i ) const { return m_pControlPoint[i]; }

	// Returns the panel size (for collision testing)
	void GetPanelSize( Vector& mins, Vector& maxs ) const;

	// Change the angular spring constant. This affects how fast the shield rotates to face the angles
	// given in SetAngles. Higher numbers are more responsive, but if you go too high (around 40), it will
	// jump past the specified angles and wiggle a little bit.
	void SetAngularSpringConstant( float flConstant );

	// Set the shield theta & phi
	void SetThetaPhi( float flTheta, float flPhi );

	// Returns the render bounds
	const Vector& GetRenderMins() const;
	const Vector& GetRenderMaxs() const;

private:
	// Simulation set up
	void ComputeRestPositions();
	void SetShieldPanelSize( Vector& mins, Vector& maxs );
	void SimulateTranslation( float dt );
	void SimulateRotation( float dt, const Vector& forward );
	void ComputeOrientationMatrix();

	float m_RestLength;
	float m_PlaneDist;
	float m_ShieldTheta;
	float m_ShieldPhi;

	// Spring constants
	float m_SpringConstant;
	float m_DampConstant;
	float m_ViscousDrag;
	float m_Mass;

	float m_AngularSpringConstant;
	float m_AngularViscousDrag;

	// collision group
	int		m_CollisionGroup;

	// Directions of the control points in shield space
	Vector	m_pFixedDirection[SHIELD_NUM_CONTROL_POINTS];

	// Position of the control points in world space
	Vector	m_pControlPoint[SHIELD_NUM_CONTROL_POINTS];

	// Bitfield indicating which vertices are active
	IActiveVertList *m_pActiveVerts;

	// Bitfield indicating which panels are active
	bool	m_pActivePanels[SHIELD_PANELS_COUNT];

	// Which point on the shield to test next
	int		m_TestPoint;
	int		m_PointList[SHIELD_NUM_CONTROL_POINTS];

	// desired position + orientation
	Vector	m_vecDesiredOrigin;
	QAngle	m_angDesiredAngles;

	// collision box
	Vector  m_PanelBoxMin;
	Vector	m_PanelBoxMax;

	// Render bounds (shield space)
	Vector  m_vecRenderMins;
	Vector	m_vecRenderMaxs;

	// Actual center position (relative to m_Origin)
	// + velocity (world space)
	Vector	m_Position;
	Vector	m_Velocity;

	// our current orientation....
	QAngle  m_CurrentAngles;
	VMatrix	m_Orientation;
	float	m_Theta;
	float	m_Phi;
	float	m_ThetaVelocity;
	float	m_PhiVelocity;
};


//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------
inline const QAngle& CShieldEffect::GetCurrentAngles() const 
{ 
	return m_CurrentAngles; 
}

//-----------------------------------------------------------------------------
// Returns the render bounds
//-----------------------------------------------------------------------------
inline const Vector& CShieldEffect::GetRenderMins() const
{
	return m_vecRenderMins;
}

inline const Vector& CShieldEffect::GetRenderMaxs() const
{
	return m_vecRenderMaxs;
}


#endif // TF_SHIELD_SHARED_H