RU UO Topic character Part 5 - LIHACHTETAN/ClassicUO-Bad-Newbie-CSharp-Scripts-IDE GitHub Wiki

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

Характер — 5

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

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

1 · 2 · 3 · 4 · 5

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


UO.Undress

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

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

int UO.Undress();

Снимает одежду и доспехи со слоёв 3,4,5,6,7,8,10,12,13,14,17,18,19,20,22,23,24. Руки, волосы, бороду, рюкзак, верховое животное и банк не затрагивает.

Параметры

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

Возвращает

Числовой флаг int: 1 (условие выполнено) — локальная операция принята, 0 (условие не выполнено) — отказ. Это не подтверждение сервера, не ID и не количество. Сервер может отказать позже; проверяйте фактическую экипировку после ответа.

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

Поведение

  • Нужны загруженные предметы и свободная рука перетаскивания. При снятии требуется настоящий рюкзак self: запасной GrabBag не используется. Неизвестные, уничтоженные и неподходящие вещи дают отказ. Чужие предметы нельзя снять через UnequipItems. Набор не является атомарной транзакцией.
  • EquipItems/UnequipItems применяют DressSpeed после принятой операции перед следующим элементом; Disarm/Undress — после каждого занятого слоя. Снятие дополнительно соблюдает DropDelay при принятом переносе. Одноимённые настройки других runtime не меняются; ускорение не отменяет ограничения сервера.
  • Неверная форма вызова, неизвестное имя слоя или непереводимое в число значение могут вызвать ошибку скрипта вместо 0. Снимок экипировки содержит только уже загруженные данные. В помощнике ChangeAndConfirm layer=1 — правая рука: для другой вещи передайте её реальный слой.
  • Для массива 1 означает, что приняты все перечисленные операции; при любом отказе возвращается 0. Остальные элементы всё равно обрабатываются, отката нет. Пустой массив даёт 1 без действий. Disarm/Undress дают 1 также при уже пустых нужных слоях; частичный отказ даёт 0.
  • UO.EquipItems · UO.UnequipItems · UO.DressSpeed · UO.DropDelay · UO.ObjAtLayerEx

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

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

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

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

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

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

1. Undress — Один выбранный предмет или слой — прямой скрипт

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

  • Сначала выберите подходящую вещь в игре: lasttarget — её ID. В примере Equip/WearItem слой 1 требует оружие правой руки. Unequip(1) снимает правую руку; Disarm/Undress работают со своими фиксированными слоями. После отказа нет автоматических повторов.
return UO.Undress();

2. Undress — Два предмета и сохранённые ID — функция сценария

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

  • Для надевания 0x0F5E — пример меча, 0x1B76 — пример щита. FindType ищет их среди загруженных вещей рюкзака, ASC преобразует возвращённый hex-ID. Для снятия читаются собственные текущие слои. Если нужной вещи нет, сценарий завершается. Массив хранит два ID; каждый предмет переносится целиком.
return  RunScenario();
 object? RunScenario()
{
    var first = UO.ObjAtLayerEx(5, UO.Self());
    var second = UO.ObjAtLayerEx(4, UO.Self());
    if (Truth(first == 0) || Truth(second == 0))
    {
        return 0;
    }

    UO.AddObject("saved_first", first);
    UO.AddObject("saved_second", second);
    return UO.Undress();
    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. Undress — Полная функция с ограниченным ожиданием — класс сценария

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

  • ChangeAndConfirm выполняет команду один раз. Затем до 20 раз проверяет фактическое состояние с паузой 100 мс. 1 — проверка увидела ожидаемое состояние, 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()
    {
        return ChangeAndConfirm();
        return null;
    }

    dynamic ChangeAndConfirm()
    {
        if (!(Truth(UO.Undress())))
        {
            return 0;
        }

        dynamic[] layers = new dynamic[checked((int)(16) + 1)];
        layers[0] = 3;
        layers[1] = 4;
        layers[2] = 5;
        layers[3] = 6;
        layers[4] = 7;
        layers[5] = 8;
        layers[6] = 10;
        layers[7] = 12;
        layers[8] = 13;
        layers[9] = 14;
        layers[10] = 17;
        layers[11] = 18;
        layers[12] = 19;
        layers[13] = 20;
        layers[14] = 22;
        layers[15] = 23;
        layers[16] = 24;
        for (int attempt = (int)(1); attempt <= 20; attempt += (int)(1))
        {
            dynamic empty = true;
            for (int i = (int)(0); i <= ArrayLength(layers) - 1; i += (int)(1))
            {
                if (Truth(UO.ObjAtLayerEx(layers[i], UO.Self()) != 0))
                {
                    empty = false;
                }
            }

            if (Truth(empty))
            {
                return 1;
            }

            UO.Wait(100);
        }

        return 0;
    }

    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.Undress() — UO.Undress()

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

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

При вызове:

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

public int Undress()

