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
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// fish.h
// Simple fish behavior
// Author: Michael S. Booth, April 2005
#ifndef _FISH_H_
#define _FISH_H_
#include "baseanimating.h"
#include "GameEventListener.h"
class CFishPool;
//----------------------------------------------------------------------------------------------
/**
* Simple ambient fish
*/
class CFish : public CBaseAnimating
{
public:
DECLARE_CLASS( CFish, CBaseAnimating );
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
CFish( void );
virtual ~CFish();
void Initialize( CFishPool *pool, unsigned int id );
virtual void Spawn( void );
virtual void Event_Killed( const CTakeDamageInfo &info );
virtual void Touch( CBaseEntity *other ); ///< in contact with "other"
void Update( float deltaT ); ///< invoked each server tick
void FlockTo( CFish *other, float amount ); ///< influence my motion to flock with other nearby fish
float Avoid( void );
void Panic( void ); ///< panic for awhile
void ResetVisible( void ); ///< zero the visible vector
void AddVisible( CFish *fish ); ///< add this fish to our visible vector
private:
friend void SendProxy_FishOriginX( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
friend void SendProxy_FishOriginY( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
CHandle<CFishPool> m_pool; ///< the pool we are in
unsigned int m_id; ///< our unique ID
CNetworkVar( float, m_x ); ///< have to send position coordinates separately since Z is unused
CNetworkVar( float, m_y ); ///< have to send position coordinates separately since Z is unused
CNetworkVar( float, m_z ); ///< only sent once since fish always swim at the same depth
CNetworkVar( float, m_angle ); ///< only yaw changes
float m_angleChange;
Vector m_forward;
Vector m_perp;
CNetworkVar( Vector, m_poolOrigin ); ///< used to efficiently network our relative position
CNetworkVar( float, m_waterLevel );
float m_speed;
float m_desiredSpeed;
float m_calmSpeed; ///< speed the fish moves when calm
float m_panicSpeed; ///< speed the fish moves when panicked
float m_avoidRange; ///< range to avoid obstacles
CountdownTimer m_turnTimer; ///< every so often our turn preference changes
bool m_turnClockwise; ///< if true this fish prefers to turn clockwise, else CCW
CountdownTimer m_goTimer; ///< start the fish moving when timer elapses
CountdownTimer m_moveTimer; ///< dont decay speed while we are moving
CountdownTimer m_panicTimer; ///< if active, fish is panicked
CountdownTimer m_disperseTimer; ///< initial non-flocking time
CUtlVector< CFish * > m_visible; ///< vector of fish that we can see
};
//----------------------------------------------------------------------------------------------
/**
* This class defines a volume of water where a number of CFish swim
*/
class CFishPool : public CBaseEntity, public CGameEventListener
{
public:
DECLARE_CLASS( CFishPool, CBaseEntity );
DECLARE_DATADESC();
CFishPool( void );
virtual void Spawn();
virtual bool KeyValue( const char *szKeyName, const char *szValue );
virtual void FireGameEvent( IGameEvent *event );
void Update( void ); ///< invoked each server tick
float GetWaterLevel( void ) const; ///< return Z coordinate of water in world coords
float GetMaxRange( void ) const; ///< return how far a fish is allowed to wander
private:
int m_fishCount; ///< number of fish in the pool
float m_maxRange; ///< how far a fish is allowed to wander
float m_swimDepth; ///< the depth the fish swim below the water surface
float m_waterLevel; ///< Z of water surface
bool m_isDormant;
CUtlVector< CHandle<CFish> > m_fishes; ///< vector of all fish in this pool
CountdownTimer m_visTimer; ///< for throttling line of sight checks between all fish
};
inline float CFishPool::GetMaxRange( void ) const
{
return m_maxRange;
}
inline float CFishPool::GetWaterLevel( void ) const
{
return m_waterLevel;
}
#endif // _FISH_H_
|