CBaseEntity/definitions

From Valve Developer Community
Jump to: navigation, search

Shared

baseentity_shared.h

baseentity_shared.cpp

Serverside

baseentity.h

//-----------------------------------------------------------------------------
// Purpose: think contexts
//-----------------------------------------------------------------------------
struct thinkfunc_t
{
	BASEPTR		m_pfnThink;
	string_t	m_iszContext;
	int			m_nNextThinkTick;
	int			m_nLastThinkTick;

	DECLARE_SIMPLE_DATADESC();
};

//
// Base Entity.  All entity types derive from this
//
class CBaseEntity : public IServerEntity
{
public:
	DECLARE_CLASS_NOBASE( CBaseEntity );	

	//----------------------------------------
	// Class vars and functions
	//----------------------------------------
	static inline void Debug_Pause(bool bPause);
	static inline bool Debug_IsPaused(void);
	static inline void Debug_SetSteps(int nSteps);
	static inline bool Debug_ShouldStep(void);
	static inline bool Debug_Step(void);

	static bool				m_bInDebugSelect;
	static int				m_nDebugPlayer;

protected:

	static bool				m_bDebugPause;		// Whether entity i/o is paused for debugging.
	static int				m_nDebugSteps;		// Number of entity outputs to fire before pausing again.

	static bool				sm_bDisableTouchFuncs;	// Disables PhysicsTouch and PhysicsStartTouch function calls
public:
	static bool				sm_bAccurateTriggerBboxChecks;	// SOLID_BBOX entities do a fully accurate trigger vs bbox check when this is set

public:
	// If bServerOnly is true, then the ent never goes to the client. This is used
	// by logical entities.
	CBaseEntity( bool bServerOnly=false );
	virtual ~CBaseEntity();

	// prediction system
	DECLARE_PREDICTABLE();
	// network data
	DECLARE_SERVERCLASS();
	// data description
	DECLARE_DATADESC();
	
	// memory handling
    void *operator new( size_t stAllocateBlock );
    void *operator new( size_t stAllocateBlock, int nBlockUse, const char *pFileName, int nLine );
	void operator delete( void *pMem );
	void operator delete( void *pMem, int nBlockUse, const char *pFileName, int nLine ) { operator delete(pMem); }

	// Class factory
	static CBaseEntity				*CreatePredictedEntityByName( const char *classname, const char *module, int line, bool persist = false );

// IHandleEntity overrides.
public:
	virtual void			SetRefEHandle( const CBaseHandle &handle );
	virtual const			CBaseHandle& GetRefEHandle() const;

// IServerUnknown overrides
	virtual ICollideable	*GetCollideable();
	virtual IServerNetworkable *GetNetworkable();
	virtual CBaseEntity		*GetBaseEntity();

// IServerEntity overrides.
public:
	virtual void			SetModelIndex( int index );
	virtual int				GetModelIndex( void ) const;
 	virtual string_t		GetModelName( void ) const;

	void					ClearModelIndexOverrides( void );
	virtual void			SetModelIndexOverride( int index, int nValue );

public:
	// virtual methods for derived classes to override
	virtual bool			TestCollision( const Ray_t& ray, unsigned int mask, trace_t& trace );
	virtual	bool			TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
	virtual void			ComputeWorldSpaceSurroundingBox( Vector *pWorldMins, Vector *pWorldMaxs );

	// non-virtual methods. Don't override these!
public:
	// An inline version the game code can use
	CCollisionProperty		*CollisionProp();
	const CCollisionProperty*CollisionProp() const;
	CServerNetworkProperty *NetworkProp();
	const CServerNetworkProperty *NetworkProp() const;

	bool					IsCurrentlyTouching( void ) const;
	const Vector&			GetAbsOrigin( void ) const;
	const QAngle&			GetAbsAngles( void ) const;

	SolidType_t				GetSolid() const;
	int			 			GetSolidFlags( void ) const;

	int						GetEFlags() const;
	void					SetEFlags( int iEFlags );
	void					AddEFlags( int nEFlagMask );
	void					RemoveEFlags( int nEFlagMask );
	bool					IsEFlagSet( int nEFlagMask ) const;

	// Quick way to ask if we have a player entity as a child anywhere in our hierarchy.
	void					RecalcHasPlayerChildBit();
	bool					DoesHavePlayerChild();

	bool					IsTransparent() const;

	void					SetNavIgnore( float duration = FLT_MAX );
	void					ClearNavIgnore();
	bool					IsNavIgnored() const;

	// Is the entity floating?
	bool					IsFloating();

	// Called by physics to see if we should avoid a collision test....
	virtual	bool			ShouldCollide( int collisionGroup, int contentsMask ) const;

	// Move type / move collide
	MoveType_t				GetMoveType() const;
	MoveCollide_t			GetMoveCollide() const;
	void					SetMoveType( MoveType_t val, MoveCollide_t moveCollide = MOVECOLLIDE_DEFAULT );
	void					SetMoveCollide( MoveCollide_t val );

	// Returns the entity-to-world transform
	matrix3x4_t				&EntityToWorldTransform();
	const matrix3x4_t		&EntityToWorldTransform() const;

	// Some helper methods that transform a point from entity space to world space + back
	void					EntityToWorldSpace( const Vector &in, Vector *pOut ) const;
	void					WorldToEntitySpace( const Vector &in, Vector *pOut ) const;

	// This function gets your parent's transform. If you're parented to an attachment,
	// this calculates the attachment's transform and gives you that.
	//
	// You must pass in tempMatrix for scratch space - it may need to fill that in and return it instead of 
	// pointing you right at a variable in your parent.
	matrix3x4_t&			GetParentToWorldTransform( matrix3x4_t &tempMatrix );

	// Externalized data objects ( see sharreddefs.h for DataObjectType_t )
	bool					HasDataObjectType( int type ) const;
	void					AddDataObjectType( int type );
	void					RemoveDataObjectType( int type );

	void					*GetDataObject( int type );
	void					*CreateDataObject( int type );
	void					DestroyDataObject( int type );
	void					DestroyAllDataObjects( void );

public:
	void SetScaledPhysics( IPhysicsObject *pNewObject );

	// virtual methods; you can override these
public:
	// Owner entity.
	// FIXME: These are virtual only because of CNodeEnt
	CBaseEntity				*GetOwnerEntity() const;
	virtual void			SetOwnerEntity( CBaseEntity* pOwner );
	void					SetEffectEntity( CBaseEntity *pEffectEnt );
	CBaseEntity				*GetEffectEntity() const;

	// Only CBaseEntity implements these. CheckTransmit calls the virtual ShouldTransmit to see if the
	// entity wants to be sent. If so, it calls SetTransmit, which will mark any dependents for transmission too.
	virtual int				ShouldTransmit( const CCheckTransmitInfo *pInfo );

	// update the global transmit state if a transmission rule changed
		    int				SetTransmitState( int nFlag);
			int				GetTransmitState( void );
	int						DispatchUpdateTransmitState();
	
	// Do NOT call this directly. Use DispatchUpdateTransmitState.
	virtual int				UpdateTransmitState();
	
	// Entities (like ropes) use this to own the transmit state of another entity
	// by forcing it to not call UpdateTransmitState.
	void					IncrementTransmitStateOwnedCounter();
	void					DecrementTransmitStateOwnedCounter();

	// This marks the entity for transmission and passes the SetTransmit call to any dependents.
	virtual void			SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );

	// This function finds out if the entity is in the 3D skybox. If so, it sets the EFL_IN_SKYBOX
	// flag so the entity gets transmitted to all the clients.
	// Entities usually call this during their Activate().
	// Returns true if the entity is in the skybox (and EFL_IN_SKYBOX was set).
	bool					DetectInSkybox();

	// Returns which skybox the entity is in
	CSkyCamera				*GetEntitySkybox();

	bool					IsSimulatedEveryTick() const;
	bool					IsAnimatedEveryTick() const;
	void					SetSimulatedEveryTick( bool sim );
	void					SetAnimatedEveryTick( bool anim );

public:

	virtual const char	*GetTracerType( void );

	// returns a pointer to the entities edict, if it has one.  should be removed!
	inline edict_t			*edict( void )			{ return NetworkProp()->edict(); }
	inline const edict_t	*edict( void ) const	{ return NetworkProp()->edict(); }
	inline int				entindex( ) const		{ return m_Network.entindex(); };
	inline int				GetSoundSourceIndex() const		{ return entindex(); }

	// These methods encapsulate MOVETYPE_FOLLOW, which became obsolete
	void FollowEntity( CBaseEntity *pBaseEntity, bool bBoneMerge = true );
	void StopFollowingEntity( );	// will also change to MOVETYPE_NONE
	bool IsFollowingEntity();
	CBaseEntity *GetFollowedEntity();

	// initialization
	virtual void Spawn( void );
	virtual void Precache( void ) {}

	virtual void SetModel( const char *szModelName );

protected:
	// Notification on model load. May be called multiple times for dynamic models.
	// Implementations must call BaseClass::OnNewModel and pass return value through.
	virtual CStudioHdr *OnNewModel();

public:
	virtual void PostConstructor( const char *szClassname );
	virtual void PostClientActive( void );
	virtual void ParseMapData( CEntityMapData *mapData );
	virtual bool KeyValue( const char *szKeyName, const char *szValue );
	virtual bool KeyValue( const char *szKeyName, float flValue );
	virtual bool KeyValue( const char *szKeyName, const Vector &vecValue );
	virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen );

	void ValidateEntityConnections();
	void FireNamedOutput( const char *pszOutput, variant_t variant, CBaseEntity *pActivator, CBaseEntity *pCaller, float flDelay = 0.0f );

	// Activate - called for each entity after each load game and level load
	virtual void Activate( void );

	// Hierarchy traversal
	CBaseEntity *GetMoveParent( void );
	CBaseEntity *GetRootMoveParent();
	CBaseEntity *FirstMoveChild( void );
	CBaseEntity *NextMovePeer( void );

	void		SetName( string_t newTarget );
	void		SetParent( string_t newParent, CBaseEntity *pActivator, int iAttachment = -1 );
	
	// Set the movement parent. Your local origin and angles will become relative to this parent.
	// If iAttachment is a valid attachment on the parent, then your local origin and angles 
	// are relative to the attachment on this entity. If iAttachment == -1, it'll preserve the
	// current m_iParentAttachment.
	virtual void	SetParent( CBaseEntity* pNewParent, int iAttachment = -1 );
	CBaseEntity* GetParent();
	int			GetParentAttachment();

	string_t	GetEntityName();

	bool		NameMatches( const char *pszNameOrWildcard );
	bool		ClassMatches( const char *pszClassOrWildcard );
	bool		NameMatches( string_t nameStr );
	bool		ClassMatches( string_t nameStr );

