RU/Event system
Система событий лежит в основе MTA-скриптинга. События тесно связаны с деревом элементов. События срабатывают, когда что-либо происходит: игрок встаёт на маркер, выбирается элемент и т.д. Каждое событие имеет исходный элемент, а именно элемент, который выполнил действие
Обработчики событий
Чтобы использовать систему событий, Вы присоединяете обработчики событий к элементам в дереве элементов с помощью функции addEventHandler. Когда Вы это сделаете, Ваша функция будет активирована для всех событий, инициированных этим элементом, это родители (и их родители) и дети (и их дети). Таким образом, обработчик событий, прикрепленный к корневому элементу, запускается, когда событие происходит для любого элемента. Как правило, Вы должны обычно использовать специфичный обработчик, как можете. Если Вы хотите просто увидеть, когда игрок встаёт на определённый маркер, просто присоедините обработчик события к этому маркеру.
Каждый обработчик событий имеет три "скрытые" переменные:
- source. Это элемент, от которого произошло событие.
- this. Это элемент, на который запускается обработчик (т.е. тот, к которому Вы привязывали его функцией addEventHandler).
- eventName. Это строка имени события, которое было вызвано (т.е имя, которое было добавлено функцией addEventHandler).
Кроме того, серверная система событий также имеет ещё одну "скрытую" переменную:
- client: Это клиент, который вызвал событие с помощью функции triggerServerEvent. Это значение не задано, если событие не было инициировано клиентом.
Исходная переменная является наиболее важной для большинства обработчиков. Вы почти всегда захотите ссылаться на эту переменную, чтобы сообщить, какой элемент вызвал событие. Эта переменная используется для обеспечения того, чтобы событие было вызвано элементом, к которому присоединён обработчик.
Важно отметить, что события следуют за иерархией элементов. Все события изначально запускаются в элементе source, за которым следуют все родительские и дочерние элементы. Это имеет несколько важных последствий:
- Событие, инициированное на корневом элементе, будет инициировано для каждого элемента в дереве элементов. Этого следует избегать, когда это возможно.
- Все события в любом месте дерева элементов будут инициированы на корневом элементе. Это означает, что вы можете легко поймать каждое событие типа, связав обработчик с корневым элементом. Это следует делать только в том случае, если действительно требуется любое событие этого типа, иначе же прикрепите его к более специфичному элементу дерева элементов.
- Вы можете прикрепить обработчик события к корневому элементу вашего ресурса, чтобы получить все события, инициированные элементами, содержащими Ваш ресурс.
- Вы можете создавать фиктивные элементы для захвата событий из группы дочерних элементов.
- Вы можете использовать фиктивные элементы, указанные в файле .map (например, <flag>) и создать для них реальные представления (например, объекты), и сделать эти реальные элементы дочерними элементами фиктивного элемента. Обработчики событий затем могут быть прикреплены к фиктивному элементу и будут получать все события реальных элементов. Это полезно, когда один ресурс управляет представлением элемента (например, создавая объекты), а другой хочет обрабатывать специальные события. Это может быть ресурс карты, который хочет обработать флаг, захваченный определенным образом. Ресурс карты, как правило, не будет знать о том, как представлен флаг. Это не имеет значения, поскольку он может просто привязывать обработчики к своему фиктивному элементу флага, в то время как другой ресурс игрового режима может обрабатывать представление.
Функция, которую Вы привязали к событию, вызывается и передает множество аргументов. Эти аргументы специфичны для событий. Каждое событие имеет определенные параметры, например onClientGUIClick имеет 4 параметра.
string button, string state, int absoluteX, int absoluteY
Функция, которую Вы привязали к этому событию, будет передана этими параметрами в качестве аргументов. Вы должны помнить, что каждое событие имеет разные параметры.
Встроенные события
MTA имеет ряд встроенных событий. Они перечислены на страницах "Клиентские события скриптинга" и "Скриптинговые события".
Пользовательские события
Вы можете создавать свои собственные события, которые могут запускаться во всех ресурсах. Это важный способ связаться с другими ресурсами и позволить им подключиться к вашему коду. Чтобы добавить свое собственное событие, просто вызовите функцию addEvent. Затем Вы можете использовать функцию triggerEvent для запуска этого события в любое время: либо с использованием таймера, либо на основе более общего события.
Например, Вы можете сделать игровой режим Capture the Flag и вызвать событие, когда игрок фиксирует флаг. Вы можете сделать это, связав обработчик события со стандартным событием MTA onMarkerHit и проверив, что игрок, входящий в маркер, имеет флаг. Если Вы сделаете это, Вы можете затем запустить своё более специфическое событие onFlagCaptured, и другие ресурсы смогут справиться с этим, как им заблагорассудится.
Отмена событий
События могут быть отменены с помощью функции cancelEvent. Это может иметь множество последствий, но в целом это означает, что сервер не будет выполнять никаких действий, которые обычно выполняются. Например, отмена события onPickupUse не позволит игроку использовать пикап, отмена события onVehicleStartEnter помешает игроку войти в транспорт. Вы можете проверить, было ли отменено текущее активное событие, используя функцию wasEventCanceled. Важно отметить, что событие отмены не предотвращает запуск других обработчиков событий.