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.

202 lines
5.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "c_tfc_player.h"
  8. #include "c_user_message_register.h"
  9. #include "view.h"
  10. #include "iclientvehicle.h"
  11. #include "ivieweffects.h"
  12. #include "input.h"
  13. #include "IEffects.h"
  14. #include "fx.h"
  15. #include "c_basetempentity.h"
  16. #include "hud_macros.h"
  17. #include "engine/ivdebugoverlay.h"
  18. #include "smoke_fog_overlay.h"
  19. #include "playerandobjectenumerator.h"
  20. #include "bone_setup.h"
  21. #include "in_buttons.h"
  22. #include "r_efx.h"
  23. #include "dlight.h"
  24. #include "shake.h"
  25. #include "cl_animevent.h"
  26. #include "weapon_tfcbase.h"
  27. #if defined( CTFCPlayer )
  28. #undef CTFCPlayer
  29. #endif
  30. #include "materialsystem/imesh.h" //for materials->FindMaterial
  31. #include "iviewrender.h" //for view->
  32. // -------------------------------------------------------------------------------- //
  33. // Player animation event. Sent to the client when a player fires, jumps, reloads, etc..
  34. // -------------------------------------------------------------------------------- //
  35. class C_TEPlayerAnimEvent : public C_BaseTempEntity
  36. {
  37. public:
  38. DECLARE_CLASS( C_TEPlayerAnimEvent, C_BaseTempEntity );
  39. DECLARE_CLIENTCLASS();
  40. virtual void PostDataUpdate( DataUpdateType_t updateType )
  41. {
  42. // Create the effect.
  43. C_TFCPlayer *pPlayer = dynamic_cast< C_TFCPlayer* >( m_hPlayer.Get() );
  44. if ( pPlayer && !pPlayer->IsDormant() )
  45. {
  46. pPlayer->DoAnimationEvent( (PlayerAnimEvent_t)m_iEvent.Get(), m_nData );
  47. }
  48. }
  49. public:
  50. CNetworkHandle( CBasePlayer, m_hPlayer );
  51. CNetworkVar( int, m_iEvent );
  52. CNetworkVar( int, m_nData );
  53. };
  54. IMPLEMENT_CLIENTCLASS_EVENT( C_TEPlayerAnimEvent, DT_TEPlayerAnimEvent, CTEPlayerAnimEvent );
  55. // ------------------------------------------------------------------------------------------ //
  56. // Data tables and prediction tables.
  57. // ------------------------------------------------------------------------------------------ //
  58. BEGIN_RECV_TABLE_NOBASE( C_TEPlayerAnimEvent, DT_TEPlayerAnimEvent )
  59. RecvPropEHandle( RECVINFO( m_hPlayer ) ),
  60. RecvPropInt( RECVINFO( m_iEvent ) ),
  61. RecvPropInt( RECVINFO( m_nData ) )
  62. END_RECV_TABLE()
  63. IMPLEMENT_CLIENTCLASS_DT( C_TFCPlayer, DT_TFCPlayer, CTFCPlayer )
  64. RecvPropFloat( RECVINFO( m_angEyeAngles[0] ) ),
  65. RecvPropFloat( RECVINFO( m_angEyeAngles[1] ) ),
  66. RecvPropDataTable( RECVINFO_DT( m_Shared ), 0, &REFERENCE_RECV_TABLE( DT_TFCPlayerShared ) )
  67. END_RECV_TABLE()
  68. BEGIN_PREDICTION_DATA( C_TFCPlayer )
  69. DEFINE_PRED_TYPEDESCRIPTION( m_Shared, CTFCPlayerShared ),
  70. END_PREDICTION_DATA()
  71. // ------------------------------------------------------------------------------------------ //
  72. // C_TFCPlayer implementation.
  73. // ------------------------------------------------------------------------------------------ //
  74. C_TFCPlayer::C_TFCPlayer() :
  75. m_iv_angEyeAngles( "C_TFCPlayer::m_iv_angEyeAngles" )
  76. {
  77. m_PlayerAnimState = CreatePlayerAnimState( this );
  78. m_Shared.Init( this );
  79. AddVar( &m_angEyeAngles, &m_iv_angEyeAngles, LATCH_SIMULATION_VAR );
  80. }
  81. C_TFCPlayer::~C_TFCPlayer()
  82. {
  83. m_PlayerAnimState->Release();
  84. }
  85. C_TFCPlayer* C_TFCPlayer::GetLocalTFCPlayer()
  86. {
  87. return ToTFCPlayer( C_BasePlayer::GetLocalPlayer() );
  88. }
  89. const QAngle& C_TFCPlayer::GetRenderAngles()
  90. {
  91. if ( IsRagdoll() )
  92. {
  93. return vec3_angle;
  94. }
  95. else
  96. {
  97. return m_PlayerAnimState->GetRenderAngles();
  98. }
  99. }
  100. void C_TFCPlayer::UpdateClientSideAnimation()
  101. {
  102. // Update the animation data. It does the local check here so this works when using
  103. // a third-person camera (and we don't have valid player angles).
  104. if ( this == C_TFCPlayer::GetLocalTFCPlayer() )
  105. m_PlayerAnimState->Update( EyeAngles()[YAW], m_angEyeAngles[PITCH] );
  106. else
  107. m_PlayerAnimState->Update( m_angEyeAngles[YAW], m_angEyeAngles[PITCH] );
  108. BaseClass::UpdateClientSideAnimation();
  109. }
  110. void C_TFCPlayer::PostDataUpdate( DataUpdateType_t updateType )
  111. {
  112. // C_BaseEntity assumes we're networking the entity's angles, so pretend that it
  113. // networked the same value we already have.
  114. SetNetworkAngles( GetLocalAngles() );
  115. BaseClass::PostDataUpdate( updateType );
  116. }
  117. void C_TFCPlayer::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
  118. {
  119. m_PlayerAnimState->DoAnimationEvent( event, nData );
  120. }
  121. void C_TFCPlayer::ProcessMuzzleFlashEvent()
  122. {
  123. // Reenable when the weapons have muzzle flash attachments in the right spot.
  124. if ( this != C_BasePlayer::GetLocalPlayer() )
  125. {
  126. Vector vAttachment;
  127. QAngle dummyAngles;
  128. C_WeaponTFCBase *pWeapon = m_Shared.GetActiveTFCWeapon();
  129. if ( pWeapon )
  130. {
  131. int iAttachment = pWeapon->LookupAttachment( "muzzle_flash" );
  132. if ( iAttachment > 0 )
  133. {
  134. float flScale = 1;
  135. pWeapon->GetAttachment( iAttachment, vAttachment, dummyAngles );
  136. // The way the models are setup, the up vector points along the barrel.
  137. Vector vForward, vRight, vUp;
  138. AngleVectors( dummyAngles, &vForward, &vRight, &vUp );
  139. VectorAngles( vUp, dummyAngles );
  140. FX_MuzzleEffect( vAttachment, dummyAngles, flScale, INVALID_EHANDLE_INDEX, NULL, true );
  141. }
  142. }
  143. }
  144. Vector vAttachment;
  145. QAngle dummyAngles;
  146. bool bFoundAttachment = GetAttachment( 1, vAttachment, dummyAngles );
  147. // If we have an attachment, then stick a light on it.
  148. if ( bFoundAttachment )
  149. {
  150. dlight_t *el = effects->CL_AllocDlight( LIGHT_INDEX_MUZZLEFLASH + index );
  151. el->origin = vAttachment;
  152. el->radius = 24;
  153. el->decay = el->radius / 0.05f;
  154. el->die = gpGlobals->curtime + 0.05f;
  155. el->color.r = 255;
  156. el->color.g = 192;
  157. el->color.b = 64;
  158. el->color.exponent = 5;
  159. }
  160. }