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

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

Multis & Houses

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

Composite objects of the world: houses and other multi, their parts and position on the map.

Sections

Topic Commands and explanations
GetMultis UO.GetMultis
Multi Parts UO.GetMultiAllParts
Parts at Position UO.GetMultiPartsAtPosition
IsHouse UO.IsHouse

All theme commands

Multis / Houses

UO.GetMultis · UO.GetMultiAllParts · UO.GetMultiPartsAtPosition · UO.IsHouse

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.GetMultis

Parameters, result and all scenarios

var items = UO.GetMultis();
UO.Print(Convert.ToString(ArrayLength(items)));

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

UO.GetMultiAllParts

Parameters, result and all scenarios

var houses = UO.GetMultis();
if (Truth(ArrayLength(houses) == 0))
{
    return null;
}
var parts = UO.GetMultiAllParts(houses[0]);
UO.Print(Convert.ToString(ArrayLength(parts)));

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;

Complete command reference


UO.GetMultiAllParts

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

C# signatures

dynamic UO.GetMultiAllParts(object? multiID);

Reads records of a component of one house.

Parameters

  • multiID — 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. There should be ID loaded at home in HouseManager.

Return value

Array<Array>. Each line contains 9 fields: [0] graphic/type components, [1] hue, [2] world X, [3] world Y, [4] world Z, [5] multiOffsetX - X offset from multi, [6] multiOffsetY - Y offset, [7] multiOffsetZ - Z offset, [8] multiSerial - serial home. No components - empty Array. Graphic is not ID; Individual static components do not have their own serial here.

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.
  • The known, non-deleted components HouseManager are returned. Separate static maps and land are not included in this list. Rows are a snapshot; fixed order or Z sort is not promised.

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.

var multis = (object?[])UO.GetMultis();
if (multis.Length > 0) {
    var parts = (object?[])UO.GetMultiAllParts(multis[0]);
    UO.Print("Parts: " + parts.Length);
}

1. Count components - direct script

Parameters and execution flow:

  • First, a loaded house is selected.
  • Length is the number of components, not their height or the number of houses.
var houses = UO.GetMultis();
if (Truth(ArrayLength(houses) == 0))
{
    return null;
}
var parts = UO.GetMultiAllParts(houses[0]);
UO.Print(Convert.ToString(ArrayLength(parts)));

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. Read graphic and position of first component - script function

Parameters and execution flow:

  • parts[0] is the first line of the array. Its [0] - type, [2]/[3]/[4] - world X/Y/Z.
  • The indices [5]/[6]/[7] contain relative offsets instead.
return  RunScenario();
 object? RunScenario()
{
    var houses = UO.GetMultis();
    if (Truth(ArrayLength(houses) == 0))
    {
        return null;
    }

    var parts = UO.GetMultiAllParts(houses[0]);
    if (Truth(ArrayLength(parts) > 0))
    {
        var part = parts[0];
        UO.Print("Type: 0x" + Hex(part[0]));
        UO.Print(Convert.ToString(part[2]) + "," + Convert.ToString(part[3]) + "," + Convert.ToString(part[4]));
    }

    return null;
}

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

3. Traverse Components and Output Owners - Script Class