            => Unequip(dressLayers, "Clothing removed.");

UO.Unequip

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

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

int UO.Unequip(object? layer);

Снимает свою вещь с указанного слоя в собственный рюкзак.

Параметры

  • layer — Номер слоя, например 1 — правая рука, 2 — левая. Equip и Unequip также принимают имя слоя, например "Rhand". WearItem использует числовой слой. Слой должен совпадать с wearable-слоем предмета; это не graphic и не ID.

Возвращает

Числовой флаг int: 1 (условие выполнено) — локальная операция принята, 0 (условие не выполнено) — отказ. Это не подтверждение сервера, не ID и не количество. Сервер может отказать позже; проверяйте фактическую экипировку после ответа.

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

Поведение

  • Нужны загруженные предметы и свободная рука перетаскивания. При снятии требуется настоящий рюкзак self: запасной GrabBag не используется. Неизвестные, уничтоженные и неподходящие вещи дают отказ. Чужие предметы нельзя снять через UnequipItems. Набор не является атомарной транзакцией.
  • EquipItems/UnequipItems применяют DressSpeed после принятой операции перед следующим элементом; Disarm/Undress — после каждого занятого слоя. Снятие дополнительно соблюдает DropDelay при принятом переносе. Одноимённые настройки других runtime не меняются; ускорение не отменяет ограничения сервера.
  • Неверная форма вызова, неизвестное имя слоя или непереводимое в число значение могут вызвать ошибку скрипта вместо 0. Снимок экипировки содержит только уже загруженные данные. В помощнике ChangeAndConfirm layer=1 — правая рука: для другой вещи передайте её реальный слой.
  • UO.EquipItems · UO.UnequipItems · UO.DressSpeed · UO.DropDelay · UO.ObjAtLayerEx

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

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

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

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

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

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

1. Unequip — Один выбранный предмет или слой — прямой скрипт

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

  • Сначала выберите подходящую вещь в игре: lasttarget — её ID. В примере Equip/WearItem слой 1 требует оружие правой руки. Unequip(1) снимает правую руку; Disarm/Undress работают со своими фиксированными слоями. После отказа нет автоматических повторов.
return UO.Unequip(1);

2. Unequip — Два предмета и сохранённые ID — функция сценария

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

  • Для надевания 0x0F5E — пример меча, 0x1B76 — пример щита. FindType ищет их среди загруженных вещей рюкзака, ASC преобразует возвращённый hex-ID. Для снятия читаются собственные текущие слои. Если нужной вещи нет, сценарий завершается. Массив хранит два ID; каждый предмет переносится целиком.
return  RunScenario();
 object? RunScenario()
{
    var first = UO.ObjAtLayerEx(1, UO.Self());
    var second = UO.ObjAtLayerEx(2, UO.Self());
    if (Truth(first == 0) || Truth(second == 0))
    {
        return 0;
    }

    UO.AddObject("saved_first", first);
    UO.AddObject("saved_second", second);
    var firstOk = UO.Unequip(1);
    var secondOk = UO.Unequip(2);
    return firstOk != 0 && secondOk != 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;

3. Unequip — Полная функция с ограниченным ожиданием — класс сценария

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

  • ChangeAndConfirm выполняет команду один раз. Затем до 20 раз проверяет фактическое состояние с паузой 100 мс. 1 — проверка увидела ожидаемое состояние, 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 item = UO.ObjAtLayerEx(1, UO.Self());
        return ChangeAndConfirm(1, item);
        return null;
    }

