EN UO Topic mobiles - LIHACHTETAN/ClassicUO-Bad-Newbie-CSharp-Scripts-IDE GitHub Wiki

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

Characters and creatures

Home · C# · IDE · UO API · A–Z · Examples · Languages

Characters, NPC, monsters and pets already known to the client. Serial defines a specific creature, body/type – its graphics; these are different meanings.

Sections

Topic Commands and explanations
Players UO.GetMobiles · UO.FindMobile
NPC UO.IsNpc · UO.FindMobile
Monsters UO.FindType · UO.FindMobile
Pets UO.GetPetsCurrent · UO.GetPetsMax
Followers UO.GetFollowers · UO.GetFollowersMax
Name / Serial / Body UO.GetName · UO.GetSerial · UO.GetType
Coordinates UO.GetX · UO.GetY · UO.GetZ
Distance UO.GetDistance
Notoriety UO.Notoriety
Status UO.GetStatus · UO.Alive · UO.Dead · UO.Hidden · UO.Poisoned · UO.Paralyzed
Rename UO.Rename

All theme commands

Players / NPC / Monsters

UO.GetMobile · UO.GetMobiles · UO.IsNpc

Pets / Followers

UO.Followers · UO.GetFollowers · UO.FollowersMax · UO.GetFollowersMax · UO.PetsCurrent · UO.GetPetsCurrent · UO.PetsMax · UO.GetPetsMax

Notoriety

UO.Notoriety · UO.GetNotoriety

Rename

UO.CanChangeName · UO.MobileCanBeRenamed · UO.Rename · UO.RenameMobile

Examples on the topic

Each command card has several independent scenarios: direct code, functions and classes. Below are selected short scenarios; restrictions and full analysis are in the cards.

UO.GetMobiles

Parameters, result and all scenarios

var radius = 12;
var allyStatus = 2;
var anyBody = -1;
var maxHeight = 8;
dynamic nearestFirst = true;
dynamic includeMe = false;
dynamic livingOnly = true;
dynamic visibleOnly = true;
var allies = UO.GetMobiles(radius, allyStatus, anyBody, maxHeight, nearestFirst, includeMe, livingOnly, visibleOnly);
if (Truth(ArrayLength(allies) == 0))
{
    return null;
}
UO.AddObject("leader", allies[0]);
UO.Follow(allies[0], 2, false);

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;

UO.GetNotoriety

Parameters, result and all scenarios

var value = UO.GetNotoriety();
UO.Print("GetNotoriety: " + Convert.ToString(value));

Complete command reference


UO.CanChangeName

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

C# signatures

int UO.CanChangeName(object? id);

Checks the client's known sign of the ability to rename mobile.

Parameters

  • id — Mandatory serial/ID of a specific object: int, hex-string or alias self, backpack, lasttarget, lastobject, lastcontainer, laststatus, finditem, lastcorpse or name AddObject. This is not a graphic/type. Unspecified name resolves to 0; the command does not open any new target. The argument is required; for yourself, pass self.

Return value

int 1 — the loaded mobile has the attribute IsRenamable. int 0 - the attribute is missing, the object is not mobile, unknown or deleted. This is the last server permission, for example for a pet. The command does not rename the object and does not guarantee that a subsequent request will be accepted by the server.

The result of the command is a numeric flag: 1 means a fulfilled condition, 0 means an unfulfilled one. After var result = command(...) check if (result != 0) or if (result == 0). Save the result of one call: a repeated call can perform the action again or read the state that has already changed.

Behavior

  • The local client model is read; There are no requests to the server, no waiting or moving.
  • The result refers to the moment of reading. After UO.Wait or other action, the object and its flags may change.
  • This is the last server permission, for example for a pet. The command does not rename the object and does not guarantee that a subsequent request will be accepted by the server.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Check your own state - direct script

Parameters and execution flow:

  • The self argument explicitly selects its character. state - 1/0 only.
  • This is the last server permission, for example for a pet. The command does not rename the object and does not guarantee that a subsequent request will be accepted by the server.
var state = UO.CanChangeName("self");
if (Truth(state))
{
    UO.Print("Rename permission flag is present");
}
else
{
    UO.Print("Rename permission flag is absent");
}

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

2. Check selected mobile - script function

Parameters and execution flow:

  • IsNpc excludes subject and unknown object. target stores one serial, not a live link to a changing lasttarget.
  • The result refers to the field IsRenamable. The data is updated only after the client receives the appropriate state.
return  RunScenario();
 object? RunScenario()
{
    var target = UO.GetSerial("lasttarget");
    if (Truth(UO.IsNPC(target)))
    {
        var state = UO.CanChangeName(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. Compare state before and after pause - script class

Parameters and execution flow:

  • UO.Wait(500) — pause in milliseconds. After it, it is separately checked that mobile still exists.
  • Two photographs are compared. Intermediate changes may be missed, and this is not a continuous subscription to server events.
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.CanChangeName(target);
            await Delay(500);
            if (Truth(UO.IsNPC(target)))
            {
                var after = UO.CanChangeName(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;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.CanChangeName(id) — UO.CanChangeName(Any)

Parameters: id (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

UO.Followers

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

C# signatures

int UO.Followers();

Helps decide in advance whether the character has enough space for the next tamed or summoned creature. Followers shows the occupied management slots, FollowersMax is their total limit. This is not the number of animals nearby or the movement command Follow. Reads your character's status counter: occupied pet control slots.

Parameters

There are no parameters.

Return value

int — occupied pet control slots, 0..255 in the client model. 0 can be a real value, no data, or a missing/destroyed Player. This is quantity, not bool, ID or type: 1 means one unit, not success. The command does not iterate over objects and does not return an array.

Behavior

  • For example, 3 from 5 is occupied - slot 2 is free. The value 4 can mean four creatures for one slot, one for four, or some other combination. For a creature at 2, the “busy < maximum” check slot is not enough: you need maximum - current >= 2. The cost of a specific creature and the limit are determined by the server; do not substitute the constant 5 for FollowersMax.
  • 0 does not prove that the pet is lost, died or released: it may be empty or the status has not yet been updated. An increase in the counter is just an additional sign of a change in control; it does not determine which creature is tamed. Also check the messages from the server and the pet itself. These slots are not equal to places in the stable.
  • The command takes no arguments. Use the exact signatures above.
  • Reading on the game thread takes Player.Followers if the current Player exists and has not been destroyed; otherwise 0. Equipment is not sorted, bonuses are not recalculated, status is not requested, and there is no waiting for updates. A present ghost is not equal to a destroyed Player.
  • PetsCurrent/Followers reports occupied control slots from its status type >= 3. One pet can occupy several slots; The rules for summoned and tamed creatures are set by the server. This is not the number of visible mobile, not the list of ID pets, and not the number of animals nearby.
  • CharacterStatus checks the required body before updating. Weight is in its own extended status, slots are with type 3, Luck - with type 4, server slots WeightMax - with type 5. A compact/old package without an optional counter leaves its previous cache. The new Player starts from scratch; the call does not prove receipt of a fresh status.
  • These functions register the API. They do not run again for every command call. C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
  • Each call reads the local data anew. The variable stores the snapshot; individual reads may receive different server updates. A non-zero result does not test the connection. Zero can be a value or no data.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Calculate available slots before exiting - direct script

Parameters and execution flow:

  • current - busy, maximum - limit, freeSlots - difference. With an unknown/zero limit or inconsistent data, the example terminates without asserting that the space is free. The command only reads the latest status, does not request a new update.
var current = UO.Followers();
var maximum = UO.FollowersMax();
if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(current > maximum))
{
    UO.Print("Follower status is unavailable or inconsistent");
    return null;
}
var freeSlots = maximum - current;
UO.Print("Control slots: " + Convert.ToString(current) + "/" + Convert.ToString(maximum));
UO.Print("Free slots: " + Convert.ToString(freeSlots));

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

2. Check Capacity Before Animal Taming - Script Function

Parameters and execution flow:

  • First, select the desired animal so that its ID is in the lasttarget. requiredSlots=2 - example setting, replace it with the real cost of this creature on your server. If there is not enough space, the target is not set and the skill is not called. Otherwise, the target's queue is prepared BEFORE the single argument UseSkill("Animal Taming"). Starting an attempt does not guarantee success: skill, range, tameability and server response are important.
return  RunScenario();
 object? RunScenario()
{
    var requiredSlots = 2;
    var current = UO.Followers();
    var maximum = UO.FollowersMax();
    if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(maximum - current < requiredSlots))
    {
        UO.Print("Not enough known control slots");
        return null;
    }

    var animal = UO.LastTarget();
    if (Truth(animal == 0))
    {
        UO.Print("Select the animal first");
        return null;
    }

    UO.WaitTargetObject(animal);
    UO.UseSkill("Animal Taming");
    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. Reuse check for creatures of different costs - scenario class

Parameters and execution flow:

  • CanAddFollower is a fully declared user helper, not a new UO command. It returns 1/true if there is a sufficient cache limit, otherwise 0/false. The extraSlots parameter is the cost of the creature being ADDED, not its type/ID. 2 - example; The function does not tame or summon. The check should be repeated immediately before action.
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(CanAddFollower(2)))
        {
            UO.Print("Capacity check passed; verify the creature cost before acting");
        }
        else
        {
            UO.Print("Insufficient capacity or unavailable status");
        }

        return null;
    }

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

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

        return extraSlots <= maximum - current;
    }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.Followers() — UO.Followers()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.Followers

API creation: These functions register the API. They do not run again for every command call.


UO.FollowersMax

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

C# signatures

int UO.FollowersMax();

Helps decide in advance whether the character has enough space for the next tamed or summoned creature. Followers shows the occupied management slots, FollowersMax is their total limit. This is not the number of animals nearby or the movement command Follow. Reads your character's status counter: maximum pet control slots.

Parameters

There are no parameters.

Return value

int — maximum pet control slots, 0..255 in the client model. 0 can be a real value, no data, or a missing/destroyed Player. This is quantity, not bool, ID or type: 1 means one unit, not success. The command does not iterate over objects and does not return an array.

Behavior

  • For example, 3 from 5 is occupied - slot 2 is free. The value 4 can mean four creatures for one slot, one for four, or some other combination. For a creature at 2, the “busy < maximum” check slot is not enough: you need maximum - current >= 2. The cost of a specific creature and the limit are determined by the server; do not substitute the constant 5 for FollowersMax.
  • 0 does not prove that the pet is lost, died or released: it may be empty or the status has not yet been updated. An increase in the counter is just an additional sign of a change in control; it does not determine which creature is tamed. Also check the messages from the server and the pet itself. These slots are not equal to places in the stable.
  • The command takes no arguments. Use the exact signatures above.
  • Reading on the game thread takes Player.FollowersMax if the current Player exists and has not been destroyed; otherwise 0. Equipment is not sorted, bonuses are not recalculated, status is not requested, and there is no waiting for updates. A present ghost is not equal to a destroyed Player.
  • PetsMax/FollowersMax reports the total slot limit allowed by the server from status type >= 3, not free slots. There may be more occupied slots than the limit. Consider the free capacity as maximum - current, replacing the negative result with 0. The team does not release anything, does not tame or call upon anything.
  • CharacterStatus checks the required body before updating. Weight is in its own extended status, slots are with type 3, Luck - with type 4, server slots WeightMax - with type 5. A compact/old package without an optional counter leaves its previous cache. The new Player starts from scratch; the call does not prove receipt of a fresh status.
  • These functions register the API. They do not run again for every command call. C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
  • Each call reads the local data anew. The variable stores the snapshot; individual reads may receive different server updates. A non-zero result does not test the connection. Zero can be a value or no data.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Calculate available slots before exiting - direct script

Parameters and execution flow:

  • current - busy, maximum - limit, freeSlots - difference. With an unknown/zero limit or inconsistent data, the example terminates without asserting that the space is free. The command only reads the latest status, does not request a new update.
var current = UO.Followers();
var maximum = UO.FollowersMax();
if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(current > maximum))
{
    UO.Print("Follower status is unavailable or inconsistent");
    return null;
}
var freeSlots = maximum - current;
UO.Print("Control slots: " + Convert.ToString(current) + "/" + Convert.ToString(maximum));
UO.Print("Free slots: " + Convert.ToString(freeSlots));

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

2. Check Capacity Before Animal Taming - Script Function

Parameters and execution flow:

