RU UO Topic world geometry - LIHACHTETAN/ClassicUO-Bad-Newbie-CSharp-Scripts-IDE GitHub Wiki

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

Мир и Геометрия

Главная · C# · IDE · UO API · A–Z · Примеры · Языки

Координаты, расстояния, линия видимости, проходимость и данные карты. Получение маршрута описано отдельно в Movement.

Разделы

Тема Команды и пояснения
X / Y / Z UO.GetX · UO.GetY · UO.GetZ
Distance UO.GetDistance · UO.Dist
LOS UO.CheckLOS · UO.LOSOptions
World Number UO.WorldNum
World Cells UO.GetWorldCell · UO.GetWorldTilesArray
Passability UO.IsWorldCellPassable · UO.GetNextStepZ
Surface Z UO.GetSurfaceZ
Map Cells UO.GetMapCell
Land Tiles UO.GetLandTileAt · UO.GetLandTileData · UO.GetLandTilesArray · UO.GetLandTilesArrayEx
Static Tiles UO.GetStaticTileAt · UO.GetStaticTileData · UO.GetStaticTiles · UO.GetStaticTilesArray · UO.GetStaticTilesArrayEx
Tile Flags UO.GetTileFlags · UO.ConvertIntegerToFlags
Tile Height UO.GetTileHeight
Tile Layer UO.GetTileLayer
Tile Name UO.GetTileName
Water Tiles UO.IsWaterTile
Tree Tiles UO.IsTreeTile
Mine Tiles UO.IsMineTile

Все команды темы

X / Y / Z

UO.X · UO.Y · UO.Z · UO.GetX · UO.GetY · UO.GetZ

Расстояние

UO.Dist · UO.GetDistance

LOS

UO.CheckLOS · UO.LOSOptions

Мировой номер

UO.WorldNum · UO.GetWorldNum

Мировые ячейки/Проходимость

UO.GetWorldCell · UO.GetMapCell · UO.IsWorldCellPassable · UO.GetSurfaceZ · UO.GetNextStepZ · UO.GetWorldTilesArray

Земельные плитки

UO.GetLandscapeTile · UO.GetLandTileAt · UO.GetLandTileData · UO.GetLandTilesArray · UO.GetLandTilesArrayEx

Статические плитки

UO.GetStaticArt · UO.GetStaticTileAt · UO.GetStaticTileData · UO.GetStaticTiles · UO.GetStaticTilesArray · UO.GetStaticTilesArrayEx · UO.ReadStaticsXY · UO.PrivateGetTile · UO.GetTileXYM · UO.GetLayerCount

Свойства плитки

UO.GetTileFlags · UO.GetTileHeight · UO.GetTileLayer · UO.GetTileName · UO.IsWaterTile · UO.IsTreeTile · UO.IsMineTile · UO.ConvertIntegerToFlags

Статика клиента

UO.AddUserStatic · UO.ClearUserStatics · UO.GetUserStatic · UO.GetUserStatics · UO.RemoveUserStatic · UO.UserStaticExists

Примеры по теме

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

UO.GetDistance

Параметры, результат и все сценарии

var target = UO.GetSerial("lasttarget");
if (Truth(UO.Exists(target)))
{
    var distance = UO.GetDistance(target);
    if (Truth(distance <= 2))
    {
        UO.Print("Target is within two tiles");
    }
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

UO.IsWorldCellPassable

Параметры, результат и все сценарии

var x = UO.GetX();
var y = UO.GetY();
var z = UO.GetZ();
var result = UO.IsWorldCellPassable(x,y,z,x+1,y,z,UO.WorldNum());
if (Truth(Truth(result[0]) == true))
{
    UO.Print("Passable, Z=" + Convert.ToString(result[1]));
}
else
{
    UO.Print("Blocked");
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

Части справочника

1 · 2

Полное описание команд


UO.AddUserStatic

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.AddUserStatic(object? staticItem, object? worldNum);
int UO.AddUserStatic(object? graphic, object? x, object? y, object? z, object? hue, object? map);

Добавляет запись пользовательского статика в локальное состояние скриптов. Числовой graphic используется для локальной проверки препятствий pathfinder’ом; объект на сервере не создаётся. Двухаргументный вызов с ненумеруемым текстом сохраняет legacy-значения и не добавляет статик в pathfinder.

Параметры

  • staticItem — числовой graphic либо legacy-текстовое значение.
  • worldNum — индекс карты для записи или локального статика.
  • graphic — ID статика от 0 до 65535.
  • z — высота. При добавлении в pathfinder значение ограничивается диапазоном signed byte.
  • hue — hue; при добавлении ограничивается диапазоном от 0 до 65535.
  • map — индекс карты; для обработки менеджером диапазон ограничен 0–255.
  • x — Мировая X пользовательского статика; int. Менеджер принимает координаты внутри текущей загруженной карты.
  • y — Мировая Y пользовательского статика; int. Менеджер принимает координаты внутри текущей загруженной карты.

Возвращает

Положительный ID созданной записи. Для шестипараметрической формы отрицательные graphic, x, y или map, а также graphic выше 65535 приводят к -1. ID можно передать в UO.UserStaticExists, UO.RemoveUserStatic или использовать для проверки/удаления legacy-записи. Сам по себе возвращённый ID не подтверждает, что статик будет виден или применён на сервере.

Поведение

    • UO.AddUserStatic('tree', 0) — поскольку tree не является числом, сохраняет пару исходных значений как legacy-запись в состоянии runtime; pathfinder её не использует.
  • Двухпараметрический вызов с числовым graphic добавляет статик этого graphic на текущие координаты персонажа, с z персонажа и hue 0.
  • Шестипараметрический вызов добавляет статик с заданными graphic, координатами, высотой, hue и картой. Pathfinding учитывает его только на активной карте и в соответствии с флагами graphic в клиентских tiledata.

Эти записи локальны для клиента скриптов: они не создают игровой объект, не отправляют сетевой запрос и не изменяют данные shard’а.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.AddUserStatic(0x0CCA, UO.GetWorldNum());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Сохранить пару как legacy-данные; текстовый StaticItem не создаёт препятствие pathfinder'у. — прямой скрипт

Параметры и ход выполнения:

  • Сохранить пару как legacy-данные; текстовый StaticItem не создаёт препятствие pathfinder'у.
var legacyId = UO.AddUserStatic("tree", 0);
UO.Print(Convert.ToString(legacyId));

2. Числовой graphic добавляется в позицию персонажа на текущей карте. — функция сценария

Параметры и ход выполнения:

  • Числовой graphic добавляется в позицию персонажа на текущей карте.
return  RunScenario();
 object? RunScenario()
{
    var staticId = UO.AddUserStatic(0x0CCA, UO.GetWorldNum());
    UO.Print(Convert.ToString(staticId));
    return null;
}

3. Явно добавить локальный static graphic в указанную позицию и на указанную карту. — класс сценария

Параметры и ход выполнения:

  • Явно добавить локальный static graphic в указанную позицию и на указанную карту.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var staticId = UO.AddUserStatic(0x0CCA, UO.GetX(), UO.GetY(), UO.GetZ(), 0, UO.GetWorldNum());
        UO.Print(Convert.ToString(staticId));
        return null;
    }
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.AddUserStatic(staticItem, worldNum) — UO.AddUserStatic(Any,Any)

Параметры: staticItem (Any), worldNum (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "adduserstatic":

                {

                    int map = Arg(1, bridge.WorldNumber);

                    if (arguments[0].Kind != InjectionValueKind.Array)

                    {

                        int graphic = 0;

                        if (arguments[0].Kind == InjectionValueKind.String &&

                            !NumberConversions.TryStr2Int(arguments[0].String, out graphic))

                        {

                            int legacyId = state.NextUserStaticId++;

                            state.UserStatics[legacyId] = Text(0) + "|" + Text(1);

                            return new InjectionValue(legacyId);

                        }

                        graphic = arguments[0].Kind == InjectionValueKind.String

                            ? graphic

                            : NumberConversions.ToInt(arguments[0]);

                        return new InjectionValue(AddUserStatic(graphic, bridge.GetX(bridge.Self), bridge.GetY(bridge.Self),

                            bridge.GetZ(bridge.Self), 0, map));

                    }

                    if (arguments[0].Array.Length < 4)

                        throw new NativeSubrutineException("AddUserStatic expects [graphic,x,y,z,color] and world number, or graphic,x,y,z,color,world.");

                    InjectionValue[] item = arguments[0].Array;

                    return new InjectionValue(AddUserStatic(

                        NumberConversions.ToInt(item[0]), NumberConversions.ToInt(item[1]), NumberConversions.ToInt(item[2]),

                        NumberConversions.ToInt(item[3]), item.Length > 4 ? NumberConversions.ToInt(item[4]) : 0, map));

                }

UO.AddUserStatic(graphic, x, y, z, hue, map) — UO.AddUserStatic(Any,Any,Any,Any,Any,Any)

Параметры: graphic (Any), x (Any), y (Any), z (Any), hue (Any), map (Any)

Результат: int / Integer.

При вызове:

Вызов выполняет сохранённый delegate обработчика. Метод регистрации создаёт этот delegate при построении API.

Внутренний код реализации, не самостоятельный скрипт.

values => new InjectionValue(AddUserStatic(

                    NumberConversions.ToInt(values[0]), NumberConversions.ToInt(values[1]), NumberConversions.ToInt(values[2]),

                    NumberConversions.ToInt(values[3]), NumberConversions.ToInt(values[4]), NumberConversions.ToInt(values[5])))

UO.CheckLOS

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.CheckLOS(object? xfrom, object? yfrom, object? zfrom, object? xto, object? yto, object? zto, object? worldNum);

Проверяет локальную проходимость линии между двумя точками карты через CheckPortableLineOfSight.

Параметры

  • xfrom — Исходный X: 0..65535.
  • yfrom — Исходный Y: 0..65535.
  • zfrom — Исходная Z, int.
  • xto — Конечный X: 0..65535.
  • yto — Конечный Y: 0..65535.
  • zto — Конечная Z, int.
  • worldNum — 0..255. Луч ненулевой длины читает только текущую загруженную _world.Map/World.Map: через CheckWorldStep нужны WorldNum == _world.MapIndex и живой Player.Pathfinder. Другой facet не загружается и не запрашивается; нет карты/персонажа/pathfinder либо шаг недоступен — 0. Исключение одинаковых X/Y пропускает весь цикл клеток: при X/Y в 0..65535, WorldNum в 0..255 и abs(Zfrom-Zto)<=20 возвращает 1 даже без загруженной карты или с другим номером карты. Это не доказательство геометрии или достижимости. Результат локальный, не решение LOS сервера.

Возвращает

int 1 — локальный луч достиг X/Y и конечная высота отличается от Zto не более чем на 20; 0 — недопустимые координаты, препятствие или предел проверки.

Поведение

  • Луч идёт алгоритмом Bresenham, максимум 4096 шагов. На каждой клетке учитываются BadLocations, CheckWorldStep и возвращённая высота.
  • При LosOptions != 0 дополнительно используется CheckLosCell; бит 0x100 проверяет обе боковые клетки диагонали. Проверка локальной геометрии не удостоверяет правила LOS конкретного сервера и ничего не перемещает.
  • Младший byte (value & 0xFF) выбирает алгоритм 1..4; другие значения младшего byte в CheckLosCell используют алгоритм 3. Алгоритмы 1/2 блокируют Wall и Impassable, 3 дополнительно NoShoot, а 4 включает NoShoot только с 0x200 и пропускает препятствия Window только с 0x400. Бит 0x100 дополнительно проверяет обе боковые клетки каждого диагонального шага луча при любом выбранном алгоритме. value=0 отключает дополнительные CheckLosCell/диагональные проверки, но BadLocations и CheckWorldStep остаются. Например 4+0x100+0x200+0x400 выбирает custom с тремя флагами; setter сохраняет исходный int, не нормализованный алгоритм.
  • Луч ненулевой длины читает только текущую загруженную _world.Map/World.Map: через CheckWorldStep нужны WorldNum == _world.MapIndex и живой Player.Pathfinder. Другой facet не загружается и не запрашивается; нет карты/персонажа/pathfinder либо шаг недоступен — 0. Исключение одинаковых X/Y пропускает весь цикл клеток: при X/Y в 0..65535, WorldNum в 0..255 и abs(Zfrom-Zto)<=20 возвращает 1 даже без загруженной карты или с другим номером карты. Это не доказательство геометрии или достижимости. Результат локальный, не решение LOS сервера.
  • CheckLosCell обходит загруженные Land/Static/Multi/Item одной клетки. Impassable Land блокирует при abs(rayZ-land.Z)<=20. Флаги Static/Multi/Item действуют только в диапазоне tile.Z-2 .. tile.Z+max(1,Height)+2; разрешённый custom Window пропускается до проверки Wall/Impassable/NoShoot. Луч X/Y использует Bresenham, максимум 4096 шагов; Z берётся из поверхностей CheckWorldStep, не интерполируется к Zto, конечный допуск высоты — 20.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.CheckLOS(UO.X(), UO.Y(), UO.Z(), UO.X() + 1, UO.Y(), UO.Z(), UO.WorldNum());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Линия на текущей клетке — прямой скрипт

Параметры и ход выполнения:

  • Одинаковые точки проходят при допустимых X/Y/map.
var x = UO.GetX();
var y = UO.GetY();
var z = UO.GetZ();
var visible = UO.CheckLOS(x,y,z,x,y,z,UO.WorldNum());
UO.Print(Convert.ToString(visible));

2. Проверка соседней клетки — функция сценария

Параметры и ход выполнения:

  • Высота и проходимость соседней клетки читаются из локальной карты.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX();
    var y = UO.GetY();
    var z = UO.GetZ();
    var clear = UO.CheckLOS(x, y, z, x + 1, y, z, UO.WorldNum());
    UO.Print(Convert.ToString(clear));
    return null;
}

3. Недопустимая координата — класс сценария

Параметры и ход выполнения:

  • Отрицательный X отклоняется с результатом 0 без прохода по карте.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var clear = UO.CheckLOS(-1, 0, 0, 0, 0, 0, 0);
        UO.Print(Convert.ToString(clear));
        return null;
    }
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.CheckLOS(xfrom, yfrom, zfrom, xto, yto, zto, worldNum) — UO.CheckLOS(Any,Any,Any,Any,Any,Any,Any)

Параметры: xfrom (Any), yfrom (Any), zfrom (Any), xto (Any), yto (Any), zto (Any), worldNum (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "checklos": return new InjectionValue(CheckPortableLineOfSight(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), Arg(5), Arg(6)) ? 1 : 0);

UO.ClearUserStatics

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

void UO.ClearUserStatics();

Удаляет все пользовательские static записи runtime и локальные статические объекты менеджера.

Параметры

Параметров нет.

Возвращает

void — возвращаемого значения нет.

Поведение

  • State.UserStatics и менеджерские объекты очищаются. Загруженные файлы карты и реальные серверные предметы не удаляются.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

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

UO.Print("Calling UO.ClearUserStatics");
UO.ClearUserStatics();

1. Очистить состояние — прямой скрипт

Параметры и ход выполнения:

  • Удаляет все пользовательские static записи runtime и локальные статические объекты менеджера.
UO.ClearUserStatics();

2. Очистить после настройки — функция сценария

Параметры и ход выполнения:

  • Добавить локальный статик на текущей клетке, затем удалить все пользовательские статики.
return  RunScenario();
 object? RunScenario()
{
    var localStatic = UO.AddUserStatic(0x0CCA, UO.GetX(), UO.GetY(), UO.GetZ(), 0, UO.WorldNum());
    UO.ClearUserStatics();
    return null;
}

3. Повторная очистка — класс сценария

Параметры и ход выполнения:

  • Очистка пустого набора допустима и не создаёт новую настройку.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        UO.ClearUserStatics();
        UO.ClearUserStatics();
        return null;
    }
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.ClearUserStatics() — UO.ClearUserStatics()

Параметры: Параметров нет.

Результат: void / Unit.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "clearuserstatics": state.UserStatics.Clear(); bridge.ClearUserStatics(); return InjectionValue.Unit;

UO.ConvertIntegerToFlags

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.ConvertIntegerToFlags(object? group, object? value);

Разбирает числовую маску tile flags в массив имён перечисления TileFlag.

Параметры

  • group — int: только 1 или 2 включают преобразование; любое другое значение даёт пустой массив.
  • value — Маска, которую Arg преобразует в знаковый 32-битный int, затем bridge приводит к ulong. Для высоких 64-битных флагов эта форма не сохраняет полную маску.

