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.

448 lines
12 KiB

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