API UO MoveXYZ - LIHACHTETAN/ClassicUO-BadNewbie-BasicIDE GitHub Wiki
UO.MoveXYZ
Оглавление · Алфавитный указатель · Movement
ClassicUO • Runtime API
Перемещает персонажа к точке мира с отдельными допусками по горизонтали и высоте.
Точный синтаксис
UO.MoveXYZ(x:Any, y:Any, z:Any, accuracyXY:Any, accuracyZ:Any, running:Any) -> Integer
UO.MoveXYZ(x:Any, y:Any, z:Any, accuracyXY:Any, accuracyZ:Any, running:Any, timeout:Any) -> Integer
UO.MoveXYZ(x:Any, y:Any, z:Any, accuracyXY:Any, accuracyZ:Any, running:Any, timeout:Any, maxSteps:Any) -> Integer
UO.MoveXYZ(x:Any, y:Any, z:Any, accuracyXY:Any, accuracyZ:Any, running:Any, timeout:Any, maxSteps:Any, avoidMobiles:Any) -> Integer
UO.MoveXYZ(x:Any, y:Any, z:Any, accuracyXY:Any, accuracyZ:Any, running:Any, timeout:Any, maxSteps:Any, avoidMobiles:Any, openDoors:Any) -> Integer
Выберите одну из зарегистрированных форм. Параметры передаются позиционно. Any означает значение BASIC с преобразованием внутри команды; Unit — отсутствие возвращаемого значения.
Параметры
x— Обязательный Integer: мировая координата X назначения, 0..65535, на текущей карте. Не координата гампа.y— Обязательный Integer: мировая координата Y назначения, 0..65535, на текущей карте.z— Обязательный Integer: целевая мировая высота -128..127. Это высота поверхности, а не номер этажа.accuracyXY— Обязательный Integer. Допуск по X и Y в клетках: оба отклонения должны укладываться в него. Значение ограничивается диапазоном 0..20; 0 требует точных X/Y.accuracyZ— Обязательный Integer. Допуск высоты: abs(фактическая Z - требуемая Z), ограничивается 0..255. Ноль требует точной высоты; 255 практически отключает ограничение Z.running— Обязательный логический флаг. TRUE/1 — запрос бега, FALSE/0 — шаг. Серверные задержки движения сохраняются; это не множитель скорости.timeout— Необязательный предел ожидания в миллисекундах; отсутствующий аргумент, 0 и отрицательное значение означают отсутствие этого дополнительного предела. Отсчёт начинается после принятия маршрута к исполнению; это не жёсткий предел длительности всего вызова вместе с подготовкой маршрута.maxSteps— Необязательный предел замеченных изменений позиции, не сетевых пакетов. 0/отрицательное/отсутствие — без этого лимита. Между опросами может пройти несколько шагов, поэтому это не точный счётчик клеток.avoidMobiles— Необязательный флаг: TRUE запрещает проход сквозь учитываемых персонажей; FALSE разрешает попытку. Без аргумента используется moveThroughNPC. Сервер всё равно может запретить проход.openDoors— Необязательный флаг открывания дверей по пути. Без аргумента используется moveOpenDoor; TRUE не предоставляет доступ к запертым дверям.
Возвращает
Integer 1 — в конце проверки персонаж находится в заданном допуске X/Y/Z, в том числе когда уже был там до вызова. Integer 0 — недопустимые координаты, отказ запуска, недостигнутая точка или сработавшее условие остановки. Это не число шагов и не serial; при аварийной отмене процедура прерывается вместо обычного возврата 0.
Это логический результат: 1 = TRUE, 0 = FALSE. После VAR result = команда(...) можно писать IF result = TRUE THEN или IF result = 1 THEN; для отрицательного результата — IF result = FALSE THEN или IF result = 0 THEN. TRUE/FALSE пишутся без кавычек. Вызовите команду один раз и сохраните результат: повторный вызов может повторить действие или прочитать уже изменившееся состояние.
Поведение
- Как работает, шаг 1: проверяет координаты, настроенные условия соединения и выносливости. Если персонаж уже находится в пределах accuracyXY и accuracyZ, сразу возвращает 1 без нового маршрута.
- Шаг 2: строит маршрут на текущей карте с учётом высоты поверхности, препятствий и выбранных условий прохода. Режим Optimized здесь включён внутри команды; передавать такой параметр в MoveXYZ не нужно.
- Шаг 3: запускает ходьбу или бег по маршруту и ждёт результат в текущей процедуре. Строка после вызова выполняется после его завершения; интерфейс клиента продолжает работать.
- Шаг 4: при отказе шага или новом препятствии клиент может пересчитать маршрут от текущего положения. Попытки ограничены. При тайм-ауте или достижении лимита наблюдаемых перемещений за пределами цели движение останавливается с 0.
- Шаг 5: после окончания движения сравнивает фактические X/Y/Z клиента с целью. Требуются одновременно abs(X-x)<=accuracyXY, abs(Y-y)<=accuracyXY и abs(Z-z)<=accuracyZ. Например, для цели 1279/540/20 с допусками 1 и 2 подходят X=1278..1280, Y=539..541, Z=18..22.
- Минимальная форма содержит шесть аргументов: UO.MoveXYZ(1279,540,20,1,2,TRUE). Дополнительные аргументы добавляются справа в порядке timeout, maxSteps, avoidMobiles, openDoors. Чтобы указать openDoors, нужно передать и предыдущие позиции; пустые места между запятыми не поддерживаются.
- Отличие от NewMoveXY: MoveXYZ получает целевую высоту третьим аргументом. У NewMoveXY третий аргумент — Optimized; передавать туда высоту нельзя. Callback у MoveXYZ в этом runtime отсутствует.
- Маршрут принадлежит запустившей его процедуре: её аварийная остановка отменяет оставшийся автоматический путь. Если другой запуск или пользователь уже заменил маршрут, отмена прежнего владельца новый маршрут не трогает. Уже отправленные шаги не отзываются.
- SetBadLocation и SetBadObject применяются как снимок запретов текущего runtime при запуске маршрута. Они сохраняются при его внутреннем перерасчёте. Изменение или очистка списков влияет на следующий маршрут, а не переписывает уже выполняющийся.
- После принятия запроса вызов ждёт на потоке скрипта. Первоначальный поиск и пересчёт выполняются на игровом потоке порциями: максимум 32 раскрытия узлов и мягкий бюджет около 1 мс за порцию. Одна сложная проверка клетки или чтение карты может превысить этот бюджет. Между порциями клиент продолжает обновления; полный лимит поиска остаётся 10000 узлов.
- timeout отсчитывается после принятия запроса и включает последующие порции поиска и пересчёта. stopOnStuck не считает работающий поиск застреванием персонажа; после завершения планирования отсутствие изменений позиции снова учитывается. Итоговый 1/0 проверяет фактические координаты, а не только готовность пути.
- Результат учитывает локальную позицию клиента; последующая серверная коррекция всё ещё возможна. Запуск конкурирующих команд движения из разных процедур меняет общий маршрут персонажа.
- Настройки moveCheckStamina, moveExitOnDisconnect, moveOpenDoor, moveThroughCorner, moveThroughNPC, moveHeuristicMult, moveTurnCost и moveBetweenTwoCorners влияют на исполнение. Явные avoidMobiles/openDoors заменяют соответствующие значения для этого вызова.
- Результат 0 не сообщает точную причину. Проверяйте координаты, соединение, выносливость и журнал; не повторяйте движение бесконечно без WAIT и лимита попыток.
Внутренние функции: от вызова до результата
Ниже разобрана реальная цепочка клиента. Это описание внутренних C#-функций, а не дополнительные команды BASIC. Запускаемые функции примеров, включая GoToPoint и AfterStep, объявлены целиком в разделе «Примеры».
1. CompactMoveXYZ
Разбирает 6..10 аргументов с явной целевой Z. Включает Optimized внутри; строкового callback у этой формы нет.
Передаёт подготовленные значения в MoveToCanonical. Это внутренний C#-метод; его имя нельзя вызвать как UO-команду.
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/InjectionApiUO.cs; функция CompactMoveXYZ.
2. MoveToCanonical
Принимает X/Y/Z, допуски и ограничения вызова. Проверяет диапазон координат, соединение, выносливость и maxDistance; ограничивает accuracy до 0..20, accuracyZ до 0..255. Уже достигнутая цель даёт 1 без нового поиска.
После bridge.MoveTo ждёт bridge.Move(), читает положение, проверяет timeout, callback, maxSteps и stopOnStuck. Между проверками вызывает bridge.Wait(5). После окончания сравнивает фактические координаты с допусками. Возврат 1/0 относится к достижению, а не к принятию маршрута.
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/InjectionApiUO.cs; функция MoveToCanonical.
3. MoveTo
Передаёт параметры из потока скрипта на игровой поток через Invoke. Создаёт снимок SetBadLocation/SetBadObject, вызывает Pathfinder.WalkTo и запоминает поколение маршрута для отмены владельцем.
Возвращает 1, если WalkTo принял маршрут, иначе 0. Это промежуточный результат: сама команда ещё ждёт завершения и проверяет цель.
Исходник проекта: src/ClassicUO.Client/Game/Managers/ClassicUOInjectionApiBridge.cs; функция MoveTo.
4. WalkTo
Принимает цель, допуск, ходьбу/бег, правила дверей/углов/персонажей, стоимость и запреты. Отклоняет отсутствие персонажа, паралич и недостаточную выносливость. Останавливает предыдущий маршрут, очищает поиск, выбирает старт, сохраняет параметры.
Вызовы из скрипта, интерфейса, следования и серверного запроса включают incremental: BeginPathSearch готовит поиск, AdvancePathSearch выполняет первую порцию. true может означать принятый незавершённый поиск; передвижение начинается только после полного пути. Старый синхронный режим C# сохранён для совместимости нативного PluginHost.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция WalkTo.
5. ResetSearchNodes
Аргументов нет. Сбрасывает использованные узлы, индексы открытых/закрытых состояний, очередь приоритетов, свободные слоты и длину пути.
Возвращаемого значения нет. Уже выделенные объекты узлов переиспользуются; это уменьшает повторные выделения памяти, но не меняет проходимость.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция ResetSearchNodes.
6. SetSearchStart
Аргументов нет. Получает GetEndPosition — положение после уже поставленных в очередь шагов и текущее направление.
Сохраняет старт X/Y/Z/направление и карту. При пересчёте ProcessAutoWalk сначала дожидается освобождения очереди; если исходная позиция или карта изменились между порциями, поиск запускается заново от актуальной точки.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция SetSearchStart.
7. FindPath
Принимает maxNodes. Синхронная совместимая обёртка: вызывает BeginPathSearch, затем AdvancePathSearch до завершения. Основные клиентские вызовы используют порции через ProcessAutoWalk и не вызывают эту обёртку.
true — полный путь построен; false — путь не найден в пределах лимитов. Этот C#-режим может занимать весь поиск за один вызов и сохранён для существующего контракта нативных плагинов.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция FindPath.
8. BeginPathSearch
Принимает общий maxNodes. Очищает признак результата, создаёт стартовый узел с X/Y/Z/направлением, задаёт оценку и сохраняет текущую позицию поиска.
Возвращаемого значения нет: состояние становится pending. Если старт уже в допусках X/Y/Z, сразу сохраняет одноточечный путь и состояние успеха. Пакеты движения здесь не отправляются.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция BeginPathSearch.
9. AdvancePathSearch
Аргументов нет: продолжает сохранённый поиск. Раскрывает максимум 32 узла через OpenNodes/FindCheapestNode. После примерно 1 мс возвращается между раскрытиями, оставляя очередь, родителей и текущий узел для следующего обновления.
При извлечении цели восстанавливает полный путь по Parent, включая старт, и отмечает успех. При исчерпании очереди или общего лимита отмечает неудачу. До завершения оставляет pending. Бюджет времени мягкий: текущее раскрытие и чтение геометрии сначала заканчиваются.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция AdvancePathSearch.
10. OpenNodes
Принимает текущий PathNode. Пробует восемь направлений через CanWalk. Если проверка сменила направление вместо запрошенного, такой сосед не добавляется.
Для допустимого соседа вызывает AddNodeToList; true означает, что хотя бы одно добавление не сообщило переполнение. Это не признак достижения конечной цели.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция OpenNodes.
11. CanWalk
Принимает направление и X/Y/Z по ссылке. GetNewXY выбирает соседнюю клетку; CalculateNewZ проверяет высоту и объекты, затем учитываются правила диагональных углов.
Возвращает bool проходимости и может изменить направление/координаты. Поэтому OpenNodes и ValidatePathLookahead проверяют не только true, но и совпадение с требуемым направлением и точкой.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция CanWalk.
12. GetNewXY
Принимает числовое направление, X и Y по ссылке. По таблице направлений добавляет смещение на одну клетку.
Меняет X/Y; ничего не отправляет серверу и не проверяет высоту или препятствия.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция GetNewXY.
13. CalculateNewZ
Принимает X/Y назначения, исходную Z по ссылке и направление. Учитывает прикладной запрет клетки и режим персонажа: обычный, мёртвый/GM, полёт или морской конёк. CalculateMinMaxZ вычисляет границы подъёма, CreateItemList собирает поверхности и препятствия.
Проверяет допустимый просвет и поверхность, при успехе записывает подходящую Z и возвращает true. false означает отсутствие допустимого локального прохода; сервер может иметь дополнительные правила.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция CalculateNewZ.
14. CalculateMinMaxZ
Получает границы высоты по ссылке, координаты/высоту, направление и режим движения. По исходной клетке, поверхностям и мостам уточняет нижнюю и верхнюю границы шага.
Возвращает вычисленную верхнюю границу и обновляет аргументы minZ/maxZ; при отсутствии исходной геометрии возвращает 0. Это вспомогательный расчёт геометрии, а не номер этажа или готовая команда движения.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция CalculateMinMaxZ.
15. CreateItemList
Получает переиспользуемый список PathObject, клетку и режим движения. Собирает землю, статики и загруженные предметы/персонажей с высотой и флагами прохода, поверхности, моста и диагоналей.
false — исходная клетка не получена из карты; true — сбор завершён, наполнение списка проверяется отдельно. Фильтры зависят от флагов персонажа, tiledata, настроек прохода и открывания дверей; функция не загружает весь неизвестный серверный мир.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция CreateItemList.
16. NodeKey
Получает X/Y/Z и направление. Формирует ключ состояния для словаря и множества.
При ненулевой цене поворота включает направление; иначе направление в ключе равно 0. Так одинаковые координаты с разным будущим штрафом поворота не объединяются ошибочно.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция NodeKey.
17. MovementCost
Получает родительский узел, направление нового шага и вид ребра. Для скриптов прямой шаг стоит 10, диагональный — 14. Если направление изменилось, добавляет moveTurnCost, ограниченный внутри WalkTo до 100000.
Возвращает стоимость одного ребра. Это внутренние весовые единицы, не миллисекунды, не число уже сделанных шагов и не скорость бега.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция MovementCost.
18. GetGoalDistCost
Получает точку-кандидат. dx=max(0,abs(goalX-X)-accuracy), dy=max(0,abs(goalY-Y)-accuracy). Для скриптов h=(10max(dx,dy)+4min(dx,dy))*multiplier/100 с целочисленным делением и ограничением сверху.
При Optimized=TRUE берётся moveHeuristicMult (по умолчанию 93, минимум 1); при FALSE используется 1. Высота проверяется при выборе цели и проходимости, а не прибавляется к этой эвристике. При значении выше 100 оптимальность по стоимости уже не гарантируется.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция GetGoalDistCost.
19. AddNodeToList
Получает тип списка, направление, X/Y/Z, родителя и вид ребра. Закрытые состояния не добавляет повторно. Для открытого состояния оставляет меньшую стоимость g; для нового выделяет или переиспользует слот. При закрытии переносит данные в стабильный закрытый узел.
Сохраняет Parent и f=g+h, добавляет приоритет в очередь. Возвращает индекс, -1 при нехватке места. Словарь/множество заменяют линейный поиск по 10000 ячейкам.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция AddNodeToList.
20. FindCheapestNode
Извлекает минимальный приоритет из очереди, пропускает устаревшие записи после уменьшения стоимости или переиспользования слота. Проверяет актуальный индекс состояния.
Закрывает узел; только теперь отмечает достигнутую цель. Возвращает индекс закрытого узла либо -1. Обнаружить цель среди соседей недостаточно для выбора лучшего маршрута.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция FindCheapestNode.
21. ValidatePathLookahead
Принимает индекс пути и прогнозируемое положение X/Y/Z. Проверяет до 4 следующих клеток при Optimized=TRUE, одну при FALSE, последовательно вызывая CanWalk.
true — все проверенные направления и X/Y/Z совпали с планом; false — нужен пересчёт. Это проверка части уже построенного пути, а не ограничение дальности всей цели.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция ValidatePathLookahead.
22. NotifyWalkDenied
Вызывается обработчиком отказа/коррекции шага. Если маршрут активен, выставляет флаг необходимости пересчёта.
Сам путь здесь не рассчитывается и новый пакет движения не отправляется.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция NotifyWalkDenied.
23. RebuildPathFromCurrentPosition
Аргументов нет. При отсутствии персонажа или восьми попытках без продвижения возвращает false. Сбрасывает поиск, обновляет старт, увеличивает счётчик и назначает следующий пересчёт не раньше чем через 40 мс.
Сохраняет цель и правила. В incremental-режиме начинает новый поиск через BeginPathSearch и возвращает true как принятие пересчёта; ProcessAutoWalk позже завершает его порциями. Синхронная ветка вызывает FindPath. false — повтор не принят либо синхронный поиск не удался. Изменение X/Y/Z сбрасывает счётчик попыток.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция RebuildPathFromCurrentPosition.
24. ProcessAutoWalk
Проверяет наличие персонажа, соединение/выносливость, актуальность старта и карты; при пересчёте ждёт окончания очереди и cooldown. Выполняет одну порцию незавершённого поиска. Пока путь не готов, шагов не отправляет. Затем соблюдает лимит Walker, выравнивает индекс по GetEndPosition и вызывает ValidatePathLookahead.
При openDoors пытается открыть соседнюю дверь через TryOpenDoor, затем делает Player.Walk. Отказ локального шага запрашивает пересчёт. Эта процедура вызывается клиентом при обновлениях; она не раскручивает бесконечный цикл отправки пакетов.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция ProcessAutoWalk.
25. StopAutoWalk
Останавливает автопуть и незавершённый поиск, меняет поколение, очищает параметры, запреты и флаг пересчёта. Последующие обновления не могут возобновить отменённый поиск.
Не отзывает уже отправленные серверу шаги. Поэтому остановка запроса не равна мгновенному откату позиции.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция StopAutoWalk.
26. StopAutoWalkIfGeneration
Получает сохранённый номер поколения маршрута.
Останавливает путь только при совпадении поколения. Отмена старого скрипта не отменяет новый маршрут другого владельца.
Исходник проекта: src/ClassicUO.Client/Game/Pathfinder.cs; функция StopAutoWalkIfGeneration.
Оптимизации здесь имеют конкретный смысл: очередь приоритетов, индексы состояний, повторное использование узлов, проверка ближайших клеток и ограниченный пересчёт. Они не увеличивают разрешённую сервером скорость. Ползунки обхода при ручном движении мышью относятся к другому механизму; Optimized и moveHeuristicMult не заменяют эти ползунки.
Примеры
Пример 1. Соседняя клетка на той же высоте
# Соседняя клетка на той же высоте
#
# Перемещает персонажа к точке мира с отдельными допусками по горизонтали и высоте.
#
# Integer 1 — в конце проверки персонаж находится в заданном допуске X/Y/Z, в том числе когда
# уже был там до вызова. Integer 0 — недопустимые координаты, отказ запуска, недостигнутая точка
# или сработавшее условие остановки. Это не число шагов и не serial; при аварийной отмене
# процедура прерывается вместо обычного возврата 0.
#
# Это логический результат: 1 = TRUE, 0 = FALSE. После VAR result = команда(...) можно писать IF
# result = TRUE THEN или IF result = 1 THEN; для отрицательного результата — IF result = FALSE
# THEN или IF result = 0 THEN. TRUE/FALSE пишутся без кавычек. Вызовите команду один раз и
# сохраните результат: повторный вызов может повторить действие или прочитать уже изменившееся
# состояние.
SUB Main()
# x/y/z — целевая точка. accuracyXY=0 и accuracyZ=0 требуют точной позиции.
# running=FALSE — ходьба. Если соседняя поверхность имеет другую высоту, результат может быть 0.
VAR ok = UO.MoveXYZ(UO.GetX() + 1, UO.GetY(), UO.GetZ(), 0, 0, FALSE)
UO.Print(STR(ok))
END SUB
Разбор параметров и выполнения:
- x/y/z — целевая точка. accuracyXY=0 и accuracyZ=0 требуют точной позиции.
- running=FALSE — ходьба. Если соседняя поверхность имеет другую высоту, результат может быть 0.
Пример 2. Подойти к точке на нужной высоте и проверить результат
# Подойти к точке на нужной высоте и проверить результат
#
# Перемещает персонажа к точке мира с отдельными допусками по горизонтали и высоте.
#
# Integer 1 — в конце проверки персонаж находится в заданном допуске X/Y/Z, в том числе когда
# уже был там до вызова. Integer 0 — недопустимые координаты, отказ запуска, недостигнутая точка
# или сработавшее условие остановки. Это не число шагов и не serial; при аварийной отмене
# процедура прерывается вместо обычного возврата 0.
#
# Это логический результат: 1 = TRUE, 0 = FALSE. После VAR result = команда(...) можно писать IF
# result = TRUE THEN или IF result = 1 THEN; для отрицательного результата — IF result = FALSE
# THEN или IF result = 0 THEN. TRUE/FALSE пишутся без кавычек. Вызовите команду один раз и
# сохраните результат: повторный вызов может повторить действие или прочитать уже изменившееся
# состояние.
SUB Main()
# Подготовка: персонаж должен быть в игре, а точка должна существовать на текущей карте.
# 1279/540/20 — учебные координаты: замените их своей доступной точкой, включая реальную высоту
# поверхности.
# 1. destinationX=1279 — первый аргумент, мировая координата X цели.
# 2. destinationY=540 — второй аргумент, мировая координата Y цели.
# 3. destinationZ=20 — третий аргумент, высота. Команда должна найти проход или лестницу;
# значение 20 само по себе не переносит на этаж.
# 4. accuracyXY=1 разрешает закончить в пределах одной клетки по каждой горизонтальной
# координате. Диагонально соседняя клетка тоже подходит.
# 5. accuracyZ=2 разрешает высоту от 18 до 22 включительно. Совпадение X/Y на другом этаже
# недостаточно для успеха.
# 6. running=TRUE запрашивает бег. Для ходьбы замените TRUE на FALSE.
# 7. timeout=8000 ограничивает ожидание после старта маршрута восемью секундами. По истечении
# этого времени, пока движение ещё идёт, команда останавливает его и возвращает 0.
# 8. maxSteps=100 ограничивает число замеченных изменений позиции. Это не точное число
# пройденных клеток: между опросами может выполниться несколько шагов.
# 9. avoidMobiles=TRUE запрещает проход сквозь учитываемых персонажей при расчёте маршрута.
# 10. openDoors=TRUE разрешает попытки открывать двери по пути. Запертую дверь или ограничения
# сервера этот флаг не обходит.
# reached получает Integer 1 или 0 после завершения вызова. IF reached = 1 выполняет ветку
# успеха; ELSE обрабатывает недостижение цели без бесконечного повторения команды.
# Последняя строка выводит текущие X/Y/Z для проверки. При аварийной остановке процедуры
# дальнейшие строки, включая этот вывод, не выполняются.
VAR destinationX = 1279
VAR destinationY = 540
VAR destinationZ = 20
VAR accuracyXY = 1
VAR accuracyZ = 2
VAR running = TRUE
VAR timeout = 8000
VAR maxSteps = 100
VAR avoidMobiles = TRUE
VAR openDoors = TRUE
VAR reached = UO.MoveXYZ(destinationX, destinationY, destinationZ, accuracyXY, accuracyZ, running, timeout, maxSteps, avoidMobiles, openDoors)
IF reached = 1 THEN
UO.Print('Destination reached')
ELSE
UO.Print('Destination not reached; check the path and limits')
END IF
UO.Print('Position: ' + STR(UO.GetX()) + ',' + STR(UO.GetY()) + ',' + STR(UO.GetZ()))
END SUB
Разбор параметров и выполнения:
- Подготовка: персонаж должен быть в игре, а точка должна существовать на текущей карте. 1279/540/20 — учебные координаты: замените их своей доступной точкой, включая реальную высоту поверхности.
-
- destinationX=1279 — первый аргумент, мировая координата X цели.
-
- destinationY=540 — второй аргумент, мировая координата Y цели.
-
- destinationZ=20 — третий аргумент, высота. Команда должна найти проход или лестницу; значение 20 само по себе не переносит на этаж.
-
- accuracyXY=1 разрешает закончить в пределах одной клетки по каждой горизонтальной координате. Диагонально соседняя клетка тоже подходит.
-
- accuracyZ=2 разрешает высоту от 18 до 22 включительно. Совпадение X/Y на другом этаже недостаточно для успеха.
-
- running=TRUE запрашивает бег. Для ходьбы замените TRUE на FALSE.
-
- timeout=8000 ограничивает ожидание после старта маршрута восемью секундами. По истечении этого времени, пока движение ещё идёт, команда останавливает его и возвращает 0.
-
- maxSteps=100 ограничивает число замеченных изменений позиции. Это не точное число пройденных клеток: между опросами может выполниться несколько шагов.
-
- avoidMobiles=TRUE запрещает проход сквозь учитываемых персонажей при расчёте маршрута.
-
- openDoors=TRUE разрешает попытки открывать двери по пути. Запертую дверь или ограничения сервера этот флаг не обходит.
- reached получает Integer 1 или 0 после завершения вызова. IF reached = 1 выполняет ветку успеха; ELSE обрабатывает недостижение цели без бесконечного повторения команды.
- Последняя строка выводит текущие X/Y/Z для проверки. При аварийной остановке процедуры дальнейшие строки, включая этот вывод, не выполняются.
Пример 3. Бег с лимитами и запретом открывать двери
# Бег с лимитами и запретом открывать двери
#
# Перемещает персонажа к точке мира с отдельными допусками по горизонтали и высоте.
#
# Integer 1 — в конце проверки персонаж находится в заданном допуске X/Y/Z, в том числе когда
# уже был там до вызова. Integer 0 — недопустимые координаты, отказ запуска, недостигнутая точка
# или сработавшее условие остановки. Это не число шагов и не serial; при аварийной отмене
# процедура прерывается вместо обычного возврата 0.
#
# Это логический результат: 1 = TRUE, 0 = FALSE. После VAR result = команда(...) можно писать IF
# result = TRUE THEN или IF result = 1 THEN; для отрицательного результата — IF result = FALSE
# THEN или IF result = 0 THEN. TRUE/FALSE пишутся без кавычек. Вызовите команду один раз и
# сохраните результат: повторный вызов может повторить действие или прочитать уже изменившееся
# состояние.
SUB Main()
# x/y/z=1445/1690/0; accuracyXY=1, accuracyZ=3; running=TRUE.
# timeout=5000, maxSteps=60 наблюдаемых перемещений, avoidMobiles=TRUE и openDoors=FALSE.
VAR ok = UO.MoveXYZ(1445, 1690, 0, 1, 3, TRUE, 5000, 60, TRUE, FALSE)
UO.Print('Result: ' + STR(ok))
END SUB
Разбор параметров и выполнения:
- x/y/z=1445/1690/0; accuracyXY=1, accuracyZ=3; running=TRUE.
- timeout=5000, maxSteps=60 наблюдаемых перемещений, avoidMobiles=TRUE и openDoors=FALSE.
Пример 4. Готовая функция с комментариями внутри скрипта
# GoToPoint — наша вспомогательная функция, а не отдельная команда API.
# Скопируйте весь пример в один файл .sc и запустите Main.
# Подставьте доступные координаты на текущей карте персонажа.
#
# x, y — мировые координаты назначения.
# z — высота поверхности, не номер этажа.
# accuracyXY — допустимое отклонение по X и Y в клетках.
# accuracyZ — допустимое отклонение по высоте.
# running — TRUE: бег; FALSE: ходьба.
# Возврат: Integer 1 = TRUE — цель достигнута, 0 = FALSE — не достигнута.
# Аварийная остановка прерывает процедуру вместо возврата 0.
FUNCTION GoToPoint(x, y, z, accuracyXY, accuracyZ, running)
# Дополнительные ограничения именно этого примера.
# timeout — миллисекунды ожидания после принятия маршрута.
VAR timeout = 8000
# maxSteps — лимит замеченных изменений позиции, не пакетов.
VAR maxSteps = 100
# TRUE — не прокладывать путь сквозь учитываемых персонажей.
VAR avoidMobiles = TRUE
# TRUE — разрешить попытки открывать двери по пути.
VAR openDoors = TRUE
# Внутри MoveXYZ клиент рассчитывает и исполняет маршрут.
# Новое препятствие может вызвать ограниченный пересчёт.
# Вызов ждёт окончания движения, затем проверяет X/Y и Z.
VAR reached = UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running, timeout, maxSteps, avoidMobiles, openDoors)
# Возвращаем результат вызывающей процедуре Main.
RETURN reached
END FUNCTION
SUB Main()
# Цель X=1279, Y=540, Z=20; замените на свою точку.
# Допуски: 1 клетка по X/Y, 2 единицы по Z; TRUE — бег.
VAR reached = GoToPoint(1279, 540, 20, 1, 2, TRUE)
# Продолжать действие у цели можно только после успеха.
# = TRUE равнозначно = 1; = FALSE равнозначно = 0.
IF reached = TRUE THEN
UO.Print('Destination reached')
ELSE
# Не зацикливаем повтор: проверяем путь и ограничения.
UO.Print('Destination not reached')
END IF
END SUB
Разбор параметров и выполнения:
- Строки с # — комментарии Basic: они сохраняются при копировании и не выполняются. Пример содержит обе необходимые части: функцию GoToPoint и запускаемую процедуру Main.
- Все шесть параметров GoToPoint передаются в MoveXYZ без изменения. Четыре дополнительных параметра заданы внутри функции: 8000 мс, 100 наблюдаемых изменений позиции, обход персонажей и открывание дверей.
- Для цели 1279/540/20 с допусками 1/2 подходят X=1278..1280, Y=539..541, Z=18..22. Точка на другой высоте за пределами 18..22 не считается достигнутой.
- Это обёртка над настоящей командой, а не вторая реализация поиска пути на скрипте. Она не вызывает лишний GetPathArray и не запускает бесконечные повторные попытки. При недостижении вызывающая процедура получает 0 и сама выбирает дальнейшее действие.