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

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

Движение

UO.LimitMove — Предел дальности движения.

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

Движение персонажа, построение пути, двери, препятствия и задержки шагов. Команды переноса вещей находятся в Items → Moving Items.

Разделы

Тема Команды и пояснения
Follow UO.Follow — фоновое следование, дистанция и остановка.
Move UO.Move
MoveXY UO.MoveXY
MoveXYZ UO.MoveXYZ
NewMoveXY UO.NewMoveXY
Step UO.Step
StepQ UO.StepQ
PMove UO.PMove
Direction UO.Direction
CalcDir UO.CalcDir
AlwaysRun UO.AlwaysRun
Поиск пути UO.GetPathArray · UO.GetPathArray3D · UO.NewMoveXY
GetPathArray UO.GetPathArray
GetPathArray3D UO.GetPathArray3D
ClientPath UO.ClientPath — путь к папке клиента, не игровой маршрут; см. Profiles & Configuration.
Doors UO.OpenDoor · UO.LastStepQUsedDoor · UO.moveOpenDoor
Obstacles UO.IsWorldCellPassable · UO.SetBadLocation · UO.moveThroughNPC · UO.moveThroughCorner
Настройки движения UO.moveCheckStamina · UO.moveExitOnDisconnect · UO.moveHeuristicMult · UO.moveTurnCost · UO.moveBetweenTwoCorners
Predicted X / Y / Z UO.PredictedX · UO.PredictedY · UO.PredictedZ
Таймеры движения UO.GetRunMountTimer · UO.GetRunUnMountTimer · UO.GetWalkMountTimer · UO.GetWalkUnmountTimer · UO.SetRunMountTimer · UO.SetRunUnmountTimer · UO.SetWalkMountTimer · UO.SetWalkUnmountTimer

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

Движение

UO.Move · UO.MoveXY · UO.MoveXYZ · UO.NewMoveXY · UO.Step · UO.StepQ · UO.PMove · UO.MoveOn · UO.MoveOff · UO.MoverStop · UO.CancelMove · UO.Moving · UO.IsMoving · UO.GetRun · UO.IsRunning · UO.AlwaysRun · UO.FixWalk

Direction

UO.Dir · UO.Direction · UO.GetDir · UO.GetDirection · UO.CalcDir · UO.PredictedDirection

Поиск пути

UO.GetPathArray · UO.GetPathArray3D · UO.AddStep · UO.AddDir

Двери

UO.OpenDoor · UO.LastStepQUsedDoor

Настройки движения

UO.moveBetweenTwoCorners · UO.moveCheckStamina · UO.moveExitOnDisconnect · UO.moveHeuristicMult · UO.moveOpenDoor · UO.moveThroughCorner · UO.moveThroughNPC · UO.moveTurnCost

Прогнозируемый X / Y / Z

UO.PredictedX · UO.PredictedY · UO.PredictedZ

Таймеры движения

UO.GetRunMountTimer · UO.GetRunUnMountTimer · UO.GetWalkMountTimer · UO.GetWalkUnmountTimer · UO.SetRunMountTimer · UO.SetRunUnmountTimer · UO.SetWalkMountTimer · UO.SetWalkUnmountTimer

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

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

UO.NewMoveXY

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

var x = UO.GetX() + 3;
var y = UO.GetY();
var ok = UO.NewMoveXY(x, y, true, 0, false);
if (Truth(ok))
{
    UO.Print("Destination reached");
}
else
{
    UO.Print("Destination not reached");
}

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

UO.GetPathArray3D

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

var x = UO.GetX();
var y = UO.GetY();
var z = UO.GetZ();
var path = UO.GetPathArray3D(x, y, z, x + 4, y, z, UO.WorldNum(), 0, 0, false);
if (Truth(ArrayLength(path) > 0))
{
    UO.Print("Steps: " + Convert.ToString(ArrayLength(path) - 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;

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

1 · 2

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


UO.AddDir

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

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

void UO.AddDir(object? directions);

Параметры

  • directions — строка, сохраняемая в legacy-списке. Смысл и формат значения зависят от совместимого скрипта, который его использует.

Возвращает

void. Добавленная запись не является подтверждением движения.

Поведение

  • Значение добавляется в список AddDir текущего состояния runtime. Сам вызов не передаёт пакет движения, не двигает персонажа и не имеет документированного публичного getter для чтения этого списка.

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

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

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

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

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

UO.Print("Calling UO.AddDir");
UO.AddDir("E");

1. Сохранить направление как совместимую legacy-запись, не двигая персонажа. — прямой скрипт

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

  • Сохранить направление как совместимую legacy-запись, не двигая персонажа.
UO.AddDir("E");

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

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

  • Передать значение из переменной в legacy-список AddDir.
return  RunScenario();
 object? RunScenario()
{
    var directionEntry = "north-east";
    UO.AddDir(directionEntry);
    return null;
}

3. Каждый вызов добавляет ещё одну строковую запись в состояние runtime. — класс сценария

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

  • Каждый вызов добавляет ещё одну строковую запись в состояние runtime.
  • Вспомогательная процедура также не отправляет команду движения.
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()
    {
        AddLegacyDirection("W");
        return null;
    }

    void AddLegacyDirection(dynamic entry)
    {
        UO.AddDir(entry);
    }
}

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

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

UO.AddDir(directions) — UO.AddDir(Any)

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

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

При вызове:

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

case "adddir":

                case "addfindlist":

                case "addgate":

                case "addrecall":

                case "addstep":

                    LegacyList(name).Add(string.Join("|", arguments.Select(value => value.ToString())));

                    break;

UO.AddStep

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

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

void UO.AddStep(object? directions);

Параметры

  • directions — значение, которое runtime преобразует в текст и добавляет в compatibility-список AddStep. Направление само по себе не интерпретируется.

Возвращает

void. Вызов не возвращает значение и не подтверждает перемещение.

Поведение

  • Каждый вызов добавляет строковое представление аргумента в список AddStep текущего состояния runtime. Эта legacy-запись не отправляет команду движения и не имеет публичного getter в текущей реализации.

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

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

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

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

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

UO.Print("Calling UO.AddStep");
UO.AddStep(2);

1. Записать значение в legacy-список; персонаж не перемещается. — прямой скрипт

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

  • Записать значение в legacy-список; персонаж не перемещается.
UO.AddStep(2);

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

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

  • Передать текстовое значение: оно сохраняется как запись, а не выполняется как направление.
return  RunScenario();
 object? RunScenario()
{
    var legacyValue = "east";
    UO.AddStep(legacyValue);
    return null;
}

3. Каждый вызов добавляет отдельную запись в AddStep текущего runtime. — класс сценария

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

  • Каждый вызов добавляет отдельную запись в AddStep текущего runtime.
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.AddStep(1);
        UO.AddStep(2);
        return null;
    }
}

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

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

UO.AddStep(directions) — UO.AddStep(Any)

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

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

При вызове:

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

case "adddir":

                case "addfindlist":

                case "addgate":

                case "addrecall":

                case "addstep":

                    LegacyList(name).Add(string.Join("|", arguments.Select(value => value.ToString())));

                    break;

UO.AlwaysRun

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

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

int UO.AlwaysRun();
void UO.AlwaysRun(object? enabled);

Читает или меняет настройку постоянного бега текущего профиля ClassicUO.

Параметры

  • enabled — 0 отключает постоянный бег; любое ненулевое значение включает его.

Возвращает

Форма без аргументов возвращает 1, если настройка включена, иначе 0. Форма с аргументом возвращает null.

Поведение

  • Значение читается из текущего профиля. Установка изменяет AlwaysRun и сохраняет текущий профиль. Без активного профиля getter возвращает 0, а setter сообщает об ошибке в клиентский журнал и не меняет настройку.

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

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

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

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

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

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

1. Прочитать настройку; 1 означает, что постоянный бег включён. — прямой скрипт

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

  • Прочитать настройку; 1 означает, что постоянный бег включён.
var isAlwaysRunning = UO.AlwaysRun();
UO.Print(Convert.ToString(isAlwaysRunning));

2. Включить постоянный бег и сохранить настройку текущего профиля. — функция сценария

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

  • Включить постоянный бег и сохранить настройку текущего профиля.
return  RunScenario();
 object? RunScenario()
{
    UO.AlwaysRun(1);
    return null;
}

3. Отключить постоянный бег, только если он сейчас включён. — класс сценария

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

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

     public object? RunScenario()
    {
        if (Truth(UO.AlwaysRun() != 0))
        {
            UO.AlwaysRun(0);
        }

        return null;
    }

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

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

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

UO.AlwaysRun() — UO.AlwaysRun()

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

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

При вызове:

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

public int AlwaysRun() => bridge.AlwaysRun();

UO.AlwaysRun(enabled) — UO.AlwaysRun(Integer)

Параметры: enabled (Integer)

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

При вызове:

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

public void AlwaysRun(int enabled) => bridge.AlwaysRun(enabled);

UO.CalcDir

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

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

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

Вычисляет направление от одной мировой точки к другой. Персонаж при этом не передвигается.

Параметры

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

Возвращает

int — код направления: 0=север, 1=северо-восток, 2=восток, 3=юго-восток, 4=юг, 5=юго-запад, 6=запад, 7=северо-запад. Совпавшие точки дают 100. Это не bool: 0 означает север, а не неудачу; 1 означает северо-восток, а не успех. Не передавайте 100 команде шага как направление.

Поведение

  • Только вычисление координат: без пакетов, ожиданий, загрузки карты, проверки препятствий, Z и карты мира. Команда не ищет проходимый маршрут и не гарантирует достижение цели. Точки должны относиться к одной системе координат; обход препятствий может увеличить путь.
  • Нужны все четыре параметра. Передавайте мировые координаты int в документированном диапазоне 0..65535. object? в сигнатуре обозначает универсальный адаптер, а не ID предмета. Значений по умолчанию, координат внутри сундука, пятого Z и перегрузки с одним объектом у этих команд нет.
  • Из координат назначения вычитаются исходные, затем проверяются знаки разностей. Уменьшение Y — север, увеличение X — восток. Если меняются обе координаты, выбирается диагональ независимо от величины разностей. Если обе разности нулевые — 100.

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

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

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

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

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

var result = UO.CalcDir(100, 100, 101, 100);
UO.Print("CalcDir: " + Convert.ToString(result));

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

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

  • Исходная точка (100,100), назначение (101,100): X увеличивается, Y не меняется. Main возвращает int 2 — восток. Команда передвижения не вызывается.
  • int — код направления: 0=север, 1=северо-восток, 2=восток, 3=юго-восток, 4=юг, 5=юго-запад, 6=запад, 7=северо-запад. Совпавшие точки дают 100. Это не bool: 0 означает север, а не неудачу; 1 означает северо-восток, а не успех. Не передавайте 100 команде шага как направление.
  • Из координат назначения вычитаются исходные, затем проверяются знаки разностей. Уменьшение Y — север, увеличение X — восток. Если меняются обе координаты, выбирается диагональ независимо от величины разностей. Если обе разности нулевые — 100.
return UO.CalcDir(100,100,101,100);

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

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

  • Обе точки равны (100,100). direction=100 означает совпадение, поэтому Main возвращает string "already there". При разных точках сработает другая ветка. Проверяется именно 100, а не true.
  • int — код направления: 0=север, 1=северо-восток, 2=восток, 3=юго-восток, 4=юг, 5=юго-запад, 6=запад, 7=северо-запад. Совпавшие точки дают 100. Это не bool: 0 означает север, а не неудачу; 1 означает северо-восток, а не успех. Не передавайте 100 команде шага как направление.
  • Из координат назначения вычитаются исходные, затем проверяются знаки разностей. Уменьшение Y — север, увеличение X — восток. Если меняются обе координаты, выбирается диагональ независимо от величины разностей. Если обе разности нулевые — 100.
return  RunScenario();
 object? RunScenario()
{
    var direction = UO.CalcDir(100, 100, 100, 100);
    if (Truth(direction == 100))
    {
        return "already there";
    }

    return "different point";
    return null;
}

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

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

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

  • При переходе от (20,20) к (19,21) X уменьшается, Y увеличивается: UO.CalcDir возвращает 5. RebuildDirection показывает все ветви этого алгоритма и тоже даёт 5. Main возвращает "5:5". Все четыре параметра помощника имеют тот же смысл координат.
  • int — код направления: 0=север, 1=северо-восток, 2=восток, 3=юго-восток, 4=юг, 5=юго-запад, 6=запад, 7=северо-запад. Совпавшие точки дают 100. Это не bool: 0 означает север, а не неудачу; 1 означает северо-восток, а не успех. Не передавайте 100 команде шага как направление.
  • Из координат назначения вычитаются исходные, затем проверяются знаки разностей. Уменьшение Y — север, увеличение X — восток. Если меняются обе координаты, выбирается диагональ независимо от величины разностей. Если обе разности нулевые — 100.
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.CalcDir(20, 20, 19, 21);
        var rebuilt = RebuildDirection(20, 20, 19, 21);
        return Convert.ToString(actual) + ":" + Convert.ToString(rebuilt);
        return null;
    }

    dynamic RebuildDirection(dynamic Xfrom, dynamic Yfrom, dynamic Xto, dynamic Yto)
    {
        var dx = Xto - Xfrom;
        var dy = Yto - Yfrom;
        if (Truth(dx == 0) && Truth(dy == 0))
        {
            return 100;
        }

        if (Truth(dx == 0))
        {
            if (Truth(dy < 0))
            {
                return 0;
            }

            return 4;
        }

        if (Truth(dy == 0))
        {
            if (Truth(dx > 0))
            {
                return 2;
            }

            return 6;
        }

        if (Truth(dx > 0))
        {
            if (Truth(dy < 0))
            {
                return 1;
            }

            return 3;
        }

        if (Truth(dy > 0))
        {
            return 5;
        }

        return 7;
    }

    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.CalcDir(xfrom, yfrom, xto, yto) — UO.CalcDir(Any,Any,Any,Any)

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

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