private:
	bool		NameMatchesComplex( const char *pszNameOrWildcard );
	bool		ClassMatchesComplex( const char *pszClassOrWildcard );
	void		TransformStepData_WorldToParent( CBaseEntity *pParent );
	void		TransformStepData_ParentToParent( CBaseEntity *pOldParent, CBaseEntity *pNewParent );
	void		TransformStepData_ParentToWorld( CBaseEntity *pParent );


public:
	int			GetSpawnFlags( void ) const;
	void		AddSpawnFlags( int nFlags );
	void		RemoveSpawnFlags( int nFlags );
	void		ClearSpawnFlags( void );
	bool		HasSpawnFlags( int nFlags ) const;

	int			GetEffects( void ) const;
	void		AddEffects( int nEffects );
	void		RemoveEffects( int nEffects );
	void		ClearEffects( void );
	void		SetEffects( int nEffects );
	bool		IsEffectActive( int nEffects ) const;

	// makes the entity inactive
	void		MakeDormant( void );
	int			IsDormant( void );

	void		RemoveDeferred( void );	// Sets the entity invisible, and makes it remove itself on the next frame

	// checks to see if the entity is marked for deletion
	bool		IsMarkedForDeletion( void );

	// capabilities
	virtual int	ObjectCaps( void );

	// Verifies that the data description is valid in debug builds.
	#ifdef _DEBUG
	void ValidateDataDescription(void);
	#endif // _DEBUG

	// handles an input (usually caused by outputs)
	// returns true if the the value in the pass in should be set, false if the input is to be ignored
	virtual bool AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID );

	//
	// Input handlers.
	//
	void InputAlternativeSorting( inputdata_t &inputdata );
	void InputAlpha( inputdata_t &inputdata );
	void InputColor( inputdata_t &inputdata );
	void InputSetParent( inputdata_t &inputdata );
	void SetParentAttachment( const char *szInputName, const char *szAttachment, bool bMaintainOffset );
	void InputSetParentAttachment( inputdata_t &inputdata );
	void InputSetParentAttachmentMaintainOffset( inputdata_t &inputdata );
	void InputClearParent( inputdata_t &inputdata );
	void InputSetTeam( inputdata_t &inputdata );
	void InputUse( inputdata_t &inputdata );
	void InputKill( inputdata_t &inputdata );
	void InputKillHierarchy( inputdata_t &inputdata );
	void InputSetDamageFilter( inputdata_t &inputdata );
	void InputDispatchEffect( inputdata_t &inputdata );
	void InputEnableDamageForces( inputdata_t &inputdata );
	void InputDisableDamageForces( inputdata_t &inputdata );
	void InputAddContext( inputdata_t &inputdata );
	void InputRemoveContext( inputdata_t &inputdata );
	void InputClearContext( inputdata_t &inputdata );
	void InputDispatchResponse( inputdata_t& inputdata );
	void InputDisableShadow( inputdata_t &inputdata );
	void InputEnableShadow( inputdata_t &inputdata );
	void InputAddOutput( inputdata_t &inputdata );
	void InputFireUser1( inputdata_t &inputdata );
	void InputFireUser2( inputdata_t &inputdata );
	void InputFireUser3( inputdata_t &inputdata );
	void InputFireUser4( inputdata_t &inputdata );

	// Returns the origin at which to play an inputted dispatcheffect 
	virtual void GetInputDispatchEffectPosition( const char *sInputString, Vector &pOrigin, QAngle &pAngles );

	// tries to read a field from the entities data description - result is placed in variant_t
	bool ReadKeyField( const char *varName, variant_t *var );

	// classname access
	void		SetClassname( const char *className );
	const char* GetClassname();

	// Debug Overlays
	void		 EntityText( int text_offset, const char *text, float flDuration, int r = 255, int g = 255, int b = 255, int a = 255 );
	const char	*GetDebugName(void); // do not make this virtual -- designed to handle NULL this
	virtual	void DrawDebugGeometryOverlays(void);					
	virtual int  DrawDebugTextOverlays(void);
	void		 DrawTimedOverlays( void );
	void		 DrawBBoxOverlay( float flDuration = 0.0f );
	void		 DrawAbsBoxOverlay();
	void		 DrawRBoxOverlay();

	void		 DrawInputOverlay(const char *szInputName, CBaseEntity *pCaller, variant_t Value);
	void		 DrawOutputOverlay(CEventAction *ev);
	void		 SendDebugPivotOverlay( void );
	void		 AddTimedOverlay( const char *msg, int endTime );

	void		SetSolid( SolidType_t val );

	// save/restore
	// only overload these if you have special data to serialize
	virtual int	Save( ISave &save );
	virtual int	Restore( IRestore &restore );
	virtual bool ShouldSavePhysics();

	// handler to reset stuff before you are restored
	// NOTE: Always chain to base class when implementing this!
	virtual void OnSave( IEntitySaveUtils *pSaveUtils );

	// handler to reset stuff after you are restored
	// called after all entities have been loaded from all affected levels
	// called before activate
	// NOTE: Always chain to base class when implementing this!
	virtual void OnRestore();

	int			 GetTextureFrameIndex( void );
	void		 SetTextureFrameIndex( int iIndex );

	// Entities block Line-Of-Sight for NPCs by default.
	// Set this to false if you want to change this behavior.
	void		 SetBlocksLOS( bool bBlocksLOS );
	bool		 BlocksLOS( void );


	void		 SetAIWalkable( bool bBlocksLOS );
	bool		 IsAIWalkable( void );
private:
	int SaveDataDescBlock( ISave &save, datamap_t *dmap );
	int RestoreDataDescBlock( IRestore &restore, datamap_t *dmap );

public:
	// Networking related methods
	void	NetworkStateChanged();
	void	NetworkStateChanged( void *pVar );

public:
 	void CalcAbsolutePosition();

	// returns the edict index the entity requires when used in save/restore (eg players, world)
	// -1 means it doesn't require any special index
	virtual int RequiredEdictIndex( void ) { return -1; } 

	// interface function pts
	void (CBaseEntity::*m_pfnMoveDone)(void);
	virtual void MoveDone( void ) { if (m_pfnMoveDone) (this->*m_pfnMoveDone)();};

	// Why do we have two separate static Instance functions?
	static CBaseEntity *Instance( const CBaseHandle &hEnt );
	static CBaseEntity *Instance( const edict_t *pent );
	static CBaseEntity *Instance( edict_t *pent );
	static CBaseEntity* Instance( int iEnt );

	// Think function handling
	void (CBaseEntity::*m_pfnThink)(void);
	virtual void Think( void ) { if (m_pfnThink) (this->*m_pfnThink)();};

	// Think functions with contexts
	int		RegisterThinkContext( const char *szContext );
	BASEPTR	ThinkSet( BASEPTR func, float flNextThinkTime = 0, const char *szContext = NULL );
	void	SetNextThink( float nextThinkTime, const char *szContext = NULL );
	float	GetNextThink( const char *szContext = NULL );
	float	GetLastThink( const char *szContext = NULL );
	int		GetNextThinkTick( const char *szContext = NULL );
	int		GetLastThinkTick( const char *szContext = NULL );

	float				GetAnimTime() const;
	void				SetAnimTime( float at );

	float				GetSimulationTime() const;
	void				SetSimulationTime( float st );

	void				SetRenderMode( RenderMode_t nRenderMode );
	RenderMode_t		GetRenderMode() const;

private:
	// NOTE: Keep this near vtable so it's in cache with vtable.
	CServerNetworkProperty m_Network;

public:
	// members
	string_t m_iClassname;  // identifier for entity creation and save/restore
	string_t m_iGlobalname; // identifier for carrying entity across level transitions
	string_t m_iParent;	// the name of the entities parent; linked into m_pParent during Activate()

	int		m_iHammerID; // Hammer unique edit id number

public:
	// was pev->speed
	float		m_flSpeed;
	// was pev->renderfx
	CNetworkVar( unsigned char, m_nRenderFX );
	// was pev->rendermode
	CNetworkVar( unsigned char, m_nRenderMode );
	CNetworkVar( short, m_nModelIndex );
	
#ifdef TF_DLL
	CNetworkArray( int, m_nModelIndexOverrides, MAX_VISION_MODES ); // used to override the base model index on the client if necessary
#endif

	// was pev->rendercolor
	CNetworkColor32( m_clrRender );
	const color32 GetRenderColor() const;
	void SetRenderColor( byte r, byte g, byte b );
	void SetRenderColor( byte r, byte g, byte b, byte a );
	void SetRenderColorR( byte r );
	void SetRenderColorG( byte g );
	void SetRenderColorB( byte b );
	void SetRenderColorA( byte a );

	// was pev->animtime:  consider moving to CBaseAnimating
	float		m_flPrevAnimTime;
	CNetworkVar( float, m_flAnimTime );  // this is the point in time that the client will interpolate to position,angle,frame,etc.
	CNetworkVar( float, m_flSimulationTime );

	void IncrementInterpolationFrame(); // Call this to cause a discontinuity (teleport)

	CNetworkVar( int, m_ubInterpolationFrame );

	int				m_nLastThinkTick;

#if !defined( NO_ENTITY_PREDICTION )
	// Certain entities (projectiles) can be created on the client and thus need a matching id number
	CNetworkVar( CPredictableId, m_PredictableID );
#endif

	// used so we know when things are no longer touching
	int			touchStamp;			

protected:

	// think function handling
	enum thinkmethods_t
	{
		THINK_FIRE_ALL_FUNCTIONS,
		THINK_FIRE_BASE_ONLY,
		THINK_FIRE_ALL_BUT_BASE,
	};
	int		GetIndexForThinkContext( const char *pszContext );
	CUtlVector< thinkfunc_t >	m_aThinkFunctions;

#ifdef _DEBUG
	int							m_iCurrentThinkContext;
#endif

	void RemoveExpiredConcepts( void );
	int	GetContextCount() const;						// Call RemoveExpiredConcepts to clean out expired concepts
	const char *GetContextName( int index ) const;		// note: context may be expired
	const char *GetContextValue( int index ) const; 	// note: context may be expired
	bool ContextExpired( int index ) const;
	int FindContextByName( const char *name ) const;
public:
	void	AddContext( const char *nameandvalue );

protected:
	CUtlVector< ResponseContext_t > m_ResponseContexts;

	// Map defined context sets
	string_t	m_iszResponseContext;

