Counter Strike : Global Offensive Source Code
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.

139 lines
4.4 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //=============================================================================//
  9. #include "cbase.h"
  10. #include "animation.h"
  11. #include "baseviewmodel.h"
  12. #include "player.h"
  13. #include <keyvalues.h>
  14. #include "studio.h"
  15. #include "vguiscreen.h"
  16. #include "saverestore_utlvector.h"
  17. #include "hltvdirector.h"
  18. #include "replaydirector.h"
  19. // memdbgon must be the last include file in a .cpp file!!!
  20. #include "tier0/memdbgon.h"
  21. void SendProxy_AnimTime( const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID );
  22. void SendProxy_SequenceChanged( const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID );
  23. //-----------------------------------------------------------------------------
  24. // Purpose: Save Data for Base Weapon object
  25. //-----------------------------------------------------------------------------//
  26. BEGIN_DATADESC( CBaseViewModel )
  27. DEFINE_FIELD( m_hOwner, FIELD_EHANDLE ),
  28. // Client only
  29. // DEFINE_FIELD( m_LagAnglesHistory, CInterpolatedVar < QAngle > ),
  30. // DEFINE_FIELD( m_vLagAngles, FIELD_VECTOR ),
  31. DEFINE_FIELD( m_nViewModelIndex, FIELD_INTEGER ),
  32. DEFINE_FIELD( m_flTimeWeaponIdle, FIELD_FLOAT ),
  33. DEFINE_FIELD( m_nAnimationParity, FIELD_INTEGER ),
  34. // Client only
  35. // DEFINE_FIELD( m_nOldAnimationParity, FIELD_INTEGER ),
  36. DEFINE_FIELD( m_vecLastFacing, FIELD_VECTOR ),
  37. DEFINE_FIELD( m_hWeapon, FIELD_EHANDLE ),
  38. DEFINE_UTLVECTOR( m_hScreens, FIELD_EHANDLE ),
  39. // Read from weapons file
  40. // DEFINE_FIELD( m_sVMName, FIELD_STRING ),
  41. // DEFINE_FIELD( m_sAnimationPrefix, FIELD_STRING ),
  42. // ---------------------------------------------------------------------
  43. // Don't save these, init to 0 and regenerate
  44. // DEFINE_FIELD( m_Activity, FIELD_INTEGER ),
  45. END_DATADESC()
  46. int CBaseViewModel::UpdateTransmitState()
  47. {
  48. if ( IsEffectActive( EF_NODRAW ) )
  49. {
  50. return SetTransmitState( FL_EDICT_DONTSEND );
  51. }
  52. return SetTransmitState( FL_EDICT_FULLCHECK );
  53. }
  54. int CBaseViewModel::ShouldTransmit( const CCheckTransmitInfo *pInfo )
  55. {
  56. // Check if recipient owns this weapon viewmodel
  57. CBasePlayer *pOwner = ToBasePlayer( m_hOwner );
  58. if ( pOwner &&
  59. ( pOwner->edict() == pInfo->m_pClientEnt ||
  60. // If we're using the other guys network connection in split screen, then also force transmit
  61. pOwner->IsSplitScreenUserOnEdict( pInfo->m_pClientEnt ) ) )
  62. {
  63. return FL_EDICT_ALWAYS;
  64. }
  65. // check if recipient (or one of his splitscreen parasites) is spectating the owner of this viewmodel
  66. CBasePlayer *pPlayer = ToBasePlayer( CBaseEntity::Instance( pInfo->m_pClientEnt ) );
  67. if ( pPlayer)
  68. {
  69. // Bug 28591: In splitscreen, when the second slot is the one in spectator mode, it wouldn't
  70. // get the viewmodel for the spectatee.
  71. //
  72. // The new logic is to loop through the splitscreen parasites (as well as the host player)
  73. // and see if any of them are observing the viewmodel owner, and if so, FL_EDICT_ALWAYS the vm for them, too.
  74. // This container was the source of most of the allocation cost in CS:GO so using a CUtlVectorFixed to avoid
  75. // allocations is important.
  76. CUtlVectorFixedGrowable< CBasePlayer *, MAX_SPLITSCREEN_CLIENTS > checkList;
  77. checkList.AddToTail( pPlayer );
  78. CUtlVector< CHandle< CBasePlayer > > &vecParasites = pPlayer->GetSplitScreenPlayers();
  79. for ( int i = 0; i < vecParasites.Count(); ++i )
  80. {
  81. checkList.AddToTail( vecParasites[ i ] );
  82. }
  83. for ( int i = 0; i < checkList.Count(); ++i )
  84. {
  85. CBasePlayer *pPlayer = checkList[ i ];
  86. if ( !pPlayer )
  87. continue;
  88. if ( pPlayer->IsHLTV() || pPlayer->IsReplay() )
  89. {
  90. // if this is the HLTV or Replay client, transmit all viewmodels in our PVS
  91. return FL_EDICT_PVSCHECK;
  92. }
  93. if ( (pPlayer->GetObserverMode() == OBS_MODE_IN_EYE) && (pPlayer->GetObserverTarget() == pOwner) )
  94. {
  95. return FL_EDICT_ALWAYS;
  96. }
  97. }
  98. }
  99. // Don't send to anyone else except the local player or his spectator
  100. return FL_EDICT_DONTSEND;
  101. }
  102. void CBaseViewModel::SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways )
  103. {
  104. // Are we already marked for transmission?
  105. if ( pInfo->m_pTransmitEdict->Get( entindex() ) )
  106. return;
  107. BaseClass::SetTransmit( pInfo, bAlways );
  108. // Force our screens to be sent too.
  109. for ( int i=0; i < m_hScreens.Count(); i++ )
  110. {
  111. CVGuiScreen *pScreen = m_hScreens[i].Get();
  112. if ( pScreen )
  113. pScreen->SetTransmit( pInfo, bAlways );
  114. }
  115. }