При вызове:

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

case "calcdir": return new InjectionValue(CalculateDirection(Arg(0), Arg(1), Arg(2), Arg(3)));

UO.CancelMove

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

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

void UO.CancelMove();

Отключает разрешение дальнейшего движения скриптом через MoveOff.

Параметры

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

Возвращает

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

Поведение

  • Вызывает MoveOff, который переводит runtime/менеджер в состояние MoveEnabled=false. Чтобы снова разрешить движение, нужен MoveOn. Команда не откатывает уже отправленные шаги.

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

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

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

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

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

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

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

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

  • Следующие команды движения учитывают выключенное разрешение.
UO.CancelMove();

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

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

  • MoveOn явно восстанавливает разрешение.
return  RunScenario();
 object? RunScenario()
{
    UO.CancelMove();
    UO.MoveOn();
    return null;
}

3. Защитная остановка при отсутствии соединения — класс сценария

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

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

     public object? RunScenario()
    {
        if (!(Truth(UO.Connected())))
        {
            UO.CancelMove();
        }

        return null;
    }

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

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

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

UO.CancelMove() — UO.CancelMove()

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

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

При вызове:

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

case "cancelmove": MoveOff(); break;

UO.Dir

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

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

int UO.Dir();

Читает направление персонажа из модели клиента.

Параметры

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

Возвращает

int — направление mobile без бита бега: 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW. Для неизвестного mobile возвращается 0, которое также означает север.

Поведение

  • Читаются уже полученные локальные данные. Запрос не открывает status и не заставляет сервер прислать обновление. После смерти, перехода карты или удаления объекта значения могут измениться между двумя вызовами.
  • C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

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

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

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

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

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

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

1. Вывести текущее значение своего персонажа — прямой скрипт

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

  • Вызов без аргументов относится к self. Направление персонажа сохраняется в value.
  • Convert.ToString преобразует число для вывода и не меняет смысл результата.
var value = UO.Dir();
UO.Print("Dir: " + Convert.ToString(value));

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

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

  • Значение читается один раз без аргументов. Направление персонажа используется в показанном расчёте или условии.
  • Числовые пороги — пример условий скрипта, а не новые пределы клиента. Поле сохраняет серверные единицы и ограничения, описанные выше.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.Dir();
    if (Truth(value == 2))
    {
        UO.Print("Facing east");
    }

    return null;
}

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

3. Наблюдать изменение за одну секунду — класс сценария

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

  • Оба вызова без аргумента читают своё текущее значение. 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.Dir();
        await Delay(1000);
        var after = UO.Dir();
        if (Truth(before != after))
        {
            UO.Print("Before: " + Convert.ToString(before) + "; after: " + Convert.ToString(after));
        }

        return null;
    }

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

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

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

UO.Dir() — UO.Dir()

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

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

При вызове:

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

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

() => bridge.GetDir(bridge.Self)

Создание API: Эти функции создают регистрацию API; они не выполняются заново при каждом вызове команды.


UO.Direction

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

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

int UO.Direction();

Читает направление персонажа из модели клиента.

Параметры

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

Возвращает

int — направление mobile без бита бега: 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW. Для неизвестного mobile возвращается 0, которое также означает север.

Поведение

  • Читаются уже полученные локальные данные. Запрос не открывает status и не заставляет сервер прислать обновление. После смерти, перехода карты или удаления объекта значения могут измениться между двумя вызовами.
  • C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

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

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

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

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

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

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

1. Вывести текущее значение своего персонажа — прямой скрипт

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

  • Вызов без аргументов относится к self. Направление персонажа сохраняется в value.
  • Convert.ToString преобразует число для вывода и не меняет смысл результата.
var value = UO.Direction();
UO.Print("Direction: " + Convert.ToString(value));

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

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

  • Значение читается один раз без аргументов. Направление персонажа используется в показанном расчёте или условии.
  • Числовые пороги — пример условий скрипта, а не новые пределы клиента. Поле сохраняет серверные единицы и ограничения, описанные выше.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.Direction();
    if (Truth(value == 2))
    {
        UO.Print("Facing east");
    }

    return null;
}

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

3. Наблюдать изменение за одну секунду — класс сценария

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

  • Оба вызова без аргумента читают своё текущее значение. 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.Direction();
        await Delay(1000);
        var after = UO.Direction();
        if (Truth(before != after))
        {
            UO.Print("Before: " + Convert.ToString(before) + "; after: " + Convert.ToString(after));
        }

        return null;
    }

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

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

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

UO.Direction() — UO.Direction()

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

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

При вызове:

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

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

() => bridge.GetDir(bridge.Self)

Создание API: Эти функции создают регистрацию API; они не выполняются заново при каждом вызове команды.


UO.FixWalk

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

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

void UO.FixWalk();

Печатает уведомление, что устаревший патч нативного клиента FixWalk не требуется ClassicUO.

Параметры

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

Возвращает

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

Поведение

  • Ветка ExecuteLegacyManualAlias только вызывает SystemMessage. Она не исправляет движение, речь, контейнеры или сетевой протокол.

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

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

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

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

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

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

1. Уведомление о совместимости — прямой скрипт

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

  • Сообщение описывает отсутствие необходимости в старом патче.
UO.FixWalk();

2. Вызов в процедуре — функция сценария

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

  • Процедура совместимости не изменяет игровой мир.
return  RunScenario();
 object? RunScenario()
{
    CompatibilityNotice();
    return null;
}

void CompatibilityNotice()
{
    UO.FixWalk();
}

3. Продолжение скрипта — класс сценария

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

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

     public object? RunScenario()
    {
        UO.FixWalk();
        UO.Print("continued");
        return null;
    }
}

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

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

UO.FixWalk() — UO.FixWalk()

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

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

При вызове:

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

case "boxhack":

                case "fixtalk":

                case "fixwalk":

                    SystemMessage($"{name}: obsolete native-client patch; ClassicUO does not require it.");

                    break;

UO.Follow

Follow применяет UO.LimitMove, moveCheckStamina, moveOpenDoor, moveThroughCorner, moveThroughNPC, moveHeuristicMult, moveTurnCost, moveExitOnDisconnect, moveBetweenTwoCorners и снимок SetBadLocation/SetBadObject. Дистанция подхода 0 разрешена также для персонажа; это не предел дальности UO.LimitMove.

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

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

int UO.Follow();
int UO.Follow(object? target);
int UO.Follow(object? target, object? distance);
int UO.Follow(object? target, object? distance, object? running);
int UO.Follow(object? target, object? distance, object? running, object? stopConditions);
int UO.Follow(object? x, object? y, object? z, object? distance, object? running);
int UO.Follow(object? x, object? y, object? z, object? distance, object? running, object? stopConditions);

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

Параметры

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

Возвращает

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

Поведение

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

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

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

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

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

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

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

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

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

  • leader — serial последней цели. Единица подтверждает принятие режима, а не прибытие. После конец метода режим продолжает работать до остановки/потери цели.
var leader = UO.GetSerial("lasttarget");
var accepted = UO.Follow(leader);
if (Truth(Truth(accepted) == true))
{
    UO.Print("Following is enabled; script continues");
}
else
{
    UO.Print("Select a loaded nearby character");
}

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

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

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

  • UO.Wait измеряется в миллисекундах. Follow(0) выключает общий режим следования; последующие перемещения цели больше не вызывают движение.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var leader = UO.GetSerial("lasttarget");
    if (Truth(UO.Follow(leader, 3, false) == 1))
    {
        await Delay(10000);
        UO.Follow(0);
        UO.Print("Following stopped");
    }

    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;

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

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

  • distance=2, running=true; максимум 20 ожиданий по 500 мс. Exists проверяет наличие объекта, не достижимость пути. finally останавливает режим при обычном выходе/ошибке; аварийная отмена владельца дополнительно обрабатывается клиентом.
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 leader = UO.GetSerial("leader");
        if (Truth(UO.Follow(leader, 2, true) == 0))
        {
            UO.Print("Cannot start following");
            return null;
        }

        try
        {
            var attempts = 0;
            while (Truth(attempts < 20) && Truth(UO.Exists(leader)))
            {
                await Delay(500);
                attempts = attempts + 1;
            }
        }
        finally
        {
            UO.Follow();
        }

        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;
}

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

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

  • Остановка по ЛЮБОМУ условию: цель дальше 12 клеток ИЛИ наши HP не больше 40% ИЛИ прошло 30 секунд. Это не AND. StopWhen приведена полностью, её можно вынести в Include. Единица означает принятие, не прибытие.
var leader = UO.GetSerial("lasttarget");
dynamic[] conditions = new dynamic[checked((int)(2) + 1)];
conditions[0] = StopWhen("distance", ">", 12);
conditions[1] = StopWhen("self.hppercent", "<=", 40);
conditions[2] = StopWhen("elapsed", ">=", 30000);
var accepted = UO.Follow(leader, 2, true, conditions);
if (Truth(accepted == 0))
{
    UO.Print("Cannot follow this target");
}

dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
{
    dynamic[] rule = new dynamic[checked((int)(2) + 1)];
    rule[0] = field;
    rule[1] = comparison;
    rule[2] = threshold;
    return rule;
}

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

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

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

  • Останавливаемся, если цель скрылась/умерла/перестала быть Ally, осталось не больше 5 выносливости либо перепад Z превысил 16. false означает идти пешком. ToArray передаёт список строк условий; размер заранее не задаётся. Если цель уже не Ally, движение не начнётся.
return  RunScenario();
 object? RunScenario()
{
    var checks = new List<object?>();
    checks.Add(StopWhen("target.hidden", "=", true));
    checks.Add(StopWhen("target.dead", "=", true));
    checks.Add(StopWhen("target.notoriety", "<>", 2));
    checks.Add(StopWhen("self.stam", "<=", 5));
    checks.Add(StopWhen("height", ">", 16));
    var leader = UO.GetSerial("lasttarget");
    var conditions = checks.ToArray();
    UO.Follow(leader, 2, false, conditions);
    return null;
}

dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
{
    dynamic[] rule = new dynamic[checked((int)(2) + 1)];
    rule[0] = field;
    rule[1] = comparison;
    rule[2] = threshold;
    return rule;
}

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

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

  • Поддерживаемая дистанция 1, условие остановки <=3; проверка каждые 250 мс может заметить достижение с задержкой. Таймаут 15000 мс не позволяет сопровождать бесконечно. Возврат Follow всё ещё означает принятие, не достижение трёх клеток.
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()
    {
        dynamic[] conditions = new dynamic[checked((int)(1) + 1)];
        conditions[0] = StopWhen("distance", "<=", 3);
        conditions[1] = StopWhen("elapsed", ">=", 15000);
        UO.Follow(UO.GetSerial("lasttarget"), 1, true, conditions);
        return null;
    }

    dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
    {
        dynamic[] rule = new dynamic[checked((int)(2) + 1)];
        rule[0] = field;
        rule[1] = comparison;
        rule[2] = threshold;
        return rule;
    }
}

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

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

  • while собирает отдельное условие для каждого элемента statuses. Остановка при статусе 5 ИЛИ 6, своих HP <=40% ИЛИ через 30000 мс. Пустой statuses пропустит цикл, но два следующих условия останутся. Новые строки добавляйте до Follow; последующее изменение List не изменяет уже установленную копию. Для background-проверок тело цикла не требуется выполнять повторно.
var statuses = new List<object?>();
statuses.Add(5);
statuses.Add(6);
var checks = new List<object?>();
var index = 0;
while (index < statuses.Count)
{
checks.Add(StopWhen("target.notoriety", "=", statuses[index]));
index += 1;
}
checks.Add(StopWhen("self.hppercent", "<=", 40));
checks.Add(StopWhen("elapsed", ">=", 30000));
var accepted = UO.Follow(UO.GetSerial("lasttarget"), 2, true, checks.ToArray());
if (Truth(accepted == 0))
{
    UO.Print("Select a loaded nearby character");
}

dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
{
    dynamic[] rule = new dynamic[checked((int)(2) + 1)];
    rule[0] = field;
    rule[1] = comparison;
    rule[2] = threshold;
    return rule;
}

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

8. Свои выражения в конец цикла UNTIL и обязательная остановка в Finally — функция сценария

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

  • StopEscort(leader, startedAt) возвращает bool-совместимые 1/0: цель дальше 12 клеток ИЛИ свои HP <=30 ИЛИ прошло 30 секунд. Добавляйте || (ещё_условие); для обязательного сочетания двух проверок используйте (условиеA && условиеB). Неизвестные HP могут читаться как 0; пример тогда отказывается начинать. Пока скрипт выполняется, он проверяет выражения примерно каждые 250 мс; пауза скрипта приостанавливает эти проверки. Finally отправляет остановку при обычном выходе/ошибке; отмену владельца дополнительно отслеживает клиент. Если цель исчезла и клиент уже остановил Follow, этот цикл завершится по своим условиям, не позже проверки таймаута. Для работы после конец метода используйте четвёртый аргумент, как в предыдущих примерах.
return  RunScenario();
 object? RunScenario()
{
    var leader = UO.GetSerial("lasttarget");
    var startedAt = Now();
    if (Truth(leader == "0x00000000") || Truth(StopEscort(leader, startedAt)))
    {
        return null;
    }

    if (Truth(UO.Follow(leader, 2, true) == 0))
    {
        return null;
    }

    try
    {
        do
        {
            UO.Wait(250);
        }
        while (!StopEscort(leader, startedAt));
    }
    finally
    {
        UO.Follow(0);
    }

    return null;
}

dynamic StopEscort(dynamic leader, dynamic startedAt)
{
    return (UO.GetDistance(leader) > 12) || (UO.GetHP("self") <= 30) || (Now() - startedAt >= 30000);
}

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

