|
| 1 | +entities |
| 2 | +======== |
| 3 | + |
| 4 | +This page contains tutorials about the :mod:`entities` package. Basically, the |
| 5 | +entities package provides functions and classes to create, modify, access and |
| 6 | +delete entities. An entity is an object somewhere on the map that has a specific |
| 7 | +type (class name) and different properties (e. g. health, position, team index, |
| 8 | +speed, model, etc.). |
| 9 | + |
| 10 | +There are two types of entities: |
| 11 | + |
| 12 | +* Networked entities |
| 13 | +* Non-networked entities |
| 14 | + |
| 15 | +``Networked`` already indicates that those entities are sent over the network. |
| 16 | +Their information is shared with all players on the server. Some common examples |
| 17 | +for those entities are players, weapons, barrels or trigger entities. |
| 18 | +Non-networked entities are entities that only exist on the server or client, but |
| 19 | +not on both sides. Entities are uniquely identified by an index that |
| 20 | +starts at 0 and can go up to the `entity limit <http://forums.sourcepython.com/>`_. |
| 21 | + |
| 22 | +.. note:: |
| 23 | + |
| 24 | + Indexes uniquely identify an entity. However, if the entity is deleted, a |
| 25 | + new entity can reuse that index. |
| 26 | + |
| 27 | + |
| 28 | +You will most likely want to access networked entities. Those are the most |
| 29 | +common and interesting ones. |
| 30 | + |
| 31 | +There are multiple classes in Source.Python to access the various entity types: |
| 32 | + |
| 33 | +* :class:`entities.entity.BaseEntity` - A very basic, but fast class to access networked and non-networked entities. |
| 34 | +* :class:`entities.entity.Entity` - An extended version of the :class:`entities.entity.BaseEntity` class. It provides a lot convenience methods, but is only able to access networked entities. |
| 35 | +* :class:`players.entity.Player` - An extended version of the :class:`entities.entity.Entity` class that provides additional methods to manipulate players. |
| 36 | +* :class:`weapons.entity.Weapon` - An extended version of the :class:`entities.entity.Entity` class that provides additional methods for weapons. |
| 37 | + |
| 38 | +This tutorial will only cover :class:`entities.entity.BaseEntity` and |
| 39 | +:class:`entities.entity.Entity`. For the other two classes, there will be |
| 40 | +separate tutorials. |
| 41 | + |
| 42 | + |
| 43 | +Accessing entities |
| 44 | +------------------ |
| 45 | + |
| 46 | +If you know the index of an entity, it's quite simple to access it. |
| 47 | + |
| 48 | +.. code-block:: python |
| 49 | +
|
| 50 | + from entities.entity import Entity |
| 51 | +
|
| 52 | + # Access the entity with index 0. The world entity always has the index 0. |
| 53 | + entity = Entity(0) |
| 54 | +
|
| 55 | + # Print the class name of the entity. This will print "worldspawn". |
| 56 | + print(entity.classname) |
| 57 | +
|
| 58 | +
|
| 59 | +However, often you need to search for entities of a specific type. E. g. to get |
| 60 | +all buy zones: |
| 61 | + |
| 62 | +.. code-block:: python |
| 63 | +
|
| 64 | + # Import the entity iterator |
| 65 | + from filters.entities import EntityIter |
| 66 | +
|
| 67 | + # Loop through all buy zones |
| 68 | + for buy_zone in EntityIter('func_buyzone'): |
| 69 | +
|
| 70 | + # Print the team index of the buy zone. Only teams with the same index can |
| 71 | + # use this buy zone. |
| 72 | + print(f'Buy zone for team: {buy_zone.team_index}') |
| 73 | +
|
| 74 | + # If you are not used to Python 3.6, the print statement might be |
| 75 | + # confusing at first. Alternatively, you could also write: |
| 76 | + # print('Buy zone for team: {}'.format(buy_zone.team_index)) |
| 77 | +
|
| 78 | +
|
| 79 | +You might wonder how to know which entity types are currently available on the |
| 80 | +map. You can easily discover that by using the following snippet. |
| 81 | + |
| 82 | +.. code-block:: python |
| 83 | +
|
| 84 | + # Import the entity iterator. |
| 85 | + from filters.entities import EntityIter |
| 86 | +
|
| 87 | + # Get the class name of every entity on the map. Use set() to get a distinct |
| 88 | + # set. |
| 89 | + classnames = set(entity.classname for entity in EntityIter()) |
| 90 | +
|
| 91 | + # Sort all class names alphabetically and then print them. |
| 92 | + for classname in sorted(classnames): |
| 93 | + print(classname) |
| 94 | +
|
| 95 | +
|
| 96 | +Modifying entities |
| 97 | +------------------ |
| 98 | + |
| 99 | +In the previous chapter we looped through all buy zones to print their team |
| 100 | +indexes. Now, let's loop through all doors on the map and open them. |
| 101 | + |
| 102 | +.. code-block:: python |
| 103 | +
|
| 104 | + # Import the entity iterator |
| 105 | + from filters.entities import EntityIter |
| 106 | +
|
| 107 | + # Loop through all doors |
| 108 | + for door in EntityIter('prop_door_rotating'): |
| 109 | +
|
| 110 | + # Open the door |
| 111 | + door.open() |
| 112 | +
|
| 113 | + # Or, if you are tired of the doors, simply remove them with: |
| 114 | + # door.remove() |
| 115 | +
|
| 116 | +
|
| 117 | +If you just tried to find information about ``door.open()`` on the wiki, you |
| 118 | +probably didn't find anything except this tutorial. This is because of all the |
| 119 | +different entity types. They all have different properties and methods, which |
| 120 | +also differs from game to game. Thus, you can only print these information at |
| 121 | +runtime. To do so, you can use the following snippet. |
| 122 | + |
| 123 | +.. code-block:: python |
| 124 | +
|
| 125 | + from entities.entity import Entity |
| 126 | +
|
| 127 | + # Find an entity with the class name "prop_door_rotating". If no entity was |
| 128 | + # found, it will be created. |
| 129 | + entity = Entity.find_or_create('prop_door_rotating') |
| 130 | +
|
| 131 | + # Loop through all attributes |
| 132 | + for attr in dir(entity): |
| 133 | +
|
| 134 | + # Print the attribute |
| 135 | + print(attr) |
| 136 | +
|
| 137 | +
|
| 138 | +Creating new entities |
| 139 | +--------------------- |
| 140 | + |
| 141 | +Creating new entities is quite simple. Often you just need to create an entity |
| 142 | +of the desired type, assign it a model and then spawn it. Here is how to do |
| 143 | +that. |
| 144 | + |
| 145 | +.. code-block:: python |
| 146 | +
|
| 147 | + # Import the required classes. |
| 148 | + from entities.entity import Entity |
| 149 | + from players.entity import Player |
| 150 | + from engines.precache import Model |
| 151 | + from events import Event |
| 152 | +
|
| 153 | + # Wrap the model (a barrel) with the Model class. It will ensure that the model |
| 154 | + # is precached, when you want to use it. Precaching is important. Otherwise |
| 155 | + # the model might not work. |
| 156 | + my_model = Model('models/props_c17/oildrum001.mdl') |
| 157 | +
|
| 158 | + # Listen to the player_say event. It gets fired everytime a player says |
| 159 | + # something in the chat. |
| 160 | + @Event('player_say') |
| 161 | + def on_player_say(event): |
| 162 | + # Get a Player instance for the player who typed something into the chat. |
| 163 | + player = Player.from_userid(event['userid']) |
| 164 | +
|
| 165 | + # Create an entity of the type "prop_physics_multiplayer". |
| 166 | + entity = Entity.create('prop_physics_multiplayer') |
| 167 | +
|
| 168 | + # Assign the model. |
| 169 | + entity.model = my_model |
| 170 | +
|
| 171 | + # Set the location where the entity should be created. In this case we want |
| 172 | + # to spawn it where the player is currently looking at. |
| 173 | + entity.origin = player.view_coordinates |
| 174 | +
|
| 175 | + # Finally spawn the entity. |
| 176 | + entity.spawn() |
| 177 | +
|
| 178 | +
|
| 179 | +.. note:: |
| 180 | + |
| 181 | + The model ``models/props_c17/oildrum001.mdl`` already exists in CS:S. In |
| 182 | + other games this might be different. |
0 commit comments