    dynamic ChangeAndConfirm(dynamic layer, dynamic item)
    {
        if (Truth(item == 0))
        {
            return 0;
        }

        if (Truth(UO.ObjAtLayerEx(layer, UO.Self()) != item))
        {
            return 0;
        }

        if (!(Truth(UO.Unequip(layer))))
        {
            return 0;
        }

        for (int attempt = (int)(1); attempt <= 20; attempt += (int)(1))
        {
            if (Truth(UO.ObjAtLayerEx(layer, UO.Self()) == 0))
            {
                return 1;
            }

            UO.Wait(100);
        }

        return 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.Unequip(layer) — UO.Unequip(Any)

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

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

При вызове:

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

case "unequip":

                    return new InjectionValue(arguments[0].Kind == InjectionValueKind.String ? Unequip(Text(0)) : bridge.Unequip(Arg(0)));

UO.Unequip(layer) — UO.Unequip(String)

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

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

При вызове:

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

public int Unequip(string layer) => bridge.Unequip(ConvertLayer(layer));

UO.UnequipItems

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

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

dynamic UO.UnequipItems(object? items);

Снимает перечисленные собственные надетые вещи в рюкзак. ID чужой вещи не снимает вашу вещь с того же слоя.

Параметры

  • items — Обязательный ID или массив ID предметов. Элементы массива — числа или числовые hex-строки. Одиночный аргумент также принимает "lasttarget"/имя AddObject. Для массива используйте объявление переменной items[1] для двух элементов с индексами 0 и 1. Передаются вещи, а не номера слоёв и не type.

Возвращает

Числовой флаг int: 1 (условие выполнено) — локальная операция принята, 0 (условие не выполнено) — отказ. Это не подтверждение сервера, не ID и не количество. Сервер может отказать позже; проверяйте фактическую экипировку после ответа.

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

Поведение

  • Нужны загруженные предметы и свободная рука перетаскивания. При снятии требуется настоящий рюкзак self: запасной GrabBag не используется. Неизвестные, уничтоженные и неподходящие вещи дают отказ. Чужие предметы нельзя снять через UnequipItems. Набор не является атомарной транзакцией.
  • EquipItems/UnequipItems применяют DressSpeed после принятой операции перед следующим элементом; Disarm/Undress — после каждого занятого слоя. Снятие дополнительно соблюдает DropDelay при принятом переносе. Одноимённые настройки других runtime не меняются; ускорение не отменяет ограничения сервера.
  • Неверная форма вызова, неизвестное имя слоя или непереводимое в число значение могут вызвать ошибку скрипта вместо 0. Снимок экипировки содержит только уже загруженные данные. В помощнике ChangeAndConfirm layer=1 — правая рука: для другой вещи передайте её реальный слой.
  • Для массива 1 означает, что приняты все перечисленные операции; при любом отказе возвращается 0. Остальные элементы всё равно обрабатываются, отката нет. Пустой массив даёт 1 без действий. Disarm/Undress дают 1 также при уже пустых нужных слоях; частичный отказ даёт 0.
  • UO.EquipItems · UO.UnequipItems · UO.DressSpeed · UO.DropDelay · UO.ObjAtLayerEx

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

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

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

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

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

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

1. UnequipItems — Один выбранный предмет или слой — прямой скрипт

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

  • Сначала выберите подходящую вещь в игре: lasttarget — её ID. В примере Equip/WearItem слой 1 требует оружие правой руки. Unequip(1) снимает правую руку; Disarm/Undress работают со своими фиксированными слоями. После отказа нет автоматических повторов.
var item = Asc(UO.GetSerial("lasttarget"), 0);
if (Truth(item == 0))
{
    return 0;
}
return UO.UnequipItems(item);

int Asc(object? value, int fallback = 0) { string text = Convert.ToString(value) ?? ""; if (text.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) return int.TryParse(text[2..], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out int hex) ? hex : fallback; return int.TryParse(text, out int number) ? number : fallback; }
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. UnequipItems — Два предмета и сохранённые ID — функция сценария

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

  • Для надевания 0x0F5E — пример меча, 0x1B76 — пример щита. FindType ищет их среди загруженных вещей рюкзака, ASC преобразует возвращённый hex-ID. Для снятия читаются собственные текущие слои. Если нужной вещи нет, сценарий завершается. Массив хранит два ID; каждый предмет переносится целиком.
return  RunScenario();
 object? RunScenario()
{
    var first = UO.ObjAtLayerEx(1, UO.Self());
    var second = UO.ObjAtLayerEx(2, UO.Self());
    if (Truth(first == 0) || Truth(second == 0))
    {
        return 0;
    }

    UO.AddObject("saved_first", first);
    UO.AddObject("saved_second", second);
    dynamic[] items = new dynamic[checked((int)(1) + 1)];
    items[0] = first;
    items[1] = second;
    return UO.UnequipItems(items);
    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. UnequipItems — Полная функция с ограниченным ожиданием — класс сценария

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

  • ChangeAndConfirm выполняет команду один раз. Затем до 20 раз проверяет фактическое состояние с паузой 100 мс. 1 — проверка увидела ожидаемое состояние, 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 item = Asc(UO.GetSerial("lasttarget"), 0);
        if (Truth(item == 0))
        {
            return 0;
        }

        return ChangeAndConfirm(1, item);
        return null;
    }

    dynamic ChangeAndConfirm(dynamic layer, dynamic item)
    {
        if (Truth(item == 0))
        {
            return 0;
        }

        if (Truth(UO.ObjAtLayerEx(layer, UO.Self()) != item))
        {
            return 0;
        }

        if (!(Truth(UO.UnequipItems(item))))
        {
            return 0;
        }

        for (int attempt = (int)(1); attempt <= 20; attempt += (int)(1))
        {
            if (Truth(UO.ObjAtLayerEx(layer, UO.Self()) == 0))
            {
                return 1;
            }

            UO.Wait(100);
        }

        return 0;
    }

    int Asc(object? value, int fallback = 0)
    {
        string text = Convert.ToString(value) ?? "";
        if (text.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
            return int.TryParse(text[2..], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out int hex) ? hex : fallback;
        return int.TryParse(text, out int number) ? number : fallback;
    }

    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.UnequipItems(items) — UO.UnequipItems(Any)

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

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

При вызове:

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

case "unequipitems":

                    return new InjectionValue(ChangeEquipmentItems(ArrayArg(0), false));

UO.UnsetArm

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

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

void UO.UnsetArm(object? name);

Удаляет запись именованного набора оружия, не разоружая персонажа.

Параметры

  • name — Строковое имя набора, например "travel" или "battle". Имена нечувствительны к регистру. Наборы одежды и оружия хранятся отдельно: одинаковое имя допустимо в обоих. Это не ID вещи и не имя файла. Только SetDress допускает отсутствие имени: тогда записывается отдельный набор для DressSavedSet/EquipDressSet.

Возвращает

void — значения нет. Вызывайте отдельной строкой; не присваивайте результат и не сравнивайте его с true. Сохранение и удаление меняют запись, а не экипировку.

Поведение

  • Одежда: слои 3,4,5,6,7,8,10,12,13,14,17,18,19,20,22,23,24. Оружие: только 1 и 2. Волосы, борода, рюкзак, животное и банк в эти наборы не входят.
  • Записываются конкретные serial уже загруженных вещей в своих слоях. Повторное сохранение того же имени заменяет запись. Пустые слои тоже имеют смысл: при восстановлении соответствующий занятый слой будет освобождён в собственный рюкзак. Поэтому сохранённый полностью пустой набор снимает вещи своих слоёв.
  • Набор хранится в состоянии runtime. Сам вызов не создаёт файл и не гарантирует перенос набора в другой профиль или новый runtime. Сначала сохраните нужный набор в используемом состоянии. Загрузка/сохранение общего состояния клиента — отдельный механизм.
  • Удаление касается только записи выбранного имени. Вещи остаются на персонаже, другие имена и другой вид наборов не затрагиваются. Повторное удаление отсутствующей записи допустимо. У UnsetDress и UnsetArm имя обязательно.
  • UO.SetDress · UO.Dress · UO.DressSavedSet · UO.SetArm · UO.Arm · UO.DressSpeed
  • В обычном клиентском host эти данные состояния берутся из GetPersistentState менеджера и общие для скриптов/чата/макросов одного мира/профиля, а не принадлежат одному скрипту. Другой процесс или явно отдельный InjectionRuntimeState имеет другое состояние. Загрузка/очистка профиля может его заменить; сохранённые serial всё равно проверяются по загруженному миру.

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

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

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

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

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

UO.Print("Calling UO.UnsetArm");
UO.UnsetArm("battle");

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

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

  • Удаляется только указанная запись. Одежда/оружие не снимаются.
UO.UnsetArm("battle");

2. Имена и режим запроса — функция сценария

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

  • Имена travel и battle удаляются отдельно. Одинаковое имя другого вида набора сохраняется.
return  RunScenario();
 object? RunScenario()
{
    UO.UnsetArm("travel");
    UO.UnsetArm("battle");
    return null;
}

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

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

  • CleanupSets — полностью объявленная процедура уборки двух собственных имён. prefix формирует имена записей, не файловые пути.
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()
    {
        CleanupSets("mine_");
        return null;
    }

    void CleanupSets(dynamic prefix)
    {
        UO.UnsetArm(prefix + "travel");
        UO.UnsetArm(prefix + "battle");
    }
}

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

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

UO.UnsetArm(name) — UO.UnsetArm(String)

Параметры: name (String)

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

При вызове:

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

public void UnsetArm(string name)

        {

            armSets.Remove(name);

            SystemMessage("Arm set removed.");

        }

UO.UnsetDress

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

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

void UO.UnsetDress(object? name);

Удаляет запись именованного набора одежды, не снимая вещи.

Параметры

  • name — Строковое имя набора, например "travel" или "battle". Имена нечувствительны к регистру. Наборы одежды и оружия хранятся отдельно: одинаковое имя допустимо в обоих. Это не ID вещи и не имя файла. Только SetDress допускает отсутствие имени: тогда записывается отдельный набор для DressSavedSet/EquipDressSet.

Возвращает

void — значения нет. Вызывайте отдельной строкой; не присваивайте результат и не сравнивайте его с true. Сохранение и удаление меняют запись, а не экипировку.

Поведение

  • Одежда: слои 3,4,5,6,7,8,10,12,13,14,17,18,19,20,22,23,24. Оружие: только 1 и 2. Волосы, борода, рюкзак, животное и банк в эти наборы не входят.
  • Записываются конкретные serial уже загруженных вещей в своих слоях. Повторное сохранение того же имени заменяет запись. Пустые слои тоже имеют смысл: при восстановлении соответствующий занятый слой будет освобождён в собственный рюкзак. Поэтому сохранённый полностью пустой набор снимает вещи своих слоёв.
  • Набор хранится в состоянии runtime. Сам вызов не создаёт файл и не гарантирует перенос набора в другой профиль или новый runtime. Сначала сохраните нужный набор в используемом состоянии. Загрузка/сохранение общего состояния клиента — отдельный механизм.
  • Удаление касается только записи выбранного имени. Вещи остаются на персонаже, другие имена и другой вид наборов не затрагиваются. Повторное удаление отсутствующей записи допустимо. У UnsetDress и UnsetArm имя обязательно.
  • UO.SetDress · UO.Dress · UO.DressSavedSet · UO.SetArm · UO.Arm · UO.DressSpeed
  • В обычном клиентском host эти данные состояния берутся из GetPersistentState менеджера и общие для скриптов/чата/макросов одного мира/профиля, а не принадлежат одному скрипту. Другой процесс или явно отдельный InjectionRuntimeState имеет другое состояние. Загрузка/очистка профиля может его заменить; сохранённые serial всё равно проверяются по загруженному миру.

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

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

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

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

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

UO.Print("Calling UO.UnsetDress");
UO.UnsetDress("travel");

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

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

  • Удаляется только указанная запись. Одежда/оружие не снимаются.
UO.UnsetDress("travel");

2. Имена и режим запроса — функция сценария

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

  • Имена travel и battle удаляются отдельно. Одинаковое имя другого вида набора сохраняется.
return  RunScenario();
 object? RunScenario()
{
    UO.UnsetDress("travel");
    UO.UnsetDress("battle");
    return null;
}

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

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

  • CleanupSets — полностью объявленная процедура уборки двух собственных имён. prefix формирует имена записей, не файловые пути.
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()
    {
        CleanupSets("mine_");
        return null;
    }

    void CleanupSets(dynamic prefix)
    {
        UO.UnsetDress(prefix + "travel");
        UO.UnsetDress(prefix + "battle");
    }
}

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

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

UO.UnsetDress(name) — UO.UnsetDress(String)

Параметры: name (String)

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

При вызове:

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

public void UnsetDress(string name)

