Pushistik↯❤
Команда форума
- Регистрация
- 6 Июл 2017
- Сообщения
- 393
- Реакции
- 97
- Баллы
- 28
[SourcePawn] Урок 3 - События (Events)
<= К содержанию
В SourceMod есть встроенные события:- OnMapStart (старт карты)
- OnMapEnd (конец карты)
- OnPluginStart (запуск плагина)
- OnPluginEnd (остановка плагина)
- OnClientConnected (игрок подключился)
- OnClientDisconnect (игрок отключился)
- и много других
- Отлов событий
Чтобы отловить событие необходимо знать его имя. Его можно узнать здесь Game Events (Source) - AlliedModders Wiki
Существует 3 режима отлова событий:- EventHookMode_Pre - Обратный вызов происходит до того, как событие произойдет
- EventHookMode_Post - Обратный вызов происходит после того как, событие произошло (Используется по умолчанию)
- EventHookMode_PostNoCopy - Обратный вызов происходит после того как, событие произошло, но данные события не копируются. Используется для оптимизации, например, когда нужно знать что событие произошло, но не нужно получать его параметры
Есть 2 функции для отлова событий.
Синтаксис:PHP:void HookEvent(const char[] name, EventHook callback, EventHookMode mode); [/LIST] bool HookEventEx(const char[] name, EventHook callback, EventHookMode mode);
- name - Имя события
- callback - Имя функции обратного вызова
- mode - Режим отлова (см. выше)
Функции обратных вызовов для событий бывают 2-х видов:- Для EventHookMode_Post и EventHookMode_PostNoCopy:
PHP:
function void(Event event, const char[] name, bool dontBroadcast)
- event - Объект типа Event, который содержит данные о событии (для EventHookMode_PostNoCopy равен null, но в действительности это не работает)
- name - Имя события
- dontBroadcast - Было ли передано событие клиентам (true если не было, противном случае - false)
- Для EventHookMode_Pre:
PHP:
function Action(Event event, const char[] name, bool dontBroadcast)
Тип Action может иметь значения:- Plugin_Continue - Разрешает продолжение события без изменений
- Plugin_Changed - Разрешает продолжение события с изменениями
- Plugin_Handled - Запрещает выполнение события, разрешая обрабатывать остальные вызовы
- Plugin_Stop - Запрещает выполнение события и обработку остальных вызовов
Сами события запретить нельзя, можно лишь запретить вывод уведомлений о них (сообщения об убийстве справа вверху, сообщение в чат при подключении/отключении игроков)
Тип Event является дочерним от типа Handle
Его свойства и методы для работы с ним можно посмотреть здесь: Event · events · SourceMod Scripting API Reference
Примеры работы с событиями:
PHP:#pragma semicolon 1 #include <sourcemod> #pragma newdecls required public void OnPluginStart() { HookEvent("player_death", Event_PlayerDeath); // Ловим событие с именем player_death // Event_PlayerDeath это имя функции, которая будет вызвана когда на сервере произойдет это событие // Мы не указали режим отлова, это значит что по умолчанию он будет EventHookMode_Post } public void Event_PlayerDeath(Event hEvent, const char[] sEvName, bool bDontBroadcast) // Функция будет вызвана когда на сервере произойдет событие player_death { // Параметры события: https://wiki.alliedmods.net/Counter-Strike:_Source_Events#player_death int iUserID = hEvent.GetInt("userid"); // userid жертвы PrintToServer("userid: %i", iUserID); int iAttackerUserID = hEvent.GetInt("attacker"); // userid убийцы PrintToServer("attacker: %i", iAttackerUserID); char szWeapon[34]; hEvent.GetString("weapon", szWeapon, sizeof(szWeapon)); // название оружия PrintToServer("weapon: %s", szWeapon); int bHS = hEvent.GetBool("headshot"); // В голову ли (true - да, иначе - false) PrintToServer("headshot: %b", bHS); }
PHP:public void OnPluginStart() { HookEvent("player_spawn", Event_PlayerSpawn); // Ловим событие с именем player_spawn // Event_PlayerSpawn это имя функции, которая будет вызвана когда на сервере произойдет это событие // Мы не указали режим отлова, это значит что по умолчанию он будет EventHookMode_Post } public void Event_PlayerSpawn(Event hEvent, const char[] sEvName, bool bDontBroadcast) // Функция будет вызвана когда на сервере произойдет событие player_spawn { int iUserID = hEvent.GetInt("userid"); // *1 int iClient = GetClientOfUserId(iUserID); // *2 if(iClient) // Аналогично if(iClient != 0) *3 { PrintToChat(iClient, "Вы возродились!"); // *4 } }
Находим наше событие на wiki Generic Source Events - AlliedModders Wiki
Смотрим его параметры:
У нашего события всего 1 параметр типа short. В SourcePawn он приводится к типу int
Параметр имеет имя userid
userid это уникальный идентификатор игрока на сервере.
При запуске сервера первый вошедший игрок получает userid - 1, второй - 2, третий - 3
Если первый игрок перезайдет он получит userid - 4.
И так будет происходить до тех пор пока не произойдет перезапус сервера и всё начнется сначала.
У сервера userid всегда 0
В строке *1 мы получаем параметр userid- iUserID - имя нашей перменной
- hEvent - имя объекта типа Event, который был передан в функции
- GetInt - метод для типа Event, который получает целочисленное значения параметра переданого его как аргумент
- userid - это имя параметра
Все функции для работы с игроками требуют как аргумент индекс игрока.
Индекс - это номер игрока на сервере.
Он может быть от 1 до MaxClients. MaxClients это константа, которая хранит количество слотов на сервере.
Следовательно индекс игрока может быть от 1 до количества слотов.
У сервера индекс всегда 0.
Значит нам нужно получить индекс игрока.
Для работы с userid есть 2 фукнции:- Возвращает userid игрока, из его индекса (его передаем как аргумент)
PHP:
int GetClientUserId(int client)
- Возвращает индекс игрока, из его userid (его передаем как аргумент)
PHP:
int GetClientOfUserId(int userid)
У нас есть userid, а нужен индекс, значит используем вторую функцию (строка *2)
Помним что если userid не существует функция вернет 0, поэтому проверяем получили ли мы индекс игрока (строка *3)
Если условие истинно - наш игрок появился на карте (спавнился).
Строки *1 и *2 можно объединить в одну:PHP:int iClient = GetClientOfUserId(hEvent.GetInt("userid"));
Например, сообщим ему что он возродился с помощью функции PrintToChat (строка *4)
Пример 2:
PHP:#pragma semicolon 1 #include <sourcemod> #pragma newdecls required public void OnPluginStart() { HookEvent("player_death", Event_PlayerDeath, EventHookMode_Pre); } public Action Event_PlayerDeath(Event hEvent, const char[] sEvName, bool bDontBroadcast) { // Параметры: https://wiki.alliedmods.net/Counter-Strike:_Source_Events#player_death if (hEvent.GetBool("headshot")) { return Plugin_Handled; } return Plugin_Continue; }
Этот код будет блокировать вывод сообщения об убийстве (справа вверху) если убийство было произведено в голову.
Пример 3:
PHP:#pragma semicolon 1 #include <sourcemod> #pragma newdecls required public void OnPluginStart() { HookEvent("player_death", Event_PlayerDeath, EventHookMode_Pre); } public Action Event_PlayerDeath(Event hEvent, const char[] sEvName, bool bDontBroadcast) { hEvent.SetBool("headshot", true); return Plugin_Changed; }
- Отправка событий
PHP:void SendDeathMessage(int iAttacker, int iVictim, const char[] sWeapon, bool bHeadShot) { Event hEvent = CreateEvent("player_death"); // Имя события if (hEvent != null) { hEvent.SetInt("userid", GetClientUserId(iVictim)); // userid жертвы hEvent.SetInt("attacker", GetClientUserId(iAttacker)); // userid убийцы hEvent.SetString("weapon", sWeapon); // Название оружия hEvent.SetBool("headshot", bHeadShot); // В голову ли hEvent.Fire(true); // true - отправит сообщение игрокам } }
Последнее редактирование: