Форварды: события для других плагинов
Форвард — событие, которое один плагин поднимает, а другие слышат, и на TypeScript, и на Pawn. Так плагин сообщает остальному серверу, что начался раунд его режима, что игрок что-то купил, что изменилась настройка.
const bought = new Forward<Player, string>("myplugin_on_bought");
server.addCommand("/buy <item>", ({ player, item }) => {
bought.emit(player, item);
});
Параметры типа — аргументы форварда, до 32 — столько, сколько AMX Mod X
даёт форварду: new Forward("myplugin_on_start") без аргументов,
new Forward<Player, string> — с двумя. emit передаёт их всем, кто слушает, и возвращает true, если
форвард ушёл.
Плагин на Pawn слышит его как любой форвард — публичной функцией с этим именем:
public myplugin_on_bought(id, const item[])
{
client_print(id, print_chat, "Ты купил %s", item);
}
Подписка из TypeScript
const bought = new Forward<Player, string>("myplugin_on_bought");
bought.subscribe((player, item) => {
console.log(`${player.name} купил ${item}`); // player: Player, item: string
});
bought.subscribe(onBought);
bought.unsubscribe(onBought);
function onBought(player: Player) { // параметров может быть меньше, чем у форварда
console.log(`${player.name} что-то купил`);
}
Другой плагин создаёт Forward с тем же именем и типами и подписывается на
него. Параметры обработчика получают типы форварда, поэтому стрелке аннотации
не нужны, а обработчик не того типа — ошибка в редакторе. Плагин может
подписаться и на форвард, который поднимает сам.
Форвард, поднятый плагином на TypeScript, доходит до всех подписчиков. Форвард, который поднимает плагин на Pawn, доходит до TypeScript, если он объявлен в include, который идёт с amxts, — из AMX Mod X, ReAPI и модулей, которые поддерживает amxts.
Типы аргументов
| Параметр типа | Что получает Pawn |
|---|---|
number | целое число |
boolean | 1 или 0 |
string | строку |
Player | индекс игрока; подписчик получает Player |
Team | номер TeamName: "UNASSIGNED" 0, "TERRORIST" 1, "CT" 2, "SPECTATOR" 3 |
RoundWinner | номер WinStatus: "none" 0, "CT" 1, "TERRORIST" 2, "draw" 3 |
Float или number, где include пишет Float: | Float |
number[] | массив; из Float, где include пишет Float: |
Vector | массив из трёх Float |
Для Team и RoundWinner нужно объявление форварда в include:
собственном include плагина
(plugin({ include }))
или в одном из тех, что знает сборка. Сборка читает из него, как передаётся
каждый аргумент:
// в myplugin.inc: forward myplugin_on_joined(id, TeamName:team);
const joined = new Forward<Player, Team>("myplugin_on_joined");
joined.emit(player, "CT"); // Pawn получит (id, 2)
joined.subscribe((player, team) => console.log(`${player.name}: ${team}`)); // team: "CT"
Сборка останавливается, называя место и причину, когда:
- у
TeamилиRoundWinnerнет объявления, которое сказало бы, какой это номер; RoundWinnerобъявлен не какWinStatus:;stringобъявлена числом (TeamName:team);- массив объявлен числом;
- массив объявлен без тега (
const data[3]): Pawn передаёт такой как текст — дайте ему тег,Float:data[3]; - в объявлении другое число аргументов.
Форвард, которого нет ни в одном include, передаётся так, как говорят его типы.
Pawn передаёт массив без его размера. Массив в форварде, который поднимает плагин на Pawn, доходит до подписчика целиком, если include указывает размер (
Float:origin[3]); массив без размера приходит пустым.Когда форвард создаётся
Форвард создаётся при первом emit или раньше, через create(). Плагины на
Pawn, которые его слушают, AMX Mod X находит в момент создания, поэтому
поднимайте его не раньше, чем загрузятся все плагины, — в событии "pluginsLoaded" или
позже. Подписка форвард не создаёт.
Остановка
const vote = new Forward<Player>("myplugin_vote");
vote.stopWhen = "handled";
С "handled" первый обработчик на Pawn, который вернёт PLUGIN_HANDLED,
останавливает форвард: обработчики после него его не слышат. По умолчанию —
"never": слышат все. Задайте это до первого emit.
События игры
То, что происходит в игре, — игрок получает урон, возрождается, умирает, покупает оружие, бросает гранату, раунд заканчивается, — это события на game. Обработчик слышит событие до того, как игра что-то сделает, и может пропустить его, изменить, остановить или ответить вместо игры:
Async и промисы
Плагин ждёт так же, как JavaScript: async-функции, await, Promise. Пока одна функция ждёт — ответа на веб-запрос, пару секунд, — сервер и остальной плагин продолжают работать.