Runtime API Usage - LIHACHTETAN/ClassicUO-BadNewbie-BasicIDE GitHub Wiki

Практическое использование Runtime API

Оглавление · Все имена · Файловые объекты

Имена, типы и перегрузки

Справочник описывает команды runtime этого проекта. Регистр не важен: UO.Info() и uo.info() означают одно и то же. Игровые команды записываются с префиксом UO.; встроенные функции BASIC — без него. Короткие имена игровых команд не используются. Пользовательские SUB/FUNCTION из AutoLoad могут иметь свои названия и параметры.

В карточке перечислены все зарегистрированные сигнатуры. Any — динамическое значение runtime; это не разрешение передавать произвольную строку вместо координаты. Integer — 32-битное знаковое целое, Decimal — число с плавающей точкой. Логические результаты в этом BASIC обычно представлены числами 1/0. Unit означает отсутствие результата: вызов выполняют отдельной строкой.

Для координат используйте UO.X(), UO.Y(), UO.Z() либо соответствующие формы UO.GetX(...), UO.GetY(...), UO.GetZ(...). Переменные x, y, z остаются пользовательскими переменными. Константы, например RightHand, читаются без скобок; не путайте их с вызовами функций.

Serial, цвета, координаты и индексы

  • Serial — идентификатор объекта, graphic/body — его внешний тип, color/hue — цвет. Это разные числа.
  • Используйте десятичную или 0x/0X запись. Старший бит hex-serial сохраняется при хранении в Integer. Для InfoGump только -1 зарезервирован под выбранное/последнее окно.
  • self, backpack, lasttarget и другие именованные объекты зависят от текущего состояния клиента. UO.Exists проверяет загруженный объект, а не всё содержимое мира сервера.
  • 0/-1 не имеют общего значения для всех команд. В поиске -1 часто означает отсутствие фильтра, в другой команде это может быть ошибка или специальный селектор.
  • Массивы Basic индексируются с 0. GetJournal(0) возвращает самую новую строку. У mid две разные системы: mid(text,start) — с 1; mid(text,start,length) — с 0.
  • Время обычно задаётся в миллисекундах, но UO.Timer() и Ticks* используют десятые доли секунды, Timer() — секунды, Now() — миллисекунды с запуска runtime.

Три разных сценария target

Подготовить автоматическую цель до действия:

UO.WaitTargetObject('self')
UO.Cast('Heal')

Дождаться уже запрошенного сервером прицела и ответить:

IF UO.WaitForTarget(3000) THEN
    UO.TargetToObject(self)
ELSE
    UO.CancelTarget()
END IF

Попросить пользователя выбрать объект в клиенте:

UO.ClientRequestObjectTarget()
IF UO.WaitForClientTargetResponse(10000) THEN
    VAR response = UO.ClientTargetResponse()
    IF GetArrayLength(response) = 5 THEN
        UO.Info(response[0])
    ELSE
        UO.Print('Selection canceled or invalid')
    END IF
END IF

ClientTargetResponse — массив [serial, graphic, x, y, z]. Завершившийся запрос может содержать пустой массив: это отмена или неподходящий выбор. Старый callback не заменяет ответ нового запроса.

Информация об объектах и окнах

UO.Info() включает выбор предмета/персонажа и затем показывает окно информации. UO.Info(serial) выводит сведения сразу в журнал. InfoTile() предназначен для земли и статики. InfoGumps() показывает список серверных окон, InfoGump() — подробный инспектор одного окна.

UO.InfoGumps()
IF UO.GetGumpCount() > 0 THEN
    UO.InfoGump(0)
END IF

InfoCounsel, InfoCom, PortTarget и WaitForTile не являются зарегистрированными именами этой версии. Если они встречаются в пользовательском AutoLoad, это отдельные процедуры. Команда управления окном называется UO.ActivateHandle(); для применения предмета служит UO.UseObject.

UO.Hide() скрывает выбранный объект локально. Для навыка скрытности используется UO.UseSkill('Hiding').

Движение и обход

UO.Move() сообщает состояние движения. Для маршрута используйте MoveXY, NewMoveXY или MoveXYZ. Возврат 1 означает, что конечная точка достигнута с заданными допусками; возврат 0 нужно обрабатывать.