9. Бежать к точному X, Y, Z — класс сценария

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

  • Пять аргументов: X=1445, Y=1690, Z=0, допуск X/Y=0, бег. Возврат 1 означает принятие, а не уже выполненное прибытие. На месте задача выключится полностью. Для досрочной ручной остановки вызовите UO.Follow(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 accepted = UO.Follow(1445, 1690, 0, 0, true);
        if (Truth(accepted == 0))
        {
            UO.Print("Coordinate task was not accepted");
        }

        return null;
    }

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

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

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

  • При HP <=40%, параличе или после 30 секунд клиент прекращает текущий путь. Иначе задача завершится в пределах двух клеток X/Y от (1445,1690), строго на Z=0. Проверки продолжаются и при поиске пути, и в движении; это не разовая проверка перед стартом. target.* здесь не применяется.
var checks = new List<object?>();
checks.Add(StopWhen("self.hppercent", "<=", 40));
checks.Add(StopWhen("self.paralyzed", "=", true));
checks.Add(StopWhen("elapsed", ">=", 30000));
UO.Follow(1445, 1690, 0, 2, true, checks.ToArray());

dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
{
    dynamic[] rule = new dynamic[checked((int)(2) + 1)];
    rule[0] = field;
    rule[1] = comparison;
    rule[2] = threshold;
    return rule;
}

11. Идти к точке, но закончить сопровождение за три клетки до неё — функция сценария

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

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

Стандартная скорость движения

Минимальный интервал шага: пешком — ходьба 400 мс, бег 200 мс; верхом — ходьба 200 мс, бег 100 мс.

Это стандартные пределы клиента, а не автоматически определённые настройки вашего шарда. Серверные режимы скорости и полёт учитываются отдельно. Таймеры скрипта могут замедлить движение, но не уменьшить эти пределы.

Шаги, маршруты, Follow, управление мышью/клавишами и карта используют общую очередь персонажа. Замена маршрута, поворот или коррекция позиции сервером не отменяют оставшуюся паузу после запроса шага. После задержки нет ускоренной серии для компенсации пропущенных кадров. Ожидание подтверждения, препятствия и плохая связь могут замедлить движение.

return  RunScenario();
 object? RunScenario()
{
    var checks = new List<object?>();
    checks.Add(StopWhen("distance", "<=", 3));
    checks.Add(StopWhen("height", ">", 16));
    checks.Add(StopWhen("elapsed", ">=", 20000));
    var x = UO.GetX("self") + 10;
    var y = UO.GetY("self");
    var z = UO.GetZ("self");
    UO.Follow(x, y, z, 0, false, checks.ToArray());
    return null;
}

dynamic StopWhen(dynamic field, dynamic comparison, dynamic threshold)
{
    dynamic[] rule = new dynamic[checked((int)(2) + 1)];
    rule[0] = field;
    rule[1] = comparison;
    rule[2] = threshold;
    return rule;
}

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

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

UO.Follow() — UO.Follow()

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

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

При вызове:

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

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

values => new InjectionValue(bridge is IApiFollowBridge follow

                        ? follow.Follow(count == 0 ? 0 : GetObject(values[0]),

                            count < 2 ? 1 : NumberConversions.ToInt(values[1]),

                            count < 3 || NumberConversions.ToInt(values[2]) != 0) : 0)

UO.Follow(target) — UO.Follow(Any)

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

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

При вызове:

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

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

values => new InjectionValue(bridge is IApiFollowBridge follow

                        ? follow.Follow(count == 0 ? 0 : GetObject(values[0]),

                            count < 2 ? 1 : NumberConversions.ToInt(values[1]),

                            count < 3 || NumberConversions.ToInt(values[2]) != 0) : 0)

UO.Follow(target, distance) — UO.Follow(Any,Any)

Параметры: target (Any), distance (Any)

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

При вызове:

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

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

values => new InjectionValue(bridge is IApiFollowBridge follow

                        ? follow.Follow(count == 0 ? 0 : GetObject(values[0]),

                            count < 2 ? 1 : NumberConversions.ToInt(values[1]),

                            count < 3 || NumberConversions.ToInt(values[2]) != 0) : 0)

UO.Follow(target, distance, running) — UO.Follow(Any,Any,Any)

Параметры: target (Any), distance (Any), running (Any)

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

При вызове:

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

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

values => new InjectionValue(bridge is IApiFollowBridge follow

                        ? follow.Follow(count == 0 ? 0 : GetObject(values[0]),

                            count < 2 ? 1 : NumberConversions.ToInt(values[1]),

                            count < 3 || NumberConversions.ToInt(values[2]) != 0) : 0)

UO.Follow(target, distance, running, stopConditions) — UO.Follow(Any,Any,Any,Any)

Параметры: target (Any), distance (Any), running (Any), stopConditions (Any)

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

При вызове:

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

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

values =>

                {

                    FollowStopCondition[] conditions = FollowStopCondition.Parse(values[3]);

                    return new InjectionValue(bridge is IApiConditionalFollowBridge follow

                        ? follow.Follow(GetObject(values[0]), NumberConversions.ToInt(values[1]), ToBoolean(values[2]), conditions) : 0);

                }

UO.Follow(x, y, z, distance, running) — UO.Follow(Any,Any,Any,Any,Any)

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

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

При вызове:

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

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

values =>

                    {

                        FollowStopCondition[] conditions = count == 6

                            ? FollowStopCondition.Parse(values[5], coordinateGoal: true) : Array.Empty<FollowStopCondition>();

                        return new InjectionValue(bridge is IApiCoordinateFollowBridge follow

                            ? follow.FollowPoint(NumberConversions.ToInt(values[0]), NumberConversions.ToInt(values[1]),

                                NumberConversions.ToInt(values[2]), NumberConversions.ToInt(values[3]), ToBoolean(values[4]), conditions) : 0);

                    }

UO.Follow(x, y, z, distance, running, stopConditions) — UO.Follow(Any,Any,Any,Any,Any,Any)

Параметры: x (Any), y (Any), z (Any), distance (Any), running (Any), stopConditions (Any)

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

При вызове:

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

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

values =>

                    {

                        FollowStopCondition[] conditions = count == 6

                            ? FollowStopCondition.Parse(values[5], coordinateGoal: true) : Array.Empty<FollowStopCondition>();

                        return new InjectionValue(bridge is IApiCoordinateFollowBridge follow

                            ? follow.FollowPoint(NumberConversions.ToInt(values[0]), NumberConversions.ToInt(values[1]),

                                NumberConversions.ToInt(values[2]), NumberConversions.ToInt(values[3]), ToBoolean(values[4]), conditions) : 0);

                    }

UO.GetDir

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

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

int UO.GetDir();
int UO.GetDir(object? id);

Читает направление персонажа из модели клиента.

Параметры

  • id — Необязательный объект только в указанных однопараметрических формах: serial числом/hex-строкой, "self", "lasttarget" или имя AddObject. Это не graphic/type. Без аргумента читается собственный персонаж. Перед чтением другого объекта проверяйте UO.Exists; неизвестное имя не открывает прицел.

Возвращает

int — направление mobile без бита бега: 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW. Для неизвестного mobile возвращается 0, которое также означает север.

Поведение

  • Читаются уже полученные локальные данные. Запрос не открывает status и не заставляет сервер прислать обновление. После смерти, перехода карты или удаления объекта значения могут измениться между двумя вызовами.
  • C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

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

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

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

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

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

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

1. Вывести текущее значение своего персонажа — прямой скрипт

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

  • Вызов без аргументов относится к self. Направление персонажа сохраняется в value.
  • Convert.ToString преобразует число для вывода и не меняет смысл результата.
var value = UO.GetDir();
UO.Print("GetDir: " + Convert.ToString(value));

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

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

  • Значение читается один раз без аргументов. Направление персонажа используется в показанном расчёте или условии.
  • Числовые пороги — пример условий скрипта, а не новые пределы клиента. Поле сохраняет серверные единицы и ограничения, описанные выше.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.GetDir();
    if (Truth(value == 2))
    {
        UO.Print("Facing east");
    }

    return null;
}

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

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

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

  • Единственный аргумент выбирает объект lasttarget; его serial должен быть известен клиенту. Graphic/type сюда не передаётся.
  • Данные другого объекта могут быть неизвестны даже при положительном Exists. Для координат предмета в сумке получается позиция контейнера, а не точка мира.
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()
    {
        if (Truth(UO.Exists("lasttarget")))
        {
            var targetValue = UO.GetDir("lasttarget");
            UO.Print("Selected value: " + Convert.ToString(targetValue));
        }
        else
        {
            UO.Print("Target is not loaded");
        }

        return null;
    }

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

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

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

UO.GetDir() — UO.GetDir()

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

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

При вызове:

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

public int GetDir() => GetDir("self");

UO.GetDir(id) — UO.GetDir(Integer)

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

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

При вызове:

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

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

UO.GetDir(id) — UO.GetDir(String)

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

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

При вызове:

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

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

UO.GetDirection

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

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

int UO.GetDirection();
dynamic UO.GetDirection(object? objID);

Читает направление персонажа из модели клиента.

Параметры

  • objID — Необязательный объект только в указанных однопараметрических формах: serial числом/hex-строкой, "self", "lasttarget" или имя AddObject. Это не graphic/type. Без аргумента читается собственный персонаж. Перед чтением другого объекта проверяйте UO.Exists; неизвестное имя не открывает прицел.

Возвращает

int — направление mobile без бита бега: 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW. Для неизвестного mobile возвращается 0, которое также означает север.

Поведение

  • Читаются уже полученные локальные данные. Запрос не открывает status и не заставляет сервер прислать обновление. После смерти, перехода карты или удаления объекта значения могут измениться между двумя вызовами.
  • C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

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

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

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

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

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

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

1. Вывести текущее значение своего персонажа — прямой скрипт

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

  • Вызов без аргументов относится к self. Направление персонажа сохраняется в value.
  • Convert.ToString преобразует число для вывода и не меняет смысл результата.
var value = UO.GetDirection();
UO.Print("GetDirection: " + Convert.ToString(value));

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

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

  • Значение читается один раз без аргументов. Направление персонажа используется в показанном расчёте или условии.
  • Числовые пороги — пример условий скрипта, а не новые пределы клиента. Поле сохраняет серверные единицы и ограничения, описанные выше.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.GetDirection();
    if (Truth(value == 2))
    {
        UO.Print("Facing east");
    }

    return null;
}

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

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

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

  • Единственный аргумент выбирает объект lasttarget; его serial должен быть известен клиенту. Graphic/type сюда не передаётся.
  • Данные другого объекта могут быть неизвестны даже при положительном Exists. Для координат предмета в сумке получается позиция контейнера, а не точка мира.
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()
    {
        if (Truth(UO.Exists("lasttarget")))
        {
            var targetValue = UO.GetDirection("lasttarget");
            UO.Print("Selected value: " + Convert.ToString(targetValue));
        }
        else
        {
            UO.Print("Target is not loaded");
        }

        return null;
    }

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

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

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

UO.GetDirection() — UO.GetDirection()

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

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

При вызове:

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

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

() => bridge.GetDir(bridge.Self)

Создание API: Эти функции создают регистрацию API; они не выполняются заново при каждом вызове команды.

UO.GetDirection(objID) — UO.GetDirection(Any)

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

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

При вызове:

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

case "getdirection": return new InjectionValue(bridge.GetDir(Arg(0)));

UO.GetPathArray

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

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

dynamic UO.GetPathArray(object? xdst, object? ydst, object? optimized, object? accuracy);

Возвращает путь от текущего положения персонажа к X/Y без выполнения движения.

Параметры

  • xdst — Мировая координата X назначения, 0..65535. Это не serial и не позиция внутри гампа.
  • ydst — Мировая координата Y назначения, 0..65535.
  • optimized — true разрешает диагональные переходы; false оставляет четыре прямых направления в этой совместимой форме. Это отличается от смысла Optimized у MoveXY.
  • accuracy — Допуск по X и Y в клетках: оба отклонения должны укладываться в него. Значение ограничивается диапазоном 0..20; 0 требует точных X/Y.

Возвращает

Array из записей [x,y,z], каждое поле — int. [0] внешнего массива — начальная точка; последняя запись находится в заданном допуске цели. Количество шагов равно ArrayLength(path)-1 только для непустого массива. Пустой массив [] означает, что полный допустимый путь не получен (недоступная цель/карта, ограничения или предел поиска). Если начальная точка уже подходит, возвращается одна запись и число шагов равно 0. Частичный путь не возвращается.

Поведение

  • Команда только рассчитывает маршрут; она не запускает движение и не открывает двери. Для исполнения используйте NewMoveXY/MoveXYZ и проверяйте их собственный результат.
  • Поиск обходит препятствия, считая соседние перемещения одинаковыми по стоимости; на неизменной карте ищется путь с наименьшим числом шагов. Проверяется реальная проходимость каждого ребра, включая высоту и ограничения диагоналей клиента.
  • Дальность задаёт UO.LimitMove: по умолчанию 2000, 0 — без предела. Скрытых границ 4096 шагов/узлов и 10000 узлов нет. Работа разбита на порции с возможностью Stop. GetPathArray учитывает числовой порог moveThroughNPC и настройку moveOpenDoor.
  • В клиенте расчёт разбивается на порции до 32 узлов с проверкой бюджета около 1 мс между узлами. Отмена проверяется между порциями. Чтение карты остаётся на игровом потоке; это не обещание фиксированного времени отдельного чтения диска.
  • Карта может измениться после проверки: персонажи перемещаются, двери закрываются, сервер исправляет положение. Полученный массив — план по доступным локальным данным, не подтверждение сервера.
  • SetBadLocation исключает клетки, SetBadObject — зоны вокруг подходящих загруженных предметов мира. Используется снимок списков своего runtime на момент запроса; запреты другого запуска не наследуются. Начальная клетка не проверяется на возможность стоять: она задаётся вызывающим кодом. Нельзя использовать произвольный Z внутри стены как достоверную исходную позицию.
  • Текущая карта и начальные X/Y/Z берутся у персонажа; допуск Z — 255. moveThroughNPC задаёт порог выносливости для прохода через персонажей, moveOpenDoor разрешает план через двери. GetPathArray не открывает двери и не двигает персонажа.

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

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

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

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

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

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

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

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

  • Xdst — пять клеток восточнее; Ydst прежний; Optimized=true; Accuracy=0.
  • count включает начальную точку. Вычитание 1 выполняется только после проверки непустого массива.