        {

            dressSets.Remove(name);

            SystemMessage("Dress set removed.");

        }

UO.UseOtherPaperdollScroll

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

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

void UO.UseOtherPaperdollScroll(object? objID);

Использует указанный serial через bridge.UseObject, обычно открывая paperdoll персонажа.

Параметры

  • objID — Serial/ID объекта: int, числовая/hex-строка или установленный алиас, например "lasttarget". Это не graphic/type. До действия проверяйте загруженный объект.

Возвращает

void — значения нет. Вызывайте отдельной строкой; завершение не подтверждает действие сервера.

Поведение

  • ObjID относится к персонажу, не к ID кнопки прокрутки. Вызов не читает структуру paperdoll и не ждёт её открытия.
  • Bridge посылает запрос на игровом потоке. Действуют правила сервера; встроенного ожидания подтверждения нет.

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

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

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

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

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

UO.Print("Calling UO.UseOtherPaperdollScroll");
UO.UseOtherPaperdollScroll(UO.GetSerial("lasttarget"));

1. Прямой вызов — прямой скрипт

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

  • Использует указанный serial через bridge.UseObject, обычно открывая paperdoll персонажа.
var id = UO.GetSerial("lasttarget");
if (Truth(UO.Exists(id)))
{
    UO.UseOtherPaperdollScroll(id);
}

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

2. Явный вариант — функция сценария

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

