Пример плагина: Работа с энтити (engine.inc + fakemeta.inc)
Пример: спавн и удаление энтити
<engine> — старый модуль (engine.inc), функции вроде find_ent_by_class, entity_set_model, DLLFunc. <fakemeta> — более современный, прямой доступ к pev_* полям (origin, velocity, model, health,classname).
Что делает плагин
- Команда
/nade— спавнит HE гранату перед игроком. - Команда
/rm— удаляет все энтити классаgrenadeв радиусе 500 юнитов. - Команда
/push— толкает ближнюю энтити в направлении взгляда игрока.
Полный код плагина
#include <amxmodx>
#include <engine>
#include <fakemeta>
public plugin_init()
{
register_plugin("Entity Demo", "1.0", "WikiExample");
register_clcmd("say /nade", "cmd_spawn_nade");
register_clcmd("say /rm", "cmd_remove_grenades");
register_clcmd("say /push", "cmd_push_entity");
}
public cmd_spawn_nade(id)
{
if (!is_user_alive(id)) return PLUGIN_HANDLED;
new Float:origin[3], Float:angles[3], Float:velocity[3];
entity_get_vector(id, EV_VEC_origin, origin); // engine
entity_get_vector(id, EV_VEC_v_angle, angles);
// сдвигаем точку спавна на 50 юнитов вперёд по взглядy
new Float:fwd[3];
angle_vector(angles, ANGLEVECTOR_FORWARD, fwd);
origin[0] += fwd[0] * 50;
origin[1] += fwd[1] * 50;
origin[2] += fwd[2] * 50 + 30;
// создаём HE гранату через fakemeta
new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "grenade"));
if (!pev_valid(ent)) return PLUGIN_HANDLED;
set_pev(ent, pev_classname, "demo_nade"); // fakemeta
set_pev(ent, pev_origin, origin);
set_pev(ent, pev_velocity, velocity); // velocity пока [0,0,0]
dllfunc(DLLFunc_Spawn, ent);
client_print(id, print_chat, "[Ent] HE граната создана перед вами.");
return PLUGIN_HANDLED;
}
public cmd_remove_grenades(id)
{
if (!is_user_alive(id)) return PLUGIN_HANDLED;
new Float:origin[3];
entity_get_vector(id, EV_VEC_origin, origin);
new ent = -1, removed = 0;
while ((ent = find_ent_by_class(ent, "grenade")) > 0)
{
new Float:eorigin[3];
entity_get_vector(ent, EV_VEC_origin, eorigin);
new Float:dist = get_distance_f(origin, eorigin);
if (dist <= 500.0)
{
remove_entity(ent);
removed++;
}
}
client_print(id, print_chat, "[Ent] Удалено гранат в радиусе: %d", removed);
return PLUGIN_HANDLED;
}
public cmd_push_entity(id)
{
if (!is_user_alive(id)) return PLUGIN_HANDLED;
//ippTrace_line пробивает куда смотрит игрок
new Float:start[3], Float:end[3], Float:angles[3];
entity_get_vector(id, EV_VEC_origin, start);
entity_get_vector(id, EV_VEC_v_angle, angles);
new Float:fwd[3];
angle_vector(angles, ANGLEVECTOR_FORWARD, fwd);
end = start;
end[0] += fwd[0] * 500;
end[1] += fwd[1] * 500;
end[2] += fwd[2] * 500;
new tr = 0;
engfunc(EngFunc_TraceLine, start, end, IGNORE_MONSTERS, id, tr);
new Float:hit_point[3];
get_tr2(tr, TR_vecEndPos, hit_point);
free_tr2(tr);
// Находим ближайшую к точке энтити
new ent = -1, target = 0;
new Float:best_dist = 99999.0;
while ((ent = find_ent_sphere(-1, hit_point)) != -1)
{
// skip players
if (1 <= ent <= 32) continue;
new Float:eorigin[3];
entity_get_vector(ent, EV_VEC_origin, eorigin);
new Float:d = get_distance_f(hit_point, eorigin);
if (d < best_dist) { best_dist = d; target = ent; }
}
if (target)
{
set_pev(target, pev_velocity, fwd); // толкаем вперёд
client_print(id, print_chat, "[Ent] Энтити #%d толкнута.", target);
}
else
client_print(id, print_chat, "[Ent] Не найдено энтити в точке взгляда.");
return PLUGIN_HANDLED;
}
Ключевые функции
engfunc(EngFunc_CreateNamedEntity, alloc_string)— создаёт энтити.set_pev(ent, pev_classname, "name")— задаёт classname.pev(ent, pev_origin, vec)/set_pev(ent, pev_origin, vec)— чтение/запись позиции.find_ent_by_class(start, "classname")— перебор по классу.find_ent_sphere(start, origin)— поиск энтити вокруг точки.remove_entity(ent)— удаление.engfunc(EngFunc_TraceLine, start, end, IGNORE_MONSTERS, ignoreent, tr)— трейслайн (линия взгляда).
Подробные инструкции и обсуждения ждём вас на нашем форуме — в разделе CS 1.6.