Skip to content

Custom Keyvalues

Christian Petersen edited this page Feb 10, 2017 · 6 revisions

In this tutorial, we'll be going over custom keyvalues.

What are 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.

Custom keyvalues in Angelscript

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.

Clone this wiki locally