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.

876 lines
28 KiB

  1. //========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef DATATABLE_SEND_H
  9. #define DATATABLE_SEND_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "dt_common.h"
  14. #include "tier0/dbg.h"
  15. #include "const.h"
  16. #include "bitvec.h"
  17. // ------------------------------------------------------------------------ //
  18. // Send proxies can be used to convert a variable into a networkable type
  19. // (a good example is converting an edict pointer into an integer index).
  20. // These allow you to translate data. For example, if you had a user-entered
  21. // string number like "10" (call the variable pUserStr) and wanted to encode
  22. // it as an integer, you would use a SendPropInt32 and write a proxy that said:
  23. // pOut->m_Int = atoi(pUserStr);
  24. // pProp : the SendProp that has the proxy
  25. // pStructBase : the base structure (like CBaseEntity*).
  26. // pData : the address of the variable to proxy.
  27. // pOut : where to output the proxied value.
  28. // iElement : the element index if this data is part of an array (or 0 if not).
  29. // objectID : entity index for debugging purposes.
  30. // Return false if you don't want the engine to register and send a delta to
  31. // the clients for this property (regardless of whether it actually changed or not).
  32. // ------------------------------------------------------------------------ //
  33. typedef void (*SendVarProxyFn)( const SendProp *pProp, const void *pStructBase, const void *pData, DVariant *pOut, int iElement, int objectID );
  34. // Return the pointer to the data for the datatable.
  35. // If the proxy returns null, it's the same as if pRecipients->ClearAllRecipients() was called.
  36. class CSendProxyRecipients;
  37. typedef void* (*SendTableProxyFn)(
  38. const SendProp *pProp,
  39. const void *pStructBase,
  40. const void *pData,
  41. CSendProxyRecipients *pRecipients,
  42. int objectID );
  43. class CNonModifiedPointerProxy
  44. {
  45. public:
  46. explicit CNonModifiedPointerProxy( SendTableProxyFn fn );
  47. public:
  48. SendTableProxyFn m_Fn;
  49. CNonModifiedPointerProxy *m_pNext;
  50. };
  51. // This tells the engine that the send proxy will not modify the pointer
  52. // - it only plays with the recipients. This must be set on proxies that work
  53. // this way, otherwise the engine can't track which properties changed
  54. // in NetworkStateChanged().
  55. #define REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( sendProxyFn ) static CNonModifiedPointerProxy __proxy_##sendProxyFn( sendProxyFn );
  56. class CStandardSendProxiesV1
  57. {
  58. public:
  59. CStandardSendProxiesV1();
  60. SendVarProxyFn m_Int8ToInt32;
  61. SendVarProxyFn m_Int16ToInt32;
  62. SendVarProxyFn m_Int32ToInt32;
  63. SendVarProxyFn m_Int64ToInt64;
  64. SendVarProxyFn m_UInt8ToInt32;
  65. SendVarProxyFn m_UInt16ToInt32;
  66. SendVarProxyFn m_UInt32ToInt32;
  67. SendVarProxyFn m_UInt64ToInt64;
  68. SendVarProxyFn m_FloatToFloat;
  69. SendVarProxyFn m_VectorToVector;
  70. };
  71. class CStandardSendProxies : public CStandardSendProxiesV1
  72. {
  73. public:
  74. CStandardSendProxies();
  75. SendTableProxyFn m_DataTableToDataTable;
  76. CNonModifiedPointerProxy **m_ppNonModifiedPointerProxies;
  77. };
  78. extern CStandardSendProxies g_StandardSendProxies;
  79. // Max # of datatable send proxies you can have in a tree.
  80. #define MAX_DATATABLE_PROXIES 32
  81. // ------------------------------------------------------------------------ //
  82. // Datatable send proxies are used to tell the engine where the datatable's
  83. // data is and to specify which clients should get the data.
  84. //
  85. // pRecipients is the object that allows you to specify which clients will
  86. // receive the data.
  87. // ------------------------------------------------------------------------ //
  88. class CSendProxyRecipients
  89. {
  90. public:
  91. void SetAllRecipients(); // Note: recipients are all set by default when each proxy is called.
  92. void ClearAllRecipients();
  93. void SetRecipient( int iClient ); // Note: these are CLIENT indices, not entity indices (so the first player's index is 0).
  94. void ClearRecipient( int iClient );
  95. // Clear all recipients and set only the specified one.
  96. void SetOnly( int iClient );
  97. // Set all recipients, save for the specified on
  98. void ExcludeOnly( int iClient );
  99. public:
  100. // Make sure we have enough room for the max possible player count
  101. CPlayerBitVec m_Bits;
  102. };
  103. inline void CSendProxyRecipients::SetAllRecipients()
  104. {
  105. m_Bits.SetAll();
  106. }
  107. inline void CSendProxyRecipients::ClearAllRecipients()
  108. {
  109. m_Bits.ClearAll();
  110. }
  111. // ------------------------------------------------------------------------ //
  112. // ArrayLengthSendProxies are used when you want to specify an array's length
  113. // dynamically.
  114. // ------------------------------------------------------------------------ //
  115. typedef int (*ArrayLengthSendProxyFn)( const void *pStruct, int objectID );
  116. class RecvProp;
  117. class SendTable;
  118. class CSendTablePrecalc;
  119. // -------------------------------------------------------------------------------------------------------------- //
  120. // SendProp.
  121. // -------------------------------------------------------------------------------------------------------------- //
  122. // If SendProp::GetDataTableProxyIndex() returns this, then the proxy is one that always sends
  123. // the data to all clients, so we don't need to store the results.
  124. #define DATATABLE_PROXY_INDEX_NOPROXY 255
  125. #define DATATABLE_PROXY_INDEX_INVALID 254
  126. #define SENDPROP_DEFAULT_PRIORITY ((byte)128)
  127. #define SENDPROP_CHANGES_OFTEN_PRIORITY ((byte)64)
  128. // This adds in all the flags that we OR into the var's offset.
  129. #define SENDPROP_NETWORKVAR_FLAGS_SHIFT 20 // We store the networkvar flags in SendProp::m_Offset and this is what we shift it by.
  130. #define SENDPROP_OFFSET_MASK ( ( 1 << SENDPROP_NETWORKVAR_FLAGS_SHIFT ) - 1 )
  131. #define NETWORKVAR_OFFSET_FLAGS( className, varName ) \
  132. ( className::NetworkVarType_##varName::GetNetworkVarFlags() << SENDPROP_NETWORKVAR_FLAGS_SHIFT )
  133. class SendProp
  134. {
  135. public:
  136. SendProp();
  137. virtual ~SendProp();
  138. void Clear();
  139. int GetOffset() const;
  140. void SetOffset( int i );
  141. SendVarProxyFn GetProxyFn() const;
  142. void SetProxyFn( SendVarProxyFn f );
  143. SendTableProxyFn GetDataTableProxyFn() const;
  144. void SetDataTableProxyFn( SendTableProxyFn f );
  145. SendTable* GetDataTable() const;
  146. void SetDataTable( SendTable *pTable );
  147. char const* GetExcludeDTName() const;
  148. // If it's one of the numbered "000", "001", etc properties in an array, then
  149. // these can be used to get its array property name for debugging.
  150. const char* GetParentArrayPropName() const;
  151. void SetParentArrayPropName( char *pArrayPropName );
  152. const char* GetName() const;
  153. bool IsSigned() const;
  154. bool IsExcludeProp() const;
  155. bool IsInsideArray() const; // Returns true if SPROP_INSIDEARRAY is set.
  156. void SetInsideArray();
  157. // Arrays only.
  158. void SetArrayProp( SendProp *pProp );
  159. SendProp* GetArrayProp() const;
  160. // Arrays only.
  161. void SetArrayLengthProxy( ArrayLengthSendProxyFn fn );
  162. ArrayLengthSendProxyFn GetArrayLengthProxy() const;
  163. int GetNumElements() const;
  164. void SetNumElements( int nElements );
  165. // Return the # of bits to encode an array length (must hold GetNumElements()).
  166. int GetNumArrayLengthBits() const;
  167. int GetElementStride() const;
  168. SendPropType GetType() const;
  169. int GetFlags() const;
  170. void SetFlags( int flags );
  171. // Some property types bind more data to the SendProp in here.
  172. const void* GetExtraData() const;
  173. void SetExtraData( const void *pData );
  174. byte GetPriority() const;
  175. void SetPriority( byte priority );
  176. // These tell us which kind of CNetworkVar we're referring to.
  177. int GetNetworkVarFlags() const;
  178. bool AreNetworkVarFlagsSet( int nFlags ) const;
  179. // This is only ever used by SendPropXXX functions internally. They receive offset with the networkvar
  180. // flags OR'd and shifted in, so they'll specify both at the same time.
  181. void SetOffsetAndNetworkVarFlags( int nOffsetAndFlags );
  182. public:
  183. RecvProp *m_pMatchingRecvProp; // This is temporary and only used while precalculating
  184. // data for the decoders.
  185. SendPropType m_Type;
  186. int m_nBits;
  187. float m_fLowValue;
  188. float m_fHighValue;
  189. SendProp *m_pArrayProp; // If this is an array, this is the property that defines each array element.
  190. ArrayLengthSendProxyFn m_ArrayLengthProxy; // This callback returns the array length.
  191. int m_nElements; // Number of elements in the array (or 1 if it's not an array).
  192. int m_ElementStride; // Pointer distance between array elements.
  193. char *m_pExcludeDTName; // If this is an exclude prop, then this is the name of the datatable to exclude a prop from.
  194. char *m_pParentArrayPropName;
  195. char *m_pVarName;
  196. float m_fHighLowMul;
  197. byte m_priority;
  198. private:
  199. int m_Flags; // SPROP_ flags.
  200. SendVarProxyFn m_ProxyFn; // NULL for DPT_DataTable.
  201. SendTableProxyFn m_DataTableProxyFn; // Valid for DPT_DataTable.
  202. SendTable *m_pDataTable;
  203. // This also contains the NETWORKVAR_ flags shifted into the SENDPROP_NETWORKVAR_FLAGS_SHIFT range.
  204. // (Use GetNetworkVarFlags to access them).
  205. int m_Offset;
  206. // Extra data bound to this property.
  207. const void *m_pExtraData;
  208. };
  209. inline int SendProp::GetOffset() const
  210. {
  211. return m_Offset & SENDPROP_OFFSET_MASK;
  212. }
  213. inline void SendProp::SetOffset( int nOffset )
  214. {
  215. Assert( !( nOffset & ~SENDPROP_OFFSET_MASK ) );
  216. m_Offset = nOffset;
  217. }
  218. inline void SendProp::SetOffsetAndNetworkVarFlags( int nOffset )
  219. {
  220. m_Offset = nOffset;
  221. }
  222. inline int SendProp::GetNetworkVarFlags() const
  223. {
  224. return m_Offset >> SENDPROP_NETWORKVAR_FLAGS_SHIFT;
  225. }
  226. inline bool SendProp::AreNetworkVarFlagsSet( int nFlags ) const
  227. {
  228. return ( GetNetworkVarFlags() & nFlags ) == nFlags;
  229. }
  230. inline SendVarProxyFn SendProp::GetProxyFn() const
  231. {
  232. Assert( m_Type != DPT_DataTable );
  233. return m_ProxyFn;
  234. }
  235. inline void SendProp::SetProxyFn( SendVarProxyFn f )
  236. {
  237. m_ProxyFn = f;
  238. }
  239. inline SendTableProxyFn SendProp::GetDataTableProxyFn() const
  240. {
  241. Assert( m_Type == DPT_DataTable );
  242. return m_DataTableProxyFn;
  243. }
  244. inline void SendProp::SetDataTableProxyFn( SendTableProxyFn f )
  245. {
  246. m_DataTableProxyFn = f;
  247. }
  248. inline SendTable* SendProp::GetDataTable() const
  249. {
  250. return m_pDataTable;
  251. }
  252. inline void SendProp::SetDataTable( SendTable *pTable )
  253. {
  254. m_pDataTable = pTable;
  255. }
  256. inline char const* SendProp::GetExcludeDTName() const
  257. {
  258. return m_pExcludeDTName;
  259. }
  260. inline const char* SendProp::GetParentArrayPropName() const
  261. {
  262. return m_pParentArrayPropName;
  263. }
  264. inline void SendProp::SetParentArrayPropName( char *pArrayPropName )
  265. {
  266. Assert( !m_pParentArrayPropName );
  267. m_pParentArrayPropName = pArrayPropName;
  268. }
  269. inline const char* SendProp::GetName() const
  270. {
  271. return m_pVarName;
  272. }
  273. inline bool SendProp::IsSigned() const
  274. {
  275. return !(m_Flags & SPROP_UNSIGNED);
  276. }
  277. inline bool SendProp::IsExcludeProp() const
  278. {
  279. return (m_Flags & SPROP_EXCLUDE) != 0;
  280. }
  281. inline bool SendProp::IsInsideArray() const
  282. {
  283. return (m_Flags & SPROP_INSIDEARRAY) != 0;
  284. }
  285. inline void SendProp::SetInsideArray()
  286. {
  287. m_Flags |= SPROP_INSIDEARRAY;
  288. }
  289. inline void SendProp::SetArrayProp( SendProp *pProp )
  290. {
  291. m_pArrayProp = pProp;
  292. }
  293. inline SendProp* SendProp::GetArrayProp() const
  294. {
  295. return m_pArrayProp;
  296. }
  297. inline void SendProp::SetArrayLengthProxy( ArrayLengthSendProxyFn fn )
  298. {
  299. m_ArrayLengthProxy = fn;
  300. }
  301. inline ArrayLengthSendProxyFn SendProp::GetArrayLengthProxy() const
  302. {
  303. return m_ArrayLengthProxy;
  304. }
  305. inline int SendProp::GetNumElements() const
  306. {
  307. return m_nElements;
  308. }
  309. inline void SendProp::SetNumElements( int nElements )
  310. {
  311. m_nElements = nElements;
  312. }
  313. inline int SendProp::GetElementStride() const
  314. {
  315. return m_ElementStride;
  316. }
  317. inline SendPropType SendProp::GetType() const
  318. {
  319. return m_Type;
  320. }
  321. inline int SendProp::GetFlags() const
  322. {
  323. return m_Flags;
  324. }
  325. inline void SendProp::SetFlags( int flags )
  326. {
  327. // Make sure they're using something from the valid set of flags.
  328. Assert( !( flags & ~((1 << SPROP_NUMFLAGBITS) - 1) ) );
  329. m_Flags = flags;
  330. }
  331. inline const void* SendProp::GetExtraData() const
  332. {
  333. return m_pExtraData;
  334. }
  335. inline void SendProp::SetExtraData( const void *pData )
  336. {
  337. m_pExtraData = pData;
  338. }
  339. inline byte SendProp::GetPriority() const
  340. {
  341. return m_priority;
  342. }
  343. inline void SendProp::SetPriority( byte priority )
  344. {
  345. m_priority = priority;
  346. }
  347. // -------------------------------------------------------------------------------------------------------------- //
  348. // SendTable.
  349. // -------------------------------------------------------------------------------------------------------------- //
  350. class SendTable
  351. {
  352. public:
  353. typedef SendProp PropType;
  354. SendTable();
  355. SendTable( SendProp *pProps, int nProps, char *pNetTableName );
  356. ~SendTable();
  357. void Construct( SendProp *pProps, int nProps, char *pNetTableName );
  358. const char* GetName() const;
  359. int GetNumProps() const;
  360. SendProp* GetProp( int i );
  361. // Used by the engine.
  362. bool IsInitialized() const;
  363. void SetInitialized( bool bInitialized );
  364. // Used by the engine while writing info into the signon.
  365. void SetWriteFlag(bool bHasBeenWritten);
  366. bool GetWriteFlag() const;
  367. bool HasPropsEncodedAgainstTickCount() const;
  368. void SetHasPropsEncodedAgainstTickcount( bool bState );
  369. public:
  370. SendProp *m_pProps;
  371. int m_nProps;
  372. char *m_pNetTableName; // The name matched between client and server.
  373. // The engine hooks the SendTable here.
  374. CSendTablePrecalc *m_pPrecalc;
  375. protected:
  376. bool m_bInitialized : 1;
  377. bool m_bHasBeenWritten : 1;
  378. bool m_bHasPropsEncodedAgainstCurrentTickCount : 1; // m_flSimulationTime and m_flAnimTime, e.g.
  379. };
  380. inline const char* SendTable::GetName() const
  381. {
  382. return m_pNetTableName;
  383. }
  384. inline int SendTable::GetNumProps() const
  385. {
  386. return m_nProps;
  387. }
  388. inline SendProp* SendTable::GetProp( int i )
  389. {
  390. Assert( i >= 0 && i < m_nProps );
  391. return &m_pProps[i];
  392. }
  393. inline bool SendTable::IsInitialized() const
  394. {
  395. return m_bInitialized;
  396. }
  397. inline void SendTable::SetInitialized( bool bInitialized )
  398. {
  399. m_bInitialized = bInitialized;
  400. }
  401. inline bool SendTable::GetWriteFlag() const
  402. {
  403. return m_bHasBeenWritten;
  404. }
  405. inline void SendTable::SetWriteFlag(bool bHasBeenWritten)
  406. {
  407. m_bHasBeenWritten = bHasBeenWritten;
  408. }
  409. inline bool SendTable::HasPropsEncodedAgainstTickCount() const
  410. {
  411. return m_bHasPropsEncodedAgainstCurrentTickCount;
  412. }
  413. inline void SendTable::SetHasPropsEncodedAgainstTickcount( bool bState )
  414. {
  415. m_bHasPropsEncodedAgainstCurrentTickCount = bState;
  416. }
  417. // ------------------------------------------------------------------------------------------------------ //
  418. // Use BEGIN_SEND_TABLE if you want to declare a SendTable and have it inherit all the properties from
  419. // its base class. There are two requirements for this to work:
  420. // 1. Its base class must have a static SendTable pointer member variable called m_pClassSendTable which
  421. // points to its send table. The DECLARE_SERVERCLASS and IMPLEMENT_SERVERCLASS macros do this automatically.
  422. // 2. Your class must typedef its base class as BaseClass. So it would look like this:
  423. // class Derived : public CBaseEntity
  424. // {
  425. // typedef CBaseEntity BaseClass;
  426. // };
  427. // If you don't want to interit a base class's properties, use BEGIN_SEND_TABLE_NOBASE.
  428. // ------------------------------------------------------------------------------------------------------ //
  429. #define BEGIN_SEND_TABLE(className, tableName) \
  430. BEGIN_SEND_TABLE_NOBASE(className, tableName) \
  431. SendPropDataTable("baseclass", 0, className::BaseClass::m_pClassSendTable, SendProxy_DataTableToDataTable),
  432. #define BEGIN_SEND_TABLE_NOBASE(className, tableName) \
  433. template <typename T> int ServerClassInit(T *); \
  434. namespace tableName { \
  435. struct ignored; \
  436. } \
  437. template <> int ServerClassInit<tableName::ignored>(tableName::ignored *); \
  438. namespace tableName { \
  439. SendTable g_SendTable;\
  440. int g_SendTableInit = ServerClassInit((tableName::ignored *)NULL); \
  441. } \
  442. template <> int ServerClassInit<tableName::ignored>(tableName::ignored *) \
  443. { \
  444. typedef className currentSendDTClass; \
  445. static char *g_pSendTableName = #tableName; \
  446. SendTable &sendTable = tableName::g_SendTable; \
  447. static SendProp g_SendProps[] = { \
  448. SendPropInt("should_never_see_this", 0, sizeof(int)), // It adds a dummy property at the start so you can define "empty" SendTables.
  449. #define END_SEND_TABLE() \
  450. };\
  451. sendTable.Construct(g_SendProps+1, sizeof(g_SendProps) / sizeof(SendProp) - 1, g_pSendTableName);\
  452. return 1; \
  453. }
  454. // These can simplify creating the variables.
  455. // Note: currentSendDTClass::MakeANetworkVar_##varName equates to currentSendDTClass. It's
  456. // there as a check to make sure all networked variables use the CNetworkXXXX macros in network_var.h.
  457. #define SENDINFO(varName) #varName, offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName) | NETWORKVAR_OFFSET_FLAGS( currentSendDTClass, varName ), sizeof(((currentSendDTClass*)0)->varName)
  458. #define SENDINFO_ARRAY(varName) #varName, offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName), sizeof(((currentSendDTClass*)0)->varName[0])
  459. #define SENDINFO_ARRAY3(varName) #varName, offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName), sizeof(((currentSendDTClass*)0)->varName[0]), sizeof(((currentSendDTClass*)0)->varName)/sizeof(((currentSendDTClass*)0)->varName[0])
  460. #define SENDINFO_ARRAYELEM(varName, i) #varName "[" #i "]", offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName[i]), sizeof(((currentSendDTClass*)0)->varName[0])
  461. #define SENDINFO_NETWORKARRAYELEM(varName, i)#varName "[" #i "]", offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName.m_Value[i]), sizeof(((currentSendDTClass*)0)->varName.m_Value[0])
  462. // NOTE: Be VERY careful to specify any other vector elems for the same vector IN ORDER and
  463. // right after each other, otherwise it might miss the Y or Z component in SP.
  464. //
  465. // Note: this macro specifies a negative offset so the engine can detect it and setup m_pNext
  466. #define SENDINFO_VECTORELEM(varName, i) #varName "[" #i "]", (int)offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName.m_Value[i]) | NETWORKVAR_OFFSET_FLAGS( currentSendDTClass, varName ), sizeof(((currentSendDTClass*)0)->varName.m_Value[0])
  467. #define SENDINFO_STRUCTELEM(className, structVarName, varName) #structVarName "." #varName, offsetof(currentSendDTClass, structVarName.varName) | NETWORKVAR_OFFSET_FLAGS( className, varName ), sizeof(((currentSendDTClass*)0)->structVarName.varName.m_Value)
  468. #define SENDINFO_STRUCTARRAYELEM(varName, i)#varName "[" #i "]", offsetof(currentSendDTClass, varName.m_Value[i]), sizeof(((currentSendDTClass*)0)->varName.m_Value[0])
  469. // Use this when you're not using a CNetworkVar to represent the data you're sending.
  470. #define SENDINFO_NOCHECK(varName) #varName, offsetof(currentSendDTClass, varName), sizeof(((currentSendDTClass*)0)->varName)
  471. #define SENDINFO_STRING_NOCHECK(varName) #varName, offsetof(currentSendDTClass, varName)
  472. #define SENDINFO_DT(varName) #varName, offsetof(currentSendDTClass, varName)
  473. #define SENDINFO_DT_NAME(varName, remoteVarName) #remoteVarName, offsetof(currentSendDTClass, varName)
  474. #define SENDINFO_NAME(varName,remoteVarName) #remoteVarName, offsetof(currentSendDTClass, varName), sizeof(((currentSendDTClass*)0)->varName)
  475. // ------------------------------------------------------------------------ //
  476. // Built-in proxy types.
  477. // See the definition of SendVarProxyFn for information about these.
  478. // ------------------------------------------------------------------------ //
  479. void SendProxy_QAngles ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  480. void SendProxy_AngleToFloat ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  481. void SendProxy_FloatToFloat ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  482. void SendProxy_VectorToVector ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  483. void SendProxy_VectorXYToVectorXY( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  484. #if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!!
  485. void SendProxy_QuaternionToQuaternion( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  486. #endif
  487. void SendProxy_Int8ToInt32 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  488. void SendProxy_Int16ToInt32 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  489. void SendProxy_Int32ToInt32 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  490. void SendProxy_Int64ToInt64 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  491. void SendProxy_Color32ToInt32 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  492. void SendProxy_StringToString ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  493. // pData is the address of a data table.
  494. void* SendProxy_DataTableToDataTable( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID );
  495. // pData is the address of a pointer to a data table.
  496. void* SendProxy_DataTablePtrToDataTable( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID );
  497. // ------------------------------------------------------------------------ //
  498. // Use these functions to setup your data tables.
  499. // ------------------------------------------------------------------------ //
  500. SendProp SendPropFloat(
  501. char *pVarName, // Variable name.
  502. int offset, // Offset into container structure.
  503. int sizeofVar=SIZEOF_IGNORE,
  504. int nBits=32, // Number of bits to use when encoding.
  505. int flags=0,
  506. float fLowValue=0.0f, // For floating point, low and high values.
  507. float fHighValue=HIGH_DEFAULT, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  508. SendVarProxyFn varProxy=SendProxy_FloatToFloat,
  509. byte priority = SENDPROP_DEFAULT_PRIORITY
  510. );
  511. SendProp SendPropVector(
  512. char *pVarName,
  513. int offset,
  514. int sizeofVar=SIZEOF_IGNORE,
  515. int nBits=32, // Number of bits (for each floating-point component) to use when encoding.
  516. int flags=SPROP_NOSCALE,
  517. float fLowValue=0.0f, // For floating point, low and high values.
  518. float fHighValue=HIGH_DEFAULT, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  519. SendVarProxyFn varProxy=SendProxy_VectorToVector,
  520. byte priority = SENDPROP_DEFAULT_PRIORITY
  521. );
  522. SendProp SendPropVectorXY(
  523. char *pVarName,
  524. int offset,
  525. int sizeofVar=SIZEOF_IGNORE,
  526. int nBits=32, // Number of bits (for each floating-point component) to use when encoding.
  527. int flags=SPROP_NOSCALE,
  528. float fLowValue=0.0f, // For floating point, low and high values.
  529. float fHighValue=HIGH_DEFAULT, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  530. SendVarProxyFn varProxy=SendProxy_VectorXYToVectorXY,
  531. byte priority = SENDPROP_DEFAULT_PRIORITY
  532. );
  533. #if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!!
  534. SendProp SendPropQuaternion(
  535. char *pVarName,
  536. int offset,
  537. int sizeofVar=SIZEOF_IGNORE,
  538. int nBits=32, // Number of bits (for each floating-point component) to use when encoding.
  539. int flags=SPROP_NOSCALE,
  540. float fLowValue=0.0f, // For floating point, low and high values.
  541. float fHighValue=HIGH_DEFAULT, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  542. SendVarProxyFn varProxy=SendProxy_QuaternionToQuaternion,
  543. byte priority = SENDPROP_DEFAULT_PRIORITY
  544. );
  545. #endif
  546. SendProp SendPropAngle(
  547. char *pVarName,
  548. int offset,
  549. int sizeofVar=SIZEOF_IGNORE,
  550. int nBits=32,
  551. int flags=0,
  552. SendVarProxyFn varProxy=SendProxy_AngleToFloat,
  553. byte priority = SENDPROP_DEFAULT_PRIORITY
  554. );
  555. SendProp SendPropQAngles(
  556. char *pVarName,
  557. int offset,
  558. int sizeofVar=SIZEOF_IGNORE,
  559. int nBits=32,
  560. int flags=0,
  561. SendVarProxyFn varProxy=SendProxy_QAngles,
  562. byte priority = SENDPROP_DEFAULT_PRIORITY
  563. );
  564. SendProp SendPropInt(
  565. char *pVarName,
  566. int offset,
  567. int sizeofVar=SIZEOF_IGNORE, // Handled by SENDINFO macro.
  568. int nBits=-1, // Set to -1 to automatically pick (max) number of bits based on size of element.
  569. int flags=0,
  570. SendVarProxyFn varProxy=0,
  571. byte priority = SENDPROP_DEFAULT_PRIORITY
  572. );
  573. inline SendProp SendPropModelIndex( const char *pVarName, int offset, int sizeofVar=SIZEOF_IGNORE )
  574. {
  575. return SendPropInt( (char *)pVarName, offset, sizeofVar, SP_MODEL_INDEX_BITS, 0 );
  576. }
  577. SendProp SendPropString(
  578. char *pVarName,
  579. int offset,
  580. int bufferLen,
  581. int flags=0,
  582. SendVarProxyFn varProxy=SendProxy_StringToString,
  583. byte priority = SENDPROP_DEFAULT_PRIORITY
  584. );
  585. // The data table encoder looks at DVariant::m_pData.
  586. SendProp SendPropDataTable(
  587. char *pVarName,
  588. int offset,
  589. SendTable *pTable,
  590. SendTableProxyFn varProxy=SendProxy_DataTableToDataTable,
  591. byte priority = SENDPROP_DEFAULT_PRIORITY
  592. );
  593. SendProp SendPropArray3(
  594. char *pVarName,
  595. int offset,
  596. int sizeofVar,
  597. int elements,
  598. SendProp pArrayProp,
  599. SendTableProxyFn varProxy=SendProxy_DataTableToDataTable,
  600. byte priority = SENDPROP_DEFAULT_PRIORITY
  601. );
  602. //
  603. // Only use this if you change the array infrequently and you usually change all the elements
  604. // when you do change it.
  605. //
  606. // The array data is all sent together, so even if you only change one element,
  607. // it'll send all the elements.
  608. //
  609. // The upside is that it doesn't need extra bits to encode indices of all the variables.
  610. //
  611. #define SendPropArray_AllAtOnce( arrayName, propDefinition ) \
  612. SendPropArray( propDefinition, arrayName )
  613. //
  614. // This is what you should use for most arrays. It will generate a separate SendProp for each array element
  615. // in your array. That way, if you change one element of the array, it will only transmit that array element
  616. // and not the whole array.
  617. //
  618. // Example:
  619. //
  620. // GenerateSendPropsForArrayElements( m_Array, SendPropInt( SENDINFO_ARRAY( m_Array ) )
  621. //
  622. #define SendPropArray_UniqueElements( arrayName, propDefinition ) \
  623. SendPropArray3( SENDINFO_ARRAY3( arrayName ), propDefinition )
  624. // Use the macro to let it automatically generate a table name. You shouldn't
  625. // ever need to reference the table name. If you want to exclude this array, then
  626. // reference the name of the variable in varTemplate.
  627. SendProp InternalSendPropArray(
  628. const int elementCount,
  629. const int elementStride,
  630. char *pName,
  631. ArrayLengthSendProxyFn proxy,
  632. byte priority = SENDPROP_DEFAULT_PRIORITY
  633. );
  634. // Use this and pass the array name and it will figure out the count and stride automatically.
  635. #define SendPropArray( varTemplate, arrayName ) \
  636. SendPropVariableLengthArray( \
  637. 0, \
  638. varTemplate, \
  639. arrayName )
  640. //
  641. // Use this when you want to send a variable-length array of data but there is no physical array you can point it at.
  642. // You need to provide:
  643. // 1. A proxy function that returns the current length of the array.
  644. // 2. The maximum length the array will ever be.
  645. // 2. A SendProp describing what the elements are comprised of.
  646. // 3. In the SendProp, you'll want to specify a proxy function so you can go grab the data from wherever it is.
  647. // 4. A property name that matches the definition on the client.
  648. //
  649. #define SendPropVirtualArray( arrayLengthSendProxy, maxArrayLength, varTemplate, propertyName ) \
  650. varTemplate, \
  651. InternalSendPropArray( \
  652. maxArrayLength, \
  653. 0, \
  654. #propertyName, \
  655. arrayLengthSendProxy \
  656. )
  657. #define SendPropVariableLengthArray( arrayLengthSendProxy, varTemplate, arrayName ) \
  658. varTemplate, \
  659. InternalSendPropArray( \
  660. sizeof(((currentSendDTClass*)0)->arrayName) / PROPSIZEOF(currentSendDTClass, arrayName[0]), \
  661. PROPSIZEOF(currentSendDTClass, arrayName[0]), \
  662. #arrayName, \
  663. arrayLengthSendProxy \
  664. )
  665. // Use this one to specify the element count and stride manually.
  666. #define SendPropArray2( arrayLengthSendProxy, varTemplate, elementCount, elementStride, arrayName ) \
  667. varTemplate, \
  668. InternalSendPropArray( elementCount, elementStride, #arrayName, arrayLengthSendProxy )
  669. // Use these to create properties that exclude other properties. This is useful if you want to use most of
  670. // a base class's datatable data, but you want to override some of its variables.
  671. SendProp SendPropExclude(
  672. char *pDataTableName, // Data table name (given to BEGIN_SEND_TABLE and BEGIN_RECV_TABLE).
  673. char *pPropName // Name of the property to exclude.
  674. );
  675. #endif // DATATABLE_SEND_H