  • First, select the desired animal so that its ID is in the lasttarget. requiredSlots=2 - example setting, replace it with the real cost of this creature on your server. If there is not enough space, the target is not set and the skill is not called. Otherwise, the target's queue is prepared BEFORE the single argument UseSkill("Animal Taming"). Starting an attempt does not guarantee success: skill, range, tameability and server response are important.
return  RunScenario();
 object? RunScenario()
{
    var requiredSlots = 2;
    var current = UO.Followers();
    var maximum = UO.FollowersMax();
    if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(maximum - current < requiredSlots))
    {
        UO.Print("Not enough known control slots");
        return null;
    }

    var animal = UO.LastTarget();
    if (Truth(animal == 0))
    {
        UO.Print("Select the animal first");
        return null;
    }

    UO.WaitTargetObject(animal);
    UO.UseSkill("Animal Taming");
    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. Reuse check for creatures of different costs - scenario class

Parameters and execution flow:

  • CanAddFollower is a fully declared user helper, not a new UO command. It returns 1/true if there is a sufficient cache limit, otherwise 0/false. The extraSlots parameter is the cost of the creature being ADDED, not its type/ID. 2 - example; The function does not tame or summon. The check should be repeated immediately before action.
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(CanAddFollower(2)))
        {
            UO.Print("Capacity check passed; verify the creature cost before acting");
        }
        else
        {
            UO.Print("Insufficient capacity or unavailable status");
        }

        return null;
    }

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

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

        return extraSlots <= maximum - current;
    }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.FollowersMax() — UO.FollowersMax()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.FollowersMax

API creation: These functions register the API. They do not run again for every command call.


UO.GetFollowers

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

C# signatures

int UO.GetFollowers();

Helps decide in advance whether the character has enough space for the next tamed or summoned creature. Followers shows the occupied management slots, FollowersMax is their total limit. This is not the number of animals nearby or the movement command Follow. Reads your character's status counter: occupied pet control slots.

Parameters

There are no parameters.

Return value

int — occupied pet control slots, 0..255 in the client model. 0 can be a real value, no data, or a missing/destroyed Player. This is quantity, not bool, ID or type: 1 means one unit, not success. The command does not iterate over objects and does not return an array.

Behavior

  • For example, 3 from 5 is occupied - slot 2 is free. The value 4 can mean four creatures for one slot, one for four, or some other combination. For a creature at 2, the “busy < maximum” check slot is not enough: you need maximum - current >= 2. The cost of a specific creature and the limit are determined by the server; do not substitute the constant 5 for FollowersMax.
  • 0 does not prove that the pet is lost, died or released: it may be empty or the status has not yet been updated. An increase in the counter is just an additional sign of a change in control; it does not determine which creature is tamed. Also check the messages from the server and the pet itself. These slots are not equal to places in the stable.
  • The command takes no arguments. Use the exact signatures above.
  • Reading on the game thread takes Player.Followers if the current Player exists and has not been destroyed; otherwise 0. Equipment is not sorted, bonuses are not recalculated, status is not requested, and there is no waiting for updates. A present ghost is not equal to a destroyed Player.
  • PetsCurrent/Followers reports occupied control slots from its status type >= 3. One pet can occupy several slots; The rules for summoned and tamed creatures are set by the server. This is not the number of visible mobile, not the list of ID pets, and not the number of animals nearby.
  • CharacterStatus checks the required body before updating. Weight is in its own extended status, slots are with type 3, Luck - with type 4, server slots WeightMax - with type 5. A compact/old package without an optional counter leaves its previous cache. The new Player starts from scratch; the call does not prove receipt of a fresh status.
  • These functions register the API. They do not run again for every command call. C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
  • Each call reads the local data anew. The variable stores the snapshot; individual reads may receive different server updates. A non-zero result does not test the connection. Zero can be a value or no data.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Calculate available slots before exiting - direct script

Parameters and execution flow:

  • current - busy, maximum - limit, freeSlots - difference. With an unknown/zero limit or inconsistent data, the example terminates without asserting that the space is free. The command only reads the latest status, does not request a new update.
var current = UO.GetFollowers();
var maximum = UO.FollowersMax();
if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(current > maximum))
{
    UO.Print("Follower status is unavailable or inconsistent");
    return null;
}
var freeSlots = maximum - current;
UO.Print("Control slots: " + Convert.ToString(current) + "/" + Convert.ToString(maximum));
UO.Print("Free slots: " + Convert.ToString(freeSlots));

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

2. Check Capacity Before Animal Taming - Script Function

Parameters and execution flow:

  • First, select the desired animal so that its ID is in the lasttarget. requiredSlots=2 - example setting, replace it with the real cost of this creature on your server. If there is not enough space, the target is not set and the skill is not called. Otherwise, the target's queue is prepared BEFORE the single argument UseSkill("Animal Taming"). Starting an attempt does not guarantee success: skill, range, tameability and server response are important.
return  RunScenario();
 object? RunScenario()
{
    var requiredSlots = 2;
    var current = UO.GetFollowers();
    var maximum = UO.FollowersMax();
    if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(maximum - current < requiredSlots))
    {
        UO.Print("Not enough known control slots");
        return null;
    }

    var animal = UO.LastTarget();
    if (Truth(animal == 0))
    {
        UO.Print("Select the animal first");
        return null;
    }

    UO.WaitTargetObject(animal);
    UO.UseSkill("Animal Taming");
    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. Reuse check for creatures of different costs - scenario class