private:
	CBaseEntity( CBaseEntity& );

	// list handling
	friend class CGlobalEntityList;
	friend class CThinkSyncTester;

	// was pev->nextthink
	CNetworkVarForDerived( int, m_nNextThinkTick );
	// was pev->effects
	CNetworkVar( int, m_fEffects );

////////////////////////////////////////////////////////////////////////////


public:

	// Returns a CBaseAnimating if the entity is derived from CBaseAnimating.
	virtual CBaseAnimating*	GetBaseAnimating() { return 0; }

	virtual IResponseSystem *GetResponseSystem();
	virtual void	DispatchResponse( const char *conceptName );

// Classify - returns the type of group (i.e, "houndeye", or "human military" so that NPCs with different classnames
// still realize that they are teammates. (overridden for NPCs that form groups)
	virtual Class_T Classify ( void );
	virtual void	DeathNotice ( CBaseEntity *pVictim ) {}// NPC maker children use this to tell the NPC maker that they have died.
	virtual bool	ShouldAttractAutoAim( CBaseEntity *pAimingEnt ) { return ((GetFlags() & FL_AIMTARGET) != 0); }
	virtual float	GetAutoAimRadius();
	virtual Vector	GetAutoAimCenter() { return WorldSpaceCenter(); }

	virtual ITraceFilter*	GetBeamTraceFilter( void );

	// Call this to do a TraceAttack on an entity, performs filtering. Don't call TraceAttack() directly except when chaining up to base class
	void			DispatchTraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator = NULL );
	virtual bool	PassesDamageFilter( const CTakeDamageInfo &info );


protected:
	virtual void	TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator = NULL );

public:

	virtual bool	CanBeHitByMeleeAttack( CBaseEntity *pAttacker ) { return true; }

	// returns the amount of damage inflicted
	virtual int		OnTakeDamage( const CTakeDamageInfo &info );

	// This is what you should call to apply damage to an entity.
	int TakeDamage( const CTakeDamageInfo &info );
	virtual void AdjustDamageDirection( const CTakeDamageInfo &info, Vector &dir, CBaseEntity *pEnt ) {}

	virtual int		TakeHealth( float flHealth, int bitsDamageType );

	virtual bool	IsAlive( void );
	// Entity killed (only fired once)
	virtual void	Event_Killed( const CTakeDamageInfo &info );
	
	void SendOnKilledGameEvent( const CTakeDamageInfo &info );

	// Notifier that I've killed some other entity. (called from Victim's Event_Killed).
	virtual void	Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) { return; }

	// UNDONE: Make this data?
	virtual int				BloodColor( void );

	void					TraceBleed( float flDamage, const Vector &vecDir, trace_t *ptr, int bitsDamageType );
	virtual bool			IsTriggered( CBaseEntity *pActivator ) {return true;}
	virtual bool			IsNPC( void ) const { return false; }
	CAI_BaseNPC				*MyNPCPointer( void ); 
	virtual CBaseCombatCharacter *MyCombatCharacterPointer( void ) { return NULL; }
	virtual INextBot		*MyNextBotPointer( void ) { return NULL; }
	virtual float			GetDelay( void ) { return 0; }
	virtual bool			IsMoving( void );
	bool					IsWorld() { return entindex() == 0; }
	virtual char const		*DamageDecal( int bitsDamageType, int gameMaterial );
	virtual void			DecalTrace( trace_t *pTrace, char const *decalName );
	virtual void			ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCustomImpactName = NULL );

	void			AddPoints( int score, bool bAllowNegativeScore );
	void			AddPointsToTeam( int score, bool bAllowNegativeScore );
	void			RemoveAllDecals( void );

	virtual bool	OnControls( CBaseEntity *pControls ) { return false; }
	virtual bool	HasTarget( string_t targetname );
	virtual	bool	IsPlayer( void ) const { return false; }
	virtual bool	IsNetClient( void ) const { return false; }
	virtual bool	IsTemplate( void ) { return false; }
	virtual bool	IsBaseObject( void ) const { return false; }
	virtual bool	IsBaseTrain( void ) const { return false; }
	bool			IsBSPModel() const;
	bool			IsCombatCharacter() { return MyCombatCharacterPointer() == NULL ? false : true; }
	bool			IsInWorld( void ) const;
	virtual bool	IsCombatItem( void ) const { return false; }

	virtual bool	IsBaseCombatWeapon( void ) const { return false; }
	virtual bool	IsWearable( void ) const { return false; }
	virtual CBaseCombatWeapon *MyCombatWeaponPointer( void ) { return NULL; }

	// If this is a vehicle, returns the vehicle interface
	virtual IServerVehicle*			GetServerVehicle() { return NULL; }

	// UNDONE: Make this data instead of procedural?
	virtual bool	IsViewable( void );					// is this something that would be looked at (model, sprite, etc.)?

	// Team Handling
	CTeam			*GetTeam( void ) const;				// Get the Team this entity is on
	int				GetTeamNumber( void ) const;		// Get the Team number of the team this entity is on
	virtual void	ChangeTeam( int iTeamNum );			// Assign this entity to a team.
	bool			IsInTeam( CTeam *pTeam ) const;		// Returns true if this entity's in the specified team
	bool			InSameTeam( CBaseEntity *pEntity ) const;	// Returns true if the specified entity is on the same team as this one
	bool			IsInAnyTeam( void ) const;			// Returns true if this entity is in any team
	const char		*TeamID( void ) const;				// Returns the name of the team this entity is on.

	// Entity events... these are events targetted to a particular entity
	// Each event defines its own well-defined event data structure
	virtual void OnEntityEvent( EntityEvent_t event, void *pEventData );

	// can stand on this entity?
	bool IsStandable() const;

	// UNDONE: Do these three functions actually need to be virtual???
	virtual bool	CanStandOn( CBaseEntity *pSurface ) const { return (pSurface && !pSurface->IsStandable()) ? false : true; }
	virtual bool	CanStandOn( edict_t	*ent ) const { return CanStandOn( GetContainingEntity( ent ) ); }
	virtual CBaseEntity		*GetEnemy( void ) { return NULL; }
	virtual CBaseEntity		*GetEnemy( void ) const { return NULL; }


	void	ViewPunch( const QAngle &angleOffset );
	void	VelocityPunch( const Vector &vecForce );

	CBaseEntity *GetNextTarget( void );
	
	// fundamental callbacks
	void (CBaseEntity ::*m_pfnTouch)( CBaseEntity *pOther );
	void (CBaseEntity ::*m_pfnUse)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
	void (CBaseEntity ::*m_pfnBlocked)( CBaseEntity *pOther );

	virtual void			Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
	virtual void			StartTouch( CBaseEntity *pOther );
	virtual void			Touch( CBaseEntity *pOther ); 
	virtual void			EndTouch( CBaseEntity *pOther );
	virtual void			StartBlocked( CBaseEntity *pOther ) {}
	virtual void			Blocked( CBaseEntity *pOther );
	virtual void			EndBlocked( void ) {}

	// Physics simulation
	virtual void			PhysicsSimulate( void );

public:
	// HACKHACK:Get the trace_t from the last physics touch call (replaces the even-hackier global trace vars)
	static const trace_t &	GetTouchTrace( void );

	// FIXME: Should be private, but I can't make em private just yet
	void					PhysicsImpact( CBaseEntity *other, trace_t &trace );
 	void					PhysicsMarkEntitiesAsTouching( CBaseEntity *other, trace_t &trace );
	void					PhysicsMarkEntitiesAsTouchingEventDriven( CBaseEntity *other, trace_t &trace );
	void					PhysicsTouchTriggers( const Vector *pPrevAbsOrigin = NULL );

	// Physics helper
	static void				PhysicsRemoveTouchedList( CBaseEntity *ent );
	static void				PhysicsNotifyOtherOfUntouch( CBaseEntity *ent, CBaseEntity *other );
	static void				PhysicsRemoveToucher( CBaseEntity *other, touchlink_t *link );

	groundlink_t			*AddEntityToGroundList( CBaseEntity *other );
	void					PhysicsStartGroundContact( CBaseEntity *pentOther );

	static void				PhysicsNotifyOtherOfGroundRemoval( CBaseEntity *ent, CBaseEntity *other );
	static void				PhysicsRemoveGround( CBaseEntity *other, groundlink_t *link );
	static void				PhysicsRemoveGroundList( CBaseEntity *ent );

	void					StartGroundContact( CBaseEntity *ground );
	void					EndGroundContact( CBaseEntity *ground );

	void					SetGroundChangeTime( float flTime );
	float					GetGroundChangeTime( void );

	// Remove this as ground entity for all object resting on this object
	void					WakeRestingObjects();
	bool					HasNPCsOnIt();

	virtual void			UpdateOnRemove( void );
	virtual void			StopLoopingSounds( void ) {}

	// common member functions
	void					SUB_Remove( void );
	void					SUB_DoNothing( void );
	void					SUB_StartFadeOut( float delay = 10.0f, bool bNotSolid = true );
	void					SUB_StartFadeOutInstant();
	void					SUB_FadeOut ( void );
	void					SUB_Vanish( void );
	void					SUB_CallUseToggle( void ) { this->Use( this, this, USE_TOGGLE, 0 ); }
	void					SUB_PerformFadeOut( void );
	virtual	bool			SUB_AllowedToFade( void );

	// change position, velocity, orientation instantly
	// passing NULL means no change
	virtual void			Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity );
	// notify that another entity (that you were watching) was teleported
	virtual void			NotifySystemEvent( CBaseEntity *pNotify, notify_system_event_t eventType, const notify_system_event_params_t &params );

	int						ShouldToggle( USE_TYPE useType, int currentState );

	// UNDONE: Move these virtuals to CBaseCombatCharacter?
	virtual void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType );
	virtual int	GetTracerAttachment( void );
	virtual void FireBullets( const FireBulletsInfo_t &info );
	virtual void DoImpactEffect( trace_t &tr, int nDamageType ); // give shooter a chance to do a custom impact.

	// OLD VERSION! Use the struct version
	void FireBullets( int cShots, const Vector &vecSrc, const Vector &vecDirShooting, 
		const Vector &vecSpread, float flDistance, int iAmmoType, int iTracerFreq = 4, 
		int firingEntID = -1, int attachmentID = -1, int iDamage = 0, 
		CBaseEntity *pAttacker = NULL, bool bFirstShotAccurate = false, bool bPrimaryAttack = true );
	virtual void ModifyFireBulletsDamage( CTakeDamageInfo* dmgInfo ) {}

	virtual CBaseEntity *Respawn( void ) { return NULL; }

	// Method used to deal with attacks passing through triggers
	void TraceAttackToTriggers( const CTakeDamageInfo &info, const Vector& start, const Vector& end, const Vector& dir );

	// Do the bounding boxes of these two intersect?
	bool	Intersects( CBaseEntity *pOther );
	virtual bool IsLockedByMaster( void ) { return false; }

	// Health accessors.
	virtual int		GetMaxHealth()  const	{ return m_iMaxHealth; }
	void	SetMaxHealth( int amt )	{ m_iMaxHealth = amt; }

	int		GetHealth() const		{ return m_iHealth; }
	void	SetHealth( int amt )	{ m_iHealth = amt; }

	float HealthFraction() const;

	// Ugly code to lookup all functions to make sure they are in the table when set.
