API UO Follow - LIHACHTETAN/ClassicUO-BadNewbie-BasicIDE GitHub Wiki

UO.Follow

ClassicUO / Basic IDE

Оглавление · Алфавитный указатель

Включает фоновое следование за загруженным персонажем/NPC либо движение к точке X, Y, Z. Во время движения клиент проверяет переданные условия остановки; скрипт продолжает выполнение сразу после вызова.

Точный синтаксис

UO.Follow() -> Integer
UO.Follow(target:Any) -> Integer
UO.Follow(target:Any, distance:Any) -> Integer
UO.Follow(target:Any, distance:Any, running:Any) -> Integer
UO.Follow(target:Any, distance:Any, running:Any, stopConditions:Any) -> Integer
UO.Follow(x:Any, y:Any, z:Any, distance:Any, running:Any) -> Integer
UO.Follow(x:Any, y:Any, z:Any, distance:Any, running:Any, stopConditions:Any) -> Integer

Выберите одну из зарегистрированных форм. Параметры передаются позиционно. Any означает значение BASIC с преобразованием внутри команды; Unit — отсутствие возвращаемого значения.

Параметры

  • target — Serial персонажа/NPC: Integer, hex/десятичная строка, lasttarget либо имя, ранее сохранённое через AddObject. Это не graphic/type и не координаты. Нельзя следовать за собой или предметом. 0 останавливает следование. Без аргументов Follow() также останавливает его; прицел не появляется.
  • distance — Допуск по X/Y в клетках: максимум |dx| и |dy|. Для персонажа Integer 1..18, по умолчанию 1; разница Z до 16 допустима. Для точки Integer 0..18, аргумент обязателен: 0 требует точного X/Y, 2 допускает остановку в пределах двух клеток; Z должен совпасть точно. Недопустимое значение не заменяет прежний режим.
  • running — Boolean-совместимое значение: true/1 — бег, false/0 — ходьба; по умолчанию true. Серверные ограничения скорости, выносливость, паралич и препятствия сохраняются. Флаг не ускоряет серверные шаги.
  • stopConditions — Необязательный массив условий остановки: четвёртый аргумент для персонажа, шестой для координат. Каждый элемент — массив ровно из трёх значений [field, comparison, threshold]. field и comparison — строки, threshold — Integer/Decimal; для флагов подходят true/false (1/0). Срабатывание ЛЮБОГО условия прекращает Follow (OR). Пустой массив не добавляет условий. Число элементов не ограничено фиксированными 3/5/10 пунктами, но ограничено памятью; большие списки проверяются порциями. Разрешённые поля и единицы перечислены ниже; неизвестное поле, оператор или неправильная форма массива вызывают ошибку до замены прежнего Follow.
  • x / y — Только формы с 5/6 аргументами: целые мировые координаты на текущей карте, 0..65535 и внутри загруженных границ карты. Это не координаты окна/gump и не serial. Переход на другую карту не выполняется.
  • z — Только формы с 5/6 аргументами: целая высота мира -128..127. Для завершения требуется именно эта высота, поэтому указывайте Z доступной поверхности нужного этажа. Отдельных значений «любой Z» или автоматического выбора высоты нет.

Возвращает

Integer 1 (true) — режим следования принят клиентом, либо выполнен запрос остановки; Integer 0 (false) — нет подходящего загруженного персонажа, игрок недоступен/мёртв, цель вне обзора, неверна дистанция или клиент не поддерживает команду. Это не результат прибытия, не serial и не число шагов. Разрешены IF result = 1 и IF result = true. Ошибки типов/неизвестного имени объекта могут вызвать ошибку скрипта. Для координат 0 также означает недопустимые X/Y/Z или допуск. 1 означает только принятие фоновой задачи; прибытие и будущая проходимость ещё не подтверждены.

