Skip to content

UO Topic files json data

Codex edited this page Oct 12, 2026 · 6 revisions

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

Файли, JSON і дані

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

Робота з файлами, JSON, масивами та колекціями. У C# можна використовувати стандартні класи .NET; у цьому розділі зібрано допоміжні команди UO для роботи з даними.

Розділи

Тема Команди та пояснення
Файли C# та стандартна бібліотека
Розбір JSON C# та стандартна бібліотека
Читання JSON із файлу C# та стандартна бібліотека))
Збереження JSON у файл C# та стандартна бібліотека
Перетворення на текст JSON C# та стандартна бібліотека
Списки C# та стандартна бібліотека
Словники C# та стандартна бібліотека
Масиви C# та стандартна бібліотека · C# та стандартна бібліотека
Потік у пам’яті C# та стандартна бібліотека

Усі команди теми

Колекції сумісності

UO.GetArrayLength · UO.GetWord · UO.GetWordCount

Випадкові значення

UO.Random

C# та стандартна бібліотека · C# та стандартна бібліотека · C# та стандартна бібліотека

Приклади на тему

Нижче наведено короткі приклади. У повному описі кожної команди є параметри, результат, обмеження та кілька самостійних скриптів: прямий код, варіант із функцією та варіант із класом.

UO.GetArrayLength

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

dynamic[] amounts = new dynamic[checked((int)(2) + 1)];
amounts[0] = 50;
amounts[1] = 75;
amounts[2] = 25;
var total = 0;
for (int index = (int)(0); index <= UO.GetArrayLength(amounts) - 1; index += (int)(1))
{
    total += amounts[index];
}
return total;

UO.GetWord

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

return ReadX("move   1445 1690");

dynamic ReadX(dynamic text)
{
    if (Truth(UO.GetWordCount(text) != 3))
    {
        return -1;
    }
    if (Truth(UO.GetWord(text, 0) != "move"))
    {
        return -1;
    }
    var xText = UO.GetWord(text, 1);
    if (!(Truth(IsNumeric(xText))))
    {
        return -1;
    }
    var x = Convert.ToDouble(xText);
    if (Truth(Convert.ToString(x) == "NaN") || Truth(x < 0) || Truth(x > 65535))
    {
        return -1;
    }
    if (Truth(x != Math.Truncate(x)))
    {
        return -1;
    }
    return Convert.ToInt32(x);
}

bool IsNumeric(object? value) => double.TryParse(Convert.ToString(value), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out _);
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

Повний опис команд


UO.GetArrayLength

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

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

dynamic UO.GetArrayLength(object? arg);

Вважає безпосередні осередки масиву для обмеженого перебору та безпечного читання індексу.

Параметри

Повернене значення

int >= 0. Порожній Array та значення іншого виду дають 0: тільки за результатом не можна перевірити тип. Це кількість, а не bool і останній індекс.

Поведінка

  • Локальна перевірка: не надсилає запит серверу, не переміщує предмети та не змінює масив. У прикладах подано навчальні дані, а не живий інвентар.
  • Перевіряє вигляд значення та читає Array.Length без обходу та підсумовування. оголошення змінної values(2) створює три осередки, індекси 0..2, включаючи незаповнені.
  • Вкладені елементи рекурсивно не рахуються. Для рядка є Len, для List/Dictionary - їх Count. UO.GetArrayLength - сумісне ім'я тієї ж локальної перевірки.

Самостійні C#-скрипти

Кожен приклад можна зберегти окремим файлом .csx та запускати в IDE. Об'єкт UO та функції очікування надає host поточної ігрової сесії. Демонстраційні serial, імена, координати та адреси замініть своїми.

Простий приклад

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

Результат одного виклику виводиться в журнал. Число не перетворюється на bool; для масиву показано кількість елементів.

object? result = UO.GetArrayLength(new[] { 10, 20, 30 });
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Скласти кількості з обмеженого списку – прямий скрипт

