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.

442 lines
11 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef EDICT_H
  7. #define EDICT_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "mathlib/vector.h"
  12. #include "cmodel.h"
  13. #include "const.h"
  14. #include "iserverentity.h"
  15. #include "globalvars_base.h"
  16. #include "engine/ICollideable.h"
  17. #include "iservernetworkable.h"
  18. #include "bitvec.h"
  19. #include "tier1/convar.h"
  20. struct edict_t;
  21. //-----------------------------------------------------------------------------
  22. // Purpose: Defines the ways that a map can be loaded.
  23. //-----------------------------------------------------------------------------
  24. enum MapLoadType_t
  25. {
  26. MapLoad_NewGame = 0,
  27. MapLoad_LoadGame,
  28. MapLoad_Transition,
  29. MapLoad_Background,
  30. };
  31. //-----------------------------------------------------------------------------
  32. // Purpose: Global variables shared between the engine and the game .dll
  33. //-----------------------------------------------------------------------------
  34. class CGlobalVars : public CGlobalVarsBase
  35. {
  36. public:
  37. CGlobalVars( bool bIsClient );
  38. public:
  39. // Current map
  40. string_t mapname;
  41. string_t mapGroupName;
  42. int mapversion;
  43. string_t startspot;
  44. MapLoadType_t eLoadType; // How the current map was loaded
  45. bool bMapLoadFailed; // Map has failed to load, we need to kick back to the main menu
  46. // game specific flags
  47. bool deathmatch;
  48. bool coop;
  49. bool teamplay;
  50. // current maxentities
  51. int maxEntities;
  52. int serverCount;
  53. edict_t *pEdicts;
  54. };
  55. inline CGlobalVars::CGlobalVars( bool bIsClient ) :
  56. CGlobalVarsBase( bIsClient )
  57. {
  58. serverCount = 0;
  59. }
  60. class CPlayerState;
  61. class IServerNetworkable;
  62. class IServerEntity;
  63. #define FL_EDICT_CHANGED (1<<0) // Game DLL sets this when the entity state changes
  64. // Mutually exclusive with FL_EDICT_PARTIAL_CHANGE.
  65. #define FL_EDICT_FREE (1<<1) // this edict if free for reuse
  66. #define FL_EDICT_FULL (1<<2) // this is a full server entity
  67. #define FL_EDICT_FULLCHECK (0<<0) // call ShouldTransmit() each time, this is a fake flag
  68. #define FL_EDICT_ALWAYS (1<<3) // always transmit this entity
  69. #define FL_EDICT_DONTSEND (1<<4) // don't transmit this entity
  70. #define FL_EDICT_PVSCHECK (1<<5) // always transmit entity, but cull against PVS
  71. // Used by local network backdoor.
  72. #define FL_EDICT_PENDING_DORMANT_CHECK (1<<6)
  73. // This is always set at the same time EFL_DIRTY_PVS_INFORMATION is set, but it
  74. // gets cleared in a different place.
  75. #define FL_EDICT_DIRTY_PVS_INFORMATION (1<<7)
  76. // This is used internally to edict_t to remember that it's carrying a
  77. // "full change list" - all its properties might have changed their value.
  78. #define FL_FULL_EDICT_CHANGED (1<<8)
  79. // Max # of variable changes we'll track in an entity before we treat it
  80. // like they all changed.
  81. #define MAX_CHANGE_OFFSETS 19
  82. #define MAX_EDICT_CHANGE_INFOS 100
  83. class CEdictChangeInfo
  84. {
  85. public:
  86. // Edicts remember the offsets of properties that change
  87. unsigned short m_ChangeOffsets[MAX_CHANGE_OFFSETS];
  88. unsigned short m_nChangeOffsets;
  89. };
  90. // Shared between engine and game DLL.
  91. class CSharedEdictChangeInfo
  92. {
  93. public:
  94. CSharedEdictChangeInfo()
  95. {
  96. m_iSerialNumber = 1;
  97. }
  98. // Matched against edict_t::m_iChangeInfoSerialNumber to determine if its
  99. // change info is valid.
  100. unsigned short m_iSerialNumber;
  101. CEdictChangeInfo m_ChangeInfos[MAX_EDICT_CHANGE_INFOS];
  102. unsigned short m_nChangeInfos; // How many are in use this frame.
  103. };
  104. extern CSharedEdictChangeInfo *g_pSharedChangeInfo;
  105. class IChangeInfoAccessor
  106. {
  107. public:
  108. inline void SetChangeInfo( unsigned short info )
  109. {
  110. m_iChangeInfo = info;
  111. }
  112. inline void SetChangeInfoSerialNumber( unsigned short sn )
  113. {
  114. m_iChangeInfoSerialNumber = sn;
  115. }
  116. inline unsigned short GetChangeInfo() const
  117. {
  118. return m_iChangeInfo;
  119. }
  120. inline unsigned short GetChangeInfoSerialNumber() const
  121. {
  122. return m_iChangeInfoSerialNumber;
  123. }
  124. private:
  125. unsigned short m_iChangeInfo;
  126. unsigned short m_iChangeInfoSerialNumber;
  127. };
  128. //-----------------------------------------------------------------------------
  129. // Purpose:
  130. //-----------------------------------------------------------------------------
  131. // NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!!
  132. class CBaseEdict
  133. {
  134. public:
  135. // Returns an IServerEntity if FL_FULLEDICT is set or NULL if this
  136. // is a lightweight networking entity.
  137. IServerEntity* GetIServerEntity();
  138. const IServerEntity* GetIServerEntity() const;
  139. IServerNetworkable* GetNetworkable();
  140. IServerUnknown* GetUnknown();
  141. // Set when initting an entity. If it's only a networkable, this is false.
  142. void SetEdict( IServerUnknown *pUnk, bool bFullEdict );
  143. int AreaNum() const;
  144. const char * GetClassName() const;
  145. bool IsFree() const;
  146. void SetFree();
  147. void ClearFree();
  148. bool HasStateChanged() const;
  149. void ClearStateChanged();
  150. void StateChanged();
  151. void StateChanged( unsigned short offset );
  152. void ClearTransmitState();
  153. private:
  154. void SetChangeInfo( unsigned short info );
  155. void SetChangeInfoSerialNumber( unsigned short sn );
  156. public:
  157. unsigned short GetChangeInfo() const;
  158. unsigned short GetChangeInfoSerialNumber() const;
  159. public:
  160. // NOTE: this is in the edict instead of being accessed by a virtual because the engine needs fast access to it.
  161. // NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!!
  162. int m_fStateFlags;
  163. // NOTE: this is in the edict instead of being accessed by a virtual because the engine needs fast access to it.
  164. int m_NetworkSerialNumber; // Game DLL sets this when it gets a serial number for its EHANDLE.
  165. // NOTE: this is in the edict instead of being accessed by a virtual because the engine needs fast access to it.
  166. IServerNetworkable *m_pNetworkable;
  167. protected:
  168. IServerUnknown *m_pUnk;
  169. public:
  170. IChangeInfoAccessor *GetChangeAccessor(); // The engine implements this and the game .dll implements as
  171. const IChangeInfoAccessor *GetChangeAccessor() const; // The engine implements this and the game .dll implements as
  172. // as callback through to the engine!!!
  173. // NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!!
  174. // This breaks HL2_VC6!!!!!
  175. // References a CEdictChangeInfo with a list of modified network props.
  176. //unsigned short m_iChangeInfo;
  177. //unsigned short m_iChangeInfoSerialNumber;
  178. friend void InitializeEntityDLLFields( edict_t *pEdict );
  179. };
  180. //-----------------------------------------------------------------------------
  181. // CBaseEdict inlines.
  182. //-----------------------------------------------------------------------------
  183. inline IServerEntity* CBaseEdict::GetIServerEntity()
  184. {
  185. if ( m_fStateFlags & FL_EDICT_FULL )
  186. return (IServerEntity*)m_pUnk;
  187. else
  188. return 0;
  189. }
  190. inline bool CBaseEdict::IsFree() const
  191. {
  192. return (m_fStateFlags & FL_EDICT_FREE) != 0;
  193. }
  194. inline bool CBaseEdict::HasStateChanged() const
  195. {
  196. return (m_fStateFlags & ( FL_EDICT_CHANGED | FL_FULL_EDICT_CHANGED ) ) != 0;
  197. }
  198. inline void CBaseEdict::ClearStateChanged()
  199. {
  200. m_fStateFlags &= ~(FL_EDICT_CHANGED | FL_FULL_EDICT_CHANGED);
  201. SetChangeInfoSerialNumber( 0 );
  202. }
  203. inline void CBaseEdict::StateChanged()
  204. {
  205. // Note: this should only happen for properties in data tables that used some kind of pointer
  206. // dereference. If the data is directly offsetable, then changes will automatically be detected
  207. m_fStateFlags |= (FL_EDICT_CHANGED | FL_FULL_EDICT_CHANGED);
  208. SetChangeInfoSerialNumber( 0 );
  209. }
  210. inline void CBaseEdict::StateChanged( unsigned short offset )
  211. {
  212. if ( m_fStateFlags & FL_FULL_EDICT_CHANGED )
  213. return;
  214. m_fStateFlags |= FL_EDICT_CHANGED;
  215. IChangeInfoAccessor *accessor = GetChangeAccessor();
  216. int nCurrSerialNumber = accessor->GetChangeInfoSerialNumber();
  217. if ( nCurrSerialNumber == g_pSharedChangeInfo->m_iSerialNumber )
  218. {
  219. // Ok, I still own this one.
  220. CEdictChangeInfo *p = &g_pSharedChangeInfo->m_ChangeInfos[accessor->GetChangeInfo()];
  221. // Now add this offset to our list of changed variables.
  222. for ( unsigned short i=0; i < p->m_nChangeOffsets; i++ )
  223. if ( p->m_ChangeOffsets[i] == offset )
  224. return;
  225. if ( p->m_nChangeOffsets == MAX_CHANGE_OFFSETS )
  226. {
  227. // Invalidate our change info.
  228. accessor->SetChangeInfoSerialNumber( 0 );
  229. m_fStateFlags |= FL_FULL_EDICT_CHANGED; // So we don't get in here again.
  230. }
  231. else
  232. {
  233. p->m_ChangeOffsets[p->m_nChangeOffsets++] = offset;
  234. }
  235. }
  236. else
  237. {
  238. if ( g_pSharedChangeInfo->m_nChangeInfos == MAX_EDICT_CHANGE_INFOS )
  239. {
  240. // Shucks.. have to mark the edict as fully changed because we don't have room to remember this change.
  241. accessor->SetChangeInfoSerialNumber( 0 );
  242. m_fStateFlags |= FL_FULL_EDICT_CHANGED;
  243. }
  244. else
  245. {
  246. //see if we previously had a change info allocated, but with a bad serial number. If so, we don't know which properties
  247. //we had changed (we lost them, so be all dirty)
  248. if( nCurrSerialNumber != 0 )
  249. {
  250. accessor->SetChangeInfoSerialNumber( 0 );
  251. m_fStateFlags |= FL_FULL_EDICT_CHANGED;
  252. }
  253. else
  254. {
  255. // Get a new CEdictChangeInfo and fill it out.
  256. accessor->SetChangeInfo( g_pSharedChangeInfo->m_nChangeInfos );
  257. g_pSharedChangeInfo->m_nChangeInfos++;
  258. accessor->SetChangeInfoSerialNumber( g_pSharedChangeInfo->m_iSerialNumber );
  259. CEdictChangeInfo *p = &g_pSharedChangeInfo->m_ChangeInfos[accessor->GetChangeInfo()];
  260. p->m_ChangeOffsets[0] = offset;
  261. p->m_nChangeOffsets = 1;
  262. }
  263. }
  264. }
  265. }
  266. inline void CBaseEdict::SetFree()
  267. {
  268. m_fStateFlags |= FL_EDICT_FREE;
  269. }
  270. inline void CBaseEdict::ClearFree()
  271. {
  272. m_fStateFlags &= ~FL_EDICT_FREE;
  273. }
  274. inline void CBaseEdict::ClearTransmitState()
  275. {
  276. m_fStateFlags &= ~(FL_EDICT_ALWAYS|FL_EDICT_PVSCHECK|FL_EDICT_DONTSEND);
  277. }
  278. inline const IServerEntity* CBaseEdict::GetIServerEntity() const
  279. {
  280. if ( m_fStateFlags & FL_EDICT_FULL )
  281. return (IServerEntity*)m_pUnk;
  282. else
  283. return 0;
  284. }
  285. inline IServerUnknown* CBaseEdict::GetUnknown()
  286. {
  287. return m_pUnk;
  288. }
  289. inline IServerNetworkable* CBaseEdict::GetNetworkable()
  290. {
  291. return m_pNetworkable;
  292. }
  293. inline void CBaseEdict::SetEdict( IServerUnknown *pUnk, bool bFullEdict )
  294. {
  295. m_pUnk = pUnk;
  296. if ( (pUnk != NULL) && bFullEdict )
  297. {
  298. m_fStateFlags = FL_EDICT_FULL;
  299. }
  300. else
  301. {
  302. m_fStateFlags = 0;
  303. }
  304. }
  305. inline int CBaseEdict::AreaNum() const
  306. {
  307. if ( !m_pUnk )
  308. return 0;
  309. return m_pNetworkable->AreaNum();
  310. }
  311. inline const char * CBaseEdict::GetClassName() const
  312. {
  313. if ( !m_pUnk )
  314. return "";
  315. return m_pNetworkable->GetClassName();
  316. }
  317. inline void CBaseEdict::SetChangeInfo( unsigned short info )
  318. {
  319. GetChangeAccessor()->SetChangeInfo( info );
  320. }
  321. inline void CBaseEdict::SetChangeInfoSerialNumber( unsigned short sn )
  322. {
  323. GetChangeAccessor()->SetChangeInfoSerialNumber( sn );
  324. }
  325. inline unsigned short CBaseEdict::GetChangeInfo() const
  326. {
  327. return GetChangeAccessor()->GetChangeInfo();
  328. }
  329. inline unsigned short CBaseEdict::GetChangeInfoSerialNumber() const
  330. {
  331. return GetChangeAccessor()->GetChangeInfoSerialNumber();
  332. }
  333. //-----------------------------------------------------------------------------
  334. // Purpose: The engine's internal representation of an entity, including some
  335. // basic collision and position info and a pointer to the class wrapped on top
  336. // of the structure
  337. //-----------------------------------------------------------------------------
  338. struct edict_t : public CBaseEdict
  339. {
  340. public:
  341. ICollideable *GetCollideable();
  342. };
  343. inline ICollideable *edict_t::GetCollideable()
  344. {
  345. IServerEntity *pEnt = GetIServerEntity();
  346. if ( pEnt )
  347. return pEnt->GetCollideable();
  348. else
  349. return NULL;
  350. }
  351. #endif // EDICT_H