var path = UO.GetPathArray(UO.GetX() + 5, UO.GetY(), true, 0);
var count = ArrayLength(path);
if (Truth(count > 0))
{
    UO.Print("Steps: " + Convert.ToString(count - 1));
}
else
{
    UO.Print("Complete path is unavailable");
}

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

2. Перебрать координаты маршрута — функция сценария

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

  • Цель 1445/1690; Optimized=false исключает диагонали; Accuracy=1 разрешает ближайшую клетку в квадрате допуска.
  • point[0]/[1]/[2] — X/Y/Z. Это не graphic, serial или тип поверхности.
return  RunScenario();
 object? RunScenario()
{
    var path = UO.GetPathArray(1445, 1690, false, 1);
    var i = 0;
    while (Truth(i < ArrayLength(path)))
    {
        var point = path[i];
        UO.Print(Convert.ToString(point[0]) + "," + Convert.ToString(point[1]) + "," + Convert.ToString(point[2]));
        i = i + 1;
    }

    return null;
}

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

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

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

  • Первая команда только считает путь. Вторая заново проверяет/исполняет движение, callback=0, timeout=5000.
  • Если нужно просто идти, предварительный GetPathArray не обязателен и добавляет работу.
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();
        var path = UO.GetPathArray(x, y, true, 0);
        if (Truth(ArrayLength(path) > 0))
        {
            var ok = UO.NewMoveXY(x, y, true, 0, false, 0, 5000);
            UO.Print("Movement result: " + Convert.ToString(ok));
        }

        return null;
    }

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

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

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

UO.GetPathArray(xdst, ydst, optimized, accuracy) — UO.GetPathArray(Any,Any,Any,Any)

Параметры: xdst (Any), ydst (Any), optimized (Any), accuracy (Any)

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

При вызове:

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

case "getpatharray":

                    return BuildPortablePath(bridge.GetX(bridge.Self), bridge.GetY(bridge.Self), bridge.GetZ(bridge.Self),

                        Arg(0), Arg(1), bridge.GetZ(bridge.Self), bridge.WorldNumber, Arg(3), 255, Arg(2) != 0, false);

UO.GetPathArray3D

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

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

dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps, object? maxDistance);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps, object? maxDistance, object? avoidMobiles);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps, object? maxDistance, object? avoidMobiles, object? avoidStatics);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps, object? maxDistance, object? avoidMobiles, object? avoidStatics, object? allowDoors);
dynamic UO.GetPathArray3D(object? startX, object? startY, object? startZ, object? finishX, object? finishY, object? finishZ, object? map, object? accuracyXY, object? accuracyZ, object? run, object? maxSteps, object? maxDistance, object? avoidMobiles, object? avoidStatics, object? allowDoors, object? allowDiagonal);

Рассчитывает массив полного пути между двумя точками мира с контролем высоты и дополнительными фильтрами.

Параметры

  • startX — Исходный мировой X, 0..65535.
  • startY — Исходный мировой Y, 0..65535.
  • startZ — Исходная высота -128..127.
  • finishX — Целевой мировой X, 0..65535.
  • finishY — Целевой мировой Y, 0..65535.
  • finishZ — Целевая высота -128..127.
  • map — Номер текущей загруженной карты, например UO.WorldNum(). Другая карта даёт пустой массив, включая совпадающие X/Y/Z.
  • accuracyXY — Допуск по X и Y в клетках: оба отклонения должны укладываться в него. Значение ограничивается диапазоном 0..20; 0 требует точных X/Y.
  • accuracyZ — Допуск высоты: abs(фактическая Z - требуемая Z), ограничивается 0..255. Ноль требует точной высоты; 255 практически отключает ограничение Z.
  • run — Обязательный совместимый флаг бега. Запрос ничего не двигает; в этой форме Optimized всегда true, поэтому run не меняет последовательность клеток или число шагов.
  • Дальность задаёт UO.LimitMove: по умолчанию 2000, 0 — без предела. Скрытых границ 4096 шагов/узлов и 10000 узлов нет. Работа разбита на порции с возможностью Stop. GetPathArray учитывает числовой порог moveThroughNPC и настройку moveOpenDoor.
  • maxSteps — Необязательный предел количества рёбер маршрута без начальной точки. maxSteps > 0 задаёт предел; 0, отсутствие или отрицательное значение не ограничивает количество шагов. UO.LimitMove отдельно проверяет расстояние до цели.
  • maxDistance — Необязательный предел исходного расстояния max(abs(dx),abs(dy)) до цели. 0/отсутствие отключают его. Это не разрешённое отклонение при обходе и не длина найденного пути.
  • avoidMobiles — true исключает X/Y загруженных персонажей, кроме self, по снимку в начале вызова; высота этого фильтра не учитывается. По умолчанию false. Обычная проверка проходимости клиента всё равно действует.
  • avoidStatics — true исключает клетку с любой записью static, даже проходимой или на другой высоте. По умолчанию false. Это строгий фильтр, а не только запрет непроходимых стен.
  • allowDoors — true допускает предварительный путь через клетку найденной двери, даже если закрытая дверь не пропускает обычную проверку. По умолчанию false. Дверь не открывается; доступ, Z и проходимость при исполнении надо проверять заново.
  • allowDiagonal — true/отсутствие разрешает восемь направлений с проверкой углов; false — только четыре прямых направления.

Возвращает

Array из записей [x,y,z], каждое поле — int. [0] внешнего массива — начальная точка; последняя запись находится в заданном допуске цели. Количество шагов равно ArrayLength(path)-1 только для непустого массива. Пустой массив [] означает, что полный допустимый путь не получен (недоступная цель/карта, ограничения или предел поиска). Если начальная точка уже подходит, возвращается одна запись и число шагов равно 0. Частичный путь не возвращается.

Поведение

  • Команда только рассчитывает маршрут; она не запускает движение и не открывает двери. Для исполнения используйте NewMoveXY/MoveXYZ и проверяйте их собственный результат.
  • Поиск обходит препятствия, считая соседние перемещения одинаковыми по стоимости; на неизменной карте ищется путь с наименьшим числом шагов. Проверяется реальная проходимость каждого ребра, включая высоту и ограничения диагоналей клиента.
  • Дальность задаёт UO.LimitMove: по умолчанию 2000, 0 — без предела. Скрытых границ 4096 шагов/узлов и 10000 узлов нет. Работа разбита на порции с возможностью Stop. GetPathArray учитывает числовой порог moveThroughNPC и настройку moveOpenDoor.
  • В клиенте расчёт разбивается на порции до 32 узлов с проверкой бюджета около 1 мс между узлами. Отмена проверяется между порциями. Чтение карты остаётся на игровом потоке; это не обещание фиксированного времени отдельного чтения диска.
  • Карта может измениться после проверки: персонажи перемещаются, двери закрываются, сервер исправляет положение. Полученный массив — план по доступным локальным данным, не подтверждение сервера.
  • SetBadLocation исключает клетки, SetBadObject — зоны вокруг подходящих загруженных предметов мира. Используется снимок списков своего runtime на момент запроса; запреты другого запуска не наследуются. Начальная клетка не проверяется на возможность стоять: она задаётся вызывающим кодом. Нельзя использовать произвольный Z внутри стены как достоверную исходную позицию.

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

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

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

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

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

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

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

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

  • Первые три значения — исходные X/Y/Z; следующие три — назначение.
  • map=WorldNum(), accuracyXY=0, accuracyZ=0 требуют точной позиции. run=false не запускает ходьбу.
var x = UO.GetX();
var y = UO.GetY();
var z = UO.GetZ();
var path = UO.GetPathArray3D(x, y, z, x + 4, y, z, UO.WorldNum(), 0, 0, false);
if (Truth(ArrayLength(path) > 0))
{
    UO.Print("Steps: " + Convert.ToString(ArrayLength(path) - 1));
}

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

2. Все параметры с фильтрами — функция сценария

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

  • Цель 1445/1690/20; accuracyXY=1, accuracyZ=2; run=true остаётся флагом совместимости.
  • maxSteps=80, maxDistance=30; avoidMobiles=true, avoidStatics=false, allowDoors=true, allowDiagonal=false. Массив может быть пустым.
  • Разрешение дверей является предположением для планирования; гарантии открытия и прохождения нет.
return  RunScenario();
 object? RunScenario()
{
    var path = UO.GetPathArray3D(UO.GetX(), UO.GetY(), UO.GetZ(), 1445, 1690, 20, UO.WorldNum(), 1, 2, true, 80, 30, true, false, true, false);
    UO.Print("Points: " + Convert.ToString(ArrayLength(path)));
    return null;
}

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

3. Прочитать последнюю достигнутую точку — класс сценария

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

  • accuracyXY=2/accuracyZ=5 разрешают ближайшую подходящую точку; maxSteps=100.
  • last — последняя запись плана, а не текущее положение персонажа. Команда не перемещает его.
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 path = UO.GetPathArray3D(UO.GetX(), UO.GetY(), UO.GetZ(), 1445, 1690, 0, UO.WorldNum(), 2, 5, false, 100);
        var count = ArrayLength(path);
        if (Truth(count > 0))
        {
            var last = path[count - 1];
            UO.Print("X=" + Convert.ToString(last[0]) + " Y=" + Convert.ToString(last[1]) + " Z=" + Convert.ToString(last[2]));
        }

        return null;
    }

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

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

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

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Параметры: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any)

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

При вызове:

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

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

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Параметры: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any)

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

При вызове:

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

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

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps, maxDistance) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Параметры: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any), maxDistance (Any)

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

При вызове:

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

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

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps, maxDistance, avoidMobiles) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Параметры: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any), maxDistance (Any), avoidMobiles (Any)

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

При вызове:

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

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

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps, maxDistance, avoidMobiles, avoidStatics) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Параметры: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any), maxDistance (Any), avoidMobiles (Any), avoidStatics (Any)

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

При вызове:

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

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

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps, maxDistance, avoidMobiles, avoidStatics, allowDoors) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Параметры: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any), maxDistance (Any), avoidMobiles (Any), avoidStatics (Any), allowDoors (Any)

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

При вызове:

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

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

values => CompactGetPathArray3D(values)

UO.GetPathArray3D(startX, startY, startZ, finishX, finishY, finishZ, map, accuracyXY, accuracyZ, run, maxSteps, maxDistance, avoidMobiles, avoidStatics, allowDoors, allowDiagonal) — UO.GetPathArray3D(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Параметры: startX (Any), startY (Any), startZ (Any), finishX (Any), finishY (Any), finishZ (Any), map (Any), accuracyXY (Any), accuracyZ (Any), run (Any), maxSteps (Any), maxDistance (Any), avoidMobiles (Any), avoidStatics (Any), allowDoors (Any), allowDiagonal (Any)

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

При вызове:

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

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

values => CompactGetPathArray3D(values)

UO.GetRun

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

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

int UO.GetRun();
int UO.GetRun(object? id);

Проверяет флаг бега в последнем известном направлении mobile.

Параметры

  • id — Обязательный serial/ID конкретного объекта: int, hex-строка либо алиас self, backpack, lasttarget, lastobject, lastcontainer, laststatus, finditem, lastcorpse или имя AddObject. Это не graphic/type. Неустановленное имя разрешается в 0; никакой новый target команда не открывает. У GetRun также есть форма GetRun() для self.

Возвращает

int 1 — загруженный mobile имеет признак Direction.Running. int 0 — признак отсутствует, объект не является mobile, неизвестен или удалён. Последний флаг бега может сохраниться после остановки. Это не активность маршрута, не скорость и не количество оставшихся шагов. Для движения self используйте также Moving().

Результат команды — числовой флаг: 1 означает выполненное условие, 0 — невыполненное. После var result = команда(...) проверяйте if (result != 0) или if (result == 0). Сохраните результат одного вызова: повторный вызов может выполнить действие снова либо прочитать уже изменившееся состояние.

Поведение

  • Читается локальная модель клиента; запросов серверу, ожидания и перемещения нет.
  • Результат относится к моменту чтения. После UO.Wait или другого действия объект и его флаги могут измениться.
  • Последний флаг бега может сохраниться после остановки. Это не активность маршрута, не скорость и не количество оставшихся шагов. Для движения self используйте также Moving().

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

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

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

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

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

var result = UO.GetRun("self");
UO.Print("GetRun: " + Convert.ToString(result));

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

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

  • Аргумент self явно выбирает своего персонажа. state — только 1/0.
  • Последний флаг бега может сохраниться после остановки. Это не активность маршрута, не скорость и не количество оставшихся шагов. Для движения self используйте также Moving().
var state = UO.GetRun("self");
var moving = UO.Moving();
UO.Print("Running flag: " + Convert.ToString(state));
UO.Print("Self movement active: " + Convert.ToString(moving));

2. Проверить выбранного mobile — функция сценария

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

  • IsNpc исключает предмет и неизвестный объект. target сохраняет один serial, а не живую ссылку на меняющийся lasttarget.
  • Результат относится к полю Direction.Running. Данные обновляются только после получения соответствующего состояния клиентом.
return  RunScenario();
 object? RunScenario()
{
    var target = UO.GetSerial("lasttarget");
    if (Truth(UO.IsNPC(target)))
    {
        var state = UO.GetRun(target);
        UO.Print("Selected mobile state 1/0: " + Convert.ToString(state));
    }
    else
    {
        UO.Print("No loaded mobile selected");
    }

    return null;
}

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

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

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

  • UO.Wait(500) — пауза в миллисекундах. После неё отдельно проверяется, что mobile ещё существует.
  • Сравниваются два снимка. Промежуточные изменения могут быть пропущены, и это не непрерывная подписка на серверные события.
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 target = UO.GetSerial("lasttarget");
        if (Truth(UO.IsNPC(target)))
        {
            var before = UO.GetRun(target);
            await Delay(500);
            if (Truth(UO.IsNPC(target)))
            {
                var after = UO.GetRun(target);
                if (Truth(before != after))
                {
                    UO.Print("Flag changed: " + Convert.ToString(before) + " -> " + Convert.ToString(after));
                }
            }
            else
            {
                UO.Print("Mobile left the local world");
            }
        }

        return null;
    }

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

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

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