# Пример точки рядом с персонажем; проверьте геометрию карты.
VAR destinationX = UO.GetX() + 3
VAR destinationY = UO.GetY()
# callback=0, timeout=5000 мс, maxSteps=20
VAR arrived = UO.NewMoveXY(destinationX, destinationY, 1, 0, 0, 0, 5000, 20)
IF arrived = 0 THEN
    UO.Print('Route was not completed')
END IF

Ползунки Bad Newbie (обход 1–5 и просмотр вперёд 0–5) относятся к ручному движению мышью. Скриптовые MoveXY/NewMoveXY используют собственный A*. Optimized включает четырёхклеточную проверку запланированного пути. PMove является старым пошаговым маршрутом; его третий аргумент z в не используется.

Поиск и массивы

В этой реализации FindAnyType ищет персонажей, а не предметы. Для предметов используйте соответствующие FindType/FindTypeEx/FindTypesArrayEx. FindAnyType возвращает один serial, а не массив.

DIM bodies(2)
bodies[0] = 0x0190
bodies[1] = 0x0191
VAR mobile = UO.FindAnyType(10, bodies)
IF mobile <> 0 THEN
    UO.Info(mobile)
END IF
DIM values(3)
values[0] = 10
values[1] = 20
values[2] = 30
IF ArrayContains(values, 20) THEN
    UO.Print('20 is present')
END IF

ArrayContains возвращает 1/0. Нельзя передавать его числовой результат в GetArrayLength как массив. GetMultis тоже требует внимания: возвращает массив serial multi-объектов, а не Pascal-записи TMultiItem.

Совместимые имена с ограниченным действием

Имя Что реально делает
messagebox Печатает текст; модального окна нет.
UO.Alarm Печатает Alarm/текст; красное мигание иконки Stealth не реализовано.
UO.SetMulPath Сохраняет строку runtime, но не переключает игровые данные.
UO.SetShowZ Сохраняет флаг, не подключённый к отрисовке.
UO.BoxHack / FixTalk / FixWalk Только сообщение об устаревшем патче.
UO.ShutdownWindows Выбрасывает ошибку; Windows не выключается.

Как читать примеры

У каждой команды есть несколько самостоятельных блоков: простой вызов, перегрузки и применение результата/условный запуск/собственная процедура. Перед запуском подставляйте свои значения. Примеры, названные перегрузками, показывают форму вызова: случайный serial или координата не становятся действительными только потому, что текст прошёл парсер.

Примеры проверены загрузчиком той же версии runtime. Проверка не исполняет покупки, файлы, нажатия, сетевые запросы или игровые действия. Практический результат серверных операций зависит от соединения, объектов и правил сервера. Подробности проверки.

Логические результаты и полные вспомогательные функции

Если раздел «Возвращает» определяет результат как логические 1/0, можно сравнивать его с TRUE/FALSE или 1/0. TRUE и FALSE пишутся без кавычек. Сохраните результат вызова в переменную: повторный вызов NewMoveXY снова запускает команду движения.

# Учебная цель: три клетки восточнее на текущей карте.
SUB Main()
    VAR x = UO.GetX() + 3
    VAR y = UO.GetY()
    # TRUE: оптимизация; 0: точные X/Y; TRUE: бег.
    # callback=0 выключает функцию после шага; timeout=8000 мс.
    VAR reached = UO.NewMoveXY(x, y, TRUE, 0, TRUE, 0, 8000)
    # = TRUE эквивалентно = 1; = FALSE эквивалентно = 0.
    IF reached = TRUE THEN
        UO.Print('Destination reached')
    ELSE
        UO.Print('Destination not reached')
    END IF
END SUB

Аварийная отмена прерывает процедуру: она не обязана возвращать FALSE и выполнять ветку ELSE. Результат NewMoveXY проверяет локальные координаты после завершения; последующая коррекция сервера возможна.

Это правило нельзя переносить на счётчики и статусы: FindCount() = 1 означает один объект поиска; Step использует 7 для выполненного шага/поворота, а StepQ без ожидания подтверждения может вернуть 0 как допустимый номер sequence. Проверяйте контракт конкретной команды.

Полный пример GoToPoint и Main содержит определение вспомогательной функции целиком, комментарии и разбор параметров. GoToPoint — функция показанного скрипта, встроенная UO.GoToPoint не объявляется. Поиск A*, проверка проходимости и серверная очередь шагов выполняются внутри клиента. Учебное описание этих внутренних действий должно быть явно отделено от запускаемого BASIC-кода.