Skip to content

UO Topic movement

Codex edited this page Oct 12, 2026 · 7 revisions

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

Рух персонажа

Головна · C# · IDE · Команди UO · За абеткою · Приклади · Мови

Кроки, біг, рух до координат, пошук шляху, двері та перешкоди. Перенесення речей описано окремо в розділі «Предмети».

Розділи

Тема Команди та пояснення
Слідування за ціллю UO.Follow — фонове проходження, дистанція та зупинка.
Рух до точки UO.Move
Рух за координатами X і Y UO.MoveXY
Рух за координатами X, Y і Z UO.MoveXYZ
Рух за X і Y з параметрами UO.NewMoveXY
Крок UO.Step
Крок без очікування UO.StepQ
Рух із параметрами UO.PMove
Напрямок UO.Direction
Обчислення напрямку UO.CalcDir
Постійний біг UO.AlwaysRun
Пошук шляху UO.GetPathArray · UO.GetPathArray3D · UO.NewMoveXY
Маршрут на площині UO.GetPathArray
Маршрут з урахуванням висоти UO.GetPathArray3D
Маршрут клієнта UO.ClientPath - шлях до папки клієнта, не ігровий маршрут; див. Profiles & Configuration.
Двері UO.OpenDoor · UO.LastStepQUsedDoor · UO.moveOpenDoor
Перешкоди UO.IsWorldCellPassable · UO.SetBadLocation · UO.moveThroughNPC · UO.moveThroughCorner
Налаштування руху UO.moveCheckStamina · UO.moveExitOnDisconnect · UO.moveHeuristicMult · UO.moveTurnCost · UO.moveBetweenTwoCorners
Прогнозовані координати 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

Напрямок

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, що також означає північ.

Поведінка

  • Читаються вже отримані локальні дані. Запит не відкриває статус і не змушує сервер надіслати оновлення. Після смерті, переходу на карту або видалення об'єкта значення можуть змінитися між двома викликами.
  • 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, що також означає північ.

Поведінка

  • Читаються вже отримані локальні дані. Запит не відкриває статус і не змушує сервер надіслати оновлення. Після смерті, переходу на карту або видалення об'єкта значення можуть змінитися між двома викликами.
  • 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

Українська · Русский · 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 1..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 мс, лише якщо відхилений рух відповідного активного запиту. Ротація, невідома послідовність, повторна синхронізація та старий/чужий запит не створюють такої заборони. Новий зовнішній запит і втрата контексту карти/програвача очищає їх. Пошук завантаженої геометрії намагається обійти перехід; це не знання всіх перешкод на сервері. Без зміни 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 збирає окрему умову для кожного елемента статусу. Зупинка при статусі 5 АБО 6, своїх HP <=40% АБО через 30000 мс. Порожній статус пропустить цикл, але дві наступні умови залишаться. Нові рядки додавайте до 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, що також означає північ.

Поведінка

  • Читаються вже отримані локальні дані. Запит не відкриває статус і не змушує сервер надіслати оновлення. Після смерті, переходу на карту або видалення об'єкта значення можуть змінитися між двома викликами.
  • 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, що також означає північ.

Поведінка

  • Читаються вже отримані локальні дані. Запит не відкриває статус і не змушує сервер надіслати оновлення. Після смерті, переходу на карту або видалення об'єкта значення можуть змінитися між двома викликами.
  • 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 та перевіряйте їх власний результат.
  • Пошук оминає перешкоди, вважаючи сусідні переміщення однаковими за вартістю; на постійній карті шукається шлях із найменшим числом кроків. Перевіряється реальна прохідність кожного ребра, включаючи висоту та обмеження діагоналей клієнта.
  • Не більше 4096 розкритих вузлів і не більше 4096 кроків. Ліміт роботи може дати порожній масив навіть за наявності далекого складного шляху; діліть довгі маршрути на ділянки.
  • У клієнті розрахунок розбивається на порції до 32 вузлів з перевіркою бюджету близько 1 мс між вузлами. Скасування перевіряється між порціями. Читання картки залишається на ігровому потоці; це не обіцянка фіксованого часу окремого читання диска.
  • Карта може змінитися після перевірки: персонажі переміщуються, двері зачиняються, сервер виправляє положення. Отриманий масив — план доступних локальних даних, не підтвердження сервера.
  • SetBadLocation виключає клітини, SetBadObject — зони навколо відповідних завантажених предметів світу. Використовується знімок списків свого runtime на момент запиту; заборони іншого запуску не успадковуються. Початкова клітина не перевіряється на можливість стояти: вона задається кодом, що викликає. Не можна використовувати довільний Z усередині стіни як достовірну вихідну позицію.
  • Поточна карта, вихідні X/Y/Z та цільовий Z беруться у персонажа. Допуск Z = 255 ⟧. Додаткових фільтрів mobiles/statics та дозволу зачинених дверей у чотирихаргументній формі немає.

