aboutsummaryrefslogtreecommitdiff
path: root/mp/src/public/edict.h
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /mp/src/public/edict.h
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/public/edict.h')
-rw-r--r--mp/src/public/edict.h446
1 files changed, 446 insertions, 0 deletions
diff --git a/mp/src/public/edict.h b/mp/src/public/edict.h
new file mode 100644
index 00000000..b43ba042
--- /dev/null
+++ b/mp/src/public/edict.h
@@ -0,0 +1,446 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef EDICT_H
+#define EDICT_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "mathlib/vector.h"
+#include "cmodel.h"
+#include "const.h"
+#include "iserverentity.h"
+#include "globalvars_base.h"
+#include "engine/ICollideable.h"
+#include "iservernetworkable.h"
+#include "bitvec.h"
+
+struct edict_t;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Defines the ways that a map can be loaded.
+//-----------------------------------------------------------------------------
+enum MapLoadType_t
+{
+ MapLoad_NewGame = 0,
+ MapLoad_LoadGame,
+ MapLoad_Transition,
+ MapLoad_Background,
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Global variables shared between the engine and the game .dll
+//-----------------------------------------------------------------------------
+class CGlobalVars : public CGlobalVarsBase
+{
+public:
+
+ CGlobalVars( bool bIsClient );
+
+public:
+
+ // Current map
+ string_t mapname;
+ int mapversion;
+ string_t startspot;
+ MapLoadType_t eLoadType; // How the current map was loaded
+ bool bMapLoadFailed; // Map has failed to load, we need to kick back to the main menu
+
+ // game specific flags
+ bool deathmatch;
+ bool coop;
+ bool teamplay;
+ // current maxentities
+ int maxEntities;
+
+ int serverCount;
+};
+
+inline CGlobalVars::CGlobalVars( bool bIsClient ) :
+ CGlobalVarsBase( bIsClient )
+{
+ serverCount = 0;
+}
+
+
+class CPlayerState;
+class IServerNetworkable;
+class IServerEntity;
+
+
+#define FL_EDICT_CHANGED (1<<0) // Game DLL sets this when the entity state changes
+ // Mutually exclusive with FL_EDICT_PARTIAL_CHANGE.
+
+#define FL_EDICT_FREE (1<<1) // this edict if free for reuse
+#define FL_EDICT_FULL (1<<2) // this is a full server entity
+
+#define FL_EDICT_FULLCHECK (0<<0) // call ShouldTransmit() each time, this is a fake flag
+#define FL_EDICT_ALWAYS (1<<3) // always transmit this entity
+#define FL_EDICT_DONTSEND (1<<4) // don't transmit this entity
+#define FL_EDICT_PVSCHECK (1<<5) // always transmit entity, but cull against PVS
+
+// Used by local network backdoor.
+#define FL_EDICT_PENDING_DORMANT_CHECK (1<<6)
+
+// This is always set at the same time EFL_DIRTY_PVS_INFORMATION is set, but it
+// gets cleared in a different place.
+#define FL_EDICT_DIRTY_PVS_INFORMATION (1<<7)
+
+// This is used internally to edict_t to remember that it's carrying a
+// "full change list" - all its properties might have changed their value.
+#define FL_FULL_EDICT_CHANGED (1<<8)
+
+
+// Max # of variable changes we'll track in an entity before we treat it
+// like they all changed.
+#define MAX_CHANGE_OFFSETS 19
+#define MAX_EDICT_CHANGE_INFOS 100
+
+
+class CEdictChangeInfo
+{
+public:
+ // Edicts remember the offsets of properties that change
+ unsigned short m_ChangeOffsets[MAX_CHANGE_OFFSETS];
+ unsigned short m_nChangeOffsets;
+};
+
+// Shared between engine and game DLL.
+class CSharedEdictChangeInfo
+{
+public:
+ CSharedEdictChangeInfo()
+ {
+ m_iSerialNumber = 1;
+ }
+
+ // Matched against edict_t::m_iChangeInfoSerialNumber to determine if its
+ // change info is valid.
+ unsigned short m_iSerialNumber;
+
+ CEdictChangeInfo m_ChangeInfos[MAX_EDICT_CHANGE_INFOS];
+ unsigned short m_nChangeInfos; // How many are in use this frame.
+};
+extern CSharedEdictChangeInfo *g_pSharedChangeInfo;
+
+class IChangeInfoAccessor
+{
+public:
+ inline void SetChangeInfo( unsigned short info )
+ {
+ m_iChangeInfo = info;
+ }
+
+ inline void SetChangeInfoSerialNumber( unsigned short sn )
+ {
+ m_iChangeInfoSerialNumber = sn;
+ }
+
+ inline unsigned short GetChangeInfo() const
+ {
+ return m_iChangeInfo;
+ }
+
+ inline unsigned short GetChangeInfoSerialNumber() const
+ {
+ return m_iChangeInfoSerialNumber;
+ }
+
+private:
+ unsigned short m_iChangeInfo;
+ unsigned short m_iChangeInfoSerialNumber;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+// NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!!
+class CBaseEdict
+{
+public:
+
+ // Returns an IServerEntity if FL_FULLEDICT is set or NULL if this
+ // is a lightweight networking entity.
+ IServerEntity* GetIServerEntity();
+ const IServerEntity* GetIServerEntity() const;
+
+ IServerNetworkable* GetNetworkable();
+ IServerUnknown* GetUnknown();
+
+ // Set when initting an entity. If it's only a networkable, this is false.
+ void SetEdict( IServerUnknown *pUnk, bool bFullEdict );
+
+ int AreaNum() const;
+ const char * GetClassName() const;
+
+ bool IsFree() const;
+ void SetFree();
+ void ClearFree();
+
+ bool HasStateChanged() const;
+ void ClearStateChanged();
+ void StateChanged();
+ void StateChanged( unsigned short offset );
+
+ void ClearTransmitState();
+
+ void SetChangeInfo( unsigned short info );
+ void SetChangeInfoSerialNumber( unsigned short sn );
+ unsigned short GetChangeInfo() const;
+ unsigned short GetChangeInfoSerialNumber() const;
+
+public:
+
+ // NOTE: this is in the edict instead of being accessed by a virtual because the engine needs fast access to it.
+ // NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!!
+#ifdef _XBOX
+ unsigned short m_fStateFlags;
+#else
+ int m_fStateFlags;
+#endif
+
+ // NOTE: this is in the edict instead of being accessed by a virtual because the engine needs fast access to it.
+ // int m_NetworkSerialNumber;
+
+ // NOTE: m_EdictIndex is an optimization since computing the edict index
+ // from a CBaseEdict* pointer otherwise requires divide-by-20. values for
+ // m_NetworkSerialNumber all fit within a 16-bit integer range, so we're
+ // repurposing the other 16 bits to cache off the index without changing
+ // the overall layout or size of this struct. existing mods compiled with
+ // a full 32-bit serial number field should still work. henryg 8/17/2011
+#if VALVE_LITTLE_ENDIAN
+ short m_NetworkSerialNumber;
+ short m_EdictIndex;
+#else
+ short m_EdictIndex;
+ short m_NetworkSerialNumber;
+#endif
+
+ // NOTE: this is in the edict instead of being accessed by a virtual because the engine needs fast access to it.
+ IServerNetworkable *m_pNetworkable;
+
+protected:
+ IServerUnknown *m_pUnk;
+
+
+public:
+
+ IChangeInfoAccessor *GetChangeAccessor(); // The engine implements this and the game .dll implements as
+ const IChangeInfoAccessor *GetChangeAccessor() const; // The engine implements this and the game .dll implements as
+ // as callback through to the engine!!!
+
+ // NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!!
+ // This breaks HL2_VC6!!!!!
+ // References a CEdictChangeInfo with a list of modified network props.
+ //unsigned short m_iChangeInfo;
+ //unsigned short m_iChangeInfoSerialNumber;
+
+ friend void InitializeEntityDLLFields( edict_t *pEdict );
+};
+
+
+//-----------------------------------------------------------------------------
+// CBaseEdict inlines.
+//-----------------------------------------------------------------------------
+inline IServerEntity* CBaseEdict::GetIServerEntity()
+{
+ if ( m_fStateFlags & FL_EDICT_FULL )
+ return (IServerEntity*)m_pUnk;
+ else
+ return 0;
+}
+
+inline bool CBaseEdict::IsFree() const
+{
+ return (m_fStateFlags & FL_EDICT_FREE) != 0;
+}
+
+
+
+inline bool CBaseEdict::HasStateChanged() const
+{
+ return (m_fStateFlags & FL_EDICT_CHANGED) != 0;
+}
+
+inline void CBaseEdict::ClearStateChanged()
+{
+ m_fStateFlags &= ~(FL_EDICT_CHANGED | FL_FULL_EDICT_CHANGED);
+ SetChangeInfoSerialNumber( 0 );
+}
+
+inline void CBaseEdict::StateChanged()
+{
+ // Note: this should only happen for properties in data tables that used some
+ // kind of pointer dereference. If the data is directly offsetable
+ m_fStateFlags |= (FL_EDICT_CHANGED | FL_FULL_EDICT_CHANGED);
+ SetChangeInfoSerialNumber( 0 );
+}
+
+inline void CBaseEdict::StateChanged( unsigned short offset )
+{
+ if ( m_fStateFlags & FL_FULL_EDICT_CHANGED )
+ return;
+
+ m_fStateFlags |= FL_EDICT_CHANGED;
+
+ IChangeInfoAccessor *accessor = GetChangeAccessor();
+
+ if ( accessor->GetChangeInfoSerialNumber() == g_pSharedChangeInfo->m_iSerialNumber )
+ {
+ // Ok, I still own this one.
+ CEdictChangeInfo *p = &g_pSharedChangeInfo->m_ChangeInfos[accessor->GetChangeInfo()];
+
+ // Now add this offset to our list of changed variables.
+ for ( unsigned short i=0; i < p->m_nChangeOffsets; i++ )
+ if ( p->m_ChangeOffsets[i] == offset )
+ return;
+
+ if ( p->m_nChangeOffsets == MAX_CHANGE_OFFSETS )
+ {
+ // Invalidate our change info.
+ accessor->SetChangeInfoSerialNumber( 0 );
+ m_fStateFlags |= FL_FULL_EDICT_CHANGED; // So we don't get in here again.
+ }
+ else
+ {
+ p->m_ChangeOffsets[p->m_nChangeOffsets++] = offset;
+ }
+ }
+ else
+ {
+ if ( g_pSharedChangeInfo->m_nChangeInfos == MAX_EDICT_CHANGE_INFOS )
+ {
+ // Shucks.. have to mark the edict as fully changed because we don't have room to remember this change.
+ accessor->SetChangeInfoSerialNumber( 0 );
+ m_fStateFlags |= FL_FULL_EDICT_CHANGED;
+ }
+ else
+ {
+ // Get a new CEdictChangeInfo and fill it out.
+ accessor->SetChangeInfo( g_pSharedChangeInfo->m_nChangeInfos );
+ g_pSharedChangeInfo->m_nChangeInfos++;
+
+ accessor->SetChangeInfoSerialNumber( g_pSharedChangeInfo->m_iSerialNumber );
+
+ CEdictChangeInfo *p = &g_pSharedChangeInfo->m_ChangeInfos[accessor->GetChangeInfo()];
+ p->m_ChangeOffsets[0] = offset;
+ p->m_nChangeOffsets = 1;
+ }
+ }
+}
+
+
+
+inline void CBaseEdict::SetFree()
+{
+ m_fStateFlags |= FL_EDICT_FREE;
+}
+
+inline void CBaseEdict::ClearFree()
+{
+ m_fStateFlags &= ~FL_EDICT_FREE;
+}
+
+inline void CBaseEdict::ClearTransmitState()
+{
+ m_fStateFlags &= ~(FL_EDICT_ALWAYS|FL_EDICT_PVSCHECK|FL_EDICT_DONTSEND);
+}
+
+inline const IServerEntity* CBaseEdict::GetIServerEntity() const
+{
+ if ( m_fStateFlags & FL_EDICT_FULL )
+ return (IServerEntity*)m_pUnk;
+ else
+ return 0;
+}
+
+inline IServerUnknown* CBaseEdict::GetUnknown()
+{
+ return m_pUnk;
+}
+
+inline IServerNetworkable* CBaseEdict::GetNetworkable()
+{
+ return m_pNetworkable;
+}
+
+inline void CBaseEdict::SetEdict( IServerUnknown *pUnk, bool bFullEdict )
+{
+ m_pUnk = pUnk;
+ if ( (pUnk != NULL) && bFullEdict )
+ {
+ m_fStateFlags = FL_EDICT_FULL;
+ }
+ else
+ {
+ m_fStateFlags = 0;
+ }
+}
+
+inline int CBaseEdict::AreaNum() const
+{
+ if ( !m_pUnk )
+ return 0;
+
+ return m_pNetworkable->AreaNum();
+}
+
+inline const char * CBaseEdict::GetClassName() const
+{
+ if ( !m_pUnk )
+ return "";
+ return m_pNetworkable->GetClassName();
+}
+
+inline void CBaseEdict::SetChangeInfo( unsigned short info )
+{
+ GetChangeAccessor()->SetChangeInfo( info );
+}
+
+inline void CBaseEdict::SetChangeInfoSerialNumber( unsigned short sn )
+{
+ GetChangeAccessor()->SetChangeInfoSerialNumber( sn );
+}
+
+inline unsigned short CBaseEdict::GetChangeInfo() const
+{
+ return GetChangeAccessor()->GetChangeInfo();
+}
+
+inline unsigned short CBaseEdict::GetChangeInfoSerialNumber() const
+{
+ return GetChangeAccessor()->GetChangeInfoSerialNumber();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: The engine's internal representation of an entity, including some
+// basic collision and position info and a pointer to the class wrapped on top
+// of the structure
+//-----------------------------------------------------------------------------
+struct edict_t : public CBaseEdict
+{
+public:
+ ICollideable *GetCollideable();
+
+ // The server timestampe at which the edict was freed (so we can try to use other edicts before reallocating this one)
+ float freetime;
+};
+
+inline ICollideable *edict_t::GetCollideable()
+{
+ IServerEntity *pEnt = GetIServerEntity();
+ if ( pEnt )
+ return pEnt->GetCollideable();
+ else
+ return NULL;
+}
+
+
+#endif // EDICT_H