#ifdef _DEBUG

#ifdef GNUC
#define ENTITYFUNCPTR_SIZE	8
#else
#define ENTITYFUNCPTR_SIZE	4
#endif

	void FunctionCheck( void *pFunction, const char *name );
	ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name ) 
	{ 
		COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE );
		m_pfnTouch = func; 
		FunctionCheck( *(reinterpret_cast<void **>(&m_pfnTouch)), name ); 
		return func;
	}
	USEPTR	UseSet( USEPTR func, char *name ) 
	{ 
		COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE );
		m_pfnUse = func; 
		FunctionCheck( *(reinterpret_cast<void **>(&m_pfnUse)), name ); 
		return func;
	}
	ENTITYFUNCPTR	BlockedSet( ENTITYFUNCPTR func, char *name ) 
	{ 
		COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE );
		m_pfnBlocked = func; 
		FunctionCheck( *(reinterpret_cast<void **>(&m_pfnBlocked)), name ); 
		return func;
	}

#endif // _DEBUG

	virtual void	ModifyOrAppendCriteria( AI_CriteriaSet& set );
	void			AppendContextToCriteria( AI_CriteriaSet& set, const char *prefix = "" );
	void			DumpResponseCriteria( void );

	// Return the IHasAttributes interface for this base entity. Removes the need for:
	//	dynamic_cast< IHasAttributes * >( pEntity );
	// Which is remarkably slow.
	// GetAttribInterface( CBaseEntity *pEntity ) in attribute_manager.h uses
	//  this function, tests for NULL, and Asserts m_pAttributes == dynamic_cast.
	inline IHasAttributes *GetHasAttributesInterfacePtr() const { return m_pAttributes; }

protected:
	// NOTE: m_pAttributes needs to be set in the leaf class constructor.
	IHasAttributes *m_pAttributes;

private:
	friend class CAI_Senses;
	CBaseEntity	*m_pLink;// used for temporary link-list operations. 

public:
	// variables promoted from edict_t
	string_t	m_target;
	CNetworkVarForDerived( int, m_iMaxHealth ); // CBaseEntity doesn't care about changes to this variable, but there are derived classes that do.
	CNetworkVarForDerived( int, m_iHealth );

	CNetworkVarForDerived( char, m_lifeState );
	CNetworkVarForDerived( char , m_takedamage );

	// Damage filtering
	string_t	m_iszDamageFilterName;	// The name of the entity to use as our damage filter.
	EHANDLE		m_hDamageFilter;		// The entity that controls who can damage us.

	// Debugging / devolopment fields
	int				m_debugOverlays;	// For debug only (bitfields)
	TimedOverlay_t*	m_pTimedOverlay;	// For debug only

	// virtual functions used by a few classes
	
	// creates an entity of a specified class, by name
	static CBaseEntity *Create( const char *szName, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner = NULL );
	static CBaseEntity *CreateNoSpawn( const char *szName, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner = NULL );

	// Collision group accessors
	int				GetCollisionGroup() const;
	void			SetCollisionGroup( int collisionGroup );
	void			CollisionRulesChanged();

	// Damage accessors
	virtual int		GetDamageType() const;
	virtual float	GetDamage() { return 0; }
	virtual void	SetDamage(float flDamage) {}

	virtual Vector	EyePosition( void );			// position of eyes
	virtual const QAngle &EyeAngles( void );		// Direction of eyes in world space
	virtual const QAngle &LocalEyeAngles( void );	// Direction of eyes
	virtual Vector	EarPosition( void );			// position of ears

	Vector	EyePosition( void ) const;			// position of eyes
	const QAngle &EyeAngles( void ) const;		// Direction of eyes in world space
	const QAngle &LocalEyeAngles( void ) const;	// Direction of eyes
	Vector	EarPosition( void ) const;			// position of ears

	virtual Vector	BodyTarget( const Vector &posSrc, bool bNoisy = true);		// position to shoot at
	virtual Vector	HeadTarget( const Vector &posSrc );
	virtual void	GetVectors(Vector* forward, Vector* right, Vector* up) const;

	virtual const Vector &GetViewOffset() const;
	virtual void SetViewOffset( const Vector &v );

	// NOTE: Setting the abs velocity in either space will cause a recomputation
	// in the other space, so setting the abs velocity will also set the local vel
	void			SetLocalVelocity( const Vector &vecVelocity );
	void			ApplyLocalVelocityImpulse( const Vector &vecImpulse );
	void			SetAbsVelocity( const Vector &vecVelocity );
	void			ApplyAbsVelocityImpulse( const Vector &vecImpulse );
	void			ApplyLocalAngularVelocityImpulse( const AngularImpulse &angImpulse );

	const Vector&	GetLocalVelocity( ) const;
	const Vector&	GetAbsVelocity( ) const;

	// NOTE: Setting the abs velocity in either space will cause a recomputation
	// in the other space, so setting the abs velocity will also set the local vel
	void			SetLocalAngularVelocity( const QAngle &vecAngVelocity );
	const QAngle&	GetLocalAngularVelocity( ) const;

	// FIXME: While we're using (dPitch, dYaw, dRoll) as our local angular velocity
	// representation, we can't actually solve this problem
//	void			SetAbsAngularVelocity( const QAngle &vecAngVelocity );
//	const QAngle&	GetAbsAngularVelocity( ) const;

	const Vector&	GetBaseVelocity() const;
	void			SetBaseVelocity( const Vector& v );

	virtual Vector	GetSmoothedVelocity( void );

	// FIXME: Figure out what to do about this
	virtual void	GetVelocity(Vector *vVelocity, AngularImpulse *vAngVelocity = NULL);

	float			GetGravity( void ) const;
	void			SetGravity( float gravity );
	float			GetFriction( void ) const;
	void			SetFriction( float flFriction );

	virtual	bool FVisible ( CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL );
	virtual bool FVisible( const Vector &vecTarget, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL );

	virtual bool CanBeSeenBy( CAI_BaseNPC *pNPC ) { return true; } // allows entities to be 'invisible' to NPC senses.

	// This function returns a value that scales all damage done by this entity.
	// Use CDamageModifier to hook in damage modifiers on a guy.
	virtual float			GetAttackDamageScale( CBaseEntity *pVictim );
	// This returns a value that scales all damage done to this entity
	// Use CDamageModifier to hook in damage modifiers on a guy.
	virtual float			GetReceivedDamageScale( CBaseEntity *pAttacker );

 	void					SetCheckUntouch( bool check );
	bool					GetCheckUntouch() const;

	void					SetGroundEntity( CBaseEntity *ground );
	CBaseEntity				*GetGroundEntity( void );
	CBaseEntity				*GetGroundEntity( void ) const { return const_cast<CBaseEntity *>(this)->GetGroundEntity(); }

	// Gets the velocity we impart to a player standing on us
	virtual void			GetGroundVelocityToApply( Vector &vecGroundVel ) { vecGroundVel = vec3_origin; }

	int						GetWaterLevel() const;
	void					SetWaterLevel( int nLevel );
	int						GetWaterType() const;
	void					SetWaterType( int nType );

	virtual bool			PhysicsSplash( const Vector &centerPoint, const Vector &normal, float rawSpeed, float scaledSpeed ) { return false; }
	virtual void			Splash() {}

	void					ClearSolidFlags( void );	
	void					RemoveSolidFlags( int flags );
	void					AddSolidFlags( int flags );
	bool					IsSolidFlagSet( int flagMask ) const;
	void				 	SetSolidFlags( int flags );
	bool					IsSolid() const;
	
	void					SetModelName( string_t name );

	model_t					*GetModel( void );

	// These methods return a *world-aligned* box relative to the absorigin of the entity.
	// This is used for collision purposes and is *not* guaranteed
	// to surround the entire entity's visual representation
	// NOTE: It is illegal to ask for the world-aligned bounds for
	// SOLID_BSP objects
	const Vector&			WorldAlignMins( ) const;
	const Vector&			WorldAlignMaxs( ) const;

	// This defines collision bounds in OBB space
	void					SetCollisionBounds( const Vector& mins, const Vector &maxs );

	// NOTE: The world space center *may* move when the entity rotates.
	virtual const Vector&	WorldSpaceCenter( ) const;
 	const Vector&			WorldAlignSize( ) const;

	// Returns a radius of a sphere 
	// *centered at the world space center* bounding the collision representation 
	// of the entity. NOTE: The world space center *may* move when the entity rotates.
	float					BoundingRadius() const;
	bool					IsPointSized() const;

	// NOTE: Setting the abs origin or angles will cause the local origin + angles to be set also
	void					SetAbsOrigin( const Vector& origin );
	void					SetAbsAngles( const QAngle& angles );

	// Origin and angles in local space ( relative to parent )
	// NOTE: Setting the local origin or angles will cause the abs origin + angles to be set also
	void					SetLocalOrigin( const Vector& origin );
	const Vector&			GetLocalOrigin( void ) const;

	void					SetLocalAngles( const QAngle& angles );
	const QAngle&			GetLocalAngles( void ) const;

	void					SetElasticity( float flElasticity );
	float					GetElasticity( void ) const;

	void					SetShadowCastDistance( float flDistance );
	float					GetShadowCastDistance( void ) const;
	void					SetShadowCastDistance( float flDesiredDistance, float flDelay );

	float					GetLocalTime( void ) const;
	void					IncrementLocalTime( float flTimeDelta );
	float					GetMoveDoneTime( ) const;
	void					SetMoveDoneTime( float flTime );
	
	// Used by the PAS filters to ask the entity where in world space the sounds it emits come from.
	// This is used right now because if you have something sitting on an incline, using our axis-aligned 
	// bounding boxes can return a position in solid space, so you won't hear sounds emitted by the object.
	// For now, we're hacking around it by moving the sound emission origin up on certain objects like vehicles.
	//
	// When OBBs get in, this can probably go away.
	virtual Vector			GetSoundEmissionOrigin() const;

	void					AddFlag( int flags );
	void					RemoveFlag( int flagsToRemove );
	void					ToggleFlag( int flagToToggle );
	int						GetFlags( void ) const;
	void					ClearFlags( void );

	// Sets the local position from a transform
	void					SetLocalTransform( const matrix3x4_t &localTransform );

	// See CSoundEmitterSystem
	void					EmitSound( const char *soundname, float soundtime = 0.0f, float *duration = NULL );  // Override for doing the general case of CPASAttenuationFilter filter( this ), and EmitSound( filter, entindex(), etc. );
	void					EmitSound( const char *soundname, HSOUNDSCRIPTHANDLE& handle, float soundtime = 0.0f, float *duration = NULL );  // Override for doing the general case of CPASAttenuationFilter filter( this ), and EmitSound( filter, entindex(), etc. );
	void					StopSound( const char *soundname );
	void					StopSound( const char *soundname, HSOUNDSCRIPTHANDLE& handle );
	void					GenderExpandString( char const *in, char *out, int maxlen );

	virtual void ModifyEmitSoundParams( EmitSound_t &params );

	static float GetSoundDuration( const char *soundname, char const *actormodel );

	static bool	GetParametersForSound( const char *soundname, CSoundParameters &params, char const *actormodel );
	static bool	GetParametersForSound( const char *soundname, HSOUNDSCRIPTHANDLE& handle, CSoundParameters &params, char const *actormodel );

	static void EmitSound( IRecipientFilter& filter, int iEntIndex, const char *soundname, const Vector *pOrigin = NULL, float soundtime = 0.0f, float *duration = NULL );
	static void EmitSound( IRecipientFilter& filter, int iEntIndex, const char *soundname, HSOUNDSCRIPTHANDLE& handle, const Vector *pOrigin = NULL, float soundtime = 0.0f, float *duration = NULL );
	static void StopSound( int iEntIndex, const char *soundname );
	static soundlevel_t LookupSoundLevel( const char *soundname );
	static soundlevel_t LookupSoundLevel( const char *soundname, HSOUNDSCRIPTHANDLE& handle );

	static void EmitSound( IRecipientFilter& filter, int iEntIndex, const EmitSound_t & params );
	static void EmitSound( IRecipientFilter& filter, int iEntIndex, const EmitSound_t & params, HSOUNDSCRIPTHANDLE& handle );

	static void StopSound( int iEntIndex, int iChannel, const char *pSample );

	static void EmitAmbientSound( int entindex, const Vector& origin, const char *soundname, int flags = 0, float soundtime = 0.0f, float *duration = NULL );

	// These files need to be listed in scripts/game_sounds_manifest.txt
	static HSOUNDSCRIPTHANDLE PrecacheScriptSound( const char *soundname );
	static void PrefetchScriptSound( const char *soundname );

	// For each client who appears to be a valid recipient, checks the client has disabled CC and if so, removes them from 
	//  the recipient list.
	static void RemoveRecipientsIfNotCloseCaptioning( CRecipientFilter& filter );
	static void EmitCloseCaption( IRecipientFilter& filter, int entindex, char const *token, CUtlVector< Vector >& soundorigins, float duration, bool warnifmissing = false );
	static void	EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex, int iChannel, int iSentenceIndex, 
		float flVolume, soundlevel_t iSoundlevel, int iFlags = 0, int iPitch = PITCH_NORM,
		const Vector *pOrigin = NULL, const Vector *pDirection = NULL, bool bUpdatePositions = true, float soundtime = 0.0f );

	static bool IsPrecacheAllowed();
	static void SetAllowPrecache( bool allow );

	static bool m_bAllowPrecache;

	static bool IsSimulatingOnAlternateTicks();

	virtual bool IsDeflectable() { return false; }
	virtual void Deflected( CBaseEntity *pDeflectedBy, Vector &vecDir ) {}

