-
Notifications
You must be signed in to change notification settings - Fork 0
API UO SetEvent
ClassicUO / Basic IDE
Оглавление · Все команды · Scripts & Runtime
Включает или выключает наблюдение за изменениями состояния персонажа и позволяет выбрать одноразовую либо повторяющуюся реакцию. Например, можно один раз отменить оставшийся target после смерти или получать предупреждения о низкой выносливости. Обработчик задаётся отдельно от условия; основной скрипт должен продолжать выполнять UO.Wait.
UO.SetEvent(name:Any, stateValue:Any) -> Unit
UO.SetEvent(name:Any, stateValue:Any, repeatOrHandler:Any) -> Unit
UO.SetEvent(nameValue:Any, stateValue:Any, repeatValue:Any, subNameValue:Any) -> Unit
Выберите одну из зарегистрированных форм. Параметры передаются позиционно. Any означает значение BASIC с преобразованием внутри команды; Unit — отсутствие возвращаемого значения.
-
name— Строка с одним из пяти имён: ChangeHitPoints, ChangeMana, ChangeStamina, Death, SeeNewPlayer. Регистр не важен; допустим префикс ev, например evChangeMana. Пробелы по краям удаляются. Числового каталога событий нет; произвольное имя не создаёт новое событие. -
nameValue— То же имя события, что name; это название первого параметра в форме с четырьмя аргументами, не дополнительное значение. -
stateValue— True/1 включает наблюдение, False/0 снимает подписку. Передавайте логические значения без кавычек. При числовом преобразовании любое ненулевое целое включает наблюдение. Отключение не ждёт и не останавливает уже запущенный обработчик. -
repeatOrHandler— Третий аргумент имеет два назначения. Нечисловая непустая строка, например "OnManaChanged", задаёт обработчик с автоматическим повторением. Число/Boolean задаёт только повтор: False/0 — одно срабатывание, True/1 — повторять; обработчик в этой форме не назначается. Строка "1" тоже числовая и не является именем процедуры. Для одноразового обработчика используйте четыре аргумента. -
repeatValue— В форме с четырьмя аргументами: False/0 — удалить подписку после первого обнаруженного перехода, True/1 — оставить её для следующих изменений. Одноразовая подписка снимается и тогда, когда обработчик не найден либо менеджер отклонил его запуск; не путайте обнаружение события с успешным завершением процедуры. -
subNameValue— Строка — имя загруженной доступной процедуры SUB без обязательных аргументов, например "OnHealthChanged". Передаётся имя, а не вызов со скобками. Пустая/пробельная строка при stateValue=True включает наблюдение БЕЗ обработчика. Для отключения передайте stateValue=False. Допустимые совместимые префиксы "exec " и "_exec " удаляются; предпочтительнее простое имя. Процедура должна присутствовать в загруженном скрипте, не быть Private и успешно проходить проверку.
Unit — значения нет. Вызывайте отдельной строкой, без VAR result = и без сравнения с True/1. Завершение регистрации не подтверждает, что обработчик найден, запущен или что сервер совершил действие. Если имя процедуры не найдено при событии, вызов не происходит.
- Два аргумента: False отключает событие; True включает повторяющееся наблюдение без обработчика. Никакая процедура с совпадающим именем автоматически не подставляется. Эта форма не возвращает обнаруженный факт и не заменяет проверку HP/Mana/Dead.
- Три аргумента: непустая строка, не распознаваемая как целое число, трактуется как имя процедуры и включает повторение; числовое значение/Boolean задаёт repeat без обработчика. Для ясного рабочего сценария передавайте имя SUB либо используйте все четыре аргумента.
- Четыре аргумента явно задают имя события, включение, повторение и обработчик. Оба логических параметра пишутся без кавычек. FALSE/0 = one-shot: подписка снимается после первого обнаруженного перехода, а не после окончания обработчика.
- Повторная регистрация одного события заменяет его прежние настройки и запоминает текущее состояние как новую точку отсчёта. Подписки SetEvent и SetEventProc на одно нормализованное имя внутри одного скрипта используют одну запись, не накапливаются.
- ChangeHitPoints сравнивает текущее HP self с предыдущим снимком; срабатывает и при потере, и при восстановлении здоровья. ChangeMana и ChangeStamina аналогично реагируют в обе стороны. Это не только урон, расход маны или усталость.
- Death срабатывает при переходе живой → мёртвый. Регистрация уже мёртвого персонажа не вызывает обработчик сразу; повторная смерть после воскрешения может вызвать его снова.
- SeeNewPlayer сравнивает набор загруженных mobiles, исключая 0 и self. Название не означает проверку реального игрока: сюда входят NPC и существа. Один или несколько новых serial за одну проверку вызывают одну попытку запуска. Возврат ушедшего из загруженного набора mobile также может считаться новым появлением. ID не передаётся обработчику — нужные объекты надо найти отдельно.
- UO.Wait делит ожидание на интервалы до 25 мс и после каждого проверяет события; Wait(0) тоже выполняет проверку. Это опрос доступного состояния, а не перехват каждого сетевого пакета: быстрое изменение и возврат между проверками может быть пропущено. В вычислительном цикле без UO.Wait или после завершения Main постоянного наблюдения нет.
- Обработчик запускается через менеджер процедур, отдельно от ожидающего Main. Не рассчитывайте на его синхронное завершение или общий локальный VAR. Повторный запуск уже работающей процедуры и настройка запрета наложения процедур могут блокировать запуск. Держите обработчики короткими; при включённом запрете параллельных процедур проверяйте состояние прямо в основном цикле.
- Подписка относится к экземпляру выполняющегося скрипта. Снимайте её в Main, который её создал: одноимённая команда внутри отдельно запущенного обработчика изменит его собственные подписки. Отмена регистрации не останавливает уже запущенный обработчик. Используйте TRY/FINALLY для обычного выхода или обрабатываемой ошибки; принудительная остановка также прекращает дальнейший опрос этого скрипта.
- Неизвестное непустое имя события при регистрации отклоняется с системным сообщением. Пустое имя ничего не делает. Наличие обработчика проверяется только при срабатывании; ошибку в его имени лучше обнаружить заранее через SubExists и проверку скрипта в IDE.
Ниже описана реализация этого движка. Имена внутренних методов не являются дополнительными командами BASIC.
Нормализует имена и сохраняет начальный снимок состояния через CaptureLegacyEventSnapshot.
Неподдерживаемое событие не остаётся активным; новый обработчик заменяет прежний для этого имени.
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/InjectionApiUO.cs; функция SetEvent.
Читает HP, mana, stamina, dead и загруженные mobiles, исключая self и 0.
Создаёт начальные значения для обнаружения последующих изменений.
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/InjectionApiUO.cs; функция CaptureLegacyEventSnapshot.
Разбивает ожидание на интервалы до 25 мс. После каждого вызывает DispatchLegacyEvents; нулевое ожидание также выполняет проверку.
Скрипт даёт клиенту возможность обновить состояние и обработать отмену.
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/InjectionApiUO.cs; функция WaitWithEvents.
Сравнивает новый снимок с предыдущим. Для группы новых mobiles хватает одного нового serial. Обновляет снимок и проверяет наличие процедуры.
При обнаруженном изменении вызывает bridge.Exec(handler). Параметры события не передаются; повторяющаяся подписка остаётся.
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/InjectionApiUO.cs; функция DispatchLegacyEvents.
Находит загруженную процедуру и передаёт её менеджеру.
Если процедура не найдена, запуск не происходит.
Исходник проекта: src/ClassicUO.Client/Game/Managers/ClassicUOInjectionApiBridge.cs; функция Exec.
Проверяет доступность, параметры, отмену и ограничения одновременных запусков.
Запуск асинхронный; Unit не является подтверждением завершения обработчика.
Исходник проекта: src/ClassicUO.Client/Game/Managers/YokoInjectionManager.cs; функция RunProcedure.
Формы с двумя и тремя аргументами приводятся к SetEvent(name, state, repeat, handler). Примеры ниже содержат все обработчики и отключают подписки при выходе.
SUB OnFirstDeath()
# Обработчик запускается отдельно и не получает аргументов.
IF UO.Targeting() THEN
UO.CancelTarget()
UO.Print("Death detected: active targeting cancelled")
ELSE
UO.Print("Death detected: no active target")
END IF
END SUB
SUB Main()
# True — включить; False — только первое изменение живой -> мёртвый.
UO.SetEvent("Death", True, False, "OnFirstDeath")
TRY
UO.Wait(8000)
FINALLY
# Полезно и если смерти не было: не оставляем подписку активной.
UO.SetEvent("Death", False)
END TRY
END SUBРазбор параметров и выполнения:
- Наблюдение длится восемь секунд. Death уже мёртвого персонажа не вызывает обработчик немедленно. Второе событие смерти после воскрешения в этом примере уже не обрабатывается.
- Обработчик проверяет активный курсор цели в момент выполнения и только тогда вызывает CancelTarget. Подготовленная очередь без активного курсора в этом примере не отменяется. Скрипт не воскрешает персонажа, не останавливает все скрипты и не завершает Main. Не запускайте пример, если хотите сохранить активную цель.
SUB OnFatigue()
# Событие означает любое изменение, а IF выбирает низкое значение.
VAR staminaNow = UO.Stamina()
IF staminaNow < 10 THEN
UO.Print("Stamina is " + CStr(staminaNow) + ": consider resting")
END IF
END SUB
SUB Main()
# Строка в третьем аргументе задаёт SUB; повторение включено.
UO.SetEvent("evChangeStamina", True, "OnFatigue")
TRY
FOR tick = 1 TO 24
UO.Wait(250)
NEXT
FINALLY
# evChangeStamina и ChangeStamina — одно нормализованное имя.
UO.SetEvent("ChangeStamina", False)
END TRY
END SUBРазбор параметров и выполнения:
- 24 × 250 мс — шесть секунд. 10 — наш порог в обработчике, не дополнительный аргумент SetEvent. Рост выносливости также вызывает обработчик, но при значении от 10 сообщение не выводится.
- True, "OnFatigue" отличается от True, True: последний вариант задаёт повторение без процедуры. Скрипт не повышает выносливость и не меняет скорость сервера.
SUB OnManaLog()
UO.Print("Mana now: " + CStr(UO.Mana()))
END SUB
SUB OnLowMana()
# Во второй фазе предупреждаем только о низком значении.
IF UO.Mana() < 20 THEN
UO.Print("Mana below 20: check the cost before casting")
END IF
END SUB
SUB Main()
UO.SetEvent("ChangeMana", True, True, "OnManaLog")
TRY
UO.Wait(2000)
# Заменяем обработчик; OnManaLog больше не запускается.
UO.SetEvent("ChangeMana", True, True, "OnLowMana")
UO.Wait(3000)
FINALLY
UO.SetEvent("ChangeMana", False)
END TRY
END SUBРазбор параметров и выполнения:
- Первые две секунды каждое обнаруженное изменение вызывает OnManaLog. Следующие три секунды используется OnLowMana. Регистрация второго обработчика сама по себе его не запускает.
- Замена не прерывает уже запущенную старую процедуру. Эти короткие обработчики не используют локальные переменные Main. При запрете наложения процедур менеджер может отклонить запуск — для такого режима проверяйте Mana прямо в Main.
ClassicUO
Bad Newbie & Basic IDE
Найти в справочнике
Клиент и скрипты
Каталоги значений
Разработка и помощь