  • ObjID относится к персонажу, не к ID кнопки прокрутки. Вызов не читает структуру paperdoll и не ждёт её открытия.
return  RunScenario();
 object? RunScenario()
{
    var id = UO.GetSerial("self");
    if (Truth(UO.Exists(id)))
    {
        UO.UseOtherPaperdollScroll(id);
    }

    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. Полная вспомогательная функция — класс сценария

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

  • Bridge посылает запрос на игровом потоке. Действуют правила сервера; встроенного ожидания подтверждения нет.
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()
    {
        ApplyToLoaded(UO.GetSerial("lasttarget"));
        return null;
    }

    void ApplyToLoaded(dynamic id)
    {
        if (Truth(UO.Exists(id)))
        {
            UO.UseOtherPaperdollScroll(id);
        }
    }

    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.UseOtherPaperdollScroll(objID) — UO.UseOtherPaperdollScroll(Any)

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

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

При вызове:

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

case "useotherpaperdollscroll": bridge.UseObject(Arg(0)); return InjectionValue.Unit;

UO.UseSelfPaperdollScroll

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

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

void UO.UseSelfPaperdollScroll();

Использует текущего персонажа, обычно открывая paperdoll.

Параметры

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

Возвращает

void — значения нет. Вызывайте отдельной строкой; завершение не подтверждает действие сервера.

Поведение

