Use

From Valve Developer Community
(Redirected from +use)
Jump to navigation Jump to search
English (en)Translate (Translate)

All entities have a Use input, though many do nothing in response to it. Any entity can have a custom use functionality set up (see Programming ↓) and if it doesn't have one the default behavior is forwarding the use to the entity's parent. Typically, use performs the action players most expect when interacting with the entity (e.g., opening/closing a door, picking up a physics object). There are several methods to invoke it:

  1. A player looking at the entity and using the +use console command (commonly bound to the E key).
  2. An entity output that specifies the Use input, or doesn't specifying any input.
  3. The firetarget cheat command. (directly calls Use method with type USE_TOGGLE)
  4. In code directly calling the C++ function.

Programming

Although there is always a Use input and a Use method available as those are parts of CBaseEntity, the actual Use function of an entity starts as null. The Use function in this context refers to the function that m_pfnUse field was set as which can be assigned at any time with SetUse( void *SomeFunc(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) ). The Use function also must be defined in the given entity's Data Descriptions using DEFINE_USEFUNC( our_func ) .

Note.pngNote:func_button and several other entities use DEFINE_FUNCTION to put their Use function pointer into data desc. There doesn't seem to be any effective difference but it's more proper to use DEFINE_USEFUNC.

The CBaseEntity::Use method simply checks if a Use function was set (i.e. m_pfnUse is not null) and if it was set then it's called; otherwise if we have a parent then the Use method of the parent is called. Many entities usually override the Use method instead of setting a Use function. Benefit of setting a Use function instead of overriding the Use method is the ability to dynamically change it to a different one, for example as response to inputs.

Use types

Defined in shareddefs.h

typedef enum
{
	USE_OFF = 0, 
	USE_ON = 1, 
	USE_SET = 2, //signifies we are passing a value
	USE_TOGGLE = 3
} USE_TYPE;

Use type in I/O

It is not possible to specify USE_TYPE or value through the I/O system when mapping. Use input uses outputID property to specify USE_TYPE. Which means specifying Use input's USE_TYPE via I/O system can be done only in code by specifying the outputID parameter of AcceptInput or AddEvent functions as the desired USE_TYPE. It is set that way for players performing use action and the USE_TYPE is set based on the entity's ObjectCaps.

OutputID parameter being used as USE_TYPE also results in following behavior:

  • ent_fire sets outputID to 0 which means use fired through it is always of type USE_OFF
  • use input fired from the first loaded output in the given game (which has outputID 1) session will USE_ON, from the 2nd USE_SET, 3rd USE_TOGGLE and the rest bogus valus that are usually interpreted as USE_TOGGLE
  • firetarget calls Use function directly with use type USE_TOGGLE
PlacementTip.pngExample:
Example where to observe this behavior

Create a map with only npc_grenade_frag which has 4 outputs OnUser1-4 !self,Use. Assuming those are the only outputs in the given map and it's the very first loaded map in the given game session then when using FireUser1-4 one of them will be able to pick the grenade up while the rest won't be. (Most likely FireUser3 will be the one that can pick it up, activator must be the player for picking up the grenade) That's because one of those outputs ids will be 3 which in terms of USE_TYPE is USE_TOGGLE and that's what CBaseGrenade::Use method is checking for to pick the grenade up. Ent_fire will not be able to pick the grenade up while firetarget will be able to.