Параметри та порядок виконання:

  • оголошення змінної amounts(2) створює три записи. Цикл обходить індекси 0..2 і повертає 150. Кількості складає цикл, а не ArrayLength.
  • Локальна перевірка: не надсилає запит серверу, не переміщує предмети та не змінює масив. У прикладах подано навчальні дані, а не живий інвентар.
dynamic[] amounts = new dynamic[checked((int)(2) + 1)];
amounts[0] = 50;
amounts[1] = 75;
amounts[2] = 25;
var total = 0;
for (int index = (int)(0); index <= UO.GetArrayLength(amounts) - 1; index += (int)(1))
{
    total += amounts[index];
}
return total;

2. Окремо порахувати точки та поля координат – функція сценарію.

Параметри та порядок виконання:

  • У route дві точки Array, у кожній по три осередки координат. Результат 2|3, а не шість. Персонаж не рухається.
  • Локальна перевірка: не надсилає запит серверу, не переміщує предмети та не змінює масив. У прикладах подано навчальні дані, а не живий інвентар.
return  RunScenario();
 object? RunScenario()
{
    dynamic[] first = new dynamic[checked((int)(2) + 1)];
    first[0] = 100;
    first[1] = 200;
    first[2] = 0;
    dynamic[] second = new dynamic[checked((int)(2) + 1)];
    second[0] = 101;
    second[1] = 200;
    second[2] = 0;
    dynamic[] route = new dynamic[checked((int)(1) + 1)];
    route[0] = first;
    route[1] = second;
    return Convert.ToString(UO.GetArrayLength(route)) + "|" + Convert.ToString(UO.GetArrayLength(route[0]));
    return null;
}

3. Перевірити перший індекс - клас сценарію

