aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/baseentity.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/game/server/baseentity.h
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/server/baseentity.h')
-rw-r--r--mp/src/game/server/baseentity.h2671
1 files changed, 2671 insertions, 0 deletions
diff --git a/mp/src/game/server/baseentity.h b/mp/src/game/server/baseentity.h
new file mode 100644
index 00000000..26d81804
--- /dev/null
+++ b/mp/src/game/server/baseentity.h
@@ -0,0 +1,2671 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef BASEENTITY_H
+#define BASEENTITY_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#define TEAMNUM_NUM_BITS 6
+
+#include "entitylist.h"
+#include "entityoutput.h"
+#include "networkvar.h"
+#include "collisionproperty.h"
+#include "ServerNetworkProperty.h"
+#include "shareddefs.h"
+#include "engine/ivmodelinfo.h"
+
+class CDamageModifier;
+class CDmgAccumulator;
+
+struct CSoundParameters;
+
+class AI_CriteriaSet;
+class IResponseSystem;
+class IEntitySaveUtils;
+class CRecipientFilter;
+class CStudioHdr;
+
+// Matching the high level concept is significantly better than other criteria
+// FIXME: Could do this in the script file by making it required and bumping up weighting there instead...
+#define CONCEPT_WEIGHT 5.0f
+
+typedef CHandle<CBaseEntity> EHANDLE;
+
+#define MANUALMODE_GETSET_PROP(type, accessorName, varName) \
+ private:\
+ type varName;\
+ public:\
+ inline const type& Get##accessorName##() const { return varName; } \
+ inline type& Get##accessorName##() { return varName; } \
+ inline void Set##accessorName##( const type &val ) { varName = val; m_NetStateMgr.StateChanged(); }
+
+#define MANUALMODE_GETSET_EHANDLE(type, accessorName, varName) \
+ private:\
+ CHandle<type> varName;\
+ public:\
+ inline type* Get##accessorName##() { return varName.Get(); } \
+ inline void Set##accessorName##( type *pType ) { varName = pType; m_NetStateMgr.StateChanged(); }
+
+
+// saverestore.h declarations
+class CSaveRestoreData;
+struct typedescription_t;
+class ISave;
+class IRestore;
+class CBaseEntity;
+class CEntityMapData;
+class CBaseCombatWeapon;
+class IPhysicsObject;
+class IPhysicsShadowController;
+class CBaseCombatCharacter;
+class CTeam;
+class Vector;
+struct gamevcollisionevent_t;
+class CBaseAnimating;
+class CBasePlayer;
+class IServerVehicle;
+struct solid_t;
+struct notify_system_event_params_t;
+class CAI_BaseNPC;
+class CAI_Senses;
+class CSquadNPC;
+class variant_t;
+class CEventAction;
+typedef struct KeyValueData_s KeyValueData;
+class CUserCmd;
+class CSkyCamera;
+class CEntityMapData;
+class INextBot;
+
+
+typedef CUtlVector< CBaseEntity* > EntityList_t;
+
+#if defined( HL2_DLL )
+
+// For CLASSIFY
+enum Class_T
+{
+ CLASS_NONE=0,
+ CLASS_PLAYER,
+ CLASS_PLAYER_ALLY,
+ CLASS_PLAYER_ALLY_VITAL,
+ CLASS_ANTLION,
+ CLASS_BARNACLE,
+ CLASS_BULLSEYE,
+ //CLASS_BULLSQUID,
+ CLASS_CITIZEN_PASSIVE,
+ CLASS_CITIZEN_REBEL,
+ CLASS_COMBINE,
+ CLASS_COMBINE_GUNSHIP,
+ CLASS_CONSCRIPT,
+ CLASS_HEADCRAB,
+ //CLASS_HOUNDEYE,
+ CLASS_MANHACK,
+ CLASS_METROPOLICE,
+ CLASS_MILITARY,
+ CLASS_SCANNER,
+ CLASS_STALKER,
+ CLASS_VORTIGAUNT,
+ CLASS_ZOMBIE,
+ CLASS_PROTOSNIPER,
+ CLASS_MISSILE,
+ CLASS_FLARE,
+ CLASS_EARTH_FAUNA,
+ CLASS_HACKED_ROLLERMINE,
+ CLASS_COMBINE_HUNTER,
+
+ NUM_AI_CLASSES
+};
+
+#elif defined( HL1_DLL )
+
+enum Class_T
+{
+ CLASS_NONE = 0,
+ CLASS_MACHINE,
+ CLASS_PLAYER,
+ CLASS_HUMAN_PASSIVE,
+ CLASS_HUMAN_MILITARY,
+ CLASS_ALIEN_MILITARY,
+ CLASS_ALIEN_MONSTER,
+ CLASS_ALIEN_PREY,
+ CLASS_ALIEN_PREDATOR,
+ CLASS_INSECT,
+ CLASS_PLAYER_ALLY,
+ CLASS_PLAYER_BIOWEAPON,
+ CLASS_ALIEN_BIOWEAPON,
+
+ NUM_AI_CLASSES
+};
+
+#elif defined( INVASION_DLL )
+
+enum Class_T
+{
+ CLASS_NONE = 0,
+ CLASS_PLAYER,
+ CLASS_PLAYER_ALLY,
+ CLASS_PLAYER_ALLY_VITAL,
+ CLASS_ANTLION,
+ CLASS_BARNACLE,
+ CLASS_BULLSEYE,
+ //CLASS_BULLSQUID,
+ CLASS_CITIZEN_PASSIVE,
+ CLASS_CITIZEN_REBEL,
+ CLASS_COMBINE,
+ CLASS_COMBINE_GUNSHIP,
+ CLASS_CONSCRIPT,
+ CLASS_HEADCRAB,
+ //CLASS_HOUNDEYE,
+ CLASS_MANHACK,
+ CLASS_METROPOLICE,
+ CLASS_MILITARY,
+ CLASS_SCANNER,
+ CLASS_STALKER,
+ CLASS_VORTIGAUNT,
+ CLASS_ZOMBIE,
+ CLASS_PROTOSNIPER,
+ CLASS_MISSILE,
+ CLASS_FLARE,
+ CLASS_EARTH_FAUNA,
+ NUM_AI_CLASSES
+};
+
+#elif defined( CSTRIKE_DLL )
+
+enum Class_T
+{
+ CLASS_NONE = 0,
+ CLASS_PLAYER,
+ CLASS_PLAYER_ALLY,
+ NUM_AI_CLASSES
+};
+
+#else
+
+enum Class_T
+{
+ CLASS_NONE = 0,
+ CLASS_PLAYER,
+ CLASS_PLAYER_ALLY,
+ NUM_AI_CLASSES
+};
+
+#endif
+
+//
+// Structure passed to input handlers.
+//
+struct inputdata_t
+{
+ CBaseEntity *pActivator; // The entity that initially caused this chain of output events.
+ CBaseEntity *pCaller; // The entity that fired this particular output.
+ variant_t value; // The data parameter for this output.
+ int nOutputID; // The unique ID of the output that was fired.
+};
+
+// Serializable list of context as set by entity i/o and used for deducing proper
+// speech state, et al.
+struct ResponseContext_t
+{
+ DECLARE_SIMPLE_DATADESC();
+
+ string_t m_iszName;
+ string_t m_iszValue;
+ float m_fExpirationTime; // when to expire context (0 == never)
+};
+
+
+//-----------------------------------------------------------------------------
+// Entity events... targetted to a particular entity
+// Each event has a well defined structure to use for parameters
+//-----------------------------------------------------------------------------
+enum EntityEvent_t
+{
+ ENTITY_EVENT_WATER_TOUCH = 0, // No data needed
+ ENTITY_EVENT_WATER_UNTOUCH, // No data needed
+ ENTITY_EVENT_PARENT_CHANGED, // No data needed
+};
+
+
+//-----------------------------------------------------------------------------
+
+typedef void (CBaseEntity::*BASEPTR)(void);
+typedef void (CBaseEntity::*ENTITYFUNCPTR)(CBaseEntity *pOther );
+typedef void (CBaseEntity::*USEPTR)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
+
+#define DEFINE_THINKFUNC( function ) DEFINE_FUNCTION_RAW( function, BASEPTR )
+#define DEFINE_ENTITYFUNC( function ) DEFINE_FUNCTION_RAW( function, ENTITYFUNCPTR )
+#define DEFINE_USEFUNC( function ) DEFINE_FUNCTION_RAW( function, USEPTR )
+
+// Things that toggle (buttons/triggers/doors) need this
+enum TOGGLE_STATE
+{
+ TS_AT_TOP,
+ TS_AT_BOTTOM,
+ TS_GOING_UP,
+ TS_GOING_DOWN
+};
+
+
+// Debug overlay bits
+enum DebugOverlayBits_t
+{
+ OVERLAY_TEXT_BIT = 0x00000001, // show text debug overlay for this entity
+ OVERLAY_NAME_BIT = 0x00000002, // show name debug overlay for this entity
+ OVERLAY_BBOX_BIT = 0x00000004, // show bounding box overlay for this entity
+ OVERLAY_PIVOT_BIT = 0x00000008, // show pivot for this entity
+ OVERLAY_MESSAGE_BIT = 0x00000010, // show messages for this entity
+ OVERLAY_ABSBOX_BIT = 0x00000020, // show abs bounding box overlay
+ OVERLAY_RBOX_BIT = 0x00000040, // show the rbox overlay
+ OVERLAY_SHOW_BLOCKSLOS = 0x00000080, // show entities that block NPC LOS
+ OVERLAY_ATTACHMENTS_BIT = 0x00000100, // show attachment points
+ OVERLAY_AUTOAIM_BIT = 0x00000200, // Display autoaim radius
+
+ OVERLAY_NPC_SELECTED_BIT = 0x00001000, // the npc is current selected
+ OVERLAY_NPC_NEAREST_BIT = 0x00002000, // show the nearest node of this npc
+ OVERLAY_NPC_ROUTE_BIT = 0x00004000, // draw the route for this npc
+ OVERLAY_NPC_TRIANGULATE_BIT = 0x00008000, // draw the triangulation for this npc
+ OVERLAY_NPC_ZAP_BIT = 0x00010000, // destroy the NPC
+ OVERLAY_NPC_ENEMIES_BIT = 0x00020000, // show npc's enemies
+ OVERLAY_NPC_CONDITIONS_BIT = 0x00040000, // show NPC's current conditions
+ OVERLAY_NPC_SQUAD_BIT = 0x00080000, // show npc squads
+ OVERLAY_NPC_TASK_BIT = 0x00100000, // show npc task details
+ OVERLAY_NPC_FOCUS_BIT = 0x00200000, // show line to npc's enemy and target
+ OVERLAY_NPC_VIEWCONE_BIT = 0x00400000, // show npc's viewcone
+ OVERLAY_NPC_KILL_BIT = 0x00800000, // kill the NPC, running all appropriate AI.
+
+ OVERLAY_WC_CHANGE_ENTITY = 0x01000000, // object changed during WC edit
+ OVERLAY_BUDDHA_MODE = 0x02000000, // take damage but don't die
+
+ OVERLAY_NPC_STEERING_REGULATIONS = 0x04000000, // Show the steering regulations associated with the NPC
+
+ OVERLAY_TASK_TEXT_BIT = 0x08000000, // show task and schedule names when they start
+
+ OVERLAY_PROP_DEBUG = 0x10000000,
+
+ OVERLAY_NPC_RELATION_BIT = 0x20000000, // show relationships between target and all children
+
+ OVERLAY_VIEWOFFSET = 0x40000000, // show view offset
+};
+
+struct TimedOverlay_t;
+
+/* ========= CBaseEntity ========
+
+ All objects in the game are derived from this.
+
+a list of all CBaseEntitys is kept in gEntList
+================================ */
+
+// creates an entity by string name, but does not spawn it
+// If iForceEdictIndex is not -1, then it will use the edict by that index. If the index is
+// invalid or there is already an edict using that index, it will error out.
+CBaseEntity *CreateEntityByName( const char *className, int iForceEdictIndex = -1 );
+CBaseNetworkable *CreateNetworkableByName( const char *className );
+
+// creates an entity and calls all the necessary spawn functions
+extern void SpawnEntityByName( const char *className, CEntityMapData *mapData = NULL );
+
+// calls the spawn functions for an entity
+extern int DispatchSpawn( CBaseEntity *pEntity );
+
+inline CBaseEntity *GetContainingEntity( edict_t *pent );
+
+//-----------------------------------------------------------------------------
+// Purpose: think contexts
+//-----------------------------------------------------------------------------
+struct thinkfunc_t
+{
+ BASEPTR m_pfnThink;
+ string_t m_iszContext;
+ int m_nNextThinkTick;
+ int m_nLastThinkTick;
+
+ DECLARE_SIMPLE_DATADESC();
+};
+
+struct EmitSound_t;
+struct rotatingpushmove_t;
+
+#define CREATE_PREDICTED_ENTITY( className ) \
+ CBaseEntity::CreatePredictedEntityByName( className, __FILE__, __LINE__ );
+
+//
+// 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_MODEL_INDEX_OVERRIDES ); // 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.
+ void 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 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; }
+
+ // Ugly code to lookup all functions to make sure they are in the table when set.
+#ifdef _DEBUG
+ void FunctionCheck( void *pFunction, const char *name );
+
+ ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name )
+ {
+#ifdef GNUC
+ COMPILE_TIME_ASSERT( sizeof(func) == 8 );
+#else
+ COMPILE_TIME_ASSERT( sizeof(func) == 4 );
+#endif
+ m_pfnTouch = func;
+ FunctionCheck( *(reinterpret_cast<void **>(&m_pfnTouch)), name );
+ return func;
+ }
+ USEPTR UseSet( USEPTR func, char *name )
+ {
+#ifdef GNUC
+ COMPILE_TIME_ASSERT( sizeof(func) == 8 );
+#else
+ COMPILE_TIME_ASSERT( sizeof(func) == 4 );
+#endif
+ m_pfnUse = func;
+ FunctionCheck( *(reinterpret_cast<void **>(&m_pfnUse)), name );
+ return func;
+ }
+ ENTITYFUNCPTR BlockedSet( ENTITYFUNCPTR func, char *name )
+ {
+#ifdef GNUC
+ COMPILE_TIME_ASSERT( sizeof(func) == 8 );
+#else
+ COMPILE_TIME_ASSERT( sizeof(func) == 4 );
+#endif
+ m_pfnBlocked = func;
+ FunctionCheck( *(reinterpret_cast<void **>(&m_pfnBlocked)), name );
+ return func;
+ }
+
+#endif
+ virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set );
+ void AppendContextToCriteria( AI_CriteriaSet& set, const char *prefix = "" );
+ void DumpResponseCriteria( void );
+
+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 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( void );
+ 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;
+ }
+};
+
+// Send tables exposed in this module.
+EXTERN_SEND_TABLE(DT_Edict);
+EXTERN_SEND_TABLE(DT_BaseEntity);
+
+
+
+// Ugly technique to override base member functions
+// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a
+// member function of a base class. static_cast is a sleezy way around that problem.
+
+#ifdef _DEBUG
+
+#define SetTouch( a ) TouchSet( static_cast <void (CBaseEntity::*)(CBaseEntity *)> (a), #a )
+#define SetUse( a ) UseSet( static_cast <void (CBaseEntity::*)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )> (a), #a )
+#define SetBlocked( a ) BlockedSet( static_cast <void (CBaseEntity::*)(CBaseEntity *)> (a), #a )
+
+#else
+
+#define SetTouch( a ) m_pfnTouch = static_cast <void (CBaseEntity::*)(CBaseEntity *)> (a)
+#define SetUse( a ) m_pfnUse = static_cast <void (CBaseEntity::*)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )> (a)
+#define SetBlocked( a ) m_pfnBlocked = static_cast <void (CBaseEntity::*)(CBaseEntity *)> (a)
+
+#endif
+
+// handling entity/edict transforms
+inline CBaseEntity *GetContainingEntity( edict_t *pent )
+{
+ if ( pent && pent->GetUnknown() )
+ {
+ return pent->GetUnknown()->GetBaseEntity();
+ }
+
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Pauses or resumes entity i/o events. When paused, no outputs will
+// fire unless Debug_SetSteps is called with a nonzero step value.
+// Input : bPause - true to pause, false to resume.
+//-----------------------------------------------------------------------------
+inline void CBaseEntity::Debug_Pause(bool bPause)
+{
+ CBaseEntity::m_bDebugPause = bPause;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns true if entity i/o is paused, false if not.
+//-----------------------------------------------------------------------------
+inline bool CBaseEntity::Debug_IsPaused(void)
+{
+ return(CBaseEntity::m_bDebugPause);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Decrements the debug step counter. Used when the entity i/o system
+// is in single step mode, this is called every time an output is fired.
+// Output : Returns true on to continue firing outputs, false to stop.
+//-----------------------------------------------------------------------------
+inline bool CBaseEntity::Debug_Step(void)
+{
+ if (CBaseEntity::m_nDebugSteps > 0)
+ {
+ CBaseEntity::m_nDebugSteps--;
+ }
+ return(CBaseEntity::m_nDebugSteps > 0);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the number of entity outputs to allow to fire before pausing
+// the entity i/o system.
+// Input : nSteps - Number of steps to execute.
+//-----------------------------------------------------------------------------
+inline void CBaseEntity::Debug_SetSteps(int nSteps)
+{
+ CBaseEntity::m_nDebugSteps = nSteps;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns true if we should allow outputs to be fired, false if not.
+//-----------------------------------------------------------------------------
+inline bool CBaseEntity::Debug_ShouldStep(void)
+{
+ return(!CBaseEntity::m_bDebugPause || CBaseEntity::m_nDebugSteps > 0);
+}
+
+//-----------------------------------------------------------------------------
+// Methods relating to traversing hierarchy
+//-----------------------------------------------------------------------------
+inline CBaseEntity *CBaseEntity::GetMoveParent( void )
+{
+ return m_hMoveParent.Get();
+}
+
+inline CBaseEntity *CBaseEntity::FirstMoveChild( void )
+{
+ return m_hMoveChild.Get();
+}
+
+inline CBaseEntity *CBaseEntity::NextMovePeer( void )
+{
+ return m_hMovePeer.Get();
+}
+
+// FIXME: Remove this! There shouldn't be a difference between moveparent + parent
+inline CBaseEntity* CBaseEntity::GetParent()
+{
+ return m_pParent.Get();
+}
+
+inline int CBaseEntity::GetParentAttachment()
+{
+ return m_iParentAttachment;
+}
+
+//-----------------------------------------------------------------------------
+// Inline methods
+//-----------------------------------------------------------------------------
+inline string_t CBaseEntity::GetEntityName()
+{
+ return m_iName;
+}
+
+inline void CBaseEntity::SetName( string_t newName )
+{
+ m_iName = newName;
+}
+
+
+inline bool CBaseEntity::NameMatches( const char *pszNameOrWildcard )
+{
+ if ( IDENT_STRINGS(m_iName, pszNameOrWildcard) )
+ return true;
+ return NameMatchesComplex( pszNameOrWildcard );
+}
+
+inline bool CBaseEntity::NameMatches( string_t nameStr )
+{
+ if ( IDENT_STRINGS(m_iName, nameStr) )
+ return true;
+ return NameMatchesComplex( STRING(nameStr) );
+}
+
+inline bool CBaseEntity::ClassMatches( const char *pszClassOrWildcard )
+{
+ if ( IDENT_STRINGS(m_iClassname, pszClassOrWildcard ) )
+ return true;
+ return ClassMatchesComplex( pszClassOrWildcard );
+}
+
+inline const char* CBaseEntity::GetClassname()
+{
+ return STRING(m_iClassname);
+}
+
+
+inline bool CBaseEntity::ClassMatches( string_t nameStr )
+{
+ if ( IDENT_STRINGS(m_iClassname, nameStr ) )
+ return true;
+ return ClassMatchesComplex( STRING(nameStr) );
+}
+
+inline int CBaseEntity::GetSpawnFlags( void ) const
+{
+ return m_spawnflags;
+}
+
+inline void CBaseEntity::AddSpawnFlags( int nFlags )
+{
+ m_spawnflags |= nFlags;
+}
+inline void CBaseEntity::RemoveSpawnFlags( int nFlags )
+{
+ m_spawnflags &= ~nFlags;
+}
+
+inline void CBaseEntity::ClearSpawnFlags( void )
+{
+ m_spawnflags = 0;
+}
+
+inline bool CBaseEntity::HasSpawnFlags( int nFlags ) const
+{
+ return (m_spawnflags & nFlags) != 0;
+}
+
+//-----------------------------------------------------------------------------
+// checks to see if the entity is marked for deletion
+//-----------------------------------------------------------------------------
+inline bool CBaseEntity::IsMarkedForDeletion( void )
+{
+ return (m_iEFlags & EFL_KILLME);
+}
+
+//-----------------------------------------------------------------------------
+// EFlags
+//-----------------------------------------------------------------------------
+inline int CBaseEntity::GetEFlags() const
+{
+ return m_iEFlags;
+}
+
+inline void CBaseEntity::SetEFlags( int iEFlags )
+{
+ m_iEFlags = iEFlags;
+
+ if ( iEFlags & ( EFL_FORCE_CHECK_TRANSMIT | EFL_IN_SKYBOX ) )
+ {
+ DispatchUpdateTransmitState();
+ }
+}
+
+inline void CBaseEntity::AddEFlags( int nEFlagMask )
+{
+ m_iEFlags |= nEFlagMask;
+
+ if ( nEFlagMask & ( EFL_FORCE_CHECK_TRANSMIT | EFL_IN_SKYBOX ) )
+ {
+ DispatchUpdateTransmitState();
+ }
+}
+
+inline void CBaseEntity::RemoveEFlags( int nEFlagMask )
+{
+ m_iEFlags &= ~nEFlagMask;
+
+ if ( nEFlagMask & ( EFL_FORCE_CHECK_TRANSMIT | EFL_IN_SKYBOX ) )
+ DispatchUpdateTransmitState();
+}
+
+inline bool CBaseEntity::IsEFlagSet( int nEFlagMask ) const
+{
+ return (m_iEFlags & nEFlagMask) != 0;
+}
+
+inline void CBaseEntity::SetNavIgnore( float duration )
+{
+ float flNavIgnoreUntilTime = ( duration == FLT_MAX ) ? FLT_MAX : gpGlobals->curtime + duration;
+ if ( flNavIgnoreUntilTime > m_flNavIgnoreUntilTime )
+ m_flNavIgnoreUntilTime = flNavIgnoreUntilTime;
+}
+
+inline void CBaseEntity::ClearNavIgnore()
+{
+ m_flNavIgnoreUntilTime = 0;
+}
+
+inline bool CBaseEntity::IsNavIgnored() const
+{
+ return ( gpGlobals->curtime <= m_flNavIgnoreUntilTime );
+}
+
+inline bool CBaseEntity::GetCheckUntouch() const
+{
+ return IsEFlagSet( EFL_CHECK_UNTOUCH );
+}
+
+//-----------------------------------------------------------------------------
+// Network state optimization
+//-----------------------------------------------------------------------------
+inline CBaseCombatCharacter *ToBaseCombatCharacter( CBaseEntity *pEntity )
+{
+ if ( !pEntity )
+ return NULL;
+
+ return pEntity->MyCombatCharacterPointer();
+}
+
+
+//-----------------------------------------------------------------------------
+// Physics state accessor methods
+//-----------------------------------------------------------------------------
+inline const Vector& CBaseEntity::GetLocalOrigin( void ) const
+{
+ return m_vecOrigin.Get();
+}
+
+inline const QAngle& CBaseEntity::GetLocalAngles( void ) const
+{
+ return m_angRotation.Get();
+}
+
+inline const Vector& CBaseEntity::GetAbsOrigin( void ) const
+{
+ Assert( CBaseEntity::IsAbsQueriesValid() );
+
+ if (IsEFlagSet(EFL_DIRTY_ABSTRANSFORM))
+ {
+ const_cast<CBaseEntity*>(this)->CalcAbsolutePosition();
+ }
+ return m_vecAbsOrigin;
+}
+
+inline const QAngle& CBaseEntity::GetAbsAngles( void ) const
+{
+ Assert( CBaseEntity::IsAbsQueriesValid() );
+
+ if (IsEFlagSet(EFL_DIRTY_ABSTRANSFORM))
+ {
+ const_cast<CBaseEntity*>(this)->CalcAbsolutePosition();
+ }
+ return m_angAbsRotation;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Returns the entity-to-world transform
+//-----------------------------------------------------------------------------
+inline matrix3x4_t &CBaseEntity::EntityToWorldTransform()
+{
+ Assert( CBaseEntity::IsAbsQueriesValid() );
+
+ if (IsEFlagSet(EFL_DIRTY_ABSTRANSFORM))
+ {
+ CalcAbsolutePosition();
+ }
+ return m_rgflCoordinateFrame;
+}
+
+inline const matrix3x4_t &CBaseEntity::EntityToWorldTransform() const
+{
+ Assert( CBaseEntity::IsAbsQueriesValid() );
+
+ if (IsEFlagSet(EFL_DIRTY_ABSTRANSFORM))
+ {
+ const_cast<CBaseEntity*>(this)->CalcAbsolutePosition();
+ }
+ return m_rgflCoordinateFrame;
+}
+
+
+//-----------------------------------------------------------------------------
+// Some helper methods that transform a point from entity space to world space + back
+//-----------------------------------------------------------------------------
+inline void CBaseEntity::EntityToWorldSpace( const Vector &in, Vector *pOut ) const
+{
+ if ( GetAbsAngles() == vec3_angle )
+ {
+ VectorAdd( in, GetAbsOrigin(), *pOut );
+ }
+ else
+ {
+ VectorTransform( in, EntityToWorldTransform(), *pOut );
+ }
+}
+
+inline void CBaseEntity::WorldToEntitySpace( const Vector &in, Vector *pOut ) const
+{
+ if ( GetAbsAngles() == vec3_angle )
+ {
+ VectorSubtract( in, GetAbsOrigin(), *pOut );
+ }
+ else
+ {
+ VectorITransform( in, EntityToWorldTransform(), *pOut );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Velocity
+//-----------------------------------------------------------------------------
+inline Vector CBaseEntity::GetSmoothedVelocity( void )
+{
+ Vector vel;
+ GetVelocity( &vel, NULL );
+ return vel;
+}
+
+inline const Vector &CBaseEntity::GetLocalVelocity( ) const
+{
+ return m_vecVelocity.Get();
+}
+
+inline const Vector &CBaseEntity::GetAbsVelocity( ) const
+{
+ Assert( CBaseEntity::IsAbsQueriesValid() );
+
+ if (IsEFlagSet(EFL_DIRTY_ABSVELOCITY))
+ {
+ const_cast<CBaseEntity*>(this)->CalcAbsoluteVelocity();
+ }
+ return m_vecAbsVelocity;
+}
+
+inline const QAngle &CBaseEntity::GetLocalAngularVelocity( ) const
+{
+ return m_vecAngVelocity;
+}
+
+/*
+// FIXME: While we're using (dPitch, dYaw, dRoll) as our local angular velocity
+// representation, we can't actually solve this problem
+inline const QAngle &CBaseEntity::GetAbsAngularVelocity( ) const
+{
+ if (IsEFlagSet(EFL_DIRTY_ABSANGVELOCITY))
+ {
+ const_cast<CBaseEntity*>(this)->CalcAbsoluteAngularVelocity();
+ }
+
+ return m_vecAbsAngVelocity;
+}
+*/
+
+inline const Vector& CBaseEntity::GetBaseVelocity() const
+{
+ return m_vecBaseVelocity.Get();
+}
+
+inline void CBaseEntity::SetBaseVelocity( const Vector& v )
+{
+ m_vecBaseVelocity = v;
+}
+
+inline float CBaseEntity::GetGravity( void ) const
+{
+ return m_flGravity;
+}
+
+inline void CBaseEntity::SetGravity( float gravity )
+{
+ m_flGravity = gravity;
+}
+
+inline float CBaseEntity::GetFriction( void ) const
+{
+ return m_flFriction;
+}
+
+inline void CBaseEntity::SetFriction( float flFriction )
+{
+ m_flFriction = flFriction;
+}
+
+inline void CBaseEntity::SetElasticity( float flElasticity )
+{
+ m_flElasticity = flElasticity;
+}
+
+inline float CBaseEntity::GetElasticity( void ) const
+{
+ return m_flElasticity;
+}
+
+inline void CBaseEntity::SetShadowCastDistance( float flDistance )
+{
+ m_flShadowCastDistance = flDistance;
+}
+
+inline float CBaseEntity::GetShadowCastDistance( void ) const
+{
+ return m_flShadowCastDistance;
+}
+
+inline float CBaseEntity::GetLocalTime( void ) const
+{
+ return m_flLocalTime;
+}
+
+inline void CBaseEntity::IncrementLocalTime( float flTimeDelta )
+{
+ m_flLocalTime += flTimeDelta;
+}
+
+inline float CBaseEntity::GetMoveDoneTime( ) const
+{
+ return (m_flMoveDoneTime >= 0) ? m_flMoveDoneTime - GetLocalTime() : -1;
+}
+
+inline CBaseEntity *CBaseEntity::Instance( const edict_t *pent )
+{
+ return GetContainingEntity( const_cast<edict_t*>(pent) );
+}
+
+inline CBaseEntity *CBaseEntity::Instance( edict_t *pent )
+{
+ if ( !pent )
+ {
+ pent = INDEXENT(0);
+ }
+ return GetContainingEntity( pent );
+}
+
+inline CBaseEntity* CBaseEntity::Instance( int iEnt )
+{
+ return Instance( INDEXENT( iEnt ) );
+}
+
+inline int CBaseEntity::GetWaterLevel() const
+{
+ return m_nWaterLevel;
+}
+
+inline void CBaseEntity::SetWaterLevel( int nLevel )
+{
+ m_nWaterLevel = nLevel;
+}
+
+inline const color32 CBaseEntity::GetRenderColor() const
+{
+ return m_clrRender.Get();
+}
+
+inline void CBaseEntity::SetRenderColor( byte r, byte g, byte b )
+{
+ m_clrRender.Init( r, g, b );
+}
+
+inline void CBaseEntity::SetRenderColor( byte r, byte g, byte b, byte a )
+{
+ m_clrRender.Init( r, g, b, a );
+}
+
+inline void CBaseEntity::SetRenderColorR( byte r )
+{
+ m_clrRender.SetR( r );
+}
+
+inline void CBaseEntity::SetRenderColorG( byte g )
+{
+ m_clrRender.SetG( g );
+}
+
+inline void CBaseEntity::SetRenderColorB( byte b )
+{
+ m_clrRender.SetB( b );
+}
+
+inline void CBaseEntity::SetRenderColorA( byte a )
+{
+ m_clrRender.SetA( a );
+}
+
+inline void CBaseEntity::SetMoveCollide( MoveCollide_t val )
+{
+ m_MoveCollide = val;
+}
+
+inline bool CBaseEntity::IsTransparent() const
+{
+ return m_nRenderMode != kRenderNormal;
+}
+
+inline int CBaseEntity::GetTextureFrameIndex( void )
+{
+ return m_iTextureFrameIndex;
+}
+
+inline void CBaseEntity::SetTextureFrameIndex( int iIndex )
+{
+ m_iTextureFrameIndex = iIndex;
+}
+
+//-----------------------------------------------------------------------------
+// An inline version the game code can use
+//-----------------------------------------------------------------------------
+inline CCollisionProperty *CBaseEntity::CollisionProp()
+{
+ return &m_Collision;
+}
+
+inline const CCollisionProperty *CBaseEntity::CollisionProp() const
+{
+ return &m_Collision;
+}
+
+inline CServerNetworkProperty *CBaseEntity::NetworkProp()
+{
+ return &m_Network;
+}
+
+inline const CServerNetworkProperty *CBaseEntity::NetworkProp() const
+{
+ return &m_Network;
+}
+
+inline void CBaseEntity::ClearSolidFlags( void )
+{
+ CollisionProp()->ClearSolidFlags();
+}
+
+inline void CBaseEntity::RemoveSolidFlags( int flags )
+{
+ CollisionProp()->RemoveSolidFlags( flags );
+}
+
+inline void CBaseEntity::AddSolidFlags( int flags )
+{
+ CollisionProp()->AddSolidFlags( flags );
+}
+
+inline int CBaseEntity::GetSolidFlags( void ) const
+{
+ return CollisionProp()->GetSolidFlags();
+}
+
+inline bool CBaseEntity::IsSolidFlagSet( int flagMask ) const
+{
+ return CollisionProp()->IsSolidFlagSet( flagMask );
+}
+
+inline bool CBaseEntity::IsSolid() const
+{
+ return CollisionProp()->IsSolid( );
+}
+
+inline void CBaseEntity::SetSolid( SolidType_t val )
+{
+ CollisionProp()->SetSolid( val );
+}
+
+inline void CBaseEntity::SetSolidFlags( int flags )
+{
+ CollisionProp()->SetSolidFlags( flags );
+}
+
+inline SolidType_t CBaseEntity::GetSolid() const
+{
+ return CollisionProp()->GetSolid();
+}
+
+
+//-----------------------------------------------------------------------------
+// Methods related to IServerUnknown
+//-----------------------------------------------------------------------------
+inline ICollideable *CBaseEntity::GetCollideable()
+{
+ return &m_Collision;
+}
+
+inline IServerNetworkable *CBaseEntity::GetNetworkable()
+{
+ return &m_Network;
+}
+
+inline CBaseEntity *CBaseEntity::GetBaseEntity()
+{
+ return this;
+}
+
+
+//-----------------------------------------------------------------------------
+// Model related methods
+//-----------------------------------------------------------------------------
+inline void CBaseEntity::SetModelName( string_t name )
+{
+ m_ModelName = name;
+ DispatchUpdateTransmitState();
+}
+
+inline string_t CBaseEntity::GetModelName( void ) const
+{
+ return m_ModelName;
+}
+
+inline int CBaseEntity::GetModelIndex( void ) const
+{
+ return m_nModelIndex;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Methods relating to bounds
+//-----------------------------------------------------------------------------
+inline const Vector& CBaseEntity::WorldAlignMins( ) const
+{
+ Assert( !CollisionProp()->IsBoundsDefinedInEntitySpace() );
+ Assert( CollisionProp()->GetCollisionAngles() == vec3_angle );
+ return CollisionProp()->OBBMins();
+}
+
+inline const Vector& CBaseEntity::WorldAlignMaxs( ) const
+{
+ Assert( !CollisionProp()->IsBoundsDefinedInEntitySpace() );
+ Assert( CollisionProp()->GetCollisionAngles() == vec3_angle );
+ return CollisionProp()->OBBMaxs();
+}
+
+inline const Vector& CBaseEntity::WorldAlignSize( ) const
+{
+ Assert( !CollisionProp()->IsBoundsDefinedInEntitySpace() );
+ Assert( CollisionProp()->GetCollisionAngles() == vec3_angle );
+ return CollisionProp()->OBBSize();
+}
+
+// Returns a radius of a sphere *centered at the world space center*
+// bounding the collision representation of the entity
+inline float CBaseEntity::BoundingRadius() const
+{
+ return CollisionProp()->BoundingRadius();
+}
+
+inline bool CBaseEntity::IsPointSized() const
+{
+ return CollisionProp()->BoundingRadius() == 0.0f;
+}
+
+inline void CBaseEntity::SetRenderMode( RenderMode_t nRenderMode )
+{
+ m_nRenderMode = nRenderMode;
+}
+
+inline RenderMode_t CBaseEntity::GetRenderMode() const
+{
+ return (RenderMode_t)m_nRenderMode.Get();
+}
+
+
+//-----------------------------------------------------------------------------
+// Methods to cast away const
+//-----------------------------------------------------------------------------
+inline Vector CBaseEntity::EyePosition( void ) const
+{
+ return const_cast<CBaseEntity*>(this)->EyePosition();
+}
+
+inline const QAngle &CBaseEntity::EyeAngles( void ) const // Direction of eyes in world space
+{
+ return const_cast<CBaseEntity*>(this)->EyeAngles();
+}
+
+inline const QAngle &CBaseEntity::LocalEyeAngles( void ) const // Direction of eyes
+{
+ return const_cast<CBaseEntity*>(this)->LocalEyeAngles();
+}
+
+inline Vector CBaseEntity::EarPosition( void ) const // position of ears
+{
+ return const_cast<CBaseEntity*>(this)->EarPosition();
+}
+
+
+//-----------------------------------------------------------------------------
+// Methods relating to networking
+//-----------------------------------------------------------------------------
+inline void CBaseEntity::NetworkStateChanged()
+{
+ NetworkProp()->NetworkStateChanged();
+}
+
+
+inline void CBaseEntity::NetworkStateChanged( void *pVar )
+{
+ // Make sure it's a semi-reasonable pointer.
+ Assert( (char*)pVar > (char*)this );
+ Assert( (char*)pVar - (char*)this < 32768 );
+
+ // Good, they passed an offset so we can track this variable's change
+ // and avoid sending the whole entity.
+ NetworkProp()->NetworkStateChanged( (char*)pVar - (char*)this );
+}
+
+
+//-----------------------------------------------------------------------------
+// IHandleEntity overrides.
+//-----------------------------------------------------------------------------
+inline const CBaseHandle& CBaseEntity::GetRefEHandle() const
+{
+ return m_RefEHandle;
+}
+
+inline void CBaseEntity::IncrementTransmitStateOwnedCounter()
+{
+ Assert( m_nTransmitStateOwnedCounter != 255 );
+ m_nTransmitStateOwnedCounter++;
+}
+
+inline void CBaseEntity::DecrementTransmitStateOwnedCounter()
+{
+ Assert( m_nTransmitStateOwnedCounter != 0 );
+ m_nTransmitStateOwnedCounter--;
+}
+
+
+//-----------------------------------------------------------------------------
+// Bullet firing (legacy)...
+//-----------------------------------------------------------------------------
+inline void CBaseEntity::FireBullets( int cShots, const Vector &vecSrc,
+ const Vector &vecDirShooting, const Vector &vecSpread, float flDistance,
+ int iAmmoType, int iTracerFreq, int firingEntID, int attachmentID,
+ int iDamage, CBaseEntity *pAttacker, bool bFirstShotAccurate, bool bPrimaryAttack )
+{
+ FireBulletsInfo_t info;
+ info.m_iShots = cShots;
+ info.m_vecSrc = vecSrc;
+ info.m_vecDirShooting = vecDirShooting;
+ info.m_vecSpread = vecSpread;
+ info.m_flDistance = flDistance;
+ info.m_iAmmoType = iAmmoType;
+ info.m_iTracerFreq = iTracerFreq;
+ info.m_flDamage = iDamage;
+ info.m_pAttacker = pAttacker;
+ info.m_nFlags = bFirstShotAccurate ? FIRE_BULLETS_FIRST_SHOT_ACCURATE : 0;
+ info.m_bPrimaryAttack = bPrimaryAttack;
+
+ FireBullets( info );
+}
+
+// Ugly technique to override base member functions
+// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a
+// member function of a base class. static_cast is a sleezy way around that problem.
+
+#define SetThink( a ) ThinkSet( static_cast <void (CBaseEntity::*)(void)> (a), 0, NULL )
+#define SetContextThink( a, b, context ) ThinkSet( static_cast <void (CBaseEntity::*)(void)> (a), (b), context )
+
+#ifdef _DEBUG
+#define SetMoveDone( a ) \
+ do \
+ { \
+ m_pfnMoveDone = static_cast <void (CBaseEntity::*)(void)> (a); \
+ FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnMoveDone)))), "BaseMoveFunc" ); \
+ } while ( 0 )
+#else
+#define SetMoveDone( a ) \
+ (void)(m_pfnMoveDone = static_cast <void (CBaseEntity::*)(void)> (a))
+#endif
+
+
+inline bool FClassnameIs(CBaseEntity *pEntity, const char *szClassname)
+{
+ return pEntity->ClassMatches(szClassname);
+}
+
+class CPointEntity : public CBaseEntity
+{
+public:
+ DECLARE_CLASS( CPointEntity, CBaseEntity );
+
+ void Spawn( void );
+ virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
+ virtual bool KeyValue( const char *szKeyName, const char *szValue );
+private:
+};
+
+// Has a position + size
+class CServerOnlyEntity : public CBaseEntity
+{
+ DECLARE_CLASS( CServerOnlyEntity, CBaseEntity );
+public:
+ CServerOnlyEntity() : CBaseEntity( true ) {}
+
+ virtual int ObjectCaps( void ) { return (BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); }
+};
+
+// Has only a position, no size
+class CServerOnlyPointEntity : public CServerOnlyEntity
+{
+ DECLARE_CLASS( CServerOnlyPointEntity, CServerOnlyEntity );
+
+public:
+ virtual bool KeyValue( const char *szKeyName, const char *szValue );
+};
+
+// Has no position or size
+class CLogicalEntity : public CServerOnlyEntity
+{
+ DECLARE_CLASS( CLogicalEntity, CServerOnlyEntity );
+
+public:
+ virtual bool KeyValue( const char *szKeyName, const char *szValue );
+};
+
+
+// Network proxy functions
+
+void SendProxy_Origin( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
+void SendProxy_OriginXY( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
+void SendProxy_OriginZ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID );
+
+
+#endif // BASEENTITY_H