  • ExecuteClientApiCompatibility вызывает bridge.UseObject(bridge.Self). Нет отдельного чтения или нажатия элемента paperdoll; это обычный запрос UseObject для self.
  • В примерах UO.Wait задаёт только паузу скрипта; окончание паузы не доказывает выполнение запроса сервером.

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

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

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

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

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

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

1. Прямой вызов — прямой скрипт

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

  • Использует текущего персонажа, обычно открывая paperdoll.
UO.UseSelfPaperdollScroll();

2. Явный вариант — функция сценария

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

  • ExecuteClientApiCompatibility вызывает bridge.UseObject(bridge.Self). Нет отдельного чтения или нажатия элемента paperdoll; это обычный запрос UseObject для self.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Self() != 0))
    {
        UO.UseSelfPaperdollScroll();
    }

    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 задаёт только паузу скрипта; окончание паузы не доказывает выполнение запроса сервером.
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.UseSelfPaperdollScroll();
        UO.Wait(500);
        UO.Print(UO.Name());
        return null;
    }
}

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

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

UO.UseSelfPaperdollScroll() — UO.UseSelfPaperdollScroll()

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

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

При вызове:

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

case "useselfpaperdollscroll": bridge.UseObject(bridge.Self); return InjectionValue.Unit;

UO.WearItem

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

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

dynamic UO.WearItem(object? layer, object? objID);

Надевает выбранный предмет на числовой слой своего персонажа.

Параметры

  • layer — Номер слоя, например 1 — правая рука, 2 — левая. Equip и Unequip также принимают имя слоя, например "Rhand". WearItem использует числовой слой. Слой должен совпадать с wearable-слоем предмета; это не graphic и не ID.
  • objID — ID конкретной загруженной вещи: целое число, hex-строка, "lasttarget" или имя AddObject. Это не type. Пример с 0x0F5E сначала ищет меч этого graphic и получает его ID.