//	void Relink() {}

public:

	// VPHYSICS Integration -----------------------------------------------
	//
	// --------------------------------------------------------------------
	// UNDONE: Move to IEntityVPhysics? or VPhysicsProp() ?
	// Called after spawn, and in the case of self-managing objects, after load
	virtual bool	CreateVPhysics();

	// Convenience routines to init the vphysics simulation for this object.
	// This creates a static object.  Something that behaves like world geometry - solid, but never moves
	IPhysicsObject *VPhysicsInitStatic( void );

	// This creates a normal vphysics simulated object - physics determines where it goes (gravity, friction, etc)
	// and the entity receives updates from vphysics.  SetAbsOrigin(), etc do not affect the object!
	IPhysicsObject *VPhysicsInitNormal( SolidType_t solidType, int nSolidFlags, bool createAsleep, solid_t *pSolid = NULL );

	// This creates a vphysics object with a shadow controller that follows the AI
	// Move the object to where it should be and call UpdatePhysicsShadowToCurrentPosition()
	IPhysicsObject *VPhysicsInitShadow( bool allowPhysicsMovement, bool allowPhysicsRotation, solid_t *pSolid = NULL );

	// Force a non-solid (ie. solid_trigger) physics object to collide with other entities.
	virtual bool	ForceVPhysicsCollide( CBaseEntity *pEntity ) { return false; }

private:
	// called by all vphysics inits
	bool			VPhysicsInitSetup();
public:

	void			VPhysicsSetObject( IPhysicsObject *pPhysics );
	// destroy and remove the physics object for this entity
	virtual void	VPhysicsDestroyObject( void );
	void			VPhysicsSwapObject( IPhysicsObject *pSwap );

	inline IPhysicsObject *VPhysicsGetObject( void ) const { return m_pPhysicsObject; }
	virtual void	VPhysicsUpdate( IPhysicsObject *pPhysics );
	void			VPhysicsUpdatePusher( IPhysicsObject *pPhysics );
	
	// react physically to damage (called from CBaseEntity::OnTakeDamage() by default)
	virtual int		VPhysicsTakeDamage( const CTakeDamageInfo &info );
	virtual void	VPhysicsShadowCollision( int index, gamevcollisionevent_t *pEvent );
	virtual void	VPhysicsShadowUpdate( IPhysicsObject *pPhysics ) {}
	virtual void	VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
	virtual void	VPhysicsFriction( IPhysicsObject *pObject, float energy, int surfaceProps, int surfacePropsHit );
	
	// update the shadow so it will coincide with the current AI position at some time
	// in the future (or 0 for now)
	virtual void	UpdatePhysicsShadowToCurrentPosition( float deltaTime );
	virtual int		VPhysicsGetObjectList( IPhysicsObject **pList, int listMax );
	virtual bool	VPhysicsIsFlesh( void );
	// --------------------------------------------------------------------

public:
#if !defined( NO_ENTITY_PREDICTION )
	// The player drives simulation of this entity
	void					SetPlayerSimulated( CBasePlayer *pOwner );
	void					UnsetPlayerSimulated( void );
	bool					IsPlayerSimulated( void ) const;
	CBasePlayer				*GetSimulatingPlayer( void );
#endif
	// FIXME: Make these private!
	void					PhysicsCheckForEntityUntouch( void );
 	bool					PhysicsRunThink( thinkmethods_t thinkMethod = THINK_FIRE_ALL_FUNCTIONS );
	bool					PhysicsRunSpecificThink( int nContextIndex, BASEPTR thinkFunc );
	bool					PhysicsTestEntityPosition( CBaseEntity **ppEntity = NULL );
	void					PhysicsPushEntity( const Vector& push, trace_t *pTrace );
	bool					PhysicsCheckWater( void );
	void					PhysicsCheckWaterTransition( void );
	void					PhysicsStepRecheckGround();
	// Computes the water level + type
	void					UpdateWaterState();
	bool					IsEdictFree() const { return edict()->IsFree(); }

	// Callbacks for the physgun/cannon picking up an entity
	virtual	CBasePlayer		*HasPhysicsAttacker( float dt ) { return NULL; }

	// UNDONE: Make this data?
	virtual unsigned int	PhysicsSolidMaskForEntity( void ) const;

	// Computes the abs position of a point specified in local space
	void					ComputeAbsPosition( const Vector &vecLocalPosition, Vector *pAbsPosition );

	// Computes the abs position of a direction specified in local space
	void					ComputeAbsDirection( const Vector &vecLocalDirection, Vector *pAbsDirection );

	void					SetPredictionEligible( bool canpredict );

protected:
	// Invalidates the abs state of all children
	void					InvalidatePhysicsRecursive( int nChangeFlags );

	int						PhysicsClipVelocity (const Vector& in, const Vector& normal, Vector& out, float overbounce );
	void					PhysicsRelinkChildren( float dt );

	// Performs the collision resolution for fliers.
	void					PerformFlyCollisionResolution( trace_t &trace, Vector &move );
	void					ResolveFlyCollisionBounce( trace_t &trace, Vector &vecVelocity, float flMinTotalElasticity = 0.0f );
	void					ResolveFlyCollisionSlide( trace_t &trace, Vector &vecVelocity );
	virtual void			ResolveFlyCollisionCustom( trace_t &trace, Vector &vecVelocity );

private:
	// Physics-related private methods
	void					PhysicsStep( void );
	void					PhysicsPusher( void );
	void					PhysicsNone( void );
	void					PhysicsNoclip( void );
	void					PhysicsStepRunTimestep( float timestep );
	void					PhysicsToss( void );
	void					PhysicsCustom( void );
	void					PerformPush( float movetime );

	// Simulation in local space of rigid children
	void					PhysicsRigidChild( void );

	// Computes the base velocity
	void					UpdateBaseVelocity( void );

	// Implement this if you use MOVETYPE_CUSTOM
	virtual void			PerformCustomPhysics( Vector *pNewPosition, Vector *pNewVelocity, QAngle *pNewAngles, QAngle *pNewAngVelocity );

	void					PhysicsDispatchThink( BASEPTR thinkFunc );

	touchlink_t				*PhysicsMarkEntityAsTouched( CBaseEntity *other );
	void					PhysicsTouch( CBaseEntity *pentOther );
	void					PhysicsStartTouch( CBaseEntity *pentOther );

	CBaseEntity				*PhysicsPushMove( float movetime );
	CBaseEntity				*PhysicsPushRotate( float movetime );

	CBaseEntity				*PhysicsCheckRotateMove( rotatingpushmove_t &rotPushmove, CBaseEntity **pPusherList, int pusherListCount );
	CBaseEntity				*PhysicsCheckPushMove( const Vector& move, CBaseEntity **pPusherList, int pusherListCount );
	int						PhysicsTryMove( float flTime, trace_t *steptrace );

	void					PhysicsCheckVelocity( void );
	void					PhysicsAddHalfGravity( float timestep );
	void					PhysicsAddGravityMove( Vector &move );

	void					CalcAbsoluteVelocity();
	void					CalcAbsoluteAngularVelocity();

	// Checks a sweep without actually performing the move
	void					PhysicsCheckSweep( const Vector& vecAbsStart, const Vector &vecAbsDelta, trace_t *pTrace );

	// Computes new angles based on the angular velocity
	void					SimulateAngles( float flFrameTime );

	void					CheckStepSimulationChanged();
	// Run regular think and latch off angle/origin changes so we can interpolate them on the server to fake simulation
	void					StepSimulationThink( float dt );

	// Compute network origin
