Главная Новости Услуги Форум | База знаний

Вверх

Меню
Пользователей онлайн
Онлайн игроков: 60

Пример плагина: Работа с энтити (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.
Назад