Самостійні 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 не змінює послідовність клітин чи число кроків.
  • maxSteps — Необов'язкова межа числа ребер шляху без початкової точки. 0/негативне/відсутність використовують спільну межу 4096. Тут вважаються клітини, на відміну від змін, що спостерігаються у NewMoveXY.
  • 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 та перевіряйте їх власний результат.
  • Пошук оминає перешкоди, вважаючи сусідні переміщення однаковими за вартістю; на постійній карті шукається шлях із найменшим числом кроків. Перевіряється реальна прохідність кожного ребра, включаючи висоту та обмеження діагоналей клієнта.
  • Не більше 4096 розкритих вузлів і не більше 4096 кроків. Ліміт роботи може дати порожній масив навіть за наявності далекого складного шляху; діліть довгі маршрути на ділянки.
  • У клієнті розрахунок розбивається на порції до 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). Збережіть результат одного виклику: повторний виклик може виконати дію знову або прочитати стан, що вже змінився.

Поведінка

  • Читаються вже отримані локальні дані. Запит не відкриває статус і не змушує сервер надіслати оновлення. Після смерті, переходу на карту або видалення об'єкта значення можуть змінитися між двома викликами.
  • 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 при запуску маршруту. Вони зберігаються за його внутрішньому перерахунку. Зміна чи очищення списків впливає на наступний маршрут, а не переписує той, що вже виконується.
  • Після прийняття запиту, виклик чекає на потоці скрипта. Початковий пошук та перерахунок виконуються на ігровому потоці порціями: максимум 32 розкриття вузлів та м'який бюджет близько 1 мс за порцію. Одна складна перевірка клітки чи читання картки може перевищити цей бюджет. Між порціями клієнт продовжує оновлення; повний ліміт пошуку залишається 10000 вузлів.
  • 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 мс, лише якщо відхилений рух відповідного активного запиту. Ротація, невідома послідовність, повторна синхронізація та старий/чужий запит не створюють такої заборони. Новий зовнішній запит і втрата контексту карти/програвача очищає їх. Пошук завантаженої геометрії намагається обійти перехід; це не знання всіх перешкод на сервері. Без зміни 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 при запуску маршруту. Вони зберігаються за його внутрішньому перерахунку. Зміна чи очищення списків впливає на наступний маршрут, а не переписує той, що вже виконується.
  • Після прийняття запиту, виклик чекає на потоці скрипта. Початковий пошук та перерахунок виконуються на ігровому потоці порціями: максимум 32 розкриття вузлів та м'який бюджет близько 1 мс за порцію. Одна складна перевірка клітки чи читання картки може перевищити цей бюджет. Між порціями клієнт продовжує оновлення; повний ліміт пошуку залишається 10000 вузлів.
  • 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 мс, лише якщо відхилений рух відповідного активного запиту. Ротація, невідома послідовність, повторна синхронізація та старий/чужий запит не створюють такої заборони. Новий зовнішній запит і втрата контексту карти/програвача очищає їх. Пошук завантаженої геометрії намагається обійти перехід; це не знання всіх перешкод на сервері. Без зміни 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). Збережіть результат одного виклику: повторний виклик може виконати дію знову або прочитати стан, що вже змінився.

Поведінка

  • Читаються вже отримані локальні дані. Запит не відкриває статус і не змушує сервер надіслати оновлення. Після смерті, переходу на карту або видалення об'єкта значення можуть змінитися між двома викликами.
  • 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; вони не виконуються заново під час кожного виклику команди.

Clone this wiki locally