private:
	void					ComputeStepSimulationNetwork( StepSimulationData *step );

public:
	bool					UseStepSimulationNetworkOrigin( const Vector **out_v );
	bool					UseStepSimulationNetworkAngles( const QAngle **out_a );

public:
	// Add a discontinuity to a step
	bool					AddStepDiscontinuity( float flTime, const Vector &vecOrigin, const QAngle &vecAngles );
	int						GetFirstThinkTick();	// get first tick thinking on any context
private:
	// origin and angles to use in step calculations
	virtual	Vector			GetStepOrigin( void ) const;
	virtual	QAngle			GetStepAngles( void ) const;
	
	// These set entity flags (EFL_*) to help optimize queries
	void					CheckHasThinkFunction( bool isThinkingHint = false );
	void					CheckHasGamePhysicsSimulation();
	bool					WillThink();
	bool					WillSimulateGamePhysics();

	friend class CPushBlockerEnum;

	// Sets/Gets the next think based on context index
	void SetNextThink( int nContextIndex, float thinkTime );
	void SetLastThink( int nContextIndex, float thinkTime );
	float GetNextThink( int nContextIndex ) const;
	int	GetNextThinkTick( int nContextIndex ) const;

	// Shot statistics
	void UpdateShotStatistics( const trace_t &tr );

	// Handle shot entering water
	bool HandleShotImpactingWater( const FireBulletsInfo_t &info, const Vector &vecEnd, ITraceFilter *pTraceFilter, Vector *pVecTracerDest );

	// Handle shot entering water
	void HandleShotImpactingGlass( const FireBulletsInfo_t &info, const trace_t &tr, const Vector &vecDir, ITraceFilter *pTraceFilter );

	// Should we draw bubbles underwater?
	bool ShouldDrawUnderwaterBulletBubbles();

	// Computes the tracer start position
	void ComputeTracerStartPosition( const Vector &vecShotSrc, Vector *pVecTracerStart );

	// Computes the tracer start position
	void CreateBubbleTrailTracer( const Vector &vecShotSrc, const Vector &vecShotEnd, const Vector &vecShotDir );

	virtual bool ShouldDrawWaterImpacts() { return true; }

	// Changes shadow cast distance over time
	void ShadowCastDistThink( );

	// Precache model sounds + particles
	static void PrecacheModelComponents( int nModelIndex );
	static void PrecacheSoundHelper( const char *pName );

protected:
	// Which frame did I simulate?
	int						m_nSimulationTick;

	// FIXME: Make this private! Still too many references to do so...
	CNetworkVar( int, m_spawnflags );

private:
	int		m_iEFlags;	// entity flags EFL_*
	// was pev->flags
	CNetworkVarForDerived( int, m_fFlags );

	string_t m_iName;	// name used to identify this entity

	// Damage modifiers
	friend class CDamageModifier;
	CUtlLinkedList<CDamageModifier*,int>	m_DamageModifiers;

	EHANDLE m_pParent;  // for movement hierarchy
	byte	m_nTransmitStateOwnedCounter;
	CNetworkVar( unsigned char,  m_iParentAttachment ); // 0 if we're relative to the parent's absorigin and absangles.
	CNetworkVar( unsigned char, m_MoveType );		// One of the MOVETYPE_ defines.
	CNetworkVar( unsigned char, m_MoveCollide );

	// Our immediate parent in the movement hierarchy.
	// FIXME: clarify m_pParent vs. m_pMoveParent
	CNetworkHandle( CBaseEntity, m_hMoveParent );
	// cached child list
	EHANDLE m_hMoveChild;	
	// generated from m_pMoveParent
	EHANDLE m_hMovePeer;	

	friend class CCollisionProperty;
	friend class CServerNetworkProperty;
	CNetworkVarEmbedded( CCollisionProperty, m_Collision );

	CNetworkHandle( CBaseEntity, m_hOwnerEntity );	// only used to point to an edict it won't collide with
	CNetworkHandle( CBaseEntity, m_hEffectEntity );	// Fire/Dissolve entity.

	CNetworkVar( int, m_CollisionGroup );		// used to cull collision tests
	IPhysicsObject	*m_pPhysicsObject;	// pointer to the entity's physics object (vphysics.dll)

	CNetworkVar( float, m_flShadowCastDistance );
	float		m_flDesiredShadowCastDistance;

	// Team handling
	int			m_iInitialTeamNum;		// Team number of this entity's team read from file
	CNetworkVar( int, m_iTeamNum );				// Team number of this entity's team. 

	// Sets water type + level for physics objects
	unsigned char	m_nWaterTouch;
	unsigned char	m_nSlimeTouch;
	unsigned char	m_nWaterType;
	CNetworkVarForDerived( unsigned char, m_nWaterLevel );
	float			m_flNavIgnoreUntilTime;

	CNetworkHandleForDerived( CBaseEntity, m_hGroundEntity );
	float			m_flGroundChangeTime; // Time that the ground entity changed
	
	string_t		m_ModelName;

	// Velocity of the thing we're standing on (world space)
	CNetworkVarForDerived( Vector, m_vecBaseVelocity );

	// Global velocity
	Vector			m_vecAbsVelocity;

	// Local angular velocity
	QAngle			m_vecAngVelocity;

	// Global angular velocity
//	QAngle			m_vecAbsAngVelocity;

	// local coordinate frame of entity
	matrix3x4_t		m_rgflCoordinateFrame;

	// Physics state
	EHANDLE			m_pBlocker;

	// was pev->gravity;
	float			m_flGravity;  // rename to m_flGravityScale;
	// was pev->friction
	CNetworkVarForDerived( float, m_flFriction );
	CNetworkVar( float, m_flElasticity );

	// was pev->ltime
	float			m_flLocalTime;
	// local time at the beginning of this frame
	float			m_flVPhysicsUpdateLocalTime;
	// local time the movement has ended
	float			m_flMoveDoneTime;

	// A counter to help quickly build a list of potentially pushed objects for physics
	int				m_nPushEnumCount;

	Vector			m_vecAbsOrigin;
	CNetworkVectorForDerived( m_vecVelocity );
	
	//Adrian
	CNetworkVar( unsigned char, m_iTextureFrameIndex );
	
	CNetworkVar( bool, m_bSimulatedEveryTick );
	CNetworkVar( bool, m_bAnimatedEveryTick );
	CNetworkVar( bool, m_bAlternateSorting );

	// User outputs. Fired when the "FireInputX" input is triggered.
	COutputEvent m_OnUser1;
	COutputEvent m_OnUser2;
	COutputEvent m_OnUser3;
	COutputEvent m_OnUser4;

	QAngle			m_angAbsRotation;

	CNetworkVector( m_vecOrigin );
	CNetworkQAngle( m_angRotation );
	CBaseHandle m_RefEHandle;

	// was pev->view_ofs ( FIXME:  Move somewhere up the hierarch, CBaseAnimating, etc. )
	CNetworkVectorForDerived( m_vecViewOffset );

private:
	// dynamic model state tracking
	bool m_bDynamicModelAllowed;
	bool m_bDynamicModelPending;
	bool m_bDynamicModelSetBounds;
	void OnModelLoadComplete( const model_t* model );
	friend class CBaseEntityModelLoadProxy;

protected:
	void EnableDynamicModels() { m_bDynamicModelAllowed = true; }

public:
	bool IsDynamicModelLoading() const { return m_bDynamicModelPending; } 
	void SetCollisionBoundsFromModel();

#if !defined( NO_ENTITY_PREDICTION )
	CNetworkVar( bool, m_bIsPlayerSimulated );
	// Player who is driving my simulation
	CHandle< CBasePlayer >			m_hPlayerSimulationOwner;
#endif

	int								m_fDataObjectTypes;

	// So it can get at the physics methods
	friend class CCollisionEvent;

// Methods shared by client and server
public:
	void							SetSize( const Vector &vecMin, const Vector &vecMax ); // UTIL_SetSize( this, mins, maxs );
	static int						PrecacheModel( const char *name, bool bPreload = true ); 
	static bool						PrecacheSound( const char *name );
	static void						PrefetchSound( const char *name );
	void							Remove( ); // UTIL_Remove( this );

private:

	// This is a random seed used by the networking code to allow client - side prediction code
	//  randon number generators to spit out the same random numbers on both sides for a particular
	//  usercmd input.
	static int						m_nPredictionRandomSeed;
	static int						m_nPredictionRandomSeedServer;
	static CBasePlayer				*m_pPredictionPlayer;

	// FIXME: Make hierarchy a member of CBaseEntity
	// or a contained private class...
	friend void UnlinkChild( CBaseEntity *pParent, CBaseEntity *pChild );
	friend void LinkChild( CBaseEntity *pParent, CBaseEntity *pChild );
	friend void ClearParent( CBaseEntity *pEntity );
	friend void UnlinkAllChildren( CBaseEntity *pParent );
	friend void UnlinkFromParent( CBaseEntity *pRemove );
	friend void TransferChildren( CBaseEntity *pOldParent, CBaseEntity *pNewParent );
	