Параметри та порядок виконання:

  • Рядок дає 0; Main повертає no route до звернення до індексу. Перевірка підходить для порожнього Array, але не розрізняє ці випадки.
  • Локальна перевірка: не надсилає запит серверу, не переміщує предмети та не змінює масив. У прикладах подано навчальні дані, а не живий інвентар.
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 route = "not an array";
        if (Truth(UO.GetArrayLength(route) == 0))
        {
            return "no route";
        }

        return route[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.GetArrayLength(arg) — UO.GetArrayLength(Any)

Параметри: arg (Any)

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

Під час виклику:

Внутрішній код реалізації, не самостійний скрипт.

public static InjectionValue GetArrayLength(InjectionValue arg) => arg.Kind==InjectionValueKind.Array?new InjectionValue(arg.Array.Length):InjectionValue.Zero;

UO.GetWord

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

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

string UO.GetWord(object? value, object? wordIndex);
string UO.GetWord(object? value, object? wordIndex, object? delimiter);

Отримує окреме слово або поле з тексту. Стане в нагоді для розбирання координат, списку пріоритетів або збереженої настройки скрипта.

Параметри

  • value - Вихідний рядок. Функція розбирає саме переданий текст: не читає журнал, файл, екіпірування чи світ самостійно.
  • wordIndex — Цілий індекс слова від 0: 0 — перше, 1 — друге. Негативний індекс та індекс не менше кількості слів повертають порожній рядок.
  • delimiter — Необов'язковий роздільник. Без нього, з "" або з одним пробілом " " текст ділиться за будь-якими символами Unicode, включаючи табуляцію і переклад рядка. Інший роздільник - точна послідовність цілком: "::" означає дві двокрапки поспіль, а не кожну двокрапку. Порожні частини відкидаються; непорожні частини не обрізаються.

Повернене значення

string - обрана непуста частина, або "", якщо індекс відсутній. Це текст, а не ID, type чи число: для числа окремо перевірте IsNumeric та перетворіть значення.

Поведінка

  • Працює локально, без пакетів та ігрових дій. GetWord та UO.GetWord викликають один обробник; GetWordCount та UO.GetWordCount також збігаються. Кожен виклик знову розділяє весь текст. У циклі збережіть кількість заздалегідь; для великого багаторазового аналізу краще зберігати вже розібрані поля в масиві. Це не CSV-парсер: лапки не захищають роздільники, порожні стовпці губляться.
  • GetWord · GetWordCount · IsNumeric

Самостійні C#-скрипти

Кожен приклад можна зберегти окремим файлом .csx та запускати в IDE. Об'єкт UO та функції очікування надає host поточної ігрової сесії. Демонстраційні serial, імена, координати та адреси замініть своїми.

Простий приклад

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

Результат одного виклику виводиться в журнал. Число не перетворюється на bool; для масиву показано кількість елементів.

var result = UO.GetWord("red green blue", 1);
UO.Print("GetWord: " + Convert.ToString(result));

1. UO.GetWord - 1 - прямий скрипт

Параметри та порядок виконання:

  • ReadX отримує рядок "move 1445 1690". Перевіряє три слова та ім'я move; індекс 1 вибирає X. IsNumeric перевіряє текст, Convert.ToInt32 повертає 1445. Це лише розбір настроювання; персонаж не рухається. При неправильній формі повертається - 1.
  • ReadX також вимагає цілий X у діапазоні 0..65535 перед Convert.ToInt32; NaN, нескінченність та дробове X відхиляються. Y тут не перевіряється.
return ReadX("move   1445 1690");

dynamic ReadX(dynamic text)
{
    if (Truth(UO.GetWordCount(text) != 3))
    {
        return -1;
    }
    if (Truth(UO.GetWord(text, 0) != "move"))
    {
        return -1;
    }
    var xText = UO.GetWord(text, 1);
    if (!(Truth(IsNumeric(xText))))
    {
        return -1;
    }
    var x = Convert.ToDouble(xText);
    if (Truth(Convert.ToString(x) == "NaN") || Truth(x < 0) || Truth(x > 65535))
    {
        return -1;
    }
    if (Truth(x != Math.Truncate(x)))
    {
        return -1;
    }
    return Convert.ToInt32(x);
}

bool IsNumeric(object? value) => double.TryParse(Convert.ToString(value), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out _);
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. UO.GetWord — 2 — функція сценарію

Параметри та порядок виконання:

  • PriorityAt отримує список "mage||tank|archer|" та index=1. Розділювач | відкидає порожні елементи, тому результат tank. Довільні імена; тут вони не реєструють ClassMask і не перевіряють одяг. Використовуйте ті самі правила поділу під час підрахунку та вибору.
return  RunScenario();
 object? RunScenario()
{
    return PriorityAt("mage||tank|archer|", 1);
    return null;
}

dynamic PriorityAt(dynamic names, dynamic index)
{
    return UO.GetWord(names, index, "|");
}

3. UO.GetWord - 3 - клас сценарію

Параметри та порядок виконання:

  • ReadPlace ділить "Britain::Bank:west" точним роздільником ::. Індекс 1 повертає Bank:west, внутрішня одиночна двокрапка залишається. Якщо немає двох непустих частин, помічник повертає " " . Прогалини навколо частин зберігаються.
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()
    {
        return ReadPlace("Britain::Bank:west");
        return null;
    }

    dynamic ReadPlace(dynamic text)
    {
        if (Truth(UO.GetWordCount(text, "::") != 2))
        {
            return "";
        }

        return UO.GetWord(text, 1, "::");
    }

    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.GetWord(value, wordIndex) — UO.GetWord(String,Integer)

Параметри: value (String), wordIndex (Integer)

Результат: string / String.

Під час виклику:

Внутрішній код реалізації, не самостійний скрипт.

private static string GetWord(string value,int wordIndex) => GetWord(value,wordIndex," ");

UO.GetWord(value, wordIndex, delimiter) — UO.GetWord(String,Integer,String)

Параметри: value (String), wordIndex (Integer), delimiter (String)

Результат: string / String.

Під час виклику:

Внутрішній код реалізації, не самостійний скрипт.

private static string GetWord(string value,int wordIndex,string delimiter)
        {
            var words=SplitWords(value,delimiter);return wordIndex>=0&&wordIndex<words.Length?words[wordIndex]:string.Empty;
        }

UO.GetWordCount

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

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

int UO.GetWordCount(object? value);
int UO.GetWordCount(object? value, object? delimiter);

Вважає непустими поля тексту. Дозволяє перевірити кількість координат перед розбором та визначити межі перебору списку.

Параметри

  • value - Вихідний рядок. Функція розбирає саме переданий текст: не читає журнал, файл, екіпірування чи світ самостійно.
  • delimiter — Необов'язковий роздільник. Без нього, з "" або з одним пробілом " " текст ділиться за будь-якими символами Unicode, включаючи табуляцію і переклад рядка. Інший роздільник - точна послідовність цілком: "::" означає дві двокрапки поспіль, а не кожну двокрапку. Порожні частини відкидаються; непорожні частини не обрізаються.

Повернене значення

int – кількість непустих частин. Порожній рядок та рядок лише з роздільників дають 0. Це лічильник, а не bool: 2 теж допустимий результат; перевіряйте count > 0 чи потрібну точну кількість.

Поведінка

  • Працює локально, без пакетів та ігрових дій. GetWord та UO.GetWord викликають один обробник; GetWordCount та UO.GetWordCount також збігаються. Кожен виклик знову розділяє весь текст. У циклі збережіть кількість заздалегідь; для великого багаторазового аналізу краще зберігати вже розібрані поля в масиві. Це не CSV-парсер: лапки не захищають роздільники, порожні стовпці губляться.
  • GetWord · GetWordCount · IsNumeric

Самостійні C#-скрипти

Кожен приклад можна зберегти окремим файлом .csx та запускати в IDE. Об'єкт UO та функції очікування надає host поточної ігрової сесії. Демонстраційні serial, імена, координати та адреси замініть своїми.

Простий приклад

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

Результат одного виклику виводиться в журнал. Число не перетворюється на bool; для масиву показано кількість елементів.

var result = UO.GetWordCount("red green blue");
UO.Print("GetWordCount: " + Convert.ToString(result));

1. UO.GetWordCount - 1 - прямий скрипт

Параметри та порядок виконання:

  • HasPoint приймає "1445 1690 0". Потребує рівно три слова та числовий текст у кожному, потім повертає 1; інакше 0. Це лише перевірка форми, а не допустимості картки, меж координат чи прохідності. GetWordCount тут повертає 3, а bool повертає наш помічник.
  • HasPoint додатково відхиляє NaN та нескінченності, які сам IsNumeric може прийняти. Дробові кінцеві числа допускаються; перед рухом потрібна окрема перевірка цілих ігрових координат.
return HasPoint("1445 1690 0");

dynamic HasPoint(dynamic text)
{
    if (Truth(UO.GetWordCount(text) != 3))
    {
        return 0;
    }
    var i = 0;
    while (Truth(i < 3))
    {
        if (!(Truth(IsNumeric(UO.GetWord(text, i)))))
        {
            return 0;
        }
        var value = Convert.ToString(Convert.ToDouble(UO.GetWord(text, i)));
        if (Truth(value == "NaN") || Truth(value == "Infinity") || Truth(value == "-Infinity"))
        {
            return 0;
        }
        i = i + 1;
    }
    return 1;
}

bool IsNumeric(object? value) => double.TryParse(Convert.ToString(value), System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out _);
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. UO.GetWordCount — 2 — функція сценарію

Параметри та порядок виконання:

  • JoinPriorities отримує "mage||tank|archer|". Один раз рахує три непусті елементи, перебирає індекси 0..2 і повертає "mage > tank > archer". Початкові, кінцеві та повторні | не створюють окремого пріоритету.
return  RunScenario();
 object? RunScenario()
{
    return JoinPriorities("mage||tank|archer|");
    return null;
}

dynamic JoinPriorities(dynamic names)
{
    var count = UO.GetWordCount(names, "|");
    var i = 0;
    var result = "";
    while (Truth(i < count))
    {
        if (Truth(i > 0))
        {
            result = result + " > ";
        }

        result = result + UO.GetWord(names, i, "|");
        i = i + 1;
    }

    return result;
}

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

3. UO.GetWordCount - 3 - клас сценарію

Параметри та порядок виконання:

  • CountPlaces отримує "Britain::Bank:west::". Розділювач :: дає два поля, кінцеве порожнє поле видаляється: результат 2. Одиночне: усередині Bank:west не поділяє текст. Це не перелік міст із клієнта, а приклад вашого формату налаштування.
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()
    {
        return CountPlaces("Britain::Bank:west::");
        return null;
    }

    dynamic CountPlaces(dynamic text)
    {
        return UO.GetWordCount(text, "::");
    }
}

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