Parameters and execution flow:

  • CanAddFollower is a fully declared user helper, not a new UO command. It returns 1/true if there is a sufficient cache limit, otherwise 0/false. The extraSlots parameter is the cost of the creature being ADDED, not its type/ID. 2 - example; The function does not tame or summon. The check should be repeated immediately before action.
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(CanAddFollower(2)))
        {
            UO.Print("Capacity check passed; verify the creature cost before acting");
        }
        else
        {
            UO.Print("Insufficient capacity or unavailable status");
        }

        return null;
    }

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

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

        return extraSlots <= maximum - current;
    }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetFollowers() — UO.GetFollowers()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.Followers

API creation: These functions register the API. They do not run again for every command call.


UO.GetFollowersMax

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

C# signatures

int UO.GetFollowersMax();

Helps decide in advance whether the character has enough space for the next tamed or summoned creature. Followers shows the occupied management slots, FollowersMax is their total limit. This is not the number of animals nearby or the movement command Follow. Reads your character's status counter: maximum pet control slots.

Parameters

There are no parameters.

Return value

int — maximum pet control slots, 0..255 in the client model. 0 can be a real value, no data, or a missing/destroyed Player. This is quantity, not bool, ID or type: 1 means one unit, not success. The command does not iterate over objects and does not return an array.

Behavior

  • For example, 3 from 5 is occupied - slot 2 is free. The value 4 can mean four creatures for one slot, one for four, or some other combination. For a creature at 2, the “busy < maximum” check slot is not enough: you need maximum - current >= 2. The cost of a specific creature and the limit are determined by the server; do not substitute the constant 5 for FollowersMax.
  • 0 does not prove that the pet is lost, died or released: it may be empty or the status has not yet been updated. An increase in the counter is just an additional sign of a change in control; it does not determine which creature is tamed. Also check the messages from the server and the pet itself. These slots are not equal to places in the stable.
  • The command takes no arguments. Use the exact signatures above.
  • Reading on the game thread takes Player.FollowersMax if the current Player exists and has not been destroyed; otherwise 0. Equipment is not sorted, bonuses are not recalculated, status is not requested, and there is no waiting for updates. A present ghost is not equal to a destroyed Player.
  • PetsMax/FollowersMax reports the total slot limit allowed by the server from status type >= 3, not free slots. There may be more occupied slots than the limit. Consider the free capacity as maximum - current, replacing the negative result with 0. The team does not release anything, does not tame or call upon anything.
  • CharacterStatus checks the required body before updating. Weight is in its own extended status, slots are with type 3, Luck - with type 4, server slots WeightMax - with type 5. A compact/old package without an optional counter leaves its previous cache. The new Player starts from scratch; the call does not prove receipt of a fresh status.
  • These functions register the API. They do not run again for every command call. C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
  • Each call reads the local data anew. The variable stores the snapshot; individual reads may receive different server updates. A non-zero result does not test the connection. Zero can be a value or no data.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Calculate available slots before exiting - direct script

Parameters and execution flow:

  • current - busy, maximum - limit, freeSlots - difference. With an unknown/zero limit or inconsistent data, the example terminates without asserting that the space is free. The command only reads the latest status, does not request a new update.
var current = UO.Followers();
var maximum = UO.GetFollowersMax();
if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(current > maximum))
{
    UO.Print("Follower status is unavailable or inconsistent");
    return null;
}
var freeSlots = maximum - current;
UO.Print("Control slots: " + Convert.ToString(current) + "/" + Convert.ToString(maximum));
UO.Print("Free slots: " + Convert.ToString(freeSlots));

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

2. Check Capacity Before Animal Taming - Script Function

Parameters and execution flow:

  • First, select the desired animal so that its ID is in the lasttarget. requiredSlots=2 - example setting, replace it with the real cost of this creature on your server. If there is not enough space, the target is not set and the skill is not called. Otherwise, the target's queue is prepared BEFORE the single argument UseSkill("Animal Taming"). Starting an attempt does not guarantee success: skill, range, tameability and server response are important.
return  RunScenario();
 object? RunScenario()
{
    var requiredSlots = 2;
    var current = UO.Followers();
    var maximum = UO.GetFollowersMax();
    if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(maximum - current < requiredSlots))
    {
        UO.Print("Not enough known control slots");
        return null;
    }

    var animal = UO.LastTarget();
    if (Truth(animal == 0))
    {
        UO.Print("Select the animal first");
        return null;
    }

    UO.WaitTargetObject(animal);
    UO.UseSkill("Animal Taming");
    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. Reuse check for creatures of different costs - scenario class

Parameters and execution flow:

  • CanAddFollower is a fully declared user helper, not a new UO command. It returns 1/true if there is a sufficient cache limit, otherwise 0/false. The extraSlots parameter is the cost of the creature being ADDED, not its type/ID. 2 - example; The function does not tame or summon. The check should be repeated immediately before action.
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(CanAddFollower(2)))
        {
            UO.Print("Capacity check passed; verify the creature cost before acting");
        }
        else
        {
            UO.Print("Insufficient capacity or unavailable status");
        }

        return null;
    }

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

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

        return extraSlots <= maximum - current;
    }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetFollowersMax() — UO.GetFollowersMax()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.FollowersMax

API creation: These functions register the API. They do not run again for every command call.


UO.GetMobile

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

C# signatures

dynamic UO.GetMobile(object? id);

Collects a compact record of properties one by one ID.

Parameters

  • id — Serial/ID of a specific object: int, decimal/hex string or set alias self, backpack, lasttarget, lastobject or name AddObject. This is not a graphic/type.

Return value

Array of 9 fields: [0] int serial, [1] string name, [2] int X, [3] int Y, [4] int Z, [5] int HP, [6] int MaxHP, [7] int notoriety, [8] int direction 0..7. For the unknown ID the array also has 9 fields: the passed ID is saved, the name is empty, the unavailable numeric properties are 0. This is not a complete Pascal record TMobile.

Behavior

  • Data already downloaded by the client is read. The command does not open the container, move items, or download objects from the entire server.
  • Array - array with indices starting from 0. Store it in var, check ArrayLength before accessing. Elements may disappear from the world after taking a snapshot: check Exists(serial) before taking action.
  • Having nine fields does not confirm the character's existence; use Exists. The command itself does not check that ID belongs to Mobile. The item's name/coordinates and zero character properties may be returned.
  • HP/MaxHP of another character depends on the scale sent by the server. Z is the height, not the layer of equipment.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Read your character's name and health - direct script

Parameters and execution flow:

  • ID=self. [1] is the name, [5]/[6] is the current and maximum HP, not Mana.
  • The array has fixed nine fields. Empty name and 0/0 are possible before entering the world.
var mobile = UO.GetMobile("self");
UO.Print(mobile[1] + ": " + Convert.ToString(mobile[5]) + "/" + Convert.ToString(mobile[6]));

2. Read the coordinates of the selected character - script function

Parameters and execution flow:

  • lasttarget should point to the character. [2]/[3]/[4] - X/Y/Z of the world.
  • First, the presence of the object is checked. If target is an item in the bag, the coordinates refer to its gump.
return  RunScenario();
 object? RunScenario()
{
    var target = UO.GetSerial("lasttarget");
    if (Truth(UO.Exists(target)))
    {
        var mobile = UO.GetMobile(target);
        UO.Print(Convert.ToString(mobile[2]) + "," + Convert.ToString(mobile[3]) + "," + Convert.ToString(mobile[4]));
    }

    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. Check the status of the selected Mobile - script class

Parameters and execution flow:

  • [7] - notoriety value, [8] - direction 0..7. No field is a type.
  • The command reads known data, does not direct the character or switch combat mode.
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 target = UO.GetSerial("lasttarget");
        if (Truth(UO.Exists(target)))
        {
            var mobile = UO.GetMobile(target);
            UO.Print("Notoriety: " + Convert.ToString(mobile[7]));
            UO.Print("Direction: " + Convert.ToString(mobile[8]));
        }

        return null;
    }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetMobile(id) — UO.GetMobile(Any)

