Игровые события

Как прослушивать игровые события в стиле Source 2.

Обзор

События — это информационные уведомления, передаваемые между объектами на сервере. Многие из них также передаются с сервера клиенту. Они определены в .res файлах в папке hl2/resource и папках resource конкретных модов. Для базового списка см. Source2 Game Events.

Важно отметить несколько концепций о событиях:

  • Они почти всегда информационные. То есть блокирование player_death не остановит смерть игрока. Это может заблокировать сообщение в HUD или консоли или что-то еще незначительное.
  • То, что событие находится в файле ресурсов, не означает, что оно когда-либо вызывается или работает так, как вы ожидаете.

Быстрый пример: Событие смерти игрока

public void RegisterEvents()
{
    HookEvent("player_death", Event_PlayerDeath);
}

public static void Event_PlayerDeath(string name, nint @event, bool dontBroadcast)
{
    EventInfo event = new EventInfo(@event);

    // Используйте типизированные методы на экземпляре EventInfo
    int victim = event.GetPlayerSlot("userid");
    int attacker = event.GetPlayerSlot("attacker");

    /* CODE */
}

Добавление слушателя событий

Вы можете привязать слушатели событий в OnPluginStart (или где угодно).

c#
c++
python
go
js
lua
using Plugify;
using static s2sdk.s2sdk;

public unsafe class Sample : Plugin
{
    public void OnPluginStart()
    {
        HookEvent("player_death", (string name, nint event, bool dontBroadcast) =>
        {
            int playerSlot = GetEventPlayerSlot(event, "userid");
            PrintToServer("event called.\n");
            return ResultType.Continue;
        }, HookMode.Post);
    }
}

Доступ к параметрам событий

Доступ к параметрам событий с использованием типизированных методов на экземпляре EventInfo:

// Чтение параметров событий
int playerSlot = event.GetPlayerSlot("userid");
float damage = event.GetFloat("damage");
string weaponName = event.GetString("weapon");
bool headshot = event.GetBool("headshot");

// Получение ссылок на сущности
nint playerController = event.GetPlayerController("userid");
nint playerPawn = event.GetPlayerPawn("userid");
nint entity = event.GetEntity("entityid");

Установка параметров событий столь же проста:

// Установка параметров событий
event.SetInt("userid", 123);
event.SetFloat("damage", 50.0f);
event.SetString("weapon", "ak47");
event.SetBool("headshot", true);

// Установка ссылок на сущности
event.SetPlayerController("userid", controllerHandle);
event.SetEntity("entityid", entityHandle);

Создание и запуск событий

Создавайте и запускайте пользовательские события используя класс EventInfo:

// Создание нового события
using (var customEvent = new EventInfo("player_hurt"))
{
    // Установка параметров события
    customEvent.SetInt("userid", 1);
    customEvent.SetInt("attacker", 2);
    customEvent.SetInt("health", 50);
    customEvent.SetString("weapon", "ak47");

    // Запуск для всех игроков
    customEvent.Fire();

    // Или запуск для конкретного игрока
    customEvent.FireToClient(playerSlot);
} // Автоматическая очистка

Предотвращение трансляции

Предотвращение трансляции события клиентам:

event.SetBroadcast(false);

Отмена события

В хуке pre-события вы можете предотвратить передачу события другим плагинам, вернув ResultType.Handled или ResultType.Stop.

public void OnPluginStart()
{
    HookEvent("player_death", OnPlayerDeathPre, HookMode.Pre);
}

private static ResultType OnPlayerDeathPre(string name, nint @event, bool dontBroadcast)
{
    EventInfo event = new EventInfo(@event);
    int victim = event.GetPlayerSlot("userid");

    // Отмена события смерти для игроков-администраторов
    if (IsPlayerAdmin(victim))
    {
        PrintToServer("Prevented admin death event\n");
        return ResultType.Handled;
    }

    return ResultType.Continue;
}