hl2_src-leak-2017/src/game/client/tf/c_entity_bird.cpp

171 lines
4.3 KiB
C++

//========= 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();
}