Parameters and execution flow:

  • [8] - serial home, [7] - offset Z component.
  • Don't pass part[0] to a command expecting serial at home: it's a graphic of a separate component.
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 houses = UO.GetMultis();
        if (Truth(ArrayLength(houses) == 0))
        {
            return null;
        }

        var parts = UO.GetMultiAllParts(houses[0]);
        var i = 0;
        while (Truth(i < ArrayLength(parts)))
        {
            var part = parts[i];
            UO.Print("Multi: 0x" + Hex(part[8]) + ", offset Z: " + Convert.ToString(part[7]));
            i = i + 1;
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    string Hex(object? value) => Convert.ToInt64(value).ToString("X");
    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.GetMultiAllParts(multiID) — UO.GetMultiAllParts(Any)

Parameters: multiID (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getmultiallparts":

                    return new InjectionValue((bridge.GetMultiAllParts(Arg(0)) ?? Array.Empty<int[]>())

                        .Select(part => new InjectionValue((part ?? Array.Empty<int>()).Select(value => new InjectionValue(value)).ToArray())).ToArray());

UO.GetMultiPartsAtPosition

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

C# signatures

dynamic UO.GetMultiPartsAtPosition(object? x, object? y);

Reads the components of houses in the specified world cell.

Parameters

  • x — World X coordinate of the current map cell, not the offset inside the house.
  • y — World coordinate Y of the cell. The components of all loaded houses in this cell, at all Z heights, are returned.

Return value

Array<Array>. Each line contains 9 fields: [0] graphic/type components, [1] hue, [2] world X, [3] world Y, [4] world Z, [5] multiOffsetX - X offset from multi, [6] multiOffsetY - Y offset, [7] multiOffsetZ - Z offset, [8] multiSerial - serial home. No components - empty Array. Graphic is not ID; Individual static components do not have their own serial here.

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.
  • The known, non-deleted components HouseManager are returned. Separate static maps and land are not included in this list. Rows are a snapshot; fixed order or Z sort is not promised.

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.GetMultiPartsAtPosition(UO.GetX(), UO.GetY());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Count components - direct script

Parameters and execution flow:

  • X/Y - the character's current position.
  • Length is the number of components, not their height or the number of houses.
var parts = UO.GetMultiPartsAtPosition(UO.GetX(), UO.GetY());
UO.Print(Convert.ToString(ArrayLength(parts)));

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

2. Read graphic and position of first component - script function

Parameters and execution flow:

  • parts[0] is the first line of the array. Its [0] - type, [2]/[3]/[4] - world X/Y/Z.
  • The indices [5]/[6]/[7] contain relative offsets instead.
return  RunScenario();
 object? RunScenario()
{
    var parts = UO.GetMultiPartsAtPosition(UO.GetX(), UO.GetY());
    if (Truth(ArrayLength(parts) > 0))
    {
        var part = parts[0];
        UO.Print("Type: 0x" + Hex(part[0]));
        UO.Print(Convert.ToString(part[2]) + "," + Convert.ToString(part[3]) + "," + Convert.ToString(part[4]));
    }

    return null;
}

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

3. Traverse Components and Output Owners - Script Class

Parameters and execution flow:

  • [8] - serial home, [7] - offset Z component.
  • Don't pass part[0] to a command expecting serial at home: it's a graphic of a separate component.
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 parts = UO.GetMultiPartsAtPosition(UO.GetX(), UO.GetY());
        var i = 0;
        while (Truth(i < ArrayLength(parts)))
        {
            var part = parts[i];
            UO.Print("Multi: 0x" + Hex(part[8]) + ", offset Z: " + Convert.ToString(part[7]));
            i = i + 1;
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    string Hex(object? value) => Convert.ToInt64(value).ToString("X");
    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.GetMultiPartsAtPosition(x, y) — UO.GetMultiPartsAtPosition(Any,Any)

Parameters: x (Any), y (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getmultipartsatposition":

                    return new InjectionValue((bridge.GetMultiPartsAtPosition(Arg(0), Arg(1)) ?? Array.Empty<int[]>())

                        .Select(part => new InjectionValue((part ?? Array.Empty<int>()).Select(value => new InjectionValue(value)).ToArray())).ToArray());

UO.GetMultis

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

C# signatures

dynamic UO.GetMultis();

List of loaded objects recognized by the client as home/multi.

Parameters

There are no parameters.

Return value

Array is a serial of world items for which IsHouse returns 1. An empty Array if there are no such objects. This is ID houses, not a list of graphics components, not coordinates, and not a list of all houses on the server.

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.
  • Data is read from loaded world items. For components of one house, use GetMultiAllParts(serial).

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.GetMultis();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Get list size - direct script

Parameters and execution flow:

  • There are no parameters; loaded house/multi items are selected.
  • Length - number of records/ID. This is not the amount of Amount in stacks. The empty list gives 0.
var items = UO.GetMultis();
UO.Print(Convert.ToString(ArrayLength(items)));

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

2. Traverse all found ID - script function

Parameters and execution flow:

  • There are no parameters; loaded house/multi items are selected.
  • items[i] — numeric serial. Hex is used for output only. The loop does not access the last index.
return  RunScenario();
 object? RunScenario()
{
    var items = UO.GetMultis();
    var i = 0;
    while (Truth(i < ArrayLength(items)))
    {
        UO.Print("0x" + Hex(items[i]));
        i = i + 1;
    }

    return null;
}

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

3. Check First Record Before Reading - Script Class

Parameters and execution flow:

  • There are no parameters; loaded house/multi items are selected.
  • Two different things are checked: the record in the snapshot and the existence of the object now. Order without explicit sorting does not mean closeness.
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 items = UO.GetMultis();
        if (Truth(ArrayLength(items) > 0))
        {
            var first = items[0];
            if (Truth(UO.Exists(first)))
            {
                UO.Print(UO.GetName(first));
            }
        }
        else
        {
            UO.Print("Empty list");
        }

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

Parameters: No parameters.

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getmultis":

                    return new InjectionValue(bridge.GetWorldItems().Where(id => bridge.IsHouse(id) != 0).Select(id => new InjectionValue(id)).ToArray());

UO.IsHouse

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

C# signatures

int UO.IsHouse(object? objID);

Checks the multi flag for a loaded object: a house, a ship, or another multi-tile structure.

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.

Return value

int 1—an item with the attribute IsMulti. int 0 - regular item, mobile, unknown or remote object. The name doesn't limit the result to houses: a ship can also give 1. The team does not return the home owner, region or area.

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.

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.IsHouse(UO.GetSerial("lasttarget"));
UO.Print("IsHouse: " + Convert.ToString(result));

1. Check the selected design - direct script

Parameters and execution flow:

  • target should contain the serial of the multi object, not the graphic of a single wall.
  • 1 means class multi; This is not proof that the structure is a residential building.
var target = UO.GetSerial("lasttarget");
if (Truth(UO.IsHouse(target)))
{
    UO.Print("Loaded multi structure");
}

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

2. Separate multi from regular item - script function

Parameters and execution flow:

  • First, presence is checked, then mobile is excluded.
  • Zero without Exists could mean the absence of an object, rather than an ordinary object.
return  RunScenario();
 object? RunScenario()
{
    var target = UO.GetSerial("lasttarget");
    if (Truth(UO.Exists(target)))
    {
        if (Truth(UO.IsNPC(target) == 0))
        {
            if (Truth(UO.IsHouse(target)))
            {
                UO.Print("Multi");
            }
            else
            {
                UO.Print("Ordinary item");
            }
        }
    }

    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. Don't confuse the character's position with the house object - scenario class

Parameters and execution flow:

  • self is mobile, so the first result is 0 even inside the house.
  • To test a construct, pass its own serial; the team is not looking for a house around the character.
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 selfIsMulti = UO.IsHouse("self");
        var selectedIsMulti = UO.IsHouse("lasttarget");
        UO.Print("Self: " + Convert.ToString(selfIsMulti));
        UO.Print("Selected object: " + Convert.ToString(selectedIsMulti));
        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.IsHouse(objID) — UO.IsHouse(Any)

Parameters: objID (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

case "ishouse": return new InjectionValue(bridge.IsHouse(Arg(0)));
⚠️ **GitHub.com Fallback** ⚠️