C# враховує регістр. Використовуйте точне ім’я UO. Числові прапорці порівнюйте з 0; bool використовуйте лише там, де сигнатура повертає bool.

UO.GetWordCount(value) — UO.GetWordCount(String)

Параметри: value (String)

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

Під час виклику:

Внутрішній код реалізації, не самостійний скрипт.

private static int GetWordCount(string value) => GetWordCount(value," ");

UO.GetWordCount(value, delimiter) — UO.GetWordCount(String,String)

Параметри: value (String), delimiter (String)

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

Під час виклику:

Внутрішній код реалізації, не самостійний скрипт.

private static int GetWordCount(string value,string delimiter) => SplitWords(value,delimiter).Length;

UO.Random

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

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

int UO.Random(object? max);
int UO.Random(object? min, object? max);

Повертає випадкове ціле число. Нова форма UO.Random(min, max) вибирає число ВІД min ДО max включно. Колишня форма UO.Random(max) збережена: вона вибирає від 0 до max−1. Результат можна зберегти в змінну та використовувати як затримку, координату, індекс чи умову.

Параметри

  • min - Перший аргумент ТІЛЬКИ двоаргументної форми - включена нижня межа, ціле від −2147483648 до 2147483647. Може бути негативною, нулем чи позитивною. Має бути не більше max. В одноаргументній формі min відсутня, а передане число означає max.
  • max — У двоаргументній формі — другий аргумент, включена верхня межа int від −2147483648 до 2147483647. У колишній одноаргументній формі — єдиний аргумент, ВИКЛЮЧЕНИЙ верхній кордон, ціле від 0 до 2147483647; Random(0) повертає 0. Негативне max в одноаргументній формі неприпустимо.

