CBaseEntity

From Valve Developer Community
Jump to navigation Jump to search
English (en)中文 (zh)Translate (Translate)
Broom icon.png
This article or section needs to be cleaned up to conform to a higher standard of quality because:
stuff, terminology?, sections
For help, see the VDC Editing Help and Wikipedia cleanup process. Also, remember to check for any notes left by the tagger at this article's talk page.
Class hierarchy
CBaseEntity
IServerEntity
IServerUnknown
IHandleEntity
baseentity.cpp

The base class for all entities.

Icon-Important.pngImportant:The following applies to all entities that inherit this class, but may be overridden by subclasses.
See also:  Briefer more mapping focused article regarding generic keyvalues, inputs and outputs

Keyvalue handling

Each entity is stored in map file as bunch keyvalues. When an entity is being spawned all its keyvalues are handled using CBaseEntity::KeyValue method (subclasses can override this method and add new special keys). Each key and its value is passed to this function and are processed as follows:

<anything>#<anything> <any>
Everything after # symbol is striped and rest is processed as <anything> keyvalue, (example. targetname#100 would be treated as targetname)
Tip.pngTip:Because this is done inside CBaseEntity it can be used to avoid processing of keyvalue inside a ::KeyValue method of a derived class. For example CPointEntity forbids changing of bounding box via mins/maxs but changing it via mins#666 would work
rendercolor / rendercolor32 <color255>
Sets rgb portion of m_clrRender ↓ (first 24 bits)
renderamt <integer>
Sets alpha portion of m_clrRender (last 8 bits)
disableshadows <boolean>
If non 0 adds EF_NOSHADOW flag to m_fEffects ↓
mins / maxs <vector>
Sets m_Collision.m_vecMins/m_Collision.m_vecMaxs ↓ (also does model scale related checks if CBaseAnimating) and recalculates m_Collision.m_flRadius ↓ if needed
disablereceiveshadows <boolean>
If non 0 adds EF_NORECEIVESHADOW flag to m_fEffects
nodamageforces <boolean>
If non 0 adds EFL_NO_DAMAGE_FORCES flag to m_iEFlags ↓
angle <float>
Supposed to be single value seting yaw but due to mistake in code causes infinite recursion and crashes the game
angles <angle>
Sets angles (has parenting related checks[Elaborate?])
origin <vector>
Sets origin (has parenting related checks[Elaborate?])
targetname <string>
Sets m_iName ↓ (calls AllocPooledString to put/get it in/from game string table same way as string keyfields)
<anything else> <any>
Try finding the key among keyfields ↓, input keys ↓ or outputs ↓ and handle appropriately. Those are defined in datadesc table and are handled by ParseKeyvalue function
Note.pngNote:Outputs from perspective of a map file are essentially just keyvalues handled by calling a custom function. The handling of output parsing then starts here. See Outputs ↓

Keyfields

m_iClassname <FIELD_STRING> (classname)

