PDA

View Full Version : [TUT] Finding relations between entities


joropito
04-05-2010, 11:50
First of all this tutorial assumes you have knowledge of entities classes also intermediate knowledge of Pawn.
Remember that engine & fakemeta gives you tools and you should put it together to get what you want.

I’ll try to explain how to get relations between entities in a map, specifically to get entities that trigger other entities (func_button).

Entities can be triggered from another entity using it's targetname value (the name of the entity).
For that, the source entity must have it's target value with the name of the destination entity.

The following example will try to find any light entity that can be turned on/off from a func_button.


// Engine way
#include <amxmodx>
#include <amxmisc>
#include <engine>

#define MAX_BUTTONS 10

new g_buttons[MAX_BUTTONS]

public plugin_init()
{
new light, button
new info[32]
new pos

while((pos <= sizeof(g_buttons)) && (light = find_ent_by_class(light, "light")))
{
if(!is_valid_ent(light))
continue

entity_get_string(light, EV_SZ_targetname, info, charsmax(info))

while((button = find_ent_by_target(button, info)))
{
if(!is_valid_ent(button))
continue

if(!find_button(button))
{
g_buttons[pos] = button
pos++
break
}
}
}
}

stock find_button(needle)
{
for(new i = 0; i < sizeof(g_buttons); i++)
{
if(g_buttons[i] == needle)
return 1
}
return 0
}


Let’s see what it does.
This will find entities of type light and not more than sizeof(g_buttons) (actually 10)


while((pos < sizeof(g_buttons)) && (light = find_ent_by_class(light, "light")))


Then we must check for a valid entity (if not, continue with next entity).
If it’s a valid entity, we need to get it’s name (targetname)


if(!is_valid_ent(light))
continue

entity_get_string(light, EV_SZ_targetname, info, charsmax(info))


Now we need to find which entity has our light found as a target


while((button = find_ent_by_target(button, info)))


Again, check for valid entity and, if it’s a valid entity, we are ready to store that entity in the array and only if it’s not already stored (at bottom of the code there's a custom stock to do this work)


if(!is_valid_ent(button))
continue

if(!find_button(button))
{
g_buttons[pos] = button
pos++
break
}



Now we have all (no more than 10) entities which handles lights in our array.


This tutorial could be used to find other kind of relations.
Sometimes, maps makers uses multi_manager entity as a tandem between activators and targets (for example when they need just one button to activate multiple lights or door or whatever)

You can find application of this in the following plugins
123373
122531
120991

EXteRmiNaToR
04-05-2010, 12:04
Nice!Reading it right now!:)

joropito
04-05-2010, 13:34
I prefer to build a list of entities at plugin_init and at Ham_Use only check if it's one of the selected entities.

In the Lights Mgmt plugin you can see that I catch kvd at precache on multi_manager, store un TrieCell and then populate the array.