-
Notifications
You must be signed in to change notification settings - Fork 0
API UO AttackNearest
ClassicUO / Basic IDE
Home · Все команды · Константы и значения
Выбирает одну подходящую боевую цель и передаёт её обработчику атаки. Фильтры ограничивают допустимых персонажей; пользовательский classMask задаёт экипировку и приоритет классов, nearest — выбор внутри класса.
UO.AttackNearest(notoriety:Any) -> Integer
UO.AttackNearest(notoriety:Any, distance:Any) -> Integer
UO.AttackNearest(notoriety:Any, distance:Any, body:Any) -> Integer
UO.AttackNearest(notoriety:Any, distance:Any, body:Any, maxZ:Any) -> Integer
UO.AttackNearest(notoriety:Any, distance:Any, body:Any, maxZ:Any, nearest:Any) -> Integer
UO.AttackNearest(notoriety:Any, distance:Any, body:Any, maxZ:Any, nearest:Any, color:Any) -> Integer
UO.AttackNearest(notoriety:Any, distance:Any, body:Any, maxZ:Any, nearest:Any, color:Any, classMask:Any) -> Integer
UO.AttackNearest(notoriety:Any, distance:Any, body:Any, maxZ:Any, nearest:Any, color:Any, classMask:Any, aliveOnly:Any) -> Integer
UO.AttackNearest(notoriety:Any, distance:Any, body:Any, maxZ:Any, nearest:Any, color:Any, classMask:Any, aliveOnly:Any, visibleOnly:Any) -> Integer
Выберите одну из зарегистрированных форм. Параметры передаются позиционно. Any означает значение BASIC с преобразованием внутри команды; Unit — отсутствие возвращаемого значения.
-
notoriety— Статус отношения к персонажу, полученный от сервера: 0 — неизвестный, 1 — Innocent, 2 — Ally, 3 — Gray, 4 — Criminal, 5 — Enemy, 6 — Murderer, 7 — Invulnerable. Число означает один статус; "5|6" или массив чисел — любой из перечисленных. Это не цвет одежды и не класс. Отрицательное число (обычно -1), 0xFFFF, "any", пустая строка или пустой массив отдельно отключают этот фильтр. Некорректная строка без допустимых чисел не находит никого. Порядок статусов приоритет не задаёт. Фильтр 5 выбирает Enemy, а не автоматически любого NPC/монстра; реальные значения зависят от сервера. -
distance— Горизонтальный радиус в клетках включительно: 5 допускает расстояние 0..5. Расстояние — max(abs(dx),abs(dy)), поэтому соседняя диагональ тоже 1. По умолчанию или при отрицательном числе берётся UO.FindDistance(), а не безлимитный поиск. 0 оставляет ту же клетку X/Y. Не длина маршрута; препятствия и этажи этим параметром не проверяются. -
body— Graphic тела персонажа/NPC, не ID конкретного персонажа и не type надетой брони. Число, hex-строка, строка "0x0190|0x0191" или массив чисел. 0x0190 (400) — мужчина-человек; 0x0191 (401) — женщина-человек. Маска объединяет оба тела. Список не включает автоматически другие расы, призраков или превращения; таблица стандартных тел. Отрицательное число (-1 по умолчанию), 0xFFFF, "any", пустая строка или пустой массив отдельно — любое тело. Неизвестный текст без допустимого числа даёт пустой результат. -
maxZ— Максимум abs(Z цели - Z своего персонажа) включительно, в единицах Z мира. Это не число этажей и не клетки X/Y. maxZ=4 при Z игрока 10 допускает Z цели 6..14; 0 требует ровно одинаковую высоту. По умолчанию/при отрицательном числе берётся UO.FindVertical(). На лестнице равная Z может исключить нужную цель. Даже малая разность Z не доказывает доступность этажа. -
nearest— true/1 по умолчанию выбирает ближайшего подходящего персонажа; равное расстояние разрешается меньшим serial. false/0 сохраняет первый подходящий объект в порядке списка клиента, не выбирает самого дальнего. При classMask сначала действует приоритет класса, затем расстояние внутри класса. -
color— Hue самого mobile: Integer или числовая/hex-строка. Отрицательное число (-1 по умолчанию) и 0xFFFF — любой hue; 0 — именно hue 0, а не любое значение. Не цвет полоски notoriety и не оттенок одежды. Цвет надетой вещи этот параметр не проверяет. -
classMask— Имена правил, заранее определённых UO.SetClassMask в этом же скриптовом runtime. Например "DTMH|охотник|запасной" — приоритет слева направо; также допускается массив строк. Названия любые, регистр не важен. Разделители строки: |, запятая или ;. Любое неизвестное имя/пустой элемент внутри списка отменяет выбор целиком: результат 0, атаки нет. Это не числовая битовая маска: 7 не значит три класса. Пропущенный аргумент, -1, "-1", "any", "all" или пустая строка отдельно отключают фильтр классов. Mage/Tank/Archer не встроены: без регистрации таких правил совпадений не будет. -
aliveOnly— true/1 исключает mobiles с IsDead != 0; false/0 по умолчанию не добавляет это условие. Не сравнение HP с нулём, не поиск трупов-предметов и не гарантия, что цель останется живой после вызова. -
visibleOnly— true/1 требует IsVisible=1 по текущему состоянию ClassicUO; false/0 по умолчанию не добавляет условие. Это видимость загруженного объекта клиенту, а не проверка стен/линии обзора. Для геометрической проверки есть отдельная UO.CheckLOS с координатами; сервер всё равно может отклонить действие.
Integer — serial выбранного mobile, либо 0, когда подходящей цели нет или classMask недействителен. Это не 1/0-флаг, не body/type, не расстояние и не подтверждение удара. Проверяйте enemy <> 0; enemy = true сравнивает ID с 1 и здесь неверно. При ненулевом ID обработчик ClassicUO ещё может показать подтверждение атаки Innocent; сервер может отклонить действие.
- Поиск локальный: только уже загруженные mobiles. Учитывается Ignore; self исключён, кроме явного includeSelf=true в поддерживающих его командах. Контейнеры и предметы не являются mobiles.
- Условия применяются вместе (AND). Допустимые альтернативы внутри body/notoriety объединены через OR. Поиск не меняет FindItem, FindCount и GetFoundItems.
- В body/notoriety маска с допустимыми числами использует именно их: "any|5" всё равно ограничивает значением 5. Пустые/неверные элементы рядом с допустимыми числами игнорируются. Для отсутствия ограничения передайте -1 отдельно. Не переносите это правило на classMask: неизвестное имя класса отклоняет весь список.
- Команды не открывают область мира, не бегут к цели и не проверяют проходимость маршрута. Между выбором и обработкой сервером состояние мира может измениться.
- Передача true и 1 равнозначна для флагов, false и 0 также. Другие ненулевые числа тоже преобразуются в true, но 8/9 не являются отдельными режимами; используйте понятные true/false.
- Имя — пользовательская метка, а не серверная профессия. Можно назвать правило DTMH, моя_группа или любым другим словом. Движок не определяет навыки/класс на сервере по имени персонажа.
- В required один type или плоский массив означает хотя бы одну вещь из списка. Массив групп означает: нужна хотя бы одна вещь из КАЖДОЙ группы. Например [кожа, посохи] требует кожу И посох. Это набор альтернатив, а не требование надеть весь перечисленный гардероб.
- Любая надетая вещь из forbidden исключает персонажа из этого правила, даже при выполненных required. Кожа плюс запрещённый chain не проходит правило кожи. Другие правила продолжают проверяться.
- Учитываются только загруженные вещи, надетые на слоях 1..24 кроме рюкзака 21. Содержимое рюкзака/сундука, маунт 25, магазин 26..28 и банк 29 не считаются одеждой. Сравнивается graphic/type; serial, имя и hue вещи здесь не используются.
- Список без загруженной подходящей экипировки не совпадает. Отсутствие запрещённой вещи в локальных данных не доказывает её отсутствие на сервере, если сервер ещё не прислал экипировку. Клиент не угадывает скрытые данные.
- Правила принадлежат одному runtime скрипта, включая его функции и Include; не передаются другим самостоятельным запускам и не сохраняются в профиль. При новом запуске определите их снова, например общей процедурой настройки. Повторный SetClassMask заменяет правило с тем же именем, только после полной проверки новых данных.
- Массивы копируются при регистрации. Изменение исходного массива не меняет правило: повторите SetClassMask. Несколько совпавших правил разрешаются порядком имён в classMask. Никаких стандартных таблиц одежды сервера нет.
- Поддерживаются 1..9 позиционных аргументов. Пропускать можно хвост; чтобы задать classMask, нужно передать первые шесть аргументов. Используйте именованные VAR, чтобы видеть смысл каждой позиции.
- Выбирается одна цель, атака отправляется один раз. Это не автоматический цикл боя. Без classMask фильтр экипировки и чтение вещей не выполняются.
- Сначала общие фильтры, затем приоритет слева направо, затем nearest. nearest=false всё равно сохраняет приоритет классов, но внутри первого подходящего класса выбирает первый mobile в списке клиента.
- Старая попытка поиска подстроки в имени/титуле заменена правилами экипировки. Перенесите такие скрипты на явный SetClassMask; имя персонажа больше не выдаёт его за определённый класс.
Ниже описана реализация этого движка. Имена внутренних методов не являются дополнительными командами BASIC.
Разбирает девять позиционных значений и их значения по умолчанию.
Не создаёт собственный боевой цикл.
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/InjectionApiUO.cs; функция CompactAttackNearest.
Один раз разрешает все имена в снимок правил. Неизвестное имя отклоняет весь список.
Никакой подмены пустым фильтром или поиском по имени mobile.
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/InjectionApiUO.ClassMasks.cs; функция TryResolveClassRules.
Исключает self/Ignore; проверяет distance, notoriety, body, maxZ, color, aliveOnly, visibleOnly.
Фильтры применяются до приоритета класса.
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/InjectionApiUO.cs; функция FilterMobiles.
На игровом потоке за одно обращение снимает graphic надетых вещей.
Перебирает экипировку одного mobile, не все предметы мира; ничего не запрашивает у сервера.
Исходник проекта: src/ClassicUO.Client/Game/Managers/ClassicUOInjectionApiBridge.cs; функция GetWornTypes.
Один проход по кандидатам: меньший номер класса, затем дистанция и serial.
Полная сортировка списка не нужна. При nearest=false сохраняется первый внутри класса.
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/InjectionApiUO.ClassMasks.cs; функция SelectClassCandidate.
Вызывает GameActions.Attack, включая штатное подтверждение потенциально криминальной атаки.
Возвращённый ID означает выбор цели, не успешный удар.
Исходник проекта: src/ClassicUO.Client/Game/Managers/ClassicUOInjectionApiBridge.cs; функция Attack.
Стоимость зависит от числа загруженных кандидатов, их вещей и правил. Нет новых потоков, ожидания или сетевого опроса экипировки.
SUB Main()
# 5 = Enemy по notoriety; второй 5 = радиус, это разные параметры.
VAR enemy = UO.AttackNearest(5, 5)
IF enemy = 0 THEN
# В этом случае атаки не было.
RETURN
END IF
# Запоминаем ID уже выбранной цели для следующих действий скрипта.
UO.AddObject("combat_target", enemy)
END SUBРазбор параметров и выполнения:
- body=-1, maxZ=FindVertical(), nearest=true, color=-1, classMask отключён, aliveOnly=false, visibleOnly=false. Для обязательного исключения мёртвых используйте полную форму ниже.
SUB Main()
# Каждая переменная соответствует одной позиции вызова ниже.
VAR status = "5|6" # Enemy или Murderer, не 5-й/6-й предмет.
VAR radius = 8 # Радиус 8 клеток, не задержка.
VAR bodies = "0x0190|0x0191" # Только эти два body; не тип брони.
VAR heightTolerance = 0 # Z цели должен совпасть с Z игрока.
VAR chooseNearest = true # Ближайший из отфильтрованных.
VAR bodyHue = -1 # Hue тела не ограничиваем; 0 означал бы hue 0.
VAR equipmentClasses = -1 # Нет фильтра одежды/приоритета классов.
VAR requireAlive = true
VAR requireVisible = true
VAR enemy = UO.AttackNearest(status, radius, bodies, heightTolerance, chooseNearest, bodyHue, equipmentClasses, requireAlive, requireVisible)
IF enemy <> 0 THEN
UO.AddObject("enemy_same_height", enemy)
END IF
END SUBРазбор параметров и выполнения:
- maxZ=0 полезен для строгого сравнения высоты, но может отсечь цель на ступеньке. visibleOnly не проверяет стену. Все девять аргументов подписаны; возвращается ID, не true.
FUNCTION Gear(ParamArray values())
# Возвращает массив переданных значений, без поиска в игре.
RETURN values
END FUNCTION
SUB Main()
# Примерные graphic/type. Сверьте свои вещи через Info/GetType.
# В списке только разрешённые вами типы, это не serial предметов.
VAR leather = Gear(0x13C4, 0x13C7)
VAR staves = Gear(0x0DF0, 0x0E81)
VAR chain = Gear(0x13BF, 0x13C0)
VAR plate = Gear(0x1415, 0x1411)
VAR bows = Gear(0x13B2, 0x0F50)
# DTMH: одна вещь из leather И одна из staves; chain запрещён.
UO.SetClassMask("DTMH", Gear(leather, staves), chain)
# охотник: одна вещь из bows; остальные вещи не ограничиваем.
UO.SetClassMask("охотник", bows)
# тяжёлый: хотя бы одна перечисленная пластинчатая вещь.
UO.SetClassMask("тяжёлый", plate)
VAR notoriety = "5|6" # Enemy ИЛИ Murderer.
VAR distance = 12 # До 12 клеток X/Y включительно.
VAR body = -1 # Любое тело, не только human.
VAR maxZ = 8 # Разница высот не больше 8 единиц Z.
VAR nearest = true # Ближайший ВНУТРИ первого доступного класса.
VAR color = -1 # Любой hue тела, одежду по hue не фильтруем.
VAR classMask = "DTMH|тяжёлый|охотник"
VAR aliveOnly = true # Отсеиваем мёртвых mobiles.
VAR visibleOnly = true # Видимых клиенту; это не CheckLOS.
VAR enemy = UO.AttackNearest(notoriety, distance, body, maxZ, nearest, color, classMask, aliveOnly, visibleOnly)
IF enemy = 0 THEN
UO.Print("No matching enemy; no attack sent")
RETURN
END IF
# AttackNearest уже направила цель в обработчик атаки; второй Attack не нужен.
UO.AddObject("selected_enemy", enemy)
END SUBРазбор параметров и выполнения:
- Сначала выбирается DTMH; только если подходящих DTMH нет — тяжёлый, затем охотник. DTMH на 10 клетках имеет приоритет над тяжёлым на 2 клетках. Для обратного порядка поменяйте строку classMask. Из двух DTMH выбирается ближайший.
- Gear — полностью приведённая пользовательская функция BASIC, не отдельная команда UO. Два массива в Gear(leather, staves) образуют две обязательные группы. Добавление типа в leather расширяет альтернативы; не требует надевать две кожаные вещи.
SUB Main()
# Не нужен порядок по расстоянию; требуем Enemy, живой и видимый.
VAR sortByDistance = false
VAR target = UO.AttackNearest(5, 10, -1, 4, sortByDistance, -1, -1, true, true)
IF target = 0 THEN
RETURN
END IF
UO.AddObject("current_enemy", target)
END SUBРазбор параметров и выполнения:
- 10 — радиус, 4 — допустимая разность Z, оба -1 после флага отключают color и classMask. Порядок списка клиента не гарантирован между обновлениями мира. Для предсказуемой близости используйте true.
FUNCTION Gear(ParamArray values())
# Возвращает массив переданных значений, без поиска в игре.
RETURN values
END FUNCTION
SUB Main()
# Примерные graphic/type. Сверьте свои вещи через Info/GetType.
# В списке только разрешённые вами типы, это не serial предметов.
VAR leather = Gear(0x13C4, 0x13C7)
VAR staves = Gear(0x0DF0, 0x0E81)
VAR chain = Gear(0x13BF, 0x13C0)
VAR plate = Gear(0x1415, 0x1411)
VAR bows = Gear(0x13B2, 0x0F50)
# DTMH: одна вещь из leather И одна из staves; chain запрещён.
UO.SetClassMask("DTMH", Gear(leather, staves), chain)
# охотник: одна вещь из bows; остальные вещи не ограничиваем.
UO.SetClassMask("охотник", bows)
# тяжёлый: хотя бы одна перечисленная пластинчатая вещь.
UO.SetClassMask("тяжёлый", plate)
# Та же одежда, но теперь охотник важнее DTMH.
VAR priority = "охотник|DTMH|тяжёлый"
VAR enemy = UO.AttackNearest(5, 12, -1, 8, true, -1, priority, true, true)
IF enemy <> 0 THEN
UO.AddObject("priority_enemy", enemy)
END IF
END SUBРазбор параметров и выполнения:
- Меняется только порядок меток: никаких новых таблиц одежды или названий в клиенте добавлять не требуется. Чтобы запретить fallback на тяжёлого, удалите его из priority.
ClassicUO
Bad Newbie & Basic IDE
Найти в справочнике
Клиент и скрипты
Каталоги значений
Разработка и помощь