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.

278 lines
7.6 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: implements various common send proxies
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "sendproxy.h"
  9. #include "basetypes.h"
  10. #include "baseentity.h"
  11. #include "team.h"
  12. #include "player.h"
  13. // memdbgon must be the last include file in a .cpp file!!!
  14. #include "tier0/memdbgon.h"
  15. void SendProxy_Color32ToInt( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID )
  16. {
  17. color32 *pIn = (color32*)pData;
  18. *((unsigned int*)&pOut->m_Int) = ((unsigned int)pIn->r << 24) | ((unsigned int)pIn->g << 16) | ((unsigned int)pIn->b << 8) | ((unsigned int)pIn->a);
  19. }
  20. void SendProxy_EHandleToInt( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID)
  21. {
  22. CBaseHandle *pHandle = (CBaseHandle*)pVarData;
  23. if ( pHandle && pHandle->Get() )
  24. {
  25. int iSerialNum = pHandle->GetSerialNumber() & (1 << NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS) - 1;
  26. pOut->m_Int = pHandle->GetEntryIndex() | (iSerialNum << MAX_EDICT_BITS);
  27. }
  28. else
  29. {
  30. pOut->m_Int = INVALID_NETWORKED_EHANDLE_VALUE;
  31. }
  32. }
  33. void SendProxy_IntAddOne( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID)
  34. {
  35. int *pInt = (int *)pVarData;
  36. pOut->m_Int = (*pInt) + 1;
  37. }
  38. void SendProxy_ShortAddOne( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID)
  39. {
  40. short *pInt = (short *)pVarData;
  41. pOut->m_Int = (*pInt) + 1;
  42. }
  43. SendProp SendPropBool(
  44. char *pVarName,
  45. int offset,
  46. int sizeofVar )
  47. {
  48. Assert( sizeofVar == sizeof( bool ) );
  49. return SendPropInt( pVarName, offset, sizeofVar, 1, SPROP_UNSIGNED );
  50. }
  51. SendProp SendPropEHandle(
  52. char *pVarName,
  53. int offset,
  54. int flags,
  55. int sizeofVar,
  56. SendVarProxyFn proxyFn )
  57. {
  58. return SendPropInt( pVarName, offset, sizeofVar, NUM_NETWORKED_EHANDLE_BITS, SPROP_UNSIGNED|flags, proxyFn );
  59. }
  60. SendProp SendPropIntWithMinusOneFlag( char *pVarName, int offset, int sizeofVar, int nBits, SendVarProxyFn proxyFn )
  61. {
  62. return SendPropInt( pVarName, offset, sizeofVar, nBits, SPROP_UNSIGNED, proxyFn );
  63. }
  64. //-----------------------------------------------------------------------------
  65. // Purpose: Proxy that only sends data to team members
  66. // Input : *pStruct -
  67. // *pData -
  68. // *pOut -
  69. // objectID -
  70. // Output : Returns true on success, false on failure.
  71. //-----------------------------------------------------------------------------
  72. void* SendProxy_OnlyToTeam( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID )
  73. {
  74. CBaseEntity *pEntity = (CBaseEntity*)pStruct;
  75. if ( pEntity )
  76. {
  77. CTeam *pTeam = pEntity->GetTeam();
  78. if ( pTeam )
  79. {
  80. pRecipients->ClearAllRecipients();
  81. for ( int i=0; i < pTeam->GetNumPlayers(); i++ )
  82. pRecipients->SetRecipient( pTeam->GetPlayer( i )->GetClientIndex() );
  83. return (void*)pVarData;
  84. }
  85. }
  86. return NULL;
  87. }
  88. REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_OnlyToTeam );
  89. #define TIME_BITS 24
  90. // This table encodes edict data.
  91. static void SendProxy_Time( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID )
  92. {
  93. float clock_base = floor( gpGlobals->curtime );
  94. float t = *( float * )pVarData;
  95. float dt = t - clock_base;
  96. int addt = Floor2Int( 1000.0f * dt + 0.5f );
  97. // TIME_BITS bits gives us TIME_BITS-1 bits plus sign bit
  98. int maxoffset = 1 << ( TIME_BITS - 1);
  99. addt = clamp( addt, -maxoffset, maxoffset );
  100. pOut->m_Int = addt;
  101. }
  102. //-----------------------------------------------------------------------------
  103. // Purpose:
  104. // Input : *pVarName -
  105. // sizeofVar -
  106. // flags -
  107. // pId -
  108. // Output : SendProp
  109. //-----------------------------------------------------------------------------
  110. SendProp SendPropTime(
  111. char *pVarName,
  112. int offset,
  113. int sizeofVar )
  114. {
  115. // return SendPropInt( pVarName, offset, sizeofVar, TIME_BITS, 0, SendProxy_Time );
  116. // FIXME: Re-enable above when it doesn't cause lots of deltas
  117. return SendPropFloat( pVarName, offset, sizeofVar, -1, SPROP_NOSCALE );
  118. }
  119. #if !defined( NO_ENTITY_PREDICTION ) && defined( USE_PREDICTABLEID )
  120. #define PREDICTABLE_ID_BITS 31
  121. //-----------------------------------------------------------------------------
  122. // Purpose: Converts a predictable Id to an integer
  123. // Input : *pStruct -
  124. // *pVarData -
  125. // *pOut -
  126. // iElement -
  127. // objectID -
  128. //-----------------------------------------------------------------------------
  129. static void SendProxy_PredictableIdToInt( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID )
  130. {
  131. CPredictableId* pId = ( CPredictableId * )pVarData;
  132. if ( pId )
  133. {
  134. pOut->m_Int = pId->GetRaw();
  135. }
  136. else
  137. {
  138. pOut->m_Int = 0;
  139. }
  140. }
  141. //-----------------------------------------------------------------------------
  142. // Purpose:
  143. // Input : *pVarName -
  144. // sizeofVar -
  145. // flags -
  146. // pId -
  147. // Output : SendProp
  148. //-----------------------------------------------------------------------------
  149. SendProp SendPropPredictableId(
  150. char *pVarName,
  151. int offset,
  152. int sizeofVar )
  153. {
  154. return SendPropInt( pVarName, offset, sizeofVar, PREDICTABLE_ID_BITS, SPROP_UNSIGNED, SendProxy_PredictableIdToInt );
  155. }
  156. #endif
  157. void SendProxy_StringT_To_String( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID )
  158. {
  159. string_t &str = *((string_t*)pVarData);
  160. pOut->m_pString = (char*)STRING( str );
  161. }
  162. SendProp SendPropStringT( char *pVarName, int offset, int sizeofVar )
  163. {
  164. // Make sure it's the right type.
  165. Assert( sizeofVar == sizeof( string_t ) );
  166. return SendPropString( pVarName, offset, DT_MAX_STRING_BUFFERSIZE, 0, SendProxy_StringT_To_String );
  167. }
  168. void CSendProxyRecipients::SetRecipient( int iClient )
  169. {
  170. m_Bits.Set( iClient );
  171. }
  172. void CSendProxyRecipients::ClearRecipient( int iClient )
  173. {
  174. m_Bits.Clear( iClient );
  175. }
  176. void CSendProxyRecipients::SetOnly( int iClient )
  177. {
  178. m_Bits.ClearAll();
  179. SetRecipient( iClient );
  180. CBaseEntity *pEntity = CBaseEntity::Instance( iClient + 1 );
  181. if ( pEntity && pEntity->IsPlayer() )
  182. {
  183. CBasePlayer *pPlayer = static_cast< CBasePlayer * >( pEntity );
  184. if ( pPlayer->IsSplitScreenPlayer() )
  185. {
  186. if ( pPlayer->GetSplitScreenPlayerOwner() )
  187. {
  188. SetRecipient( pPlayer->GetSplitScreenPlayerOwner()->entindex() - 1 );
  189. }
  190. else
  191. {
  192. AssertOnce( !"CSendProxyRecipients::SetOnly: NULL pPlayer->GetSplitScreenPlayerOwner()" );
  193. }
  194. }
  195. else
  196. {
  197. CUtlVector< CHandle< CBasePlayer> > &list = pPlayer->GetSplitScreenPlayers();
  198. for ( int i = 0; i < list.Count(); ++i )
  199. {
  200. CBasePlayer *pSplitPlayer = list[ i ];
  201. if ( !pSplitPlayer )
  202. {
  203. continue;
  204. }
  205. int iEntIndex = pSplitPlayer->entindex();
  206. SetRecipient( iEntIndex - 1 );
  207. }
  208. }
  209. }
  210. }
  211. void CSendProxyRecipients::ExcludeOnly( int iClient )
  212. {
  213. m_Bits.SetAll();
  214. ClearRecipient( iClient );
  215. CBaseEntity *pEntity = CBaseEntity::Instance( iClient + 1 );
  216. if ( pEntity && pEntity->IsPlayer() )
  217. {
  218. CBasePlayer *pPlayer = static_cast< CBasePlayer * >( pEntity );
  219. if ( pPlayer->IsSplitScreenPlayer() )
  220. {
  221. if ( pPlayer->GetSplitScreenPlayerOwner() )
  222. {
  223. ClearRecipient( pPlayer->GetSplitScreenPlayerOwner()->entindex() - 1 );
  224. }
  225. }
  226. else
  227. {
  228. CUtlVector< CHandle< CBasePlayer> > &list = pPlayer->GetSplitScreenPlayers();
  229. for ( int i = 0; i < list.Count(); ++i )
  230. {
  231. CBasePlayer *pSplitPlayer = list[ i ];
  232. if ( !pSplitPlayer )
  233. {
  234. continue;
  235. }
  236. int iEntIndex = pSplitPlayer->entindex();
  237. ClearRecipient( iEntIndex - 1 );
  238. }
  239. }
  240. }
  241. }