Повернене значення

int - одне псевдовипадкове ціле число. За двох аргументів min ≤ результат ≤ max; обидві межі можуть випасти. За одного позитивного аргументу 0 ≤ результат < max. Повторення числа, що раніше випало, припустимо: команда не вибирає числа без повторень.

Поведінка

  • Підтримуються рівно дві форми: UO.Random(max) та UO.Random(min, max). Виклик без аргументів не зареєстровано. Для діапазону від і до використовуйте два аргументи.
  • Random(5, 5) завжди повертає 5. Random(10, 1) повідомляє про помилку діапазону: кордони не переставляються мовчки. Random(-10, -1) коректний, тому що −10 менше −1.
  • Обидві межі - цілі int; для десяткових часток можна вибрати цілі одиниці потрібного масштабу, а потім розділити. Наприклад, Random(0, 100) / 100.0 дає дискретні значення від ?0? до ?1? з кроком ?0,01?.
  • Повний діапазон Random(-2147483648, 2147483647) допустимо. Реалізація не додає 1 до max у int і тому не переповнюється на верхній межі. Для широких діапазонів використовується відкидання зайвих значень, щоб залишок розподілу не зміщував вибір.
  • Виклик обчислює число локально, не відправляє пакети і не робить паузу. Для випадкової паузи передайте результат UO.Wait. Мінімальну необхідну затримку серверу повинен зберігати ваш скрипт.
  • Збережіть результат у var, якщо одне й те число потрібно кілька разів. Два окремі дзвінки Random можуть повернути різні значення. Команда не перевіряє, чи допустима обрана клітина для руху або перенесення: це перевіряє відповідна ігрова команда.