Возвращает

Числовой флаг int: 1 (условие выполнено) — локальная операция принята, 0 (условие не выполнено) — отказ. Это не подтверждение сервера, не ID и не количество. Сервер может отказать позже; проверяйте фактическую экипировку после ответа.

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

Поведение

  • Нужны загруженные предметы и свободная рука перетаскивания. При снятии требуется настоящий рюкзак self: запасной GrabBag не используется. Неизвестные, уничтоженные и неподходящие вещи дают отказ. Чужие предметы нельзя снять через UnequipItems. Набор не является атомарной транзакцией.
  • EquipItems/UnequipItems применяют DressSpeed после принятой операции перед следующим элементом; Disarm/Undress — после каждого занятого слоя. Снятие дополнительно соблюдает DropDelay при принятом переносе. Одноимённые настройки других runtime не меняются; ускорение не отменяет ограничения сервера.
  • Неверная форма вызова, неизвестное имя слоя или непереводимое в число значение могут вызвать ошибку скрипта вместо 0. Снимок экипировки содержит только уже загруженные данные. В помощнике ChangeAndConfirm layer=1 — правая рука: для другой вещи передайте её реальный слой.
  • UO.EquipItems · UO.UnequipItems · UO.DressSpeed · UO.DropDelay · UO.ObjAtLayerEx

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

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

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

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

int item = UO.LastTarget();
if (item != 0)
    UO.Print("Accepted flag: " + Convert.ToString(UO.WearItem(1, item)));

1. WearItem — Один выбранный предмет или слой — прямой скрипт

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

  • Сначала выберите подходящую вещь в игре: lasttarget — её ID. В примере Equip/WearItem слой 1 требует оружие правой руки. Unequip(1) снимает правую руку; Disarm/Undress работают со своими фиксированными слоями. После отказа нет автоматических повторов.
var item = Asc(UO.GetSerial("lasttarget"), 0);
if (Truth(item == 0))
{
    return 0;
}
return UO.WearItem(1, item);

int Asc(object? value, int fallback = 0) { string text = Convert.ToString(value) ?? ""; if (text.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) return int.TryParse(text[2..], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out int hex) ? hex : fallback; return int.TryParse(text, out int number) ? number : fallback; }
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. WearItem — Два предмета и сохранённые ID — функция сценария

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

  • Для надевания 0x0F5E — пример меча, 0x1B76 — пример щита. FindType ищет их среди загруженных вещей рюкзака, ASC преобразует возвращённый hex-ID. Для снятия читаются собственные текущие слои. Если нужной вещи нет, сценарий завершается. Массив хранит два ID; каждый предмет переносится целиком.
return  RunScenario();
 object? RunScenario()
{
    var first = Asc(UO.FindType(0x0F5E, -1, "backpack"), 0);
    var second = Asc(UO.FindType(0x1B76, -1, "backpack"), 0);
    if (Truth(first == 0) || Truth(second == 0))
    {
        return 0;
    }

    UO.AddObject("saved_first", first);
    UO.AddObject("saved_second", second);
    var firstOk = UO.WearItem(1, first);
    var secondOk = UO.WearItem(2, second);
    return firstOk != 0 && secondOk != 0;
    return null;
}