UO.GetRun() — UO.GetRun()

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

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

При вызове:

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

public int GetRun() => bridge.GetRun(bridge.Self);

UO.GetRun(id) — UO.GetRun(Any)

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

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

При вызове:

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

public int GetRun(InjectionValue id) => bridge.GetRun(GetObject(id));

UO.GetRunMountTimer

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

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

dynamic UO.GetRunMountTimer();

Показывает настроенный интервал одного шага бега верхом в миллисекундах. Полезна для проверки режима, оценки времени и сохранения настройки перед временным замедлением.

Параметры

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

Возвращает

int от 100 до 2000 включительно — настроенный интервал в миллисекундах. По умолчанию 100. Это число времени, не true/false, не ID и не количество пройденных клеток.

Поведение

  • Настройка относится к режиму бега верхом. Стандартное и минимально разрешённое значение — 100 мс; верхняя граница — 2000 мс. Остальные три режима имеют отдельные настройки.
  • Это локальный интервал движения персонажа, а не ping, FPS, тайм-аут поиска пути или измеренная длительность серверного шага. Увеличение числа замедляет движение; уменьшение ниже стандартного интервала не ускоряет отправку пакетов.
  • Команда сама не начинает движение, не садится на ездовое животное и не меняет режим ходьбы/бега. Режим выбирается при движении; заданный сервером режим скорости и полёт также учитываются клиентом.
  • Настройка общая для движения этого клиента: её могут использовать ручное управление, маршрут карты и другие скрипты. Временно меняя её, сохраните прежнее значение и восстановите после операции; не меняйте один режим одновременно из нескольких процедур.
  • Поворот и отклонённый шаг отличаются от обычного перемещения. Серверное подтверждение, задержки связи и препятствия могут увеличить фактическое время. Клиент не отправляет серию ускоренных шагов, чтобы догнать пропущенные кадры.

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

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

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

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

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

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

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

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

  • UO.GetRunMountTimer() вызывается без аргументов. delayMs — интервал именно бега верхом; другие режимы здесь не измеряются.
var delayMs = UO.GetRunMountTimer();
UO.Print("Movement delay, ms: " + Convert.ToString(delayMs));

2. Оценить вклад задержек в короткий маршрут — функция сценария

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

  • steps=5 — число шагов для оценки, а не параметр команды. Умножение даёт только вклад настроенных задержек; это не обещание времени прибытия и не тайм-аут маршрута.
return  RunScenario();
 object? RunScenario()
{
    var steps = 5;
    var delayMs = UO.GetRunMountTimer();
    var estimateMs = steps * delayMs;
    UO.Print("Step-delay budget, ms: " + Convert.ToString(estimateMs));
    return null;
}

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

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

  • previous сравнивается с 100 мс. Устанавливается стандартный интервал, остальные три режима сохраняются. Персонаж никуда не движется от самого вызова.
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 previous = UO.GetRunMountTimer();
        if (Truth(previous > 100))
        {
            UO.SetRunMountTimer(100);
        }

        return null;
    }

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

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

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

UO.GetRunMountTimer() — UO.GetRunMountTimer()

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

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

При вызове:

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

case "getrunmounttimer": return new InjectionValue(state.RunMountTimer);

UO.GetRunUnMountTimer

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

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

dynamic UO.GetRunUnMountTimer();

Показывает настроенный интервал одного шага бега пешком в миллисекундах. Полезна для проверки режима, оценки времени и сохранения настройки перед временным замедлением.

Параметры

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

Возвращает

int от 200 до 2000 включительно — настроенный интервал в миллисекундах. По умолчанию 200. Это число времени, не true/false, не ID и не количество пройденных клеток.

Поведение

  • Настройка относится к режиму бега пешком. Стандартное и минимально разрешённое значение — 200 мс; верхняя граница — 2000 мс. Остальные три режима имеют отдельные настройки.
  • Это локальный интервал движения персонажа, а не ping, FPS, тайм-аут поиска пути или измеренная длительность серверного шага. Увеличение числа замедляет движение; уменьшение ниже стандартного интервала не ускоряет отправку пакетов.
  • Команда сама не начинает движение, не садится на ездовое животное и не меняет режим ходьбы/бега. Режим выбирается при движении; заданный сервером режим скорости и полёт также учитываются клиентом.
  • Настройка общая для движения этого клиента: её могут использовать ручное управление, маршрут карты и другие скрипты. Временно меняя её, сохраните прежнее значение и восстановите после операции; не меняйте один режим одновременно из нескольких процедур.
  • Поворот и отклонённый шаг отличаются от обычного перемещения. Серверное подтверждение, задержки связи и препятствия могут увеличить фактическое время. Клиент не отправляет серию ускоренных шагов, чтобы догнать пропущенные кадры.

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

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

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

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

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

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

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

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

  • UO.GetRunUnmountTimer() вызывается без аргументов. delayMs — интервал именно бега пешком; другие режимы здесь не измеряются.
var delayMs = UO.GetRunUnMountTimer();
UO.Print("Movement delay, ms: " + Convert.ToString(delayMs));

2. Оценить вклад задержек в короткий маршрут — функция сценария

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

  • steps=5 — число шагов для оценки, а не параметр команды. Умножение даёт только вклад настроенных задержек; это не обещание времени прибытия и не тайм-аут маршрута.
return  RunScenario();
 object? RunScenario()
{
    var steps = 5;
    var delayMs = UO.GetRunUnMountTimer();
    var estimateMs = steps * delayMs;
    UO.Print("Step-delay budget, ms: " + Convert.ToString(estimateMs));
    return null;
}

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

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

  • previous сравнивается с 200 мс. Устанавливается стандартный интервал, остальные три режима сохраняются. Персонаж никуда не движется от самого вызова.
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 previous = UO.GetRunUnMountTimer();
        if (Truth(previous > 200))
        {
            UO.SetRunUnmountTimer(200);
        }

        return null;
    }

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

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

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

UO.GetRunUnMountTimer() — UO.GetRunUnMountTimer()

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

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

При вызове:

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

case "getrununmounttimer": return new InjectionValue(state.RunUnmountTimer);

UO.GetWalkMountTimer

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

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

dynamic UO.GetWalkMountTimer();

Показывает настроенный интервал одного шага ходьбы верхом в миллисекундах. Полезна для проверки режима, оценки времени и сохранения настройки перед временным замедлением.

Параметры

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

Возвращает

int от 200 до 2000 включительно — настроенный интервал в миллисекундах. По умолчанию 200. Это число времени, не true/false, не ID и не количество пройденных клеток.

Поведение

  • Настройка относится к режиму ходьбы верхом. Стандартное и минимально разрешённое значение — 200 мс; верхняя граница — 2000 мс. Остальные три режима имеют отдельные настройки.
  • Это локальный интервал движения персонажа, а не ping, FPS, тайм-аут поиска пути или измеренная длительность серверного шага. Увеличение числа замедляет движение; уменьшение ниже стандартного интервала не ускоряет отправку пакетов.
  • Команда сама не начинает движение, не садится на ездовое животное и не меняет режим ходьбы/бега. Режим выбирается при движении; заданный сервером режим скорости и полёт также учитываются клиентом.
  • Настройка общая для движения этого клиента: её могут использовать ручное управление, маршрут карты и другие скрипты. Временно меняя её, сохраните прежнее значение и восстановите после операции; не меняйте один режим одновременно из нескольких процедур.
  • Поворот и отклонённый шаг отличаются от обычного перемещения. Серверное подтверждение, задержки связи и препятствия могут увеличить фактическое время. Клиент не отправляет серию ускоренных шагов, чтобы догнать пропущенные кадры.
  • В обычном клиентском host эти данные состояния берутся из GetPersistentState менеджера и общие для скриптов/чата/макросов одного мира/профиля, а не принадлежат одному скрипту. Другой процесс или явно отдельный InjectionRuntimeState имеет другое состояние. Загрузка/очистка профиля может его заменить; сохранённые serial всё равно проверяются по загруженному миру.

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

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

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

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

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

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

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

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

  • UO.GetWalkMountTimer() вызывается без аргументов. delayMs — интервал именно ходьбы верхом; другие режимы здесь не измеряются.
var delayMs = UO.GetWalkMountTimer();
UO.Print("Movement delay, ms: " + Convert.ToString(delayMs));

2. Оценить вклад задержек в короткий маршрут — функция сценария

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

  • steps=5 — число шагов для оценки, а не параметр команды. Умножение даёт только вклад настроенных задержек; это не обещание времени прибытия и не тайм-аут маршрута.
return  RunScenario();
 object? RunScenario()
{
    var steps = 5;
    var delayMs = UO.GetWalkMountTimer();
    var estimateMs = steps * delayMs;
    UO.Print("Step-delay budget, ms: " + Convert.ToString(estimateMs));
    return null;
}

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

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

  • previous сравнивается с 200 мс. Устанавливается стандартный интервал, остальные три режима сохраняются. Персонаж никуда не движется от самого вызова.
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 previous = UO.GetWalkMountTimer();
        if (Truth(previous > 200))
        {
            UO.SetWalkMountTimer(200);
        }

        return null;
    }

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

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

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

UO.GetWalkMountTimer() — UO.GetWalkMountTimer()

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

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

При вызове:

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

case "getwalkmounttimer": return new InjectionValue(state.WalkMountTimer);

UO.GetWalkUnmountTimer

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

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

dynamic UO.GetWalkUnmountTimer();

Показывает настроенный интервал одного шага ходьбы пешком в миллисекундах. Полезна для проверки режима, оценки времени и сохранения настройки перед временным замедлением.

Параметры

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

Возвращает

int от 400 до 2000 включительно — настроенный интервал в миллисекундах. По умолчанию 400. Это число времени, не true/false, не ID и не количество пройденных клеток.

Поведение

  • Настройка относится к режиму ходьбы пешком. Стандартное и минимально разрешённое значение — 400 мс; верхняя граница — 2000 мс. Остальные три режима имеют отдельные настройки.
  • Это локальный интервал движения персонажа, а не ping, FPS, тайм-аут поиска пути или измеренная длительность серверного шага. Увеличение числа замедляет движение; уменьшение ниже стандартного интервала не ускоряет отправку пакетов.
  • Команда сама не начинает движение, не садится на ездовое животное и не меняет режим ходьбы/бега. Режим выбирается при движении; заданный сервером режим скорости и полёт также учитываются клиентом.
  • Настройка общая для движения этого клиента: её могут использовать ручное управление, маршрут карты и другие скрипты. Временно меняя её, сохраните прежнее значение и восстановите после операции; не меняйте один режим одновременно из нескольких процедур.
  • Поворот и отклонённый шаг отличаются от обычного перемещения. Серверное подтверждение, задержки связи и препятствия могут увеличить фактическое время. Клиент не отправляет серию ускоренных шагов, чтобы догнать пропущенные кадры.
  • В обычном клиентском host эти данные состояния берутся из GetPersistentState менеджера и общие для скриптов/чата/макросов одного мира/профиля, а не принадлежат одному скрипту. Другой процесс или явно отдельный InjectionRuntimeState имеет другое состояние. Загрузка/очистка профиля может его заменить; сохранённые serial всё равно проверяются по загруженному миру.

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

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

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

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

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

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

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

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

  • UO.GetWalkUnmountTimer() вызывается без аргументов. delayMs — интервал именно ходьбы пешком; другие режимы здесь не измеряются.
var delayMs = UO.GetWalkUnmountTimer();
UO.Print("Movement delay, ms: " + Convert.ToString(delayMs));

2. Оценить вклад задержек в короткий маршрут — функция сценария

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

  • steps=5 — число шагов для оценки, а не параметр команды. Умножение даёт только вклад настроенных задержек; это не обещание времени прибытия и не тайм-аут маршрута.
return  RunScenario();
 object? RunScenario()
{
    var steps = 5;
    var delayMs = UO.GetWalkUnmountTimer();
    var estimateMs = steps * delayMs;
    UO.Print("Step-delay budget, ms: " + Convert.ToString(estimateMs));
    return null;
}

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

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

  • previous сравнивается с 400 мс. Устанавливается стандартный интервал, остальные три режима сохраняются. Персонаж никуда не движется от самого вызова.
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 previous = UO.GetWalkUnmountTimer();
        if (Truth(previous > 400))
        {
            UO.SetWalkUnmountTimer(400);
        }

        return null;
    }

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

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

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

UO.GetWalkUnmountTimer() — UO.GetWalkUnmountTimer()

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

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

При вызове:

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

case "getwalkunmounttimer": return new InjectionValue(state.WalkUnmountTimer);

UO.IsMoving

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

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

int UO.IsMoving();

Проверяет движение своего персонажа.

Параметры

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

Возвращает

int bool (1/0): 1 — активен автоматический Pathfinder либо в очереди персонажа ещё есть шаги; 0 — оба отсутствуют или персонаж не загружен. Это не подтверждение достижения цели и не количество шагов.

Результат команды — числовой флаг: 1 означает выполненное условие, 0 — невыполненное. После var result = команда(...) проверяйте if (result != 0) или if (result == 0). Сохраните результат одного вызова: повторный вызов может выполнить действие снова либо прочитать уже изменившееся состояние.