Поведение

  • Ровно один режим Follow на клиента: персонаж или координаты. Повторный успешный вызов заменяет цель и параметры. Неуспешный вызов не отменяет прежнюю цель. Для следования за персонажем он должен уже находиться в загруженном списке Mobiles в пределах ClientViewRange; координатная точка может находиться дальше обзора.
  • При достижении distance возле персонажа ходьба прекращается, но режим остаётся включённым и возобновляет движение, когда цель отходит. Возле координатной точки задача полностью завершается при соблюдении допуска X/Y и точного Z. Команда не сообщает о гарантированной достижимости маршрута при запуске.
  • Follow(), Follow(0), MoverStop(), ручное перемещение мышью/стрелками, новый скриптовый маршрут или стандартное следование клиента прекращают этот режим. TerminateAll/Terminate("all") также его останавливают. Отмена ещё выполняющегося скрипта-владельца останавливает его Follow.
  • Оба режима прекращаются при смене карты или персонажа, смерти игрока и разрыве соединения. Следование за персонажем дополнительно прекращается при исчезновении цели из памяти/обзора. Появление цели позднее не запускает режим автоматически: нужен новый Follow.
  • Закрытие IDE не останавливает режим. Нормальное завершение запустившего скрипта оставляет Follow включённым. Пауза скрипта сама по себе не является паузой этого клиентского режима; перед паузой используйте Follow(0), когда движение нужно прекратить.
  • Расчёт выполняет обычный Pathfinder порциями на игровом потоке. При следовании за персонажем новый маршрут запрашивается не чаще одного раза за 500 мс; уже выполняющийся поиск не перезапускается. После отказа повторная попытка не чаще раза за 1000 мс. Такой режим может оставаться активным без движения — используйте таймаут. Координатная задача при отказе пути завершается, как описано ниже.
  • Follow не запускает поиск отсутствующей цели, не телепортирует и не открывает двери сам. Уже отправленные серверу шаги могут завершиться после команды остановки. В варианте Classic без Basic IDE скриптовая команда недоступна.
  • Поля расстояния/времени: distance — текущая дистанция до цели в клетках max(abs(dx),abs(dy)); height — абсолютная разность Z в единицах мира; elapsed — миллисекунды с принятия этого Follow. distance > 12 останавливает при удалении дальше 12 клеток, elapsed >= 30000 — после 30 секунд. Повторный успешный Follow начинает отсчёт заново.
  • Состояние своего персонажа: self.hp / self.mana / self.stam — текущие значения; self.hppercent / self.manapercent / self.stampercent — проценты 0..100 от соответствующего максимума. Неизвестный максимум (<=0) означает неизвестное значение: условие по этой характеристике не срабатывает, а не получает выдуманный 0.
  • Логические поля своего персонажа: self.poisoned (отравлен), self.paralyzed (парализован), self.hidden (скрыт). Значения 1/0. Например self.paralyzed = true прекращает следование при параличе.
  • Поля цели: target.dead — мёртвый mobile, target.hidden — скрыт, target.visible — видим клиенту (не CheckLOS), target.hp / target.hppercent — загруженные HP/проценты. Если HP max неизвестен, условие HP не срабатывает. Сервер может прислать относительную шкалу HP чужого персонажа, поэтому для неё удобнее hppercent.
  • Дополнительные поля цели: target.notoriety — статус 0..7 (0 неизвестный, 1 Innocent, 2 Ally, 3 Gray, 4 Criminal, 5 Enemy, 6 Murderer, 7 Invulnerable); target.body — числовой graphic тела. Это не type одежды. Например target.notoriety <> 2 прекращает сопровождение при потере статуса Ally.
  • Операторы: "=", "<>", "<", "<=", ">", ">=". Равенство точное; для процентов обычно нужен порог <= или >=. Поля нечувствительны к регистру. Условия являются данными, не исполняемыми строками BASIC: произвольные команды или имена функций в field не вызываются.
  • Копия условий фиксируется при вызове, включая числовые пороги. Изменение исходного массива/переменной не обновляет режим; повторите Follow с новым массивом. Отменённый режим сам не возобновляется, когда условие перестанет выполняться.
  • Условия проверяются и во время движения, и когда персонаж уже стоит возле цели. Обычный список до 64 элементов проверяется за один игровой кадр, следующая проверка не раньше чем через 250 мс. Больший список — по 64 элемента за кадр, затем пауза 250 мс. Поле elapsed может остановить позже порога на время проверки/кадра: это не точный таймер.
  • До окончания первой проверки всего списка новый маршрут не начинается. Если условие уже выполнено, Follow вернёт 1 за принятый запрос, затем остановится на обновлении без первого шага. Пакеты шагов от прежнего движения уже могли быть отправлены.
  • Новые условия не отключают обязательные причины остановки: потерю цели/игрока/карты/соединения, смерть игрока, отмену владельца, Terminate all и ручное/другое движение. Скриптовый код не выполняется на игровом потоке; проверяются только перечисленные локальные значения.
  • Координатные формы: Follow(x,y,z,distance,running) и Follow(x,y,z,distance,running,stopConditions). Первые пять аргументов обязательны. Follow(x,y,z) не является короткой записью координат: три аргумента по-прежнему означают target,distance,running.
  • В координатном режиме distance в условии означает оставшееся расстояние по X/Y до точки, height — абсолютную разницу с её Z; elapsed и все self.* работают как обычно. Поля target.* недопустимы: у точки нет HP, тела или статуса. Попытка передать их вызывает ошибку скрипта до замены прежнего режима.
  • Условия проверяются до первого маршрута, во время его расчёта и пока персонаж движется. Срабатывание любого условия снимает задачу и отменяет принадлежащий ей путь. Частота и обработка больших списков такие же, как при следовании за персонажем; уже отправленные серверу шаги могут завершиться.
  • Координатная задача завершается при достижении точки либо отказе/окончании поиска и движения без достижения. Бесконечные повторы к недоступной точке не запускаются. Обычные внутренние перерасчёты Pathfinder при препятствиях сохраняются. После завершения уход с места не возобновляет задачу.
  • Если Pathfinder уже отправил последние шаги и закончил путь, но эти шаги ещё выполняются/ожидают подтверждения, задача продолжает проверять условия. Сама очередь отправленных шагов не стирается: её должен обработать обычный механизм движения и подтверждений сервера.
  • Список можно собрать через List.Add в DO … LOOP или FOR, а затем один раз передать checks.ToArray() последним аргументом соответствующей формы. Не нужно вызывать Follow заново на каждой итерации: это заменяет режим и сбрасывает elapsed. Количество строк не ограничено небольшим числом, но набор поддерживаемых field ограничен перечисленными выше полями.
  • Для собственных вычислений и сочетаний И/ИЛИ используйте обычный BASIC-цикл: LOOP UNTIL (условие1) OrElse (условие2), а для одновременного выполнения — AndAlso и скобки. LOOP завершает только цикл, поэтому после него явно вызовите UO.Follow(0), предпочтительно в Finally. Такой цикл и его проверки существуют, пока работает скрипт; массив stopConditions проверяет сам клиент и после нормального завершения скрипта.

