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 |
UO.X · UO.Y · UO.Z · UO.GetX · UO.GetY · UO.GetZ
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
В каждой карточке команды есть несколько самостоятельных сценариев: прямой код, функции и классы. Ниже приведены отдельные короткие сценарии; ограничения и полный разбор находятся в карточках.
Параметры, результат и все сценарии
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;Параметры, результат и все сценарии
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;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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персонажа и hue0. - Шестипараметрический вызов добавляет статик с заданными graphic, координатами, высотой, hue и картой. Pathfinding учитывает его только на активной карте и в соответствии с флагами graphic в клиентских tiledata.
Эти записи локальны для клиента скриптов: они не создают игровой объект, не отправляют сетевой запрос и не изменяют данные shard’а.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- Числовой 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.
Параметры: staticItem (Any), worldNum (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(1, bridge.WorldNumber). -
InjectionScript.Runtime.NumberConversions.TryStr2Int:NumberConversions.TryStr2Int(arguments[0].String, out graphic). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Text:Text(0). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(arguments[0]). -
InjectionScript.Runtime.InjectionApiUO.AddUserStatic:AddUserStatic(graphic, bridge.GetX(bridge.Self), bridge.GetY(bridge.Self), bridge.GetZ(bridge.Self), 0, map). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetX:bridge.GetX(bridge.Self). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetY:bridge.GetY(bridge.Self). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetZ:bridge.GetZ(bridge.Self). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.WorldNumber:bridge.WorldNumber. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.Self:bridge.Self.
Внутренний код реализации, не самостоятельный скрипт.
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));
}Параметры: graphic (Any), x (Any), y (Any), z (Any), hue (Any), map (Any)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.Register [AddUserStatic]. -
InjectionScript.Runtime.InjectionApiUO.AddUserStatic: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])). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(values[0]).
Вызов выполняет сохранённый 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])))Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- Одинаковые точки проходят при допустимых 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));Параметры и ход выполнения:
- Высота и проходимость соседней клетки читаются из локальной карты.
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;
}Параметры и ход выполнения:
- Отрицательный 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.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
InjectionScript.Runtime.InjectionApiUO.CheckPortableLineOfSight:CheckPortableLineOfSight(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), Arg(5), Arg(6)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Внутренний код реализации, не самостоятельный скрипт.
case "checklos": return new InjectionValue(CheckPortableLineOfSight(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), Arg(5), Arg(6)) ? 1 : 0);Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
void UO.ClearUserStatics();Удаляет все пользовательские static записи runtime и локальные статические объекты менеджера.
Параметров нет.
void — возвращаемого значения нет.
- State.UserStatics и менеджерские объекты очищаются. Загруженные файлы карты и реальные серверные предметы не удаляются.
Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.
Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.
Команда вызывается отдельной строкой. Сообщение перед ней показывает начало вызова, а не подтверждение действия сервера.
UO.Print("Calling UO.ClearUserStatics");
UO.ClearUserStatics();Параметры и ход выполнения:
- Удаляет все пользовательские static записи runtime и локальные статические объекты менеджера.
UO.ClearUserStatics();Параметры и ход выполнения:
- Добавить локальный статик на текущей клетке, затем удалить все пользовательские статики.
return RunScenario();
object? RunScenario()
{
var localStatic = UO.AddUserStatic(0x0CCA, UO.GetX(), UO.GetY(), UO.GetZ(), 0, UO.WorldNum());
UO.ClearUserStatics();
return null;
}Параметры и ход выполнения:
- Очистка пустого набора допустима и не создаёт новую настройку.
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.
Параметры: Параметров нет.
Результат: void / Unit.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.ClearUserStatics:bridge.ClearUserStatics().
Внутренний код реализации, не самостоятельный скрипт.
case "clearuserstatics": state.UserStatics.Clear(); bridge.ClearUserStatics(); return InjectionValue.Unit;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- Ни один ненулевой 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;Параметры и ход выполнения:
- Массив содержит реальные имена 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;Параметры и ход выполнения:
- Группа 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.
Параметры: group (Any), value (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.ConvertTileFlags:bridge.ConvertTileFlags(Arg(0), Arg(1)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Внутренний код реализации, не самостоятельный скрипт.
case "convertintegertoflags":
return new InjectionValue(bridge.ConvertTileFlags(Arg(0), Arg(1))
.Select(flag => new InjectionValue(flag)).ToArray());Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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)). При перестановке точек результат тот же. Это не евклидово расстояние, не сумма разностей и не число шагов при обходе препятствия.
Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.
Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.
Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.
var result = UO.Dist(100, 100, 103, 104);
UO.Print("Dist: " + Convert.ToString(result));Параметры и ход выполнения:
- От (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);Параметры и ход выполнения:
- От (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;
}Параметры и ход выполнения:
- 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.
Параметры: xfrom (Any), yfrom (Any), xto (Any), yto (Any)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
InjectionScript.Runtime.InjectionApiUO.GetDistance:GetDistance(Arg(0), Arg(1), Arg(2), Arg(3)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetDistance:bridge.GetDistance(Arg(0)).
Внутренний код реализации, не самостоятельный скрипт.
case "dist": return new InjectionValue(arguments.Length >= 4
? GetDistance(Arg(0), Arg(1), Arg(2), Arg(3))
: bridge.GetDistance(Arg(0)));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 и проверка его результата; стены могут сделать реальный путь длиннее.
Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.
Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.
Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.
var result = UO.GetDistance("lasttarget");
UO.Print("GetDistance: " + Convert.ToString(result));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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;
}Параметры и ход выполнения:
- Два аргумента 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.
Параметры: id (Any/Integer/String)
Результат: int / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetDistance:bridge.GetDistance(Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Внутренний код реализации, не самостоятельный скрипт.
case "getdistance": return new InjectionValue(bridge.GetDistance(Arg(0)));Параметры: id (Any/Integer/String)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetDistance. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetDistance:bridge.GetDistance(id).
Внутренний код реализации, не самостоятельный скрипт.
public int GetDistance(int id) => bridge.GetDistance(id);Параметры: id (Any/Integer/String)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetDistance. -
InjectionScript.Runtime.InjectionApiUO.GetDistance:GetDistance(GetObject(id)). -
InjectionScript.Runtime.InjectionApiUO.GetObject:GetObject(id).
Внутренний код реализации, не самостоятельный скрипт.
public int GetDistance(string id) => GetDistance(GetObject(id));Параметры: x (Integer), y (Integer)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetDistance. -
InjectionScript.Runtime.InjectionApiUO.GetDistance:GetDistance(bridge.GetX(bridge.Self), bridge.GetY(bridge.Self), x, y). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetX:bridge.GetX(bridge.Self). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetY:bridge.GetY(bridge.Self). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.Self:bridge.Self.
Внутренний код реализации, не самостоятельный скрипт.
public int GetDistance(int x, int y) => GetDistance(bridge.GetX(bridge.Self), bridge.GetY(bridge.Self), x, y);Параметры: id1 (Any), x2 (Any), y2 (Any)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetDistance. -
InjectionScript.Runtime.InjectionApiUO.GetObject:GetObject(id1). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetX:bridge.GetX(obj1). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetY:bridge.GetY(obj1). -
InjectionScript.Runtime.InjectionApiUO.GetDistance:GetDistance(x1, y1, NumberConversions.ToInt(x2), NumberConversions.ToInt(y2)). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(x2).
Внутренний код реализации, не самостоятельный скрипт.
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));
}Параметры: 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);
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 — порядковый номер записи клетки.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- Используются те же координаты; 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;Параметры и ход выполнения:
- 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.
Параметры: x (Any), y (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetLandTileAt. -
InjectionScript.Runtime.InjectionApiUO.GetLandTileAt:GetLandTileAt(x, y, new InjectionValue(bridge.WorldNumber)). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.WorldNumber:bridge.WorldNumber.
Внутренний код реализации, не самостоятельный скрипт.
public InjectionValue GetLandTileAt(InjectionValue x, InjectionValue y)
=> GetLandTileAt(x, y, new InjectionValue(bridge.WorldNumber));Параметры: x (Any), y (Any), map (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetLandTileAt. -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(x). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetLandscapeTile:bridge.GetLandscapeTile(cellX, cellY, world). -
InjectionScript.Runtime.InjectionApiUO.BuildWorldTileRecord:BuildWorldTileRecord("land", 0, land[0], cellX, cellY, land[1], 0, 0).
Внутренний код реализации, не самостоятельный скрипт.
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>());
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 в мире. Флаги описывают ресурс; результат не заменяет полноценную проверку маршрута.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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.
Параметры: tile (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
InjectionScript.Runtime.InjectionApiUO.BuildTileData:BuildTileData(0, Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Внутренний код реализации, не самостоятельный скрипт.
case "getlandtiledata":
return BuildTileData(0, Arg(0));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 мс. Отмена проверяется между порциями. Сложная клетка или холодное чтение могут превысить бюджет. Большую область лучше делить; мир может меняться во время чтения.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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 передана от большего угла к меньшему. Алгоритм сам нормализует границы. 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;Параметры и ход выполнения:
- Не более трёх поисков одной клетки; между попытками 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.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
InjectionScript.Runtime.InjectionApiUO.FindPortableTiles:FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), new[] { Arg(5) }, false). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Внутренний код реализации, не самостоятельный скрипт.
case "getlandtilesarray":
return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), new[] { Arg(5) }, false);Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 мс. Отмена проверяется между порциями. Сложная клетка или холодное чтение могут превысить бюджет. Большую область лучше делить; мир может меняться во время чтения.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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 передана от большего угла к меньшему. Алгоритм сам нормализует границы. 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;Параметры и ход выполнения:
- Не более трёх поисков одной клетки; между попытками 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.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
InjectionScript.Runtime.InjectionApiUO.FindPortableTiles:FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), ArrayArg(5), false). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::ArrayArg:ArrayArg(5).
Внутренний код реализации, не самостоятельный скрипт.
case "getlandtilesarrayex":
return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), ArrayArg(5), false);Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 — порядковый номер записи клетки.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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.
Параметры: x (Any), y (Any), map (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetLandscapeTile. -
InjectionScript.Runtime.InjectionApiUO.ToArray:ToArray(bridge.GetLandscapeTile(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map))). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetLandscapeTile:bridge.GetLandscapeTile(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map)). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(x).
Внутренний код реализации, не самостоятельный скрипт.
public InjectionValue GetLandscapeTile(InjectionValue x, InjectionValue y, InjectionValue map)
=> ToArray(bridge.GetLandscapeTile(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map)));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- count — число записей клетки; 1 означает одну запись, а не логический успех.
var count = UO.GetLayerCount(UO.GetX(), UO.GetY(), UO.WorldNum());
UO.Print("Tile records: " + Convert.ToString(count));Параметры и ход выполнения:
- Отсутствие записей не доказывает проходимость земли. Наличие записи тоже не доказывает, что она является стеной.
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;Параметры и ход выполнения:
- Проверяются текущая и соседняя клетки в том же мире. Количество слоёв не является их высотой или 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.
Параметры: x (Any), y (Any), worldNum (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetStaticTiles:bridge.GetStaticTiles(Arg(0), Arg(1), Arg(2)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Внутренний код реализации, не самостоятельный скрипт.
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);Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 могут быть допустимыми данными; проверяйте форму результата.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- Второй вызов читает клетку восточнее, оба используют одну карту.
- Разность высот земли не доказывает проходимость: стены, статики и другие объекты проверяются отдельно.
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;Параметры и ход выполнения:
- 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.
Параметры: x (Any), y (Any), worldNum (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetLandscapeTile:bridge.GetLandscapeTile(Arg(0), Arg(1), Arg(2)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Внутренний код реализации, не самостоятельный скрипт.
case "getmapcell":
return new InjectionValue(bridge.GetLandscapeTile(Arg(0), Arg(1), Arg(2))
.Select(value => new InjectionValue(value)).ToArray());Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- Шесть параметров: исходные 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));Параметры и ход выполнения:
- Вызов выполняется только при известном подключении. Между проверкой и чтением соединение может пропасть; 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;Параметры и ход выполнения:
- Координаты исходной и целевой клеток передаются отдельно. Результат — предполагаемая высота, даже при непроходимости; флаг прохода отдельно даёт 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.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.IsOnline:bridge.IsOnline(). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(4). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.CheckWorldStep:bridge.CheckWorldStep(Arg(0), Arg(1), Arg(5), Arg(2), Arg(3), Arg(4)). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.WorldNumber:bridge.WorldNumber.
Внутренний код реализации, не самостоятельный скрипт.
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));
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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.
Параметры: objType (Any), hue (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetStaticArt:bridge.GetStaticArt(ResolveType(arguments[0]), Arg(1)). -
InjectionScript.Runtime.InjectionApiUO.ResolveType:ResolveType(arguments[0]). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(1).
Внутренний код реализации, не самостоятельный скрипт.
case "getstaticart":
return new InjectionValue(bridge.GetStaticArt(ResolveType(arguments[0]), Arg(1)).Select(value => new InjectionValue(value)).ToArray());Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 — порядковый номер записи клетки.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- Используются те же координаты; 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;Параметры и ход выполнения:
- 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.
Параметры: x (Any), y (Any), index (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetStaticTileAt. -
InjectionScript.Runtime.InjectionApiUO.GetStaticTileAt:GetStaticTileAt(x, y, new InjectionValue(bridge.WorldNumber), index). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.WorldNumber:bridge.WorldNumber.
Внутренний код реализации, не самостоятельный скрипт.
public InjectionValue GetStaticTileAt(InjectionValue x, InjectionValue y, InjectionValue index)
=> GetStaticTileAt(x, y, new InjectionValue(bridge.WorldNumber), index);Параметры: x (Any), y (Any), map (Any), index (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetStaticTileAt. -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(x). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetStaticTiles:bridge.GetStaticTiles(cellX, cellY, NumberConversions.ToInt(map)). -
InjectionScript.Runtime.InjectionApiUO.BuildWorldTileRecord:BuildWorldTileRecord("static", 0, statics[offset], cellX, cellY, statics[offset + 1], statics[offset + 2], 1).
Внутренний код реализации, не самостоятельный скрипт.
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>());
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 в мире. Флаги описывают ресурс; результат не заменяет полноценную проверку маршрута.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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.
Параметры: tile (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
InjectionScript.Runtime.InjectionApiUO.BuildTileData:BuildTileData(1, Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Внутренний код реализации, не самостоятельный скрипт.
case "getstatictiledata":
return BuildTileData(1, Arg(0));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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.
Параметры: x (Any), y (Any), map (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetStaticTiles. -
InjectionScript.Runtime.InjectionApiUO.ToArray:ToArray(bridge.GetStaticTiles(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map))). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetStaticTiles:bridge.GetStaticTiles(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map)). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(x).
Внутренний код реализации, не самостоятельный скрипт.
public InjectionValue GetStaticTiles(InjectionValue x, InjectionValue y, InjectionValue map)
=> ToArray(bridge.GetStaticTiles(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map)));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 не включаются. Она шире классической выборки только статик из файлов.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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 передана от большего угла к меньшему. Алгоритм сам нормализует границы. 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;Параметры и ход выполнения:
- Не более трёх поисков одной клетки; между попытками 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.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
InjectionScript.Runtime.InjectionApiUO.FindPortableTiles:FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), new[] { Arg(5) }, true). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Внутренний код реализации, не самостоятельный скрипт.
case "getstatictilesarray":
return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), new[] { Arg(5) }, true);Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 не включаются. Она шире классической выборки только статик из файлов.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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 передана от большего угла к меньшему. Алгоритм сам нормализует границы. 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;Параметры и ход выполнения:
- Не более трёх поисков одной клетки; между попытками 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.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
InjectionScript.Runtime.InjectionApiUO.FindPortableTiles:FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), ArrayArg(5), true). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::ArrayArg:ArrayArg(5).
Внутренний код реализации, не самостоятельный скрипт.
case "getstatictilesarrayex":
return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), ArrayArg(5), true);Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 могут быть допустимыми данными; проверяйте форму результата.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- Все три параметра относятся к текущей клетке карты. 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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- Разность показывает наклон земли. Этот пример ничего не перемещает и не считает маршрут.
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.
Параметры: x (Any), y (Any), worldNum (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetSurfaceZ:bridge.GetSurfaceZ(Arg(0), Arg(1), Arg(2)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Внутренний код реализации, не самостоятельный скрипт.
case "getsurfacez":
return new InjectionValue(bridge.GetSurfaceZ(Arg(0), Arg(1), Arg(2)));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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, а не из текущего состояния конкретного предмета.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- Первые два аргумента 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.
Параметры: group (Any), tileId (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetTileFlags. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetTileFlags:bridge.GetTileFlags(NumberConversions.ToInt(group), NumberConversions.ToInt(tileId)). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(group).
Внутренний код реализации, не самостоятельный скрипт.
public InjectionValue GetTileFlags(InjectionValue group, InjectionValue tileId)
=> new InjectionValue(unchecked((int)bridge.GetTileFlags(NumberConversions.ToInt(group), NumberConversions.ToInt(tileId))));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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, а не из текущего состояния конкретного предмета.
Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.
Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.
Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.
var result = UO.GetTileHeight(1, 0x0CCA);
UO.Print("GetTileHeight: " + Convert.ToString(result));Параметры и ход выполнения:
- group=1 выбирает static tiledata; tileId=0x0CCA — graphic дерева.
- value содержит результат, описанный в разделе «Возвращает»; его смысл не совпадает с serial.
var value = UO.GetTileHeight(1, 0x0CCA);
UO.Print("Tiledata height: " + Convert.ToString(value));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- Первые два аргумента 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.
Параметры: group (Any), tileId (Any)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetTileHeight. -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(group). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetTileDataProperties:bridge.GetTileDataProperties(tileGroup, NumberConversions.ToInt(tileId)).
Внутренний код реализации, не самостоятельный скрипт.
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];
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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, а не из текущего состояния конкретного предмета.
Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.
Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.
Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.
var result = UO.GetTileLayer(1, 0x0CCA);
UO.Print("GetTileLayer: " + Convert.ToString(result));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- Первые два аргумента 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.
Параметры: group (Any), tileId (Any)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetTileLayer. -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(group). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetTileDataProperties:bridge.GetTileDataProperties(tileGroup, NumberConversions.ToInt(tileId)).
Внутренний код реализации, не самостоятельный скрипт.
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];
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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, а не из текущего состояния конкретного предмета.
Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.
Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.
Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.
var result = UO.GetTileName(1, 0x0CCA);
UO.Print("GetTileName: " + Convert.ToString(result));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- Первые два аргумента 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.
Параметры: group (Any), tileId (Any)
Результат: string / String.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetTileName. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetTileDataName:bridge.GetTileDataName(NumberConversions.ToInt(group), NumberConversions.ToInt(tileId)). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(group).
Внутренний код реализации, не самостоятельный скрипт.
public string GetTileName(InjectionValue group, InjectionValue tileId)
=> bridge.GetTileDataName(NumberConversions.ToInt(group), NumberConversions.ToInt(tileId));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- Каждая запись занимает четыре 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;Параметры и ход выполнения:
- Индексы 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;Параметры и ход выполнения:
- Диапазон 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.
Параметры: x (Any), y (Any), map (Any), tileStart (Any), tileEnd (Any), uoPath (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetTileXYM. -
InjectionScript.Runtime.InjectionApiUO.ToArray:ToArray(bridge.GetTileXYM(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map), NumberConversions.ToInt(tileStart), NumberConversions.ToInt(tileEnd), uoPath.ToString())). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetTileXYM:bridge.GetTileXYM(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map), NumberConversions.ToInt(tileStart), NumberConversions.ToInt(tileEnd), uoPath.ToString()). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(x). -
InjectionScript.Runtime.InjectionValue.ToString:uoPath.ToString().
Внутренний код реализации, не самостоятельный скрипт.
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()));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 всё равно проверяются по загруженному миру.
Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.
Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.
Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.
var result = UO.GetUserStatic(1);
UO.Print("GetUserStatic: " + Convert.ToString(result));Параметры и ход выполнения:
- Читает сохранённую пользовательскую static-запись.
UO.Print(UO.GetUserStatic(1));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- Читает текущее локальное состояние. Пакета, 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.
Параметры: id (Any)
Результат: string / String.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetUserStatic. -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(id).
Внутренний код реализации, не самостоятельный скрипт.
public string GetUserStatic(InjectionValue id)
=> state.UserStatics.TryGetValue(NumberConversions.ToInt(id), out string value) ? value : string.Empty;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 всё равно проверяются по загруженному миру.
Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.
Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.
Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.
object? result = UO.GetUserStatics();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));Параметры и ход выполнения:
- Читает state.UserStatics.
var records = UO.GetUserStatics();
UO.Print(UO.GetArrayLength(records));Параметры и ход выполнения:
- Читает 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;Параметры и ход выполнения:
- Читает текущее локальное состояние. Пакета, 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.
Параметры: Параметров нет.
Результат: 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());Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 вызывают ошибку команды, а не частичный массив. Для частого опроса выбирайте небольшую область.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- Область выбирается координатами, а не контейнером.
- Проверка 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;Параметры и ход выполнения:
- 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.
Параметры: x (Any), y (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetWorldCell. -
InjectionScript.Runtime.InjectionApiUO.GetWorldCell:GetWorldCell(x, y, new InjectionValue(bridge.WorldNumber)). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.WorldNumber:bridge.WorldNumber.
Внутренний код реализации, не самостоятельный скрипт.
public InjectionValue GetWorldCell(InjectionValue x, InjectionValue y)
=> GetWorldCell(x, y, new InjectionValue(bridge.WorldNumber));Параметры: x (Any), y (Any), map (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetWorldCell. -
InjectionScript.Runtime.InjectionApiUO.BuildWorldCell:BuildWorldCell(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map), true). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(x).
Внутренний код реализации, не самостоятельный скрипт.
public InjectionValue GetWorldCell(InjectionValue x, InjectionValue y, InjectionValue map)
=> BuildWorldCell(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map), true);Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.GetWorldNum();Читает номер текущей карты из модели клиента.
Параметров нет.
int — индекс текущей карты клиента, обычно 0=Felucca, 1=Trammel, 2=Ilshenar, 3=Malas, 4=Tokuno, 5=Ter Mur. Пользовательский сервер может использовать иной набор карт. 0 — полноценная карта, не признак ошибки.
- Читаются уже полученные локальные данные. Запрос не открывает status и не заставляет сервер прислать обновление. После смерти, перехода карты или удаления объекта значения могут измениться между двумя вызовами.
- C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.
Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.
Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.
Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.
var result = UO.GetWorldNum();
UO.Print("GetWorldNum: " + Convert.ToString(result));Параметры и ход выполнения:
- Вызов без аргументов относится к self. Номер текущей карты сохраняется в value.
- Convert.ToString преобразует число для вывода и не меняет смысл результата.
var value = UO.GetWorldNum();
UO.Print("GetWorldNum: " + Convert.ToString(value));Параметры и ход выполнения:
- Значение читается один раз без аргументов. Номер текущей карты используется в показанном расчёте или условии.
- Числовые пороги — пример условий скрипта, а не новые пределы клиента. Поле сохраняет серверные единицы и ограничения, описанные выше.
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;Параметры и ход выполнения:
- Оба вызова без аргумента читают своё текущее значение. 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.
Параметры: Параметров нет.
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.RegisterCharacterGetterAliases [GetWorldNum]. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.WorldNumber:bridge.WorldNumber.
Вызов выполняет сохранённый delegate обработчика. Метод регистрации создаёт этот delegate при построении API.
Внутренний код реализации, не самостоятельный скрипт.
() => bridge.WorldNumberСоздание API: Эти функции создают регистрацию API; они не выполняются заново при каждом вызове команды.
Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 вызывают ошибку команды, а не частичный массив. Для частого опроса выбирайте небольшую область.
Каждый пример можно сохранить отдельным файлом .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));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- Область выбирается координатами, а не контейнером.
- Проверка 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;Параметры и ход выполнения:
- 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.
Параметры: minX (Any), minY (Any), maxX (Any), maxY (Any), map (Any)
Результат: dynamic / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetWorldTilesArray. -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(minX). -
InjectionScript.Runtime.InjectionApiUO.BuildWorldCell:BuildWorldCell(cellX, cellY, world, false). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetWorldItems:bridge.GetWorldItems(). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetX:bridge.GetX(serial). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetY:bridge.GetY(serial). -
InjectionScript.Runtime.InjectionApiUO.BuildWorldTileRecord:BuildWorldTileRecord("object", serial, bridge.GetGraphics(serial), objectX, objectY, bridge.GetZ(serial), bridge.GetColor(serial), 1). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetGraphics:bridge.GetGraphics(serial). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetZ:bridge.GetZ(serial). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetColor:bridge.GetColor(serial). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.WorldNumber:bridge.WorldNumber.
Внутренний код реализации, не самостоятельный скрипт.
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());
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 задают положение внутри гампа; команда не переводит их в мировые координаты владельца.
- Читается текущая координата объекта. Ожидающие подтверждения шаги не превращаются этой командой в расчёт маршрута.
int x = UO.GetX();
UO.Print($"X = {x}");Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.
Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.
Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.
var result = UO.GetX();
UO.Print("GetX: " + Convert.ToString(result));Параметры и ход выполнения:
- Форма без аргумента выбирает self, текущего персонажа.
- position содержит координата X, а не serial.
var position = UO.GetX();
UO.Print("X: " + Convert.ToString(position));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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.
Параметры: Параметров нет.
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetX. -
InjectionScript.Runtime.InjectionApiUO.GetX:GetX("self").
Внутренний код реализации, не самостоятельный скрипт.
public int GetX() => GetX("self");Параметры: id (Any/Integer/String)
Результат: int / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetX:bridge.GetX(Arg(0, bridge.Self)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0, bridge.Self). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.Self:bridge.Self.
Внутренний код реализации, не самостоятельный скрипт.
case "getx": return new InjectionValue(bridge.GetX(Arg(0, bridge.Self)));Параметры: id (Any/Integer/String)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetX. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetX:bridge.GetX(id).
Внутренний код реализации, не самостоятельный скрипт.
public int GetX(int id) => bridge.GetX(id);Параметры: id (Any/Integer/String)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetX. -
InjectionScript.Runtime.InjectionApiUO.GetX:GetX(GetObject(id)). -
InjectionScript.Runtime.InjectionApiUO.GetObject:GetObject(id).
Внутренний код реализации, не самостоятельный скрипт.
public int GetX(string id) => GetX(GetObject(id));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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 задают положение внутри гампа; команда не переводит их в мировые координаты владельца.
- Читается текущая координата объекта. Ожидающие подтверждения шаги не превращаются этой командой в расчёт маршрута.
int y = UO.GetY();
UO.Print($"Y = {y}");Каждый пример можно сохранить отдельным файлом .csx и запускать в IDE. Объект UO и функции ожидания предоставляет host текущей игровой сессии. Демонстрационные serial, имена, координаты и адреса замените своими.
Выполните этот код как отдельный файл .csx. Аргументы видны прямо в вызове; демонстрационные имена, serial и адреса замените своими.
Результат одного вызова выводится в журнал. Число не преобразуется в bool; для массива показано количество элементов.
var result = UO.GetY();
UO.Print("GetY: " + Convert.ToString(result));Параметры и ход выполнения:
- Форма без аргумента выбирает self, текущего персонажа.
- position содержит координата Y, а не serial.
var position = UO.GetY();
UO.Print("Y: " + Convert.ToString(position));Параметры и ход выполнения:
- 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;Параметры и ход выполнения:
- 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.
Параметры: Параметров нет.
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetY. -
InjectionScript.Runtime.InjectionApiUO.GetY:GetY("self").
Внутренний код реализации, не самостоятельный скрипт.
public int GetY() => GetY("self");Параметры: id (Any/Integer/String)
Результат: int / Any.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetY:bridge.GetY(Arg(0, bridge.Self)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0, bridge.Self). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.Self:bridge.Self.
Внутренний код реализации, не самостоятельный скрипт.
case "gety": return new InjectionValue(bridge.GetY(Arg(0, bridge.Self)));Параметры: id (Any/Integer/String)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetY. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetY:bridge.GetY(id).
Внутренний код реализации, не самостоятельный скрипт.
public int GetY(int id) => bridge.GetY(id);Параметры: id (Any/Integer/String)
Результат: int / Integer.
При вызове:
-
InjectionScript.Runtime.InjectionApiUO.GetY. -
InjectionScript.Runtime.InjectionApiUO.GetY:GetY(GetObject(id)). -
InjectionScript.Runtime.InjectionApiUO.GetObject:GetObject(id).
Внутренний код реализации, не самостоятельный скрипт.
public int GetY(string id) => GetY(GetObject(id));