Parameters: id (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getmobile":

                {

                    int id = Arg(0);

                    return new InjectionValue(new[]

                    {

                        new InjectionValue(id), new InjectionValue(bridge.GetName(id)), new InjectionValue(bridge.GetX(id)),

                        new InjectionValue(bridge.GetY(id)), new InjectionValue(bridge.GetZ(id)), new InjectionValue(bridge.GetHP(id)),

                        new InjectionValue(bridge.GetMaxHP(id)), new InjectionValue(bridge.GetNotoriety(id)), new InjectionValue(bridge.GetDir(id))

                    });

                }

UO.GetMobiles

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

C# signatures

dynamic UO.GetMobiles();
dynamic UO.GetMobiles(object? distance);
dynamic UO.GetMobiles(object? distance, object? notoriety);
dynamic UO.GetMobiles(object? distance, object? notoriety, object? body);
dynamic UO.GetMobiles(object? distance, object? notoriety, object? body, object? maxZ);
dynamic UO.GetMobiles(object? distance, object? notoriety, object? body, object? maxZ, object? nearest);
dynamic UO.GetMobiles(object? distance, object? notoriety, object? body, object? maxZ, object? nearest, object? includeSelf);
dynamic UO.GetMobiles(object? distance, object? notoriety, object? body, object? maxZ, object? nearest, object? includeSelf, object? aliveOnly);
dynamic UO.GetMobiles(object? distance, object? notoriety, object? body, object? maxZ, object? nearest, object? includeSelf, object? aliveOnly, object? visibleOnly);

Gets an array ID of matching loaded characters/NPC. It is needed when the script needs to check several targets, select its own, calculate the environment, or add its own condition before an action.

Parameters

  • distance — Horizontal radius in cells inclusive: 5 allows distance 0..5. The distance is max(abs(dx),abs(dy)), so the adjacent diagonal is also 1. By default or if the number is negative, UO.FindDistance() is taken rather than unlimited search. 0 leaves the same X/Y cell. Not the length of the route; obstacles and floors are not checked by this parameter.
  • notoriety — Relationship status to the character received from the server: 0 — unknown, 1 — Innocent, 2 — Ally, 3 — Gray, 4 — Criminal, 5 — Enemy, 6 — Murderer, 7 - Invulnerable. The number means one status; "5|6" or an array of numbers - any of the above. It's not the color of the clothes or the class. A negative number (usually -1), 0xFFFF, "any", an empty string or an empty array separately disables this filter. An invalid string without valid numbers does not find anyone. The order of statuses does not set priority. The 5 filter selects Enemy rather than automatically selecting any NPC/monster; actual values ​​depend on the server.
  • body - Graphic of the character's body/NPC, not ID of a specific character and not type of the armor worn. A number, a hex string, the string "0x0190|0x0191" or an array of numbers. 0x0190 (400) - human male; 0x0191 (401) - female human. The mask unites both bodies. The list does not automatically include other races, ghosts, or transformations; table of standard graphic body types. A negative number (-1 by default), 0xFFFF, "any", an empty string or an empty array alone - any body. Unknown text without a valid number produces an empty result.
  • maxZ — Maximum abs(target's Z - own character's Z), inclusive, in world Z units. This is not the number of floors or X/Y cells. maxZ=4 with Z player 10 allows Z target 6..14; 0 requires exactly the same height. By default/for a negative number, UO.FindVertical() is taken. On the stairs, an equal Z can eliminate the desired target. Even a small difference in Z does not prove the accessibility of the floor.
  • nearest - true/1 sorts the array from closest to farthest, then by serial if equal. false/0 preserves client order by default. This is not an additional radius or a selection of one object.
  • includeSelf — true/1 allows you to enable self if all other filters and Ignore allow it. false/0 excludes self by default. Inclusion does not guarantee the presence of self in the result.
  • aliveOnly - true/1 excludes mobiles with IsDead != 0; false/0 does not add this condition by default. Not comparing HP to zero, not searching for corpse items, and not guaranteeing that the target will remain alive after being summoned.
  • visibleOnly - true/1 requires IsVisible=1 according to the current state of ClassicUO; false/0 does not add a condition by default. This is the visibility of the loaded object to the client, not a wall/sight line check. For geometric checking there is a separate UO.CheckLOS with coordinates; the server may still reject the action.

Return value

Array - serial mobiles. An empty array means there are no matches; check ArrayLength before targets[0]. Not body/type, not total HP, not 1/0. The no-argument form still applies FindDistance/FindVertical/Ignore and excludes self.

Behavior

  • Local search: only already downloaded mobiles. Ignore is taken into account; self is excluded, except for the explicit includeSelf=true in commands that support it. Containers and items are not mobiles.
  • The conditions apply together (AND). Valid alternatives within body/notoriety are combined via OR. The search does not change FindItem, FindCount and GetFoundItems.
  • In body/notoriety, a mask with valid numbers uses exactly these: "any|5" still limits it to the value 5. Blank/invalid elements next to valid numbers are ignored. For no restriction, pass -1 separately. Do not carry this rule to classMask: unknown class name rejects the entire list.
  • Teams do not open an area of ​​the world, do not run to the goal, and do not check the passability of the route. Between the selection and the server's processing, the state of the world may change.
  • Passing true and 1 is equivalent for flags, false and 0 as well. Other non-zero numbers also convert to true, but 8/9 are not separate modes; use clear true/false.
  • 0..8 positional arguments are supported. classMask and color are not present in this command; do not carry over the order of the arguments AttackNearest here.
  • Array - snapshot ID. The target may disappear later; recheck Exists if there was a wait between the search and the action. Nothing attacks on its own.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

object? result = UO.GetMobiles(5, 2, -1, 8, true, false, true, true);
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Select the closest ally and enable following - direct script

Parameters and execution flow:

  • nearestFirst=true makes allies[0] the closest ally. Follow enables background walking; stops UO.Follow(0). The ally's name/class is not determined by this command.
var radius = 12;
var allyStatus = 2;
var anyBody = -1;
var maxHeight = 8;
dynamic nearestFirst = true;
dynamic includeMe = false;
dynamic livingOnly = true;
dynamic visibleOnly = true;
var allies = UO.GetMobiles(radius, allyStatus, anyBody, maxHeight, nearestFirst, includeMe, livingOnly, visibleOnly);
if (Truth(ArrayLength(allies) == 0))
{
    return null;
}
UO.AddObject("leader", allies[0]);
UO.Follow(allies[0], 2, false);

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. Count dangerous targets and select an action based on their number - script function

Parameters and execution flow:

  • Here nearest=false is appropriate: the counter is important. ArrayLength is the number of mobiles, not the number of items in the stack. Alarm prints a notification to the log.
return  RunScenario();
 object? RunScenario()
{
    var enemies = UO.GetMobiles(5, "5|6", -1, 4, false, false, true, true);
    var count = ArrayLength(enemies);
    if (Truth(count == 1))
    {
        UO.Attack(enemies[0]);
    }
    else if (Truth(count > 1))
    {
        UO.Alarm();
    }

    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. List on the same cell and height including itself - script class

Parameters and execution flow:

  • distance=0 - identical X/Y, maxZ=0 - identical Z. body is limited to two graphic. includeSelf=true allows self, but it must still match body and aliveOnly. The example reports other characters on the same square.
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 sameCell = UO.GetMobiles(0, -1, "0x0190|0x0191", 0, false, true, true, false);
        var i = 0;
        var others = 0;
        while (Truth(i < ArrayLength(sameCell)))
        {
            if (Truth(sameCell[i] != UO.GetSerial("self")))
            {
                others += 1;
            }

            i += 1;
        }

        if (Truth(others > 0))
        {
            UO.Alarm();
        }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetMobiles() — UO.GetMobiles()

Parameters: No parameters.

Result: dynamic / Any.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetMobiles(values)

UO.GetMobiles(distance) — UO.GetMobiles(Any)

Parameters: distance (Any)

Result: dynamic / Any.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetMobiles(values)

UO.GetMobiles(distance, notoriety) — UO.GetMobiles(Any,Any)

Parameters: distance (Any), notoriety (Any)

Result: dynamic / Any.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetMobiles(values)

UO.GetMobiles(distance, notoriety, body) — UO.GetMobiles(Any,Any,Any)

Parameters: distance (Any), notoriety (Any), body (Any)

Result: dynamic / Any.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetMobiles(values)

UO.GetMobiles(distance, notoriety, body, maxZ) — UO.GetMobiles(Any,Any,Any,Any)

Parameters: distance (Any), notoriety (Any), body (Any), maxZ (Any)

Result: dynamic / Any.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetMobiles(values)

UO.GetMobiles(distance, notoriety, body, maxZ, nearest) — UO.GetMobiles(Any,Any,Any,Any,Any)

Parameters: distance (Any), notoriety (Any), body (Any), maxZ (Any), nearest (Any)

Result: dynamic / Any.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetMobiles(values)

UO.GetMobiles(distance, notoriety, body, maxZ, nearest, includeSelf) — UO.GetMobiles(Any,Any,Any,Any,Any,Any)

Parameters: distance (Any), notoriety (Any), body (Any), maxZ (Any), nearest (Any), includeSelf (Any)

Result: dynamic / Any.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetMobiles(values)

UO.GetMobiles(distance, notoriety, body, maxZ, nearest, includeSelf, aliveOnly) — UO.GetMobiles(Any,Any,Any,Any,Any,Any,Any)

Parameters: distance (Any), notoriety (Any), body (Any), maxZ (Any), nearest (Any), includeSelf (Any), aliveOnly (Any)

Result: dynamic / Any.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetMobiles(values)

UO.GetMobiles(distance, notoriety, body, maxZ, nearest, includeSelf, aliveOnly, visibleOnly) — UO.GetMobiles(Any,Any,Any,Any,Any,Any,Any,Any)

Parameters: distance (Any), notoriety (Any), body (Any), maxZ (Any), nearest (Any), includeSelf (Any), aliveOnly (Any), visibleOnly (Any)

Result: dynamic / Any.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

values => CompactGetMobiles(values)

UO.GetNotoriety

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

C# signatures

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

Reads the character's reputation from the client model.

Parameters

  • id — Optional object only in the specified one-parameter forms: serial number/hex string, "self", "lasttarget" or name AddObject. This is not a graphic/type. Without argument, one's own character is read. Before reading another object, check UO.Exists; an unknown name does not open the target cursor.

Return value

int — 0=unknown, 1=innocent, 2=ally, 3=gray, 4=criminal, 5=enemy, 6=murderer, 7=invulnerable. This is a status code, not hue, karma or fame. Unknown mobile gives 0.

Behavior

  • Already received local data is read. The request does not open status and does not force the server to send an update. After death, map transition, or object deletion, the values ​​may change between two calls.
  • C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Display the current value of your character - direct script

Parameters and execution flow:

  • A call without arguments refers to self. The character's reputation is stored in value.
  • Convert.ToString converts the number to be output and does not change the meaning of the result.
var value = UO.GetNotoriety();
UO.Print("GetNotoriety: " + Convert.ToString(value));

2. Use Value in Application Validation - Script Function

Parameters and execution flow:

  • The value is read once without any arguments. The character's reputation is used in the calculation or condition shown.
  • Numerical thresholds are examples of script conditions and not new client limits. The field stores the server units and restrictions described above.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.GetNotoriety();
    if (Truth(value == 3) || Truth(value == 4))
    {
        UO.Print("Gray or criminal notoriety");
    }

    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. Read property of selected object - script class

Parameters and execution flow:

  • The single argument selects the lasttarget object; its serial must be known to the client. Graphic/type is not passed here.
  • The data of another object may be unknown even with positive Exists. For the coordinates of an item in a bag, the position of the container is obtained, not the world point.
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.GetNotoriety("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;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetNotoriety() — UO.GetNotoriety()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.GetNotoriety(bridge.Self)

API creation: These functions register the API. They do not run again for every command call.

UO.GetNotoriety(id) — UO.GetNotoriety(Any)

Parameters: id (Any/Integer/String)

Result: int / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getnotoriety": return new InjectionValue(bridge.GetNotoriety(Arg(0)));

UO.GetNotoriety(id) — UO.GetNotoriety(Integer)

Parameters: id (Any/Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

UO.GetNotoriety(id) — UO.GetNotoriety(String)

Parameters: id (Any/Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

UO.GetPetsCurrent

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

C# signatures

int UO.GetPetsCurrent();

Helps decide in advance whether the character has enough space for the next tamed or summoned creature. Followers shows the occupied management slots, FollowersMax is their total limit. This is not the number of animals nearby or the movement command Follow. Reads your character's status counter: occupied pet control slots.

Parameters

There are no parameters.

Return value

int — occupied pet control slots, 0..255 in the client model. 0 can be a real value, no data, or a missing/destroyed Player. This is quantity, not bool, ID or type: 1 means one unit, not success. The command does not iterate over objects and does not return an array.

Behavior

  • For example, 3 from 5 is occupied - slot 2 is free. The value 4 can mean four creatures for one slot, one for four, or some other combination. For a creature at 2, the “busy < maximum” check slot is not enough: you need maximum - current >= 2. The cost of a specific creature and the limit are determined by the server; do not substitute the constant 5 for FollowersMax.
  • 0 does not prove that the pet is lost, died or released: it may be empty or the status has not yet been updated. An increase in the counter is just an additional sign of a change in control; it does not determine which creature is tamed. Also check the messages from the server and the pet itself. These slots are not equal to places in the stable.
  • The command takes no arguments. Use the exact signatures above.
  • Reading on the game thread takes Player.Followers if the current Player exists and has not been destroyed; otherwise 0. Equipment is not sorted, bonuses are not recalculated, status is not requested, and there is no waiting for updates. A present ghost is not equal to a destroyed Player.
  • PetsCurrent/Followers reports occupied control slots from its status type >= 3. One pet can occupy several slots; The rules for summoned and tamed creatures are set by the server. This is not the number of visible mobile, not the list of ID pets, and not the number of animals nearby.
  • CharacterStatus checks the required body before updating. Weight is in its own extended status, slots are with type 3, Luck - with type 4, server slots WeightMax - with type 5. A compact/old package without an optional counter leaves its previous cache. The new Player starts from scratch; the call does not prove receipt of a fresh status.
  • These functions register the API. They do not run again for every command call. C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
  • Each call reads the local data anew. The variable stores the snapshot; individual reads may receive different server updates. A non-zero result does not test the connection. Zero can be a value or no data.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Calculate available slots before exiting - direct script

Parameters and execution flow:

  • current - busy, maximum - limit, freeSlots - difference. With an unknown/zero limit or inconsistent data, the example terminates without asserting that the space is free. The command only reads the latest status, does not request a new update.
var current = UO.GetPetsCurrent();
var maximum = UO.FollowersMax();
if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(current > maximum))
{
    UO.Print("Follower status is unavailable or inconsistent");
    return null;
}
var freeSlots = maximum - current;
UO.Print("Control slots: " + Convert.ToString(current) + "/" + Convert.ToString(maximum));
UO.Print("Free slots: " + Convert.ToString(freeSlots));

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

2. Check Capacity Before Animal Taming - Script Function

Parameters and execution flow:

  • First, select the desired animal so that its ID is in the lasttarget. requiredSlots=2 - example setting, replace it with the real cost of this creature on your server. If there is not enough space, the target is not set and the skill is not called. Otherwise, the target's queue is prepared BEFORE the single argument UseSkill("Animal Taming"). Starting an attempt does not guarantee success: skill, range, tameability and server response are important.
return  RunScenario();
 object? RunScenario()
{
    var requiredSlots = 2;
    var current = UO.GetPetsCurrent();
    var maximum = UO.FollowersMax();
    if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(maximum - current < requiredSlots))
    {
        UO.Print("Not enough known control slots");
        return null;
    }

    var animal = UO.LastTarget();
    if (Truth(animal == 0))
    {
        UO.Print("Select the animal first");
        return null;
    }

    UO.WaitTargetObject(animal);
    UO.UseSkill("Animal Taming");
    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. Reuse check for creatures of different costs - scenario class

Parameters and execution flow:

  • CanAddFollower is a fully declared user helper, not a new UO command. It returns 1/true if there is a sufficient cache limit, otherwise 0/false. The extraSlots parameter is the cost of the creature being ADDED, not its type/ID. 2 - example; The function does not tame or summon. The check should be repeated immediately before action.
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(CanAddFollower(2)))
        {
            UO.Print("Capacity check passed; verify the creature cost before acting");
        }
        else
        {
            UO.Print("Insufficient capacity or unavailable status");
        }

        return null;
    }

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

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

        return extraSlots <= maximum - current;
    }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetPetsCurrent() — UO.GetPetsCurrent()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.Followers

API creation: These functions register the API. They do not run again for every command call.


UO.GetPetsMax

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

C# signatures

int UO.GetPetsMax();

Helps decide in advance whether the character has enough space for the next tamed or summoned creature. Followers shows the occupied management slots, FollowersMax is their total limit. This is not the number of animals nearby or the movement command Follow. Reads your character's status counter: maximum pet control slots.

Parameters

There are no parameters.

Return value

int — maximum pet control slots, 0..255 in the client model. 0 can be a real value, no data, or a missing/destroyed Player. This is quantity, not bool, ID or type: 1 means one unit, not success. The command does not iterate over objects and does not return an array.

Behavior

  • For example, 3 from 5 is occupied - slot 2 is free. The value 4 can mean four creatures for one slot, one for four, or some other combination. For a creature at 2, the “busy < maximum” check slot is not enough: you need maximum - current >= 2. The cost of a specific creature and the limit are determined by the server; do not substitute the constant 5 for FollowersMax.
  • 0 does not prove that the pet is lost, died or released: it may be empty or the status has not yet been updated. An increase in the counter is just an additional sign of a change in control; it does not determine which creature is tamed. Also check the messages from the server and the pet itself. These slots are not equal to places in the stable.
  • The command takes no arguments. Use the exact signatures above.
  • Reading on the game thread takes Player.FollowersMax if the current Player exists and has not been destroyed; otherwise 0. Equipment is not sorted, bonuses are not recalculated, status is not requested, and there is no waiting for updates. A present ghost is not equal to a destroyed Player.
  • PetsMax/FollowersMax reports the total slot limit allowed by the server from status type >= 3, not free slots. There may be more occupied slots than the limit. Consider the free capacity as maximum - current, replacing the negative result with 0. The team does not release anything, does not tame or call upon anything.
  • CharacterStatus checks the required body before updating. Weight is in its own extended status, slots are with type 3, Luck - with type 4, server slots WeightMax - with type 5. A compact/old package without an optional counter leaves its previous cache. The new Player starts from scratch; the call does not prove receipt of a fresh status.
  • These functions register the API. They do not run again for every command call. C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
  • Each call reads the local data anew. The variable stores the snapshot; individual reads may receive different server updates. A non-zero result does not test the connection. Zero can be a value or no data.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Calculate available slots before exiting - direct script

Parameters and execution flow:

  • current - busy, maximum - limit, freeSlots - difference. With an unknown/zero limit or inconsistent data, the example terminates without asserting that the space is free. The command only reads the latest status, does not request a new update.
var current = UO.Followers();
var maximum = UO.GetPetsMax();
if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(current > maximum))
{
    UO.Print("Follower status is unavailable or inconsistent");
    return null;
}
var freeSlots = maximum - current;
UO.Print("Control slots: " + Convert.ToString(current) + "/" + Convert.ToString(maximum));
UO.Print("Free slots: " + Convert.ToString(freeSlots));

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

