EN UO Topic multis houses - LIHACHTETAN/ClassicUO-Bad-Newbie-CSharp-Scripts-IDE GitHub Wiki
Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
| Topic | Commands and explanations |
|---|---|
| GetMultis | UO.GetMultis |
| Multi Parts | UO.GetMultiAllParts |
| Parts at Position | UO.GetMultiPartsAtPosition |
| IsHouse | UO.IsHouse |
UO.GetMultis · UO.GetMultiAllParts · UO.GetMultiPartsAtPosition · UO.IsHouse
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.
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;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;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
dynamic UO.GetMultiAllParts(object? multiID);Reads records of a component of one house.
-
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.
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.
- 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.
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.
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);
}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;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;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;
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: multiID (Any)
Result: dynamic / Any.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetMultiAllParts:bridge.GetMultiAllParts(Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
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());Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
dynamic UO.GetMultiPartsAtPosition(object? x, object? y);Reads the components of houses in the specified world cell.
-
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.
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.
- 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.
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.
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));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;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;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;
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: x (Any), y (Any)
Result: dynamic / Any.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetMultiPartsAtPosition:bridge.GetMultiPartsAtPosition(Arg(0), Arg(1)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
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());Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
dynamic UO.GetMultis();List of loaded objects recognized by the client as home/multi.
There are no parameters.
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.
- 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).
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.
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));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;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;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;
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: No parameters.
Result: dynamic / Any.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetWorldItems:bridge.GetWorldItems(). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.IsHouse:bridge.IsHouse(id).
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());Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.IsHouse(object? objID);Checks the multi flag for a loaded object: a house, a ship, or another multi-tile structure.
-
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.
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.
- 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.
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.
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));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;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;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;
}
}C# is case sensitive. Use the exact UO name. Compare numeric flags with 0; use bool only where the signature returns bool.
Parameters: objID (Any)
Result: int / Integer.
During a call:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.IsHouse:bridge.IsHouse(Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Internal implementation code; this is not a standalone script.
case "ishouse": return new InjectionValue(bridge.IsHouse(Arg(0)));