-
Notifications
You must be signed in to change notification settings - Fork 4
Custom Keyvalues
In this tutorial, we'll be going over custom keyvalues.
Custom keyvalues, for those who don't know, are keyvalues that can be set dynamically on any entity. A custom keyvalue begins with an $, optionally a type specifier and underscore, and a name. Combined with trigger_changevalue
and trigger_copyvalue
, you can use custom keyvalues to manage state.
You can use one of 4 different types for a keyvalue:
string
integer
float
Vector
For more information, see Sven Co-op Entity Guide or Sven Co-op Manor.
Unlike other entity variables, custom keyvalues cannot be directly accessed by name. This is because they are created on demand, and can't be dynamically bound at runtime.
Here's how you access and use custom keyvalues:
Accessing an entity's custom keyvalues:
Entity@ pEntity = ...;
...
CustomKeyvalues@ pCustom = entity.GetCustomKeyvalues();
This gets the custom keyvalues manager for the entity. You should never store this instance anywhere, only use local variables. If you remove the entity, do not access its custom keyvalues afterwards.
Getting a custom keyvalue:
CustomKeyvalue value( pCustom.GetKeyvalue( "$i_myint" ) );
This gets a custom keyvalue named $i_myint
. It has the type of int
, which means the custom keyvalues code will force it to convert to an integer internally.
Using a custom keyvalue:
if( value.Exists() )
{
g_Game.AlertMessage( at_console, "Value: %1\n", value.GetString() );
}
else
{
g_Game.AlertMessage( at_console, "Value didn't exist!\n" );
}
This checks if the keyvalue actually has a value, and if so, prints it out as a string. Any value can be converted to a string, but not all values can convert to the other supported types. Use value.GetType
to get the underlying type as an Entvartype
enum value.
Setting a custom keyvalue:
pCustom.SetKeyvalue( "$i_myint", 456 );
This sets the integer keyvalue to integer 456
. Note that the code does not check to see if the type specifier matches the type you're setting. If you pass a float to an integer type, it will still convert successfully, and be internally considered as a float. Try to avoid deviating from the name, or avoid using the type specifier if you need to support multiple types.
The keyvalue does not have to exist in order to set it.
Checking if a custom keyvalue exists:
bool fExists = pCustom.HasKeyvalue( "$i_myint" );
Default initializing a keyvalue:
pCustom.InitializeKeyvalueWithDefault( "$i_myint" );
This sets the keyvalue $i_myint
to the default value for its type. This is 0 for integer and float, { 0, 0, 0 } for vector, and an empty string for string. Again, the keyvalue does not have to exist to set it.
Removing custom keyvalues: Currently not possible:
Do not try to store a CustomKeyvalue
instance directly: the class can only be default constructed (no value), or copy constructed (value from CustomKeyvalues::GetKeyvalue
). This is to prevent you from having a reference to a keyvalue whose memory has been freed. For safety purposes, do not try to access custom keyvalues when the entity from which they came has been removed.