summaryrefslogtreecommitdiff
path: root/game/client/tf/c_entity_bird.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/client/tf/c_entity_bird.cpp')
-rw-r--r--game/client/tf/c_entity_bird.cpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/game/client/tf/c_entity_bird.cpp b/game/client/tf/c_entity_bird.cpp
new file mode 100644
index 0000000..a2001fa
--- /dev/null
+++ b/game/client/tf/c_entity_bird.cpp
@@ -0,0 +1,170 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Dove entity for the Meet the Medic tease.
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "tf_gamerules.h"
+#include "c_baseanimating.h"
+
+#define ENTITY_FLYING_BIRD_MODEL "models/props_forest/dove.mdl"
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class C_EntityFlyingBird : public CBaseAnimating
+{
+ DECLARE_CLASS( C_EntityFlyingBird, CBaseAnimating );
+public:
+ void InitFromServerData( float flyAngle, float flyAngleRate, float flAccelZ, float flSpeed, float flGlideTime );
+ virtual void Touch( CBaseEntity *pOther );
+
+private:
+ virtual void ClientThink( void );
+ void UpdateFlyDirection( void );
+
+private:
+ Vector m_flyForward;
+ float m_flyAngle;
+ float m_flyAngleRate;
+ float m_flyZ;
+ float m_accelZ;
+ float m_speed;
+ float m_timestamp;
+
+ CountdownTimer m_lifetimeTimer;
+ CountdownTimer m_glideTimer;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Server message that tells us to create a dove
+//-----------------------------------------------------------------------------
+void __MsgFunc_SpawnFlyingBird( bf_read &msg )
+{
+ Vector vecPos;
+ msg.ReadBitVec3Coord( vecPos );
+ float flyAngle = msg.ReadFloat();
+ float flyAngleRate = msg.ReadFloat();
+ float flAccelZ = msg.ReadFloat();
+ float flSpeed = msg.ReadFloat();
+ float flGlideTime = msg.ReadFloat();
+
+ C_EntityFlyingBird *pBird = new C_EntityFlyingBird();
+ if ( !pBird )
+ return;
+
+ pBird->SetAbsOrigin( vecPos );
+ pBird->InitFromServerData( flyAngle, flyAngleRate, flAccelZ, flSpeed, flGlideTime );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_EntityFlyingBird::UpdateFlyDirection( void )
+{
+ Vector forward;
+
+ forward.x = cos( m_flyAngle );
+ forward.y = sin( m_flyAngle );
+ forward.z = m_flyZ;
+ forward.NormalizeInPlace();
+
+ SetAbsVelocity( forward * m_speed );
+
+ QAngle angles;
+ VectorAngles( forward, angles );
+
+ SetAbsAngles( angles );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_EntityFlyingBird::InitFromServerData( float flyAngle, float flyAngleRate, float flAccelZ, float flSpeed, float flGlideTime )
+{
+ if ( InitializeAsClientEntity( ENTITY_FLYING_BIRD_MODEL, RENDER_GROUP_OPAQUE_ENTITY ) == false )
+ {
+ Release();
+ return;
+ }
+
+ SetMoveType( MOVETYPE_FLY );
+ SetSolid( SOLID_BBOX );
+ SetCollisionGroup( COLLISION_GROUP_DEBRIS );
+ SetSize( -Vector(8,8,0), Vector(8,8,16) );
+
+ m_flyAngle = flyAngle;
+ m_flyAngleRate = flyAngleRate;
+ m_accelZ = flAccelZ;
+ m_flyZ = 0.0;
+ m_speed = flSpeed;
+
+ UpdateFlyDirection();
+
+ SetSequence( 0 );
+ SetPlaybackRate( 1.0f );
+ SetCycle( 0 );
+ ResetSequenceInfo();
+
+ // make sure the bird is removed
+ m_lifetimeTimer.Start( 10.0f );
+
+ m_glideTimer.Start( flGlideTime );
+
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ m_timestamp = gpGlobals->curtime;
+
+ SetModelScale( 0.1f );
+ SetModelScale( 1.0f, 0.5f );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Fly away!
+//-----------------------------------------------------------------------------
+void C_EntityFlyingBird::ClientThink( void )
+{
+ if ( m_lifetimeTimer.IsElapsed() )
+ {
+ Release();
+ return;
+ }
+
+ if ( m_glideTimer.HasStarted() && m_glideTimer.IsElapsed() )
+ {
+ SetSequence( 1 );
+ SetPlaybackRate( 1.0f );
+ SetCycle( 0 );
+ ResetSequenceInfo();
+ m_glideTimer.Invalidate();
+ }
+
+ StudioFrameAdvance();
+
+ PhysicsSimulate();
+
+ const float deltaT = gpGlobals->curtime - m_timestamp;
+ m_flyAngle += m_flyAngleRate * deltaT;
+ m_flyZ += m_accelZ * deltaT;
+
+ UpdateFlyDirection();
+
+ m_timestamp = gpGlobals->curtime;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_EntityFlyingBird::Touch( CBaseEntity *pOther )
+{
+ if ( !pOther || !pOther->IsWorld() )
+ return;
+
+ BaseClass::Touch( pOther );
+
+ // Die at next think. Not safe to remove ourselves during physics touch.
+ m_lifetimeTimer.Invalidate();
+}
+