Внутренние функции: последовательность выполнения

Ниже описана реализация этого движка. Имена внутренних методов не являются дополнительными командами BASIC.

1. InjectionApiUO

Конструктор регистрирует семь форм UO.Follow: 0..4 аргумента для персонажа/остановки, 5/6 — для точки. В формах 4/6 проверяет массив условий.

Через IApiFollowBridge / IApiConditionalFollowBridge / IApiCoordinateFollowBridge передаёт запрос клиенту и возвращает Integer 1/0.

Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/InjectionApiUO.cs; функция InjectionApiUO.

2. Follow

На игровом потоке проверяет доступность Basic и запускает контроллер.

Отключает прежнее стандартное следование после принятия новой цели.

Исходник проекта: src/ClassicUO.Client/Game/Managers/ClassicUOInjectionApiBridge.cs; функция Follow.

3. Start

Проверяет цель и дистанцию, запоминает карту, игрока и владельца.

Заменяет прежний режим только после успешной проверки.

Исходник проекта: src/ClassicUO.Client/Game/Managers/BasicFollowController.cs; функция Start.

4. Update

Проверяет отмену, потерю цели, карту и дистанцию. При необходимости запускает incremental WalkTo с ограничением частоты.

Возле цели останавливает путь и ждёт её следующего перемещения, сохраняя режим.

Исходник проекта: src/ClassicUO.Client/Game/Managers/BasicFollowController.cs; функция Update.

5. Stop

Вызывает StopOwnedPath и очищает цель/владельца.

Номер маршрута защищает новый чужой путь от отмены старым владельцем.

Исходник проекта: src/ClassicUO.Client/Game/Managers/BasicFollowController.cs; функция Stop.

6. Parse

На потоке скрипта проверяет массив строк, имена полей, операторы и числовые пороги.

Создаёт неизменяемые условия; ошибка не заменяет прежний режим.

Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/FollowStopCondition.cs; функция Parse.

7. CheckStopConditions

До планирования движения проверяет не больше 64 условий за кадр; после полного прохода ждёт 250 мс.

Первое совпадение вызывает Stop; большие списки не обрабатываются целиком за один кадр.

Исходник проекта: src/ClassicUO.Client/Game/Managers/BasicFollowController.cs; функция CheckStopConditions.

8. StartAt