2. Check Capacity Before Animal Taming - Script Function

Parameters and execution flow:

  • First, select the desired animal so that its ID is in the lasttarget. requiredSlots=2 - example setting, replace it with the real cost of this creature on your server. If there is not enough space, the target is not set and the skill is not called. Otherwise, the target's queue is prepared BEFORE the single argument UseSkill("Animal Taming"). Starting an attempt does not guarantee success: skill, range, tameability and server response are important.
return  RunScenario();
 object? RunScenario()
{
    var requiredSlots = 2;
    var current = UO.Followers();
    var maximum = UO.GetPetsMax();
    if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(maximum - current < requiredSlots))
    {
        UO.Print("Not enough known control slots");
        return null;
    }

    var animal = UO.LastTarget();
    if (Truth(animal == 0))
    {
        UO.Print("Select the animal first");
        return null;
    }

    UO.WaitTargetObject(animal);
    UO.UseSkill("Animal Taming");
    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. Reuse check for creatures of different costs - scenario class

Parameters and execution flow:

  • CanAddFollower is a fully declared user helper, not a new UO command. It returns 1/true if there is a sufficient cache limit, otherwise 0/false. The extraSlots parameter is the cost of the creature being ADDED, not its type/ID. 2 - example; The function does not tame or summon. The check should be repeated immediately before action.
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(CanAddFollower(2)))
        {
            UO.Print("Capacity check passed; verify the creature cost before acting");
        }
        else
        {
            UO.Print("Insufficient capacity or unavailable status");
        }

        return null;
    }

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

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

        return extraSlots <= maximum - current;
    }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.GetPetsMax() — UO.GetPetsMax()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.FollowersMax