Самостійні C#-скрипти

Кожен приклад можна зберегти окремим файлом .csx та запускати в IDE. Об'єкт UO та функції очікування надає host поточної ігрової сесії. Демонстраційні serial, імена, координати та адреси замініть своїми.

Простий приклад

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

Результат одного виклику виводиться в журнал. Число не перетворюється на bool; для масиву показано кількість елементів.

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

1. Випадкове число від 1 до 6 — прямий скрипт

Параметри та порядок виконання:

  • min отримує lower = 1, max отримує upper = 6. Можливі рівно шість значень: ?1?, ?2?, ?3?, ?4?, ?5? і ?6?.
  • roll зберігає одне отримане число. Print виводить саме його; Convert.ToString перетворює int на рядок. Повторний запуск може дати те число.
var lower = 1;
var upper = 6;
var roll = UO.Random(lower, upper);
UO.Print("Roll: " + Convert.ToString(roll));

2. Випадкова пауза між 350 та 700 мілісекундами - функція сценарію

Параметри та порядок виконання:

  • min=350 та max=700 задають включені межі затримки. Результат, наприклад, 350, 512 або 700, записується в delay.
  • UO.Wait отримує один аргумент delay у мілісекундах. Пауза відбувається у UO.Wait; Random тільки обчислює число.
  • Підберіть нижню межу під дії та вимоги вашого сервера. Випадкова затримка не замінює очікування відповіді сервера, якщо наступній дії потрібна ця відповідь.
return  RunScenario();
 object? RunScenario()
{
    var delay = UO.Random(350, 700);
    UO.Print("Waiting " + Convert.ToString(delay) + " ms");
    UO.Wait(delay);
    UO.Print("Wait finished");
    return null;
}

3. Вибрати одну з трьох дій умовою – клас сценарію

Параметри та порядок виконання:

  • min=1, max=3: choice дорівнює 1, 2 або 3. Кожній гілці відповідає одне з допустимих чисел.
  • Дзвінок Random здійснюється один раз до if. Якщо викликати його наново в кожній умові, це будуть різні вибори.
  • Замініть Print потрібними діями вашого скрипта, зберігши перевірки умов, дальності та відповіді сервера для цих дій.
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 choice = UO.Random(1, 3);
        if (Truth(choice == 1))
        {
            UO.Print("First action");
        }
        else
        {
            if (Truth(choice == 2))
            {
                UO.Print("Second action");
            }
            else
            {
                UO.Print("Third action");
            }
        }

        return null;
    }

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

4. Вибрати місце для MassMove всередині рюкзака - прямий скрипт

Параметри та порядок виконання:

  • Перший Random: min=50, max=90, результат x. Другий: min=60, max=100, результат y. Це дві незалежні координати всередині контейнера, не екранні координати й не координати карти.
  • В MassMove delay = 350 мс, quantity = 10 цілих items, type = 0 визначається першим ручним переносом, destination = backpack, x / y беруться зі змінних, z = 0.
  • Після команди перетягніть зразок мишею з вихідного контейнера. Все це включення MassMove використовує одну вибрану позицію. Для випадкової позиції кожного окремого предмета потрібен цикл з окремими MoveItem, а не один виклик MassMove.
  • Виберіть діапазон X/Y усередині доступної області вашого рюкзака. Сервер може змінити розміщення предметів.
var x = UO.Random(50, 90);
var y = UO.Random(60, 100);
UO.MassMove(350, 10, 0, "backpack", x, y, 0);
UO.Print("Drag a source item; position: " + Convert.ToString(x) + ", " + Convert.ToString(y));

5. Негативне зміщення щодо вихідної координати – функція сценарію