The classname keyvalue is the very first keyvalue that's being read from a map file, before the entity is even spawned and spawning won't be attempted without it existing. Classnames are assosiated with a C++ classes using LINK_ENTITY_TO_CLASS() to determine class used to spawn the given entity.
After the entity is spawned or during the spawning period the classname may be used to do other specific checks regarding how the entity should behave (for example prop_physics and prop_physics_override are both tied to CPhysicsProp but one is forbidden to spawn without prop data and this check is done using a classname)
Changing classname in-game has effect on such checks. Notable one is when an entity is preserved entity in round based game. (Need to be careful with this in games that have save files because when saving and then loading the game after entity's classname was changed the entity will not be recreated correctly or at all)

m_iGlobalname <FIELD_STRING> (globalname)

When the player transitions to a new map, entities in the new map with matching globalnames will have their previous map's states copied over to it.

m_iParent <FIELD_STRING> (parentname)

m_iHammerID <FIELD_INTEGER> (hammerid)

The entity's unique Hammer ID that's auto-generated on map compiles. Mainly used by plugins or debugging commands (like the ent_keyvalue command). Entities spawned in run-time don't have a Hammer ID.

m_flSpeed <FIELD_FLOAT> (speed)

m_nRenderFX <FIELD_CHARACTER> (renderfx)

m_nRenderMode <FIELD_CHARACTER> (rendermode)

m_nNextThinkTick <FIELD_TICK> (nextthink)

Amount of time before the entity thinks again.

m_fEffects <FIELD_INTEGER> (effects)

Combination of effect flags to use. See effect flags.

m_clrRender <FIELD_COLOR32> (rendercolor)

m_nModelIndex <FIELD_SHORT> (modelindex)

Given the number index from dumping the cl_precacheinfo modelprecache table, sets entity model to the index.
Warning.pngWarning:If an entity has animations that will be played, then the set model also must have its own sequences, else the game crashes.

m_iszResponseContext <FIELD_STRING> (ResponseContext)

Pre-defined response system contexts; Format is [key]:[value],[key]:[value],...and so on.
Tip.pngTip:Can also be filtered for or against!

m_iMaxHealth <FIELD_INTEGER> (max_health)

Health cannot exceed this value. This keyvalue applies to only specific entities.

m_iHealth <FIELD_INTEGER> (health)

Current health of an entity. This keyvalue applies to only specific entities.

m_target <FIELD_STRING> (target)

m_iszDamageFilterName <FIELD_STRING> (damagefilter)

Name of a filter that controls which entities can damage this entity.

m_flShadowCastDistance <FIELD_FLOAT> (shadowcastdist)

Sets how far the entity casts dynamic shadows. 0 means default distance from the shadow_control entity.

m_ModelName <FIELD_MODELNAME> (model)

In-game representation of the entity to display

m_vecBaseVelocity <FIELD_VECTOR> (basevelocity)

m_vecAngVelocity <FIELD_VECTOR> (avelocity)

m_nWaterLevel <FIELD_CHARACTER> (waterlevel)

m_flGravity <FIELD_FLOAT> (gravity)

Gravity

m_flFriction <FIELD_FLOAT> (friction)

m_flLocalTime <FIELD_FLOAT> (ltime)

The local time of the entity, independent of the global clock. Used mainly for physics calculations.

m_vecVelocity <FIELD_VECTOR> (velocity)

m_iTextureFrameIndex <FIELD_CHARACTER> (texframeindex)

The initial frame number for all animated textures on this entity.

m_spawnflags <FIELD_INTEGER> (spawnflags)

Toggles exclusive features of an entity, its specific number is determined by the combination of flags added.

m_vecViewOffset <FIELD_VECTOR> (view_ofs)


Note.pngNote:The 3 following fields have an assigned key since Alien Swarm Alien Swarm and also in Team Fortress 2 Team Fortress 2

m_iTeamNum <FIELD_INTEGER> (teamnumber)

m_CollisionGroup <FIELD_INTEGER> (CollisionGroup)

Sets a collision group for this entity, which changes its collision behavior. See Collision groups for more information.

m_MoveType <FIELD_CHARACTER> (MoveType)

Sets a movetype for this entity, which changes its movement behavior. See MoveType for more information.

m_bDisableX360 (only in Left 4 Dead 2)<FIELD_BOOLEAN> (disableX360)

If this entity should automatically be given the 'Disable' input on the Xbox 360 version of Source.

m_bGlowBackfaceMult (only in Left 4 Dead 2)<FIELD? 4bytes> (glowbackfacemult)

If this object has a glow effect, multiply the effect by this much on the sides of the object that are facing away from the viewer.
Todo: more testing what this does

m_AIAddOn (in Left 4 Dead 2Alien SwarmPortal 2)<FIELD? 4bytes> (addon)

m_bLagCompensate (in Left 4 Dead 2Alien SwarmPortal 2)<FIELD_BOOLEAN> (LagCompensate)


m_iszVScripts (in all games since Left 4 Dead 2)(also in Team Fortress 2)<FIELD_STRING> (vscripts)

Space delimited names of files without extension that will be searched for in scripts/vscripts folder with extension based on what scripting language the current game is running (usually .nut). They will be executed one by one and between each execution functions named Precache and OnPostSpawn are gathered in 2 instances of vscript class CSimpleCallChainer. This way at the end of executing all files, the defined functions Precache and OnPostSpawn are gathered in those 2 instances and all of them can be called at proper time. (Precache runs before the entity's Spawn method is called, OnPostSpawn runs after)

m_iszScriptThinkFunction (in all games since Left 4 Dead 2)(also in Team Fortress 2)<FIELD_STRING> (thinkfunction)

It stores the name of the function called by ScriptThink ↓. One way ScriptThink is activated is during entity spawning if this is not empty string. (vscripts keyvalue must also be set)

m_nMinCPULevel (in all games since Left 4 Dead)<FIELD_CHARACTER> (mincpulevel)

m_nMaxCPULevel (in all games since Left 4 Dead)<FIELD_CHARACTER> (maxcpulevel)

m_nMinGPULevel (in all games since Left 4 Dead)<FIELD_CHARACTER> (mingpulevel)

m_nMaxGPULevel (in all games since Left 4 Dead)<FIELD_CHARACTER> (maxgpulevel)

m_flFadeScale (in all games since Left 4 Dead)<FIELD_FLOAT> (fadescale)


Inputs

Inputs are defined in datadesc either as DEFINE_INPUT or DEFINE_INPUTFUNC. They are handled by CBaseEntity::AcceptInput method which is usually called from the event queue.

Input keys

Inputs keys are defined using DEFINE_INPUT and can be used as both inputs and keyvalues alike. When an input that needs to just change some single property is needed, this is a quick way to define it. (handled here when used as input). The command ent_fire does not auto-complete these when writing in console.


m_iInitialTeamNum <FIELD_INTEGER> (TeamNum)


m_fadeMinDist (in all games since Left 4 Dead)<FIELD_INTEGER> (fademindist)

m_fadeMaxDist (in all games since Left 4 Dead)<FIELD_INTEGER> (fademaxdist)


Input functions

Regular inputs are defined using DEFINE_INPUTFUNC and are linked to some function.


SetTeam <FIELD_INTEGER> linked function: InputSetTeam

Changes this entity's team. Changes m_iTeamNum ↑

Kill <FIELD_VOID> linked function: InputKill

Removes this entity and any entities parented to it from the world.

KillHierarchy <FIELD_VOID> linked function: InputKillHierarchy

Functions the same as Kill, although this entity and any entities parented to it are killed on the same frame, being marginally faster thanKillinput.

Use <FIELD_VOID> linked function: InputUse

Same as a player invoking +use

Alpha <FIELD_INTEGER> linked function: InputAlpha

Sets the entity's transparency to a number from 0 (invisible) to 255 (fully visible). Requires the entity to have its Render Mode (rendermode) set to a number other than 0.

AlternativeSorting <FIELD_BOOLEAN> linked function: InputAlternativeSorting

Swaps the rendering order of the entity. Used to attempt to fix sorting problems when rendering, for example an object rendering in front of translucent materials.

Color <FIELD_COLOR32> linked function: InputColor

Sets an RGB color for the entity.

SetParent <FIELD_STRING> linked function: InputSetParent

Move with specified entity. Accepts only targetnames as argument.

SetParentAttachment <FIELD_STRING> linked function: InputSetParentAttachment

Change this entity to attach to a specific attachment point on its parent. The entity will teleport so that the position of its root bone matches that of the attachment. Entities must be parented before being sent this input.

SetParentAttachmentMaintainOffset <FIELD_STRING> linked function: InputSetParentAttachmentMaintainOffset

As above, but without teleporting. The entity retains its position relative to the attachment at the time of the input being received.

ClearParent <FIELD_VOID> linked function: InputClearParent

Removes this entity from the movement hierarchy, leaving it free to move independently.

SetDamageFilter <FIELD_STRING> linked function: InputSetDamageFilter

Sets a filter for this entity for when it receives damage.

EnableDamageForces <FIELD_VOID> linked function: InputEnableDamageForces

Allows the entity to be pushed by damage done to it (usually force amount correlates with the damage done).

DisableDamageForces <FIELD_VOID> linked function: InputDisableDamageForces

Prevents the entity from being pushed by damage done to it.

DispatchEffect (removed since Left 4 Dead) <FIELD_STRING> linked function: InputDispatchEffect

Dispatches a special effect from the entity's origin; See also List of Client Effects. Replaced by the particle system since Left 4 Dead.

DispatchResponse <FIELD_STRING> linked function: InputDispatchResponse

Dispatches a response to the entity. See Response and Concept.

AddContext <FIELD_STRING> linked function: InputAddContext

Adds to the entity's list of response contexts. See Context. (This and also RemoveContext and ClearContext modify field m_ResponseContexts ↓)

RemoveContext <FIELD_STRING> linked function: InputRemoveContext

Remove a context from this entity's list. The name should match the key of an existing context.

ClearContext <FIELD_STRING> linked function: InputClearContext

Removes all contexts from this entity's list.

DisableShadow <FIELD_VOID> linked function: InputDisableShadow

Turn dynamic shadows off for this entity. Adds flag EF_NOSHADOW to m_fEffects ↓

EnableShadow <FIELD_VOID> linked function: InputEnableShadow

Turn dynamic shadows on for this entity. Removes flag EF_NOSHADOW from m_fEffects

AddOutput <FIELD_STRING> linked function: InputAddOutput

Splits the string argument at first '' (space symbol) and replaces every ':' with ','. The rest is handled by ::KeyValue method.
For example: "OnUser1 test:use" will be handled as KeyValue("OnUser1", "test,use") (see keyvalues ↑ and outputs ↓)

FireUser1 <FIELD_STRING> linked function: InputFireUser1

FireUser2 <FIELD_STRING> linked function: InputFireUser2

FireUser3 <FIELD_STRING> linked function: InputFireUser3

FireUser4 <FIELD_STRING> linked function: InputFireUser4

Fires the respectiveOnUseroutputs; see User Inputs and Outputs.

Only in Portal 2 Portal 2

SetLocalOrigin (also in Left 4 Dead 2Team Fortress 2Alien Swarm: Reactive DropMapbase as SetLocalOrigin vscript function)<FIELD_VECTOR> linked function: InputSetLocalOrigin

Set this entity's local origin (relative to the parent). Calls function SetLocalOrigin which checks if angles differ from curent m_vecOrigin ↓ and if so calls InvalidatePhysicsRecursive to update some neccessary stuff[Elaborate?] for the origin to change properly and sets m_vecOrigin afterwards

SetLocalAngles (also in Left 4 Dead 2Team Fortress 2Alien Swarm: Reactive DropMapbase as SetLocalAngles vscript function)<FIELD_VECTOR> linked function: InputSetLocalAngles

Set this entity's local angles. (relative to the parent) Calls function SetLocalAngles which checks if angles differ from curent m_angRotation ↓ and if so calls InvalidatePhysicsRecursive to update some neccessary stuff[Elaborate?] for the angles to change properly and sets m_angRotation afterwards.

DisableDraw <FIELD_VOID> linked function: InputDisableDraw

Adds flag EF_NODRAW to m_fEffects ↓. Note that this is different than Render Mode 10.

EnableDraw <FIELD_VOID> linked function: InputEnableDraw

Removes flag EF_NODRAW from m_fEffects ↓

DisableReceivingFlashlight <FIELD_VOID> linked function: InputDisableReceivingFlashlight

Adds flag EF_NOFLASHLIGHT to m_fEffects ↓

EnableReceivingFlashlight <FIELD_VOID> linked function: InputEnableReceivingFlashlight

Removes flag EF_NOFLASHLIGHT from m_fEffects ↓

DisableDrawInFastReflection <FIELD_VOID> linked function: InputDisableDrawInFastReflection

Turns off rendering of this entity in reflections when using $reflectonlymarkedentities in water material by removing flag EF_MARKED_FOR_FAST_REFLECTION from m_fEffects ↓

EnableDrawInFastReflection <FIELD_VOID> linked function: InputEnableDrawInFastReflection

Turn on rendering of this entity in reflections when using $reflectonlymarkedentities in water material by adding flag EF_MARKED_FOR_FAST_REFLECTION to m_fEffects ↓

RemovePaint <FIELD_VOID> linked function: InputRemovePaint

Since Left 4 Dead 2 Left 4 Dead 2 and also in Team Fortress 2 Team Fortress 2

RunScriptFile <FIELD_STRING> linked function: InputRunScriptFile

Execute a VScript file from disk, without file extension. The script contents are merged with the script scope of the receiving entity.

RunScriptCode <FIELD_STRING> linked function: InputRunScript

Execute a string of VScript source code in the scope of the entity receiving the input. String quotation may be needed when fired via console.

CallScriptFunction <FIELD_STRING> linked function: InputCallScriptFunction

Calls a VScript function defined in the scope of the receiving entity.

TerminateScriptScope (only in Team Fortress 2) <FIELD_VOID> linked function: InputTerminateScriptScope

Destroys the script scope of the receiving entity.

Outputs

All outputs are derived from CBaseEntityOutput. Each output is internally an object that contains a list of actions which will all be fired when given output is fired. Output being fired means that the output's FireOutput method was called. The method is called from individual entities' code at appropriate times. Some outputs also store a value and each time this values is changed the output is also fired. (e.g. OutValue of math_counter which is COutputFloat) Adding an action to the output is done via keyvalues i.e. CBaseEntity::KeyValue method needs to be called with key being the associated output name and the value being the action that has the following format (parsed here)

<target>,<input name>,<paramater override>,<delay>,<refire count>
  • target - see targetname. !caller, !self, !activator targets depend on how the output is fired in the given entity's code
  • input name - input fired to the target (if unspecified then "Use" input is chosen)
  • paramater override - called override because outputs that have a value will automatically set this if left empty
  • delay - delay of the given action
  • refire count - how many times can this output fire, 0 or -1 means infinite
PlacementTip.pngExample:"Explanation" via examples of equivalent ways to add the same set of actions to OnUser1 output of an entity named "someent"

Turning off smart-edit and adding following (or setting the same up via 'Outputs' tab):

  • key = "OnUser1" value = "Test,Kill,,5,5"
  • key = "OnUser1#2" value = "test2"
  • key = "OnUser1#999" value = "!activator,SetParent,test2"

following ent_fires:

  • ent_fire someent AddOutput "OnUser1 Test:Kill::5:5"
  • ent_fire someent AddOutput "onUsEr1 test2"
  • ent_fire someent AddOutput "ONUSER1 !activator,SetParent,test2"

following vscript in games where the function is available:

handle_of_someent.__KeyValueFromString("onuser1", "Test,kill,,5,5");
handle_of_someent.__KeyValueFromString("onuser1", "test2");
handle_of_someent.__KeyValueFromString("onuser1", "!activator,SetParent,test2");

Vscript also provides direct way to add/remove actions to an output using `CScriptEntityOutputs`.


m_OnUser1 <COutputEvent> (OnUser1)

m_OnUser2 <COutputEvent> (OnUser2)

m_OnUser3 <COutputEvent> (OnUser3)

m_OnUser4 <COutputEvent> (OnUser4)

FireUser1 to FireUser4 inputs fire these outputs and set !activator as activator of the FireUser input and !caller as the current entity.

m_OnKilled (only in Left 4 Dead)<COutputEvent> (OnKilled)

Fired when entity is killed

Other fields

Keyless fields

Note.pngNote:Most of these are changeable for example via vscript's CNetPropManager see also ↓

m_iName <FIELD_STRING>

Name other entities use to refer to this entity (vscript GetName() returns this)

m_vecOrigin <FIELD_VECTOR>

Relative to parent[confirm]

m_vecAbsOrigin <FIELD_POSITION_VECTOR>

m_vecAbsVelocity <FIELD_VECTOR>


m_angRotation <FIELD_VECTOR>

m_angAbsRotation <FIELD_VECTOR>


m_fFlags <FIELD_INTEGER>

m_iEFlags <FIELD_INTEGER>


m_debugOverlays <FIELD_INTEGER>

Set by commands like ent_text, ent_bbox, see Entity debugging ↓

m_flPrevAnimTime <FIELD_TIME>

m_flAnimTime <FIELD_TIME>


m_lifeState <FIELD_CHARACTER>

  • LIFE_ALIVE = 0
  • LIFE_DYING = 1 // playing death animation or still falling off of a ledge waiting to hit ground
  • LIFE_DEAD = 2 // dead. lying still.
  • LIFE_RESPAWNABLE = 3
  • LIFE_DISCARDBODY = 4

m_takedamage <FIELD_CHARACTER>

  • DAMAGE_NO = 0
  • DAMAGE_EVENTS_ONLY = 1 // Call damage functions, but don't modify health
  • DAMAGE_YES = 2
  • DAMAGE_AIM = 3

m_MoveCollide <FIELD_CHARACTER>

m_flElasticity <FIELD_FLOAT>


touchStamp <FIELD_INTEGER>


m_flDesiredShadowCastDistance <FIELD_FLOAT>

m_flGroundChangeTime <FIELD_TIME>


m_nWaterType <FIELD_CHARACTER>


m_pBlocker <FIELD_EHANDLE>

m_flVPhysicsUpdateLocalTime <FIELD_FLOAT>

m_flMoveDoneTime <FIELD_FLOAT>


m_bAlternateSorting <FIELD_BOOLEAN>


m_flSimulationTime <FIELD_TIME>

m_nLastThinkTick <FIELD_TICK>

m_nSimulationTick <FIELD_TICK>

m_bSimulatedEveryTick <FIELD_BOOLEAN>

m_bAnimatedEveryTick <FIELD_BOOLEAN>

m_nTransmitStateOwnedCounter <FIELD_CHARACTER>


m_flNavIgnoreUntilTime <FIELD_TIME>


m_pParent <FIELD_EHANDLE>

m_iParentAttachment <FIELD_CHARACTER>

m_hMoveParent <FIELD_EHANDLE>

m_hMoveChild <FIELD_EHANDLE>

m_hMovePeer <FIELD_EHANDLE>


m_hDamageFilter <FIELD_EHANDLE>

m_hOwnerEntity <FIELD_EHANDLE>

m_hEffectEntity <FIELD_EHANDLE>

m_hGroundEntity <FIELD_EHANDLE>


m_bForcePurgeFixedupStrings (in Team Fortress 2Portal 2)<FIELD_BOOLEAN>


m_flCreateTime (in Left 4 Dead seriesAlien Swarm)<FIELD_TIME>


m_bClientSideRagdoll (in all games since Left 4 Dead)<FIELD_BOOLEAN>


m_iszScriptId (in all games since Left 4 Dead 2)(also in Team Fortress 2)<FIELD_STRING>


m_hScriptUseTarget (only in Left 4 Dead 2)<FIELD_EHANDLE>

m_PreStasisMoveType (only in Left 4 Dead 2)<FIELD_INTEGER>

m_bIsInStasis (only in Left 4 Dead 2)<FIELD_BOOLEAN>


m_iSignifierName (only in Portal 2)<FIELD? 4bytes>

m_iObjectCapsCache (only in Portal 2)<FIELD? 4bytes>


Array fields

m_rgflCoordinateFrame[12] <FIELD_FLOAT>


m_nModelIndexOverrides[4] (only in Team Fortress 2)<FIELD_INTEGER>


Tables

Note.pngNote:Accessed in vscript like m_Collision.m_vecMins

m_Collision (CCollisionProperty)

m_vecMins <FIELD_VECTOR>

m_vecMaxs <FIELD_VECTOR>

Mins/maxs are used to determine the entity's bounding box (shown by ent_bbox ↓)

m_usSolidFlags <FIELD_SHORT>

m_nSurroundType <FIELD_CHARACTER>

//Specifies how to compute the surrounding box
  • 0: USE_OBB_COLLISION_BOUNDS
  • 1: USE_BEST_COLLISION_BOUNDS // Always use the best bounds (most expensive)
  • 2: USE_HITBOXES
  • 3: USE_SPECIFIED_BOUNDS
  • 4: USE_GAME_CODE
  • 5: USE_ROTATION_EXPANDED_BOUNDS
  • 6: USE_COLLISION_BOUNDS_NEVER_VPHYSICS

m_flRadius <FIELD_FLOAT>

Radius of a sphere around our AABB
Todo: see this image and describe with better wording

m_triggerBloat <FIELD_CHARACTER>

If m_usSolidFlags has FSOLID_USE_TRIGGER_BOUNDS this value is added to mins/maxs (for z axis only only maxs are modified and with half the value). (ent_bbox show this bloat with cyan lines) See CCollisionProperty::WorldSpaceTriggerBounds

m_vecSpecifiedSurroundingMins <FIELD_VECTOR>

m_vecSpecifiedSurroundingMaxs <FIELD_VECTOR>

[Todo]

m_vecSurroundingMins <FIELD_VECTOR>

m_vecSurroundingMaxs <FIELD_VECTOR>

Surrounding mins/maxs are used to determine the entity's AABB (shown by ent_absbox ↓)

m_bUniformTriggerBloat (only in Team Fortress 2)<FIELD_BOOLEAN>

m_nSolidType <FIELD_CHARACTER> (solid)


Removed since Left 4 Dead Left 4 Dead

m_vecMinsPreScaled <FIELD_VECTOR>

m_vecMaxsPreScaled <FIELD_VECTOR>

m_vecSpecifiedSurroundingMinsPreScaled <FIELD_VECTOR>

m_vecSpecifiedSurroundingMaxsPreScaled <FIELD_VECTOR>


m_Network (CServerNetworkProperty)

m_hParent <FIELD_EHANDLE>


m_Glow (CGlowProperty) (only in Left 4 Dead 2)

m_iGlowType <FIELD_INTEGER>


IPhysicsObject pointer

m_pPhysicsObject <FIELD_CUSTOM>

Associated physics object of this entity

CUtlVector type

m_ResponseContexts <FIELD_EMBEDDED>

An element consists of:
m_iszName <FIELD_STRING>
m_iszValue <FIELD_STRING>
m_fExpirationTime <FIELD_STRING>


Elements to this are added/removed by using AddContext/SetContext/ClearContext inputs, Left 4 Dead 2SetContext/SetContextNum vscript functions or response system's ApplyContext.

DEFINE_CUSTOM_FIELD

m_aThinkFunctions <FIELD_CUSTOM>

Used when using SetContextThink() to have multiple think functions

Function fields

Cpp.pngCode:These can be set to functions defined with DEFINE_FUNCTION, DEFINE_THINKFUNC, DEFINE_ENTITYFUNC or DEFINE_USEFUNC [confirm]

m_pfnThink <FIELD_FUNCTION>

Stored function parameters ( void )
Stores single think function. See SetThink()

m_pfnTouch <FIELD_FUNCTION>

Stored function parameters ( CBaseEntity *pOther )
Stores touch function. Set by SetTouch
PlacementTip.pngExample:Standing on prop_physics that has set up PressureDelay and Break on pressure flag (BreakablePropTouch)

m_pfnUse <FIELD_FUNCTION>

Stored function parameters ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
Stores use function

m_pfnBlocked <FIELD_FUNCTION>

Stored function parameters ( CBaseEntity *pOther )

m_pfnMoveDone <FIELD_FUNCTION>

Stored function parameters ( void )

Functions

Cpp.pngCode:These can be set as value of function fields, defined by DEFINE_FUNCTION[confirm]

Think functions

Note.pngNote:Defined by DEFINE_THINKFUNC
ScriptThink

(in all games since Left 4 Dead 2)(also in Team Fortress 2)

Handles vscript thinkfunction.

It works by trying to call a vscript function named m_iszScriptThinkFunction ↑ in the current entity's script scope. If no function of that name exists ScriptThink ends. If such function is found, it's executed and its return value will be used as a delay for the next time ScriptThink should be called. If no return value was given (either the function ended in error or it was just not provided) then sv_script_think_interval cvar is used as the delay (default value 0.1).

ScriptThink is in code used as context think and it's activated by the presence of thinkfunction keyvalue with non-empty string (vscripts ↑ keyvalue also must be non-empty) when the entity is being spawned or by using vscript function AddThinkToEnt.

ShadowCastDistThink
FrictionRevertThink Left 4 Dead seriesAlien Swarm

Server class (DT_BaseEntity)

Variables optimized for network traffic are called SendProps [confirm]. See individual netprop dumps for details on send bits and flags.

Only SendProps that are not part of datadesc table (i.e. described higher) are to be described in this section.

moveparent <handle>

movetype <unsigned>

movecollide <unsigned>


m_Gender (only in Left 4 Dead 2)<integer>


m_ubInterpolationFrame (removed since Left 4 Dead)<integer>


m_cellbits (in all games since Left 4 Dead 2)<integer>

m_cellX (in all games since Left 4 Dead 2)<integer>

m_cellY (in all games since Left 4 Dead 2)<integer>

m_cellZ (in all games since Left 4 Dead 2)<integer>


predictable_id (DT_PredictableId) (removed since Left 4 Dead)

m_PredictableID <integer>

m_bIsPlayerSimulated <boolean>


m_Glow (DT_GlowProperty) - (only in Left 4 Dead 2)

m_nGlowRange <integer>

m_nGlowRangeMin <integer>

m_glowColorOverride <integer>

m_bFlashing <integer>


AnimTimeMustBeFirst (DT_AnimTimeMustBeFirst)

m_Collision (DT_CollisionProperty)

Entity debugging

Note.pngNote:The following information applies to overlays coming from CBaseEntity. Derived classes can add their own info as needed/or override the functionality completely and would be documented on the article for the given class.

Changing m_debugOverlays shows various debug overlays when developer mode is active.

OVERLAY_TEXT_BIT : [1]

Added by ent_text

OVERLAY_NAME_BIT : [2]

Added by ent_name

OVERLAY_BBOX_BIT : [4]

Added by ent_bbox (bounding box overlay for this entity)

OVERLAY_PIVOT_BIT : [8]

Added by ent_pivot (show pivot for this entity)

OVERLAY_MESSAGE_BIT : [16]

Added by ent_messages (show messages for this entity)

OVERLAY_ABSBOX_BIT : [32]

Added by ent_absbox (show abs bounding box overlay)

OVERLAY_RBOX_BIT : [64]

Added by ent_rbox

OVERLAY_SHOW_BLOCKSLOS : [128]

See ai_debug_los (show entities that block NPC LOS)

OVERLAY_ATTACHMENTS_BIT : [256]

Added by ent_attachments (show attachment points)

OVERLAY_AUTOAIM_BIT : [512]

Added by ent_autoaim (Display autoaim radius)

OVERLAY_VIEWOFFSET : [1073741824]

Added by ent_viewoffset (show view offset)

ent_text

(<entindex()>) Name: <GetDebugName()> (<m_iClassname>)
GLOBALNAME: <m_iGlobalname> <!-- if m_iGlobalname not empty then this line is present -->
Position: <%0.1f, %0.1f, %0.1f, m_vecAbsOrigin.x, m_vecAbsOrigin.y, m_vecAbsOrigin.z>
Model:<m_ModelName> <!-- if m_ModelName not empty or this entity is derived from CBaseAnimating then this line is present -->
DAMAGE FILTER:<m_hDamageFilter->GetDebugName()> <!-- if m_hDamageFilter is not null then this line is present and its debug name is shown -->

ent_viewoffset

Draws red cross at EyePosition(). Eye position is m_vecAbsOrigin + m_vecViewOffset

NDebugOverlay::Cross3D( EyePosition(), 16, 255, 0, 0, true, 0.05f )

ent_name

Show just the debug name (GetDebugName())

ent_bbox

Orange color. Draws bounding box if we are an edict (not derived from CServerOnlyEntity) CBaseEntity::DrawBBoxOverlay

ent_absbox

Green color. Draws absolute bounding box if we are not an edict. If we have vphysics object (m_pPhysicsObject ↑) associated with us and it's also asleep the color will be darker green. Drawn by CBaseEntity::DrawAbsBoxOverlay

ent_pivot

If we are an edict draws pivot at m_vecAbsOrigin with rotation of GetAbsAngles()

NDebugOverlay::Axis( GetAbsOrigin(), GetAbsAngles(), 20, true, 0 );

ent_rbox

DrawRBoxOverlay() - draws nothing, assuming rbox stands for render box it makes sense because render boxes would be client side thing and those can be shown by r_drawrenderboxes or cl_ent_rbox

Programming related

To get the class name of an entity, use

entity->edict()->GetClassName();

Asserts

Client

Problem:

// Model could not be found
Assert( !"Model could not be found, index is -1" );

Solution:

  • Check your model name three times.
  • Precache your model on both server and client.

C++ definitions from Source 2013 Multiplayer Source 2013 Multiplayer

[edit]

Shared

baseentity_shared.h

baseentity_shared.cpp

Serverside

baseentity.h

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

	DECLARE_SIMPLE_DATADESC();
};

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

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

	static bool				m_bInDebugSelect;
	static int				m_nDebugPlayer;

protected:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	bool					IsTransparent() const;

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

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

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

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

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

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

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

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

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

public:
	void SetScaledPhysics( IPhysicsObject *pNewObject );

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

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

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

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

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

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

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

public:

	virtual const char	*GetTracerType( void );

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

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

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

	virtual void SetModel( const char *szModelName );

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

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

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

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

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

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

	string_t	GetEntityName();

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

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


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

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

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

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

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

	// capabilities
	virtual int	ObjectCaps( void );

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

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

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

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

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

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

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

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

	void		SetSolid( SolidType_t val );

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

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

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

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

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


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

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

public:
 	void CalcAbsolutePosition();

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

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

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

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

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

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

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

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

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

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

	int		m_iHammerID; // Hammer unique edit id number

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

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

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

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

	CNetworkVar( int, m_ubInterpolationFrame );

	int				m_nLastThinkTick;

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

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

protected:

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

#ifdef _DEBUG
	int							m_iCurrentThinkContext;
#endif

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

protected:
	CUtlVector< ResponseContext_t > m_ResponseContexts;

	// Map defined context sets
	string_t	m_iszResponseContext;

private:
	CBaseEntity( CBaseEntity& );

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

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

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


public:

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

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

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

	virtual ITraceFilter*	GetBeamTraceFilter( void );

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


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

public:

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

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

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

	virtual int		TakeHealth( float flHealth, int bitsDamageType );

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

	// Physics simulation
	virtual void			PhysicsSimulate( void );

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

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

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

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

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

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

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

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

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

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

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

	int						ShouldToggle( USE_TYPE useType, int currentState );

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

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

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

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

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

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

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

	float HealthFraction() const;

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

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

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

#endif // _DEBUG

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	virtual Vector	GetSmoothedVelocity( void );

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

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

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

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

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

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

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

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

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

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

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

	model_t					*GetModel( void );

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

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

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

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

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

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

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

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

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

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

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

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

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

	virtual void ModifyEmitSoundParams( EmitSound_t &params );

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

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

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

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

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

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

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

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

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

	static bool m_bAllowPrecache;

	static bool IsSimulatingOnAlternateTicks();

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

//	void Relink() {}

public:

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

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

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

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

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

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

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

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

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

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

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

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

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

	void					SetPredictionEligible( bool canpredict );

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

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

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

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

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

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

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

	void					PhysicsDispatchThink( BASEPTR thinkFunc );

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

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

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

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

	void					CalcAbsoluteVelocity();
	void					CalcAbsoluteAngularVelocity();

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

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

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

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

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

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

	friend class CPushBlockerEnum;

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

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

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

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

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

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

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

	virtual bool ShouldDrawWaterImpacts() { return true; }

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

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

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

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

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

	string_t m_iName;	// name used to identify this entity

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

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

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

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

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

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

	CNetworkVar( float, m_flShadowCastDistance );
	float		m_flDesiredShadowCastDistance;

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

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

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

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

	// Global velocity
	Vector			m_vecAbsVelocity;

	// Local angular velocity
	QAngle			m_vecAngVelocity;

	// Global angular velocity
//	QAngle			m_vecAbsAngVelocity;

	// local coordinate frame of entity
	matrix3x4_t		m_rgflCoordinateFrame;

	// Physics state
	EHANDLE			m_pBlocker;

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

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

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

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

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

	QAngle			m_angAbsRotation;

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

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

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

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

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

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

	int								m_fDataObjectTypes;

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

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

private:

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

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


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

	static bool						IsClient( void )
	{
		return false;
	}

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

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

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

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

baseentity.cpp

BEGIN_SIMPLE_DATADESC( thinkfunc_t )

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

END_DATADESC()

BEGIN_SIMPLE_DATADESC( ResponseContext_t )

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

END_DATADESC()

BEGIN_DATADESC_NO_BASE( CBaseEntity )

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

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

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

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

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

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

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

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

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

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

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

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

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

//	DEFINE_FIELD( m_bSentLastFrame, FIELD_INTEGER ),

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

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

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

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

//	DEFINE_FIELD( m_nPushEnumCount, FIELD_INTEGER ),

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

	DEFINE_KEYFIELD( m_vecViewOffset, FIELD_VECTOR, "view_ofs" ),

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

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

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

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

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

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

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

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

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

	DEFINE_INPUTFUNC( FIELD_STRING, "AddOutput", InputAddOutput ),

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

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

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

	DEFINE_FIELD( m_hEffectEntity, FIELD_EHANDLE ),

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

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

END_DATADESC()

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

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

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

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

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

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

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

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

END_SEND_TABLE()

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

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

Clientside

c_baseentity.h

c_baseentity.cpp

See Also