API creation: These functions register the API. They do not run again for every command call.


UO.IsNPC

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

C# signatures

int UO.IsNPC(object? objID);

Checks the loaded mobile against the explicitly transmitted serial.

Parameters

  • objID — Mandatory serial/ID of a specific object: int, hex-string or alias self, backpack, lasttarget, lastobject, lastcontainer, laststatus, finditem, lastcorpse or name AddObject. This is not a graphic/type. Unspecified name resolves to 0; the command does not open any new target. Only IsNpc also has a no-argument form registered: self is used.

Return value

int 1 — loaded, not deleted mobile. int 0 — item, unknown serial or remote object. The name IsNPC does not mean "non-player character only": your own character and other players also give 1.

The result of the command is a numeric flag: 1 means a fulfilled condition, 0 means an unfulfilled one. After var result = command(...) check if (result != 0) or if (result == 0). Save the result of one call: a repeated call can perform the action again or read the state that has already changed.

Behavior

  • The local client model is read; There are no requests to the server, no waiting or moving.
  • The result refers to the moment of reading. After UO.Wait or other action, the object and its flags may change.
  • The game manager treats IsNpc and IsNPC as variants of the same name; in the C# source code, use the exact spelling of the public form. This result cannot reliably distinguish the player from NPC; the rules for this distinction depend on the server.

In C# the name's characters are case-sensitive: UO.IsNPC requires an argument; the form UO.IsNpc() without arguments selects self. Both names are verified by mobile, including players, and not exclusively NPC.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Check serial of your own character - direct script

Parameters and execution flow:

  • This C#-form requires an argument. Own character also gives 1; This is a mobile check, not exclusively NPC.
int mobile = UO.IsNPC(UO.Self());
UO.Print($"Self is a loaded mobile: {mobile != 0}");

2. Select loaded target before reading coordinates - script function

Parameters and execution flow:

  • Serial is taken from lasttarget. Coordinates are read only if there is a mobile known to the client.
return  RunScenario();
 object? RunScenario()
{
    string target = UO.GetSerial("lasttarget");
    if (UO.IsNPC(target) == 0)
        return false;
    UO.Print($"Mobile coordinates: {UO.GetX(target)}, {UO.GetY(target)}, {UO.GetZ(target)}");
    return true;
    return null;
}

3. Compare Character and Backpack - Scenario Class

Parameters and execution flow:

  • The character who enters the world is a mobile, and the backpack is an item. The result refers to the moment of local reading.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        int character = UO.IsNPC(UO.Self());
        int bag = UO.IsNPC(UO.Backpack());
        UO.Print($"Character mobile flag: {character}; backpack mobile flag: {bag}");
        return null;
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.IsNPC(objID) — UO.IsNPC(Any)