Возвращает

Array строк с именами ненулевых TileFlag, чьи биты полностью присутствуют в маске. Маска 0 даёт пустой массив.

Поведение

  • Group 1 и 2 используют один и тот же Enum.GetValues, а не разные каталоги. Это локальное преобразование маски; данные tiledata не запрашиваются.
  • API-регистрация использует object?, но диспетчер Arg(1) передаёт int. Отрицательный int sign-extends при приведении к ulong. GetTileFlags также возвращает лишь младшие 32 бита как signed int: эта совместимая пара не предоставляет полный 64-битный контракт tiledata.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.ConvertIntegerToFlags(1, 0);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Нулевая маска — прямой скрипт

Параметры и ход выполнения:

  • Ни один ненулевой flag не присутствует в маске 0.
var flags = UO.ConvertIntegerToFlags(1,0);
UO.Print(Convert.ToString(ArrayLength(flags)));

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

2. Маска низшего бита — функция сценария

Параметры и ход выполнения:

  • Массив содержит реальные имена TileFlag выбранной маски.
return  RunScenario();
 object? RunScenario()
{
    var flags = UO.ConvertIntegerToFlags(2, 1);
    for (int i = (int)(0); i <= ArrayLength(flags) - 1; i += (int)(1))
    {
        UO.Print(flags[i]);
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

3. Неверная группа — класс сценария

Параметры и ход выполнения:

  • Группа 0 не принята этой командой и возвращает пустой массив.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var flags = UO.ConvertIntegerToFlags(0, 1);
        UO.Print(Convert.ToString(ArrayLength(flags)));
        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.ConvertIntegerToFlags(group, value) — UO.ConvertIntegerToFlags(Any,Any)

Параметры: group (Any), value (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "convertintegertoflags":

                    return new InjectionValue(bridge.ConvertTileFlags(Arg(0), Arg(1))

                        .Select(flag => new InjectionValue(flag)).ToArray());

UO.Dist

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

int UO.Dist(object? xfrom, object? yfrom, object? xto, object? yto);

Вычисляет расстояние в клетках между двумя мировыми точками: наибольшую из абсолютных разностей X и Y.

Параметры

  • xfrom — Координата X исходной точки.
  • yfrom — Координата Y исходной точки.
  • xto — Координата X назначения.
  • yto — Координата Y назначения.

Возвращает

int — расстояние в клетках, неотрицательное для допустимых координат. 0 означает одинаковые XY, 1 — одну клетку. Это количество, а не признак успеха. Отдельное сравнение distance <= 2 возвращает bool true либо false; само расстояние остаётся int.

Поведение

  • Только вычисление координат: без пакетов, ожиданий, загрузки карты, проверки препятствий, Z и карты мира. Команда не ищет проходимый маршрут и не гарантирует достижение цели. Точки должны относиться к одной системе координат; обход препятствий может увеличить путь.
  • Нужны все четыре параметра. Передавайте мировые координаты int в документированном диапазоне 0..65535. object? в сигнатуре обозначает универсальный адаптер, а не ID предмета. Значений по умолчанию, координат внутри сундука, пятого Z и перегрузки с одним объектом у этих команд нет.
  • Формула: Max(Abs(Xto-Xfrom), Abs(Yto-Yfrom)). При перестановке точек результат тот же. Это не евклидово расстояние, не сумма разностей и не число шагов при обходе препятствия.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

var result = UO.Dist(100, 100, 103, 104);
UO.Print("Dist: " + Convert.ToString(result));

1. Прямое вычисление — прямой скрипт

Параметры и ход выполнения:

  • От (100,100) до (103,104): абсолютные разности равны 3 и 4, максимум — 4. Main возвращает int 4.
  • int — расстояние в клетках, неотрицательное для допустимых координат. 0 означает одинаковые XY, 1 — одну клетку. Это количество, а не признак успеха. Отдельное сравнение distance <= 2 возвращает bool true либо false; само расстояние остаётся int.
  • Формула: Max(Abs(Xto-Xfrom), Abs(Yto-Yfrom)). При перестановке точек результат тот же. Это не евклидово расстояние, не сумма разностей и не число шагов при обходе препятствия.
return UO.Dist(100,100,103,104);

2. Правильная проверка результата — функция сценария

Параметры и ход выполнения:

  • От (100,100) до (101,99) расстояние равно 1. Отдельное сравнение distance<=2 даёт true=1. Main возвращает "1:1": первая единица — расстояние, вторая — логический результат сравнения.
  • int — расстояние в клетках, неотрицательное для допустимых координат. 0 означает одинаковые XY, 1 — одну клетку. Это количество, а не признак успеха. Отдельное сравнение distance <= 2 возвращает bool true либо false; само расстояние остаётся int.
  • Формула: Max(Abs(Xto-Xfrom), Abs(Yto-Yfrom)). При перестановке точек результат тот же. Это не евклидово расстояние, не сумма разностей и не число шагов при обходе препятствия.
return  RunScenario();
 object? RunScenario()
{
    var distance = UO.Dist(100, 100, 101, 99);
    var close = distance <= 2;
    return Convert.ToString(distance) + ":" + Convert.ToString(close);
    return null;
}

3. Полный скриптовый разбор — класс сценария

Параметры и ход выполнения:

  • UO.Dist возвращает 4. RebuildTileDistance вычисляет разности через Abs, сравнивает их и возвращает большую, также 4. Main возвращает "4:4". Помощник полностью приведён в примере и не является ещё одной командой движка.
  • int — расстояние в клетках, неотрицательное для допустимых координат. 0 означает одинаковые XY, 1 — одну клетку. Это количество, а не признак успеха. Отдельное сравнение distance <= 2 возвращает bool true либо false; само расстояние остаётся int.
  • Формула: Max(Abs(Xto-Xfrom), Abs(Yto-Yfrom)). При перестановке точек результат тот же. Это не евклидово расстояние, не сумма разностей и не число шагов при обходе препятствия.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var actual = UO.Dist(100, 100, 103, 104);
        var rebuilt = RebuildTileDistance(100, 100, 103, 104);
        return Convert.ToString(actual) + ":" + Convert.ToString(rebuilt);
        return null;
    }

    dynamic RebuildTileDistance(dynamic Xfrom, dynamic Yfrom, dynamic Xto, dynamic Yto)
    {
        var dx = Math.Abs(Xto - Xfrom);
        var dy = Math.Abs(Yto - Yfrom);
        if (Truth(dx > dy))
        {
            return dx;
        }

        return dy;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.Dist(xfrom, yfrom, xto, yto) — UO.Dist(Any,Any,Any,Any)

Параметры: xfrom (Any), yfrom (Any), xto (Any), yto (Any)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "dist": return new InjectionValue(arguments.Length >= 4

                    ? GetDistance(Arg(0), Arg(1), Arg(2), Arg(3))

                    : bridge.GetDistance(Arg(0)));

UO.GetDistance

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

int UO.GetDistance(object? id);
int UO.GetDistance(object? x, object? y);
int UO.GetDistance(object? id1, object? x2, object? y2);
int UO.GetDistance(object? x1, object? y1, object? x2, object? y2);

Измеряет расстояние в клетках по максимуму разностей X/Y. Это геометрическая оценка без поиска пути.

Параметры

  • id — Один аргумент: serial или алиас загруженного объекта, расстояние до которого нужно получить.
  • x — Два аргумента: мировая точка назначения. Началом служат GetX(self), GetY(self).
  • y — Два аргумента: мировая точка назначения. Началом служат GetX(self), GetY(self).
  • id1 — В форме с тремя аргументами — serial/алиас объекта, координаты которого служат началом.
  • x1 — В форме с четырьмя аргументами — координаты начала. Никакой объект для этой формы не нужен.
  • y1 — В форме с четырьмя аргументами — координаты начала. Никакой объект для этой формы не нужен.
  • x2 — В формах с тремя/четырьмя аргументами — координаты конца. Не путайте их с serial второго объекта.
  • y2 — В формах с тремя/четырьмя аргументами — координаты конца. Не путайте их с serial второго объекта.

Возвращает

int — max(abs(x2-x1), abs(y2-y1)): горизонталь, вертикаль и диагональ на соседнюю клетку имеют расстояние 1. Высота Z и препятствия не учитываются. Для неизвестного serial форма с одним аргументом возвращает 0; для существующего объекта при отсутствии персонажа — 65535. Для неизвестного id1 форма с тремя аргументами использует (0,0), поэтому сначала проверяйте Exists(id1).

Поведение

  • Форма с одним объектом использует текущий центр расчёта дальности World.RangeSize и последнюю позицию из очереди шагов движущегося моба. Во время движения результат может отличаться от расчёта через GetX/GetY.
  • Координатные формы работают с переданными числами. Для игровых координат используйте диапазон 0..65535; экстремальные значения int и переполнение разности не являются поддерживаемыми координатами.
  • Команда не обещает достижимость цели. Для движения нужен MoveXY/NewMoveXY и проверка его результата; стены могут сделать реальный путь длиннее.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

var result = UO.GetDistance("lasttarget");
UO.Print("GetDistance: " + Convert.ToString(result));

1. Проверить дальность до цели — прямой скрипт

Параметры и ход выполнения:

  • target — serial, не type. Проверка Exists не позволяет принять ноль неизвестного объекта за близкую цель.
  • distance<=2 проверяет дальность по X/Y. Видимость и проходимость проверяются отдельно.
var target = UO.GetSerial("lasttarget");
if (Truth(UO.Exists(target)))
{
    var distance = UO.GetDistance(target);
    if (Truth(distance <= 2))
    {
        UO.Print("Target is within two tiles");
    }
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Расстояние между двумя точками — функция сценария

Параметры и ход выполнения:

  • x1=100, y1=200, x2=103, y2=204. Разности равны 3 и 4.
  • Результат равен 4, а не 7 и не евклидовым 5.
return  RunScenario();
 object? RunScenario()
{
    var distance = UO.GetDistance(100, 200, 103, 204);
    UO.Print(Convert.ToString(distance));
    return null;
}

3. Начало из объекта и из своего персонажа — класс сценария

Параметры и ход выполнения:

  • Два аргумента x/y используют текущую позицию self. Три аргумента id1/x2/y2 позволяют явно задать объект начала.
  • При неизменной позиции обе величины равны 3. Координаты должны оставаться в границах карты.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var x = UO.GetX() + 3;
        var y = UO.GetY() + 1;
        var fromSelf = UO.GetDistance(x, y);
        var fromObject = UO.GetDistance("self", x, y);
        UO.Print(Convert.ToString(fromSelf) + " / " + Convert.ToString(fromObject));
        return null;
    }
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetDistance(id) — UO.GetDistance(Any)

Параметры: id (Any/Integer/String)

Результат: int / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getdistance": return new InjectionValue(bridge.GetDistance(Arg(0)));

UO.GetDistance(id) — UO.GetDistance(Integer)

Параметры: id (Any/Integer/String)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetDistance(int id) => bridge.GetDistance(id);

UO.GetDistance(id) — UO.GetDistance(String)

Параметры: id (Any/Integer/String)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetDistance(string id) => GetDistance(GetObject(id));

UO.GetDistance(x, y) — UO.GetDistance(Integer,Integer)

Параметры: x (Integer), y (Integer)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetDistance(int x, int y) => GetDistance(bridge.GetX(bridge.Self), bridge.GetY(bridge.Self), x, y);

UO.GetDistance(id1, x2, y2) — UO.GetDistance(Any,Any,Any)

Параметры: id1 (Any), x2 (Any), y2 (Any)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetDistance(InjectionValue id1, InjectionValue x2, InjectionValue y2)

        {

            var obj1 = GetObject(id1);

            int x1 = bridge.GetX(obj1);

            int y1 = bridge.GetY(obj1);



            return GetDistance(x1, y1, NumberConversions.ToInt(x2), NumberConversions.ToInt(y2));

        }

UO.GetDistance(x1, y1, x2, y2) — UO.GetDistance(Integer,Integer,Integer,Integer)

Параметры: x1 (Integer), y1 (Integer), x2 (Integer), y2 (Integer)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetDistance(int x1, int y1, int x2, int y2)

        {

            int dx = Math.Abs(x1 - x2);

            int dy = Math.Abs(y1 - y2);



            return Math.Max(dx, dy);

        }

UO.GetLandTileAt

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetLandTileAt(object? x, object? y);
dynamic UO.GetLandTileAt(object? x, object? y, object? map);

Возвращает расширенную запись земли выбранной клетки.

Параметры

  • x — X клетки текущей загруженной карты; мировая координата, не позиция внутри гампа.
  • y — Y клетки текущей загруженной карты; мировая координата, не позиция внутри гампа.
  • map — Номер карты. Если этот аргумент отсутствует в выбранной форме, используется текущая карта. Реальный клиент читает тайлы только текущей загруженной карты.

Возвращает

Array из 11 полей одной записи; индексы начинаются с 0:

  • [0] kind — string: "land", "static" либо "object".
  • [1] serial — int: serial динамического предмета; для land/static равен 0.
  • [2] graphic — int: type графики.
  • [3] x, [4] y — int: мировые координаты клетки.
  • [5] z — int: высота основания в мире.
  • [6] hue — int: цвет, у земли 0.
  • [7] flags — int: младшие 32 бита флагов tiledata.
  • [8] name — string: название из tiledata.
  • [9] layer — int: слой экипировки из tiledata, у земли 0; не индекс статики.
  • [10] height — int: высота graphic из tiledata, у земли 0; не координата Z.

Пустой массив [] означает отсутствие записи или недоступную карту/клетку. Для GetStaticTileAt отрицательный/слишком большой index также даёт []; переполнение индекса не выбирает чужую запись.

Поведение

  • Данные относятся к текущей загруженной карте. Другая карта или недоступная клетка дают пустой массив. Прямые запросы тайлов могут дополнительно сообщать о несовпадении карты; GetWorldCell и GetWorldTilesArray сразу возвращают пустой массив без такого сообщения.
  • Индексы массивов начинаются с 0. Перед чтением поля проверяйте ArrayLength. Z означает высоту в мире; layer — свойство экипировки из tiledata, а index — порядковый номер записи клетки.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetLandTileAt(UO.GetX(), UO.GetY());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Раздельно прочитать type, Z и слой — прямой скрипт

Параметры и ход выполнения:

  • x/y — положение персонажа; карта опущена и выбирается автоматически. Для GetStaticTileAt index=0 означает первую запись.
  • Поля [2], [5], [9] имеют разный смысл; все читаются только после проверки длины 11.
var tile = UO.GetLandTileAt(UO.GetX(), UO.GetY());
if (Truth(ArrayLength(tile) == 11))
{
    UO.Print("Type: " + Convert.ToString(tile[2]));
    UO.Print("World Z: " + Convert.ToString(tile[5]));
    UO.Print("Equipment layer: " + Convert.ToString(tile[9]));
}
else
{
    UO.Print("Tile is unavailable");
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Получить имя и высоту graphic — функция сценария

Параметры и ход выполнения:

  • Используются те же координаты; GetStaticTileAt читает index=0.
  • tile[8] — строка названия, tile[10] — размер по высоте из tiledata, а не Z основания.
return  RunScenario();
 object? RunScenario()
{
    var tile = UO.GetLandTileAt(UO.GetX(), UO.GetY());
    if (Truth(ArrayLength(tile) == 11))
    {
        UO.Print(tile[8]);
        UO.Print("Graphic height: " + Convert.ToString(tile[10]));
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Подготовить цель по type и координатам — класс сценария

Параметры и ход выполнения:

  • WaitTargetTile получает graphic, x, y, z из полей 2…5.
  • Это только подготовка следующего target. Пример не запускает применение инструмента или заклинание. serial=0 для статики не следует передавать как ID предмета.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var tile = UO.GetLandTileAt(UO.GetX(), UO.GetY());
        if (Truth(ArrayLength(tile) == 11))
        {
            UO.WaitTargetTile(tile[2], tile[3], tile[4], tile[5]);
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetLandTileAt(x, y) — UO.GetLandTileAt(Any,Any)

Параметры: x (Any), y (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetLandTileAt(InjectionValue x, InjectionValue y)

            => GetLandTileAt(x, y, new InjectionValue(bridge.WorldNumber));

UO.GetLandTileAt(x, y, map) — UO.GetLandTileAt(Any,Any,Any)

Параметры: x (Any), y (Any), map (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetLandTileAt(InjectionValue x, InjectionValue y, InjectionValue map)

        {

            int cellX = NumberConversions.ToInt(x);

            int cellY = NumberConversions.ToInt(y);

            int world = NumberConversions.ToInt(map);

            int[] land = bridge.GetLandscapeTile(cellX, cellY, world) ?? Array.Empty<int>();

            return land.Length >= 2

                ? BuildWorldTileRecord("land", 0, land[0], cellX, cellY, land[1], 0, 0)

                : new InjectionValue(Array.Empty<InjectionValue>());

        }

UO.GetLandTileData

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetLandTileData(object? tile);

Читает расширенную справочную запись земли из tiledata.

Параметры

  • tile — Graphic/type записи, не serial и не индекс внутри клетки. Таблица земли выбрана самим именем команды.

Возвращает

Array из 7 полей для допустимого graphic. Все поля int, кроме name (string):

  • [0] graphic — graphic/type записи.
  • [1] flags — младшие 32 бита флагов.
  • [2] name — название из tiledata (string).
  • [3] texId — ID текстуры земли.
  • [4] wet — 1 если установлен wet, иначе 0.
  • [5] impassable — 1 если impassable, иначе 0.
  • [6] noDiagonal — 1 если noDiagonal, иначе 0.

Для недопустимого graphic справочные свойства отсутствуют: возвращается короткий массив [переданный graphic, 0, ""]. Проверяйте полную длину перед чтением свойств. Это не Pascal record и не список объектов.

Поведение

  • Команда читает tiledata и не требует предмета с этим graphic в мире. Флаги описывают ресурс; результат не заменяет полноценную проверку маршрута.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetLandTileData(0x0003);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Прочитать имя записи — прямой скрипт

Параметры и ход выполнения:

  • Tile — числовой graphic выбранной таблицы.
  • data[2] содержит имя. Проверка длины отделяет полноценную запись от короткой записи недопустимого graphic.
var data = UO.GetLandTileData(0x0003);
if (Truth(ArrayLength(data) == 7))
{
    UO.Print(data[2]);
}
else
{
    UO.Print("Tiledata entry is unavailable");
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Проверить отдельный логический флаг — функция сценария

Параметры и ход выполнения:

  • data[5] — отдельное поле impassable: 1 (условие выполнено), 0 (условие не выполнено).
  • Эта проверка не учитывает другие объекты в клетке или способности персонажа.
return  RunScenario();
 object? RunScenario()
{
    var data = UO.GetLandTileData(0x0003);
    if (Truth(ArrayLength(data) == 7))
    {
        if (Truth(data[5]))
        {
            UO.Print("Impassable flag is set");
        }
        else
        {
            UO.Print("Impassable flag is not set");
        }
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Вывести graphic и общую маску флагов — класс сценария

Параметры и ход выполнения:

  • data[0] повторяет переданный graphic, data[1] — общая маска флагов.
  • Маска может содержать одновременно несколько битов; её численное значение не является serial.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var data = UO.GetLandTileData(0x0003);
        if (Truth(ArrayLength(data) == 7))
        {
            UO.Print("Graphic: " + Convert.ToString(data[0]));
            UO.Print("Flags: " + Convert.ToString(data[1]));
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetLandTileData(tile) — UO.GetLandTileData(Any)

Параметры: tile (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getlandtiledata":

                    return BuildTileData(0, Arg(0));

UO.GetLandTilesArray

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetLandTilesArray(object? xmin, object? ymin, object? xmax, object? ymax, object? worldNum, object? tileType);

Ищет тайлы земли по graphic/type в прямоугольнике.

Параметры

  • xmin — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • ymin — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • xmax — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • ymax — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • worldNum — Карта/фасет 0..255; используйте UO.WorldNum(). Другая карта даёт пустой Array. Если карта меняется между порциями, частичный результат отбрасывается.
  • tileType — Один graphic/type тайла, обычно 0..65535; это не serial. 0 — точный graphic 0, -1 не означает любой type. Несовпадающий type даёт пустой результат.

Возвращает

Array записей [graphic, X, Y, Z]; все поля int. graphic — type земли, Z — её основание. Нет совпадений: пустой Array. Количество — ArrayLength(result), не сам результат. Индексы начинаются с 0. Это не bool, serial или Pascal record; седьмого выходного параметра нет.

Поведение

  • Читаются локальные данные. Поиск не меняет FindItem/FindCount и не выполняет движение, target или сетевую команду.
  • Порядок: X по возрастанию, внутри X — Y по возрастанию. Записи одной клетки сохраняют порядок bridge; это не сортировка по расстоянию или высоте.
  • Поиск обрабатывается порциями до 32 клеток с мягким бюджетом около 1 мс. Отмена проверяется между порциями. Сложная клетка или холодное чтение могут превысить бюджет. Большую область лучше делить; мир может меняться во время чтения.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetLandTilesArray(UO.GetX(), UO.GetY(), UO.GetX() + 2, UO.GetY() + 2, UO.WorldNum(), 0x0003);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Поиск рядом с персонажем — прямой скрипт

Параметры и ход выполнения:

  • x/y — позиция self, map — текущая карта. Область 3×3 включает границы. В Ex передаются два type, в обычной форме один. Измените образцы под свои ресурсы; это graphic, не ID объекта.
var x = UO.GetX();
var y = UO.GetY();
var map = UO.WorldNum();
var rows = UO.GetLandTilesArray(x, y, x + 2, y + 2, map, 0x0003);
UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

2. Переставленные углы и вывод всех полей — функция сценария

Параметры и ход выполнения:

  • Область 2×2 передана от большего угла к меньшему. Алгоритм сам нормализует границы. row — одна запись; PrintTile объявлена целиком и только форматирует числа, ничего не перемещая. graphic — type, x/y — координаты, z — высота, hue — цвет. Для земли передан условный hue=0: в записи земли нет поля цвета.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX();
    var y = UO.GetY();
    var map = UO.WorldNum();
    var rows = UO.GetLandTilesArray(x + 1, y + 1, x, y, map, 0x0003);
    var i = 0;
    while (Truth(i < ArrayLength(rows)))
    {
        var row = rows[i];
        PrintTile(row[0], row[1], row[2], row[3], 0);
        i = i + 1;
    }

    return null;
}

void PrintTile(dynamic graphic, dynamic x, dynamic y, dynamic z, dynamic hue)
{
    UO.Print("Type=" + Convert.ToString(graphic) + " X=" + Convert.ToString(x) + " Y=" + Convert.ToString(y));
    UO.Print("Z=" + Convert.ToString(z) + " hue=" + Convert.ToString(hue));
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Повторный опрос с ограничением попыток — класс сценария

Параметры и ход выполнения:

  • Не более трёх поисков одной клетки; между попытками WaitAsync(250). Каждый вызов создаёт новый результат. Нулевая длина означает отсутствие совпадений сейчас, а не постоянное отсутствие объекта на сервере.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var attempt = 0;
        while (Truth(attempt < 3))
        {
            var rows = UO.GetLandTilesArray(x, y, x, y, map, 0x0003);
            UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));
            attempt = attempt + 1;
            await Delay(250);
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetLandTilesArray(xmin, ymin, xmax, ymax, worldNum, tileType) — UO.GetLandTilesArray(Any,Any,Any,Any,Any,Any)

Параметры: xmin (Any), ymin (Any), xmax (Any), ymax (Any), worldNum (Any), tileType (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getlandtilesarray":

                    return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), new[] { Arg(5) }, false);

UO.GetLandTilesArrayEx

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetLandTilesArrayEx(object? xmin, object? ymin, object? xmax, object? ymax, object? worldNum, object? tileTypes);

Ищет тайлы земли по graphic/type в прямоугольнике.

Параметры

  • xmin — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • ymin — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • xmax — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • ymax — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • worldNum — Карта/фасет 0..255; используйте UO.WorldNum(). Другая карта даёт пустой Array. Если карта меняется между порциями, частичный результат отбрасывается.
  • tileTypes — Array числовых graphic/type; каждый совпадающий type включается. Повторение type не дублирует записи. Скаляр также принимается как один type. Пустой Array означает все type; массив из одного 0 ищет только 0.

Возвращает

Array записей [graphic, X, Y, Z]; все поля int. graphic — type земли, Z — её основание. Нет совпадений: пустой Array. Количество — ArrayLength(result), не сам результат. Индексы начинаются с 0. Это не bool, serial или Pascal record; седьмого выходного параметра нет.

Поведение

  • Читаются локальные данные. Поиск не меняет FindItem/FindCount и не выполняет движение, target или сетевую команду.
  • Порядок: X по возрастанию, внутри X — Y по возрастанию. Записи одной клетки сохраняют порядок bridge; это не сортировка по расстоянию или высоте.
  • Поиск обрабатывается порциями до 32 клеток с мягким бюджетом около 1 мс. Отмена проверяется между порциями. Сложная клетка или холодное чтение могут превысить бюджет. Большую область лучше делить; мир может меняться во время чтения.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetLandTilesArrayEx(UO.X(), UO.Y(), UO.X() + 1, UO.Y() + 1, UO.WorldNum(), new[] { 0x0003 });
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Поиск рядом с персонажем — прямой скрипт

Параметры и ход выполнения:

  • x/y — позиция self, map — текущая карта. Область 3×3 включает границы. В Ex передаются два type, в обычной форме один. Измените образцы под свои ресурсы; это graphic, не ID объекта.
dynamic[] types = new dynamic[checked((int)(1) + 1)];
types[0] = 0x0003;
types[1] = 0x0004;
var x = UO.GetX();
var y = UO.GetY();
var map = UO.WorldNum();
var rows = UO.GetLandTilesArrayEx(x, y, x + 2, y + 2, map, types);
UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

2. Переставленные углы и вывод всех полей — функция сценария

Параметры и ход выполнения:

  • Область 2×2 передана от большего угла к меньшему. Алгоритм сам нормализует границы. row — одна запись; PrintTile объявлена целиком и только форматирует числа, ничего не перемещая. graphic — type, x/y — координаты, z — высота, hue — цвет. Для земли передан условный hue=0: в записи земли нет поля цвета.
return  RunScenario();
 object? RunScenario()
{
    dynamic[] types = new dynamic[checked((int)(1) + 1)];
    types[0] = 0x0003;
    types[1] = 0x0004;
    var x = UO.GetX();
    var y = UO.GetY();
    var map = UO.WorldNum();
    var rows = UO.GetLandTilesArrayEx(x + 1, y + 1, x, y, map, types);
    var i = 0;
    while (Truth(i < ArrayLength(rows)))
    {
        var row = rows[i];
        PrintTile(row[0], row[1], row[2], row[3], 0);
        i = i + 1;
    }

    return null;
}

void PrintTile(dynamic graphic, dynamic x, dynamic y, dynamic z, dynamic hue)
{
    UO.Print("Type=" + Convert.ToString(graphic) + " X=" + Convert.ToString(x) + " Y=" + Convert.ToString(y));
    UO.Print("Z=" + Convert.ToString(z) + " hue=" + Convert.ToString(hue));
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Повторный опрос с ограничением попыток — класс сценария

Параметры и ход выполнения:

  • Не более трёх поисков одной клетки; между попытками WaitAsync(250). Каждый вызов создаёт новый результат. Нулевая длина означает отсутствие совпадений сейчас, а не постоянное отсутствие объекта на сервере.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        dynamic[] types = new dynamic[checked((int)(1) + 1)];
        types[0] = 0x0003;
        types[1] = 0x0004;
        var x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var attempt = 0;
        while (Truth(attempt < 3))
        {
            var rows = UO.GetLandTilesArrayEx(x, y, x, y, map, types);
            UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));
            attempt = attempt + 1;
            await Delay(250);
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetLandTilesArrayEx(xmin, ymin, xmax, ymax, worldNum, tileTypes) — UO.GetLandTilesArrayEx(Any,Any,Any,Any,Any,Any)

Параметры: xmin (Any), ymin (Any), xmax (Any), ymax (Any), worldNum (Any), tileTypes (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getlandtilesarrayex":

                    return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), ArrayArg(5), false);

UO.GetLandscapeTile

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetLandscapeTile(object? x, object? y, object? map);

Читает землю одной клетки текущей карты.

Параметры

  • x — X клетки текущей загруженной карты; мировая координата, не позиция внутри гампа.
  • y — Y клетки текущей загруженной карты; мировая координата, не позиция внутри гампа.
  • map — Номер карты. Если этот аргумент отсутствует в выбранной форме, используется текущая карта. Реальный клиент читает тайлы только текущей загруженной карты.

Возвращает

Array из трёх int: [0] graphic — type земли; [1] z — мировая высота земли; [2] flags — младшие 32 бита tiledata-флагов. Если карта/клетка недоступна или земли нет, возвращается пустой массив []. Это плоская запись, а не список из трёх тайлов.

Поведение

  • Данные относятся к текущей загруженной карте. Другая карта или недоступная клетка дают пустой массив. Прямые запросы тайлов могут дополнительно сообщать о несовпадении карты; GetWorldCell и GetWorldTilesArray сразу возвращают пустой массив без такого сообщения.
  • Индексы массивов начинаются с 0. Перед чтением поля проверяйте ArrayLength. Z означает высоту в мире; layer — свойство экипировки из tiledata, а index — порядковый номер записи клетки.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

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

Параметры и ход выполнения:

  • x/y берутся из позиции персонажа; map=WorldNum() выбирает текущую карту.
  • Наличие трёх полей проверяется до индексации; land[0] — graphic, land[1] — Z.
var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
if (Truth(ArrayLength(land) >= 3))
{
    UO.Print("Graphic: " + Convert.ToString(land[0]));
    UO.Print("Ground Z: " + Convert.ToString(land[1]));
}
else
{
    UO.Print("Land is unavailable");
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Сравнить высоту соседней клетки — функция сценария

Параметры и ход выполнения:

  • x+1 — соседняя клетка, y и map сохраняются.
  • deltaZ сравнивает землю и персонажа. Это не проверка проходимости: мосты и статики учитываются отдельно.
return  RunScenario();
 object? RunScenario()
{
    var land = UO.GetLandscapeTile(UO.GetX() + 1, UO.GetY(), UO.WorldNum());
    if (Truth(ArrayLength(land) >= 3))
    {
        var deltaZ = land[1] - UO.GetZ();
        UO.Print("Ground height difference: " + Convert.ToString(deltaZ));
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Прочитать название найденной земли — класс сценария

Параметры и ход выполнения:

  • group=0 выбирает землю; land[0] — graphic.
  • GetTileName возвращает текст, тогда как GetLandscapeTile возвращает массив.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(land) >= 3))
        {
            var name = UO.GetTileName(0, land[0]);
            UO.Print(name);
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetLandscapeTile(x, y, map) — UO.GetLandscapeTile(Any,Any,Any)

Параметры: x (Any), y (Any), map (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetLandscapeTile(InjectionValue x, InjectionValue y, InjectionValue map)

            => ToArray(bridge.GetLandscapeTile(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map)));

UO.GetLayerCount

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetLayerCount(object? x, object? y, object? worldNum);

Считает записи неземельной геометрии в одной клетке.

Параметры

  • x — Мировая координата X клетки текущей карты, не положение в гампе.
  • y — Мировая координата Y клетки текущей карты.
  • worldNum — Номер карты/фасета; используйте UO.WorldNum(). Читается только текущая загруженная карта.

Возвращает

int — количество троек graphic/Z/hue, полученных GetStaticTiles. В текущем клиенте учитываются Static, Multi и Item: несколько записей одной высоты считаются отдельно. Пустая клетка/другая карта дают 0. Это не номер слоя экипировки, не число этажей, не количество уникальных высот и не bool.

Поведение

  • Команда читает локальную карту и не запускает движение или target. Клетка за пределами размеров карты не подменяется клеткой соседнего столбца.
  • Высота Z, graphic/type, цвет hue, флаги и слой экипировки имеют разный смысл. Нулевой graphic или Z=0 могут быть допустимыми данными; проверяйте форму результата.
  • Состав соответствует ReadStaticsXY, а не GetLayer или ObjAtLayer. Этот клиент включает динамические предметы и части Multi.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetLayerCount(UO.GetX(), UO.GetY(), UO.WorldNum());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Посчитать записи под персонажем — прямой скрипт

Параметры и ход выполнения:

  • count — число записей клетки; 1 означает одну запись, а не логический успех.
var count = UO.GetLayerCount(UO.GetX(), UO.GetY(), UO.WorldNum());
UO.Print("Tile records: " + Convert.ToString(count));

2. Проверить соседнюю клетку — функция сценария

Параметры и ход выполнения:

  • Отсутствие записей не доказывает проходимость земли. Наличие записи тоже не доказывает, что она является стеной.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX() + 1;
    var y = UO.GetY();
    var count = UO.GetLayerCount(x, y, UO.WorldNum());
    if (Truth(count > 0))
    {
        UO.Print("Non-land geometry exists: " + Convert.ToString(count));
    }
    else
    {
        UO.Print("No loaded non-land records");
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Сравнить содержимое двух слоёв карты — класс сценария

Параметры и ход выполнения:

  • Проверяются текущая и соседняя клетки в том же мире. Количество слоёв не является их высотой или graphic.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        int x = UO.GetX();
        int y = UO.GetY();
        int world = UO.WorldNum();
        int land = UO.GetLayerCount(x, y, world);
        int nearby = UO.GetLayerCount(x + 1, y, world);
        UO.Print($"Layers here: {land}; adjacent tile: {nearby}");
        return null;
    }
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetLayerCount(x, y, worldNum) — UO.GetLayerCount(Any,Any,Any)

Параметры: x (Any), y (Any), worldNum (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getlayercount":

                    // Stealth's deprecated GetLayerCount(X,Y,WorldNum) is the

                    // number of static records at a map cell.  The portable

                    // bridge returns each record as Graphic/Z/Hue triples.

                    return new InjectionValue(bridge.GetStaticTiles(Arg(0), Arg(1), Arg(2)).Length / 3);

UO.GetMapCell

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetMapCell(object? x, object? y, object? worldNum);

Читает graphic, высоту и флаги земли в одной клетке карты.

Параметры

  • x — Мировая координата X клетки текущей карты, не положение в гампе.
  • y — Мировая координата Y клетки текущей карты.
  • worldNum — Номер карты/фасета; используйте UO.WorldNum(). Читается только текущая загруженная карта.

Возвращает

Array из трёх int: [0] graphic/type земли, [1] мировая Z основания land, [2] младшие 32 бита флагов tiledata. Недоступная клетка или другая карта дают пустой Array. Это не serial, bool или Pascal record; не используйте поля .Tile/.Z. Для количества полей вызывайте ArrayLength(cell).

Поведение

  • Команда читает локальную карту и не запускает движение или target. Клетка за пределами размеров карты не подменяется клеткой соседнего столбца.
  • Высота Z, graphic/type, цвет hue, флаги и слой экипировки имеют разный смысл. Нулевой graphic или Z=0 могут быть допустимыми данными; проверяйте форму результата.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetMapCell(UO.GetX(), UO.GetY(), UO.WorldNum());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Прочитать землю под персонажем — прямой скрипт

Параметры и ход выполнения:

  • X/Y берутся у self, WorldNum — текущая карта. cell сохраняет все поля одного вызова.
  • Индексы начинаются с 0. cell[1] — высота, а не признак успешного поиска; пустой массив проверяется до индексации.
var cell = UO.GetMapCell(UO.GetX(), UO.GetY(), UO.WorldNum());
if (Truth(ArrayLength(cell) == 3))
{
    UO.Print("Type: " + Convert.ToString(cell[0]));
    UO.Print("Land Z: " + Convert.ToString(cell[1]));
    UO.Print("Flags: " + Convert.ToString(cell[2]));
}
else
{
    UO.Print("Map cell unavailable");
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Сравнить две соседние клетки — функция сценария

Параметры и ход выполнения:

  • Второй вызов читает клетку восточнее, оба используют одну карту.
  • Разность высот земли не доказывает проходимость: стены, статики и другие объекты проверяются отдельно.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX();
    var y = UO.GetY();
    var map = UO.WorldNum();
    var here = UO.GetMapCell(x, y, map);
    var east = UO.GetMapCell(x + 1, y, map);
    if (Truth(ArrayLength(here) == 3) && Truth(ArrayLength(east) == 3))
    {
        UO.Print("Land difference: " + Convert.ToString(east[1] - here[1]));
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Сравнить основание земли со средней поверхностью — класс сценария

Параметры и ход выполнения:

  • GetMapCell читает Land.Z; GetSurfaceZ читает Land.AverageZ.
  • Оба значения являются высотой. На наклонной земле они могут различаться; это не высота пола дома.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var cell = UO.GetMapCell(x, y, map);
        if (Truth(ArrayLength(cell) == 3))
        {
            var average = UO.GetSurfaceZ(x, y, map);
            UO.Print("Base: " + Convert.ToString(cell[1]) + ", average: " + Convert.ToString(average));
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetMapCell(x, y, worldNum) — UO.GetMapCell(Any,Any,Any)

Параметры: x (Any), y (Any), worldNum (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getmapcell":

                    return new InjectionValue(bridge.GetLandscapeTile(Arg(0), Arg(1), Arg(2))

                        .Select(value => new InjectionValue(value)).ToArray());

UO.GetNextStepZ

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

int UO.GetNextStepZ(object? currX, object? currY, object? destX, object? destY, object? worldNum, object? currZ);

Вычисляет предполагаемую высоту следующего шага в указанном направлении.

Параметры

  • currX — Исходная мировая X, обычно UO.GetX().
  • currY — Исходная мировая Y, обычно UO.GetY().
  • destX — X назначения. Для проверки одного конкретного шага передавайте соседнюю клетку.
  • destY — Y назначения; вместе с DestX задаёт направление одного шага, а не полный маршрут.
  • worldNum — Номер карты/фасета; используйте UO.WorldNum(). Читается только текущая загруженная карта.
  • currZ — Исходная высота Z, обычно UO.GetZ(); геометрический расчёт использует диапазон -128..127.

Возвращает

int — рассчитанная Z следующего шага; 0 и отрицательные числа являются допустимой высотой. При отключённом персонаже или другой карте 0. Метод возвращает компонент Z проверки даже при непроходимости; само число не является подтверждением прохода. Для флага и высоты вместе используйте IsWorldCellPassable и читайте [0]/[1].

Поведение

  • Команда читает локальную карту и не запускает движение или target. Клетка за пределами размеров карты не подменяется клеткой соседнего столбца.
  • Высота Z, graphic/type, цвет hue, флаги и слой экипировки имеют разный смысл. Нулевой graphic или Z=0 могут быть допустимыми данными; проверяйте форму результата.
  • Расчёт не делает шаг и не открывает дверь. Он проверяет локальную геометрию; сервер может отклонить реальное движение. Если bridge не вернул Z, используется CurrZ.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

var result = UO.GetNextStepZ(UO.GetX(), UO.GetY(), UO.GetX() + 1, UO.GetY(), UO.WorldNum(), UO.GetZ());
UO.Print("GetNextStepZ: " + Convert.ToString(result));

1. Узнать предполагаемую высоту восточного шага — прямой скрипт

Параметры и ход выполнения:

  • Шесть параметров: исходные X/Y, соседние X/Y, карта и исходная Z. nextZ — высота, не true/false.
var x = UO.GetX();
var y = UO.GetY();
var z = UO.GetZ();
var nextZ = UO.GetNextStepZ(x, y, x + 1, y, UO.WorldNum(), z);
UO.Print("Candidate Z: " + Convert.ToString(nextZ));

2. Отделить отключение от настоящей высоты 0 — функция сценария

Параметры и ход выполнения:

  • Вызов выполняется только при известном подключении. Между проверкой и чтением соединение может пропасть; Z=0 всё равно не является кодом успеха.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(Truth(UO.Connected()) == true))
    {
        var x = UO.GetX();
        var y = UO.GetY();
        var z = UO.GetNextStepZ(x, y, x, y + 1, UO.WorldNum(), UO.GetZ());
        UO.Print("South candidate Z: " + Convert.ToString(z));
    }
    else
    {
        UO.Print("Character disconnected");
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Проверить следующий шаг с текущей высоты — класс сценария

Параметры и ход выполнения:

  • Координаты исходной и целевой клеток передаются отдельно. Результат — предполагаемая высота, даже при непроходимости; флаг прохода отдельно даёт IsWorldCellPassable.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        int x = UO.GetX();
        int y = UO.GetY();
        int z = UO.GetZ();
        int nextZ = UO.GetNextStepZ(x, y, x + 1, y, UO.WorldNum(), z);
        UO.Print($"Current height: {z}; next-step result: {nextZ}");
        return null;
    }
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetNextStepZ(currX, currY, destX, destY, worldNum, currZ) — UO.GetNextStepZ(Any,Any,Any,Any,Any,Any)

Параметры: currX (Any), currY (Any), destX (Any), destY (Any), worldNum (Any), currZ (Any)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getnextstepz":

                {

                    if (bridge.IsOnline() == 0 || Arg(4) != bridge.WorldNumber)

                        return new InjectionValue(0);

                    int[] step = bridge.CheckWorldStep(Arg(0), Arg(1), Arg(5), Arg(2), Arg(3), Arg(4));

                    return new InjectionValue(step.Length > 1 ? step[1] : Arg(5));

                }

UO.GetStaticArt

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetStaticArt(object? objType, object? hue);

Получает изображение одного Graphic из установленных файлов графики Ultima Online и возвращает его в памяти в формате BMP. Пригодится для проверки своих игровых ресурсов, размеров иконки, чтения цвета пикселя и сравнения окрашенных вариантов предмета. Команда сама не открывает окно, не сохраняет файл и не ищет предметы в мире.

Параметры

  • objType — Обязательный Graphic/type из раздела static art: целое 0..65535, строка с таким числом или сохранённое имя AddType. Например 0x0EED — арт стопки золота. Это не serial предмета, не map/tile координата и не номер анимации тела. Чтобы получить арт загруженного предмета, передайте UO.GetType(item), где item — его serial. При числовом type вне диапазона получается пустой массив; неизвестное строковое имя вызывает ошибку преобразования.
  • hue — Обязательное целое значение окраски: 0 — исходные цвета арта; положительное значение — hue из файлов клиента. Числовые строки допустимы, в том числе результат UO.GetColor(item). Значение ограничивается диапазоном 0..65535: отрицательное превращается в 0, слишком большое — в 65535. Здесь -1 НЕ означает любой цвет. Для арта с флагом PartialHue используется частичное окрашивание; для остальных — полное. Результат конкретного hue зависит от загруженной таблицы цветов.

Возвращает

Array — одномерный массив int, каждый элемент 0..255 представляет один байт полного BMP-файла, начиная с заголовка. Индексация с 0. Это не bool, не ID, не путь, не объект Bitmap и не массив цветов RGB. Пустой массив означает, что числовой type недопустим, арт отсутствует или необходимые игровые файлы не загружены. Перед чтением заголовка проверяйте ArrayLength; пустой массив не равен числу 0.

Поведение

  • Нужно ровно два аргумента. Чтение выполняется из локальных ресурсов клиента, без запроса к серверу. Существование предмета в мире не требуется. Для mobile число из GetType означает body; здесь то же число адресует другой раздел ресурсов и не даёт изображение анимации персонажа.
  • Формат результата: несжатый 24-bit BMP. Байты [0]=66 и [1]=77 — BM; [2..5] — размер всего файла; [10..13] — начало пикселей, сейчас 54; [14..17] — размер DIB-заголовка, сейчас 40; [18..21] — ширина; [22..25] — положительная высота; [26..27] — 1 плоскость; [28..29] — 24 бита. Многобайтовые числа записаны little-endian.
  • Каждый пиксель занимает три байта в порядке B, G, R. Строки идут снизу вверх и дополняются нулевыми байтами до кратности 4. Длина строки = Int((width * 3 + 3) / 4) * 4. Для координат x,y от левого верхнего угла смещение = 54 + (height - 1 - y) * stride + x * 3. Перед доступом проверяйте границы и размер массива.
  • Прозрачность исходного арта не сохраняется: BMP здесь не содержит alpha. Прозрачный фон становится чёрным, и отличить его от исходного чёрного пикселя по результату нельзя. Скриншот экрана, масштабирование игрового окна, свет, дальность видимости и координаты предмета не участвуют.
  • На каждый вызов формируется массив изображения. Если арт нужен много раз, сохраните результат в переменную и обрабатывайте его повторно. Не вызывайте загрузку/окрашивание для каждого пикселя внутри цикла. Одинаковые параметры и неизменные файлы дают одинаковый результат; разные hue не обязаны менять каждый пиксель, особенно при PartialHue.
  • Для реального .bmp нужен двоичный вывод точных байтов без текстового кодирования. Обычный File.WriteLine или JsonSave не создаёт BMP. Примеры ниже обрабатывают массив в памяти и не обещают наличие несуществующего File.WriteBytes.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetStaticArt(0x0EED, 0);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Проверить размер иконки перед собственной обработкой — прямой скрипт

Параметры и ход выполнения:

  • ObjType=0x0EED выбирает ресурс, Hue=0 оставляет исходные цвета. Массив проверяется до чтения смещений 18 и 22. 64 — собственный предел примера, не ограничение команды.
  • ArtSizeField — пользовательская функция C#, не команда UO. Складывает четыре байта с весами 1, 256, 65536, 16777216. Скрипт помогает выбрать размер своей ячейки; автоматически гамп не создаёт.
var bmp = UO.GetStaticArt(0x0EED, 0);
if (Truth(ArrayLength(bmp) < 54))
{
    UO.Print("Gold art is unavailable");
    return null;
}
var width = ArtSizeField(bmp, 18);
var height = ArtSizeField(bmp, 22);
if (Truth(width > 64) || Truth(height > 64))
{
    UO.Print("Use a larger cell for this icon");
    return null;
}
UO.Print("Icon fits: " + Convert.ToString(width) + " x " + Convert.ToString(height));

dynamic ArtSizeField(dynamic bytes, dynamic offset)
{
    return bytes[offset] + bytes[offset+1]*256 + bytes[offset+2]*65536 + bytes[offset+3]*16777216;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Вычислить RGB пикселя с учётом перевёрнутых строк BMP — функция сценария

Параметры и ход выполнения:

  • GetStaticArt возвращает BMP; ArtPixelRGB — отдельная функция примера для этого формата. x=0,y=0 означает левый верхний пиксель изображения, а не координаты мира. Замена height-1-y обязательна из-за порядка строк снизу вверх.
  • Функция возвращает RGB int 0..16777215, а -1 использует только как свой признак отсутствия пикселя. Чёрный 0 — действительный цвет, не false и не ошибка. Поэтому проверка if rgb < 0 отделена от if rgb = 0.
return  RunScenario();
 object? RunScenario()
{
    var bmp = UO.GetStaticArt(0x0EED, 0);
    var rgb = ArtPixelRGB(bmp, 0, 0);
    if (Truth(rgb < 0))
    {
        UO.Print("No pixel at this position");
        return null;
    }

    if (Truth(rgb == 0))
    {
        UO.Print("Black pixel: may also be the original transparent background");
    }

    return null;
}

dynamic ArtPixelRGB(dynamic bmp, dynamic x, dynamic y)
{
    if (Truth(ArrayLength(bmp) < 54))
    {
        return -1;
    }

    var width = bmp[18] + bmp[19] * 256 + bmp[20] * 65536 + bmp[21] * 16777216;
    var height = bmp[22] + bmp[23] * 256 + bmp[24] * 65536 + bmp[25] * 16777216;
    if (Truth(x < 0) || Truth(y < 0) || Truth(x >= width) || Truth(y >= height))
    {
        return -1;
    }

    var stride = Math.Floor((width * 3 + 3) / 4) * 4;
    var offset = 54 + (height - 1 - y) * stride + x * 3;
    if (Truth(offset + 2 >= ArrayLength(bmp)))
    {
        return -1;
    }

    return bmp[offset + 2] * 65536 + bmp[offset + 1] * 256 + bmp[offset];
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Сравнить исходную и окрашенную версию одного арта — класс сценария

Параметры и ход выполнения:

  • 0x1F03 — Graphic робы; 0 и 0x0044 — исходный и выбранный hue. Одинаковый Graphic даёт одинаковые размеры. При пустом результате сравнение не начинается.
  • changed считает различающиеся байты цветовых каналов, а не предметы и не число пикселей. Один пиксель может изменить до трёх байтов. PartialHue, таблица цветов и исходные цвета могут оставить часть или всё изображение прежним; это не доказательство ошибки команды.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var original = UO.GetStaticArt(0x1F03, 0);
        var colored = UO.GetStaticArt(0x1F03, 0x0044);
        var size = ArrayLength(original);
        if (Truth(size < 54) || Truth(size != ArrayLength(colored)))
        {
            UO.Print("Cannot compare these art resources");
            return null;
        }

        var changed = 0;
        for (int offset = (int)(54); offset <= size - 1; offset += (int)(1))
        {
            if (Truth(original[offset] != colored[offset]))
            {
                changed = changed + 1;
            }
        }

        if (Truth(changed == 0))
        {
            UO.Print("This hue did not change the exported bytes");
        }
        else
        {
            UO.Print("Changed color bytes: " + Convert.ToString(changed));
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetStaticArt(objType, hue) — UO.GetStaticArt(Any,Any)

Параметры: objType (Any), hue (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getstaticart":

                    return new InjectionValue(bridge.GetStaticArt(ResolveType(arguments[0]), Arg(1)).Select(value => new InjectionValue(value)).ToArray());

UO.GetStaticTileAt

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetStaticTileAt(object? x, object? y, object? index);
dynamic UO.GetStaticTileAt(object? x, object? y, object? map, object? index);

Возвращает расширенную запись одной записи над землёй выбранной клетки.

Параметры

  • x — X клетки текущей загруженной карты; мировая координата, не позиция внутри гампа.
  • y — Y клетки текущей загруженной карты; мировая координата, не позиция внутри гампа.
  • map — Номер карты. Если этот аргумент отсутствует в выбранной форме, используется текущая карта. Реальный клиент читает тайлы только текущей загруженной карты.
  • index — Порядковый номер записи в результатах GetStaticTiles, начиная с 0. Это не graphic, не Z и не слой экипировки. В форме из 3 аргументов index стоит третьим; в форме из 4 аргументов map третий, index четвёртый.

Возвращает

Array из 11 полей одной записи; индексы начинаются с 0:

  • [0] kind — string: "land", "static" либо "object".
  • [1] serial — int: serial динамического предмета; для land/static равен 0.
  • [2] graphic — int: type графики.
  • [3] x, [4] y — int: мировые координаты клетки.
  • [5] z — int: высота основания в мире.
  • [6] hue — int: цвет, у земли 0.
  • [7] flags — int: младшие 32 бита флагов tiledata.
  • [8] name — string: название из tiledata.
  • [9] layer — int: слой экипировки из tiledata, у земли 0; не индекс статики.
  • [10] height — int: высота graphic из tiledata, у земли 0; не координата Z.

Пустой массив [] означает отсутствие записи или недоступную карту/клетку. Для GetStaticTileAt отрицательный/слишком большой index также даёт []; переполнение индекса не выбирает чужую запись.

Поведение

  • Данные относятся к текущей загруженной карте. Другая карта или недоступная клетка дают пустой массив. Прямые запросы тайлов могут дополнительно сообщать о несовпадении карты; GetWorldCell и GetWorldTilesArray сразу возвращают пустой массив без такого сообщения.
  • Индексы массивов начинаются с 0. Перед чтением поля проверяйте ArrayLength. Z означает высоту в мире; layer — свойство экипировки из tiledata, а index — порядковый номер записи клетки.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetStaticTileAt(UO.GetX(), UO.GetY(), 0);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Раздельно прочитать type, Z и слой — прямой скрипт

Параметры и ход выполнения:

  • x/y — положение персонажа; карта опущена и выбирается автоматически. Для GetStaticTileAt index=0 означает первую запись.
  • Поля [2], [5], [9] имеют разный смысл; все читаются только после проверки длины 11.
var tile = UO.GetStaticTileAt(UO.GetX(), UO.GetY(), 0);
if (Truth(ArrayLength(tile) == 11))
{
    UO.Print("Type: " + Convert.ToString(tile[2]));
    UO.Print("World Z: " + Convert.ToString(tile[5]));
    UO.Print("Equipment layer: " + Convert.ToString(tile[9]));
}
else
{
    UO.Print("Tile is unavailable");
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Получить имя и высоту graphic — функция сценария

Параметры и ход выполнения:

  • Используются те же координаты; GetStaticTileAt читает index=0.
  • tile[8] — строка названия, tile[10] — размер по высоте из tiledata, а не Z основания.
return  RunScenario();
 object? RunScenario()
{
    var tile = UO.GetStaticTileAt(UO.GetX(), UO.GetY(), 0);
    if (Truth(ArrayLength(tile) == 11))
    {
        UO.Print(tile[8]);
        UO.Print("Graphic height: " + Convert.ToString(tile[10]));
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Подготовить цель по type и координатам — класс сценария

Параметры и ход выполнения:

  • WaitTargetTile получает graphic, x, y, z из полей 2…5.
  • Это только подготовка следующего target. Пример не запускает применение инструмента или заклинание. serial=0 для статики не следует передавать как ID предмета.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var tile = UO.GetStaticTileAt(UO.GetX(), UO.GetY(), 0);
        if (Truth(ArrayLength(tile) == 11))
        {
            UO.WaitTargetTile(tile[2], tile[3], tile[4], tile[5]);
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetStaticTileAt(x, y, index) — UO.GetStaticTileAt(Any,Any,Any)

Параметры: x (Any), y (Any), index (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetStaticTileAt(InjectionValue x, InjectionValue y, InjectionValue index)

            => GetStaticTileAt(x, y, new InjectionValue(bridge.WorldNumber), index);

UO.GetStaticTileAt(x, y, map, index) — UO.GetStaticTileAt(Any,Any,Any,Any)

Параметры: x (Any), y (Any), map (Any), index (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetStaticTileAt(InjectionValue x, InjectionValue y, InjectionValue map, InjectionValue index)

        {

            int cellX = NumberConversions.ToInt(x);

            int cellY = NumberConversions.ToInt(y);

            int[] statics = bridge.GetStaticTiles(cellX, cellY, NumberConversions.ToInt(map)) ?? Array.Empty<int>();

            int tileIndex = NumberConversions.ToInt(index);

            if (tileIndex < 0 || tileIndex >= statics.Length / 3)

                return new InjectionValue(Array.Empty<InjectionValue>());

            int offset = tileIndex * 3;

            return offset + 2 < statics.Length

                ? BuildWorldTileRecord("static", 0, statics[offset], cellX, cellY, statics[offset + 1], statics[offset + 2], 1)

                : new InjectionValue(Array.Empty<InjectionValue>());

        }

UO.GetStaticTileData

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetStaticTileData(object? tile);

Читает расширенную справочную запись static graphic из tiledata.

Параметры

  • tile — Graphic/type записи, не serial и не индекс внутри клетки. Таблица статики выбрана самим именем команды.

Возвращает

Array из 17 полей для допустимого graphic. Все поля int, кроме name (string):

  • [0] graphic — graphic/type записи.
  • [1] flags — младшие 32 бита флагов.
  • [2] name — название из tiledata (string).
  • [3] weight — вес из tiledata.
  • [4] layer — номер слоя экипировки.
  • [5] count — поле Count из tiledata, не количество предметов в мире.
  • [6] animId — ID анимации.
  • [7] hue — hue из tiledata.
  • [8] lightIndex — индекс источника света.
  • [9] height — высота graphic, не мировая Z.
  • [10] wet — 1 если установлен wet, иначе 0.
  • [11] impassable — 1 если impassable, иначе 0.
  • [12] surface — 1 если surface, иначе 0.
  • [13] foliage — 1 если foliage, иначе 0.
  • [14] door — 1 если door, иначе 0.
  • [15] wall — 1 если wall, иначе 0.
  • [16] container — 1 если container, иначе 0.

Для недопустимого graphic справочные свойства отсутствуют: возвращается короткий массив [переданный graphic, 0, ""]. Проверяйте полную длину перед чтением свойств. Это не Pascal record и не список объектов.

Поведение

  • Команда читает tiledata и не требует предмета с этим graphic в мире. Флаги описывают ресурс; результат не заменяет полноценную проверку маршрута.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetStaticTileData(0x0CCA);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Прочитать имя записи — прямой скрипт

Параметры и ход выполнения:

  • Tile — числовой graphic выбранной таблицы.
  • data[2] содержит имя. Проверка длины отделяет полноценную запись от короткой записи недопустимого graphic.
var data = UO.GetStaticTileData(0x0CCA);
if (Truth(ArrayLength(data) == 17))
{
    UO.Print(data[2]);
}
else
{
    UO.Print("Tiledata entry is unavailable");
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Проверить отдельный логический флаг — функция сценария

Параметры и ход выполнения:

  • data[11] — отдельное поле impassable: 1 (условие выполнено), 0 (условие не выполнено).
  • Эта проверка не учитывает другие объекты в клетке или способности персонажа.
return  RunScenario();
 object? RunScenario()
{
    var data = UO.GetStaticTileData(0x0CCA);
    if (Truth(ArrayLength(data) == 17))
    {
        if (Truth(data[11]))
        {
            UO.Print("Impassable flag is set");
        }
        else
        {
            UO.Print("Impassable flag is not set");
        }
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Вывести graphic и общую маску флагов — класс сценария

Параметры и ход выполнения:

  • data[0] повторяет переданный graphic, data[1] — общая маска флагов.
  • Маска может содержать одновременно несколько битов; её численное значение не является serial.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var data = UO.GetStaticTileData(0x0CCA);
        if (Truth(ArrayLength(data) == 17))
        {
            UO.Print("Graphic: " + Convert.ToString(data[0]));
            UO.Print("Flags: " + Convert.ToString(data[1]));
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetStaticTileData(tile) — UO.GetStaticTileData(Any)

Параметры: tile (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getstatictiledata":

                    return BuildTileData(1, Arg(0));

UO.GetStaticTiles

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetStaticTiles(object? x, object? y, object? map);

Читает записи над землёй в одной клетке текущей карты.

Параметры

  • x — X клетки текущей загруженной карты; мировая координата, не позиция внутри гампа.
  • y — Y клетки текущей загруженной карты; мировая координата, не позиция внутри гампа.
  • map — Номер карты. Если этот аргумент отсутствует в выбранной форме, используется текущая карта. Реальный клиент читает тайлы только текущей загруженной карты.

Возвращает

Array — плоская последовательность int-троек [graphic0, z0, hue0, graphic1, z1, hue1, …]. Число записей равно длине массива / 3. Для записи i graphic находится в [i*3], Z в [i*3+1], hue в [i*3+2]. Пустой массив означает отсутствие записей или недоступную карту/клетку. Serial и номер слоя здесь не возвращаются.

Поведение

  • Данные относятся к текущей загруженной карте. Другая карта или недоступная клетка дают пустой массив. Прямые запросы тайлов могут дополнительно сообщать о несовпадении карты; GetWorldCell и GetWorldTilesArray сразу возвращают пустой массив без такого сообщения.
  • Индексы массивов начинаются с 0. Перед чтением поля проверяйте ArrayLength. Z означает высоту в мире; layer — свойство экипировки из tiledata, а index — порядковый номер записи клетки.
  • В текущем bridge перечисляются Static, Multi и мировые Item в цепочке клетки. Название команды не ограничивает результат исключительно записями statics.mul. Порядок цепочки не гарантирует сортировку по Z.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetStaticTiles(UO.GetX(), UO.GetY(), UO.WorldNum());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Посчитать записи клетки — прямой скрипт

Параметры и ход выполнения:

  • x/y/map выбирают текущую клетку.
  • Длина массива — число полей. Деление на 3 даёт число записей.
var tiles = UO.GetStaticTiles(UO.GetX(), UO.GetY(), UO.WorldNum());
var count = ArrayLength(tiles) / 3;
UO.Print("Tile records: " + Convert.ToString(count));

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

2. Перебрать graphic и высоту всех записей — функция сценария

Параметры и ход выполнения:

  • offset — индекс первого поля очередной тройки, увеличивается на 3.
  • Проверка offset+2 защищает чтение всей записи.
return  RunScenario();
 object? RunScenario()
{
    var tiles = UO.GetStaticTiles(UO.GetX(), UO.GetY(), UO.WorldNum());
    var offset = 0;
    while (Truth(offset + 2 < ArrayLength(tiles)))
    {
        UO.Print("Type: " + Convert.ToString(tiles[offset]) + ", Z: " + Convert.ToString(tiles[offset + 1]));
        offset = offset + 3;
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Прочитать hue первой записи — класс сценария

Параметры и ход выполнения:

  • x+1 выбирает соседнюю клетку.
  • tiles[2] — цвет первой записи; это не третий тайл.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var tiles = UO.GetStaticTiles(UO.GetX() + 1, UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(tiles) >= 3))
        {
            var hue = tiles[2];
            UO.Print("First tile hue: " + Convert.ToString(hue));
        }
        else
        {
            UO.Print("No tile records");
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetStaticTiles(x, y, map) — UO.GetStaticTiles(Any,Any,Any)

Параметры: x (Any), y (Any), map (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetStaticTiles(InjectionValue x, InjectionValue y, InjectionValue map)

            => ToArray(bridge.GetStaticTiles(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map)));

UO.GetStaticTilesArray

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetStaticTilesArray(object? xmin, object? ymin, object? xmax, object? ymax, object? worldNum, object? tileType);

Ищет записи Static/Multi/Item по graphic/type в прямоугольнике.

Параметры

  • xmin — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • ymin — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • xmax — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • ymax — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • worldNum — Карта/фасет 0..255; используйте UO.WorldNum(). Другая карта даёт пустой Array. Если карта меняется между порциями, частичный результат отбрасывается.
  • tileType — Один graphic/type тайла, обычно 0..65535; это не serial. 0 — точный graphic 0, -1 не означает любой type. Несовпадающий type даёт пустой результат.

Возвращает

Array записей [graphic, X, Y, Z, hue]; все поля int. graphic — type, Z — основание, hue — цвет. Несколько записей клетки остаются отдельными. Нет совпадений: пустой Array. Количество — ArrayLength(result), не сам результат. Индексы начинаются с 0. Это не bool, serial или Pascal record; седьмого выходного параметра нет.

Поведение

  • Читаются локальные данные. Поиск не меняет FindItem/FindCount и не выполняет движение, target или сетевую команду.
  • Порядок: X по возрастанию, внутри X — Y по возрастанию. Записи одной клетки сохраняют порядок bridge; это не сортировка по расстоянию или высоте.
  • Поиск обрабатывается порциями до 32 клеток с мягким бюджетом около 1 мс. Отмена проверяется между порциями. Сложная клетка или холодное чтение могут превысить бюджет. Большую область лучше делить; мир может меняться во время чтения.
  • Static-ветка текущего клиента включает Static, Multi и Item из клетки, включая загруженные предметы на земле; Land и Mobile не включаются. Она шире классической выборки только статик из файлов.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetStaticTilesArray(UO.GetX(), UO.GetY(), UO.GetX() + 2, UO.GetY() + 2, UO.WorldNum(), 0x0CCA);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Поиск рядом с персонажем — прямой скрипт

Параметры и ход выполнения:

  • x/y — позиция self, map — текущая карта. Область 3×3 включает границы. В Ex передаются два type, в обычной форме один. Измените образцы под свои ресурсы; это graphic, не ID объекта.
var x = UO.GetX();
var y = UO.GetY();
var map = UO.WorldNum();
var rows = UO.GetStaticTilesArray(x, y, x + 2, y + 2, map, 0x0CCA);
UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

2. Переставленные углы и вывод всех полей — функция сценария

Параметры и ход выполнения:

  • Область 2×2 передана от большего угла к меньшему. Алгоритм сам нормализует границы. row — одна запись; PrintTile объявлена целиком и только форматирует числа, ничего не перемещая. graphic — type, x/y — координаты, z — высота, hue — цвет. Для земли передан условный hue=0: в записи земли нет поля цвета.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX();
    var y = UO.GetY();
    var map = UO.WorldNum();
    var rows = UO.GetStaticTilesArray(x + 1, y + 1, x, y, map, 0x0CCA);
    var i = 0;
    while (Truth(i < ArrayLength(rows)))
    {
        var row = rows[i];
        PrintTile(row[0], row[1], row[2], row[3], row[4]);
        i = i + 1;
    }

    return null;
}

void PrintTile(dynamic graphic, dynamic x, dynamic y, dynamic z, dynamic hue)
{
    UO.Print("Type=" + Convert.ToString(graphic) + " X=" + Convert.ToString(x) + " Y=" + Convert.ToString(y));
    UO.Print("Z=" + Convert.ToString(z) + " hue=" + Convert.ToString(hue));
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Повторный опрос с ограничением попыток — класс сценария

Параметры и ход выполнения:

  • Не более трёх поисков одной клетки; между попытками WaitAsync(250). Каждый вызов создаёт новый результат. Нулевая длина означает отсутствие совпадений сейчас, а не постоянное отсутствие объекта на сервере.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var attempt = 0;
        while (Truth(attempt < 3))
        {
            var rows = UO.GetStaticTilesArray(x, y, x, y, map, 0x0CCA);
            UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));
            attempt = attempt + 1;
            await Delay(250);
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetStaticTilesArray(xmin, ymin, xmax, ymax, worldNum, tileType) — UO.GetStaticTilesArray(Any,Any,Any,Any,Any,Any)

Параметры: xmin (Any), ymin (Any), xmax (Any), ymax (Any), worldNum (Any), tileType (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getstatictilesarray":

                    return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), new[] { Arg(5) }, true);

UO.GetStaticTilesArrayEx

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetStaticTilesArrayEx(object? xmin, object? ymin, object? xmax, object? ymax, object? worldNum, object? tileTypes);

Ищет записи Static/Multi/Item по graphic/type в прямоугольнике.

Параметры

  • xmin — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • ymin — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • xmax — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • ymax — Мировые координаты двух углов, включительно; 0..65535. Переставленные углы нормализуются. Область не более 1 000 000 клеток; недопустимые границы вызывают ошибку скрипта до чтения карты.
  • worldNum — Карта/фасет 0..255; используйте UO.WorldNum(). Другая карта даёт пустой Array. Если карта меняется между порциями, частичный результат отбрасывается.
  • tileTypes — Array числовых graphic/type; каждый совпадающий type включается. Повторение type не дублирует записи. Скаляр также принимается как один type. Пустой Array означает все type; массив из одного 0 ищет только 0.

Возвращает

Array записей [graphic, X, Y, Z, hue]; все поля int. graphic — type, Z — основание, hue — цвет. Несколько записей клетки остаются отдельными. Нет совпадений: пустой Array. Количество — ArrayLength(result), не сам результат. Индексы начинаются с 0. Это не bool, serial или Pascal record; седьмого выходного параметра нет.

Поведение

  • Читаются локальные данные. Поиск не меняет FindItem/FindCount и не выполняет движение, target или сетевую команду.
  • Порядок: X по возрастанию, внутри X — Y по возрастанию. Записи одной клетки сохраняют порядок bridge; это не сортировка по расстоянию или высоте.
  • Поиск обрабатывается порциями до 32 клеток с мягким бюджетом около 1 мс. Отмена проверяется между порциями. Сложная клетка или холодное чтение могут превысить бюджет. Большую область лучше делить; мир может меняться во время чтения.
  • Static-ветка текущего клиента включает Static, Multi и Item из клетки, включая загруженные предметы на земле; Land и Mobile не включаются. Она шире классической выборки только статик из файлов.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetStaticTilesArrayEx(UO.X(), UO.Y(), UO.X() + 1, UO.Y() + 1, UO.WorldNum(), new[] { 0x0CCA });
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Поиск рядом с персонажем — прямой скрипт

Параметры и ход выполнения:

  • x/y — позиция self, map — текущая карта. Область 3×3 включает границы. В Ex передаются два type, в обычной форме один. Измените образцы под свои ресурсы; это graphic, не ID объекта.
dynamic[] types = new dynamic[checked((int)(1) + 1)];
types[0] = 0x0CCA;
types[1] = 0x0CCB;
var x = UO.GetX();
var y = UO.GetY();
var map = UO.WorldNum();
var rows = UO.GetStaticTilesArrayEx(x, y, x + 2, y + 2, map, types);
UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

2. Переставленные углы и вывод всех полей — функция сценария

Параметры и ход выполнения:

  • Область 2×2 передана от большего угла к меньшему. Алгоритм сам нормализует границы. row — одна запись; PrintTile объявлена целиком и только форматирует числа, ничего не перемещая. graphic — type, x/y — координаты, z — высота, hue — цвет. Для земли передан условный hue=0: в записи земли нет поля цвета.
return  RunScenario();
 object? RunScenario()
{
    dynamic[] types = new dynamic[checked((int)(1) + 1)];
    types[0] = 0x0CCA;
    types[1] = 0x0CCB;
    var x = UO.GetX();
    var y = UO.GetY();
    var map = UO.WorldNum();
    var rows = UO.GetStaticTilesArrayEx(x + 1, y + 1, x, y, map, types);
    var i = 0;
    while (Truth(i < ArrayLength(rows)))
    {
        var row = rows[i];
        PrintTile(row[0], row[1], row[2], row[3], row[4]);
        i = i + 1;
    }

    return null;
}

void PrintTile(dynamic graphic, dynamic x, dynamic y, dynamic z, dynamic hue)
{
    UO.Print("Type=" + Convert.ToString(graphic) + " X=" + Convert.ToString(x) + " Y=" + Convert.ToString(y));
    UO.Print("Z=" + Convert.ToString(z) + " hue=" + Convert.ToString(hue));
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Повторный опрос с ограничением попыток — класс сценария

Параметры и ход выполнения:

  • Не более трёх поисков одной клетки; между попытками WaitAsync(250). Каждый вызов создаёт новый результат. Нулевая длина означает отсутствие совпадений сейчас, а не постоянное отсутствие объекта на сервере.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        dynamic[] types = new dynamic[checked((int)(1) + 1)];
        types[0] = 0x0CCA;
        types[1] = 0x0CCB;
        var x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var attempt = 0;
        while (Truth(attempt < 3))
        {
            var rows = UO.GetStaticTilesArrayEx(x, y, x, y, map, types);
            UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));
            attempt = attempt + 1;
            await Delay(250);
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetStaticTilesArrayEx(xmin, ymin, xmax, ymax, worldNum, tileTypes) — UO.GetStaticTilesArrayEx(Any,Any,Any,Any,Any,Any)

Параметры: xmin (Any), ymin (Any), xmax (Any), ymax (Any), worldNum (Any), tileTypes (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getstatictilesarrayex":

                    return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), ArrayArg(5), true);

UO.GetSurfaceZ

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetSurfaceZ(object? x, object? y, object? worldNum);

Читает среднюю высоту поверхности земли в клетке.

Параметры

  • x — Мировая координата X клетки текущей карты, не положение в гампе.
  • y — Мировая координата Y клетки текущей карты.
  • worldNum — Номер карты/фасета; используйте UO.WorldNum(). Читается только текущая загруженная карта.

Возвращает

int — Land.AverageZ, в том числе отрицательная высота и 0. При отсутствии карты/земли либо несовпадении карты возвращается 0, поэтому это значение не отличает отсутствие данных от настоящей высоты 0. Это не bool, этаж или высота ближайшей статики.

Поведение

  • Команда читает локальную карту и не запускает движение или target. Клетка за пределами размеров карты не подменяется клеткой соседнего столбца.
  • Высота Z, graphic/type, цвет hue, флаги и слой экипировки имеют разный смысл. Нулевой graphic или Z=0 могут быть допустимыми данными; проверяйте форму результата.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetSurfaceZ(UO.GetX(), UO.GetY(), UO.WorldNum());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Средняя высота под персонажем — прямой скрипт

Параметры и ход выполнения:

  • Все три параметра относятся к текущей клетке карты. z — числовая высота, не результат движения.
var x = UO.GetX();
var y = UO.GetY();
var map = UO.WorldNum();
var z = UO.GetSurfaceZ(x, y, map);
UO.Print("Average land Z: " + Convert.ToString(z));

2. Проверить доступность земли до чтения — функция сценария

Параметры и ход выполнения:

  • GetMapCell нужен, чтобы отличить отсутствующие данные от высоты 0. Между двумя вызовами карта всё равно может измениться.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX() + 1;
    var y = UO.GetY();
    var map = UO.WorldNum();
    var cell = UO.GetMapCell(x, y, map);
    if (Truth(ArrayLength(cell) == 3))
    {
        UO.Print("Average: " + Convert.ToString(UO.GetSurfaceZ(x, y, map)));
    }
    else
    {
        UO.Print("No land data");
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Показать изменение средней высоты к востоку — класс сценария

Параметры и ход выполнения:

  • Разность показывает наклон земли. Этот пример ничего не перемещает и не считает маршрут.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var a = UO.GetMapCell(x, y, map);
        var b = UO.GetMapCell(x + 1, y, map);
        if (Truth(ArrayLength(a) == 3) && Truth(ArrayLength(b) == 3))
        {
            var difference = UO.GetSurfaceZ(x + 1, y, map) - UO.GetSurfaceZ(x, y, map);
            UO.Print("Average difference: " + Convert.ToString(difference));
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetSurfaceZ(x, y, worldNum) — UO.GetSurfaceZ(Any,Any,Any)

Параметры: x (Any), y (Any), worldNum (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getsurfacez":

                    return new InjectionValue(bridge.GetSurfaceZ(Arg(0), Arg(1), Arg(2)));

UO.GetTileFlags

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetTileFlags(object? group, object? tileId);

Читает битовую маску свойств graphic из записи tiledata.

Параметры

  • group — 0 — таблица земли (land); 1 — таблица статических graphic. Реализация считает любое ненулевое group второй таблицей; используйте 0 или 1.
  • tileId — Graphic/type записи в tiledata, обычно целое 0…65535. Это не serial предмета и не индекс статики внутри клетки.

Возвращает

int — младшие 32 бита флагов tiledata. Установленный старший бит даёт отрицательное знаковое число. 0 означает отсутствие этих флагов либо недопустимый tileId; это не самостоятельный признак ошибки и не bool. Несколько свойств могут быть установлены одновременно.

Поведение

  • Эта команда читает справочную запись graphic; координаты мира не нужны. group=0 и group=1 выбирают разные таблицы даже при одинаковом tileId.
  • Свойство читается из данных graphic, а не из текущего состояния конкретного предмета.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetTileFlags(1, 0x0CCA);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Прочитать свойство известного static graphic — прямой скрипт

Параметры и ход выполнения:

  • group=1 выбирает static tiledata; tileId=0x0CCA — graphic дерева.
  • value содержит результат, описанный в разделе «Возвращает»; его смысл не совпадает с serial.
var value = UO.GetTileFlags(1, 0x0CCA);
if (Truth((Convert.ToUInt64(value) & 0x40UL) != 0))
{
    UO.Print("Impassable flag is set");
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Прочитать свойство graphic найденного предмета — функция сценария

Параметры и ход выполнения:

  • FindType возвращает serial. GetType превращает его в числовой graphic.
  • group=1 используется для предметов; в tileId передаётся graphic, не item.
return  RunScenario();
 object? RunScenario()
{
    var item = UO.FindType(0x0EED, -1, "backpack");
    if (Truth(item != ""))
    {
        var graphic = UO.GetType(item);
        var value = UO.GetTileFlags(1, graphic);
        UO.Print(Convert.ToString(value));
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Прочитать свойство земли под персонажем — класс сценария

Параметры и ход выполнения:

  • Первые два аргумента GetLandscapeTile — текущие мировые X/Y; третий — текущая карта.
  • land[0] содержит graphic земли. group=0 выбирает land tiledata. Для GetTileLayer/GetTileHeight земля даёт 0.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(land) >= 3))
        {
            var graphic = land[0];
            var value = UO.GetTileFlags(0, graphic);
            UO.Print(Convert.ToString(value));
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetTileFlags(group, tileId) — UO.GetTileFlags(Any,Any)

Параметры: group (Any), tileId (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetTileFlags(InjectionValue group, InjectionValue tileId)

            => new InjectionValue(unchecked((int)bridge.GetTileFlags(NumberConversions.ToInt(group), NumberConversions.ToInt(tileId))));

UO.GetTileHeight

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

int UO.GetTileHeight(object? group, object? tileId);

Читает высоту graphic из записи tiledata.

Параметры

  • group — 0 — таблица земли (land); 1 — таблица статических graphic. Реализация считает любое ненулевое group второй таблицей; используйте 0 или 1.
  • tileId — Graphic/type записи в tiledata, обычно целое 0…65535. Это не serial предмета и не индекс статики внутри клетки.

Возвращает

int — высота графики в единицах Z из tiledata. Это размер графики по высоте, а не мировая координата её основания Z. Для земли, отсутствующей записи или нулевой высоты возвращается 0. Высота сама по себе не доказывает проходимость.

Поведение

  • Эта команда читает справочную запись graphic; координаты мира не нужны. group=0 и group=1 выбирают разные таблицы даже при одинаковом tileId.
  • Свойство читается из данных graphic, а не из текущего состояния конкретного предмета.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

var result = UO.GetTileHeight(1, 0x0CCA);
UO.Print("GetTileHeight: " + Convert.ToString(result));

1. Прочитать свойство известного static graphic — прямой скрипт

Параметры и ход выполнения:

  • group=1 выбирает static tiledata; tileId=0x0CCA — graphic дерева.
  • value содержит результат, описанный в разделе «Возвращает»; его смысл не совпадает с serial.
var value = UO.GetTileHeight(1, 0x0CCA);
UO.Print("Tiledata height: " + Convert.ToString(value));

2. Прочитать свойство graphic найденного предмета — функция сценария

Параметры и ход выполнения:

  • FindType возвращает serial. GetType превращает его в числовой graphic.
  • group=1 используется для предметов; в tileId передаётся graphic, не item.
return  RunScenario();
 object? RunScenario()
{
    var item = UO.FindType(0x0EED, -1, "backpack");
    if (Truth(item != ""))
    {
        var graphic = UO.GetType(item);
        var value = UO.GetTileHeight(1, graphic);
        UO.Print(Convert.ToString(value));
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Прочитать свойство земли под персонажем — класс сценария

Параметры и ход выполнения:

  • Первые два аргумента GetLandscapeTile — текущие мировые X/Y; третий — текущая карта.
  • land[0] содержит graphic земли. group=0 выбирает land tiledata. Для GetTileLayer/GetTileHeight земля даёт 0.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(land) >= 3))
        {
            var graphic = land[0];
            var value = UO.GetTileHeight(0, graphic);
            UO.Print(Convert.ToString(value));
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetTileHeight(group, tileId) — UO.GetTileHeight(Any,Any)

Параметры: group (Any), tileId (Any)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetTileHeight(InjectionValue group, InjectionValue tileId)

        {

            int tileGroup = NumberConversions.ToInt(group);

            int[] properties = bridge.GetTileDataProperties(tileGroup, NumberConversions.ToInt(tileId)) ?? Array.Empty<int>();

            return tileGroup == 0 || properties.Length < 7 ? 0 : properties[6];

        }

UO.GetTileLayer

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

int UO.GetTileLayer(object? group, object? tileId);

Читает номер слоя экипировки из записи tiledata.

Параметры

  • group — 0 — таблица земли (land); 1 — таблица статических graphic. Реализация считает любое ненулевое group второй таблицей; используйте 0 или 1.
  • tileId — Graphic/type записи в tiledata, обычно целое 0…65535. Это не serial предмета и не индекс статики внутри клетки.

Возвращает

int — номер слоя экипировки graphic: например 1=Rhand, 2=Lhand, 21=Backpack. Для земли, отсутствующей записи или нулевого слоя возвращается 0. Это не порядок статики в клетке, не этаж и не Z.

Поведение

  • Эта команда читает справочную запись graphic; координаты мира не нужны. group=0 и group=1 выбирают разные таблицы даже при одинаковом tileId.
  • Свойство читается из данных graphic, а не из текущего состояния конкретного предмета.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

var result = UO.GetTileLayer(1, 0x0CCA);
UO.Print("GetTileLayer: " + Convert.ToString(result));

1. Прочитать свойство известного static graphic — прямой скрипт

Параметры и ход выполнения:

  • group=1 выбирает static tiledata; tileId=0x0CCA — graphic дерева.
  • value содержит результат, описанный в разделе «Возвращает»; его смысл не совпадает с serial.
var value = UO.GetTileLayer(1, 0x0CCA);
if (Truth(value == 1))
{
    UO.Print("Right-hand graphic");
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Прочитать свойство graphic найденного предмета — функция сценария

Параметры и ход выполнения:

  • FindType возвращает serial. GetType превращает его в числовой graphic.
  • group=1 используется для предметов; в tileId передаётся graphic, не item.
return  RunScenario();
 object? RunScenario()
{
    var item = UO.FindType(0x0EED, -1, "backpack");
    if (Truth(item != ""))
    {
        var graphic = UO.GetType(item);
        var value = UO.GetTileLayer(1, graphic);
        UO.Print(Convert.ToString(value));
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Прочитать свойство земли под персонажем — класс сценария

Параметры и ход выполнения:

  • Первые два аргумента GetLandscapeTile — текущие мировые X/Y; третий — текущая карта.
  • land[0] содержит graphic земли. group=0 выбирает land tiledata. Для GetTileLayer/GetTileHeight земля даёт 0.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(land) >= 3))
        {
            var graphic = land[0];
            var value = UO.GetTileLayer(0, graphic);
            UO.Print(Convert.ToString(value));
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetTileLayer(group, tileId) — UO.GetTileLayer(Any,Any)

Параметры: group (Any), tileId (Any)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetTileLayer(InjectionValue group, InjectionValue tileId)

        {

            int tileGroup = NumberConversions.ToInt(group);

            int[] properties = bridge.GetTileDataProperties(tileGroup, NumberConversions.ToInt(tileId)) ?? Array.Empty<int>();

            return tileGroup == 0 || properties.Length < 2 ? 0 : properties[1];

        }

UO.GetTileName

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

string UO.GetTileName(object? group, object? tileId);

Читает название graphic из записи tiledata.

Параметры

  • group — 0 — таблица земли (land); 1 — таблица статических graphic. Реализация считает любое ненулевое group второй таблицей; используйте 0 или 1.
  • tileId — Graphic/type записи в tiledata, обычно целое 0…65535. Это не serial предмета и не индекс статики внутри клетки.

Возвращает

string — название из игровых файлов tiledata. Пустая строка означает пустое имя или недопустимый tileId. Название берётся из ресурсов игры и не переводится автоматически на язык интерфейса IDE. Это не имя конкретного предмета от сервера.

Поведение

  • Эта команда читает справочную запись graphic; координаты мира не нужны. group=0 и group=1 выбирают разные таблицы даже при одинаковом tileId.
  • Свойство читается из данных graphic, а не из текущего состояния конкретного предмета.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

var result = UO.GetTileName(1, 0x0CCA);
UO.Print("GetTileName: " + Convert.ToString(result));

1. Прочитать свойство известного static graphic — прямой скрипт

Параметры и ход выполнения:

  • group=1 выбирает static tiledata; tileId=0x0CCA — graphic дерева.
  • value содержит результат, описанный в разделе «Возвращает»; его смысл не совпадает с serial.
var value = UO.GetTileName(1, 0x0CCA);
if (Truth(value != ""))
{
    UO.Print(value);
}
else
{
    UO.Print("No tiledata name");
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Прочитать свойство graphic найденного предмета — функция сценария

Параметры и ход выполнения:

  • FindType возвращает serial. GetType превращает его в числовой graphic.
  • group=1 используется для предметов; в tileId передаётся graphic, не item.
return  RunScenario();
 object? RunScenario()
{
    var item = UO.FindType(0x0EED, -1, "backpack");
    if (Truth(item != ""))
    {
        var graphic = UO.GetType(item);
        var value = UO.GetTileName(1, graphic);
        UO.Print(Convert.ToString(value));
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Прочитать свойство земли под персонажем — класс сценария

Параметры и ход выполнения:

  • Первые два аргумента GetLandscapeTile — текущие мировые X/Y; третий — текущая карта.
  • land[0] содержит graphic земли. group=0 выбирает land tiledata. Для GetTileLayer/GetTileHeight земля даёт 0.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(land) >= 3))
        {
            var graphic = land[0];
            var value = UO.GetTileName(0, graphic);
            UO.Print(Convert.ToString(value));
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetTileName(group, tileId) — UO.GetTileName(Any,Any)

Параметры: group (Any), tileId (Any)

Результат: string / String.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public string GetTileName(InjectionValue group, InjectionValue tileId)

            => bridge.GetTileDataName(NumberConversions.ToInt(group), NumberConversions.ToInt(tileId));

UO.GetTileXYM

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetTileXYM(object? x, object? y, object? map, object? tileStart, object? tileEnd, object? uoPath);

Читает совпавшие graphic ID из цепочки объектов клетки текущей загруженной игровой карты.

Параметры

  • x — Координата X клетки, int.
  • y — Координата Y клетки, int.
  • map — Номер карты; должен совпадать с World.MapIndex, и World.Map должен существовать.
  • tileStart — Нижняя включённая граница Graphic.
  • tileEnd — Верхняя включённая граница Graphic. Обратный диапазон не переставляется и не даёт совпадений.
  • uoPath — Параметр совместимости преобразуется в string, но текущий bridge его не использует и не загружает другую папку файлов UO.

Возвращает

Array int с плоскими четвёрками [graphic,x,y,z,graphic,x,y,z,...]. Ошибка карты даёт пустой массив и сообщение; отсутствие совпадений также даёт пустой массив.

Поведение

  • Идёт по World.Map.GetTile(x,y).TNext и проверяет tileStart<=Graphic<=tileEnd. Типы объектов отдельно не фильтруются: это цепочка клетки, а не только statics.
  • Команда читает клиентскую загруженную геометрию. Данные с другого map/facet не загружаются. Параметр uoPath не используется для загрузки файлов; число записей равно длине массива/4.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetTileXYM(UO.GetX(), UO.GetY(), UO.WorldNum(), 0, 65535, "");
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Все графики текущей клетки — прямой скрипт

Параметры и ход выполнения:

  • Каждая запись занимает четыре int.
var tiles = UO.GetTileXYM(UO.GetX(),UO.GetY(),UO.WorldNum(),0,65535,"");
UO.Print(Convert.ToString(ArrayLength(tiles)/4));

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

2. Печатать graphic и высоту — функция сценария

Параметры и ход выполнения:

  • Индексы i и i+3 соответствуют graphic и z одной записи.
return  RunScenario();
 object? RunScenario()
{
    var tiles = UO.GetTileXYM(UO.GetX(), UO.GetY(), UO.WorldNum(), 0, 65535, "");
    for (int i = (int)(0); i <= ArrayLength(tiles) - 1; i += (int)(4))
    {
        UO.Print(Convert.ToString(tiles[i]) + " " + Convert.ToString(tiles[i + 3]));
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

3. Обратный диапазон — класс сценария

Параметры и ход выполнения:

  • Диапазон 100..99 не содержит ни одного graphic и даёт пустой массив.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var tiles = UO.GetTileXYM(UO.GetX(), UO.GetY(), UO.WorldNum(), 100, 99, "");
        UO.Print(Convert.ToString(ArrayLength(tiles)));
        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetTileXYM(x, y, map, tileStart, tileEnd, uoPath) — UO.GetTileXYM(Any,Any,Any,Any,Any,Any)

Параметры: x (Any), y (Any), map (Any), tileStart (Any), tileEnd (Any), uoPath (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetTileXYM(InjectionValue x, InjectionValue y, InjectionValue map, InjectionValue tileStart, InjectionValue tileEnd, InjectionValue uoPath)

            => ToArray(bridge.GetTileXYM(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map), NumberConversions.ToInt(tileStart), NumberConversions.ToInt(tileEnd), uoPath.ToString()));

UO.GetUserStatic

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

string UO.GetUserStatic(object? id);

Читает сохранённую пользовательскую static-запись.

Параметры

  • id — int ID, полученный AddUserStatic; не graphic/type и не serial мира.

Возвращает

string — сохранённая сериализованная запись; неизвестный ID даёт пустую строку.

Поведение

  • state.UserStatics.TryGetValue возвращает строку без её разбора. Геометрическая запись — "graphic|x|y|z|hue|map"; старые текстовые записи могут быть другим текстом.
  • Читает текущее локальное состояние. Пакета, target и автоматического обновления нет; отдельные чтения могут видеть разные состояния.
  • В обычном клиентском host эти данные состояния берутся из GetPersistentState менеджера и общие для скриптов/чата/макросов одного мира/профиля, а не принадлежат одному скрипту. Другой процесс или явно отдельный InjectionRuntimeState имеет другое состояние. Загрузка/очистка профиля может его заменить; сохранённые serial всё равно проверяются по загруженному миру.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

var result = UO.GetUserStatic(1);
UO.Print("GetUserStatic: " + Convert.ToString(result));

1. Прямой вызов — прямой скрипт

Параметры и ход выполнения:

  • Читает сохранённую пользовательскую static-запись.
UO.Print(UO.GetUserStatic(1));

2. Явный вариант — функция сценария

Параметры и ход выполнения:

  • state.UserStatics.TryGetValue возвращает строку без её разбора. Геометрическая запись — "graphic|x|y|z|hue|map"; старые текстовые записи могут быть другим текстом.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.UserStaticExists(1)))
    {
        UO.Print(UO.GetUserStatic(1));
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Полная вспомогательная функция — класс сценария

Параметры и ход выполнения:

  • Читает текущее локальное состояние. Пакета, target и автоматического обновления нет; отдельные чтения могут видеть разные состояния.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var records = UO.GetUserStatics();
        if (Truth(UO.GetArrayLength(records) > 0))
        {
            UO.Print(UO.GetUserStatic(records[0][0]));
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetUserStatic(id) — UO.GetUserStatic(Any)

Параметры: id (Any)

Результат: string / String.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public string GetUserStatic(InjectionValue id)

            => state.UserStatics.TryGetValue(NumberConversions.ToInt(id), out string value) ? value : string.Empty;

UO.GetUserStatics

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetUserStatics();

Читает state.UserStatics.

Параметры

Параметров нет.

Возвращает

Array строк [id, serializedText], отсортированных по id. Каждый id — int, serializedText — string; пустой словарь даёт пустой массив.

Поведение

  • Читает state.UserStatics. Геометрическая запись хранится как "graphic|x|y|z|hue|map"; старые текстовые записи AddUserStatic могут иметь другой формат. Это локальные пользовательские записи, не все статики карты.
  • Читает текущее локальное состояние. Пакета, target и автоматического обновления нет; отдельные чтения могут видеть разные состояния.
  • В обычном клиентском host эти данные состояния берутся из GetPersistentState менеджера и общие для скриптов/чата/макросов одного мира/профиля, а не принадлежат одному скрипту. Другой процесс или явно отдельный InjectionRuntimeState имеет другое состояние. Загрузка/очистка профиля может его заменить; сохранённые serial всё равно проверяются по загруженному миру.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetUserStatics();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Прямой вызов — прямой скрипт

Параметры и ход выполнения:

  • Читает state.UserStatics.
var records = UO.GetUserStatics();
UO.Print(UO.GetArrayLength(records));

2. Явный вариант — функция сценария

Параметры и ход выполнения:

  • Читает state.UserStatics. Геометрическая запись хранится как "graphic|x|y|z|hue|map"; старые текстовые записи AddUserStatic могут иметь другой формат. Это локальные пользовательские записи, не все статики карты.
return  RunScenario();
 object? RunScenario()
{
    var records = UO.GetUserStatics();
    if (Truth(UO.GetArrayLength(records) > 0))
    {
        UO.Print(records[0][0]);
        UO.Print(records[0][1]);
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Полная вспомогательная функция — класс сценария

Параметры и ход выполнения:

  • Читает текущее локальное состояние. Пакета, target и автоматического обновления нет; отдельные чтения могут видеть разные состояния.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var before = UO.GetUserStatics();
        UO.Wait(500);
        var after = UO.GetUserStatics();
        UO.Print(before);
        UO.Print(after);
        return null;
    }
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetUserStatics() — UO.GetUserStatics()

Параметры: Параметров нет.

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetUserStatics()

            => new InjectionValue(state.UserStatics.OrderBy(pair => pair.Key)

                .Select(pair => new InjectionValue(new[] { new InjectionValue(pair.Key), new InjectionValue(pair.Value) }))

                .ToArray());

UO.GetWorldCell

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetWorldCell(object? x, object? y);
dynamic UO.GetWorldCell(object? x, object? y, object? map);

Читает расширенные записи земли, записей над землёй и загруженных мировых предметов в выбранной области.

Параметры

  • x — X клетки текущей загруженной карты; мировая координата, не позиция внутри гампа.
  • y — Y клетки текущей загруженной карты; мировая координата, не позиция внутри гампа.
  • map — Номер карты. Если этот аргумент отсутствует в выбранной форме, используется текущая карта. Реальный клиент читает тайлы только текущей загруженной карты.

Возвращает

Array записей. Каждый элемент result[i] имеет следующий формат:

Array из 11 полей одной записи; индексы начинаются с 0:

  • [0] kind — string: "land", "static" либо "object".
  • [1] serial — int: serial динамического предмета; для land/static равен 0.
  • [2] graphic — int: type графики.
  • [3] x, [4] y — int: мировые координаты клетки.
  • [5] z — int: высота основания в мире.
  • [6] hue — int: цвет, у земли 0.
  • [7] flags — int: младшие 32 бита флагов tiledata.
  • [8] name — string: название из tiledata.
  • [9] layer — int: слой экипировки из tiledata, у земли 0; не индекс статики.
  • [10] height — int: высота graphic из tiledata, у земли 0; не координата Z.

ArrayLength(result) — число записей, не число клеток и не число шагов маршрута. Результат может быть пустым. У одного x/y может быть несколько записей с разными Z. Запись "object" имеет serial; запись "static" не имеет пригодного serial.

Поведение

  • Данные относятся к текущей загруженной карте. Другая карта или недоступная клетка дают пустой массив. Прямые запросы тайлов могут дополнительно сообщать о несовпадении карты; GetWorldCell и GetWorldTilesArray сразу возвращают пустой массив без такого сообщения.
  • Индексы массивов начинаются с 0. Перед чтением поля проверяйте ArrayLength. Z означает высоту в мире; layer — свойство экипировки из tiledata, а index — порядковый номер записи клетки.
  • Статическая часть использует GetStaticTiles: его текущая выборка включает также Multi/Item. Мировой Item может дополнительно присутствовать как "object" с serial; не считайте каждую запись уникальным предметом.
  • GetWorldTilesArray ограничивает область 1 000 000 клеток. Превышение или координаты вне 0…65535/map вне 0…255 вызывают ошибку команды, а не частичный массив. Для частого опроса выбирайте небольшую область.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetWorldCell(UO.GetX(), UO.GetY());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Посчитать и перечислить записи — прямой скрипт

Параметры и ход выполнения:

  • GetWorldCell читает одну клетку; GetWorldTilesArray в этом примере читает квадрат 3×3 с включёнными границами.
  • cells[i] — вложенный массив. tile[0] — категория, [2] — graphic, [5] — Z.
var cells = UO.GetWorldCell(UO.GetX(), UO.GetY());
var i = 0;
while (Truth(i < ArrayLength(cells)))
{
    var tile = cells[i];
    UO.Print(tile[0] + ": " + Convert.ToString(tile[2]) + ", Z=" + Convert.ToString(tile[5]));
    i = i + 1;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Показать только записи с serial предмета — функция сценария

Параметры и ход выполнения:

  • Область выбирается координатами, а не контейнером.
  • Проверка kind="object" отделяет серийные предметы от земли/статики; [1] содержит serial.
return  RunScenario();
 object? RunScenario()
{
    var cells = UO.GetWorldCell(UO.GetX(), UO.GetY());
    var i = 0;
    while (Truth(i < ArrayLength(cells)))
    {
        var tile = cells[i];
        if (Truth(tile[0] == "object"))
        {
            UO.Print("Object serial: " + Convert.ToString(tile[1]));
        }

        i = i + 1;
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Отобрать записи на высоте персонажа — класс сценария

Параметры и ход выполнения:

  • tile[5] и GetZ() сравниваются в одинаковых единицах мировой высоты.
  • Равенство Z фильтрует основание, но не означает проходимость или совпадение этажа целиком.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var cells = UO.GetWorldCell(UO.GetX(), UO.GetY());
        var i = 0;
        while (Truth(i < ArrayLength(cells)))
        {
            var tile = cells[i];
            if (Truth(tile[5] == UO.GetZ()))
            {
                UO.Print(tile[8]);
            }

            i = i + 1;
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetWorldCell(x, y) — UO.GetWorldCell(Any,Any)

Параметры: x (Any), y (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetWorldCell(InjectionValue x, InjectionValue y)

            => GetWorldCell(x, y, new InjectionValue(bridge.WorldNumber));

UO.GetWorldCell(x, y, map) — UO.GetWorldCell(Any,Any,Any)

Параметры: x (Any), y (Any), map (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetWorldCell(InjectionValue x, InjectionValue y, InjectionValue map)

            => BuildWorldCell(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map), true);

UO.GetWorldNum

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

int UO.GetWorldNum();

Читает номер текущей карты из модели клиента.

Параметры

Параметров нет.

Возвращает

int — индекс текущей карты клиента, обычно 0=Felucca, 1=Trammel, 2=Ilshenar, 3=Malas, 4=Tokuno, 5=Ter Mur. Пользовательский сервер может использовать иной набор карт. 0 — полноценная карта, не признак ошибки.

Поведение

  • Читаются уже полученные локальные данные. Запрос не открывает status и не заставляет сервер прислать обновление. После смерти, перехода карты или удаления объекта значения могут измениться между двумя вызовами.
  • C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

var result = UO.GetWorldNum();
UO.Print("GetWorldNum: " + Convert.ToString(result));

1. Вывести текущее значение своего персонажа — прямой скрипт

Параметры и ход выполнения:

  • Вызов без аргументов относится к self. Номер текущей карты сохраняется в value.
  • Convert.ToString преобразует число для вывода и не меняет смысл результата.
var value = UO.GetWorldNum();
UO.Print("GetWorldNum: " + Convert.ToString(value));

2. Использовать значение в прикладной проверке — функция сценария

Параметры и ход выполнения:

  • Значение читается один раз без аргументов. Номер текущей карты используется в показанном расчёте или условии.
  • Числовые пороги — пример условий скрипта, а не новые пределы клиента. Поле сохраняет серверные единицы и ограничения, описанные выше.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.GetWorldNum();
    var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), value);
    UO.Print("Land record length: " + Convert.ToString(ArrayLength(land)));
    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

3. Наблюдать изменение за одну секунду — класс сценария

Параметры и ход выполнения:

  • Оба вызова без аргумента читают своё текущее значение. UO.Wait(1000) даёт паузу в миллисекундах между снимками.
  • Сравнивается изменение: номер текущей карты. Пример ничего не изменяет в мире и не ждёт бесконечно. События внутри этой секунды могут быть пропущены.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var before = UO.GetWorldNum();
        await Delay(1000);
        var after = UO.GetWorldNum();
        if (Truth(before != after))
        {
            UO.Print("Before: " + Convert.ToString(before) + "; after: " + Convert.ToString(after));
        }

        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetWorldNum() — UO.GetWorldNum()

Параметры: Параметров нет.

Результат: int / Integer.

При вызове:

Вызов выполняет сохранённый delegate обработчика. Метод регистрации создаёт этот delegate при построении API.

Внутренний код реализации, не самостоятельный скрипт.

() => bridge.WorldNumber

Создание API: Эти функции создают регистрацию API; они не выполняются заново при каждом вызове команды.


UO.GetWorldTilesArray

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

dynamic UO.GetWorldTilesArray(object? minX, object? minY, object? maxX, object? maxY, object? map);

Читает расширенные записи земли, записей над землёй и загруженных мировых предметов в выбранной области.

Параметры

  • minX — Первая граница X прямоугольника, включённая; 0…65535.
  • minY — Первая граница Y прямоугольника, включённая; 0…65535.
  • maxX — Вторая включённая граница X; меньшая/большая из двух X выбираются автоматически.
  • maxY — Вторая включённая граница Y; меньшая/большая из двух Y выбираются автоматически.
  • map — Номер карты. Если этот аргумент отсутствует в выбранной форме, используется текущая карта. Реальный клиент читает тайлы только текущей загруженной карты.

Возвращает

Array записей. Каждый элемент result[i] имеет следующий формат:

Array из 11 полей одной записи; индексы начинаются с 0:

  • [0] kind — string: "land", "static" либо "object".
  • [1] serial — int: serial динамического предмета; для land/static равен 0.
  • [2] graphic — int: type графики.
  • [3] x, [4] y — int: мировые координаты клетки.
  • [5] z — int: высота основания в мире.
  • [6] hue — int: цвет, у земли 0.
  • [7] flags — int: младшие 32 бита флагов tiledata.
  • [8] name — string: название из tiledata.
  • [9] layer — int: слой экипировки из tiledata, у земли 0; не индекс статики.
  • [10] height — int: высота graphic из tiledata, у земли 0; не координата Z.

ArrayLength(result) — число записей, не число клеток и не число шагов маршрута. Результат может быть пустым. У одного x/y может быть несколько записей с разными Z. Запись "object" имеет serial; запись "static" не имеет пригодного serial.

Поведение

  • Данные относятся к текущей загруженной карте. Другая карта или недоступная клетка дают пустой массив. Прямые запросы тайлов могут дополнительно сообщать о несовпадении карты; GetWorldCell и GetWorldTilesArray сразу возвращают пустой массив без такого сообщения.
  • Индексы массивов начинаются с 0. Перед чтением поля проверяйте ArrayLength. Z означает высоту в мире; layer — свойство экипировки из tiledata, а index — порядковый номер записи клетки.
  • Статическая часть использует GetStaticTiles: его текущая выборка включает также Multi/Item. Мировой Item может дополнительно присутствовать как "object" с serial; не считайте каждую запись уникальным предметом.
  • GetWorldTilesArray ограничивает область 1 000 000 клеток. Превышение или координаты вне 0…65535/map вне 0…255 вызывают ошибку команды, а не частичный массив. Для частого опроса выбирайте небольшую область.

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

object? result = UO.GetWorldTilesArray(UO.GetX() - 1, UO.GetY() - 1, UO.GetX() + 1, UO.GetY() + 1, UO.WorldNum());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Посчитать и перечислить записи — прямой скрипт

Параметры и ход выполнения:

  • GetWorldCell читает одну клетку; GetWorldTilesArray в этом примере читает квадрат 3×3 с включёнными границами.
  • cells[i] — вложенный массив. tile[0] — категория, [2] — graphic, [5] — Z.
var cells = UO.GetWorldTilesArray(UO.GetX() - 1, UO.GetY() - 1, UO.GetX() + 1, UO.GetY() + 1, UO.WorldNum());
var i = 0;
while (Truth(i < ArrayLength(cells)))
{
    var tile = cells[i];
    UO.Print(tile[0] + ": " + Convert.ToString(tile[2]) + ", Z=" + Convert.ToString(tile[5]));
    i = i + 1;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Показать только записи с serial предмета — функция сценария

Параметры и ход выполнения:

  • Область выбирается координатами, а не контейнером.
  • Проверка kind="object" отделяет серийные предметы от земли/статики; [1] содержит serial.
return  RunScenario();
 object? RunScenario()
{
    var cells = UO.GetWorldTilesArray(UO.GetX() - 1, UO.GetY() - 1, UO.GetX() + 1, UO.GetY() + 1, UO.WorldNum());
    var i = 0;
    while (Truth(i < ArrayLength(cells)))
    {
        var tile = cells[i];
        if (Truth(tile[0] == "object"))
        {
            UO.Print("Object serial: " + Convert.ToString(tile[1]));
        }

        i = i + 1;
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Отобрать записи на высоте персонажа — класс сценария

Параметры и ход выполнения:

  • tile[5] и GetZ() сравниваются в одинаковых единицах мировой высоты.
  • Равенство Z фильтрует основание, но не означает проходимость или совпадение этажа целиком.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var cells = UO.GetWorldTilesArray(UO.GetX() - 1, UO.GetY() - 1, UO.GetX() + 1, UO.GetY() + 1, UO.WorldNum());
        var i = 0;
        while (Truth(i < ArrayLength(cells)))
        {
            var tile = cells[i];
            if (Truth(tile[5] == UO.GetZ()))
            {
                UO.Print(tile[8]);
            }

            i = i + 1;
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetWorldTilesArray(minX, minY, maxX, maxY, map) — UO.GetWorldTilesArray(Any,Any,Any,Any,Any)

Параметры: minX (Any), minY (Any), maxX (Any), maxY (Any), map (Any)

Результат: dynamic / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public InjectionValue GetWorldTilesArray(InjectionValue minX, InjectionValue minY, InjectionValue maxX, InjectionValue maxY, InjectionValue map)

        {

            int firstX = Math.Min(NumberConversions.ToInt(minX), NumberConversions.ToInt(maxX));

            int lastX = Math.Max(NumberConversions.ToInt(minX), NumberConversions.ToInt(maxX));

            int firstY = Math.Min(NumberConversions.ToInt(minY), NumberConversions.ToInt(maxY));

            int lastY = Math.Max(NumberConversions.ToInt(minY), NumberConversions.ToInt(maxY));

            int world = NumberConversions.ToInt(map);

            if (firstX < 0 || firstY < 0 || lastX > ushort.MaxValue || lastY > ushort.MaxValue

                || world < 0 || world > byte.MaxValue)

                throw new NativeSubrutineException("World tile coordinates must be 0..65535 and the map must be 0..255.");

            if (((long)lastX - firstX + 1) * ((long)lastY - firstY + 1) > 1_000_000L)

                throw new NativeSubrutineException("World tile array is limited to 1,000,000 cells per call.");

            // Live world items have no per-result map field. Never combine the

            // current world's items with a request for a different map, or scan

            // every cell only to report the same unloaded-map failure repeatedly.

            if (world != bridge.WorldNumber)

                return new InjectionValue(Array.Empty<InjectionValue>());



            var result = new List<InjectionValue>();

            for (int cellX = firstX; cellX <= lastX; cellX++)

            for (int cellY = firstY; cellY <= lastY; cellY++)

            {

                InjectionValue cell = BuildWorldCell(cellX, cellY, world, false);

                if (cell.Kind == InjectionValueKind.Array)

                    result.AddRange(cell.Array);

            }



            foreach (int serial in bridge.GetWorldItems() ?? Array.Empty<int>())

            {

                int objectX = bridge.GetX(serial);

                int objectY = bridge.GetY(serial);

                if (objectX >= firstX && objectX <= lastX && objectY >= firstY && objectY <= lastY)

                    result.Add(BuildWorldTileRecord("object", serial, bridge.GetGraphics(serial), objectX, objectY,

                        bridge.GetZ(serial), bridge.GetColor(serial), 1));

            }

            return new InjectionValue(result.ToArray());

        }

UO.GetX

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

int UO.GetX();
int UO.GetX(object? id);

Читает поле X загруженного объекта или текущего персонажа.

Параметры

  • id — Serial/ID объекта, а не graphic/type. Число, hex-строка, стандартное имя self/backpack/lasttarget/lastobject/lastcontainer/laststatus/finditem/lastcorpse или имя AddObject. Алиас должен быть установлен; существование проверяется Exists. В зарегистрированной форме без аргументов используется self.

Возвращает

int — координата X. Для неизвестного объекта возвращается 0. Ноль также является допустимой координатой. Измеряется в клетках для объектов мира; это не экранные пиксели.

Поведение

  • Читаются последние данные, уже известные клиенту; запрос обновления серверу не отправляется.
  • Неизвестный объект и ещё не полученное свойство могут иметь нулевое/пустое значение. Проверяйте Exists и условия конкретного действия.
  • Для персонажа или предмета на земле это координата мира. У предмета внутри контейнера X/Y задают положение внутри гампа; команда не переводит их в мировые координаты владельца.
  • Читается текущая координата объекта. Ожидающие подтверждения шаги не превращаются этой командой в расчёт маршрута.

Пример .csx

int x = UO.GetX();
UO.Print($"X = {x}");

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

var result = UO.GetX();
UO.Print("GetX: " + Convert.ToString(result));

1. Прочитать свою координату — прямой скрипт

Параметры и ход выполнения:

  • Форма без аргумента выбирает self, текущего персонажа.
  • position содержит координата X, а не serial.
var position = UO.GetX();
UO.Print("X: " + Convert.ToString(position));

2. Сравнить с выбранным персонажем — функция сценария

Параметры и ход выполнения:

  • lasttarget должен указывать на загруженного персонажа или предмет на земле.
  • delta — разность по одной оси. Она не является длиной маршрута; значение может быть отрицательным.
return  RunScenario();
 object? RunScenario()
{
    var other = UO.GetSerial("lasttarget");
    if (Truth(UO.Exists(other)))
    {
        var delta = UO.GetX(other) - UO.GetX();
        UO.Print("Difference: " + Convert.ToString(delta));
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Запомнить точку и сравнить позднее — класс сценария

Параметры и ход выполнения:

  • id="self" — явная форма выбора персонажа. UO.Wait=500 миллисекунд.
  • Сравнение показывает изменение только оси X. Изменение другой оси или поворот здесь не учитываются.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var before = UO.GetX("self");
        await Delay(500);
        var after = UO.GetX("self");
        if (Truth(before != after))
        {
            UO.Print("Coordinate changed");
        }

        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetX() — UO.GetX()

Параметры: Параметров нет.

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetX() => GetX("self");

UO.GetX(id) — UO.GetX(Any)

Параметры: id (Any/Integer/String)

Результат: int / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "getx": return new InjectionValue(bridge.GetX(Arg(0, bridge.Self)));

UO.GetX(id) — UO.GetX(Integer)

Параметры: id (Any/Integer/String)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetX(int id) => bridge.GetX(id);

UO.GetX(id) — UO.GetX(String)

Параметры: id (Any/Integer/String)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetX(string id) => GetX(GetObject(id));

UO.GetY

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-сигнатуры

int UO.GetY();
int UO.GetY(object? id);

Читает поле Y загруженного объекта или текущего персонажа.

Параметры

  • id — Serial/ID объекта, а не graphic/type. Число, hex-строка, стандартное имя self/backpack/lasttarget/lastobject/lastcontainer/laststatus/finditem/lastcorpse или имя AddObject. Алиас должен быть установлен; существование проверяется Exists. В зарегистрированной форме без аргументов используется self.

Возвращает

int — координата Y. Для неизвестного объекта возвращается 0. Ноль также является допустимой координатой. Измеряется в клетках для объектов мира; это не экранные пиксели.

Поведение

  • Читаются последние данные, уже известные клиенту; запрос обновления серверу не отправляется.
  • Неизвестный объект и ещё не полученное свойство могут иметь нулевое/пустое значение. Проверяйте Exists и условия конкретного действия.
  • Для персонажа или предмета на земле это координата мира. У предмета внутри контейнера X/Y задают положение внутри гампа; команда не переводит их в мировые координаты владельца.
  • Читается текущая координата объекта. Ожидающие подтверждения шаги не превращаются этой командой в расчёт маршрута.

Пример .csx

int y = UO.GetY();
UO.Print($"Y = {y}");

Самостоятельные C#-скрипты

Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.

Простой пример

Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.

Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.

var result = UO.GetY();
UO.Print("GetY: " + Convert.ToString(result));

1. Прочитать свою координату — прямой скрипт

Параметры и ход выполнения:

  • Форма без аргумента выбирает self, текущего персонажа.
  • position содержит координата Y, а не serial.
var position = UO.GetY();
UO.Print("Y: " + Convert.ToString(position));

2. Сравнить с выбранным персонажем — функция сценария

Параметры и ход выполнения:

  • lasttarget должен указывать на загруженного персонажа или предмет на земле.
  • delta — разность по одной оси. Она не является длиной маршрута; значение может быть отрицательным.
return  RunScenario();
 object? RunScenario()
{
    var other = UO.GetSerial("lasttarget");
    if (Truth(UO.Exists(other)))
    {
        var delta = UO.GetY(other) - UO.GetY();
        UO.Print("Difference: " + Convert.ToString(delta));
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Запомнить точку и сравнить позднее — класс сценария

Параметры и ход выполнения:

  • id="self" — явная форма выбора персонажа. UO.Wait=500 миллисекунд.
  • Сравнение показывает изменение только оси Y. Изменение другой оси или поворот здесь не учитываются.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var before = UO.GetY("self");
        await Delay(500);
        var after = UO.GetY("self");
        if (Truth(before != after))
        {
            UO.Print("Coordinate changed");
        }

        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Реализация команды

C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

UO.GetY() — UO.GetY()

Параметры: Параметров нет.

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetY() => GetY("self");

UO.GetY(id) — UO.GetY(Any)

Параметры: id (Any/Integer/String)

Результат: int / Any.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

case "gety": return new InjectionValue(bridge.GetY(Arg(0, bridge.Self)));

UO.GetY(id) — UO.GetY(Integer)

Параметры: id (Any/Integer/String)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetY(int id) => bridge.GetY(id);

UO.GetY(id) — UO.GetY(String)

Параметры: id (Any/Integer/String)

Результат: int / Integer.

При вызове:

Внутренний код реализации, не самостоятельный скрипт.

public int GetY(string id) => GetY(GetObject(id));
⚠️ **GitHub.com Fallback** ⚠️