Entities changes

Discuss API design here.
User avatar
satoon101
Project Leader
Posts: 2697
Joined: Sat Jul 07, 2012 1:59 am

Entities changes

Postby satoon101 » Sun Jan 18, 2015 1:58 am

The BaseEntity class has gone through a lot of updating and for those who weren't paying attention to the repository, I feel many of those changes need explained. We will work on the full documentation on the wiki at some point, but for now I just want to highlight those main changes.

In one of the last updates that the BaseEntity class got in the master branch before we started working on these changes, we added the ability to get and set descriptors (non-networked properties from an entity's DataMaps) by name. For instance, you could get and set a player's kill count in CS:S with the following:

Syntax: Select all

# Get kills
kills = <PlayerEntity>.m_iFrags

# Set kills
<PlayerEntity>.m_iFrags = 7

However, we realized that this goes against our naming scheme where all attributes must be lower_case_with_underscores. We then set out to create methods to get and set these descriptors and eventually decided that we should require the type be in the methods as we have done with other objects within the plugin. Through the course of this, it was also decided that we should remove the old SendProps (network properties) implementation and make it all on the Python side, as well. So, now, the same way you get descriptors, you get networked properties. The internals to BaseEntity knows which ones are networked and which ones are not, so that when a networked property is set, we call the entity's edict's state_changed method to notify the server of the change. Now, to get/set a players kills, you can use:

Syntax: Select all

# Get kills
kills = <PlayerEntity>.get_property_int('m_iFrags')

# Set kills
<PlayerEntity>.set_property_int('m_iFrags', 7)

And the same goes for networked properties:

Syntax: Select all

# Get money
money = <PlayerEntity>.get_property_int('m_iAccount')

# Set money
<PlayerEntity>.set_property_int('m_iAccount', 16000)



We also had originally added the ability to get inputs by name (again, from an entity's DataMaps):

Syntax: Select all

# Destroy an entity and remove it from the server
<BaseEntity>.Kill()


# Set an entity on fire for 2 seconds
<BaseEntity>.IgniteLifetime(2.0)


# Hook CCSPlayer.OnRescueZoneTouch
@PreHook(<PlayerEntity>.OnRescueZoneTouch)
def pre_rescue_zone_touch(args):
...


Again, this also goes against our naming scheme where all methods and functions should be lower_case_with_underscores. So, we decided to add a get_input method that the inputs name can be passed into to get the entity's input:

Syntax: Select all

# Destroy an entity and remove it from the server
<BaseEntity>.get_input('Kill')()


# Set an entity on fire for 2 seconds
<BaseEntity>.get_input('IgniteLifetime')(2.0)


# Hook CCSPlayer.OnRescueZoneTouch
@PreHook(<PlayerEntity>.get_input('OnRescueZoneTouch'))
def pre_rescue_zone_touch(args):
...

We later added a call_input method for when you just want to call the input and not necessarily 'get' it:

Syntax: Select all

# Destroy an entity and remove it from the server
<BaseEntity>.call_input('Kill')


# Set an entity on fire for 2 seconds
<BaseEntity>.call_input('IgniteLifetime', 2.0)



To find all properties/descriptors of an entity, you can iterate through its 'properties' attribute:

Syntax: Select all

for prop in <BaseEntity>.properties:
print(prop)


The same goes for inputs:

Syntax: Select all

for input_name in <BaseEntity>.inputs:
print(input_name)


You can also get most of an entity's KeyValues by using the 'keyvalues' attribute:

Syntax: Select all

for keyvalue in <BaseEntity>.keyvalues:
print(keyvalue)

The reason I say 'most' is because some of the KeyValues are not given to the DataMaps, so you just have to know that all entity's carry them. I will compile a list of these and add them here when I get the chance.


We still use the data to make life even easier on scripters as we give names to many of these properties, descriptors, inputs, and keyvalues that allow you to access them as attributes of the BaseEntity instance.

Syntax: Select all

# Get kills
kills = <PlayerEntity>.kills

# Set kills
<PlayerEntity>.kills = 7

# Get money
money = <PlayerEntity>.cash

# Set money
<PlayerEntity>.cash = 16000

# Destroy an entity and remove it from the server
<BaseEntity>.remove()

# Set an entity on fire for 2 seconds
<BaseEntity>.ignite_lifetime(2.0)

# Hook CCSPlayer.OnRescueZoneTouch
@PreHook(<BaseEntity>.on_rescue_zone_touch)
def pre_rescue_zone_touch(args):
...



To see all attributes of a BaseEntity instance, simply use the built-in dir function:

Syntax: Select all

for attribute in dir(<BaseEntity>):
print(attribute)
Image

Return to “API Design”

Who is online

Users browsing this forum: No registered users and 12 guests