Параметри та порядок виконання:

  • В обох викликах min=−2 та max=2: можливі −2, −1, 0, 1, 2. GetX/GetY без аргументів читають координати персонажа.
  • x/y — лише розрахована клітинка у квадраті навколо персонажа. Цей приклад не починає рух і не викидає предмети.
  • Випадкова клітина може виявитися непрохідною або за кордоном картки. Перед ігровою дією використовуйте відповідні перевірки координат та маршруту.
return  RunScenario();
 object? RunScenario()
{
    var offsetX = UO.Random(-2, 2);
    var offsetY = UO.Random(-2, 2);
    var x = UO.GetX() + offsetX;
    var y = UO.GetY() + offsetY;
    UO.Print("Candidate tile: " + Convert.ToString(x) + ", " + Convert.ToString(y));
    return null;
}

6. Збережена сумісність із Random(max) — клас сценарію

Параметри та порядок виконання:

  • У Random(count) є лише max=10: верхня межа виключена, можливі 0..9. Число 10 не випадає.
  • У Random(0, count−1) min=0 та max=9 включно: допустимий діапазон той самий, але виклик робить новий незалежний вибір.
  • count має бути позитивним для вибору індексу. Особливий сумісний випадок Random(0)=0 не означає, що порожня колекція має елемент з індексом 0.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var count = 10;
        var index = UO.Random(count);
        var equivalent = UO.Random(0, count - 1);
        UO.Print("Index 0..9: " + Convert.ToString(index));
        UO.Print("Another independent index: " + Convert.ToString(equivalent));
        return null;
    }
}

7. Рівні межі та повний діапазон int – прямий скрипт

Параметри та порядок виконання:

  • min=7 та max=7 дають єдиний результат 7.
  • min=−100 та max=−50 дають лише негативні числа, включаючи обидві межі.
  • Останній виклик охоплює весь знаковий 32-бітний int. Його результат може бути позитивним, негативним чи нулем.
  • Межі передаються від меншої до більшої. Помилковий виклик Random(10, 1) зупиняється з повідомленням min must not exceed max; його не слід використовувати для перевернутого діапазону.
var fixedValue = UO.Random(7, 7);
var negative = UO.Random(-100, -50);
var signedValue = UO.Random(-2147483648, 2147483647);
UO.Print("Fixed: " + Convert.ToString(fixedValue));
UO.Print("Negative: " + Convert.ToString(negative));
UO.Print("Signed Integer: " + Convert.ToString(signedValue));

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

C# враховує регістр. Використовуйте точне ім’я UO. Числові прапорці порівнюйте з 0; bool використовуйте лише там, де сигнатура повертає bool.

UO.Random(max) — UO.Random(Integer)

Параметри: max (Integer)

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

Під час виклику:

Внутрішній код реалізації, не самостійний скрипт.

public int Random(int max)

        {

            lock (randomSync) return random.Next(max);

        }

UO.Random(min, max) — UO.Random(Integer,Integer)

Параметри: min (Integer), max (Integer)

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

Під час виклику:

Внутрішній код реалізації, не самостійний скрипт.

public int Random(int min, int max)

        {

            if (min > max)

                throw new NativeSubrutineException("UO.Random(min, max): min must not exceed max.");

            if (min == max) return min;

            long count = (long)max - min + 1;

            lock (randomSync)

            {

                if (count <= int.MaxValue)

                    return (int)(min + (long)random.Next((int)count));



                // Inclusive Int32.MaxValue and the full signed range must not

                // overflow. Rejection avoids modulo bias; reuse the four bytes.

                const ulong domain = 1UL << 32;

                ulong limit = domain - domain % (ulong)count;

                uint sample;

                do

                {

                    random.NextBytes(randomRangeBytes);

                    sample = BitConverter.ToUInt32(randomRangeBytes, 0);

                } while (sample >= limit);

                return (int)(min + (long)(sample % (ulong)count));

            }

        }

Clone this wiki locally