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