Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
4.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Dove entity for the Meet the Medic tease.
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "tf_gamerules.h"
  8. #include "c_baseanimating.h"
  9. #define ENTITY_FLYING_BIRD_MODEL "models/props_forest/dove.mdl"
  10. //-----------------------------------------------------------------------------
  11. // Purpose:
  12. //-----------------------------------------------------------------------------
  13. class C_EntityFlyingBird : public CBaseAnimating
  14. {
  15. DECLARE_CLASS( C_EntityFlyingBird, CBaseAnimating );
  16. public:
  17. void InitFromServerData( float flyAngle, float flyAngleRate, float flAccelZ, float flSpeed, float flGlideTime );
  18. virtual void Touch( CBaseEntity *pOther );
  19. private:
  20. virtual void ClientThink( void );
  21. void UpdateFlyDirection( void );
  22. private:
  23. Vector m_flyForward;
  24. float m_flyAngle;
  25. float m_flyAngleRate;
  26. float m_flyZ;
  27. float m_accelZ;
  28. float m_speed;
  29. float m_timestamp;
  30. CountdownTimer m_lifetimeTimer;
  31. CountdownTimer m_glideTimer;
  32. };
  33. //-----------------------------------------------------------------------------
  34. // Purpose: Server message that tells us to create a dove
  35. //-----------------------------------------------------------------------------
  36. void __MsgFunc_SpawnFlyingBird( bf_read &msg )
  37. {
  38. Vector vecPos;
  39. msg.ReadBitVec3Coord( vecPos );
  40. float flyAngle = msg.ReadFloat();
  41. float flyAngleRate = msg.ReadFloat();
  42. float flAccelZ = msg.ReadFloat();
  43. float flSpeed = msg.ReadFloat();
  44. float flGlideTime = msg.ReadFloat();
  45. C_EntityFlyingBird *pBird = new C_EntityFlyingBird();
  46. if ( !pBird )
  47. return;
  48. pBird->SetAbsOrigin( vecPos );
  49. pBird->InitFromServerData( flyAngle, flyAngleRate, flAccelZ, flSpeed, flGlideTime );
  50. }
  51. //-----------------------------------------------------------------------------
  52. // Purpose:
  53. //-----------------------------------------------------------------------------
  54. void C_EntityFlyingBird::UpdateFlyDirection( void )
  55. {
  56. Vector forward;
  57. forward.x = cos( m_flyAngle );
  58. forward.y = sin( m_flyAngle );
  59. forward.z = m_flyZ;
  60. forward.NormalizeInPlace();
  61. SetAbsVelocity( forward * m_speed );
  62. QAngle angles;
  63. VectorAngles( forward, angles );
  64. SetAbsAngles( angles );
  65. }
  66. //-----------------------------------------------------------------------------
  67. // Purpose:
  68. //-----------------------------------------------------------------------------
  69. void C_EntityFlyingBird::InitFromServerData( float flyAngle, float flyAngleRate, float flAccelZ, float flSpeed, float flGlideTime )
  70. {
  71. if ( InitializeAsClientEntity( ENTITY_FLYING_BIRD_MODEL, RENDER_GROUP_OPAQUE_ENTITY ) == false )
  72. {
  73. Release();
  74. return;
  75. }
  76. SetMoveType( MOVETYPE_FLY );
  77. SetSolid( SOLID_BBOX );
  78. SetCollisionGroup( COLLISION_GROUP_DEBRIS );
  79. SetSize( -Vector(8,8,0), Vector(8,8,16) );
  80. m_flyAngle = flyAngle;
  81. m_flyAngleRate = flyAngleRate;
  82. m_accelZ = flAccelZ;
  83. m_flyZ = 0.0;
  84. m_speed = flSpeed;
  85. UpdateFlyDirection();
  86. SetSequence( 0 );
  87. SetPlaybackRate( 1.0f );
  88. SetCycle( 0 );
  89. ResetSequenceInfo();
  90. // make sure the bird is removed
  91. m_lifetimeTimer.Start( 10.0f );
  92. m_glideTimer.Start( flGlideTime );
  93. SetNextClientThink( CLIENT_THINK_ALWAYS );
  94. m_timestamp = gpGlobals->curtime;
  95. SetModelScale( 0.1f );
  96. SetModelScale( 1.0f, 0.5f );
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Purpose: Fly away!
  100. //-----------------------------------------------------------------------------
  101. void C_EntityFlyingBird::ClientThink( void )
  102. {
  103. if ( m_lifetimeTimer.IsElapsed() )
  104. {
  105. Release();
  106. return;
  107. }
  108. if ( m_glideTimer.HasStarted() && m_glideTimer.IsElapsed() )
  109. {
  110. SetSequence( 1 );
  111. SetPlaybackRate( 1.0f );
  112. SetCycle( 0 );
  113. ResetSequenceInfo();
  114. m_glideTimer.Invalidate();
  115. }
  116. StudioFrameAdvance();
  117. PhysicsSimulate();
  118. const float deltaT = gpGlobals->curtime - m_timestamp;
  119. m_flyAngle += m_flyAngleRate * deltaT;
  120. m_flyZ += m_accelZ * deltaT;
  121. UpdateFlyDirection();
  122. m_timestamp = gpGlobals->curtime;
  123. }
  124. //-----------------------------------------------------------------------------
  125. // Purpose:
  126. //-----------------------------------------------------------------------------
  127. void C_EntityFlyingBird::Touch( CBaseEntity *pOther )
  128. {
  129. if ( !pOther || !pOther->IsWorld() )
  130. return;
  131. BaseClass::Touch( pOther );
  132. // Die at next think. Not safe to remove ourselves during physics touch.
  133. m_lifetimeTimer.Invalidate();
  134. }