public:
	// Accessors for above
	static int						GetPredictionRandomSeed( bool bUseUnSyncedServerPlatTime = false );
	static void						SetPredictionRandomSeed( const CUserCmd *cmd );
	static CBasePlayer				*GetPredictionPlayer( void );
	static void						SetPredictionPlayer( CBasePlayer *player );


	// For debugging shared code
	static bool						IsServer( void )
	{
		return true;
	}

	static bool						IsClient( void )
	{
		return false;
	}

	static char const				*GetDLLType( void )
	{
		return "server";
	}
	
	// Used to access m_vecAbsOrigin during restore when it's unsafe to call GetAbsOrigin.
	friend class CPlayerRestoreHelper;
	
	static bool s_bAbsQueriesValid;

	// Call this when hierarchy is not completely set up (such as during Restore) to throw asserts
	// when people call GetAbsAnything. 
	static inline void SetAbsQueriesValid( bool bValid )
	{
		s_bAbsQueriesValid = bValid;
	}
	
	static inline bool IsAbsQueriesValid()
	{
		return s_bAbsQueriesValid;
	}

	virtual bool ShouldBlockNav() const { return true; }
};

// Send tables exposed in this module.
EXTERN_SEND_TABLE(DT_Edict);
EXTERN_SEND_TABLE(DT_BaseEntity);

baseentity.cpp

BEGIN_SIMPLE_DATADESC( thinkfunc_t )

	DEFINE_FIELD( m_iszContext,	FIELD_STRING ),
	// DEFINE_FIELD( m_pfnThink,		FIELD_FUNCTION ),		// Manually written
	DEFINE_FIELD( m_nNextThinkTick,	FIELD_TICK	),
	DEFINE_FIELD( m_nLastThinkTick,	FIELD_TICK	),

END_DATADESC()

BEGIN_SIMPLE_DATADESC( ResponseContext_t )

	DEFINE_FIELD( m_iszName,			FIELD_STRING ),
	DEFINE_FIELD( m_iszValue,			FIELD_STRING ),
	DEFINE_FIELD( m_fExpirationTime,	FIELD_TIME ),

END_DATADESC()

BEGIN_DATADESC_NO_BASE( CBaseEntity )

	DEFINE_KEYFIELD( m_iClassname, FIELD_STRING, "classname" ),
	DEFINE_GLOBAL_KEYFIELD( m_iGlobalname, FIELD_STRING, "globalname" ),
	DEFINE_KEYFIELD( m_iParent, FIELD_STRING, "parentname" ),

	DEFINE_KEYFIELD( m_iHammerID, FIELD_INTEGER, "hammerid" ), // save ID numbers so that entities can be tracked between save/restore and vmf

	DEFINE_KEYFIELD( m_flSpeed, FIELD_FLOAT, "speed" ),
	DEFINE_KEYFIELD( m_nRenderFX, FIELD_CHARACTER, "renderfx" ),
	DEFINE_KEYFIELD( m_nRenderMode, FIELD_CHARACTER, "rendermode" ),

	// Consider moving to CBaseAnimating?
	DEFINE_FIELD( m_flPrevAnimTime, FIELD_TIME ),
	DEFINE_FIELD( m_flAnimTime, FIELD_TIME ),
	DEFINE_FIELD( m_flSimulationTime, FIELD_TIME ),
	DEFINE_FIELD( m_nLastThinkTick, FIELD_TICK ),

	DEFINE_KEYFIELD( m_nNextThinkTick, FIELD_TICK, "nextthink" ),
	DEFINE_KEYFIELD( m_fEffects, FIELD_INTEGER, "effects" ),
	DEFINE_KEYFIELD( m_clrRender, FIELD_COLOR32, "rendercolor" ),
	DEFINE_GLOBAL_KEYFIELD( m_nModelIndex, FIELD_SHORT, "modelindex" ),
#if !defined( NO_ENTITY_PREDICTION )
	// DEFINE_FIELD( m_PredictableID, CPredictableId ),
#endif
	DEFINE_FIELD( touchStamp, FIELD_INTEGER ),
	DEFINE_CUSTOM_FIELD( m_aThinkFunctions, thinkcontextFuncs ),
	//								m_iCurrentThinkContext (not saved, debug field only, and think transient to boot)

	DEFINE_UTLVECTOR(m_ResponseContexts,		FIELD_EMBEDDED),
	DEFINE_KEYFIELD( m_iszResponseContext, FIELD_STRING, "ResponseContext" ),

	DEFINE_FIELD( m_pfnThink, FIELD_FUNCTION ),
	DEFINE_FIELD( m_pfnTouch, FIELD_FUNCTION ),
	DEFINE_FIELD( m_pfnUse, FIELD_FUNCTION ),
	DEFINE_FIELD( m_pfnBlocked, FIELD_FUNCTION ),
	DEFINE_FIELD( m_pfnMoveDone, FIELD_FUNCTION ),

	DEFINE_FIELD( m_lifeState, FIELD_CHARACTER ),
	DEFINE_FIELD( m_takedamage, FIELD_CHARACTER ),
	DEFINE_KEYFIELD( m_iMaxHealth, FIELD_INTEGER, "max_health" ),
	DEFINE_KEYFIELD( m_iHealth, FIELD_INTEGER, "health" ),
	// DEFINE_FIELD( m_pLink, FIELD_CLASSPTR ),
	DEFINE_KEYFIELD( m_target, FIELD_STRING, "target" ),

	DEFINE_KEYFIELD( m_iszDamageFilterName, FIELD_STRING, "damagefilter" ),
	DEFINE_FIELD( m_hDamageFilter, FIELD_EHANDLE ),
	
	DEFINE_FIELD( m_debugOverlays, FIELD_INTEGER ),

	DEFINE_GLOBAL_FIELD( m_pParent, FIELD_EHANDLE ),
	DEFINE_FIELD( m_iParentAttachment, FIELD_CHARACTER ),
	DEFINE_GLOBAL_FIELD( m_hMoveParent, FIELD_EHANDLE ),
	DEFINE_GLOBAL_FIELD( m_hMoveChild, FIELD_EHANDLE ),
	DEFINE_GLOBAL_FIELD( m_hMovePeer, FIELD_EHANDLE ),
	
	DEFINE_FIELD( m_iEFlags, FIELD_INTEGER ),

	DEFINE_FIELD( m_iName, FIELD_STRING ),
	DEFINE_EMBEDDED( m_Collision ),
	DEFINE_EMBEDDED( m_Network ),

	DEFINE_FIELD( m_MoveType, FIELD_CHARACTER ),
	DEFINE_FIELD( m_MoveCollide, FIELD_CHARACTER ),
	DEFINE_FIELD( m_hOwnerEntity, FIELD_EHANDLE ),
	DEFINE_FIELD( m_CollisionGroup, FIELD_INTEGER ),
	DEFINE_PHYSPTR( m_pPhysicsObject),
	DEFINE_FIELD( m_flElasticity, FIELD_FLOAT ),
	DEFINE_KEYFIELD( m_flShadowCastDistance, FIELD_FLOAT, "shadowcastdist" ),
	DEFINE_FIELD( m_flDesiredShadowCastDistance, FIELD_FLOAT ),

	DEFINE_INPUT( m_iInitialTeamNum, FIELD_INTEGER, "TeamNum" ),
	DEFINE_FIELD( m_iTeamNum, FIELD_INTEGER ),

//	DEFINE_FIELD( m_bSentLastFrame, FIELD_INTEGER ),

	DEFINE_FIELD( m_hGroundEntity, FIELD_EHANDLE ),
	DEFINE_FIELD( m_flGroundChangeTime, FIELD_TIME ),
	DEFINE_GLOBAL_KEYFIELD( m_ModelName, FIELD_MODELNAME, "model" ),
	
	DEFINE_KEYFIELD( m_vecBaseVelocity, FIELD_VECTOR, "basevelocity" ),
	DEFINE_FIELD( m_vecAbsVelocity, FIELD_VECTOR ),
	DEFINE_KEYFIELD( m_vecAngVelocity, FIELD_VECTOR, "avelocity" ),
//	DEFINE_FIELD( m_vecAbsAngVelocity, FIELD_VECTOR ),
	DEFINE_ARRAY( m_rgflCoordinateFrame, FIELD_FLOAT, 12 ), // NOTE: MUST BE IN LOCAL SPACE, NOT POSITION_VECTOR!!! (see CBaseEntity::Restore)

	DEFINE_KEYFIELD( m_nWaterLevel, FIELD_CHARACTER, "waterlevel" ),
	DEFINE_FIELD( m_nWaterType, FIELD_CHARACTER ),
	DEFINE_FIELD( m_pBlocker, FIELD_EHANDLE ),

	DEFINE_KEYFIELD( m_flGravity, FIELD_FLOAT, "gravity" ),
	DEFINE_KEYFIELD( m_flFriction, FIELD_FLOAT, "friction" ),

	// Local time is local to each object.  It doesn't need to be re-based if the clock
	// changes.  Therefore it is saved as a FIELD_FLOAT, not a FIELD_TIME
	DEFINE_KEYFIELD( m_flLocalTime, FIELD_FLOAT, "ltime" ),
	DEFINE_FIELD( m_flVPhysicsUpdateLocalTime, FIELD_FLOAT ),
	DEFINE_FIELD( m_flMoveDoneTime, FIELD_FLOAT ),

//	DEFINE_FIELD( m_nPushEnumCount, FIELD_INTEGER ),

	DEFINE_FIELD( m_vecAbsOrigin, FIELD_POSITION_VECTOR ),
	DEFINE_KEYFIELD( m_vecVelocity, FIELD_VECTOR, "velocity" ),
	DEFINE_KEYFIELD( m_iTextureFrameIndex, FIELD_CHARACTER, "texframeindex" ),
	DEFINE_FIELD( m_bSimulatedEveryTick, FIELD_BOOLEAN ),
	DEFINE_FIELD( m_bAnimatedEveryTick, FIELD_BOOLEAN ),
	DEFINE_FIELD( m_bAlternateSorting, FIELD_BOOLEAN ),
	DEFINE_KEYFIELD( m_spawnflags, FIELD_INTEGER, "spawnflags" ),
	DEFINE_FIELD( m_nTransmitStateOwnedCounter, FIELD_CHARACTER ),
	DEFINE_FIELD( m_angAbsRotation, FIELD_VECTOR ),
	DEFINE_FIELD( m_vecOrigin, FIELD_VECTOR ),			// NOTE: MUST BE IN LOCAL SPACE, NOT POSITION_VECTOR!!! (see CBaseEntity::Restore)
	DEFINE_FIELD( m_angRotation, FIELD_VECTOR ),

	DEFINE_KEYFIELD( m_vecViewOffset, FIELD_VECTOR, "view_ofs" ),

	DEFINE_FIELD( m_fFlags, FIELD_INTEGER ),