int Asc(object? value, int fallback = 0)
{
    string text = Convert.ToString(value) ?? "";
    if (text.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
        return int.TryParse(text[2..], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out int hex) ? hex : fallback;
    return int.TryParse(text, out int number) ? number : fallback;
}

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

3. WearItem — Полная функция с ограниченным ожиданием — класс сценария

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

  • ChangeAndConfirm выполняет команду один раз. Затем до 20 раз проверяет фактическое состояние с паузой 100 мс. 1 — проверка увидела ожидаемое состояние, 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 item = Asc(UO.GetSerial("lasttarget"), 0);
        if (Truth(item == 0))
        {
            return 0;
        }

        return ChangeAndConfirm(1, item);
        return null;
    }

    dynamic ChangeAndConfirm(dynamic layer, dynamic item)
    {
        if (Truth(item == 0))
        {
            return 0;
        }

        if (!(Truth(UO.WearItem(layer, item))))
        {
            return 0;
        }

        for (int attempt = (int)(1); attempt <= 20; attempt += (int)(1))
        {
            if (Truth(UO.ObjAtLayerEx(layer, UO.Self()) == item))
            {
                return 1;
            }

            UO.Wait(100);
        }

        return 0;
    }

    int Asc(object? value, int fallback = 0)
    {
        string text = Convert.ToString(value) ?? "";
        if (text.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
            return int.TryParse(text[2..], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out int hex) ? hex : fallback;
        return int.TryParse(text, out int number) ? number : fallback;
    }

    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.WearItem(layer, objID) — UO.WearItem(Any,Any)

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

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

При вызове:

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

case "wearitem": return new InjectionValue(bridge.Equip(Arg(0), Arg(1)));

UO.Weight

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

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

int UO.Weight();

Читает счётчик статуса своего персонажа: текущий вес в stones.

Параметры

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

Возвращает

int — текущий вес в stones, 0..65535 в модели клиента. 0 может быть реальным значением, отсутствием данных либо отсутствующим/уничтоженным Player. Это количество, не bool, ID или type: 1 означает одну единицу, а не успех. Команда не перебирает объекты и не возвращает массив.

Поведение

  • Команда не принимает аргументов. Используйте точные сигнатуры выше.
  • Чтение в игровом потоке берёт Player.Weight, если текущий Player существует и не уничтожен; иначе 0. Экипировка не перебирается, бонусы не пересчитываются, статус не запрашивается, ожидания обновления нет. Присутствующий призрак не равен уничтоженному Player.
  • Weight читает общий вес, сообщённый сервером, в stones. Какие веса тела, экипировки и вложенных сумок входят в сумму, определяют правила шарда. Команда не обходит контейнеры, не суммирует веса предметов и не обновляет закрытые сумки. Это не свойство Weight отдельного предмета и не число items.
  • CharacterStatus проверяет обязательное тело до обновления. Weight есть в собственном расширенном статусе, слоты — с type 3, Luck — с type 4, серверный WeightMax — с type 5. Компактный/старый пакет без необязательного счётчика оставляет его предыдущий кэш. Новый Player начинает с нулей; вызов не доказывает получение свежего статуса.
  • Эти функции создают регистрацию API; они не выполняются заново при каждом вызове команды. C# учитывает регистр. Используйте точное имя UO. Числовые флаги сравнивайте с 0; bool используйте только там, где сигнатура возвращает bool.
  • Каждый вызов читает локальные данные заново. Переменная хранит снимок; отдельные чтения могут получить разные обновления сервера. Ненулевой результат не проверяет подключение. Ноль может быть значением либо отсутствием данных.

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

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

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

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

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

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

1. Вывести сохранённый счётчик — прямой скрипт

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

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

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

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

  • UO.Wait(500) разделяет before и after на 500 миллисекунд. difference может быть положительной, нулевой или отрицательной; промежуточные обновления и смена персонажа могут быть пропущены. Пауза относится к примеру.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var before = UO.Weight();
    await Delay(500);
    var after = UO.Weight();
    var difference = after - before;
    UO.Print("Counter change: " + Convert.ToString(difference));
    return null;
}

Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));

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

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

  • CanCarry(extra) получает дополнительный вес в stones; 10 — пример, не число стопок. Отвергает отрицательный extra, отсутствие Player или maximum <= 0, читает текущий вес и предел, затем возвращает bool: true либо false по extra <= maximum - current. Вычитание избегает переполнения current + extra. При перегрузе результат false даже для extra=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()
    {
        if (Truth(Truth(CanCarry(10)) == true))
        {
            UO.Print("Local check passed");
        }
        else
        {
            UO.Print("Local check failed or data unavailable");
        }

        return null;
    }

    dynamic CanCarry(dynamic extra)
    {
        if (Truth(extra < 0) || Truth(UO.Self() == 0))
        {
            return false;
        }

        var current = UO.Weight();
        var maximum = UO.MaxWeight();
        if (Truth(maximum <= 0))
        {
            return false;
        }

        return extra <= maximum - current;
    }

    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.Weight() — UO.Weight()

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

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

При вызове:

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

case "weight": return new InjectionValue(bridge.Weight);
⚠️ **GitHub.com Fallback** ⚠️