Проверяет координаты, допуск, состояние игрока и совместимость условий; сохраняет точку текущей карты.

Возвращает признак принятия задачи; это ещё не прибытие к точке.

Исходник проекта: src/ClassicUO.Client/Game/Managers/BasicFollowController.cs; функция StartAt.

9. Update

Проверяет условия перед планированием и во время активного пути. Передаёт Pathfinder точный Z и допуск X/Y.

При достижении, условии остановки или отказе пути очищает задачу; номер пути защищает новое движение.

Исходник проекта: src/ClassicUO.Client/Game/Managers/BasicFollowController.cs; функция Update.

Новые потоки или циклы ожидания на каждый Follow не создаются. Контроллер обновляется вместе с менеджером скриптов, независимо от открытого окна IDE.

Примеры

Пример 1. Бежать за последней целью

SUB Main()
    # Сначала выберите персонажа/NPC обычным игровым таргетом.
    VAR leader = UO.GetSerial("lasttarget")
    # Только target: distance=1, running=true.
    VAR accepted = UO.Follow(leader)
    IF accepted = true THEN
        UO.Print("Following is enabled; script continues")
    ELSE
        UO.Print("Select a loaded nearby character")
    END IF
END SUB

Разбор параметров и выполнения:

  • leader — serial последней цели. Единица подтверждает принятие режима, а не прибытие. После END SUB режим продолжает работать до остановки/потери цели.

Пример 2. Идти пешком на расстоянии трёх клеток, затем остановиться

SUB Main()
    VAR leader = UO.GetSerial("lasttarget")
    # target=leader, distance=3 клетки, running=false.
    IF UO.Follow(leader, 3, false) = 1 THEN
        # Скрипт свободен выполнять другую работу. Здесь ждём 10 секунд.
        WAIT(10000)
        UO.Follow(0)
        UO.Print("Following stopped")
    END IF
END SUB

Разбор параметров и выполнения:

  • WAIT измеряется в миллисекундах. Follow(0) выключает общий режим следования; последующие перемещения цели больше не вызывают движение.

Пример 3. Ограничить время следования и гарантированно выключить его

SUB Main()
    # Имя leader предварительно сохранено через AddObject.
    VAR leader = UO.GetSerial("leader")
    IF UO.Follow(leader, 2, true) = 0 THEN
        UO.Print("Cannot start following")
        RETURN
    END IF
    TRY
        VAR attempts = 0
        WHILE attempts < 20 AND UO.Exists(leader)
            # Не переиздаём Follow в циклережим уже наблюдает цель.
            WAIT(500)
            attempts = attempts + 1
        WEND
    FINALLY
        # Без аргументовостановка. Это не выбор новой цели.
        UO.Follow()
    END TRY
END SUB

Разбор параметров и выполнения:

  • distance=2, running=true; максимум 20 ожиданий по 500 мс. Exists проверяет наличие объекта, не достижимость пути. FINALLY останавливает режим при обычном выходе/ошибке; аварийная отмена владельца дополнительно обрабатывается клиентом.

Пример 4. Остановиться по расстоянию, своим HP или времени

FUNCTION StopWhen(field, comparison, threshold)
    # Пользовательская функция: создаёт одну строку условия.
    DIM rule[2]
    rule[0] = field
    rule[1] = comparison
    rule[2] = threshold
    RETURN rule
END FUNCTION

SUB Main()
    VAR leader = UO.GetSerial("lasttarget")
    DIM conditions[2] # Три условия: индексы 0, 1, 2.
    conditions[0] = StopWhen("distance", ">", 12)
    conditions[1] = StopWhen("self.hppercent", "<=", 40)
    conditions[2] = StopWhen("elapsed", ">=", 30000)
    # distance=2 здесьдистанция сопровождения, не предел 12 выше.
    VAR accepted = UO.Follow(leader, 2, true, conditions)
    IF accepted = 0 THEN
        UO.Print("Cannot follow this target")
    END IF
    # Скрипт заканчивается, клиент продолжает сопровождение и проверки.
END SUB

Разбор параметров и выполнения:

  • Остановка по ЛЮБОМУ условию: цель дальше 12 клеток ИЛИ наши HP не больше 40% ИЛИ прошло 30 секунд. Это не AND. StopWhen приведена полностью, её можно вынести в Include. Единица означает принятие, не прибытие.

Пример 5. Добавлять условия через список без заранее заданного размера

