CBaseEntity/definitions
Contents
Serverside
baseentity.h
//-----------------------------------------------------------------------------
// Purpose: think contexts
//-----------------------------------------------------------------------------
struct thinkfunc_t
{
BASEPTR m_pfnThink;
string_t m_iszContext;
int m_nNextThinkTick;
int m_nLastThinkTick;
DECLARE_SIMPLE_DATADESC();
};
//
// Base Entity. All entity types derive from this
//
class CBaseEntity : public IServerEntity
{
public:
DECLARE_CLASS_NOBASE( CBaseEntity );
//----------------------------------------
// Class vars and functions
//----------------------------------------
static inline void Debug_Pause(bool bPause);
static inline bool Debug_IsPaused(void);
static inline void Debug_SetSteps(int nSteps);
static inline bool Debug_ShouldStep(void);
static inline bool Debug_Step(void);
static bool m_bInDebugSelect;
static int m_nDebugPlayer;
protected:
static bool m_bDebugPause; // Whether entity i/o is paused for debugging.
static int m_nDebugSteps; // Number of entity outputs to fire before pausing again.
static bool sm_bDisableTouchFuncs; // Disables PhysicsTouch and PhysicsStartTouch function calls
public:
static bool sm_bAccurateTriggerBboxChecks; // SOLID_BBOX entities do a fully accurate trigger vs bbox check when this is set
public:
// If bServerOnly is true, then the ent never goes to the client. This is used
// by logical entities.
CBaseEntity( bool bServerOnly=false );
virtual ~CBaseEntity();
// prediction system
DECLARE_PREDICTABLE();
// network data
DECLARE_SERVERCLASS();
// data description
DECLARE_DATADESC();
// memory handling
void *operator new( size_t stAllocateBlock );
void *operator new( size_t stAllocateBlock, int nBlockUse, const char *pFileName, int nLine );
void operator delete( void *pMem );
void operator delete( void *pMem, int nBlockUse, const char *pFileName, int nLine ) { operator delete(pMem); }
// Class factory
static CBaseEntity *CreatePredictedEntityByName( const char *classname, const char *module, int line, bool persist = false );
// IHandleEntity overrides.
public:
virtual void SetRefEHandle( const CBaseHandle &handle );
virtual const CBaseHandle& GetRefEHandle() const;
// IServerUnknown overrides
virtual ICollideable *GetCollideable();
virtual IServerNetworkable *GetNetworkable();
virtual CBaseEntity *GetBaseEntity();
// IServerEntity overrides.
public:
virtual void SetModelIndex( int index );
virtual int GetModelIndex( void ) const;
virtual string_t GetModelName( void ) const;
void ClearModelIndexOverrides( void );
virtual void SetModelIndexOverride( int index, int nValue );
public:
// virtual methods for derived classes to override
virtual bool TestCollision( const Ray_t& ray, unsigned int mask, trace_t& trace );
virtual bool TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
virtual void ComputeWorldSpaceSurroundingBox( Vector *pWorldMins, Vector *pWorldMaxs );
// non-virtual methods. Don't override these!
public:
// An inline version the game code can use
CCollisionProperty *CollisionProp();
const CCollisionProperty*CollisionProp() const;
CServerNetworkProperty *NetworkProp();
const CServerNetworkProperty *NetworkProp() const;
bool IsCurrentlyTouching( void ) const;
const Vector& GetAbsOrigin( void ) const;
const QAngle& GetAbsAngles( void ) const;
SolidType_t GetSolid() const;
int GetSolidFlags( void ) const;
int GetEFlags() const;
void SetEFlags( int iEFlags );
void AddEFlags( int nEFlagMask );
void RemoveEFlags( int nEFlagMask );
bool IsEFlagSet( int nEFlagMask ) const;
// Quick way to ask if we have a player entity as a child anywhere in our hierarchy.
void RecalcHasPlayerChildBit();
bool DoesHavePlayerChild();
bool IsTransparent() const;
void SetNavIgnore( float duration = FLT_MAX );
void ClearNavIgnore();
bool IsNavIgnored() const;
// Is the entity floating?
bool IsFloating();
// Called by physics to see if we should avoid a collision test....
virtual bool ShouldCollide( int collisionGroup, int contentsMask ) const;
// Move type / move collide
MoveType_t GetMoveType() const;
MoveCollide_t GetMoveCollide() const;
void SetMoveType( MoveType_t val, MoveCollide_t moveCollide = MOVECOLLIDE_DEFAULT );
void SetMoveCollide( MoveCollide_t val );
// Returns the entity-to-world transform
matrix3x4_t &EntityToWorldTransform();
const matrix3x4_t &EntityToWorldTransform() const;
// Some helper methods that transform a point from entity space to world space + back
void EntityToWorldSpace( const Vector &in, Vector *pOut ) const;
void WorldToEntitySpace( const Vector &in, Vector *pOut ) const;
// This function gets your parent's transform. If you're parented to an attachment,
// this calculates the attachment's transform and gives you that.
//
// You must pass in tempMatrix for scratch space - it may need to fill that in and return it instead of
// pointing you right at a variable in your parent.
matrix3x4_t& GetParentToWorldTransform( matrix3x4_t &tempMatrix );
// Externalized data objects ( see sharreddefs.h for DataObjectType_t )
bool HasDataObjectType( int type ) const;
void AddDataObjectType( int type );
void RemoveDataObjectType( int type );
void *GetDataObject( int type );
void *CreateDataObject( int type );
void DestroyDataObject( int type );
void DestroyAllDataObjects( void );
public:
void SetScaledPhysics( IPhysicsObject *pNewObject );
// virtual methods; you can override these
public:
// Owner entity.
// FIXME: These are virtual only because of CNodeEnt
CBaseEntity *GetOwnerEntity() const;
virtual void SetOwnerEntity( CBaseEntity* pOwner );
void SetEffectEntity( CBaseEntity *pEffectEnt );
CBaseEntity *GetEffectEntity() const;
// Only CBaseEntity implements these. CheckTransmit calls the virtual ShouldTransmit to see if the
// entity wants to be sent. If so, it calls SetTransmit, which will mark any dependents for transmission too.
virtual int ShouldTransmit( const CCheckTransmitInfo *pInfo );
// update the global transmit state if a transmission rule changed
int SetTransmitState( int nFlag);
int GetTransmitState( void );
int DispatchUpdateTransmitState();
// Do NOT call this directly. Use DispatchUpdateTransmitState.
virtual int UpdateTransmitState();
// Entities (like ropes) use this to own the transmit state of another entity
// by forcing it to not call UpdateTransmitState.
void IncrementTransmitStateOwnedCounter();
void DecrementTransmitStateOwnedCounter();
// This marks the entity for transmission and passes the SetTransmit call to any dependents.
virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );
// This function finds out if the entity is in the 3D skybox. If so, it sets the EFL_IN_SKYBOX
// flag so the entity gets transmitted to all the clients.
// Entities usually call this during their Activate().
// Returns true if the entity is in the skybox (and EFL_IN_SKYBOX was set).
bool DetectInSkybox();
// Returns which skybox the entity is in
CSkyCamera *GetEntitySkybox();
bool IsSimulatedEveryTick() const;
bool IsAnimatedEveryTick() const;
void SetSimulatedEveryTick( bool sim );
void SetAnimatedEveryTick( bool anim );
public:
virtual const char *GetTracerType( void );
// returns a pointer to the entities edict, if it has one. should be removed!
inline edict_t *edict( void ) { return NetworkProp()->edict(); }
inline const edict_t *edict( void ) const { return NetworkProp()->edict(); }
inline int entindex( ) const { return m_Network.entindex(); };
inline int GetSoundSourceIndex() const { return entindex(); }
// These methods encapsulate MOVETYPE_FOLLOW, which became obsolete
void FollowEntity( CBaseEntity *pBaseEntity, bool bBoneMerge = true );
void StopFollowingEntity( ); // will also change to MOVETYPE_NONE
bool IsFollowingEntity();
CBaseEntity *GetFollowedEntity();
// initialization
virtual void Spawn( void );
virtual void Precache( void ) {}
virtual void SetModel( const char *szModelName );
protected:
// Notification on model load. May be called multiple times for dynamic models.
// Implementations must call BaseClass::OnNewModel and pass return value through.
virtual CStudioHdr *OnNewModel();
public:
virtual void PostConstructor( const char *szClassname );
virtual void PostClientActive( void );
virtual void ParseMapData( CEntityMapData *mapData );
virtual bool KeyValue( const char *szKeyName, const char *szValue );
virtual bool KeyValue( const char *szKeyName, float flValue );
virtual bool KeyValue( const char *szKeyName, const Vector &vecValue );
virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen );
void ValidateEntityConnections();
void FireNamedOutput( const char *pszOutput, variant_t variant, CBaseEntity *pActivator, CBaseEntity *pCaller, float flDelay = 0.0f );
// Activate - called for each entity after each load game and level load
virtual void Activate( void );
// Hierarchy traversal
CBaseEntity *GetMoveParent( void );
CBaseEntity *GetRootMoveParent();
CBaseEntity *FirstMoveChild( void );
CBaseEntity *NextMovePeer( void );
void SetName( string_t newTarget );
void SetParent( string_t newParent, CBaseEntity *pActivator, int iAttachment = -1 );
// Set the movement parent. Your local origin and angles will become relative to this parent.
// If iAttachment is a valid attachment on the parent, then your local origin and angles
// are relative to the attachment on this entity. If iAttachment == -1, it'll preserve the
// current m_iParentAttachment.
virtual void SetParent( CBaseEntity* pNewParent, int iAttachment = -1 );
CBaseEntity* GetParent();
int GetParentAttachment();
string_t GetEntityName();
bool NameMatches( const char *pszNameOrWildcard );
bool ClassMatches( const char *pszClassOrWildcard );
bool NameMatches( string_t nameStr );
bool ClassMatches( string_t nameStr );
private:
bool NameMatchesComplex( const char *pszNameOrWildcard );
bool ClassMatchesComplex( const char *pszClassOrWildcard );
void TransformStepData_WorldToParent( CBaseEntity *pParent );
void TransformStepData_ParentToParent( CBaseEntity *pOldParent, CBaseEntity *pNewParent );
void TransformStepData_ParentToWorld( CBaseEntity *pParent );
public:
int GetSpawnFlags( void ) const;
void AddSpawnFlags( int nFlags );
void RemoveSpawnFlags( int nFlags );
void ClearSpawnFlags( void );
bool HasSpawnFlags( int nFlags ) const;
int GetEffects( void ) const;
void AddEffects( int nEffects );
void RemoveEffects( int nEffects );
void ClearEffects( void );
void SetEffects( int nEffects );
bool IsEffectActive( int nEffects ) const;
// makes the entity inactive
void MakeDormant( void );
int IsDormant( void );
void RemoveDeferred( void ); // Sets the entity invisible, and makes it remove itself on the next frame
// checks to see if the entity is marked for deletion
bool IsMarkedForDeletion( void );
// capabilities
virtual int ObjectCaps( void );
// Verifies that the data description is valid in debug builds.
#ifdef _DEBUG
void ValidateDataDescription(void);
#endif // _DEBUG
// handles an input (usually caused by outputs)
// returns true if the the value in the pass in should be set, false if the input is to be ignored
virtual bool AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID );
//
// Input handlers.
//
void InputAlternativeSorting( inputdata_t &inputdata );
void InputAlpha( inputdata_t &inputdata );
void InputColor( inputdata_t &inputdata );
void InputSetParent( inputdata_t &inputdata );
void SetParentAttachment( const char *szInputName, const char *szAttachment, bool bMaintainOffset );
void InputSetParentAttachment( inputdata_t &inputdata );
void InputSetParentAttachmentMaintainOffset( inputdata_t &inputdata );
void InputClearParent( inputdata_t &inputdata );
void InputSetTeam( inputdata_t &inputdata );
void InputUse( inputdata_t &inputdata );
void InputKill( inputdata_t &inputdata );
void InputKillHierarchy( inputdata_t &inputdata );
void InputSetDamageFilter( inputdata_t &inputdata );
void InputDispatchEffect( inputdata_t &inputdata );
void InputEnableDamageForces( inputdata_t &inputdata );
void InputDisableDamageForces( inputdata_t &inputdata );
void InputAddContext( inputdata_t &inputdata );
void InputRemoveContext( inputdata_t &inputdata );
void InputClearContext( inputdata_t &inputdata );
void InputDispatchResponse( inputdata_t& inputdata );
void InputDisableShadow( inputdata_t &inputdata );
void InputEnableShadow( inputdata_t &inputdata );
void InputAddOutput( inputdata_t &inputdata );
void InputFireUser1( inputdata_t &inputdata );
void InputFireUser2( inputdata_t &inputdata );
void InputFireUser3( inputdata_t &inputdata );
void InputFireUser4( inputdata_t &inputdata );
// Returns the origin at which to play an inputted dispatcheffect
virtual void GetInputDispatchEffectPosition( const char *sInputString, Vector &pOrigin, QAngle &pAngles );
// tries to read a field from the entities data description - result is placed in variant_t
bool ReadKeyField( const char *varName, variant_t *var );
// classname access
void SetClassname( const char *className );
const char* GetClassname();
// Debug Overlays
void EntityText( int text_offset, const char *text, float flDuration, int r = 255, int g = 255, int b = 255, int a = 255 );
const char *GetDebugName(void); // do not make this virtual -- designed to handle NULL this
virtual void DrawDebugGeometryOverlays(void);
virtual int DrawDebugTextOverlays(void);
void DrawTimedOverlays( void );
void DrawBBoxOverlay( float flDuration = 0.0f );
void DrawAbsBoxOverlay();
void DrawRBoxOverlay();
void DrawInputOverlay(const char *szInputName, CBaseEntity *pCaller, variant_t Value);
void DrawOutputOverlay(CEventAction *ev);
void SendDebugPivotOverlay( void );
void AddTimedOverlay( const char *msg, int endTime );
void SetSolid( SolidType_t val );
// save/restore
// only overload these if you have special data to serialize
virtual int Save( ISave &save );
virtual int Restore( IRestore &restore );
virtual bool ShouldSavePhysics();
// handler to reset stuff before you are restored
// NOTE: Always chain to base class when implementing this!
virtual void OnSave( IEntitySaveUtils *pSaveUtils );
// handler to reset stuff after you are restored
// called after all entities have been loaded from all affected levels
// called before activate
// NOTE: Always chain to base class when implementing this!
virtual void OnRestore();
int GetTextureFrameIndex( void );
void SetTextureFrameIndex( int iIndex );
// Entities block Line-Of-Sight for NPCs by default.
// Set this to false if you want to change this behavior.
void SetBlocksLOS( bool bBlocksLOS );
bool BlocksLOS( void );
void SetAIWalkable( bool bBlocksLOS );
bool IsAIWalkable( void );
private:
int SaveDataDescBlock( ISave &save, datamap_t *dmap );
int RestoreDataDescBlock( IRestore &restore, datamap_t *dmap );
public:
// Networking related methods
void NetworkStateChanged();
void NetworkStateChanged( void *pVar );
public:
void CalcAbsolutePosition();
// returns the edict index the entity requires when used in save/restore (eg players, world)
// -1 means it doesn't require any special index
virtual int RequiredEdictIndex( void ) { return -1; }
// interface function pts
void (CBaseEntity::*m_pfnMoveDone)(void);
virtual void MoveDone( void ) { if (m_pfnMoveDone) (this->*m_pfnMoveDone)();};
// Why do we have two separate static Instance functions?
static CBaseEntity *Instance( const CBaseHandle &hEnt );
static CBaseEntity *Instance( const edict_t *pent );
static CBaseEntity *Instance( edict_t *pent );
static CBaseEntity* Instance( int iEnt );
// Think function handling
void (CBaseEntity::*m_pfnThink)(void);
virtual void Think( void ) { if (m_pfnThink) (this->*m_pfnThink)();};
// Think functions with contexts
int RegisterThinkContext( const char *szContext );
BASEPTR ThinkSet( BASEPTR func, float flNextThinkTime = 0, const char *szContext = NULL );
void SetNextThink( float nextThinkTime, const char *szContext = NULL );
float GetNextThink( const char *szContext = NULL );
float GetLastThink( const char *szContext = NULL );
int GetNextThinkTick( const char *szContext = NULL );
int GetLastThinkTick( const char *szContext = NULL );
float GetAnimTime() const;
void SetAnimTime( float at );
float GetSimulationTime() const;
void SetSimulationTime( float st );
void SetRenderMode( RenderMode_t nRenderMode );
RenderMode_t GetRenderMode() const;
private:
// NOTE: Keep this near vtable so it's in cache with vtable.
CServerNetworkProperty m_Network;
public:
// members
string_t m_iClassname; // identifier for entity creation and save/restore
string_t m_iGlobalname; // identifier for carrying entity across level transitions
string_t m_iParent; // the name of the entities parent; linked into m_pParent during Activate()
int m_iHammerID; // Hammer unique edit id number
public:
// was pev->speed
float m_flSpeed;
// was pev->renderfx
CNetworkVar( unsigned char, m_nRenderFX );
// was pev->rendermode
CNetworkVar( unsigned char, m_nRenderMode );
CNetworkVar( short, m_nModelIndex );
#ifdef TF_DLL
CNetworkArray( int, m_nModelIndexOverrides, MAX_VISION_MODES ); // used to override the base model index on the client if necessary
#endif
// was pev->rendercolor
CNetworkColor32( m_clrRender );
const color32 GetRenderColor() const;
void SetRenderColor( byte r, byte g, byte b );
void SetRenderColor( byte r, byte g, byte b, byte a );
void SetRenderColorR( byte r );
void SetRenderColorG( byte g );
void SetRenderColorB( byte b );
void SetRenderColorA( byte a );
// was pev->animtime: consider moving to CBaseAnimating
float m_flPrevAnimTime;
CNetworkVar( float, m_flAnimTime ); // this is the point in time that the client will interpolate to position,angle,frame,etc.
CNetworkVar( float, m_flSimulationTime );
void IncrementInterpolationFrame(); // Call this to cause a discontinuity (teleport)
CNetworkVar( int, m_ubInterpolationFrame );
int m_nLastThinkTick;
#if !defined( NO_ENTITY_PREDICTION )
// Certain entities (projectiles) can be created on the client and thus need a matching id number
CNetworkVar( CPredictableId, m_PredictableID );
#endif
// used so we know when things are no longer touching
int touchStamp;
protected:
// think function handling
enum thinkmethods_t
{
THINK_FIRE_ALL_FUNCTIONS,
THINK_FIRE_BASE_ONLY,
THINK_FIRE_ALL_BUT_BASE,
};
int GetIndexForThinkContext( const char *pszContext );
CUtlVector< thinkfunc_t > m_aThinkFunctions;
#ifdef _DEBUG
int m_iCurrentThinkContext;
#endif
void RemoveExpiredConcepts( void );
int GetContextCount() const; // Call RemoveExpiredConcepts to clean out expired concepts
const char *GetContextName( int index ) const; // note: context may be expired
const char *GetContextValue( int index ) const; // note: context may be expired
bool ContextExpired( int index ) const;
int FindContextByName( const char *name ) const;
public:
void AddContext( const char *nameandvalue );
protected:
CUtlVector< ResponseContext_t > m_ResponseContexts;
// Map defined context sets
string_t m_iszResponseContext;
private:
CBaseEntity( CBaseEntity& );
// list handling
friend class CGlobalEntityList;
friend class CThinkSyncTester;
// was pev->nextthink
CNetworkVarForDerived( int, m_nNextThinkTick );
// was pev->effects
CNetworkVar( int, m_fEffects );
////////////////////////////////////////////////////////////////////////////
public:
// Returns a CBaseAnimating if the entity is derived from CBaseAnimating.
virtual CBaseAnimating* GetBaseAnimating() { return 0; }
virtual IResponseSystem *GetResponseSystem();
virtual void DispatchResponse( const char *conceptName );
// Classify - returns the type of group (i.e, "houndeye", or "human military" so that NPCs with different classnames
// still realize that they are teammates. (overridden for NPCs that form groups)
virtual Class_T Classify ( void );
virtual void DeathNotice ( CBaseEntity *pVictim ) {}// NPC maker children use this to tell the NPC maker that they have died.
virtual bool ShouldAttractAutoAim( CBaseEntity *pAimingEnt ) { return ((GetFlags() & FL_AIMTARGET) != 0); }
virtual float GetAutoAimRadius();
virtual Vector GetAutoAimCenter() { return WorldSpaceCenter(); }
virtual ITraceFilter* GetBeamTraceFilter( void );
// Call this to do a TraceAttack on an entity, performs filtering. Don't call TraceAttack() directly except when chaining up to base class
void DispatchTraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator = NULL );
virtual bool PassesDamageFilter( const CTakeDamageInfo &info );
protected:
virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator = NULL );
public:
virtual bool CanBeHitByMeleeAttack( CBaseEntity *pAttacker ) { return true; }
// returns the amount of damage inflicted
virtual int OnTakeDamage( const CTakeDamageInfo &info );
// This is what you should call to apply damage to an entity.
int TakeDamage( const CTakeDamageInfo &info );
virtual void AdjustDamageDirection( const CTakeDamageInfo &info, Vector &dir, CBaseEntity *pEnt ) {}
virtual int TakeHealth( float flHealth, int bitsDamageType );
virtual bool IsAlive( void );
// Entity killed (only fired once)
virtual void Event_Killed( const CTakeDamageInfo &info );
void SendOnKilledGameEvent( const CTakeDamageInfo &info );
// Notifier that I've killed some other entity. (called from Victim's Event_Killed).
virtual void Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) { return; }
// UNDONE: Make this data?
virtual int BloodColor( void );
void TraceBleed( float flDamage, const Vector &vecDir, trace_t *ptr, int bitsDamageType );
virtual bool IsTriggered( CBaseEntity *pActivator ) {return true;}
virtual bool IsNPC( void ) const { return false; }
CAI_BaseNPC *MyNPCPointer( void );
virtual CBaseCombatCharacter *MyCombatCharacterPointer( void ) { return NULL; }
virtual INextBot *MyNextBotPointer( void ) { return NULL; }
virtual float GetDelay( void ) { return 0; }
virtual bool IsMoving( void );
bool IsWorld() { return entindex() == 0; }
virtual char const *DamageDecal( int bitsDamageType, int gameMaterial );
virtual void DecalTrace( trace_t *pTrace, char const *decalName );
virtual void ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCustomImpactName = NULL );
void AddPoints( int score, bool bAllowNegativeScore );
void AddPointsToTeam( int score, bool bAllowNegativeScore );
void RemoveAllDecals( void );
virtual bool OnControls( CBaseEntity *pControls ) { return false; }
virtual bool HasTarget( string_t targetname );
virtual bool IsPlayer( void ) const { return false; }
virtual bool IsNetClient( void ) const { return false; }
virtual bool IsTemplate( void ) { return false; }
virtual bool IsBaseObject( void ) const { return false; }
virtual bool IsBaseTrain( void ) const { return false; }
bool IsBSPModel() const;
bool IsCombatCharacter() { return MyCombatCharacterPointer() == NULL ? false : true; }
bool IsInWorld( void ) const;
virtual bool IsCombatItem( void ) const { return false; }
virtual bool IsBaseCombatWeapon( void ) const { return false; }
virtual bool IsWearable( void ) const { return false; }
virtual CBaseCombatWeapon *MyCombatWeaponPointer( void ) { return NULL; }
// If this is a vehicle, returns the vehicle interface
virtual IServerVehicle* GetServerVehicle() { return NULL; }
// UNDONE: Make this data instead of procedural?
virtual bool IsViewable( void ); // is this something that would be looked at (model, sprite, etc.)?
// Team Handling
CTeam *GetTeam( void ) const; // Get the Team this entity is on
int GetTeamNumber( void ) const; // Get the Team number of the team this entity is on
virtual void ChangeTeam( int iTeamNum ); // Assign this entity to a team.
bool IsInTeam( CTeam *pTeam ) const; // Returns true if this entity's in the specified team
bool InSameTeam( CBaseEntity *pEntity ) const; // Returns true if the specified entity is on the same team as this one
bool IsInAnyTeam( void ) const; // Returns true if this entity is in any team
const char *TeamID( void ) const; // Returns the name of the team this entity is on.
// Entity events... these are events targetted to a particular entity
// Each event defines its own well-defined event data structure
virtual void OnEntityEvent( EntityEvent_t event, void *pEventData );
// can stand on this entity?
bool IsStandable() const;
// UNDONE: Do these three functions actually need to be virtual???
virtual bool CanStandOn( CBaseEntity *pSurface ) const { return (pSurface && !pSurface->IsStandable()) ? false : true; }
virtual bool CanStandOn( edict_t *ent ) const { return CanStandOn( GetContainingEntity( ent ) ); }
virtual CBaseEntity *GetEnemy( void ) { return NULL; }
virtual CBaseEntity *GetEnemy( void ) const { return NULL; }
void ViewPunch( const QAngle &angleOffset );
void VelocityPunch( const Vector &vecForce );
CBaseEntity *GetNextTarget( void );
// fundamental callbacks
void (CBaseEntity ::*m_pfnTouch)( CBaseEntity *pOther );
void (CBaseEntity ::*m_pfnUse)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void (CBaseEntity ::*m_pfnBlocked)( CBaseEntity *pOther );
virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual void StartTouch( CBaseEntity *pOther );
virtual void Touch( CBaseEntity *pOther );
virtual void EndTouch( CBaseEntity *pOther );
virtual void StartBlocked( CBaseEntity *pOther ) {}
virtual void Blocked( CBaseEntity *pOther );
virtual void EndBlocked( void ) {}
// Physics simulation
virtual void PhysicsSimulate( void );
public:
// HACKHACK:Get the trace_t from the last physics touch call (replaces the even-hackier global trace vars)
static const trace_t & GetTouchTrace( void );
// FIXME: Should be private, but I can't make em private just yet
void PhysicsImpact( CBaseEntity *other, trace_t &trace );
void PhysicsMarkEntitiesAsTouching( CBaseEntity *other, trace_t &trace );
void PhysicsMarkEntitiesAsTouchingEventDriven( CBaseEntity *other, trace_t &trace );
void PhysicsTouchTriggers( const Vector *pPrevAbsOrigin = NULL );
// Physics helper
static void PhysicsRemoveTouchedList( CBaseEntity *ent );
static void PhysicsNotifyOtherOfUntouch( CBaseEntity *ent, CBaseEntity *other );
static void PhysicsRemoveToucher( CBaseEntity *other, touchlink_t *link );
groundlink_t *AddEntityToGroundList( CBaseEntity *other );
void PhysicsStartGroundContact( CBaseEntity *pentOther );
static void PhysicsNotifyOtherOfGroundRemoval( CBaseEntity *ent, CBaseEntity *other );
static void PhysicsRemoveGround( CBaseEntity *other, groundlink_t *link );
static void PhysicsRemoveGroundList( CBaseEntity *ent );
void StartGroundContact( CBaseEntity *ground );
void EndGroundContact( CBaseEntity *ground );
void SetGroundChangeTime( float flTime );
float GetGroundChangeTime( void );
// Remove this as ground entity for all object resting on this object
void WakeRestingObjects();
bool HasNPCsOnIt();
virtual void UpdateOnRemove( void );
virtual void StopLoopingSounds( void ) {}
// common member functions
void SUB_Remove( void );
void SUB_DoNothing( void );
void SUB_StartFadeOut( float delay = 10.0f, bool bNotSolid = true );
void SUB_StartFadeOutInstant();
void SUB_FadeOut ( void );
void SUB_Vanish( void );
void SUB_CallUseToggle( void ) { this->Use( this, this, USE_TOGGLE, 0 ); }
void SUB_PerformFadeOut( void );
virtual bool SUB_AllowedToFade( void );
// change position, velocity, orientation instantly
// passing NULL means no change
virtual void Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity );
// notify that another entity (that you were watching) was teleported
virtual void NotifySystemEvent( CBaseEntity *pNotify, notify_system_event_t eventType, const notify_system_event_params_t ¶ms );
int ShouldToggle( USE_TYPE useType, int currentState );
// UNDONE: Move these virtuals to CBaseCombatCharacter?
virtual void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType );
virtual int GetTracerAttachment( void );
virtual void FireBullets( const FireBulletsInfo_t &info );
virtual void DoImpactEffect( trace_t &tr, int nDamageType ); // give shooter a chance to do a custom impact.
// OLD VERSION! Use the struct version
void FireBullets( int cShots, const Vector &vecSrc, const Vector &vecDirShooting,
const Vector &vecSpread, float flDistance, int iAmmoType, int iTracerFreq = 4,
int firingEntID = -1, int attachmentID = -1, int iDamage = 0,
CBaseEntity *pAttacker = NULL, bool bFirstShotAccurate = false, bool bPrimaryAttack = true );
virtual void ModifyFireBulletsDamage( CTakeDamageInfo* dmgInfo ) {}
virtual CBaseEntity *Respawn( void ) { return NULL; }
// Method used to deal with attacks passing through triggers
void TraceAttackToTriggers( const CTakeDamageInfo &info, const Vector& start, const Vector& end, const Vector& dir );
// Do the bounding boxes of these two intersect?
bool Intersects( CBaseEntity *pOther );
virtual bool IsLockedByMaster( void ) { return false; }
// Health accessors.
virtual int GetMaxHealth() const { return m_iMaxHealth; }
void SetMaxHealth( int amt ) { m_iMaxHealth = amt; }
int GetHealth() const { return m_iHealth; }
void SetHealth( int amt ) { m_iHealth = amt; }
float HealthFraction() const;
// Ugly code to lookup all functions to make sure they are in the table when set.
#ifdef _DEBUG
#ifdef GNUC
#define ENTITYFUNCPTR_SIZE 8
#else
#define ENTITYFUNCPTR_SIZE 4
#endif
void FunctionCheck( void *pFunction, const char *name );
ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name )
{
COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE );
m_pfnTouch = func;
FunctionCheck( *(reinterpret_cast<void **>(&m_pfnTouch)), name );
return func;
}
USEPTR UseSet( USEPTR func, char *name )
{
COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE );
m_pfnUse = func;
FunctionCheck( *(reinterpret_cast<void **>(&m_pfnUse)), name );
return func;
}
ENTITYFUNCPTR BlockedSet( ENTITYFUNCPTR func, char *name )
{
COMPILE_TIME_ASSERT( sizeof(func) == ENTITYFUNCPTR_SIZE );
m_pfnBlocked = func;
FunctionCheck( *(reinterpret_cast<void **>(&m_pfnBlocked)), name );
return func;
}
#endif // _DEBUG
virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set );
void AppendContextToCriteria( AI_CriteriaSet& set, const char *prefix = "" );
void DumpResponseCriteria( void );
// Return the IHasAttributes interface for this base entity. Removes the need for:
// dynamic_cast< IHasAttributes * >( pEntity );
// Which is remarkably slow.
// GetAttribInterface( CBaseEntity *pEntity ) in attribute_manager.h uses
// this function, tests for NULL, and Asserts m_pAttributes == dynamic_cast.
inline IHasAttributes *GetHasAttributesInterfacePtr() const { return m_pAttributes; }
protected:
// NOTE: m_pAttributes needs to be set in the leaf class constructor.
IHasAttributes *m_pAttributes;
private:
friend class CAI_Senses;
CBaseEntity *m_pLink;// used for temporary link-list operations.
public:
// variables promoted from edict_t
string_t m_target;
CNetworkVarForDerived( int, m_iMaxHealth ); // CBaseEntity doesn't care about changes to this variable, but there are derived classes that do.
CNetworkVarForDerived( int, m_iHealth );
CNetworkVarForDerived( char, m_lifeState );
CNetworkVarForDerived( char , m_takedamage );
// Damage filtering
string_t m_iszDamageFilterName; // The name of the entity to use as our damage filter.
EHANDLE m_hDamageFilter; // The entity that controls who can damage us.
// Debugging / devolopment fields
int m_debugOverlays; // For debug only (bitfields)
TimedOverlay_t* m_pTimedOverlay; // For debug only
// virtual functions used by a few classes
// creates an entity of a specified class, by name
static CBaseEntity *Create( const char *szName, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner = NULL );
static CBaseEntity *CreateNoSpawn( const char *szName, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner = NULL );
// Collision group accessors
int GetCollisionGroup() const;
void SetCollisionGroup( int collisionGroup );
void CollisionRulesChanged();
// Damage accessors
virtual int GetDamageType() const;
virtual float GetDamage() { return 0; }
virtual void SetDamage(float flDamage) {}
virtual Vector EyePosition( void ); // position of eyes
virtual const QAngle &EyeAngles( void ); // Direction of eyes in world space
virtual const QAngle &LocalEyeAngles( void ); // Direction of eyes
virtual Vector EarPosition( void ); // position of ears
Vector EyePosition( void ) const; // position of eyes
const QAngle &EyeAngles( void ) const; // Direction of eyes in world space
const QAngle &LocalEyeAngles( void ) const; // Direction of eyes
Vector EarPosition( void ) const; // position of ears
virtual Vector BodyTarget( const Vector &posSrc, bool bNoisy = true); // position to shoot at
virtual Vector HeadTarget( const Vector &posSrc );
virtual void GetVectors(Vector* forward, Vector* right, Vector* up) const;
virtual const Vector &GetViewOffset() const;
virtual void SetViewOffset( const Vector &v );
// NOTE: Setting the abs velocity in either space will cause a recomputation
// in the other space, so setting the abs velocity will also set the local vel
void SetLocalVelocity( const Vector &vecVelocity );
void ApplyLocalVelocityImpulse( const Vector &vecImpulse );
void SetAbsVelocity( const Vector &vecVelocity );
void ApplyAbsVelocityImpulse( const Vector &vecImpulse );
void ApplyLocalAngularVelocityImpulse( const AngularImpulse &angImpulse );
const Vector& GetLocalVelocity( ) const;
const Vector& GetAbsVelocity( ) const;
// NOTE: Setting the abs velocity in either space will cause a recomputation
// in the other space, so setting the abs velocity will also set the local vel
void SetLocalAngularVelocity( const QAngle &vecAngVelocity );
const QAngle& GetLocalAngularVelocity( ) const;
// FIXME: While we're using (dPitch, dYaw, dRoll) as our local angular velocity
// representation, we can't actually solve this problem
// void SetAbsAngularVelocity( const QAngle &vecAngVelocity );
// const QAngle& GetAbsAngularVelocity( ) const;
const Vector& GetBaseVelocity() const;
void SetBaseVelocity( const Vector& v );
virtual Vector GetSmoothedVelocity( void );
// FIXME: Figure out what to do about this
virtual void GetVelocity(Vector *vVelocity, AngularImpulse *vAngVelocity = NULL);
float GetGravity( void ) const;
void SetGravity( float gravity );
float GetFriction( void ) const;
void SetFriction( float flFriction );
virtual bool FVisible ( CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL );
virtual bool FVisible( const Vector &vecTarget, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL );
virtual bool CanBeSeenBy( CAI_BaseNPC *pNPC ) { return true; } // allows entities to be 'invisible' to NPC senses.
// This function returns a value that scales all damage done by this entity.
// Use CDamageModifier to hook in damage modifiers on a guy.
virtual float GetAttackDamageScale( CBaseEntity *pVictim );
// This returns a value that scales all damage done to this entity
// Use CDamageModifier to hook in damage modifiers on a guy.
virtual float GetReceivedDamageScale( CBaseEntity *pAttacker );
void SetCheckUntouch( bool check );
bool GetCheckUntouch() const;
void SetGroundEntity( CBaseEntity *ground );
CBaseEntity *GetGroundEntity( void );
CBaseEntity *GetGroundEntity( void ) const { return const_cast<CBaseEntity *>(this)->GetGroundEntity(); }
// Gets the velocity we impart to a player standing on us
virtual void GetGroundVelocityToApply( Vector &vecGroundVel ) { vecGroundVel = vec3_origin; }
int GetWaterLevel() const;
void SetWaterLevel( int nLevel );
int GetWaterType() const;
void SetWaterType( int nType );
virtual bool PhysicsSplash( const Vector ¢erPoint, 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 ¶ms );
static float GetSoundDuration( const char *soundname, char const *actormodel );
static bool GetParametersForSound( const char *soundname, CSoundParameters ¶ms, char const *actormodel );
static bool GetParametersForSound( const char *soundname, HSOUNDSCRIPTHANDLE& handle, CSoundParameters ¶ms, char const *actormodel );
static void EmitSound( IRecipientFilter& filter, int iEntIndex, const char *soundname, const Vector *pOrigin = NULL, float soundtime = 0.0f, float *duration = NULL );
static void EmitSound( IRecipientFilter& filter, int iEntIndex, const char *soundname, HSOUNDSCRIPTHANDLE& handle, const Vector *pOrigin = NULL, float soundtime = 0.0f, float *duration = NULL );
static void StopSound( int iEntIndex, const char *soundname );
static soundlevel_t LookupSoundLevel( const char *soundname );
static soundlevel_t LookupSoundLevel( const char *soundname, HSOUNDSCRIPTHANDLE& handle );
static void EmitSound( IRecipientFilter& filter, int iEntIndex, const EmitSound_t & params );
static void EmitSound( IRecipientFilter& filter, int iEntIndex, const EmitSound_t & params, HSOUNDSCRIPTHANDLE& handle );
static void StopSound( int iEntIndex, int iChannel, const char *pSample );
static void EmitAmbientSound( int entindex, const Vector& origin, const char *soundname, int flags = 0, float soundtime = 0.0f, float *duration = NULL );
// These files need to be listed in scripts/game_sounds_manifest.txt
static HSOUNDSCRIPTHANDLE PrecacheScriptSound( const char *soundname );
static void PrefetchScriptSound( const char *soundname );
// For each client who appears to be a valid recipient, checks the client has disabled CC and if so, removes them from
// the recipient list.
static void RemoveRecipientsIfNotCloseCaptioning( CRecipientFilter& filter );
static void EmitCloseCaption( IRecipientFilter& filter, int entindex, char const *token, CUtlVector< Vector >& soundorigins, float duration, bool warnifmissing = false );
static void EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex, int iChannel, int iSentenceIndex,
float flVolume, soundlevel_t iSoundlevel, int iFlags = 0, int iPitch = PITCH_NORM,
const Vector *pOrigin = NULL, const Vector *pDirection = NULL, bool bUpdatePositions = true, float soundtime = 0.0f );
static bool IsPrecacheAllowed();
static void SetAllowPrecache( bool allow );
static bool m_bAllowPrecache;
static bool IsSimulatingOnAlternateTicks();
virtual bool IsDeflectable() { return false; }
virtual void Deflected( CBaseEntity *pDeflectedBy, Vector &vecDir ) {}
// void Relink() {}
public:
// VPHYSICS Integration -----------------------------------------------
//
// --------------------------------------------------------------------
// UNDONE: Move to IEntityVPhysics? or VPhysicsProp() ?
// Called after spawn, and in the case of self-managing objects, after load
virtual bool CreateVPhysics();
// Convenience routines to init the vphysics simulation for this object.
// This creates a static object. Something that behaves like world geometry - solid, but never moves
IPhysicsObject *VPhysicsInitStatic( void );
// This creates a normal vphysics simulated object - physics determines where it goes (gravity, friction, etc)
// and the entity receives updates from vphysics. SetAbsOrigin(), etc do not affect the object!
IPhysicsObject *VPhysicsInitNormal( SolidType_t solidType, int nSolidFlags, bool createAsleep, solid_t *pSolid = NULL );
// This creates a vphysics object with a shadow controller that follows the AI
// Move the object to where it should be and call UpdatePhysicsShadowToCurrentPosition()
IPhysicsObject *VPhysicsInitShadow( bool allowPhysicsMovement, bool allowPhysicsRotation, solid_t *pSolid = NULL );
// Force a non-solid (ie. solid_trigger) physics object to collide with other entities.
virtual bool ForceVPhysicsCollide( CBaseEntity *pEntity ) { return false; }
private:
// called by all vphysics inits
bool VPhysicsInitSetup();
public:
void VPhysicsSetObject( IPhysicsObject *pPhysics );
// destroy and remove the physics object for this entity
virtual void VPhysicsDestroyObject( void );
void VPhysicsSwapObject( IPhysicsObject *pSwap );
inline IPhysicsObject *VPhysicsGetObject( void ) const { return m_pPhysicsObject; }
virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
void VPhysicsUpdatePusher( IPhysicsObject *pPhysics );
// react physically to damage (called from CBaseEntity::OnTakeDamage() by default)
virtual int VPhysicsTakeDamage( const CTakeDamageInfo &info );
virtual void VPhysicsShadowCollision( int index, gamevcollisionevent_t *pEvent );
virtual void VPhysicsShadowUpdate( IPhysicsObject *pPhysics ) {}
virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
virtual void VPhysicsFriction( IPhysicsObject *pObject, float energy, int surfaceProps, int surfacePropsHit );
// update the shadow so it will coincide with the current AI position at some time
// in the future (or 0 for now)
virtual void UpdatePhysicsShadowToCurrentPosition( float deltaTime );
virtual int VPhysicsGetObjectList( IPhysicsObject **pList, int listMax );
virtual bool VPhysicsIsFlesh( void );
// --------------------------------------------------------------------
public:
#if !defined( NO_ENTITY_PREDICTION )
// The player drives simulation of this entity
void SetPlayerSimulated( CBasePlayer *pOwner );
void UnsetPlayerSimulated( void );
bool IsPlayerSimulated( void ) const;
CBasePlayer *GetSimulatingPlayer( void );
#endif
// FIXME: Make these private!
void PhysicsCheckForEntityUntouch( void );
bool PhysicsRunThink( thinkmethods_t thinkMethod = THINK_FIRE_ALL_FUNCTIONS );
bool PhysicsRunSpecificThink( int nContextIndex, BASEPTR thinkFunc );
bool PhysicsTestEntityPosition( CBaseEntity **ppEntity = NULL );
void PhysicsPushEntity( const Vector& push, trace_t *pTrace );
bool PhysicsCheckWater( void );
void PhysicsCheckWaterTransition( void );
void PhysicsStepRecheckGround();
// Computes the water level + type
void UpdateWaterState();
bool IsEdictFree() const { return edict()->IsFree(); }
// Callbacks for the physgun/cannon picking up an entity
virtual CBasePlayer *HasPhysicsAttacker( float dt ) { return NULL; }
// UNDONE: Make this data?
virtual unsigned int PhysicsSolidMaskForEntity( void ) const;
// Computes the abs position of a point specified in local space
void ComputeAbsPosition( const Vector &vecLocalPosition, Vector *pAbsPosition );
// Computes the abs position of a direction specified in local space
void ComputeAbsDirection( const Vector &vecLocalDirection, Vector *pAbsDirection );
void SetPredictionEligible( bool canpredict );
protected:
// Invalidates the abs state of all children
void InvalidatePhysicsRecursive( int nChangeFlags );
int PhysicsClipVelocity (const Vector& in, const Vector& normal, Vector& out, float overbounce );
void PhysicsRelinkChildren( float dt );
// Performs the collision resolution for fliers.
void PerformFlyCollisionResolution( trace_t &trace, Vector &move );
void ResolveFlyCollisionBounce( trace_t &trace, Vector &vecVelocity, float flMinTotalElasticity = 0.0f );
void ResolveFlyCollisionSlide( trace_t &trace, Vector &vecVelocity );
virtual void ResolveFlyCollisionCustom( trace_t &trace, Vector &vecVelocity );
private:
// Physics-related private methods
void PhysicsStep( void );
void PhysicsPusher( void );
void PhysicsNone( void );
void PhysicsNoclip( void );
void PhysicsStepRunTimestep( float timestep );
void PhysicsToss( void );
void PhysicsCustom( void );
void PerformPush( float movetime );
// Simulation in local space of rigid children
void PhysicsRigidChild( void );
// Computes the base velocity
void UpdateBaseVelocity( void );
// Implement this if you use MOVETYPE_CUSTOM
virtual void PerformCustomPhysics( Vector *pNewPosition, Vector *pNewVelocity, QAngle *pNewAngles, QAngle *pNewAngVelocity );
void PhysicsDispatchThink( BASEPTR thinkFunc );
touchlink_t *PhysicsMarkEntityAsTouched( CBaseEntity *other );
void PhysicsTouch( CBaseEntity *pentOther );
void PhysicsStartTouch( CBaseEntity *pentOther );
CBaseEntity *PhysicsPushMove( float movetime );
CBaseEntity *PhysicsPushRotate( float movetime );
CBaseEntity *PhysicsCheckRotateMove( rotatingpushmove_t &rotPushmove, CBaseEntity **pPusherList, int pusherListCount );
CBaseEntity *PhysicsCheckPushMove( const Vector& move, CBaseEntity **pPusherList, int pusherListCount );
int PhysicsTryMove( float flTime, trace_t *steptrace );
void PhysicsCheckVelocity( void );
void PhysicsAddHalfGravity( float timestep );
void PhysicsAddGravityMove( Vector &move );
void CalcAbsoluteVelocity();
void CalcAbsoluteAngularVelocity();
// Checks a sweep without actually performing the move
void PhysicsCheckSweep( const Vector& vecAbsStart, const Vector &vecAbsDelta, trace_t *pTrace );
// Computes new angles based on the angular velocity
void SimulateAngles( float flFrameTime );
void CheckStepSimulationChanged();
// Run regular think and latch off angle/origin changes so we can interpolate them on the server to fake simulation
void StepSimulationThink( float dt );
// Compute network origin
private:
void ComputeStepSimulationNetwork( StepSimulationData *step );
public:
bool UseStepSimulationNetworkOrigin( const Vector **out_v );
bool UseStepSimulationNetworkAngles( const QAngle **out_a );
public:
// Add a discontinuity to a step
bool AddStepDiscontinuity( float flTime, const Vector &vecOrigin, const QAngle &vecAngles );
int GetFirstThinkTick(); // get first tick thinking on any context
private:
// origin and angles to use in step calculations
virtual Vector GetStepOrigin( void ) const;
virtual QAngle GetStepAngles( void ) const;
// These set entity flags (EFL_*) to help optimize queries
void CheckHasThinkFunction( bool isThinkingHint = false );
void CheckHasGamePhysicsSimulation();
bool WillThink();
bool WillSimulateGamePhysics();
friend class CPushBlockerEnum;
// Sets/Gets the next think based on context index
void SetNextThink( int nContextIndex, float thinkTime );
void SetLastThink( int nContextIndex, float thinkTime );
float GetNextThink( int nContextIndex ) const;
int GetNextThinkTick( int nContextIndex ) const;
// Shot statistics
void UpdateShotStatistics( const trace_t &tr );
// Handle shot entering water
bool HandleShotImpactingWater( const FireBulletsInfo_t &info, const Vector &vecEnd, ITraceFilter *pTraceFilter, Vector *pVecTracerDest );
// Handle shot entering water
void HandleShotImpactingGlass( const FireBulletsInfo_t &info, const trace_t &tr, const Vector &vecDir, ITraceFilter *pTraceFilter );
// Should we draw bubbles underwater?
bool ShouldDrawUnderwaterBulletBubbles();
// Computes the tracer start position
void ComputeTracerStartPosition( const Vector &vecShotSrc, Vector *pVecTracerStart );
// Computes the tracer start position
void CreateBubbleTrailTracer( const Vector &vecShotSrc, const Vector &vecShotEnd, const Vector &vecShotDir );
virtual bool ShouldDrawWaterImpacts() { return true; }
// Changes shadow cast distance over time
void ShadowCastDistThink( );
// Precache model sounds + particles
static void PrecacheModelComponents( int nModelIndex );
static void PrecacheSoundHelper( const char *pName );
protected:
// Which frame did I simulate?
int m_nSimulationTick;
// FIXME: Make this private! Still too many references to do so...
CNetworkVar( int, m_spawnflags );
private:
int m_iEFlags; // entity flags EFL_*
// was pev->flags
CNetworkVarForDerived( int, m_fFlags );
string_t m_iName; // name used to identify this entity
// Damage modifiers
friend class CDamageModifier;
CUtlLinkedList<CDamageModifier*,int> m_DamageModifiers;
EHANDLE m_pParent; // for movement hierarchy
byte m_nTransmitStateOwnedCounter;
CNetworkVar( unsigned char, m_iParentAttachment ); // 0 if we're relative to the parent's absorigin and absangles.
CNetworkVar( unsigned char, m_MoveType ); // One of the MOVETYPE_ defines.
CNetworkVar( unsigned char, m_MoveCollide );
// Our immediate parent in the movement hierarchy.
// FIXME: clarify m_pParent vs. m_pMoveParent
CNetworkHandle( CBaseEntity, m_hMoveParent );
// cached child list
EHANDLE m_hMoveChild;
// generated from m_pMoveParent
EHANDLE m_hMovePeer;
friend class CCollisionProperty;
friend class CServerNetworkProperty;
CNetworkVarEmbedded( CCollisionProperty, m_Collision );
CNetworkHandle( CBaseEntity, m_hOwnerEntity ); // only used to point to an edict it won't collide with
CNetworkHandle( CBaseEntity, m_hEffectEntity ); // Fire/Dissolve entity.
CNetworkVar( int, m_CollisionGroup ); // used to cull collision tests
IPhysicsObject *m_pPhysicsObject; // pointer to the entity's physics object (vphysics.dll)
CNetworkVar( float, m_flShadowCastDistance );
float m_flDesiredShadowCastDistance;
// Team handling
int m_iInitialTeamNum; // Team number of this entity's team read from file
CNetworkVar( int, m_iTeamNum ); // Team number of this entity's team.
// Sets water type + level for physics objects
unsigned char m_nWaterTouch;
unsigned char m_nSlimeTouch;
unsigned char m_nWaterType;
CNetworkVarForDerived( unsigned char, m_nWaterLevel );
float m_flNavIgnoreUntilTime;
CNetworkHandleForDerived( CBaseEntity, m_hGroundEntity );
float m_flGroundChangeTime; // Time that the ground entity changed
string_t m_ModelName;
// Velocity of the thing we're standing on (world space)
CNetworkVarForDerived( Vector, m_vecBaseVelocity );
// Global velocity
Vector m_vecAbsVelocity;
// Local angular velocity
QAngle m_vecAngVelocity;
// Global angular velocity
// QAngle m_vecAbsAngVelocity;
// local coordinate frame of entity
matrix3x4_t m_rgflCoordinateFrame;
// Physics state
EHANDLE m_pBlocker;
// was pev->gravity;
float m_flGravity; // rename to m_flGravityScale;
// was pev->friction
CNetworkVarForDerived( float, m_flFriction );
CNetworkVar( float, m_flElasticity );
// was pev->ltime
float m_flLocalTime;
// local time at the beginning of this frame
float m_flVPhysicsUpdateLocalTime;
// local time the movement has ended
float m_flMoveDoneTime;
// A counter to help quickly build a list of potentially pushed objects for physics
int m_nPushEnumCount;
Vector m_vecAbsOrigin;
CNetworkVectorForDerived( m_vecVelocity );
//Adrian
CNetworkVar( unsigned char, m_iTextureFrameIndex );
CNetworkVar( bool, m_bSimulatedEveryTick );
CNetworkVar( bool, m_bAnimatedEveryTick );
CNetworkVar( bool, m_bAlternateSorting );
// User outputs. Fired when the "FireInputX" input is triggered.
COutputEvent m_OnUser1;
COutputEvent m_OnUser2;
COutputEvent m_OnUser3;
COutputEvent m_OnUser4;
QAngle m_angAbsRotation;
CNetworkVector( m_vecOrigin );
CNetworkQAngle( m_angRotation );
CBaseHandle m_RefEHandle;
// was pev->view_ofs ( FIXME: Move somewhere up the hierarch, CBaseAnimating, etc. )
CNetworkVectorForDerived( m_vecViewOffset );
private:
// dynamic model state tracking
bool m_bDynamicModelAllowed;
bool m_bDynamicModelPending;
bool m_bDynamicModelSetBounds;
void OnModelLoadComplete( const model_t* model );
friend class CBaseEntityModelLoadProxy;
protected:
void EnableDynamicModels() { m_bDynamicModelAllowed = true; }
public:
bool IsDynamicModelLoading() const { return m_bDynamicModelPending; }
void SetCollisionBoundsFromModel();
#if !defined( NO_ENTITY_PREDICTION )
CNetworkVar( bool, m_bIsPlayerSimulated );
// Player who is driving my simulation
CHandle< CBasePlayer > m_hPlayerSimulationOwner;
#endif
int m_fDataObjectTypes;
// So it can get at the physics methods
friend class CCollisionEvent;
// Methods shared by client and server
public:
void SetSize( const Vector &vecMin, const Vector &vecMax ); // UTIL_SetSize( this, mins, maxs );
static int PrecacheModel( const char *name, bool bPreload = true );
static bool PrecacheSound( const char *name );
static void PrefetchSound( const char *name );
void Remove( ); // UTIL_Remove( this );
private:
// This is a random seed used by the networking code to allow client - side prediction code
// randon number generators to spit out the same random numbers on both sides for a particular
// usercmd input.
static int m_nPredictionRandomSeed;
static int m_nPredictionRandomSeedServer;
static CBasePlayer *m_pPredictionPlayer;
// FIXME: Make hierarchy a member of CBaseEntity
// or a contained private class...
friend void UnlinkChild( CBaseEntity *pParent, CBaseEntity *pChild );
friend void LinkChild( CBaseEntity *pParent, CBaseEntity *pChild );
friend void ClearParent( CBaseEntity *pEntity );
friend void UnlinkAllChildren( CBaseEntity *pParent );
friend void UnlinkFromParent( CBaseEntity *pRemove );
friend void TransferChildren( CBaseEntity *pOldParent, CBaseEntity *pNewParent );
public:
// Accessors for above
static int GetPredictionRandomSeed( bool bUseUnSyncedServerPlatTime = false );
static void SetPredictionRandomSeed( const CUserCmd *cmd );
static CBasePlayer *GetPredictionPlayer( void );
static void SetPredictionPlayer( CBasePlayer *player );
// For debugging shared code
static bool IsServer( void )
{
return true;
}
static bool IsClient( void )
{
return false;
}
static char const *GetDLLType( void )
{
return "server";
}
// Used to access m_vecAbsOrigin during restore when it's unsafe to call GetAbsOrigin.
friend class CPlayerRestoreHelper;
static bool s_bAbsQueriesValid;
// Call this when hierarchy is not completely set up (such as during Restore) to throw asserts
// when people call GetAbsAnything.
static inline void SetAbsQueriesValid( bool bValid )
{
s_bAbsQueriesValid = bValid;
}
static inline bool IsAbsQueriesValid()
{
return s_bAbsQueriesValid;
}
virtual bool ShouldBlockNav() const { return true; }
};
// Send tables exposed in this module.
EXTERN_SEND_TABLE(DT_Edict);
EXTERN_SEND_TABLE(DT_BaseEntity);
|
baseentity.cpp
BEGIN_SIMPLE_DATADESC( thinkfunc_t )
DEFINE_FIELD( m_iszContext, FIELD_STRING ),
// DEFINE_FIELD( m_pfnThink, FIELD_FUNCTION ), // Manually written
DEFINE_FIELD( m_nNextThinkTick, FIELD_TICK ),
DEFINE_FIELD( m_nLastThinkTick, FIELD_TICK ),
END_DATADESC()
BEGIN_SIMPLE_DATADESC( ResponseContext_t )
DEFINE_FIELD( m_iszName, FIELD_STRING ),
DEFINE_FIELD( m_iszValue, FIELD_STRING ),
DEFINE_FIELD( m_fExpirationTime, FIELD_TIME ),
END_DATADESC()
BEGIN_DATADESC_NO_BASE( CBaseEntity )
DEFINE_KEYFIELD( m_iClassname, FIELD_STRING, "classname" ),
DEFINE_GLOBAL_KEYFIELD( m_iGlobalname, FIELD_STRING, "globalname" ),
DEFINE_KEYFIELD( m_iParent, FIELD_STRING, "parentname" ),
DEFINE_KEYFIELD( m_iHammerID, FIELD_INTEGER, "hammerid" ), // save ID numbers so that entities can be tracked between save/restore and vmf
DEFINE_KEYFIELD( m_flSpeed, FIELD_FLOAT, "speed" ),
DEFINE_KEYFIELD( m_nRenderFX, FIELD_CHARACTER, "renderfx" ),
DEFINE_KEYFIELD( m_nRenderMode, FIELD_CHARACTER, "rendermode" ),
// Consider moving to CBaseAnimating?
DEFINE_FIELD( m_flPrevAnimTime, FIELD_TIME ),
DEFINE_FIELD( m_flAnimTime, FIELD_TIME ),
DEFINE_FIELD( m_flSimulationTime, FIELD_TIME ),
DEFINE_FIELD( m_nLastThinkTick, FIELD_TICK ),
DEFINE_KEYFIELD( m_nNextThinkTick, FIELD_TICK, "nextthink" ),
DEFINE_KEYFIELD( m_fEffects, FIELD_INTEGER, "effects" ),
DEFINE_KEYFIELD( m_clrRender, FIELD_COLOR32, "rendercolor" ),
DEFINE_GLOBAL_KEYFIELD( m_nModelIndex, FIELD_SHORT, "modelindex" ),
#if !defined( NO_ENTITY_PREDICTION )
// DEFINE_FIELD( m_PredictableID, CPredictableId ),
#endif
DEFINE_FIELD( touchStamp, FIELD_INTEGER ),
DEFINE_CUSTOM_FIELD( m_aThinkFunctions, thinkcontextFuncs ),
// m_iCurrentThinkContext (not saved, debug field only, and think transient to boot)
DEFINE_UTLVECTOR(m_ResponseContexts, FIELD_EMBEDDED),
DEFINE_KEYFIELD( m_iszResponseContext, FIELD_STRING, "ResponseContext" ),
DEFINE_FIELD( m_pfnThink, FIELD_FUNCTION ),
DEFINE_FIELD( m_pfnTouch, FIELD_FUNCTION ),
DEFINE_FIELD( m_pfnUse, FIELD_FUNCTION ),
DEFINE_FIELD( m_pfnBlocked, FIELD_FUNCTION ),
DEFINE_FIELD( m_pfnMoveDone, FIELD_FUNCTION ),
DEFINE_FIELD( m_lifeState, FIELD_CHARACTER ),
DEFINE_FIELD( m_takedamage, FIELD_CHARACTER ),
DEFINE_KEYFIELD( m_iMaxHealth, FIELD_INTEGER, "max_health" ),
DEFINE_KEYFIELD( m_iHealth, FIELD_INTEGER, "health" ),
// DEFINE_FIELD( m_pLink, FIELD_CLASSPTR ),
DEFINE_KEYFIELD( m_target, FIELD_STRING, "target" ),
DEFINE_KEYFIELD( m_iszDamageFilterName, FIELD_STRING, "damagefilter" ),
DEFINE_FIELD( m_hDamageFilter, FIELD_EHANDLE ),
DEFINE_FIELD( m_debugOverlays, FIELD_INTEGER ),
DEFINE_GLOBAL_FIELD( m_pParent, FIELD_EHANDLE ),
DEFINE_FIELD( m_iParentAttachment, FIELD_CHARACTER ),
DEFINE_GLOBAL_FIELD( m_hMoveParent, FIELD_EHANDLE ),
DEFINE_GLOBAL_FIELD( m_hMoveChild, FIELD_EHANDLE ),
DEFINE_GLOBAL_FIELD( m_hMovePeer, FIELD_EHANDLE ),
DEFINE_FIELD( m_iEFlags, FIELD_INTEGER ),
DEFINE_FIELD( m_iName, FIELD_STRING ),
DEFINE_EMBEDDED( m_Collision ),
DEFINE_EMBEDDED( m_Network ),
DEFINE_FIELD( m_MoveType, FIELD_CHARACTER ),
DEFINE_FIELD( m_MoveCollide, FIELD_CHARACTER ),
DEFINE_FIELD( m_hOwnerEntity, FIELD_EHANDLE ),
DEFINE_FIELD( m_CollisionGroup, FIELD_INTEGER ),
DEFINE_PHYSPTR( m_pPhysicsObject),
DEFINE_FIELD( m_flElasticity, FIELD_FLOAT ),
DEFINE_KEYFIELD( m_flShadowCastDistance, FIELD_FLOAT, "shadowcastdist" ),
DEFINE_FIELD( m_flDesiredShadowCastDistance, FIELD_FLOAT ),
DEFINE_INPUT( m_iInitialTeamNum, FIELD_INTEGER, "TeamNum" ),
DEFINE_FIELD( m_iTeamNum, FIELD_INTEGER ),
// DEFINE_FIELD( m_bSentLastFrame, FIELD_INTEGER ),
DEFINE_FIELD( m_hGroundEntity, FIELD_EHANDLE ),
DEFINE_FIELD( m_flGroundChangeTime, FIELD_TIME ),
DEFINE_GLOBAL_KEYFIELD( m_ModelName, FIELD_MODELNAME, "model" ),
DEFINE_KEYFIELD( m_vecBaseVelocity, FIELD_VECTOR, "basevelocity" ),
DEFINE_FIELD( m_vecAbsVelocity, FIELD_VECTOR ),
DEFINE_KEYFIELD( m_vecAngVelocity, FIELD_VECTOR, "avelocity" ),
// DEFINE_FIELD( m_vecAbsAngVelocity, FIELD_VECTOR ),
DEFINE_ARRAY( m_rgflCoordinateFrame, FIELD_FLOAT, 12 ), // NOTE: MUST BE IN LOCAL SPACE, NOT POSITION_VECTOR!!! (see CBaseEntity::Restore)
DEFINE_KEYFIELD( m_nWaterLevel, FIELD_CHARACTER, "waterlevel" ),
DEFINE_FIELD( m_nWaterType, FIELD_CHARACTER ),
DEFINE_FIELD( m_pBlocker, FIELD_EHANDLE ),
DEFINE_KEYFIELD( m_flGravity, FIELD_FLOAT, "gravity" ),
DEFINE_KEYFIELD( m_flFriction, FIELD_FLOAT, "friction" ),
// Local time is local to each object. It doesn't need to be re-based if the clock
// changes. Therefore it is saved as a FIELD_FLOAT, not a FIELD_TIME
DEFINE_KEYFIELD( m_flLocalTime, FIELD_FLOAT, "ltime" ),
DEFINE_FIELD( m_flVPhysicsUpdateLocalTime, FIELD_FLOAT ),
DEFINE_FIELD( m_flMoveDoneTime, FIELD_FLOAT ),
// DEFINE_FIELD( m_nPushEnumCount, FIELD_INTEGER ),
DEFINE_FIELD( m_vecAbsOrigin, FIELD_POSITION_VECTOR ),
DEFINE_KEYFIELD( m_vecVelocity, FIELD_VECTOR, "velocity" ),
DEFINE_KEYFIELD( m_iTextureFrameIndex, FIELD_CHARACTER, "texframeindex" ),
DEFINE_FIELD( m_bSimulatedEveryTick, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bAnimatedEveryTick, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bAlternateSorting, FIELD_BOOLEAN ),
DEFINE_KEYFIELD( m_spawnflags, FIELD_INTEGER, "spawnflags" ),
DEFINE_FIELD( m_nTransmitStateOwnedCounter, FIELD_CHARACTER ),
DEFINE_FIELD( m_angAbsRotation, FIELD_VECTOR ),
DEFINE_FIELD( m_vecOrigin, FIELD_VECTOR ), // NOTE: MUST BE IN LOCAL SPACE, NOT POSITION_VECTOR!!! (see CBaseEntity::Restore)
DEFINE_FIELD( m_angRotation, FIELD_VECTOR ),
DEFINE_KEYFIELD( m_vecViewOffset, FIELD_VECTOR, "view_ofs" ),
DEFINE_FIELD( m_fFlags, FIELD_INTEGER ),
#if !defined( NO_ENTITY_PREDICTION )
// DEFINE_FIELD( m_bIsPlayerSimulated, FIELD_INTEGER ),
// DEFINE_FIELD( m_hPlayerSimulationOwner, FIELD_EHANDLE ),
#endif
// DEFINE_FIELD( m_pTimedOverlay, TimedOverlay_t* ),
DEFINE_FIELD( m_nSimulationTick, FIELD_TICK ),
// DEFINE_FIELD( m_RefEHandle, CBaseHandle ),
// DEFINE_FIELD( m_nWaterTouch, FIELD_INTEGER ),
// DEFINE_FIELD( m_nSlimeTouch, FIELD_INTEGER ),
DEFINE_FIELD( m_flNavIgnoreUntilTime, FIELD_TIME ),
// DEFINE_FIELD( m_bToolRecording, FIELD_BOOLEAN ),
// DEFINE_FIELD( m_ToolHandle, FIELD_INTEGER ),
// NOTE: This is tricky. TeamNum must be saved, but we can't directly
// read it in, because we can only set it after the team entity has been read in,
// which may or may not actually occur before the entity is parsed.
// Therefore, we set the TeamNum from the InitialTeamNum in Activate
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTeam", InputSetTeam ),
DEFINE_INPUTFUNC( FIELD_VOID, "Kill", InputKill ),
DEFINE_INPUTFUNC( FIELD_VOID, "KillHierarchy", InputKillHierarchy ),
DEFINE_INPUTFUNC( FIELD_VOID, "Use", InputUse ),
DEFINE_INPUTFUNC( FIELD_INTEGER, "Alpha", InputAlpha ),
DEFINE_INPUTFUNC( FIELD_BOOLEAN, "AlternativeSorting", InputAlternativeSorting ),
DEFINE_INPUTFUNC( FIELD_COLOR32, "Color", InputColor ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetParent", InputSetParent ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetParentAttachment", InputSetParentAttachment ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetParentAttachmentMaintainOffset", InputSetParentAttachmentMaintainOffset ),
DEFINE_INPUTFUNC( FIELD_VOID, "ClearParent", InputClearParent ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetDamageFilter", InputSetDamageFilter ),
DEFINE_INPUTFUNC( FIELD_VOID, "EnableDamageForces", InputEnableDamageForces ),
DEFINE_INPUTFUNC( FIELD_VOID, "DisableDamageForces", InputDisableDamageForces ),
DEFINE_INPUTFUNC( FIELD_STRING, "DispatchEffect", InputDispatchEffect ),
DEFINE_INPUTFUNC( FIELD_STRING, "DispatchResponse", InputDispatchResponse ),
// Entity I/O methods to alter context
DEFINE_INPUTFUNC( FIELD_STRING, "AddContext", InputAddContext ),
DEFINE_INPUTFUNC( FIELD_STRING, "RemoveContext", InputRemoveContext ),
DEFINE_INPUTFUNC( FIELD_STRING, "ClearContext", InputClearContext ),
DEFINE_INPUTFUNC( FIELD_VOID, "DisableShadow", InputDisableShadow ),
DEFINE_INPUTFUNC( FIELD_VOID, "EnableShadow", InputEnableShadow ),
DEFINE_INPUTFUNC( FIELD_STRING, "AddOutput", InputAddOutput ),
DEFINE_INPUTFUNC( FIELD_STRING, "FireUser1", InputFireUser1 ),
DEFINE_INPUTFUNC( FIELD_STRING, "FireUser2", InputFireUser2 ),
DEFINE_INPUTFUNC( FIELD_STRING, "FireUser3", InputFireUser3 ),
DEFINE_INPUTFUNC( FIELD_STRING, "FireUser4", InputFireUser4 ),
DEFINE_OUTPUT( m_OnUser1, "OnUser1" ),
DEFINE_OUTPUT( m_OnUser2, "OnUser2" ),
DEFINE_OUTPUT( m_OnUser3, "OnUser3" ),
DEFINE_OUTPUT( m_OnUser4, "OnUser4" ),
// Function Pointers
DEFINE_FUNCTION( SUB_Remove ),
DEFINE_FUNCTION( SUB_DoNothing ),
DEFINE_FUNCTION( SUB_StartFadeOut ),
DEFINE_FUNCTION( SUB_StartFadeOutInstant ),
DEFINE_FUNCTION( SUB_FadeOut ),
DEFINE_FUNCTION( SUB_Vanish ),
DEFINE_FUNCTION( SUB_CallUseToggle ),
DEFINE_THINKFUNC( ShadowCastDistThink ),
DEFINE_FIELD( m_hEffectEntity, FIELD_EHANDLE ),
//DEFINE_FIELD( m_DamageModifiers, FIELD_?? ), // can't save?
// DEFINE_FIELD( m_fDataObjectTypes, FIELD_INTEGER ),
#ifdef TF_DLL
DEFINE_ARRAY( m_nModelIndexOverrides, FIELD_INTEGER, MAX_VISION_MODES ),
#endif
END_DATADESC()
// This table encodes the CBaseEntity data.
IMPLEMENT_SERVERCLASS_ST_NOBASE( CBaseEntity, DT_BaseEntity )
SendPropDataTable( "AnimTimeMustBeFirst", 0, &REFERENCE_SEND_TABLE(DT_AnimTimeMustBeFirst), SendProxy_ClientSideAnimation ),
SendPropInt (SENDINFO(m_flSimulationTime), SIMULATION_TIME_WINDOW_BITS, SPROP_UNSIGNED|SPROP_CHANGES_OFTEN|SPROP_ENCODED_AGAINST_TICKCOUNT, SendProxy_SimulationTime),
#if PREDICTION_ERROR_CHECK_LEVEL > 1
SendPropVector (SENDINFO(m_vecOrigin), -1, SPROP_NOSCALE|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ),
#else
SendPropVector (SENDINFO(m_vecOrigin), -1, SPROP_COORD|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ),
#endif
SendPropInt (SENDINFO( m_ubInterpolationFrame ), NOINTERP_PARITY_MAX_BITS, SPROP_UNSIGNED ),
SendPropModelIndex(SENDINFO(m_nModelIndex)),
SendPropDataTable( SENDINFO_DT( m_Collision ), &REFERENCE_SEND_TABLE(DT_CollisionProperty) ),
SendPropInt (SENDINFO(m_nRenderFX), 8, SPROP_UNSIGNED ),
SendPropInt (SENDINFO(m_nRenderMode), 8, SPROP_UNSIGNED ),
SendPropInt (SENDINFO(m_fEffects), EF_MAX_BITS, SPROP_UNSIGNED),
SendPropInt (SENDINFO(m_clrRender), 32, SPROP_UNSIGNED),
SendPropInt (SENDINFO(m_iTeamNum), TEAMNUM_NUM_BITS, 0),
SendPropInt (SENDINFO(m_CollisionGroup), 5, SPROP_UNSIGNED),
SendPropFloat (SENDINFO(m_flElasticity), 0, SPROP_COORD),
SendPropFloat (SENDINFO(m_flShadowCastDistance), 12, SPROP_UNSIGNED ),
SendPropEHandle (SENDINFO(m_hOwnerEntity)),
SendPropEHandle (SENDINFO(m_hEffectEntity)),
SendPropEHandle (SENDINFO_NAME(m_hMoveParent, moveparent)),
SendPropInt (SENDINFO(m_iParentAttachment), NUM_PARENTATTACHMENT_BITS, SPROP_UNSIGNED),
SendPropInt (SENDINFO_NAME( m_MoveType, movetype ), MOVETYPE_MAX_BITS, SPROP_UNSIGNED ),
SendPropInt (SENDINFO_NAME( m_MoveCollide, movecollide ), MOVECOLLIDE_MAX_BITS, SPROP_UNSIGNED ),
#if PREDICTION_ERROR_CHECK_LEVEL > 1
SendPropVector (SENDINFO(m_angRotation), -1, SPROP_NOSCALE|SPROP_CHANGES_OFTEN, 0, HIGH_DEFAULT, SendProxy_Angles ),
#else
SendPropQAngles (SENDINFO(m_angRotation), 13, SPROP_CHANGES_OFTEN, SendProxy_Angles ),
#endif
SendPropInt ( SENDINFO( m_iTextureFrameIndex ), 8, SPROP_UNSIGNED ),
#if !defined( NO_ENTITY_PREDICTION )
SendPropDataTable( "predictable_id", 0, &REFERENCE_SEND_TABLE( DT_PredictableId ), SendProxy_SendPredictableId ),
#endif
// FIXME: Collapse into another flag field?
SendPropInt (SENDINFO(m_bSimulatedEveryTick), 1, SPROP_UNSIGNED ),
SendPropInt (SENDINFO(m_bAnimatedEveryTick), 1, SPROP_UNSIGNED ),
SendPropBool( SENDINFO( m_bAlternateSorting )),
#ifdef TF_DLL
SendPropArray3( SENDINFO_ARRAY3(m_nModelIndexOverrides), SendPropInt( SENDINFO_ARRAY(m_nModelIndexOverrides), SP_MODEL_INDEX_BITS, 0 ) ),
#endif
END_SEND_TABLE()
BEGIN_SEND_TABLE_NOBASE( CBaseEntity, DT_AnimTimeMustBeFirst )
// NOTE: Animtime must be sent before origin and angles ( from pev ) because it has a
// proxy on the client that stores off the old values before writing in the new values and
// if it is sent after the new values, then it will only have the new origin and studio model, etc.
// interpolation will be busted
SendPropInt (SENDINFO(m_flAnimTime), 8, SPROP_UNSIGNED|SPROP_CHANGES_OFTEN|SPROP_ENCODED_AGAINST_TICKCOUNT, SendProxy_AnimTime),
END_SEND_TABLE()
#if !defined( NO_ENTITY_PREDICTION )
BEGIN_SEND_TABLE_NOBASE( CBaseEntity, DT_PredictableId )
SendPropPredictableId( SENDINFO( m_PredictableID ) ),
SendPropInt( SENDINFO( m_bIsPlayerSimulated ), 1, SPROP_UNSIGNED ),
END_SEND_TABLE()
|