Parameters: objID (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

case "isnpc": return new InjectionValue(bridge.IsNpc(Arg(0)));

UO.IsNpc

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

C# signatures

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

Parameters

  • id — Mandatory serial/ID of a specific object: int, hex-string or alias self, backpack, lasttarget, lastobject, lastcontainer, laststatus, finditem, lastcorpse or name AddObject. This is not a graphic/type. Unspecified name resolves to 0; the command does not open any new target. Only IsNpc also has a no-argument form registered: self is used.

Return value

int 1 — loaded, not deleted mobile. int 0 — item, unknown serial or remote object. The name IsNPC does not mean "non-player character only": your own character and other players also give 1.

The result of the command is a numeric flag: 1 means a fulfilled condition, 0 means an unfulfilled one. After var result = command(...) check if (result != 0) or if (result == 0). Save the result of one call: a repeated call can perform the action again or read the state that has already changed.

Behavior

  • The local client model is read; There are no requests to the server, no waiting or moving.
  • The result refers to the moment of reading. After UO.Wait or other action, the object and its flags may change.
  • The game manager treats IsNpc and IsNPC as variants of the same name; in the C# source code, use the exact spelling of the public form. This result cannot reliably distinguish the player from NPC; the rules for this distinction depend on the server.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Test your own character - direct script

Parameters and execution flow:

  • The no-argument form selects self. The result 1/0 is not serial and does not distinguish NPC from the player.
int mobile = UO.IsNpc();
if (mobile != 0) UO.Print("Self is a loaded mobile");

2. Distinguish between mobile, object and unknown target - script function

Parameters and execution flow:

  • Pre-select lasttarget. First, the loading of the object is checked; the classification of mobile does not determine its hostility.
return  RunScenario();
 object? RunScenario()
{
    string target = UO.GetSerial("lasttarget");
    if (UO.Exists(target) == 0)
        UO.Print("Target is not loaded");
    else
        UO.Print(UO.IsNpc(target) != 0 ? "Mobile: NPC or player" : "Loaded item");
    return null;
}

3. Read hits known to the client only from mobile - script class

Parameters and execution flow:

  • Other people's hits can be normalized by the server. The check does not ask for full status.
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()
    {
        string target = UO.GetSerial("lasttarget");
        if (UO.IsNpc(target) != 0)
            UO.Print($"Known hits: {UO.GetHP(target)}/{UO.GetMaxHP(target)}");
        return null;
    }
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.IsNpc() — UO.IsNpc()

Parameters: No parameters.

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

UO.IsNpc(id) — UO.IsNpc(Integer)

Parameters: id (Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

UO.IsNpc(id) — UO.IsNpc(String)

Parameters: id (Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

UO.MobileCanBeRenamed

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

C# signatures

int UO.MobileCanBeRenamed(object? mobID);

Checks the client's known sign of the ability to rename mobile.

Parameters

  • mobID — Mandatory serial/ID of a specific object: int, hex-string or alias self, backpack, lasttarget, lastobject, lastcontainer, laststatus, finditem, lastcorpse or name AddObject. This is not a graphic/type. Unspecified name resolves to 0; the command does not open any new target. The argument is required; for yourself, pass self.

Return value

int 1 — the loaded mobile has the attribute IsRenamable. int 0 - the attribute is missing, the object is not mobile, unknown or deleted. This is the last server permission, for example for a pet. The command does not rename the object and does not guarantee that a subsequent request will be accepted by the server.

The result of the command is a numeric flag: 1 means a fulfilled condition, 0 means an unfulfilled one. After var result = command(...) check if (result != 0) or if (result == 0). Save the result of one call: a repeated call can perform the action again or read the state that has already changed.

Behavior

  • The local client model is read; There are no requests to the server, no waiting or moving.
  • The result refers to the moment of reading. After UO.Wait or other action, the object and its flags may change.
  • This is the last server permission, for example for a pet. The command does not rename the object and does not guarantee that a subsequent request will be accepted by the server.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Check your own state - direct script

Parameters and execution flow:

  • The self argument explicitly selects its character. state - 1/0 only.
  • This is the last server permission, for example for a pet. The command does not rename the object and does not guarantee that a subsequent request will be accepted by the server.
var state = UO.MobileCanBeRenamed("self");
if (Truth(state))
{
    UO.Print("Rename permission flag is present");
}
else
{
    UO.Print("Rename permission flag is absent");
}

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

2. Check selected mobile - script function

Parameters and execution flow:

  • IsNpc excludes subject and unknown object. target stores one serial, not a live link to a changing lasttarget.
  • The result refers to the field IsRenamable. The data is updated only after the client receives the appropriate state.
return  RunScenario();
 object? RunScenario()
{
    var target = UO.GetSerial("lasttarget");
    if (Truth(UO.IsNPC(target)))
    {
        var state = UO.MobileCanBeRenamed(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. Compare state before and after pause - script class

Parameters and execution flow:

  • UO.Wait(500) — pause in milliseconds. After it, it is separately checked that mobile still exists.
  • Two photographs are compared. Intermediate changes may be missed, and this is not a continuous subscription to server events.
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.MobileCanBeRenamed(target);
            await Delay(500);
            if (Truth(UO.IsNPC(target)))
            {
                var after = UO.MobileCanBeRenamed(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;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.MobileCanBeRenamed(mobID) — UO.MobileCanBeRenamed(Any)

Parameters: mobID (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

case "mobilecanberenamed": return new InjectionValue(bridge.CanChangeName(Arg(0)));

UO.Notoriety

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

C# signatures

int UO.Notoriety();

Reads the character's reputation from the client model.

Parameters

There are no parameters.

Return value

int — 0=unknown, 1=innocent, 2=ally, 3=gray, 4=criminal, 5=enemy, 6=murderer, 7=invulnerable. This is a status code, not hue, karma or fame. Unknown mobile gives 0.

Behavior

  • Already received local data is read. The request does not open status and does not force the server to send an update. After death, map transition, or object deletion, the values ​​may change between two calls.
  • C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Display the current value of your character - direct script

Parameters and execution flow:

  • A call without arguments refers to self. The character's reputation is stored in value.
  • Convert.ToString converts the number to be output and does not change the meaning of the result.
var value = UO.Notoriety();
UO.Print("Notoriety: " + Convert.ToString(value));

2. Use Value in Application Validation - Script Function

Parameters and execution flow:

  • The value is read once without any arguments. The character's reputation is used in the calculation or condition shown.
  • Numerical thresholds are examples of script conditions and not new client limits. The field stores the server units and restrictions described above.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.Notoriety();
    if (Truth(value == 3) || Truth(value == 4))
    {
        UO.Print("Gray or criminal notoriety");
    }

    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. Watch change in one second - script class

Parameters and execution flow:

  • Both calls without an argument read their current value. UO.Wait(1000) gives a pause in milliseconds between shots.
  • The change being compared is the character's reputation. An example does not change anything in the world and does not wait endlessly. Events within this second may be missed.
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.Notoriety();
        await Delay(1000);
        var after = UO.Notoriety();
        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;
}

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.Notoriety() — UO.Notoriety()

Parameters: No parameters.

Result: int / Integer.

During a call:

The call executes the stored handler delegate. The registration method creates this delegate while building the API.

Internal implementation code; this is not a standalone script.

() => bridge.GetNotoriety(bridge.Self)

API creation: These functions register the API. They do not run again for every command call.


UO.PetsCurrent

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

C# signatures

int UO.PetsCurrent();

Helps decide in advance whether the character has enough space for the next tamed or summoned creature. Followers shows the occupied management slots, FollowersMax is their total limit. This is not the number of animals nearby or the movement command Follow. Reads your character's status counter: occupied pet control slots.

Parameters

There are no parameters.

Return value

int — occupied pet control slots, 0..255 in the client model. 0 can be a real value, no data, or a missing/destroyed Player. This is quantity, not bool, ID or type: 1 means one unit, not success. The command does not iterate over objects and does not return an array.

Behavior

  • For example, 3 from 5 is occupied - slot 2 is free. The value 4 can mean four creatures for one slot, one for four, or some other combination. For a creature at 2, the “busy < maximum” check slot is not enough: you need maximum - current >= 2. The cost of a specific creature and the limit are determined by the server; do not substitute the constant 5 for FollowersMax.
  • 0 does not prove that the pet is lost, died or released: it may be empty or the status has not yet been updated. An increase in the counter is just an additional sign of a change in control; it does not determine which creature is tamed. Also check the messages from the server and the pet itself. These slots are not equal to places in the stable.
  • The command takes no arguments. Use the exact signatures above.
  • Reading on the game thread takes Player.Followers if the current Player exists and has not been destroyed; otherwise 0. Equipment is not sorted, bonuses are not recalculated, status is not requested, and there is no waiting for updates. A present ghost is not equal to a destroyed Player.
  • PetsCurrent/Followers reports occupied control slots from its status type >= 3. One pet can occupy several slots; The rules for summoned and tamed creatures are set by the server. This is not the number of visible mobile, not the list of ID pets, and not the number of animals nearby.
  • CharacterStatus checks the required body before updating. Weight is in its own extended status, slots are with type 3, Luck - with type 4, server slots WeightMax - with type 5. A compact/old package without an optional counter leaves its previous cache. The new Player starts from scratch; the call does not prove receipt of a fresh status.
  • These functions register the API. They do not run again for every command call. C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
  • Each call reads the local data anew. The variable stores the snapshot; individual reads may receive different server updates. A non-zero result does not test the connection. Zero can be a value or no data.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Calculate available slots before exiting - direct script

Parameters and execution flow:

  • current - busy, maximum - limit, freeSlots - difference. With an unknown/zero limit or inconsistent data, the example terminates without asserting that the space is free. The command only reads the latest status, does not request a new update.
var current = UO.PetsCurrent();
var maximum = UO.FollowersMax();
if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(current > maximum))
{
    UO.Print("Follower status is unavailable or inconsistent");
    return null;
}
var freeSlots = maximum - current;
UO.Print("Control slots: " + Convert.ToString(current) + "/" + Convert.ToString(maximum));
UO.Print("Free slots: " + Convert.ToString(freeSlots));

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

2. Check Capacity Before Animal Taming - Script Function

Parameters and execution flow:

  • First, select the desired animal so that its ID is in the lasttarget. requiredSlots=2 - example setting, replace it with the real cost of this creature on your server. If there is not enough space, the target is not set and the skill is not called. Otherwise, the target's queue is prepared BEFORE the single argument UseSkill("Animal Taming"). Starting an attempt does not guarantee success: skill, range, tameability and server response are important.
return  RunScenario();
 object? RunScenario()
{
    var requiredSlots = 2;
    var current = UO.PetsCurrent();
    var maximum = UO.FollowersMax();
    if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(maximum - current < requiredSlots))
    {
        UO.Print("Not enough known control slots");
        return null;
    }

    var animal = UO.LastTarget();
    if (Truth(animal == 0))
    {
        UO.Print("Select the animal first");
        return null;
    }

    UO.WaitTargetObject(animal);
    UO.UseSkill("Animal Taming");
    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. Reuse check for creatures of different costs - scenario class

Parameters and execution flow:

  • CanAddFollower is a fully declared user helper, not a new UO command. It returns 1/true if there is a sufficient cache limit, otherwise 0/false. The extraSlots parameter is the cost of the creature being ADDED, not its type/ID. 2 - example; The function does not tame or summon. The check should be repeated immediately before action.
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(CanAddFollower(2)))
        {
            UO.Print("Capacity check passed; verify the creature cost before acting");
        }
        else
        {
            UO.Print("Insufficient capacity or unavailable status");
        }

        return null;
    }

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

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

        return extraSlots <= maximum - current;
    }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.PetsCurrent() — UO.PetsCurrent()

Parameters: No parameters.

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

case "petscurrent": return new InjectionValue(bridge.Followers);

UO.PetsMax

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

C# signatures

int UO.PetsMax();

Helps decide in advance whether the character has enough space for the next tamed or summoned creature. Followers shows the occupied management slots, FollowersMax is their total limit. This is not the number of animals nearby or the movement command Follow. Reads your character's status counter: maximum pet control slots.

Parameters

There are no parameters.

Return value

int — maximum pet control slots, 0..255 in the client model. 0 can be a real value, no data, or a missing/destroyed Player. This is quantity, not bool, ID or type: 1 means one unit, not success. The command does not iterate over objects and does not return an array.

Behavior

  • For example, 3 from 5 is occupied - slot 2 is free. The value 4 can mean four creatures for one slot, one for four, or some other combination. For a creature at 2, the “busy < maximum” check slot is not enough: you need maximum - current >= 2. The cost of a specific creature and the limit are determined by the server; do not substitute the constant 5 for FollowersMax.
  • 0 does not prove that the pet is lost, died or released: it may be empty or the status has not yet been updated. An increase in the counter is just an additional sign of a change in control; it does not determine which creature is tamed. Also check the messages from the server and the pet itself. These slots are not equal to places in the stable.
  • The command takes no arguments. Use the exact signatures above.
  • Reading on the game thread takes Player.FollowersMax if the current Player exists and has not been destroyed; otherwise 0. Equipment is not sorted, bonuses are not recalculated, status is not requested, and there is no waiting for updates. A present ghost is not equal to a destroyed Player.
  • PetsMax/FollowersMax reports the total slot limit allowed by the server from status type >= 3, not free slots. There may be more occupied slots than the limit. Consider the free capacity as maximum - current, replacing the negative result with 0. The team does not release anything, does not tame or call upon anything.
  • CharacterStatus checks the required body before updating. Weight is in its own extended status, slots are with type 3, Luck - with type 4, server slots WeightMax - with type 5. A compact/old package without an optional counter leaves its previous cache. The new Player starts from scratch; the call does not prove receipt of a fresh status.
  • These functions register the API. They do not run again for every command call. C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
  • Each call reads the local data anew. The variable stores the snapshot; individual reads may receive different server updates. A non-zero result does not test the connection. Zero can be a value or no data.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The result of one call is printed in the journal. A number is not converted to bool; an array is displayed as its element count.

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

1. Calculate available slots before exiting - direct script

Parameters and execution flow:

  • current - busy, maximum - limit, freeSlots - difference. With an unknown/zero limit or inconsistent data, the example terminates without asserting that the space is free. The command only reads the latest status, does not request a new update.
var current = UO.Followers();
var maximum = UO.PetsMax();
if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(current > maximum))
{
    UO.Print("Follower status is unavailable or inconsistent");
    return null;
}
var freeSlots = maximum - current;
UO.Print("Control slots: " + Convert.ToString(current) + "/" + Convert.ToString(maximum));
UO.Print("Free slots: " + Convert.ToString(freeSlots));

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

2. Check Capacity Before Animal Taming - Script Function

Parameters and execution flow:

  • First, select the desired animal so that its ID is in the lasttarget. requiredSlots=2 - example setting, replace it with the real cost of this creature on your server. If there is not enough space, the target is not set and the skill is not called. Otherwise, the target's queue is prepared BEFORE the single argument UseSkill("Animal Taming"). Starting an attempt does not guarantee success: skill, range, tameability and server response are important.
return  RunScenario();
 object? RunScenario()
{
    var requiredSlots = 2;
    var current = UO.Followers();
    var maximum = UO.PetsMax();
    if (Truth(UO.Self() == 0) || Truth(maximum <= 0) || Truth(maximum - current < requiredSlots))
    {
        UO.Print("Not enough known control slots");
        return null;
    }

    var animal = UO.LastTarget();
    if (Truth(animal == 0))
    {
        UO.Print("Select the animal first");
        return null;
    }

    UO.WaitTargetObject(animal);
    UO.UseSkill("Animal Taming");
    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. Reuse check for creatures of different costs - scenario class

Parameters and execution flow:

  • CanAddFollower is a fully declared user helper, not a new UO command. It returns 1/true if there is a sufficient cache limit, otherwise 0/false. The extraSlots parameter is the cost of the creature being ADDED, not its type/ID. 2 - example; The function does not tame or summon. The check should be repeated immediately before action.
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(CanAddFollower(2)))
        {
            UO.Print("Capacity check passed; verify the creature cost before acting");
        }
        else
        {
            UO.Print("Insufficient capacity or unavailable status");
        }

        return null;
    }

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

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

        return extraSlots <= maximum - current;
    }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.PetsMax() — UO.PetsMax()

Parameters: No parameters.

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

case "petsmax": return new InjectionValue(bridge.FollowersMax);

UO.Rename

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

C# signatures

void UO.Rename(object? mobile, object? newName);

Requests a character/pet name change.

Parameters

  • mobile — Serial/ID object: int, numeric/hex string or set alias, for example "lasttarget". This is not a graphic/type. Check the loaded object before taking action.
  • newName — Text through ToString; saved as transmitted.

Return value

void - no value. Call on a separate line; completion does not confirm the server's action.

Behavior

  • The order is serial, then the new name. Bridge.RenameMobile calls GameActions.Rename(serial, name). API does not check CanChangeName and does not change the local Name itself.
  • The server checks the permission to rename. For pet, first check MobileCanBeRenamed; the request does not guarantee acceptance of the name.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The command is a separate statement. The message before it marks the start of the call; it does not confirm a server action.

UO.Print("Calling UO.Rename");
UO.Rename(UO.GetSerial("lasttarget"), "Companion");

1. Direct call - direct script

Parameters and execution flow:

  • Requests a character/pet name change.
var id = UO.GetSerial("lasttarget");
if (Truth(UO.MobileCanBeRenamed(id)))
{
    UO.Rename(id, "Companion");
}

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

2. Explicit option - script function

Parameters and execution flow:

  • The order is serial, then the new name. Bridge.RenameMobile calls GameActions.Rename(serial, name). API does not check CanChangeName and does not change the local Name itself.
return  RunScenario();
 object? RunScenario()
{
    var id = UO.GetSerial("lasttarget");
    if (Truth(UO.Exists(id)) && Truth(UO.MobileCanBeRenamed(id)))
    {
        UO.Rename(id, "Guardian");
    }

    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. Full Helper Function - Script Class

Parameters and execution flow:

  • The server checks the permission to rename. For pet, first check MobileCanBeRenamed; the request does not guarantee acceptance of the name.
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()
    {
        RenamePet(UO.GetSerial("lasttarget"), "Companion");
        return null;
    }

    void RenamePet(dynamic id, dynamic name)
    {
        if (Truth(UO.MobileCanBeRenamed(id)) && Truth(Len(name) > 0))
        {
            UO.Rename(id, name);
        }
    }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.Rename(mobile, newName) — UO.Rename(Any,Any)

Parameters: mobile (Any), newName (Any)

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "rename": bridge.RenameMobile(Arg(0, bridge.LastTarget), Text(1)); break;

UO.RenameMobile

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

C# signatures

void UO.RenameMobile(object? mobID, object? newName);

Requests a character/pet name change.

Parameters

  • mobID — Serial/ID object: int, numeric/hex string or set alias, for example "lasttarget". This is not a graphic/type. Check the loaded object before taking action.
  • newName — Text through ToString; saved as transmitted.

Return value

void - no value. Call on a separate line; completion does not confirm the server's action.

Behavior

  • The order is serial, then the new name. Bridge.RenameMobile calls GameActions.Rename(serial, name). API does not check CanChangeName and does not change the local Name itself.
  • The server checks the permission to rename. For pet, first check MobileCanBeRenamed; the request does not guarantee acceptance of the name.

Standalone C# scripts

Each example can be saved as a separate file .csx and run in IDE. The UO object and wait functions provide the host of the current game session. Replace demo serial names, coordinates and addresses with your own.

Simple example

Run this code as a separate .csx file. Arguments appear directly in the call; replace demonstration names, serials and addresses with your own.

The command is a separate statement. The message before it marks the start of the call; it does not confirm a server action.

UO.Print("Calling UO.RenameMobile");
UO.RenameMobile(UO.GetSerial("lasttarget"), "Companion");

1. Direct call - direct script

Parameters and execution flow:

  • Requests a character/pet name change.
var id = UO.GetSerial("lasttarget");
if (Truth(UO.MobileCanBeRenamed(id)))
{
    UO.RenameMobile(id, "Companion");
}

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

2. Explicit option - script function

Parameters and execution flow:

  • The order is serial, then the new name. Bridge.RenameMobile calls GameActions.Rename(serial, name). API does not check CanChangeName and does not change the local Name itself.
return  RunScenario();
 object? RunScenario()
{
    var id = UO.GetSerial("lasttarget");
    if (Truth(UO.Exists(id)) && Truth(UO.MobileCanBeRenamed(id)))
    {
        UO.RenameMobile(id, "Guardian");
    }

    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. Full Helper Function - Script Class

Parameters and execution flow:

  • The server checks the permission to rename. For pet, first check MobileCanBeRenamed; the request does not guarantee acceptance of the name.
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()
    {
        RenamePet(UO.GetSerial("lasttarget"), "Companion");
        return null;
    }

    void RenamePet(dynamic id, dynamic name)
    {
        if (Truth(UO.MobileCanBeRenamed(id)) && Truth(Len(name) > 0))
        {
            UO.RenameMobile(id, name);
        }
    }

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

Command implementation

C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.

UO.RenameMobile(mobID, newName) — UO.RenameMobile(Any,Any)

Parameters: mobID (Any), newName (Any)

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "renamemobile": bridge.RenameMobile(Arg(0), Text(1)); return InjectionValue.Unit;
⚠️ **GitHub.com Fallback** ⚠️