FUNCTION StopWhen(field, comparison, threshold)
    # Пользовательская функция: создаёт одну строку условия.
    DIM rule[2]
    rule[0] = field
    rule[1] = comparison
    rule[2] = threshold
    RETURN rule
END FUNCTION

SUB Main()
    VAR checks = List()
    checks.Add(StopWhen("target.hidden", "=", true))
    checks.Add(StopWhen("target.dead", "=", true))
    checks.Add(StopWhen("target.notoriety", "<>", 2))
    checks.Add(StopWhen("self.stam", "<=", 5))
    checks.Add(StopWhen("height", ">", 16))
    # Можно дописывать checks.Add(...) для других условий/порогов.
    VAR leader = UO.GetSerial("lasttarget")
    VAR conditions = checks.ToArray()
    UO.Follow(leader, 2, false, conditions)
END SUB

Разбор параметров и выполнения:

  • Останавливаемся, если цель скрылась/умерла/перестала быть Ally, осталось не больше 5 выносливости либо перепад Z превысил 16. false означает идти пешком. ToArray передаёт список строк условий; размер заранее не задаётся. Если цель уже не Ally, движение не начнётся.

Пример 6. Следовать до приближения, затем полностью выключить режим

FUNCTION StopWhen(field, comparison, threshold)
    # Пользовательская функция: создаёт одну строку условия.
    DIM rule[2]
    rule[0] = field
    rule[1] = comparison
    rule[2] = threshold
    RETURN rule
END FUNCTION

SUB Main()
    DIM conditions[1]
    conditions[0] = StopWhen("distance", "<=", 3)
    conditions[1] = StopWhen("elapsed", ">=", 15000)
    # Обычный Follow возле цели остаётся активным. Условие distance<=3
    # полностью выключает режим: за дальнейшим уходом цели уже не идём.
    UO.Follow(UO.GetSerial("lasttarget"), 1, true, conditions)
END SUB

Разбор параметров и выполнения:

  • Поддерживаемая дистанция 1, условие остановки <=3; проверка каждые 250 мс может заметить достижение с задержкой. Таймаут 15000 мс не позволяет сопровождать бесконечно. Возврат Follow всё ещё означает принятие, не достижение трёх клеток.

Пример 7. Собрать условия в DO … LOOP: остановиться при статусе 5 или 6

FUNCTION StopWhen(field, comparison, threshold)
    # Пользовательская функция: создаёт одну строку условия.
    DIM rule[2]
    rule[0] = field
    rule[1] = comparison
    rule[2] = threshold
    RETURN rule
END FUNCTION

SUB Main()
    # Редактируйте список: здесь два статуса, но можно добавить другие.
    VAR statuses = List()
    statuses.Add(5) # Enemy.
    statuses.Add(6) # Murderer.
    VAR checks = List()
    VAR index = 0
    DO WHILE index < statuses.Count()
        checks.Add(StopWhen("target.notoriety", "=", statuses[index]))
        index += 1
    LOOP
    # К построенному списку добавляем условия другого вида.
    checks.Add(StopWhen("self.hppercent", "<=", 40))
    checks.Add(StopWhen("elapsed", ">=", 30000))
    # Один вызов устанавливает весь список, а не только последнюю строку.
    VAR accepted = UO.Follow(UO.GetSerial("lasttarget"), 2, true, checks.ToArray())
    IF accepted = 0 THEN
        UO.Print("Select a loaded nearby character")
    END IF
END SUB

Разбор параметров и выполнения:

  • DO WHILE собирает отдельное условие для каждого элемента statuses. Остановка при статусе 5 ИЛИ 6, своих HP <=40% ИЛИ через 30000 мс. Пустой statuses пропустит цикл, но два следующих условия останутся. Новые строки добавляйте до Follow; последующее изменение List не изменяет уже установленную копию. Для background-проверок тело цикла не требуется выполнять повторно.

Пример 8. Свои выражения в LOOP UNTIL и обязательная остановка в Finally

FUNCTION StopEscort(leader, startedAt)
    # Функция скрипта, не строка поля stopConditions.
    # HP здесь в единицах здоровья, не в процентах.
    RETURN (UO.GetDistance(leader) > 12) OrElse (UO.GetHP("self") <= 30) OrElse (Now() - startedAt >= 30000)
END FUNCTION

