Уроки - Функции и обратно-вызываемые события

## Знакомство

#### **Функции.**

Каждая функция выполняет какую-либо задачу. Это может быть как проработанный разработчиком платформы алгоритм с использованием игровых данных, так и собственноручно написанная. Говоря более проще: функции - это и есть те самые скрипты, или наоборот - помощники для написания скриптов. Список основных функций платформы вы можете посмотреть на главной странице вики.

#### **Обратно-вызываемые события.**

Здесь дело обстоит иначе. Событиями называют функции, которые вызываются автоматически при выполнении какого-либо действия, что затрагивает это событие (колбек в будущем). К примеру рассмотрим колбек `OnGameModeInit()`. Он отвечает за то, что сервер загружает сразу после чтения файла `gmp_server.ini`. Соответственно и срабатывает это событие в момент запуска сервера. Иной пример с колбеком `OnPlayerConnect()`: срабатывает, когда игрок/бот подключается к серверу. Список основных событий вы можете посмотреть на главной странице вики.

## Изучение

Открываем файл `new.lua` в папке `gamemodes` нашего сервера и проверяем кодировку (об этом в прошлых уроках). Далее изучаем содержимое. Перед глазами неполный ряд существующих событий, с которыми мы можем работать. Чтобы лучше понимать как устроены обратно-вызываемые события, воспользуемся уже используемой функцией "`SendPlayerMessage(playerid, r, g, b, string)".`

В колбеке `OnPlayerConnect(playerid)` ищем строчку с вышеуказанной функцией.

```
function OnPlayerConnect(playerid) -- начало/обратно-вызываемое событие (колбек)
	SendPlayerMessage(playerid, 0, 255, 0, "Welcome to my server! :>"); -- функция отправки КОНКРЕТНОМУ игроку сообщения с указанием цвета.
end -- конец события.

```

Большинство различных функций требуют указания аргументов. Аргументы сравнимы с параметрами для использования функции. В данной функции задано 5 аргументов:

1. `ID игрока (в данном случае playerid - это игрок, который подключается к серверу);`
2. `Цвет по red;`
3. `Цвет по green;`
4. `Цвет по black;`
5. `Строковое сообщение (пишется в кавычках).`

В результате получается следующее: когда игрок подключается к серверу, срабатывает обратно-вызываемое событие `OnPlayerConnect`, после чего этому игроку отправляется сообщение в чат в заданном цвете. При желании можно задать любой цвет по RGB (палитра).

После отправки сообщения в чат, обратимся к другой функции - `SpawnPlayer()`. Она отвечает за полный спавн игрока и так же имеет 5 аргументов:

1. `ID (playerid);`
2. `float x = 0;`
3. `float y = 0;`
4. `float z = 0;`
5. `angle = 0`

Но прошу учесть важную деталь: существуют аргументы, которые уточнять НЕ обязательно. Функция сработает и без них. На практике количество таких функций можно пересчитать на пальцах.

Сразу после функции отправки сообщения в чат, вставим новую функцию спавна и укажем аргумент `playerid`. На выходе получится следующее:

```
function OnPlayerConnect(playerid) -- начало/обратно-вызываемое событие (колбек)
	SendPlayerMessage(playerid, 0, 255, 0, "Welcome to my server! :>"); -- функция отправки КОНКРЕТНОМУ игроку сообщения с указанием цвета.
    SpawnPlayer(playerid); -- заспавнить игрока в мире
end -- конец события.

```
Теперь игрок при заходе на сервер будет получать сообщение в чат и будет отспавнен. Если же не использовать функцию спавна то появятся проблемы синхронизации игроков. Но помимо этого, функция `SpawnPlayer()` напрямую связана с обратно-вызываемым событием `OnPlayerSpawn()`.
Связаны они потому, что `OnPlayerSpawn()` - событие, вызываемое при спавне игрока. Соответственно, в нем тоже можно использовать какие-либо функции. Колбек имеет один аргумент - `playerid`. По умолчанию, в файле уже будет прописано действие отправки сообщения в чат при спавне.

```
function OnPlayerSpawn(playerid) -- начало события
	SendPlayerMessage(playerid, 0, 255, 255, "Spawned"); -- функция отправки сообщения конкретному игроку, на которого сработал колбек.
end -- конец события.

```
Обратите внимание на важную вещь: нельзя дублировать колбеки во избежании конфликтов с работе сервера. Если нужно использовать разные проверки или добавить новую функцию - делайте все в одном блоке (событии), не создавая дубликатов.

## Заключение

Теперь посмотрим на чат в игре при заходе на сервер. Не забудьте, что каждое изменение файла new.lua (или того, который вы используете как `gamemode`), требует сохранения и перезапуска сервера.