Поведение

  • Читаются уже полученные локальные данные. Запрос не открывает status и не заставляет сервер прислать обновление. После смерти, перехода карты или удаления объекта значения могут измениться между двумя вызовами.
  • C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

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

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

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

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

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

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

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

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

  • Пустые скобки читают self. active — число 1 или 0; текст сообщения служит примером обработки ветвей.
  • 1 — активен автоматический Pathfinder либо в очереди персонажа ещё есть шаги; 0 — оба отсутствуют или персонаж не загружен. Это не подтверждение достижения цели и не количество шагов.
var active = UO.IsMoving();
if (Truth(active))
{
    UO.Print("State is active");
}
else
{
    UO.Print("State is inactive or unavailable");
}

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

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

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

  • У команды нет аргумента объекта: даже после Exists(self) она читает только собственное состояние.
  • Exists(self) проверяет загруженность игрока отдельно от запрашиваемого флага. Между проверками мир может измениться.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Exists("self")))
    {
        var state = UO.IsMoving();
        UO.Print("State 1/0: " + Convert.ToString(state));
    }

    return null;
}

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

3. Заметить изменение состояния без бесконечного ожидания — класс сценария

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

  • Два вызова без аргументов читают self; UO.Wait(500) — пауза полсекунды.
  • Сравниваются два снимка флага. Переходы между снимками могут быть пропущены; это не подписка на все серверные события.
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.IsMoving();
        await Delay(500);
        var after = UO.IsMoving();
        if (Truth(before != after))
        {
            UO.Print("State changed from " + Convert.ToString(before) + " to " + Convert.ToString(after));
        }

        return null;
    }

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

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

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

UO.IsMoving() — UO.IsMoving()

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

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

При вызове:

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

public int IsMoving() => bridge.IsMoving();

UO.IsRunning

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

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

int UO.IsRunning(object? objID);

Проверяет флаг бега в последнем известном направлении mobile.

Параметры

  • objID — Обязательный serial/ID конкретного объекта: int, hex-строка либо алиас self, backpack, lasttarget, lastobject, lastcontainer, laststatus, finditem, lastcorpse или имя AddObject. Это не graphic/type. Неустановленное имя разрешается в 0; никакой новый target команда не открывает. Аргумент обязателен; для себя передайте self.

Возвращает

int 1 — загруженный mobile имеет признак Direction.Running. int 0 — признак отсутствует, объект не является mobile, неизвестен или удалён. Последний флаг бега может сохраниться после остановки. Это не активность маршрута, не скорость и не количество оставшихся шагов. Для движения self используйте также Moving().

Результат команды — числовой флаг: 1 означает выполненное условие, 0 — невыполненное. После var result = команда(...) проверяйте if (result != 0) или if (result == 0). Сохраните результат одного вызова: повторный вызов может выполнить действие снова либо прочитать уже изменившееся состояние.

Поведение

  • Читается локальная модель клиента; запросов серверу, ожидания и перемещения нет.
  • Результат относится к моменту чтения. После UO.Wait или другого действия объект и его флаги могут измениться.
  • Последний флаг бега может сохраниться после остановки. Это не активность маршрута, не скорость и не количество оставшихся шагов. Для движения self используйте также Moving().

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

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

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

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

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

var result = UO.IsRunning("self");
UO.Print("IsRunning: " + Convert.ToString(result));

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

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

  • Аргумент self явно выбирает своего персонажа. state — только 1/0.
  • Последний флаг бега может сохраниться после остановки. Это не активность маршрута, не скорость и не количество оставшихся шагов. Для движения self используйте также Moving().
var state = UO.IsRunning("self");
var moving = UO.Moving();
UO.Print("Running flag: " + Convert.ToString(state));
UO.Print("Self movement active: " + Convert.ToString(moving));

2. Проверить выбранного mobile — функция сценария

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

  • IsNpc исключает предмет и неизвестный объект. target сохраняет один serial, а не живую ссылку на меняющийся lasttarget.
  • Результат относится к полю Direction.Running. Данные обновляются только после получения соответствующего состояния клиентом.
return  RunScenario();
 object? RunScenario()
{
    var target = UO.GetSerial("lasttarget");
    if (Truth(UO.IsNPC(target)))
    {
        var state = UO.IsRunning(target);
        UO.Print("Selected mobile state 1/0: " + Convert.ToString(state));
    }
    else
    {
        UO.Print("No loaded mobile selected");
    }

    return null;
}

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

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

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

  • UO.Wait(500) — пауза в миллисекундах. После неё отдельно проверяется, что mobile ещё существует.
  • Сравниваются два снимка. Промежуточные изменения могут быть пропущены, и это не непрерывная подписка на серверные события.
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 target = UO.GetSerial("lasttarget");
        if (Truth(UO.IsNPC(target)))
        {
            var before = UO.IsRunning(target);
            await Delay(500);
            if (Truth(UO.IsNPC(target)))
            {
                var after = UO.IsRunning(target);
                if (Truth(before != after))
                {
                    UO.Print("Flag changed: " + Convert.ToString(before) + " -> " + Convert.ToString(after));
                }
            }
            else
            {
                UO.Print("Mobile left the local world");
            }
        }

        return null;
    }

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

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

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

UO.IsRunning(objID) — UO.IsRunning(Any)

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

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

При вызове:

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

case "isrunning": return new InjectionValue(bridge.GetRun(Arg(0, bridge.Self)));

UO.LastStepQUsedDoor

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

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

dynamic UO.LastStepQUsedDoor();
dynamic UO.LastStepQUsedDoor(object? value);

Читает либо вручную изменяет отметку попытки открытия двери последней командой StepQ.

Параметры

  • value — Необязательное целое. С аргументом сохраняется ровно это число; без аргумента выполняется чтение.

Возвращает

int — сохранённая отметка. Обычный StepQ сбрасывает её в 0 и при включённом moveOpenDoor записывает результат TryOpenDoorForStep: 1 при обнаруженной попытке, 0 иначе. Ручная форма допускает и другие числа. Это не serial двери и не подтверждение её открытия.

Поведение

  • Проверка не читает состояние двери с сервера. Резервный вызов OpenDoor не меняет нулевую отметку.
  • При раннем отказе StepQ из-за соединения/выносливости сброс ещё не выполняется, поэтому может остаться предыдущее значение.
  • В обычном клиентском host эти данные состояния берутся из GetPersistentState менеджера и общие для скриптов/чата/макросов одного мира/профиля, а не принадлежат одному скрипту. Другой процесс или явно отдельный InjectionRuntimeState имеет другое состояние. Загрузка/очистка профиля может его заменить; сохранённые serial всё равно проверяются по загруженному миру.

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

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

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

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

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

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

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

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

  • Без аргументов читается сохранённое число.
  • Не используйте его как ID для UseObject.
UO.Print(Convert.ToString(UO.LastStepQUsedDoor()));

2. Сбросить перед попыткой шага — функция сценария

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

  • value=0 очищает прежнюю отметку. direction=2 — E; run=false.
  • Результат StepQ и отметка двери имеют разные значения.
return  RunScenario();
 object? RunScenario()
{
    UO.LastStepQUsedDoor(0);
    var status = UO.StepQ(2, false);
    UO.Print(Convert.ToString(UO.LastStepQUsedDoor()));
    return null;
}

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

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

  • previous — сохранённое значение.
  • Ручное восстановление не выполняет никаких действий с дверью.
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 previous = UO.LastStepQUsedDoor();
        UO.LastStepQUsedDoor(0);
        UO.Print(Convert.ToString(UO.LastStepQUsedDoor()));
        UO.LastStepQUsedDoor(previous);
        return null;
    }
}

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

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

UO.LastStepQUsedDoor() — UO.LastStepQUsedDoor()

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

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

При вызове:

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

case "laststepquseddoor":

                    if (arguments.Length > 0) state.LastStepUsedDoor = Arg(0);

                    return new InjectionValue(state.LastStepUsedDoor);

UO.LastStepQUsedDoor(value) — UO.LastStepQUsedDoor(Any)

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

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

При вызове:

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

case "laststepquseddoor":

                    if (arguments.Length > 0) state.LastStepUsedDoor = Arg(0);

                    return new InjectionValue(state.LastStepUsedDoor);

UO.Move

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

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

int UO.Move();

Читает, есть ли автоматический маршрут или ещё не завершённые шаги персонажа.

Параметры

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

Возвращает

int 1 — активен Pathfinder либо в очереди анимации персонажа остаются шаги; 0 — оба отсутствуют или персонаж не загружен. Это не число шагов, не результат достижения предыдущей цели и не признак удержания мыши.

Результат команды — числовой флаг: 1 означает выполненное условие, 0 — невыполненное. После var result = команда(...) проверяйте if (result != 0) или if (result == 0). Сохраните результат одного вызова: повторный вызов может выполнить действие снова либо прочитать уже изменившееся состояние.

Поведение

  • Команда только читает состояние. При ненулевом результате обновляется совместимый таймер TicksAnim. Учитываются и шаги, запрошенные мышью/клавишами, пока они остаются в очереди.
  • Для остановки автоматического маршрута используйте MoverStop. MoveOff управляет другими, клавишными шагами.

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

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

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

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

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

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

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

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

  • Аргументов нет.
  • 0 не доказывает, что цель достигнута: маршрут мог быть отменён.
UO.Print("Movement active or queued: " + Convert.ToString(UO.Move()));

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

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

  • 100 ожиданий по 50 мс задают приблизительный предел 5 секунд.
  • Выполнение этой проверки само не запускает и не останавливает движение.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var attempts = 0;
    while (Truth(UO.Move()) && Truth(attempts < 100))
    {
        await Delay(50);
        attempts = attempts + 1;
    }

    UO.Print("Still moving: " + Convert.ToString(UO.Move()));
    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;

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

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

  • Move() проверяет активность, MoverStop() снимает маршрут.
  • Уже отправленные пакеты могут ещё подтверждаться сервером.
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()
    {
        if (Truth(UO.Move()))
        {
            UO.MoverStop();
        }

        return null;
    }

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

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

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

UO.Move() — UO.Move()

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

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

При вызове:

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

public int Move()

        {

            int result = bridge.Move();

            if (result != 0)

                ticksAnim = Timer();

            return result;

        }

UO.MoveOff

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

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

void UO.MoveOff();

Запрещает совместимые клавишные шаги PMove.

Параметры

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

Возвращает

void — возвращаемого значения нет. Вызывайте отдельной строкой; это не true/false и не число шагов.

Поведение

  • Меняет флаг MoveEnabled в состоянии runtime. Это не универсальная блокировка персонажа: NewMoveXY, MoveXYZ, Step и мышь не управляются этим флагом.
  • MoveOff не останавливает уже работающий Pathfinder; для него нужна MoverStop.
  • В обычном клиентском host эти данные состояния берутся из GetPersistentState менеджера и общие для скриптов/чата/макросов одного мира/профиля, а не принадлежат одному скрипту. Другой процесс или явно отдельный InjectionRuntimeState имеет другое состояние. Загрузка/очистка профиля может его заменить; сохранённые serial всё равно проверяются по загруженному миру.

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

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

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

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

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

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

1. Изменить разрешение клавишных шагов — прямой скрипт

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

  • Аргументов нет.
  • Изменяется флаг PMove, без возвращаемого значения.
UO.MoveOff();

2. Явно разрешить следующий PMove — функция сценария

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

  • MoveOn включает клавишные шаги перед PMove; MoveOff выключает после его обычного завершения.
  • Это последовательные команды; выключенный флаг не является аварийной остановкой всех процедур.
return  RunScenario();
 object? RunScenario()
{
    UO.MoveOn();
    UO.PMove(UO.GetX() + 1, UO.GetY());
    UO.MoveOff();
    return null;
}

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

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

  • Две команды управляют разными механизмами движения.
  • Move() читает автоматический маршрут; не считайте его проверкой MoveEnabled.
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.MoveOff();
        UO.MoverStop();
        UO.Print(Convert.ToString(UO.Move()));
        return null;
    }
}

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

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

UO.MoveOff() — UO.MoveOff()

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

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

При вызове:

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

public void MoveOff() => bridge.EnableMove(false);

UO.MoveOn

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

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

void UO.MoveOn();

Разрешает совместимые клавишные шаги PMove.

Параметры

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

Возвращает

void — возвращаемого значения нет. Вызывайте отдельной строкой; это не true/false и не число шагов.

Поведение

  • Меняет флаг MoveEnabled в состоянии runtime. Это не универсальная блокировка персонажа: NewMoveXY, MoveXYZ, Step и мышь не управляются этим флагом.
  • MoveOff не останавливает уже работающий Pathfinder; для него нужна MoverStop.
  • В обычном клиентском host эти данные состояния берутся из GetPersistentState менеджера и общие для скриптов/чата/макросов одного мира/профиля, а не принадлежат одному скрипту. Другой процесс или явно отдельный InjectionRuntimeState имеет другое состояние. Загрузка/очистка профиля может его заменить; сохранённые serial всё равно проверяются по загруженному миру.

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

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

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

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

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

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

1. Изменить разрешение клавишных шагов — прямой скрипт

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

  • Аргументов нет.
  • Изменяется флаг PMove, без возвращаемого значения.
UO.MoveOn();

2. Явно разрешить следующий PMove — функция сценария

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

  • MoveOn включает клавишные шаги перед PMove; MoveOff выключает после его обычного завершения.
  • Это последовательные команды; выключенный флаг не является аварийной остановкой всех процедур.
return  RunScenario();
 object? RunScenario()
{
    UO.MoveOn();
    UO.PMove(UO.GetX() + 1, UO.GetY());
    UO.MoveOff();
    return null;
}

3. Восстановить клавишное движение перед PMove — класс сценария

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

  • MoveOn разрешает совместимые клавишные шаги PMove и не возвращает значение. Результат перемещения проверяется по координатам; MoveOn не управляет всеми способами движения.
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.MoveOn();
        int destinationX = UO.GetX() + 1;
        int destinationY = UO.GetY();
        UO.PMove(destinationX, destinationY);
        UO.Print($"Reached requested tile: {UO.GetX() == destinationX && UO.GetY() == destinationY}");
        return null;
    }
}

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

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

