[TUT] Entities: what they are and how to use them
Before we begin, please be aware that this tutorial is aimed toward scripters of intermediate level that understand Pawn conceptually but are still sketchy when it comes to implementation. Beginners may get confused, and experts may find they already know all this.
An entity is basically anything in the game that can change. The map is not an entity - it is impossible to change. You can do something like put a spraypaint on it, but that's not changing the map per se; rather it simply paints another texture on the location you sprayed. Lights, players, the bomb, weapons (when on the ground, or even while being held in some mods) and breakable glass are all examples of entities. But what is important about ent(ities -- from now on they will be abbreviated to 'ents')? As said above, they can change. This means you can modify gameplay or make the game look different with them. One of the most basic things that must be learned about entities is how to spawn one. Throughout this tutorial, I will post both an engine and fakemeta method of doing things, so here is one example: Code:
Code:
Now what do we see here that I haven't explained? What is this "classname"? A classname is given to all ents to help the engine determine what it is. If we stopped reading this tutorial and went outside, looking at various things, a person walking by might be classname "human" (however players in game are classname "player"), a tree might be classname "tree", a car might be "func_car" (func_ since it's a usable entity or it serves a purpose) and a cat might be "monster_cat" (monster_ because it's an NPC that may or may not be hostile). What can we do with the classname? We can use it to implement game functions (if you name an ent "hostage_entity" then Counter-Strike will automatically assume it's a hostage) or we can search for it (using find_ent_by_class or similar functions) among other things. An entity also has other values. These values, such as health, target, targetname, gravity, movetype, etc. are all defined in part of HLSDK called the "edict_t" structure. An edict is effectively the basis for an entity because of this. If you have any experience with AMXX scripting, you've probably ran into the function set_user_health. You may not understand what it does, but you know it works. What it basically does is go into the player's edict_t structure and change the "health" value (which is actually a float, not an int) to whatever you specify. Let's look at how it actually implements this though. Let's say for example we want to set a player's health to 200. In fun, it looks like this: Code:
But in engine/fakemeta, it looks like this: Code:
We obviously have more power this way. It looks much more confusing, but rather than simply making a "set_user_x" (where x is gravity, targetname, or what not) we have access to the entire edict_t structure (which links to the entvars structure, which is where all the information really is). But what about this "entity_set_float"? There are 12 functions when it comes to engine and manipulating the entvars of an ent: entity_get_int entity_get_float entity_get_string entity_get_vector entity_get_edict entity_get_byte entity_set_int entity_set_float entity_set_string entity_set_vector entity_set_edict entity_set_byte Additionally, we have some other functions that do similar things: entity_set_origin entity_set_model entity_set_size Note that these are not the same as simply using entity_set_vector/string, as they actually notify the engine (not the module) of the changes. We have similar functions in fakemeta, however there are only 2 that do the same thing as these: pev set_pev Because there is only 2, we have to be much more careful with fakemeta, since we could accidentally pass a float when the pev expects an int, or something to that effect. There are also other functions which can be executed through engfunc and dllfunc (as shown near the top with the new Ent = engfunc... bit). But now, how can these be implemented? We've already seen above how we can avoid fun and instead use engine/fakemeta, but what are some other things we can do with ents? Well, let's say we want to teleport a player to a spot on the map. The first thing we must understand about where we want to teleport them, is that the location will be a vector. Why? Because a vector is a 3 cell array that contain data that generally acts as an x,y,z axis. We must also understand that all vectors implemented with engine/fakemeta are floats. Here is an example of a vector: Code:
Now, how is this relevant to setting a player's location? We must first look up how we set the entity's origin. After looking through the funcwiki we come across this: entity_set_origin So what do we do? First, we find out where we want to teleport the player. Let's say we want to teleport them to 50,-30,1000. We must first convert this to a vector: Code:
Then set their origin. Code:
When creating an entity, one of the most important things is to set its owner. Say, for example, a player types "car" in their console which creates a car in front of them, that can only be used by them. This can be done by setting their owner, and then checking when the ent is used if the owner is the person using it. Here is an example: Code:
Code:
With these examples, we went into a few things that we haven't before. First of all - solidity. When we boil water and steam floats up from it, if we put our hands through they do not get stopped after they touch the first water droplet. If go poke the nearest person, our finger will get stopped once it makes contact with them. This can be represented through solidity in the HL engine. There are 5 different solid types, which can be found here: http://www.amxmodx.org/funcwiki.php?...=3#const_solid The one we used in this case was SOLID_TRIGGER, because we want the player to trigger a touch when they touch the car (even though it will still trigger on BBOX or BSP). Another concept we have yet to go over is entity_set_size / engfunc(EngFunc_SetSize..., which allows you to set the size of an entity. This is important because without it, the ent's solidity will not matter. If the entity is 0 units on the x,y,z axis, then it is by definition SOLID_NOT, even if we set it to SOLID_BSP/_BBOX. No matter how big the model is, it's the size that really matters. This is already way too long, so I'm going to end this here. If you have any questions about this or any way to improve upon it, feel free to post. Additional information: The list of current Engine (module) entvar types can be found here (and below it): http://www.amxmodx.org/funcwiki.php?...#const_ent_int and the list of current Fakemeta entvars can be found here: http://www.amxmodx.org/funcwiki.php?go=module&id=16 |
Re: Entities: what they are and how to use them
You've become a tutorial beast Hawk! Although it didn't do anything for me, somebody new to HL scripting could well benefit from this :up:.
|
Re: Entities: what they are and how to use them
Quote:
you can set it the same way as any other entity. for something like the bomb though, you should run drop_to_floor on it, to make sure that whoever tries to defuse it can. To find the bomb and move it to x,y,z: Code:
|
Re: Entities: what they are and how to use them
Quote:
Code:
assuming Ent is the bomb. Or you can just do: Code:
If you don't have the bomb's ent id, you can do: Code:
|
Re: Entities: what they are and how to use them
Your the man Hawk gj
|
Re: Entities: what they are and how to use them
I've always wondered..
When creating an custom entity why must be the classname info_target? Or can be anything? |
Re: Entities: what they are and how to use them
Quote:
|
Re: Entities: what they are and how to use them
I have a question concerning creating models that appear at server/map start.
Is there something that can be registered in public plugin_init() that is not a command and is executed during map start? |
Re: Entities: what they are and how to use them
Quote:
Code:
|
Re: Entities: what they are and how to use them
Nice tutorial Hawk, I have a question though, using engine, how can I create 2 or more entities with the same command or function. For instance, how could I set clcmd "CmdSayCar" to spawn two cars instead of one? (this is not the best example but I'm hoping that you understand what I'm trying to ask)
|
All times are GMT -4. The time now is 00:38. |
Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.