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.

808 lines
26 KiB

  1. //========= Copyright 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. 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_UInt8ToInt32;
  64. SendVarProxyFn m_UInt16ToInt32;
  65. SendVarProxyFn m_UInt32ToInt32;
  66. SendVarProxyFn m_FloatToFloat;
  67. SendVarProxyFn m_VectorToVector;
  68. #ifdef SUPPORTS_INT64
  69. SendVarProxyFn m_Int64ToInt64;
  70. SendVarProxyFn m_UInt64ToInt64;
  71. #endif
  72. };
  73. class CStandardSendProxies : public CStandardSendProxiesV1
  74. {
  75. public:
  76. CStandardSendProxies();
  77. SendTableProxyFn m_DataTableToDataTable;
  78. SendTableProxyFn m_SendLocalDataTable;
  79. CNonModifiedPointerProxy **m_ppNonModifiedPointerProxies;
  80. };
  81. extern CStandardSendProxies g_StandardSendProxies;
  82. // Max # of datatable send proxies you can have in a tree.
  83. #define MAX_DATATABLE_PROXIES 32
  84. // ------------------------------------------------------------------------ //
  85. // Datatable send proxies are used to tell the engine where the datatable's
  86. // data is and to specify which clients should get the data.
  87. //
  88. // pRecipients is the object that allows you to specify which clients will
  89. // receive the data.
  90. // ------------------------------------------------------------------------ //
  91. class CSendProxyRecipients
  92. {
  93. public:
  94. void SetAllRecipients(); // Note: recipients are all set by default when each proxy is called.
  95. void ClearAllRecipients();
  96. void SetRecipient( int iClient ); // Note: these are CLIENT indices, not entity indices (so the first player's index is 0).
  97. void ClearRecipient( int iClient );
  98. // Clear all recipients and set only the specified one.
  99. void SetOnly( int iClient );
  100. public:
  101. // Make sure we have enough room for the max possible player count
  102. CBitVec< ABSOLUTE_PLAYER_LIMIT > m_Bits;
  103. };
  104. inline void CSendProxyRecipients::SetAllRecipients()
  105. {
  106. m_Bits.SetAll();
  107. }
  108. inline void CSendProxyRecipients::ClearAllRecipients()
  109. {
  110. m_Bits.ClearAll();
  111. }
  112. inline void CSendProxyRecipients::SetRecipient( int iClient )
  113. {
  114. m_Bits.Set( iClient );
  115. }
  116. inline void CSendProxyRecipients::ClearRecipient( int iClient )
  117. {
  118. m_Bits.Clear( iClient );
  119. }
  120. inline void CSendProxyRecipients::SetOnly( int iClient )
  121. {
  122. m_Bits.ClearAll();
  123. m_Bits.Set( iClient );
  124. }
  125. // ------------------------------------------------------------------------ //
  126. // ArrayLengthSendProxies are used when you want to specify an array's length
  127. // dynamically.
  128. // ------------------------------------------------------------------------ //
  129. typedef int (*ArrayLengthSendProxyFn)( const void *pStruct, int objectID );
  130. class RecvProp;
  131. class SendTable;
  132. class CSendTablePrecalc;
  133. // -------------------------------------------------------------------------------------------------------------- //
  134. // SendProp.
  135. // -------------------------------------------------------------------------------------------------------------- //
  136. // If SendProp::GetDataTableProxyIndex() returns this, then the proxy is one that always sends
  137. // the data to all clients, so we don't need to store the results.
  138. #define DATATABLE_PROXY_INDEX_NOPROXY 255
  139. #define DATATABLE_PROXY_INDEX_INVALID 254
  140. class SendProp
  141. {
  142. public:
  143. SendProp();
  144. virtual ~SendProp();
  145. void Clear();
  146. int GetOffset() const;
  147. void SetOffset( int i );
  148. SendVarProxyFn GetProxyFn() const;
  149. void SetProxyFn( SendVarProxyFn f );
  150. SendTableProxyFn GetDataTableProxyFn() const;
  151. void SetDataTableProxyFn( SendTableProxyFn f );
  152. SendTable* GetDataTable() const;
  153. void SetDataTable( SendTable *pTable );
  154. char const* GetExcludeDTName() const;
  155. // If it's one of the numbered "000", "001", etc properties in an array, then
  156. // these can be used to get its array property name for debugging.
  157. const char* GetParentArrayPropName() const;
  158. void SetParentArrayPropName( char *pArrayPropName );
  159. const char* GetName() const;
  160. bool IsSigned() const;
  161. bool IsExcludeProp() const;
  162. bool IsInsideArray() const; // Returns true if SPROP_INSIDEARRAY is set.
  163. void SetInsideArray();
  164. // Arrays only.
  165. void SetArrayProp( SendProp *pProp );
  166. SendProp* GetArrayProp() const;
  167. // Arrays only.
  168. void SetArrayLengthProxy( ArrayLengthSendProxyFn fn );
  169. ArrayLengthSendProxyFn GetArrayLengthProxy() const;
  170. int GetNumElements() const;
  171. void SetNumElements( int nElements );
  172. // Return the # of bits to encode an array length (must hold GetNumElements()).
  173. int GetNumArrayLengthBits() const;
  174. int GetElementStride() const;
  175. SendPropType GetType() const;
  176. int GetFlags() const;
  177. void SetFlags( int flags );
  178. // Some property types bind more data to the SendProp in here.
  179. const void* GetExtraData() const;
  180. void SetExtraData( const void *pData );
  181. public:
  182. RecvProp *m_pMatchingRecvProp; // This is temporary and only used while precalculating
  183. // data for the decoders.
  184. SendPropType m_Type;
  185. int m_nBits;
  186. float m_fLowValue;
  187. float m_fHighValue;
  188. SendProp *m_pArrayProp; // If this is an array, this is the property that defines each array element.
  189. ArrayLengthSendProxyFn m_ArrayLengthProxy; // This callback returns the array length.
  190. int m_nElements; // Number of elements in the array (or 1 if it's not an array).
  191. int m_ElementStride; // Pointer distance between array elements.
  192. const char *m_pExcludeDTName; // If this is an exclude prop, then this is the name of the datatable to exclude a prop from.
  193. const char *m_pParentArrayPropName;
  194. const char *m_pVarName;
  195. float m_fHighLowMul;
  196. private:
  197. int m_Flags; // SPROP_ flags.
  198. SendVarProxyFn m_ProxyFn; // NULL for DPT_DataTable.
  199. SendTableProxyFn m_DataTableProxyFn; // Valid for DPT_DataTable.
  200. SendTable *m_pDataTable;
  201. // SENDPROP_VECTORELEM makes this negative to start with so we can detect that and
  202. // set the SPROP_IS_VECTOR_ELEM flag.
  203. int m_Offset;
  204. // Extra data bound to this property.
  205. const void *m_pExtraData;
  206. };
  207. inline int SendProp::GetOffset() const
  208. {
  209. return m_Offset;
  210. }
  211. inline void SendProp::SetOffset( int i )
  212. {
  213. m_Offset = i;
  214. }
  215. inline SendVarProxyFn SendProp::GetProxyFn() const
  216. {
  217. Assert( m_Type != DPT_DataTable );
  218. return m_ProxyFn;
  219. }
  220. inline void SendProp::SetProxyFn( SendVarProxyFn f )
  221. {
  222. m_ProxyFn = f;
  223. }
  224. inline SendTableProxyFn SendProp::GetDataTableProxyFn() const
  225. {
  226. Assert( m_Type == DPT_DataTable );
  227. return m_DataTableProxyFn;
  228. }
  229. inline void SendProp::SetDataTableProxyFn( SendTableProxyFn f )
  230. {
  231. m_DataTableProxyFn = f;
  232. }
  233. inline SendTable* SendProp::GetDataTable() const
  234. {
  235. return m_pDataTable;
  236. }
  237. inline void SendProp::SetDataTable( SendTable *pTable )
  238. {
  239. m_pDataTable = pTable;
  240. }
  241. inline char const* SendProp::GetExcludeDTName() const
  242. {
  243. return m_pExcludeDTName;
  244. }
  245. inline const char* SendProp::GetParentArrayPropName() const
  246. {
  247. return m_pParentArrayPropName;
  248. }
  249. inline void SendProp::SetParentArrayPropName( char *pArrayPropName )
  250. {
  251. Assert( !m_pParentArrayPropName );
  252. m_pParentArrayPropName = pArrayPropName;
  253. }
  254. inline const char* SendProp::GetName() const
  255. {
  256. return m_pVarName;
  257. }
  258. inline bool SendProp::IsSigned() const
  259. {
  260. return !(m_Flags & SPROP_UNSIGNED);
  261. }
  262. inline bool SendProp::IsExcludeProp() const
  263. {
  264. return (m_Flags & SPROP_EXCLUDE) != 0;
  265. }
  266. inline bool SendProp::IsInsideArray() const
  267. {
  268. return (m_Flags & SPROP_INSIDEARRAY) != 0;
  269. }
  270. inline void SendProp::SetInsideArray()
  271. {
  272. m_Flags |= SPROP_INSIDEARRAY;
  273. }
  274. inline void SendProp::SetArrayProp( SendProp *pProp )
  275. {
  276. m_pArrayProp = pProp;
  277. }
  278. inline SendProp* SendProp::GetArrayProp() const
  279. {
  280. return m_pArrayProp;
  281. }
  282. inline void SendProp::SetArrayLengthProxy( ArrayLengthSendProxyFn fn )
  283. {
  284. m_ArrayLengthProxy = fn;
  285. }
  286. inline ArrayLengthSendProxyFn SendProp::GetArrayLengthProxy() const
  287. {
  288. return m_ArrayLengthProxy;
  289. }
  290. inline int SendProp::GetNumElements() const
  291. {
  292. return m_nElements;
  293. }
  294. inline void SendProp::SetNumElements( int nElements )
  295. {
  296. m_nElements = nElements;
  297. }
  298. inline int SendProp::GetElementStride() const
  299. {
  300. return m_ElementStride;
  301. }
  302. inline SendPropType SendProp::GetType() const
  303. {
  304. return m_Type;
  305. }
  306. inline int SendProp::GetFlags() const
  307. {
  308. return m_Flags;
  309. }
  310. inline void SendProp::SetFlags( int flags )
  311. {
  312. // Make sure they're using something from the valid set of flags.
  313. Assert( !( flags & ~((1 << SPROP_NUMFLAGBITS) - 1) ) );
  314. m_Flags = flags;
  315. }
  316. inline const void* SendProp::GetExtraData() const
  317. {
  318. return m_pExtraData;
  319. }
  320. inline void SendProp::SetExtraData( const void *pData )
  321. {
  322. m_pExtraData = pData;
  323. }
  324. // -------------------------------------------------------------------------------------------------------------- //
  325. // SendTable.
  326. // -------------------------------------------------------------------------------------------------------------- //
  327. class SendTable
  328. {
  329. public:
  330. typedef SendProp PropType;
  331. SendTable();
  332. SendTable( SendProp *pProps, int nProps, const char *pNetTableName );
  333. ~SendTable();
  334. void Construct( SendProp *pProps, int nProps, const char *pNetTableName );
  335. const char* GetName() const;
  336. int GetNumProps() const;
  337. SendProp* GetProp( int i );
  338. // Used by the engine.
  339. bool IsInitialized() const;
  340. void SetInitialized( bool bInitialized );
  341. // Used by the engine while writing info into the signon.
  342. void SetWriteFlag(bool bHasBeenWritten);
  343. bool GetWriteFlag() const;
  344. bool HasPropsEncodedAgainstTickCount() const;
  345. void SetHasPropsEncodedAgainstTickcount( bool bState );
  346. public:
  347. SendProp *m_pProps;
  348. int m_nProps;
  349. const char *m_pNetTableName; // The name matched between client and server.
  350. // The engine hooks the SendTable here.
  351. CSendTablePrecalc *m_pPrecalc;
  352. protected:
  353. bool m_bInitialized : 1;
  354. bool m_bHasBeenWritten : 1;
  355. bool m_bHasPropsEncodedAgainstCurrentTickCount : 1; // m_flSimulationTime and m_flAnimTime, e.g.
  356. };
  357. inline const char* SendTable::GetName() const
  358. {
  359. return m_pNetTableName;
  360. }
  361. inline int SendTable::GetNumProps() const
  362. {
  363. return m_nProps;
  364. }
  365. inline SendProp* SendTable::GetProp( int i )
  366. {
  367. Assert( i >= 0 && i < m_nProps );
  368. return &m_pProps[i];
  369. }
  370. inline bool SendTable::IsInitialized() const
  371. {
  372. return m_bInitialized;
  373. }
  374. inline void SendTable::SetInitialized( bool bInitialized )
  375. {
  376. m_bInitialized = bInitialized;
  377. }
  378. inline bool SendTable::GetWriteFlag() const
  379. {
  380. return m_bHasBeenWritten;
  381. }
  382. inline void SendTable::SetWriteFlag(bool bHasBeenWritten)
  383. {
  384. m_bHasBeenWritten = bHasBeenWritten;
  385. }
  386. inline bool SendTable::HasPropsEncodedAgainstTickCount() const
  387. {
  388. return m_bHasPropsEncodedAgainstCurrentTickCount;
  389. }
  390. inline void SendTable::SetHasPropsEncodedAgainstTickcount( bool bState )
  391. {
  392. m_bHasPropsEncodedAgainstCurrentTickCount = bState;
  393. }
  394. // ------------------------------------------------------------------------------------------------------ //
  395. // Use BEGIN_SEND_TABLE if you want to declare a SendTable and have it inherit all the properties from
  396. // its base class. There are two requirements for this to work:
  397. // 1. Its base class must have a static SendTable pointer member variable called m_pClassSendTable which
  398. // points to its send table. The DECLARE_SERVERCLASS and IMPLEMENT_SERVERCLASS macros do this automatically.
  399. // 2. Your class must typedef its base class as BaseClass. So it would look like this:
  400. // class Derived : public CBaseEntity
  401. // {
  402. // typedef CBaseEntity BaseClass;
  403. // };
  404. // If you don't want to interit a base class's properties, use BEGIN_SEND_TABLE_NOBASE.
  405. // ------------------------------------------------------------------------------------------------------ //
  406. #define BEGIN_SEND_TABLE(className, tableName) \
  407. BEGIN_SEND_TABLE_NOBASE(className, tableName) \
  408. SendPropDataTable("baseclass", 0, className::BaseClass::m_pClassSendTable, SendProxy_DataTableToDataTable),
  409. #define BEGIN_SEND_TABLE_NOBASE(className, tableName) \
  410. template <typename T> int ServerClassInit(T *); \
  411. namespace tableName { \
  412. struct ignored; \
  413. } \
  414. template <> int ServerClassInit<tableName::ignored>(tableName::ignored *); \
  415. namespace tableName { \
  416. SendTable g_SendTable;\
  417. int g_SendTableInit = ServerClassInit((tableName::ignored *)NULL); \
  418. } \
  419. template <> int ServerClassInit<tableName::ignored>(tableName::ignored *) \
  420. { \
  421. typedef className currentSendDTClass; \
  422. static const char *g_pSendTableName = #tableName; \
  423. SendTable &sendTable = tableName::g_SendTable; \
  424. static SendProp g_SendProps[] = { \
  425. SendPropInt("should_never_see_this", 0, sizeof(int)), // It adds a dummy property at the start so you can define "empty" SendTables.
  426. #define END_SEND_TABLE() \
  427. };\
  428. sendTable.Construct(g_SendProps+1, sizeof(g_SendProps) / sizeof(SendProp) - 1, g_pSendTableName);\
  429. return 1; \
  430. }
  431. // Normal offset of is invalid on non-array-types, this is dubious as hell. The rest of the codebase converted to the
  432. // legit offsetof from the C headers, so we'll use the old impl here to avoid exposing temptation to others
  433. #define _hacky_dtsend_offsetof(s,m) ((size_t)&(((s *)0)->m))
  434. // These can simplify creating the variables.
  435. // Note: currentSendDTClass::MakeANetworkVar_##varName equates to currentSendDTClass. It's
  436. // there as a check to make sure all networked variables use the CNetworkXXXX macros in network_var.h.
  437. #define SENDINFO(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName), sizeof(((currentSendDTClass*)0)->varName)
  438. #define SENDINFO_ARRAY(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName), sizeof(((currentSendDTClass*)0)->varName[0])
  439. #define SENDINFO_ARRAY3(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName), sizeof(((currentSendDTClass*)0)->varName[0]), sizeof(((currentSendDTClass*)0)->varName)/sizeof(((currentSendDTClass*)0)->varName[0])
  440. #define SENDINFO_ARRAYELEM(varName, i) #varName "[" #i "]", _hacky_dtsend_offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName[i]), sizeof(((currentSendDTClass*)0)->varName[0])
  441. #define SENDINFO_NETWORKARRAYELEM(varName, i)#varName "[" #i "]", _hacky_dtsend_offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName.m_Value[i]), sizeof(((currentSendDTClass*)0)->varName.m_Value[0])
  442. // NOTE: Be VERY careful to specify any other vector elems for the same vector IN ORDER and
  443. // right after each other, otherwise it might miss the Y or Z component in SP.
  444. //
  445. // Note: this macro specifies a negative offset so the engine can detect it and setup m_pNext
  446. #define SENDINFO_VECTORELEM(varName, i) #varName "[" #i "]", -(int)_hacky_dtsend_offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName.m_Value[i]), sizeof(((currentSendDTClass*)0)->varName.m_Value[0])
  447. #define SENDINFO_STRUCTELEM(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName), sizeof(((currentSendDTClass*)0)->varName.m_Value)
  448. #define SENDINFO_STRUCTARRAYELEM(varName, i)#varName "[" #i "]", _hacky_dtsend_offsetof(currentSendDTClass, varName.m_Value[i]), sizeof(((currentSendDTClass*)0)->varName.m_Value[0])
  449. // Use this when you're not using a CNetworkVar to represent the data you're sending.
  450. #define SENDINFO_NOCHECK(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName), sizeof(((currentSendDTClass*)0)->varName)
  451. #define SENDINFO_STRING_NOCHECK(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName)
  452. #define SENDINFO_DT(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName)
  453. #define SENDINFO_DT_NAME(varName, remoteVarName) #remoteVarName, _hacky_dtsend_offsetof(currentSendDTClass, varName)
  454. #define SENDINFO_NAME(varName,remoteVarName) #remoteVarName, _hacky_dtsend_offsetof(currentSendDTClass, varName), sizeof(((currentSendDTClass*)0)->varName)
  455. // ------------------------------------------------------------------------ //
  456. // Built-in proxy types.
  457. // See the definition of SendVarProxyFn for information about these.
  458. // ------------------------------------------------------------------------ //
  459. void SendProxy_QAngles ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  460. void SendProxy_AngleToFloat ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  461. void SendProxy_FloatToFloat ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  462. void SendProxy_VectorToVector ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  463. void SendProxy_VectorXYToVectorXY( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  464. #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!!!
  465. void SendProxy_QuaternionToQuaternion( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  466. #endif
  467. void SendProxy_Int8ToInt32 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  468. void SendProxy_Int16ToInt32 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  469. void SendProxy_Int32ToInt32 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  470. #ifdef SUPPORTS_INT64
  471. void SendProxy_Int64ToInt64 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  472. #endif
  473. void SendProxy_StringToString ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
  474. // pData is the address of a data table.
  475. void* SendProxy_DataTableToDataTable( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID );
  476. // pData is the address of a pointer to a data table.
  477. void* SendProxy_DataTablePtrToDataTable( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID );
  478. // Used on player entities - only sends the data to the local player (objectID-1).
  479. void* SendProxy_SendLocalDataTable( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID );
  480. // ------------------------------------------------------------------------ //
  481. // Use these functions to setup your data tables.
  482. // ------------------------------------------------------------------------ //
  483. SendProp SendPropFloat(
  484. const char *pVarName, // Variable name.
  485. int offset, // Offset into container structure.
  486. int sizeofVar=SIZEOF_IGNORE,
  487. int nBits=32, // Number of bits to use when encoding.
  488. int flags=0,
  489. float fLowValue=0.0f, // For floating point, low and high values.
  490. float fHighValue=HIGH_DEFAULT, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  491. SendVarProxyFn varProxy=SendProxy_FloatToFloat
  492. );
  493. SendProp SendPropVector(
  494. const char *pVarName,
  495. int offset,
  496. int sizeofVar=SIZEOF_IGNORE,
  497. int nBits=32, // Number of bits (for each floating-point component) to use when encoding.
  498. int flags=SPROP_NOSCALE,
  499. float fLowValue=0.0f, // For floating point, low and high values.
  500. float fHighValue=HIGH_DEFAULT, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  501. SendVarProxyFn varProxy=SendProxy_VectorToVector
  502. );
  503. SendProp SendPropVectorXY(
  504. const char *pVarName,
  505. int offset,
  506. int sizeofVar=SIZEOF_IGNORE,
  507. int nBits=32, // Number of bits (for each floating-point component) to use when encoding.
  508. int flags=SPROP_NOSCALE,
  509. float fLowValue=0.0f, // For floating point, low and high values.
  510. float fHighValue=HIGH_DEFAULT, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  511. SendVarProxyFn varProxy=SendProxy_VectorXYToVectorXY
  512. );
  513. #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!!!
  514. SendProp SendPropQuaternion(
  515. const char *pVarName,
  516. int offset,
  517. int sizeofVar=SIZEOF_IGNORE,
  518. int nBits=32, // Number of bits (for each floating-point component) to use when encoding.
  519. int flags=SPROP_NOSCALE,
  520. float fLowValue=0.0f, // For floating point, low and high values.
  521. float fHighValue=HIGH_DEFAULT, // High value. If HIGH_DEFAULT, it's (1<<nBits).
  522. SendVarProxyFn varProxy=SendProxy_QuaternionToQuaternion
  523. );
  524. #endif
  525. SendProp SendPropAngle(
  526. const char *pVarName,
  527. int offset,
  528. int sizeofVar=SIZEOF_IGNORE,
  529. int nBits=32,
  530. int flags=0,
  531. SendVarProxyFn varProxy=SendProxy_AngleToFloat
  532. );
  533. SendProp SendPropQAngles(
  534. const char *pVarName,
  535. int offset,
  536. int sizeofVar=SIZEOF_IGNORE,
  537. int nBits=32,
  538. int flags=0,
  539. SendVarProxyFn varProxy=SendProxy_QAngles
  540. );
  541. SendProp SendPropInt(
  542. const char *pVarName,
  543. int offset,
  544. int sizeofVar=SIZEOF_IGNORE, // Handled by SENDINFO macro.
  545. int nBits=-1, // Set to -1 to automatically pick (max) number of bits based on size of element.
  546. int flags=0,
  547. SendVarProxyFn varProxy=0
  548. );
  549. inline SendProp SendPropModelIndex( const char *pVarName, int offset, int sizeofVar=SIZEOF_IGNORE )
  550. {
  551. return SendPropInt( pVarName, offset, sizeofVar, SP_MODEL_INDEX_BITS, 0 );
  552. }
  553. SendProp SendPropString(
  554. const char *pVarName,
  555. int offset,
  556. int bufferLen,
  557. int flags=0,
  558. SendVarProxyFn varProxy=SendProxy_StringToString);
  559. // The data table encoder looks at DVariant::m_pData.
  560. SendProp SendPropDataTable(
  561. const char *pVarName,
  562. int offset,
  563. SendTable *pTable,
  564. SendTableProxyFn varProxy=SendProxy_DataTableToDataTable
  565. );
  566. SendProp SendPropArray3(
  567. const char *pVarName,
  568. int offset,
  569. int sizeofVar,
  570. int elements,
  571. SendProp pArrayProp,
  572. SendTableProxyFn varProxy=SendProxy_DataTableToDataTable
  573. );
  574. // Use the macro to let it automatically generate a table name. You shouldn't
  575. // ever need to reference the table name. If you want to exclude this array, then
  576. // reference the name of the variable in varTemplate.
  577. SendProp InternalSendPropArray(
  578. const int elementCount,
  579. const int elementStride,
  580. const char *pName,
  581. ArrayLengthSendProxyFn proxy
  582. );
  583. // Use this and pass the array name and it will figure out the count and stride automatically.
  584. #define SendPropArray( varTemplate, arrayName ) \
  585. SendPropVariableLengthArray( \
  586. 0, \
  587. varTemplate, \
  588. arrayName )
  589. //
  590. // Use this when you want to send a variable-length array of data but there is no physical array you can point it at.
  591. // You need to provide:
  592. // 1. A proxy function that returns the current length of the array.
  593. // 2. The maximum length the array will ever be.
  594. // 2. A SendProp describing what the elements are comprised of.
  595. // 3. In the SendProp, you'll want to specify a proxy function so you can go grab the data from wherever it is.
  596. // 4. A property name that matches the definition on the client.
  597. //
  598. #define SendPropVirtualArray( arrayLengthSendProxy, maxArrayLength, varTemplate, propertyName ) \
  599. varTemplate, \
  600. InternalSendPropArray( \
  601. maxArrayLength, \
  602. 0, \
  603. #propertyName, \
  604. arrayLengthSendProxy \
  605. )
  606. #define SendPropVariableLengthArray( arrayLengthSendProxy, varTemplate, arrayName ) \
  607. varTemplate, \
  608. InternalSendPropArray( \
  609. sizeof(((currentSendDTClass*)0)->arrayName) / PROPSIZEOF(currentSendDTClass, arrayName[0]), \
  610. PROPSIZEOF(currentSendDTClass, arrayName[0]), \
  611. #arrayName, \
  612. arrayLengthSendProxy \
  613. )
  614. // Use this one to specify the element count and stride manually.
  615. #define SendPropArray2( arrayLengthSendProxy, varTemplate, elementCount, elementStride, arrayName ) \
  616. varTemplate, \
  617. InternalSendPropArray( elementCount, elementStride, #arrayName, arrayLengthSendProxy )
  618. // Use these to create properties that exclude other properties. This is useful if you want to use most of
  619. // a base class's datatable data, but you want to override some of its variables.
  620. SendProp SendPropExclude(
  621. const char *pDataTableName, // Data table name (given to BEGIN_SEND_TABLE and BEGIN_RECV_TABLE).
  622. const char *pPropName // Name of the property to exclude.
  623. );
  624. #endif // DATATABLE_SEND_H