UO.MoveOn() — UO.MoveOn()

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

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

При вызове:

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

public void MoveOn() => bridge.EnableMove(true);

UO.MoveXY

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

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

dynamic UO.MoveXY(object? xdst, object? ydst, object? optimized, object? accuracy, object? running);

Перемещает персонажа к X/Y с пятью обязательными параметрами и ожидает результат.

Параметры

  • xdst — Мировая координата X назначения, 0..65535. Это не serial и не позиция внутри гампа.
  • ydst — Мировая координата Y назначения, 0..65535.
  • optimized — true — обычный режим поиска и проверки пути вперёд; false — уменьшенная эвристика и проверка ближайшего шага. false не отключает обход препятствий.
  • accuracy — Допуск по X и Y в клетках: оба отклонения должны укладываться в него. Значение ограничивается диапазоном 0..20; 0 требует точных X/Y.
  • running — true/1 — запрос бега, false/0 — шаг. Серверные задержки движения сохраняются; это не множитель скорости.

Возвращает

int 1 — в конце проверки персонаж находится в заданном допуске X/Y/Z, в том числе когда уже был там до вызова. int 0 — недопустимые координаты, отказ запуска, недостигнутая точка или сработавшее условие остановки. Это не число шагов и не serial; при аварийной отмене процедура прерывается вместо обычного возврата 0.

Результат команды — числовой флаг: 1 означает выполненное условие, 0 — невыполненное. После var result = команда(...) проверяйте if (result != 0) или if (result == 0). Сохраните результат одного вызова: повторный вызов может выполнить действие снова либо прочитать уже изменившееся состояние.

Поведение

  • Полный маршрут A* строится до первого шага, короткими порциями между обновлениями клиента. При Optimized=true проверяются следующие 4 клетки пути; при false — ближайший шаг. Это проверка уже рассчитанного пути, а не дальность всего маршрута и не ползунки обхода при движении мышью.
  • Отказ сервера DenyWalk или новое препятствие запрашивает перерасчёт от текущей позиции после завершения очереди шагов. Число повторов и частота перерасчёта ограничены; отсутствие пути может завершить движение с 0.
  • Маршрут принадлежит запустившей его процедуре: её аварийная остановка отменяет оставшийся автоматический путь. Если другой запуск или пользователь уже заменил маршрут, отмена прежнего владельца новый маршрут не трогает. Уже отправленные шаги не отзываются.
  • SetBadLocation и SetBadObject применяются как снимок запретов текущего runtime при запуске маршрута. Они сохраняются при его внутреннем перерасчёте. Изменение или очистка списков влияет на следующий маршрут, а не переписывает уже выполняющийся.
  • Дальность задаёт UO.LimitMove: по умолчанию 2000, 0 — без предела. Скрытых границ 4096 шагов/узлов и 10000 узлов нет. Работа разбита на порции с возможностью Stop. GetPathArray учитывает числовой порог moveThroughNPC и настройку moveOpenDoor.
  • timeout отсчитывается после принятия запроса и включает последующие порции поиска и пересчёта. stopOnStuck не считает работающий поиск застреванием персонажа; после завершения планирования отсутствие изменений позиции снова учитывается. Итоговый 1/0 проверяет фактические координаты, а не только готовность пути.
  • Результат учитывает локальную позицию клиента; последующая серверная коррекция всё ещё возможна. Запуск конкурирующих команд движения из разных процедур меняет общий маршрут персонажа.
  • Настройки moveCheckStamina, moveExitOnDisconnect, moveOpenDoor, moveThroughCorner, moveThroughNPC, moveHeuristicMult, moveTurnCost и moveBetweenTwoCorners влияют на исполнение. Явные avoidMobiles/openDoors заменяют соответствующие значения для этого вызова.
  • Результат 0 не сообщает точную причину. Проверяйте координаты, соединение, выносливость и журнал; не повторяйте движение бесконечно без UO.Wait и лимита попыток.
  • Целевой Z берётся при вызове, допуск Z=255. Для дополнительных ограничений используйте NewMoveXY; для выбора высоты — MoveXYZ.
  • Основной bridge фиксирует номер запроса, экземпляры игрока/Pathfinder/карты и индекс карты. Новый запрос, смена контекста или окончательный отказ дают 0; проверка повторяется после чтения координат и последнего callback. Timeout, maxSteps и callback=0 останавливают только сохранённый запрос, не новый чужой маршрут. Временный Blocked при ещё активном восстановлении не теряет владение: ожидание продолжается. Для внешнего legacy-bridge без IApiMovementOwnershipBridge сохранён прежний совместимый механизм.
  • Общий Pathfinder хранит до 8 временных запретов направленного перехода X/Y/Z на 2000 мс, только по отклонённому перемещению соответствующего активного запроса. Поворот, неизвестный sequence, ресинхронизация и старый/чужой запрос не создают такой запрет. Новый внешний запрос и потеря контекста карты/игрока очищают их. Поиск по загруженной геометрии пытается обойти переход; это не знание всех серверных препятствий. Без изменения X/Y/Z игрока разрешены до 8 внутренних перерасчётов с паузой не меньше 40 мс. Нет полного пути или исчерпан этот бюджет — маршрут заканчивается. Координатная задача затем завершается после обработки отправленных шагов; mobile-Follow может повторить попытку по своей задержке.

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

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

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

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

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

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

1. Точная точка пешком — прямой скрипт

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

  • Xdst — две клетки восточнее; Ydst не меняется.
  • Optimized=true, Accuracy=0, Running=false. Вызов возвращает результат после завершения.
var ok = UO.MoveXY(UO.GetX() + 2, UO.GetY(), true, 0, false);
UO.Print(Convert.ToString(ok));

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

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

  • Xdst/Ydst читаются из выбранного объекта; он должен быть объектом мира, не предметом внутри контейнера.
  • Accuracy=1 позволяет стать рядом; Running=true. Высота не ограничивается этим вызовом.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Exists("lasttarget")))
    {
        var ok = UO.MoveXY(UO.GetX("lasttarget"), UO.GetY("lasttarget"), true, 1, true);
        UO.Print("Approach result: " + Convert.ToString(ok));
    }

    return null;
}

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

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

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

  • Цель 1445/1690 замените своей. Порог выносливости задаётся отдельной настройкой, не шестым параметром MoveXY.
  • После нормального возврата исходное значение восстанавливается. При аварийном прерывании дальнейшие строки не выполняются.

Стандартная скорость движения

Минимальный интервал шага: пешком — ходьба 400 мс, бег 200 мс; верхом — ходьба 200 мс, бег 100 мс.

Это стандартные пределы клиента, а не автоматически определённые настройки вашего шарда. Серверные режимы скорости и полёт учитываются отдельно. Таймеры скрипта могут замедлить движение, но не уменьшить эти пределы.

Шаги, маршруты, Follow, управление мышью/клавишами и карта используют общую очередь персонажа. Замена маршрута, поворот или коррекция позиции сервером не отменяют оставшуюся паузу после запроса шага. После задержки нет ускоренной серии для компенсации пропущенных кадров. Ожидание подтверждения, препятствия и плохая связь могут замедлить движение.

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 previous = UO.moveCheckStamina();
        UO.moveCheckStamina(15);
        var ok = UO.MoveXY(1445, 1690, true, 0, false);
        UO.moveCheckStamina(previous);
        UO.Print(Convert.ToString(ok));
        return null;
    }
}

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

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

UO.MoveXY(xdst, ydst, optimized, accuracy, running) — UO.MoveXY(Any,Any,Any,Any,Any)

Параметры: xdst (Any), ydst (Any), optimized (Any), accuracy (Any), running (Any)

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

При вызове:

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

case "movexy":

                    return new InjectionValue(MoveTo(Arg(0), Arg(1), bridge.GetZ(bridge.Self), Arg(3), Arg(4) != 0, 255, Arg(2) != 0));

UO.MoveXYZ

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

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

int UO.MoveXYZ(object? x, object? y, object? z, object? accuracyXY, object? accuracyZ, object? running);
int UO.MoveXYZ(object? x, object? y, object? z, object? accuracyXY, object? accuracyZ, object? running, object? timeout);
int UO.MoveXYZ(object? x, object? y, object? z, object? accuracyXY, object? accuracyZ, object? running, object? timeout, object? maxSteps);
int UO.MoveXYZ(object? x, object? y, object? z, object? accuracyXY, object? accuracyZ, object? running, object? timeout, object? maxSteps, object? avoidMobiles);
int UO.MoveXYZ(object? x, object? y, object? z, object? accuracyXY, object? accuracyZ, object? running, object? timeout, object? maxSteps, object? avoidMobiles, object? openDoors);

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

Параметры

  • x — Обязательный int: мировая координата X назначения, 0..65535, на текущей карте. Не координата гампа.
  • y — Обязательный int: мировая координата Y назначения, 0..65535, на текущей карте.
  • z — Обязательный int: целевая мировая высота -128..127. Это высота поверхности, а не номер этажа.
  • accuracyXY — Обязательный int. Допуск по X и Y в клетках: оба отклонения должны укладываться в него. Значение ограничивается диапазоном 0..20; 0 требует точных X/Y.
  • accuracyZ — Обязательный int. Допуск высоты: abs(фактическая Z - требуемая Z), ограничивается 0..255. Ноль требует точной высоты; 255 практически отключает ограничение Z.
  • running — Обязательный логический флаг. true/1 — запрос бега, false/0 — шаг. Серверные задержки движения сохраняются; это не множитель скорости.
  • timeout — Необязательный предел ожидания в миллисекундах; отсутствующий аргумент, 0 и отрицательное значение означают отсутствие этого дополнительного предела. Отсчёт начинается после принятия маршрута к исполнению; это не жёсткий предел длительности всего вызова вместе с подготовкой маршрута.
  • maxSteps — Необязательный предел замеченных изменений позиции, не сетевых пакетов. 0/отрицательное/отсутствие — без этого лимита. Между опросами может пройти несколько шагов, поэтому это не точный счётчик клеток.
  • avoidMobiles — Необязательный флаг: true запрещает проход сквозь учитываемых персонажей; false разрешает попытку. Без аргумента используется moveThroughNPC. Сервер всё равно может запретить проход.
  • openDoors — Необязательный флаг открывания дверей по пути. Без аргумента используется moveOpenDoor; true не предоставляет доступ к запертым дверям.

Возвращает

int 1 — в конце проверки персонаж находится в заданном допуске X/Y/Z, в том числе когда уже был там до вызова. int 0 — недопустимые координаты, отказ запуска, недостигнутая точка или сработавшее условие остановки. Это не число шагов и не serial; при аварийной отмене процедура прерывается вместо обычного возврата 0.

Результат команды — числовой флаг: 1 означает выполненное условие, 0 — невыполненное. После var result = команда(...) проверяйте if (result != 0) или if (result == 0). Сохраните результат одного вызова: повторный вызов может выполнить действие снова либо прочитать уже изменившееся состояние.

Поведение

  • Как работает, шаг 1: проверяет координаты, настроенные условия соединения и выносливости. Если персонаж уже находится в пределах accuracyXY и accuracyZ, сразу возвращает 1 без нового маршрута.
  • Шаг 2: строит маршрут на текущей карте с учётом высоты поверхности, препятствий и выбранных условий прохода. Режим Optimized здесь включён внутри команды; передавать такой параметр в MoveXYZ не нужно.
  • Шаг 3: запускает ходьбу или бег по маршруту и ждёт результат в текущей процедуре. Строка после вызова выполняется после его завершения; интерфейс клиента продолжает работать.
  • Шаг 4: при отказе шага или новом препятствии клиент может пересчитать маршрут от текущего положения. Попытки ограничены. При тайм-ауте или достижении лимита наблюдаемых перемещений за пределами цели движение останавливается с 0.
  • Шаг 5: после окончания движения сравнивает фактические X/Y/Z клиента с целью. Требуются одновременно abs(X-x)<=accuracyXY, abs(Y-y)<=accuracyXY и abs(Z-z)<=accuracyZ. Например, для цели 1279/540/20 с допусками 1 и 2 подходят X=1278..1280, Y=539..541, Z=18..22.
  • Минимальная форма содержит шесть аргументов: UO.MoveXYZ(1279,540,20,1,2,true). Дополнительные аргументы добавляются справа в порядке timeout, maxSteps, avoidMobiles, openDoors. Чтобы указать openDoors, нужно передать и предыдущие позиции; пустые места между запятыми не поддерживаются.
  • Отличие от NewMoveXY: MoveXYZ получает целевую высоту третьим аргументом. У NewMoveXY третий аргумент — Optimized; передавать туда высоту нельзя. Callback у MoveXYZ в этом runtime отсутствует.
  • Маршрут принадлежит запустившей его процедуре: её аварийная остановка отменяет оставшийся автоматический путь. Если другой запуск или пользователь уже заменил маршрут, отмена прежнего владельца новый маршрут не трогает. Уже отправленные шаги не отзываются.
  • SetBadLocation и SetBadObject применяются как снимок запретов текущего runtime при запуске маршрута. Они сохраняются при его внутреннем перерасчёте. Изменение или очистка списков влияет на следующий маршрут, а не переписывает уже выполняющийся.
  • Дальность задаёт UO.LimitMove: по умолчанию 2000, 0 — без предела. Скрытых границ 4096 шагов/узлов и 10000 узлов нет. Работа разбита на порции с возможностью Stop. GetPathArray учитывает числовой порог moveThroughNPC и настройку moveOpenDoor.
  • timeout отсчитывается после принятия запроса и включает последующие порции поиска и пересчёта. stopOnStuck не считает работающий поиск застреванием персонажа; после завершения планирования отсутствие изменений позиции снова учитывается. Итоговый 1/0 проверяет фактические координаты, а не только готовность пути.
  • Результат учитывает локальную позицию клиента; последующая серверная коррекция всё ещё возможна. Запуск конкурирующих команд движения из разных процедур меняет общий маршрут персонажа.
  • Настройки moveCheckStamina, moveExitOnDisconnect, moveOpenDoor, moveThroughCorner, moveThroughNPC, moveHeuristicMult, moveTurnCost и moveBetweenTwoCorners влияют на исполнение. Явные avoidMobiles/openDoors заменяют соответствующие значения для этого вызова.
  • Результат 0 не сообщает точную причину. Проверяйте координаты, соединение, выносливость и журнал; не повторяйте движение бесконечно без UO.Wait и лимита попыток.
  • Основной bridge фиксирует номер запроса, экземпляры игрока/Pathfinder/карты и индекс карты. Новый запрос, смена контекста или окончательный отказ дают 0; проверка повторяется после чтения координат и последнего callback. Timeout, maxSteps и callback=0 останавливают только сохранённый запрос, не новый чужой маршрут. Временный Blocked при ещё активном восстановлении не теряет владение: ожидание продолжается. Для внешнего legacy-bridge без IApiMovementOwnershipBridge сохранён прежний совместимый механизм.
  • Общий Pathfinder хранит до 8 временных запретов направленного перехода X/Y/Z на 2000 мс, только по отклонённому перемещению соответствующего активного запроса. Поворот, неизвестный sequence, ресинхронизация и старый/чужой запрос не создают такой запрет. Новый внешний запрос и потеря контекста карты/игрока очищают их. Поиск по загруженной геометрии пытается обойти переход; это не знание всех серверных препятствий. Без изменения X/Y/Z игрока разрешены до 8 внутренних перерасчётов с паузой не меньше 40 мс. Нет полного пути или исчерпан этот бюджет — маршрут заканчивается. Координатная задача затем завершается после обработки отправленных шагов; mobile-Follow может повторить попытку по своей задержке.

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

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

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

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

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

