Skip to content

Entity Intermediate

GeckoN edited this page Feb 13, 2017 · 6 revisions

This article covers some intermediate aspects of the entity system.

Entity Basics

Fundamental functions

There are 4 fundamental functions used to drive the behaviour of any entity:

  • Think
  • Use
  • Touch
  • Blocked

Each of these is responsible for an important part of an entity's behaviour.

Think

Think functions are used to make entities act on their own. An entity "thinks" every so often and performs tasks while doing so.

For example, a train will think every frame to determine if it's reached the current node along its path. if so, it will calculate the velocity needed to move to the next node, or stop, if it has reached the final node.

Entities can think every frame or once every so often. This allows you to set timeouts for when an action should take place, or update something every 5 seconds, for example.

Always think

To set an entity as always thinking, you have to enable the FL_ALWAYSTHINK flag:

pev.flags |= FL_ALWAYSTHINK;

Note: This can be expensive, especially if costly calculations are performed in the think function. This is typically reserved for entities that move themselves between move than 2 positions. Trains and vehicles are prime candidates for it.

Setting the next think time

To set the next think time, you will have to set entvars_t::nextthink:

pev.nextthink = g_Engine.time + 5; // 5 seconds from now

For brush entities, instead of g_Engine.time, you will have to use pev.ltime:

pev.nextthink = pev.ltime + 5;

This is because the engine treats brush entities differently, and does not work properly when using g_Engine.time.

Function signature

Think functions are defined as follows:

void MyThink()
{
	// Code here
}

Setting Think functions

It is currently impossible to set think functions through Angelscript for built-in entities, but for custom entities, it is possible by using the SetThink function:

pCustomEnt.SetThink( ThinkFunction( pCustomEnt.MyThink ) );

Where MyThink is a think function defined in the custom entity's class. ThinkFunction is a funcdef. Its use is required here to convert the function to a type that the SetThink function can use.

It is also possible to define a Think function by overriding the default function. If this is done, you will not be able to set Think functions using SetThink. Overriding the default is done like this:

void Think()
{
	// Code here
}

Use

Use functions are used to trigger entities. When an entity is "used", it responds by performing an action. For example, a button will react by optionally moving, and when it finishes moving, triggers its target. A door will open or close, while a changelevel changes the map.

ObjectCaps

There are a few ObjectCaps flags that affect how player use behaves with specific entities:

Flag Behavior Parameters
FCAP_IMPULSE_USE The entity is triggered when the player presses the use button. Holding down the button or releasing it does not trigger it again. USE_SET with value 1
FCAP_CONTINUOUS_USE Every frame that the use button is pressed, the entity is triggered. USE_SET with value 1
FCAP_ONOFF_USE Similar to impulse use, but if the player releases the use button and this entity is the target, it is triggered with USE_SET and a value of 0. USE_SET with value 1, USE_SET with value 0 when use is released
FCAP_DIRECTIONAL_USE Used by trains. Does not affect player use. Instead, the entity will receive a trigger when the player presses the forward or back button while in control of this entity. Sent only in the frame that the button press is received, not continuous. USE_SET with value 1 when forward is pressed, USE_SET with value -1 when back is pressed.

USE_TYPE

The USE_TYPE enum contains constants used to indicate what kind of use action is being performed on an entity.

Constant Value Description
USE_OFF 0 Explicit off (only close/deactivate/lock/disable etc).
USE_ON 1 Explicit on (only open/activate/unlock/enable etc).
USE_SET 2 Entity was +use'd by a player, or some other form of player input.
USE_TOGGLE 3 Toggle on/off (if entity on do off, if entity off do on).
USE_KILL 4 Explicitly destroy entity. Items remove themselves when they receive this. Most other entity types don't handle it.

Function signature

Use functions are defined as follows:

void MyUse( CBaseEntity@ pActivator, CBaseEntity@ pCaller, USE_TYPE useType, float flValue )
{
	// Code here
}

Setting Use functions

It is currently impossible to set use functions through Angelscript for built-in entities, but for custom entities, it is possible by using the SetUse function:

pCustomEnt.SetUse( UseFunction( pCustomEnt.MyUse ) );

Where MyUse is a use function defined in the custom entity's class. UseFunction is a funcdef. Its use is required here to convert the function to a type that the SetUse function can use.

It is also possible to define a Use function by overriding the default function. If this is done, you will not be able to set Use functions using SetUse. Overriding the default is done like this:

void Use( CBaseEntity@ pActivator, CBaseEntity@ pCaller, USE_TYPE useType, float flValue )
{
	// Code here
}

Touch functions

Touch functions are used to detect and respond to entities touching each-other.

Entities touch each-other when their collision hulls intersect. Depending on the type of entity, this may be a point, a bounding box, or a brush model.

When entities touch, the Touch functions for both entities are called, first the entity being moved, then the entity being touched.

Function signature

Touch functions are defined as follows:

void MyTouch( CBaseEntity@ pOther )
{
	// Code here
}

Setting Touch functions

It is currently impossible to set touch functions through Angelscript for built-in entities, but for custom entities, it is possible by using the SetTouch function:

pCustomEnt.SetTouch( TouchFunction( pCustomEnt.MyTouch ) );

Where MyTouch is a touch function defined in the custom entity's class. TouchFunction is a funcdef. Its use is required here to convert the function to a type that the SetTouch function can use.

It is also possible to define a Touch function by overriding the default function. If this is done, you will not be able to set Touch functions using SetTouch. Overriding the default is done like this:

void Touch( CBaseEntity@ pOther )
{
	// Code here
}

Blocked functions

Blocked functions are used to detect and respond to entities blocking each-other.

An entity blocks another entity when the entity moving towards the entity cannot move any further due to the blocking entity being in the way.

When an entity is blocked, its Blocked function is called. The blocking entity's Blocked function is not called.

Function signature

Blocked functions are defined as follows:

void MyBlocked( CBaseEntity@ pOther )
{
	// Code here
}

Setting Blocked functions

It is currently impossible to set blocked functions through Angelscript for built-in entities, but for custom entities, it is possible by using the SetBlocked function:

pCustomEnt.SetBlocked( BlockedFunction( pCustomEnt.MyBlocked ) );

Where MyBlocked is a blocked function defined in the custom entity's class. BlockedFunction is a funcdef. Its use is required here to convert the function to a type that the SetBlocked function can use.

It is also possible to define a Blocked function by overriding the default function. If this is done, you will not be able to set Blocked functions using SetBlocked. Overriding the default is done like this:

void Blocked( CBaseEntity@ pOther )
{
	// Code here
}
Clone this wiki locally