#if !defined( NO_ENTITY_PREDICTION )
//	DEFINE_FIELD( m_bIsPlayerSimulated, FIELD_INTEGER ),
//	DEFINE_FIELD( m_hPlayerSimulationOwner, FIELD_EHANDLE ),
#endif
	// DEFINE_FIELD( m_pTimedOverlay, TimedOverlay_t* ),
	DEFINE_FIELD( m_nSimulationTick, FIELD_TICK ),
	// DEFINE_FIELD( m_RefEHandle, CBaseHandle ),

//	DEFINE_FIELD( m_nWaterTouch,		FIELD_INTEGER ),
//	DEFINE_FIELD( m_nSlimeTouch,		FIELD_INTEGER ),
	DEFINE_FIELD( m_flNavIgnoreUntilTime,	FIELD_TIME ),

//	DEFINE_FIELD( m_bToolRecording,		FIELD_BOOLEAN ),
//	DEFINE_FIELD( m_ToolHandle,		FIELD_INTEGER ),

	// NOTE: This is tricky. TeamNum must be saved, but we can't directly
	// read it in, because we can only set it after the team entity has been read in,
	// which may or may not actually occur before the entity is parsed.
	// Therefore, we set the TeamNum from the InitialTeamNum in Activate
	DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTeam", InputSetTeam ),

	DEFINE_INPUTFUNC( FIELD_VOID, "Kill", InputKill ),
	DEFINE_INPUTFUNC( FIELD_VOID, "KillHierarchy", InputKillHierarchy ),
	DEFINE_INPUTFUNC( FIELD_VOID, "Use", InputUse ),
	DEFINE_INPUTFUNC( FIELD_INTEGER, "Alpha", InputAlpha ),
	DEFINE_INPUTFUNC( FIELD_BOOLEAN, "AlternativeSorting", InputAlternativeSorting ),
	DEFINE_INPUTFUNC( FIELD_COLOR32, "Color", InputColor ),
	DEFINE_INPUTFUNC( FIELD_STRING, "SetParent", InputSetParent ),
	DEFINE_INPUTFUNC( FIELD_STRING, "SetParentAttachment", InputSetParentAttachment ),
	DEFINE_INPUTFUNC( FIELD_STRING, "SetParentAttachmentMaintainOffset", InputSetParentAttachmentMaintainOffset ),
	DEFINE_INPUTFUNC( FIELD_VOID, "ClearParent", InputClearParent ),
	DEFINE_INPUTFUNC( FIELD_STRING, "SetDamageFilter", InputSetDamageFilter ),

	DEFINE_INPUTFUNC( FIELD_VOID, "EnableDamageForces", InputEnableDamageForces ),
	DEFINE_INPUTFUNC( FIELD_VOID, "DisableDamageForces", InputDisableDamageForces ),

	DEFINE_INPUTFUNC( FIELD_STRING, "DispatchEffect", InputDispatchEffect ),
	DEFINE_INPUTFUNC( FIELD_STRING, "DispatchResponse", InputDispatchResponse ),

	// Entity I/O methods to alter context
	DEFINE_INPUTFUNC( FIELD_STRING, "AddContext", InputAddContext ),
	DEFINE_INPUTFUNC( FIELD_STRING, "RemoveContext", InputRemoveContext ),
	DEFINE_INPUTFUNC( FIELD_STRING, "ClearContext", InputClearContext ),

	DEFINE_INPUTFUNC( FIELD_VOID, "DisableShadow", InputDisableShadow ),
	DEFINE_INPUTFUNC( FIELD_VOID, "EnableShadow", InputEnableShadow ),

	DEFINE_INPUTFUNC( FIELD_STRING, "AddOutput", InputAddOutput ),

	DEFINE_INPUTFUNC( FIELD_STRING, "FireUser1", InputFireUser1 ),
	DEFINE_INPUTFUNC( FIELD_STRING, "FireUser2", InputFireUser2 ),
	DEFINE_INPUTFUNC( FIELD_STRING, "FireUser3", InputFireUser3 ),
	DEFINE_INPUTFUNC( FIELD_STRING, "FireUser4", InputFireUser4 ),

	DEFINE_OUTPUT( m_OnUser1, "OnUser1" ),
	DEFINE_OUTPUT( m_OnUser2, "OnUser2" ),
	DEFINE_OUTPUT( m_OnUser3, "OnUser3" ),
	DEFINE_OUTPUT( m_OnUser4, "OnUser4" ),

	// Function Pointers
	DEFINE_FUNCTION( SUB_Remove ),
	DEFINE_FUNCTION( SUB_DoNothing ),
	DEFINE_FUNCTION( SUB_StartFadeOut ),
	DEFINE_FUNCTION( SUB_StartFadeOutInstant ),
	DEFINE_FUNCTION( SUB_FadeOut ),
	DEFINE_FUNCTION( SUB_Vanish ),
	DEFINE_FUNCTION( SUB_CallUseToggle ),
	DEFINE_THINKFUNC( ShadowCastDistThink ),

	DEFINE_FIELD( m_hEffectEntity, FIELD_EHANDLE ),

	//DEFINE_FIELD( m_DamageModifiers, FIELD_?? ), // can't save?
	// DEFINE_FIELD( m_fDataObjectTypes, FIELD_INTEGER ),

#ifdef TF_DLL
	DEFINE_ARRAY( m_nModelIndexOverrides, FIELD_INTEGER, MAX_VISION_MODES ),
#endif

END_DATADESC()

// This table encodes the CBaseEntity data.
IMPLEMENT_SERVERCLASS_ST_NOBASE( CBaseEntity, DT_BaseEntity )
	SendPropDataTable( "AnimTimeMustBeFirst", 0, &REFERENCE_SEND_TABLE(DT_AnimTimeMustBeFirst), SendProxy_ClientSideAnimation ),
	SendPropInt			(SENDINFO(m_flSimulationTime),	SIMULATION_TIME_WINDOW_BITS, SPROP_UNSIGNED|SPROP_CHANGES_OFTEN|SPROP_ENCODED_AGAINST_TICKCOUNT, SendProxy_SimulationTime),

#if PREDICTION_ERROR_CHECK_LEVEL > 1 
	SendPropVector	(SENDINFO(m_vecOrigin), -1,  SPROP_NOSCALE|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ),
#else
	SendPropVector	(SENDINFO(m_vecOrigin), -1,  SPROP_COORD|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ),
#endif

	SendPropInt		(SENDINFO( m_ubInterpolationFrame ), NOINTERP_PARITY_MAX_BITS, SPROP_UNSIGNED ),
	SendPropModelIndex(SENDINFO(m_nModelIndex)),
	SendPropDataTable( SENDINFO_DT( m_Collision ), &REFERENCE_SEND_TABLE(DT_CollisionProperty) ),
	SendPropInt		(SENDINFO(m_nRenderFX),		8, SPROP_UNSIGNED ),
	SendPropInt		(SENDINFO(m_nRenderMode),	8, SPROP_UNSIGNED ),
	SendPropInt		(SENDINFO(m_fEffects),		EF_MAX_BITS, SPROP_UNSIGNED),
	SendPropInt		(SENDINFO(m_clrRender),	32, SPROP_UNSIGNED),
	SendPropInt		(SENDINFO(m_iTeamNum),		TEAMNUM_NUM_BITS, 0),
	SendPropInt		(SENDINFO(m_CollisionGroup), 5, SPROP_UNSIGNED),
	SendPropFloat	(SENDINFO(m_flElasticity), 0, SPROP_COORD),
	SendPropFloat	(SENDINFO(m_flShadowCastDistance), 12, SPROP_UNSIGNED ),
	SendPropEHandle (SENDINFO(m_hOwnerEntity)),
	SendPropEHandle (SENDINFO(m_hEffectEntity)),
	SendPropEHandle (SENDINFO_NAME(m_hMoveParent, moveparent)),
	SendPropInt		(SENDINFO(m_iParentAttachment), NUM_PARENTATTACHMENT_BITS, SPROP_UNSIGNED),

	SendPropInt		(SENDINFO_NAME( m_MoveType, movetype ), MOVETYPE_MAX_BITS, SPROP_UNSIGNED ),
	SendPropInt		(SENDINFO_NAME( m_MoveCollide, movecollide ), MOVECOLLIDE_MAX_BITS, SPROP_UNSIGNED ),
#if PREDICTION_ERROR_CHECK_LEVEL > 1 
	SendPropVector	(SENDINFO(m_angRotation), -1, SPROP_NOSCALE|SPROP_CHANGES_OFTEN, 0, HIGH_DEFAULT, SendProxy_Angles ),
#else
	SendPropQAngles	(SENDINFO(m_angRotation), 13, SPROP_CHANGES_OFTEN, SendProxy_Angles ),
#endif

	SendPropInt		( SENDINFO( m_iTextureFrameIndex ),		8, SPROP_UNSIGNED ),

#if !defined( NO_ENTITY_PREDICTION )
	SendPropDataTable( "predictable_id", 0, &REFERENCE_SEND_TABLE( DT_PredictableId ), SendProxy_SendPredictableId ),
#endif

	// FIXME: Collapse into another flag field?
	SendPropInt		(SENDINFO(m_bSimulatedEveryTick),		1, SPROP_UNSIGNED ),
	SendPropInt		(SENDINFO(m_bAnimatedEveryTick),		1, SPROP_UNSIGNED ),
	SendPropBool( SENDINFO( m_bAlternateSorting )),

#ifdef TF_DLL
	SendPropArray3( SENDINFO_ARRAY3(m_nModelIndexOverrides), SendPropInt( SENDINFO_ARRAY(m_nModelIndexOverrides), SP_MODEL_INDEX_BITS, 0 ) ),
#endif

END_SEND_TABLE()

BEGIN_SEND_TABLE_NOBASE( CBaseEntity, DT_AnimTimeMustBeFirst )
	// NOTE:  Animtime must be sent before origin and angles ( from pev ) because it has a 
	//  proxy on the client that stores off the old values before writing in the new values and
	//  if it is sent after the new values, then it will only have the new origin and studio model, etc.
	//  interpolation will be busted
	SendPropInt	(SENDINFO(m_flAnimTime), 8, SPROP_UNSIGNED|SPROP_CHANGES_OFTEN|SPROP_ENCODED_AGAINST_TICKCOUNT, SendProxy_AnimTime),
END_SEND_TABLE()

#if !defined( NO_ENTITY_PREDICTION )
BEGIN_SEND_TABLE_NOBASE( CBaseEntity, DT_PredictableId )
	SendPropPredictableId( SENDINFO( m_PredictableID ) ),
	SendPropInt( SENDINFO( m_bIsPlayerSimulated ), 1, SPROP_UNSIGNED ),
END_SEND_TABLE()

Clientside

c_baseentity.h

c_baseentity.cpp