var result = UO.MoveXYZ(UO.GetX() + 1, UO.GetY(), UO.GetZ(), 0, 0, false);
UO.Print("MoveXYZ: " + Convert.ToString(result));

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

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

  • x/y/z — целевая точка. accuracyXY=0 и accuracyZ=0 требуют точной позиции.
  • running=false — ходьба. Если соседняя поверхность имеет другую высоту, результат может быть 0.
var ok = UO.MoveXYZ(UO.GetX() + 1, UO.GetY(), UO.GetZ(), 0, 0, false);
UO.Print(Convert.ToString(ok));

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

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

  • Подготовка: персонаж должен быть в игре, а точка должна существовать на текущей карте. 1279/540/20 — учебные координаты: замените их своей доступной точкой, включая реальную высоту поверхности.
    1. destinationX=1279 — первый аргумент, мировая координата X цели.
    1. destinationY=540 — второй аргумент, мировая координата Y цели.
    1. destinationZ=20 — третий аргумент, высота. Команда должна найти проход или лестницу; значение 20 само по себе не переносит на этаж.
    1. accuracyXY=1 разрешает закончить в пределах одной клетки по каждой горизонтальной координате. Диагонально соседняя клетка тоже подходит.
    1. accuracyZ=2 разрешает высоту от 18 до 22 включительно. Совпадение X/Y на другом этаже недостаточно для успеха.
    1. running=true запрашивает бег. Для ходьбы замените true на false.
    1. timeout=8000 ограничивает ожидание после старта маршрута восемью секундами. По истечении этого времени, пока движение ещё идёт, команда останавливает его и возвращает 0.
    1. maxSteps=100 ограничивает число замеченных изменений позиции. Это не точное число пройденных клеток: между опросами может выполниться несколько шагов.
    1. avoidMobiles=true запрещает проход сквозь учитываемых персонажей при расчёте маршрута.
    1. openDoors=true разрешает попытки открывать двери по пути. Запертую дверь или ограничения сервера этот флаг не обходит.
  • reached получает int 1 или 0 после завершения вызова. if reached == 1 выполняет ветку успеха; else обрабатывает недостижение цели без бесконечного повторения команды.
  • Последняя строка выводит текущие X/Y/Z для проверки. При аварийной остановке процедуры дальнейшие строки, включая этот вывод, не выполняются.
return  RunScenario();
 object? RunScenario()
{
    var destinationX = 1279;
    var destinationY = 540;
    var destinationZ = 20;
    var accuracyXY = 1;
    var accuracyZ = 2;
    dynamic running = true;
    var timeout = 8000;
    var maxSteps = 100;
    dynamic avoidMobiles = true;
    dynamic openDoors = true;
    var reached = UO.MoveXYZ(destinationX, destinationY, destinationZ, accuracyXY, accuracyZ, running, timeout, maxSteps, avoidMobiles, openDoors);
    if (Truth(reached == 1))
    {
        UO.Print("Destination reached");
    }
    else
    {
        UO.Print("Destination not reached; check the path and limits");
    }

    UO.Print("Position: " + Convert.ToString(UO.GetX()) + "," + Convert.ToString(UO.GetY()) + "," + Convert.ToString(UO.GetZ()));
    return null;
}

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

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

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

  • x/y/z=1445/1690/0; accuracyXY=1, accuracyZ=3; running=true.
  • timeout=5000, maxSteps=60 наблюдаемых перемещений, avoidMobiles=true и openDoors=false.
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 ok = UO.MoveXYZ(1445, 1690, 0, 1, 3, true, 5000, 60, true, false);
        UO.Print("Result: " + Convert.ToString(ok));
        return null;
    }
}

4. Готовая функция с комментариями внутри скрипта — прямой скрипт

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

  • Строки с # — комментарии C#: они сохраняются при копировании и не выполняются. Пример содержит обе необходимые части: функцию GoToPoint и запускаемую процедуру Main.
  • Все шесть параметров GoToPoint передаются в MoveXYZ без изменения. Четыре дополнительных параметра заданы внутри функции: 8000 мс, 100 наблюдаемых изменений позиции, обход персонажей и открывание дверей.
  • Для цели 1279/540/20 с допусками 1/2 подходят X=1278..1280, Y=539..541, Z=18..22. Точка на другой высоте за пределами 18..22 не считается достигнутой.
  • Это обёртка над настоящей командой, а не вторая реализация поиска пути на скрипте. Она не вызывает лишний GetPathArray и не запускает бесконечные повторные попытки. При недостижении вызывающая процедура получает 0 и сама выбирает дальнейшее действие.

Стандартная скорость движения

Минимальный интервал шага: пешком — ходьба 400 мс, бег 200 мс; верхом — ходьба 200 мс, бег 100 мс.

Это стандартные пределы клиента, а не автоматически определённые настройки вашего шарда. Серверные режимы скорости и полёт учитываются отдельно. Таймеры скрипта могут замедлить движение, но не уменьшить эти пределы.

Шаги, маршруты, Follow, управление мышью/клавишами и карта используют общую очередь персонажа. Замена маршрута, поворот или коррекция позиции сервером не отменяют оставшуюся паузу после запроса шага. После задержки нет ускоренной серии для компенсации пропущенных кадров. Ожидание подтверждения, препятствия и плохая связь могут замедлить движение.

var reached = GoToPoint(1279, 540, 20, 1, 2, true);
if (Truth(Truth(reached) == true))
{
    UO.Print("Destination reached");
}
else
{
    UO.Print("Destination not reached");
}

dynamic GoToPoint(dynamic x, dynamic y, dynamic z, dynamic accuracyXY, dynamic accuracyZ, dynamic running)
{
    var timeout = 8000;
    var maxSteps = 100;
    dynamic avoidMobiles = true;
    dynamic openDoors = true;
    var reached = UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running, timeout, maxSteps, avoidMobiles, openDoors);
    return reached;
}

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.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running) — UO.MoveXYZ(Any,Any,Any,Any,Any,Any)

Параметры: x (Any), y (Any), z (Any), accuracyXY (Any), accuracyZ (Any), running (Any)

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

При вызове:

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

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

values => new InjectionValue(CompactMoveXYZ(values))

UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running, timeout) — UO.MoveXYZ(Any,Any,Any,Any,Any,Any,Any)

Параметры: x (Any), y (Any), z (Any), accuracyXY (Any), accuracyZ (Any), running (Any), timeout (Any)

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

При вызове:

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

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

values => new InjectionValue(CompactMoveXYZ(values))

UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running, timeout, maxSteps) — UO.MoveXYZ(Any,Any,Any,Any,Any,Any,Any,Any)

Параметры: x (Any), y (Any), z (Any), accuracyXY (Any), accuracyZ (Any), running (Any), timeout (Any), maxSteps (Any)

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

При вызове:

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

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

values => new InjectionValue(CompactMoveXYZ(values))

UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running, timeout, maxSteps, avoidMobiles) — UO.MoveXYZ(Any,Any,Any,Any,Any,Any,Any,Any,Any)

Параметры: x (Any), y (Any), z (Any), accuracyXY (Any), accuracyZ (Any), running (Any), timeout (Any), maxSteps (Any), avoidMobiles (Any)

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

При вызове:

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

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

values => new InjectionValue(CompactMoveXYZ(values))

UO.MoveXYZ(x, y, z, accuracyXY, accuracyZ, running, timeout, maxSteps, avoidMobiles, openDoors) — UO.MoveXYZ(Any,Any,Any,Any,Any,Any,Any,Any,Any,Any)

Параметры: x (Any), y (Any), z (Any), accuracyXY (Any), accuracyZ (Any), running (Any), timeout (Any), maxSteps (Any), avoidMobiles (Any), openDoors (Any)

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

При вызове:

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

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

values => new InjectionValue(CompactMoveXYZ(values))

UO.MoverStop

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

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

void UO.MoverStop();

Останавливает автоматический маршрут Pathfinder.

Параметры

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

Возвращает

void — возвращаемого значения нет. Вызывайте отдельной строкой; это не true/false и не число шагов.

Поведение

  • Снимает локальное автоматическое движение. Уже отправленные шаги и серверные подтверждения не отзываются.
  • Это не TerminateAll: выполнение остальных строк скрипта и других процедур продолжается.

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

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

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

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

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

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

1. Снять маршрут — прямой скрипт

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

  • Аргументов нет.
  • Команда не возвращает код успеха.
UO.MoverStop();

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

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

  • Move() читает автоматическое движение.
  • Print — локальное сообщение скрипта; оно не является подтверждением сервера.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Move()))
    {
        UO.MoverStop();
        UO.Print("Route stopped");
    }

    return null;
}

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

3. Прекратить движение и проверить позицию — класс сценария

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

  • UO.Wait=100 мс даёт клиенту обработать очередные события.
  • После остановки координаты читаются отдельно; задержка не гарантирует получение всех сетевых подтверждений.
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()
    {
        UO.MoverStop();
        await Delay(100);
        UO.Print(Convert.ToString(UO.GetX()) + "," + Convert.ToString(UO.GetY()));
        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
}

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

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

UO.MoverStop() — UO.MoverStop()

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

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

При вызове:

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

case "moverstop": bridge.StopMoving(); return InjectionValue.Unit;

UO.Moving

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

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

int UO.Moving();

Проверяет движение своего персонажа.

Параметры

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

Возвращает

int bool (1/0): 1 — активен автоматический Pathfinder либо в очереди персонажа ещё есть шаги; 0 — оба отсутствуют или персонаж не загружен. Это не подтверждение достижения цели и не количество шагов.

Результат команды — числовой флаг: 1 означает выполненное условие, 0 — невыполненное. После var result = команда(...) проверяйте if (result != 0) или if (result == 0). Сохраните результат одного вызова: повторный вызов может выполнить действие снова либо прочитать уже изменившееся состояние.

Поведение

  • Читаются уже полученные локальные данные. Запрос не открывает status и не заставляет сервер прислать обновление. После смерти, перехода карты или удаления объекта значения могут измениться между двумя вызовами.
  • C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.

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

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

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

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

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

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

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

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

  • Пустые скобки читают self. active — число 1 или 0; текст сообщения служит примером обработки ветвей.
  • 1 — активен автоматический Pathfinder либо в очереди персонажа ещё есть шаги; 0 — оба отсутствуют или персонаж не загружен. Это не подтверждение достижения цели и не количество шагов.
var active = UO.Moving();
if (Truth(active))
{
    UO.Print("State is active");
}
else
{
    UO.Print("State is inactive or unavailable");
}

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

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

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

  • У команды нет аргумента объекта: даже после Exists(self) она читает только собственное состояние.
  • Exists(self) проверяет загруженность игрока отдельно от запрашиваемого флага. Между проверками мир может измениться.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Exists("self")))
    {
        var state = UO.Moving();
        UO.Print("State 1/0: " + Convert.ToString(state));
    }

    return null;
}

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

3. Заметить изменение состояния без бесконечного ожидания — класс сценария

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

  • Два вызова без аргументов читают self; UO.Wait(500) — пауза полсекунды.
  • Сравниваются два снимка флага. Переходы между снимками могут быть пропущены; это не подписка на все серверные события.
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.Moving();
        await Delay(500);
        var after = UO.Moving();
        if (Truth(before != after))
        {
            UO.Print("State changed from " + Convert.ToString(before) + " to " + Convert.ToString(after));
        }

        return null;
    }

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

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

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

UO.Moving() — UO.Moving()

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

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

При вызове:

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

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

() => bridge.IsMoving()

Создание API: Эти функции создают регистрацию API; они не выполняются заново при каждом вызове команды.

UO.LimitMove — Предел дальности движения. Дальность задаёт UO.LimitMove: по умолчанию 2000, 0 — без предела. Скрытых границ 4096 шагов/узлов и 10000 узлов нет. Работа разбита на порции с возможностью Stop. GetPathArray учитывает числовой порог moveThroughNPC и настройку moveOpenDoor.

⚠️ **GitHub.com Fallback** ⚠️