SUB Main()
    VAR leader = UO.GetSerial("lasttarget")
    VAR startedAt = Now() # Миллисекунды; не UO.Timer().
    # Проверяем также до первого шага/ожидания.
    IF leader = 0 OrElse StopEscort(leader, startedAt) THEN
        RETURN
    END IF
    IF UO.Follow(leader, 2, true) = 0 THEN
        RETURN
    END IF
    TRY
        DO
            UO.Wait(250) # Не опрашиваем игру непрерывно без ожидания.
        LOOP UNTIL StopEscort(leader, startedAt)
    FINALLY
        # Выход из LOOP сам по себе не выключает фоновое следование.
        UO.Follow(0)
    END TRY
END SUB

Разбор параметров и выполнения:

  • StopEscort(leader, startedAt) возвращает Boolean-совместимые 1/0: цель дальше 12 клеток ИЛИ свои HP <=30 ИЛИ прошло 30 секунд. Добавляйте OrElse (ещё_условие); для обязательного сочетания двух проверок используйте (условиеA AndAlso условиеB). Неизвестные HP могут читаться как 0; пример тогда отказывается начинать. Пока скрипт выполняется, он проверяет выражения примерно каждые 250 мс; пауза скрипта приостанавливает эти проверки. Finally отправляет остановку при обычном выходе/ошибке; отмену владельца дополнительно отслеживает клиент. Если цель исчезла и клиент уже остановил Follow, этот цикл завершится по своим условиям, не позже проверки таймаута. Для работы после END SUB используйте четвёртый аргумент, как в предыдущих примерах.

Пример 9. Бежать к точному X, Y, Z

SUB Main()
    # Замените координаты и Z на доступную точку своей карты.
    # distance=0: точный X/Y; running=true: бег.
    VAR accepted = UO.Follow(1445, 1690, 0, 0, true)
    IF accepted = 0 THEN
        UO.Print("Coordinate task was not accepted")
    END IF
END SUB

Разбор параметров и выполнения:

  • Пять аргументов: X=1445, Y=1690, Z=0, допуск X/Y=0, бег. Возврат 1 означает принятие, а не уже выполненное прибытие. На месте задача выключится полностью. Для досрочной ручной остановки вызовите UO.Follow(0).

Пример 10. К точке с остановкой по своим HP, параличу или времени

FUNCTION StopWhen(field, comparison, threshold)
    # Пользовательская функция: создаёт одну строку условия.
    DIM rule[2]
    rule[0] = field
    rule[1] = comparison
    rule[2] = threshold
    RETURN rule
END FUNCTION

SUB Main()
    VAR checks = List()
    checks.Add(StopWhen("self.hppercent", "<=", 40))
    checks.Add(StopWhen("self.paralyzed", "=", true))
    checks.Add(StopWhen("elapsed", ">=", 30000))
    # Один вызов: точка, допуск две клетки, бег, весь массив условий.
    UO.Follow(1445, 1690, 0, 2, true, checks.ToArray())
    # END SUB не выключает клиентские проверки во время пути.
END SUB

Разбор параметров и выполнения:

  • При HP <=40%, параличе или после 30 секунд клиент прекращает текущий путь. Иначе задача завершится в пределах двух клеток X/Y от (1445,1690), строго на Z=0. Проверки продолжаются и при поиске пути, и в движении; это не разовая проверка перед стартом. target.* здесь не применяется.

Пример 11. Идти к точке, но закончить сопровождение за три клетки до неё

FUNCTION StopWhen(field, comparison, threshold)
    # Пользовательская функция: создаёт одну строку условия.
    DIM rule[2]
    rule[0] = field
    rule[1] = comparison
    rule[2] = threshold
    RETURN rule
END FUNCTION

SUB Main()
    VAR checks = List()
    checks.Add(StopWhen("distance", "<=", 3))
    checks.Add(StopWhen("height", ">", 16))
    checks.Add(StopWhen("elapsed", ">=", 20000))
    # До точки десять клеток на восток от текущего положения.
    VAR x = UO.GetX("self") + 10
    VAR y = UO.GetY("self")
    VAR z = UO.GetZ("self")
    UO.Follow(x, y, z, 0, false, checks.ToArray())
END SUB

Разбор параметров и выполнения:

  • distance=0 в вызове задаёт точное прибытие, но условие distance<=3 прекращает задачу раньше, когда очередная проверка заметит такое расстояние. false означает ходьбу. Перепад Z>16 или 20000 мс тоже останавливают задачу. Направление не гарантирует проходимости; замените смещение на точку своего маршрута.
⚠️ **GitHub.com Fallback** ⚠️