Skip to content

EN UO Topic world geometry

Codex edited this page Oct 12, 2026 · 4 revisions

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

World & Geometry

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

Coordinates, distances, line of sight, cross-country ability and map data. Getting a route is described separately in Movement.

Sections

Topic Commands and explanations
X / Y / Z UO.GetX · UO.GetY · UO.GetZ
Distance UO.GetDistance · UO.Dist
LOS UO.CheckLOS · UO.LOSOptions
World Number UO.WorldNum
World Cells UO.GetWorldCell · UO.GetWorldTilesArray
Passability UO.IsWorldCellPassable · UO.GetNextStepZ
Surface Z UO.GetSurfaceZ
Map Cells UO.GetMapCell
Land Tiles UO.GetLandTileAt · UO.GetLandTileData · UO.GetLandTilesArray · UO.GetLandTilesArrayEx
Static Tiles UO.GetStaticTileAt · UO.GetStaticTileData · UO.GetStaticTiles · UO.GetStaticTilesArray · UO.GetStaticTilesArrayEx
Tile Flags UO.GetTileFlags · UO.ConvertIntegerToFlags
Tile Height UO.GetTileHeight
Tile Layer UO.GetTileLayer
Tile Name UO.GetTileName
Water Tiles UO.IsWaterTile
Tree Tiles UO.IsTreeTile
Mine Tiles UO.IsMineTile

All theme commands

X / Y / Z

UO.X · UO.Y · UO.Z · UO.GetX · UO.GetY · UO.GetZ

Distance

UO.Dist · UO.GetDistance

LOS

UO.CheckLOS · UO.LOSOptions

World Number

UO.WorldNum · UO.GetWorldNum

World Cells / Passability

UO.GetWorldCell · UO.GetMapCell · UO.IsWorldCellPassable · UO.GetSurfaceZ · UO.GetNextStepZ · UO.GetWorldTilesArray

Land Tiles

UO.GetLandscapeTile · UO.GetLandTileAt · UO.GetLandTileData · UO.GetLandTilesArray · UO.GetLandTilesArrayEx

Static Tiles

UO.GetStaticArt · UO.GetStaticTileAt · UO.GetStaticTileData · UO.GetStaticTiles · UO.GetStaticTilesArray · UO.GetStaticTilesArrayEx · UO.ReadStaticsXY · UO.PrivateGetTile · UO.GetTileXYM · UO.GetLayerCount

Tile Properties

UO.GetTileFlags · UO.GetTileHeight · UO.GetTileLayer · UO.GetTileName · UO.IsWaterTile · UO.IsTreeTile · UO.IsMineTile · UO.ConvertIntegerToFlags

Client Statics

UO.AddUserStatic · UO.ClearUserStatics · UO.GetUserStatic · UO.GetUserStatics · UO.RemoveUserStatic · UO.UserStaticExists

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

Parameters, result and all scenarios

var target = UO.GetSerial("lasttarget");
if (Truth(UO.Exists(target)))
{
    var distance = UO.GetDistance(target);
    if (Truth(distance <= 2))
    {
        UO.Print("Target is within two tiles");
    }
}

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

UO.IsWorldCellPassable

Parameters, result and all scenarios

var x = UO.GetX();
var y = UO.GetY();
var z = UO.GetZ();
var result = UO.IsWorldCellPassable(x,y,z,x+1,y,z,UO.WorldNum());
if (Truth(Truth(result[0]) == true))
{
    UO.Print("Passable, Z=" + Convert.ToString(result[1]));
}
else
{
    UO.Print("Blocked");
}

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

Reference parts

1 · 2

Complete command reference


UO.AddUserStatic

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

C# signatures

dynamic UO.AddUserStatic(object? staticItem, object? worldNum);
int UO.AddUserStatic(object? graphic, object? x, object? y, object? z, object? hue, object? map);

Adds a custom static entry to the local script state. Numeric graphic is used for local obstacle checking by pathfinder; the object is not created on the server. A two-argument call with unnumbered text preserves legacy values ​​and does not add static to the pathfinder.

Parameters

  • staticItem — numeric graphic or legacy text value.
  • worldNum - index of the card for recording or local static.
  • graphic - ID statics from 0 to 65535.
  • z — height. When added to pathfinder, the value is limited to the signed byte range.
  • hue - hue; when added, limited to the range from 0 to 65535.
  • map — map index; for manager processing, the range is limited to 0–255.
  • x — World X custom statics; int. The manager accepts coordinates within the currently loaded map.
  • y — World Y custom statics; int. The manager accepts coordinates within the currently loaded map.

Return value

Positive ID of the created entry. For the six-parameter form, negative graphic, x, y or map, as well as graphic above 65535 result in -1. ID can be passed to UO.UserStaticExists, UO.RemoveUserStatic or used to check/delete a legacy record. The returned ID by itself does not confirm that the static will be visible or applied on the server.

Behavior

    • UO.AddUserStatic('tree', 0) - since tree is not a number, saves a pair of original values ​​as a legacy record in the runtime state; pathfinder doesn't use it.
  • A two-parameter call with a numeric graphic adds that graphic's static to the character's current coordinates, with the character's z and hue 0.
  • The six-parameter call adds a static with the given graphic, coordinates, height, hue and map. Pathfinding only takes it into account on the active map and according to the graphic flags in the client tiledata.

These entries are local to the script client: they do not create a game object, make a network request, or modify shard 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.

object? result = UO.AddUserStatic(0x0CCA, UO.GetWorldNum());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Save the pair as legacy data; text StaticItem does not create an obstacle to the pathfinder. - direct script

Parameters and execution flow:

  • Save the pair as legacy data; text StaticItem does not create an obstacle to the pathfinder.
var legacyId = UO.AddUserStatic("tree", 0);
UO.Print(Convert.ToString(legacyId));

2. A numeric graphic is added to the character's position on the current map. - script function

Parameters and execution flow:

  • A numeric graphic is added to the character's position on the current map.
return  RunScenario();
 object? RunScenario()
{
    var staticId = UO.AddUserStatic(0x0CCA, UO.GetWorldNum());
    UO.Print(Convert.ToString(staticId));
    return null;
}

3. Explicitly add a local static graphic at the specified position and to the specified map. - script class

Parameters and execution flow:

  • Explicitly add a local static graphic at the specified position and to the specified map.
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 staticId = UO.AddUserStatic(0x0CCA, UO.GetX(), UO.GetY(), UO.GetZ(), 0, UO.GetWorldNum());
        UO.Print(Convert.ToString(staticId));
        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.AddUserStatic(staticItem, worldNum) — UO.AddUserStatic(Any,Any)

Parameters: staticItem (Any), worldNum (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "adduserstatic":

                {

                    int map = Arg(1, bridge.WorldNumber);

                    if (arguments[0].Kind != InjectionValueKind.Array)

                    {

                        int graphic = 0;

                        if (arguments[0].Kind == InjectionValueKind.String &&

                            !NumberConversions.TryStr2Int(arguments[0].String, out graphic))

                        {

                            int legacyId = state.NextUserStaticId++;

                            state.UserStatics[legacyId] = Text(0) + "|" + Text(1);

                            return new InjectionValue(legacyId);

                        }

                        graphic = arguments[0].Kind == InjectionValueKind.String

                            ? graphic

                            : NumberConversions.ToInt(arguments[0]);

                        return new InjectionValue(AddUserStatic(graphic, bridge.GetX(bridge.Self), bridge.GetY(bridge.Self),

                            bridge.GetZ(bridge.Self), 0, map));

                    }

                    if (arguments[0].Array.Length < 4)

                        throw new NativeSubrutineException("AddUserStatic expects [graphic,x,y,z,color] and world number, or graphic,x,y,z,color,world.");

                    InjectionValue[] item = arguments[0].Array;

                    return new InjectionValue(AddUserStatic(

                        NumberConversions.ToInt(item[0]), NumberConversions.ToInt(item[1]), NumberConversions.ToInt(item[2]),

                        NumberConversions.ToInt(item[3]), item.Length > 4 ? NumberConversions.ToInt(item[4]) : 0, map));

                }

UO.AddUserStatic(graphic, x, y, z, hue, map) — UO.AddUserStatic(Any,Any,Any,Any,Any,Any)

Parameters: graphic (Any), x (Any), y (Any), z (Any), hue (Any), map (Any)

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.

values => new InjectionValue(AddUserStatic(

                    NumberConversions.ToInt(values[0]), NumberConversions.ToInt(values[1]), NumberConversions.ToInt(values[2]),

                    NumberConversions.ToInt(values[3]), NumberConversions.ToInt(values[4]), NumberConversions.ToInt(values[5])))

UO.CheckLOS

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

C# signatures

dynamic UO.CheckLOS(object? xfrom, object? yfrom, object? zfrom, object? xto, object? yto, object? zto, object? worldNum);

Checks the local passability of a line between two map points via CheckPortableLineOfSight.

Parameters

  • xfrom — Source X: 0..65535.
  • yfrom — Source Y: 0..65535.
  • zfrom — Initial Z, int.
  • xto - End X: 0..65535.
  • yto - End Y: 0..65535.
  • zto — Final Z, int.
  • worldNum - 0..255. A beam of non-zero length reads only the currently loaded _world.Map/World.Map: via CheckWorldStep you need WorldNum == _world.MapIndex and a live Player.Pathfinder. Another facet is not loaded or requested; there is no map/character/pathfinder or the step is not available - 0. Excluding identical X/Y skips the entire cycle of cells: with X/Y in 0..65535, WorldNum in 0..255 and abs(Zfrom-Zto)<=20 returns 1 even without a loaded card or with a different card number. This is not a proof of geometry or reachability. The result is local, not a LOS server solution.

Return value

int 1 — the local ray has reached X/Y and the final height differs from Zto by no more than 20; 0—invalid coordinates, obstacle, or check limit.

Behavior

  • The beam travels using the Bresenham algorithm, with a maximum of 4096 steps. On each cell, BadLocations, CheckWorldStep and the returned height are taken into account.
  • When LosOptions != 0 additionally CheckLosCell is used; bit 0x100 checks both side squares of the diagonal. Local geometry checking does not validate server-specific LOS rules and does not move anything.
  • Low byte (value & 0xFF) selects algorithm 1..4; other low byte values ​​in CheckLosCell use the 3 algorithm. Algorithms 1/2 block Wall and Impassable, 3 additionally NoShoot, and 4 enables NoShoot only with 0x200 and allows Window obstacles only with 0x400. Bit 0x100 additionally checks both side cells of each diagonal beam step for any selected algorithm. value=0 disables the additional CheckLosCell/diagonal checks, but BadLocations and CheckWorldStep remain. For example 4+0x100+0x200+0x400 selects custom with three flags; setter stores the original int, not the normalized algorithm.
  • A beam of non-zero length reads only the currently loaded _world.Map/World.Map: via CheckWorldStep you need WorldNum == _world.MapIndex and a live Player.Pathfinder. Another facet is not loaded or requested; there is no map/character/pathfinder or the step is unavailable - 0. Excluding identical X/Y skips the entire cycle of cells: with X/Y in 0..65535, WorldNum in 0..255 and abs(Zfrom-Zto)<=20 returns 1 even without a loaded card or with a different card number. This is not a proof of geometry or reachability. The result is local, not a LOS server solution.
  • CheckLosCell bypasses the loaded Land/Static/Multi/Item of one cell. Impassable Land blocks with abs(rayZ-land.Z)<=20. The Static/Multi/Item flags are only valid in the range tile.Z-2 .. tile.Z+max(1,Height)+2; allowed custom Window is skipped until Wall/Impassable/NoShoot is checked. X/Y beam uses Bresenham, maximum 4096 steps; Z is taken from surfaces CheckWorldStep, not interpolated to Zto, final height tolerance is 20.

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.CheckLOS(UO.X(), UO.Y(), UO.Z(), UO.X() + 1, UO.Y(), UO.Z(), UO.WorldNum());
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Line on the current cell - direct script

Parameters and execution flow:

  • Identical points pass within acceptable X/Y/map.
var x = UO.GetX();
var y = UO.GetY();
var z = UO.GetZ();
var visible = UO.CheckLOS(x,y,z,x,y,z,UO.WorldNum());
UO.Print(Convert.ToString(visible));

2. Checking adjacent cell - script function

Parameters and execution flow:

  • The height and permeability of the neighboring cell are read from the local map.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX();
    var y = UO.GetY();
    var z = UO.GetZ();
    var clear = UO.CheckLOS(x, y, z, x + 1, y, z, UO.WorldNum());
    UO.Print(Convert.ToString(clear));
    return null;
}

3. Invalid coordinate — script class

Parameters and execution flow:

  • A negative X is rejected with a result of 0 without passing through the map.
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 clear = UO.CheckLOS(-1, 0, 0, 0, 0, 0, 0);
        UO.Print(Convert.ToString(clear));
        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.CheckLOS(xfrom, yfrom, zfrom, xto, yto, zto, worldNum) — UO.CheckLOS(Any,Any,Any,Any,Any,Any,Any)

Parameters: xfrom (Any), yfrom (Any), zfrom (Any), xto (Any), yto (Any), zto (Any), worldNum (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "checklos": return new InjectionValue(CheckPortableLineOfSight(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), Arg(5), Arg(6)) ? 1 : 0);

UO.ClearUserStatics

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

C# signatures

void UO.ClearUserStatics();

Removes all user static runtime entries and local static manager objects.

Parameters

There are no parameters.

Return value

void - no return value.

Behavior

  • State.UserStatics and manager objects are cleared. Uploaded map files and real server items are not deleted.

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.ClearUserStatics");
UO.ClearUserStatics();

1. Clear state - direct script

Parameters and execution flow:

  • Removes all user static runtime entries and local static manager objects.
UO.ClearUserStatics();

2. Clear after setup - script function

Parameters and execution flow:

  • Add a local static on the current cell, then remove all custom statics.
return  RunScenario();
 object? RunScenario()
{
    var localStatic = UO.AddUserStatic(0x0CCA, UO.GetX(), UO.GetY(), UO.GetZ(), 0, UO.WorldNum());
    UO.ClearUserStatics();
    return null;
}

3. Re-Purge - Script Class

Parameters and execution flow:

  • Clearing an empty set is acceptable and does not create a new setting.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        UO.ClearUserStatics();
        UO.ClearUserStatics();
        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.ClearUserStatics() — UO.ClearUserStatics()

Parameters: No parameters.

Result: void / Unit.

During a call:

Internal implementation code; this is not a standalone script.

case "clearuserstatics": state.UserStatics.Clear(); bridge.ClearUserStatics(); return InjectionValue.Unit;

UO.ConvertIntegerToFlags

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

C# signatures

dynamic UO.ConvertIntegerToFlags(object? group, object? value);

Parses a numeric mask of tile flags into an array of enumeration names TileFlag.

Parameters

  • group - int: only 1 or 2 enable conversion; any other value results in an empty array.
  • value — A mask that Arg converts to a signed 32-bit int, then bridge leads to ulong. For high 64-bit flags, this form does not preserve the full mask.

Return value

Array of strings named non-zero TileFlag whose bits are fully present in the mask. The mask 0 produces an empty array.

Behavior

  • Group 1 and 2 use the same Enum.GetValues rather than different directories. This is a local mask transformation; tiledata is not requested.
  • API-registration uses object?, but Arg(1) dispatcher passes int. Negative int sign-extends when casting to ulong. GetTileFlags also returns only the low 32 bits as a signed int: this compatible pair does not provide the full 64-bit tiledata contract.

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

1. Null mask - direct script

Parameters and execution flow:

  • No non-zero flag is present in the mask 0.
var flags = UO.ConvertIntegerToFlags(1,0);
UO.Print(Convert.ToString(ArrayLength(flags)));

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

2. Low Bit Mask - Script Function

Parameters and execution flow:

  • The array contains the real names TileFlag of the selected mask.
return  RunScenario();
 object? RunScenario()
{
    var flags = UO.ConvertIntegerToFlags(2, 1);
    for (int i = (int)(0); i <= ArrayLength(flags) - 1; i += (int)(1))
    {
        UO.Print(flags[i]);
    }

    return null;
}

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

3. Invalid Group - Script Class

Parameters and execution flow:

  • Group 0 is not accepted by this command and returns an empty array.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var flags = UO.ConvertIntegerToFlags(0, 1);
        UO.Print(Convert.ToString(ArrayLength(flags)));
        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 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.ConvertIntegerToFlags(group, value) — UO.ConvertIntegerToFlags(Any,Any)

Parameters: group (Any), value (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "convertintegertoflags":

                    return new InjectionValue(bridge.ConvertTileFlags(Arg(0), Arg(1))

                        .Select(flag => new InjectionValue(flag)).ToArray());

UO.Dist

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

C# signatures

int UO.Dist(object? xfrom, object? yfrom, object? xto, object? yto);

Calculates the distance in cells between two world points: the greatest of the absolute differences between X and Y.

Parameters

  • xfrom — X coordinate of the starting point.
  • yfrom — Y coordinate of the starting point.
  • xto — X coordinate of destination.
  • yto — Y coordinate of destination.

Return value

int — distance in cells, non-negative for valid coordinates. 0 means the same XY, 1 - one cell. This is a quantity, not a sign of success. A separate comparison distance <= 2 returns bool true or false; the distance itself remains int.

Behavior

  • Calculate coordinates only: no batches, no waiting, no map loading, no obstacle checking, no Z, no world map. The team does not search for a passable route and does not guarantee the achievement of the goal. The points must belong to the same coordinate system; avoiding obstacles can lengthen the path.
  • All four parameters are needed. Send world coordinates int in the documented range 0..65535. object? in the signature indicates a universal adapter, not the item's ID. These commands do not have default values, coordinates inside the chest, fifth Z and overload with one object.
  • Formula: Max(Abs(Xto-Xfrom), Abs(Yto-Yfrom)). When you rearrange the points, the result is the same. This is not the Euclidean distance, not the sum of the differences, and not the number of steps when going around an obstacle.

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.Dist(100, 100, 103, 104);
UO.Print("Dist: " + Convert.ToString(result));

1. Direct calculation - direct script

Parameters and execution flow:

  • From (100,100) to (103,104): the absolute differences are 3 and 4, with a maximum of 4. Main returns int 4.
  • int — distance in cells, non-negative for valid coordinates. 0 means the same XY, 1 - one cell. This is a quantity, not a sign of success. A separate comparison distance <= 2 returns bool true or false; the distance itself remains int.
  • Formula: Max(Abs(Xto-Xfrom), Abs(Yto-Yfrom)). When you rearrange the points, the result is the same. This is not the Euclidean distance, not the sum of the differences, and not the number of steps when going around an obstacle.
return UO.Dist(100,100,103,104);

2. Correctly checking the result is a function of the script

Parameters and execution flow:

  • From (100,100) to (101,99) the distance is 1. A separate comparison of distance<=2 gives true=1. Main returns "1:1": the first unit is the distance, the second is the logical result of the comparison.
  • int — distance in cells, non-negative for valid coordinates. 0 means the same XY, 1 - one cell. This is a quantity, not a sign of success. A separate comparison distance <= 2 returns bool true or false; the distance itself remains int.
  • Formula: Max(Abs(Xto-Xfrom), Abs(Yto-Yfrom)). When you rearrange the points, the result is the same. This is not the Euclidean distance, not the sum of the differences, and not the number of steps when going around an obstacle.
return  RunScenario();
 object? RunScenario()
{
    var distance = UO.Dist(100, 100, 101, 99);
    var close = distance <= 2;
    return Convert.ToString(distance) + ":" + Convert.ToString(close);
    return null;
}

3. Full script parsing - script class

Parameters and execution flow:

  • UO.Dist returns 4. RebuildTileDistance calculates the differences via Abs, compares them and returns the larger one, so does 4. Main returns "4:4". The assistant is fully shown in the example and is not another engine command.
  • int — distance in cells, non-negative for valid coordinates. 0 means the same XY, 1 - one cell. This is a quantity, not a sign of success. A separate comparison distance <= 2 returns bool true or false; the distance itself remains int.
  • Formula: Max(Abs(Xto-Xfrom), Abs(Yto-Yfrom)). When you rearrange the points, the result is the same. This is not the Euclidean distance, not the sum of the differences, and not the number of steps when going around an obstacle.
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 actual = UO.Dist(100, 100, 103, 104);
        var rebuilt = RebuildTileDistance(100, 100, 103, 104);
        return Convert.ToString(actual) + ":" + Convert.ToString(rebuilt);
        return null;
    }

    dynamic RebuildTileDistance(dynamic Xfrom, dynamic Yfrom, dynamic Xto, dynamic Yto)
    {
        var dx = Math.Abs(Xto - Xfrom);
        var dy = Math.Abs(Yto - Yfrom);
        if (Truth(dx > dy))
        {
            return dx;
        }

        return dy;
    }

    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.Dist(xfrom, yfrom, xto, yto) — UO.Dist(Any,Any,Any,Any)

Parameters: xfrom (Any), yfrom (Any), xto (Any), yto (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

case "dist": return new InjectionValue(arguments.Length >= 4

                    ? GetDistance(Arg(0), Arg(1), Arg(2), Arg(3))

                    : bridge.GetDistance(Arg(0)));

UO.GetDistance

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

C# signatures

int UO.GetDistance(object? id);
int UO.GetDistance(object? x, object? y);
int UO.GetDistance(object? id1, object? x2, object? y2);
int UO.GetDistance(object? x1, object? y1, object? x2, object? y2);

Measures the distance in cells based on the maximum X/Y differences. This is geometric estimation without pathfinding.

Parameters

  • id — One argument: serial or alias of the loaded object, the distance to which you want to get.
  • x — Two arguments: world destination. The beginning is GetX(self), GetY(self).
  • y — Two arguments: world destination. The beginning is GetX(self), GetY(self).
  • id1 — In three-argument form, the serial/alias of the object whose coordinates serve as the origin.
  • x1 — In four-argument form, the coordinates of the origin. No object is needed for this form.
  • y1 — In four-argument form, the coordinates of the origin. No object is needed for this form.
  • x2 — In forms with three/four arguments, the end coordinates. Don't confuse them with serial of the second object.
  • y2 — In forms with three/four arguments, the end coordinates. Don't confuse them with serial of the second object.

Return value

int - max(abs(x2-x1), abs(y2-y1)): horizontal, vertical and diagonal to an adjacent cell have a distance 1. Z height and obstacles are not taken into account. For unknown serial, the one-argument form returns 0; for an existing object in the absence of a character - 65535. For unknown id1, the three-argument form uses (0,0), so check Exists(id1) first.

Behavior

  • The single-object form uses the current World.RangeSize range center and the last position in the moving mob's step queue. During movement, the result may differ from the calculation via GetX/GetY.
  • Coordinate forms work with passed numbers. For game coordinates, use the range 0..65535; extreme int values ​​and difference overflow are not supported coordinates.
  • The team does not promise that the goal will be achievable. To move, you need MoveXY/NewMoveXY and checking its result; walls can make the actual path longer.

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

1. Check range to target - direct script

Parameters and execution flow:

  • target is serial, not type. The Exists check prevents an unknown object zero from being mistaken for a nearby target.
  • distance<=2 checks the X/Y distance. Visibility and passability are checked separately.
var target = UO.GetSerial("lasttarget");
if (Truth(UO.Exists(target)))
{
    var distance = UO.GetDistance(target);
    if (Truth(distance <= 2))
    {
        UO.Print("Target is within two tiles");
    }
}

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

2. Distance between two points - script function

Parameters and execution flow:

  • x1=100, y1=200, x2=103, y2=204. The differences are 3 and 4.
  • The result is 4, not 7 and not the Euclidean 5.
return  RunScenario();
 object? RunScenario()
{
    var distance = UO.GetDistance(100, 200, 103, 204);
    UO.Print(Convert.ToString(distance));
    return null;
}

3. Start from an object and from your character - script class

Parameters and execution flow:

  • The two x/y arguments use the current position of self. The three arguments id1/x2/y2 allow you to explicitly specify the start object.
  • At a constant position, both quantities are equal to 3. The coordinates must remain within the boundaries of the map.
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 x = UO.GetX() + 3;
        var y = UO.GetY() + 1;
        var fromSelf = UO.GetDistance(x, y);
        var fromObject = UO.GetDistance("self", x, y);
        UO.Print(Convert.ToString(fromSelf) + " / " + Convert.ToString(fromObject));
        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.GetDistance(id) — UO.GetDistance(Any)

Parameters: id (Any/Integer/String)

Result: int / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getdistance": return new InjectionValue(bridge.GetDistance(Arg(0)));

UO.GetDistance(id) — UO.GetDistance(Integer)

Parameters: id (Any/Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

UO.GetDistance(id) — UO.GetDistance(String)

Parameters: id (Any/Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

UO.GetDistance(x, y) — UO.GetDistance(Integer,Integer)

Parameters: x (Integer), y (Integer)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetDistance(int x, int y) => GetDistance(bridge.GetX(bridge.Self), bridge.GetY(bridge.Self), x, y);

UO.GetDistance(id1, x2, y2) — UO.GetDistance(Any,Any,Any)

Parameters: id1 (Any), x2 (Any), y2 (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetDistance(InjectionValue id1, InjectionValue x2, InjectionValue y2)

        {

            var obj1 = GetObject(id1);

            int x1 = bridge.GetX(obj1);

            int y1 = bridge.GetY(obj1);



            return GetDistance(x1, y1, NumberConversions.ToInt(x2), NumberConversions.ToInt(y2));

        }

UO.GetDistance(x1, y1, x2, y2) — UO.GetDistance(Integer,Integer,Integer,Integer)

Parameters: x1 (Integer), y1 (Integer), x2 (Integer), y2 (Integer)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetDistance(int x1, int y1, int x2, int y2)

        {

            int dx = Math.Abs(x1 - x2);

            int dy = Math.Abs(y1 - y2);



            return Math.Max(dx, dy);

        }

UO.GetLandTileAt

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

C# signatures

dynamic UO.GetLandTileAt(object? x, object? y);
dynamic UO.GetLandTileAt(object? x, object? y, object? map);

Returns the extended land record of the selected cell.

Parameters

  • x — X cell of the currently loaded map; world coordinate, not position inside the gump.
  • y — Y cell of the currently loaded map; world coordinate, not position inside the gump.
  • map — Card number. If this argument is not present in the selected form, the current map is used. The real client only reads tiles from the currently loaded map.

Return value

Array of 11 fields of one record; indices start with 0:

  • [0] kind — string: "land", "static", or "object".
  • [1] serial — int: serial of a dynamic item; for land/static is 0.
  • [2] graphic — int: graphics type.
  • [3] x, [4] y - int: world coordinates of the cell.
  • [5] z - int: the height of the base in the world.
  • [6] hue - int: color, near the ground 0.
  • [7] flags - int: low 32 bits of tiledata flags.
  • [8] name — string: name from tiledata.
  • [9] layer - int: layer of equipment from tiledata, near the ground 0; not a static index.
  • [10] height - int: graphic height from tiledata, near the ground 0; not the Z coordinate.

An empty array [] means no entry or an inaccessible card/cell. For GetStaticTileAt, a negative/too large index also produces []; index overflow does not select someone else's entry.

Behavior

  • The data refers to the currently loaded map. Another card or unreachable cell results in an empty array. Direct tile queries may additionally report map mismatches; GetWorldCell and GetWorldTilesArray immediately return an empty array without such a message.
  • Array indices start with 0. Check ArrayLength before reading the field. Z stands for world altitude; layer is the equipment property from tiledata, and index is the serial number of the cell entry.

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

1. Read type, Z and layer separately - direct script

Parameters and execution flow:

  • x/y — character position; the card is lowered and selected automatically. For GetStaticTileAt index=0 means the first entry.
  • The fields [2], [5], [9] have different meanings; all are read only after checking the length of 11.
var tile = UO.GetLandTileAt(UO.GetX(), UO.GetY());
if (Truth(ArrayLength(tile) == 11))
{
    UO.Print("Type: " + Convert.ToString(tile[2]));
    UO.Print("World Z: " + Convert.ToString(tile[5]));
    UO.Print("Equipment layer: " + Convert.ToString(tile[9]));
}
else
{
    UO.Print("Tile is unavailable");
}

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. Get graphic name and height - script function

Parameters and execution flow:

  • The same coordinates are used; GetStaticTileAt reads index=0.
  • tile[8] is the title string, tile[10] is the height dimension from tiledata, not the Z base.
return  RunScenario();
 object? RunScenario()
{
    var tile = UO.GetLandTileAt(UO.GetX(), UO.GetY());
    if (Truth(ArrayLength(tile) == 11))
    {
        UO.Print(tile[8]);
        UO.Print("Graphic height: " + Convert.ToString(tile[10]));
    }

    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. Prepare target by type and coordinates - script class

Parameters and execution flow:

  • WaitTargetTile gets graphic, x, y, z from fields 2…5.
  • This is just preparation for the next target. The example does not trigger a tool or spell. serial=0 for statics should not be passed as ID of the item.
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 tile = UO.GetLandTileAt(UO.GetX(), UO.GetY());
        if (Truth(ArrayLength(tile) == 11))
        {
            UO.WaitTargetTile(tile[2], tile[3], tile[4], tile[5]);
        }

        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.GetLandTileAt(x, y) — UO.GetLandTileAt(Any,Any)

Parameters: x (Any), y (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetLandTileAt(InjectionValue x, InjectionValue y)

            => GetLandTileAt(x, y, new InjectionValue(bridge.WorldNumber));

UO.GetLandTileAt(x, y, map) — UO.GetLandTileAt(Any,Any,Any)

Parameters: x (Any), y (Any), map (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetLandTileAt(InjectionValue x, InjectionValue y, InjectionValue map)

        {

            int cellX = NumberConversions.ToInt(x);

            int cellY = NumberConversions.ToInt(y);

            int world = NumberConversions.ToInt(map);

            int[] land = bridge.GetLandscapeTile(cellX, cellY, world) ?? Array.Empty<int>();

            return land.Length >= 2

                ? BuildWorldTileRecord("land", 0, land[0], cellX, cellY, land[1], 0, 0)

                : new InjectionValue(Array.Empty<InjectionValue>());

        }

UO.GetLandTileData

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

C# signatures

dynamic UO.GetLandTileData(object? tile);

Reads the extended land reference record from tiledata.

Parameters

  • tile — Graphic/type of record, not serial and not an index inside the cell. The land table is chosen by the team name itself.

Return value

Array of 7 fields for a valid graphic. All fields are int except name (string):

  • [0] graphic — graphic/type of entry.
  • [1] flags — low-order 32 flag bits.
  • [2] name — name from tiledata (string).
  • [3] texId - ID ground textures.
  • [4] wet — 1 if wet is installed, otherwise 0.
  • [5] impassable — 1 if impassable, otherwise 0.
  • [6] noDiagonal — 1 if noDiagonal, otherwise 0.

For an invalid graphic, there are no reference properties: the short array [переданный graphic, 0, ""] is returned. Check the full length before reading the properties. This is not a Pascal record or a list of objects.

Behavior

  • The command reads tiledata and does not require an item with this graphic in the world. Flags describe the resource; the result does not replace a full route check.

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

1. Read entry name - direct script

Parameters and execution flow:

  • Tile — numeric graphic of the selected table.
  • data[2] contains the name. Length check separates a full entry from a short entry of invalid graphic.
var data = UO.GetLandTileData(0x0003);
if (Truth(ArrayLength(data) == 7))
{
    UO.Print(data[2]);
}
else
{
    UO.Print("Tiledata entry is unavailable");
}

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. Check Individual Boolean Flag - Script Function

Parameters and execution flow:

  • data[5] is a separate impassable field: 1 (condition met), 0 (condition not met).
  • This check does not take into account other objects in the cell or the character's abilities.
return  RunScenario();
 object? RunScenario()
{
    var data = UO.GetLandTileData(0x0003);
    if (Truth(ArrayLength(data) == 7))
    {
        if (Truth(data[5]))
        {
            UO.Print("Impassable flag is set");
        }
        else
        {
            UO.Print("Impassable flag is not set");
        }
    }

    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. Output graphic and general flag mask - script class

Parameters and execution flow:

  • data[0] repeats the transmitted graphic, data[1] is a general flag mask.
  • The mask can contain several bits at the same time; its numeric value is not serial.
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 data = UO.GetLandTileData(0x0003);
        if (Truth(ArrayLength(data) == 7))
        {
            UO.Print("Graphic: " + Convert.ToString(data[0]));
            UO.Print("Flags: " + Convert.ToString(data[1]));
        }

        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.GetLandTileData(tile) — UO.GetLandTileData(Any)

Parameters: tile (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getlandtiledata":

                    return BuildTileData(0, Arg(0));

UO.GetLandTilesArray

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

C# signatures

dynamic UO.GetLandTilesArray(object? xmin, object? ymin, object? xmax, object? ymax, object? worldNum, object? tileType);

Searches for land tiles by graphic/type in a rectangle.

Parameters

  • xmin — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • ymin — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • xmax — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • ymax — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • worldNum — Map/facet 0..255; use UO.WorldNum(). Another map gives an empty Array. If the map changes between chunks, the partial result is discarded.
  • tileType — One graphic/type of tile, usually 0..65535; this is not serial. 0 is the exact graphic 0, -1 does not mean any type. A mismatched type gives an empty result.

Return value

Array of entries [graphic, X, Y, Z]; all fields are int. graphic — type of earth, Z — its base. No matches: empty Array. The quantity is ArrayLength(result), not the result itself. The indices start with 0. This is not a bool, serial or Pascal record; there is no seventh output parameter.

Behavior

  • Local data is read. Search does not change FindItem/FindCount and does not perform a move, target, or network command.
  • Order: X ascending, within X - Y ascending. Records of one cell preserve the order of bridge; it is not sorted by distance or height.
  • The search is processed in chunks of up to 32 cells with a soft budget of about 1 ms. Cancellation is checked between servings. A complex cell or cold read may go over budget. It is better to divide a large area; the world can change while reading.

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

1. Search near a character - direct script

Parameters and execution flow:

  • x/y — position self, map — current map. The region 3×3 includes the boundaries. In Ex two type are transmitted, in normal form one. Change the samples to suit your resources; this is a graphic, not a ID object.
var x = UO.GetX();
var y = UO.GetY();
var map = UO.WorldNum();
var rows = UO.GetLandTilesArray(x, y, x + 2, y + 2, map, 0x0003);
UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));

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

2. Rearranged angles and output of all fields - script function

Parameters and execution flow:

  • The region 2×2 is transferred from the larger angle to the smaller one. The algorithm itself normalizes the boundaries. row - one record; PrintTile is declared in its entirety and only formats numbers, without moving anything. graphic - type, x/y - coordinates, z - height, hue - color. For land, a conditional hue=0 is passed: there is no color field in the land record.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX();
    var y = UO.GetY();
    var map = UO.WorldNum();
    var rows = UO.GetLandTilesArray(x + 1, y + 1, x, y, map, 0x0003);
    var i = 0;
    while (Truth(i < ArrayLength(rows)))
    {
        var row = rows[i];
        PrintTile(row[0], row[1], row[2], row[3], 0);
        i = i + 1;
    }

    return null;
}

void PrintTile(dynamic graphic, dynamic x, dynamic y, dynamic z, dynamic hue)
{
    UO.Print("Type=" + Convert.ToString(graphic) + " X=" + Convert.ToString(x) + " Y=" + Convert.ToString(y));
    UO.Print("Z=" + Convert.ToString(z) + " hue=" + Convert.ToString(hue));
}

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. Re-Poll with Retry Limit - Script Class

Parameters and execution flow:

  • No more than three searches for one cell; between attempts WaitAsync(250). Each call creates a new result. Zero length means there are no matches now, rather than the object being permanently missing from the server.
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 x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var attempt = 0;
        while (Truth(attempt < 3))
        {
            var rows = UO.GetLandTilesArray(x, y, x, y, map, 0x0003);
            UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));
            attempt = attempt + 1;
            await Delay(250);
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    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.GetLandTilesArray(xmin, ymin, xmax, ymax, worldNum, tileType) — UO.GetLandTilesArray(Any,Any,Any,Any,Any,Any)

Parameters: xmin (Any), ymin (Any), xmax (Any), ymax (Any), worldNum (Any), tileType (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getlandtilesarray":

                    return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), new[] { Arg(5) }, false);

UO.GetLandTilesArrayEx

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

C# signatures

dynamic UO.GetLandTilesArrayEx(object? xmin, object? ymin, object? xmax, object? ymax, object? worldNum, object? tileTypes);

Searches for land tiles by graphic/type in a rectangle.

Parameters

  • xmin — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • ymin — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • xmax — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • ymax — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • worldNum — Map/facet 0..255; use UO.WorldNum(). Another map gives an empty Array. If the map changes between chunks, the partial result is discarded.
  • tileTypes — Array of numeric graphic/type; every matching type is included. Repeating type does not duplicate entries. A scalar is also accepted as one type. An empty Array means all type; an array of one 0 searches only 0.

Return value

Array of entries [graphic, X, Y, Z]; all fields are int. graphic — type of earth, Z — its base. No matches: empty Array. The quantity is ArrayLength(result), not the result itself. The indices start with 0. This is not a bool, serial or Pascal record; there is no seventh output parameter.

Behavior

  • Local data is read. Search does not change FindItem/FindCount and does not perform a move, target, or network command.
  • Order: X ascending, within X - Y ascending. Records of one cell preserve the order of bridge; it is not sorted by distance or height.
  • The search is processed in chunks of up to 32 cells with a soft budget of about 1 ms. Cancellation is checked between servings. A complex cell or cold read may go over budget. It is better to divide a large area; the world can change while reading.

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.GetLandTilesArrayEx(UO.X(), UO.Y(), UO.X() + 1, UO.Y() + 1, UO.WorldNum(), new[] { 0x0003 });
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Search near a character - direct script

Parameters and execution flow:

  • x/y — position self, map — current map. The region 3×3 includes the boundaries. In Ex two type are transmitted, in normal form one. Change the samples to suit your resources; this is a graphic, not a ID object.
dynamic[] types = new dynamic[checked((int)(1) + 1)];
types[0] = 0x0003;
types[1] = 0x0004;
var x = UO.GetX();
var y = UO.GetY();
var map = UO.WorldNum();
var rows = UO.GetLandTilesArrayEx(x, y, x + 2, y + 2, map, types);
UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));

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

2. Rearranged angles and output of all fields - script function

Parameters and execution flow:

  • The region 2×2 is transferred from the larger angle to the smaller one. The algorithm itself normalizes the boundaries. row - one record; PrintTile is declared in its entirety and only formats numbers, without moving anything. graphic - type, x/y - coordinates, z - height, hue - color. For land, a conditional hue=0 is passed: there is no color field in the land record.
return  RunScenario();
 object? RunScenario()
{
    dynamic[] types = new dynamic[checked((int)(1) + 1)];
    types[0] = 0x0003;
    types[1] = 0x0004;
    var x = UO.GetX();
    var y = UO.GetY();
    var map = UO.WorldNum();
    var rows = UO.GetLandTilesArrayEx(x + 1, y + 1, x, y, map, types);
    var i = 0;
    while (Truth(i < ArrayLength(rows)))
    {
        var row = rows[i];
        PrintTile(row[0], row[1], row[2], row[3], 0);
        i = i + 1;
    }

    return null;
}

void PrintTile(dynamic graphic, dynamic x, dynamic y, dynamic z, dynamic hue)
{
    UO.Print("Type=" + Convert.ToString(graphic) + " X=" + Convert.ToString(x) + " Y=" + Convert.ToString(y));
    UO.Print("Z=" + Convert.ToString(z) + " hue=" + Convert.ToString(hue));
}

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. Re-Poll with Retry Limit - Script Class

Parameters and execution flow:

  • No more than three searches for one cell; between attempts WaitAsync(250). Each call creates a new result. Zero length means there are no matches now, rather than the object being permanently missing from the server.
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()
    {
        dynamic[] types = new dynamic[checked((int)(1) + 1)];
        types[0] = 0x0003;
        types[1] = 0x0004;
        var x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var attempt = 0;
        while (Truth(attempt < 3))
        {
            var rows = UO.GetLandTilesArrayEx(x, y, x, y, map, types);
            UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));
            attempt = attempt + 1;
            await Delay(250);
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    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.GetLandTilesArrayEx(xmin, ymin, xmax, ymax, worldNum, tileTypes) — UO.GetLandTilesArrayEx(Any,Any,Any,Any,Any,Any)

Parameters: xmin (Any), ymin (Any), xmax (Any), ymax (Any), worldNum (Any), tileTypes (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getlandtilesarrayex":

                    return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), ArrayArg(5), false);

UO.GetLandscapeTile

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

C# signatures

dynamic UO.GetLandscapeTile(object? x, object? y, object? map);

Reads the land of one cell of the current card.

Parameters

  • x — X cell of the currently loaded map; world coordinate, not position inside the gump.
  • y — Y cell of the currently loaded map; world coordinate, not position inside the gump.
  • map — Card number. If this argument is not present in the selected form, the current map is used. The real client only reads tiles from the currently loaded map.

Return value

Array of three int: [0] graphic - type lands; [1] z — world altitude of the earth; [2] flags — low 32 bits of tiledata flags. If the card/tile is not available or there is no land, an empty array [] is returned. This is a flat record, not a list of three tiles.

Behavior

  • The data refers to the currently loaded map. Another card or unreachable cell results in an empty array. Direct tile queries may additionally report map mismatches; GetWorldCell and GetWorldTilesArray immediately return an empty array without such a message.
  • Array indices start with 0. Check ArrayLength before reading the field. Z stands for world altitude; layer is the equipment property from tiledata, and index is the serial number of the cell entry.

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

1. Show the ground under the character - direct script

Parameters and execution flow:

  • x/y are taken from the character's position; map=WorldNum() selects the current map.
  • The presence of three fields is checked before indexing; land[0] - graphic, land[1] - Z.
var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
if (Truth(ArrayLength(land) >= 3))
{
    UO.Print("Graphic: " + Convert.ToString(land[0]));
    UO.Print("Ground Z: " + Convert.ToString(land[1]));
}
else
{
    UO.Print("Land is unavailable");
}

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. Compare height of neighboring cell - script function

Parameters and execution flow:

  • x+1 is a neighboring cell, y and map are preserved.
  • deltaZ compares land and character. This is not a passability test: bridges and statics are counted separately.
return  RunScenario();
 object? RunScenario()
{
    var land = UO.GetLandscapeTile(UO.GetX() + 1, UO.GetY(), UO.WorldNum());
    if (Truth(ArrayLength(land) >= 3))
    {
        var deltaZ = land[1] - UO.GetZ();
        UO.Print("Ground height difference: " + Convert.ToString(deltaZ));
    }

    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. Read the name of the found land - scenario class

Parameters and execution flow:

  • group=0 selects land; land[0] - graphic.
  • GetTileName returns text, whereas GetLandscapeTile returns an array.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(land) >= 3))
        {
            var name = UO.GetTileName(0, land[0]);
            UO.Print(name);
        }

        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.GetLandscapeTile(x, y, map) — UO.GetLandscapeTile(Any,Any,Any)

Parameters: x (Any), y (Any), map (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetLandscapeTile(InjectionValue x, InjectionValue y, InjectionValue map)

            => ToArray(bridge.GetLandscapeTile(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map)));

UO.GetLayerCount

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

C# signatures

dynamic UO.GetLayerCount(object? x, object? y, object? worldNum);

Counts non-earth geometry records in one cell.

Parameters

  • x — World coordinate X of the cell of the current map, not the position in the gump.
  • y — World Y coordinate of the current map cell.
  • worldNum — Card/facet number; use UO.WorldNum(). Only the currently loaded card is read.

Return value

int — the number of graphic/Z/hue triples received by GetStaticTiles. In the current client, Static, Multi and Item are taken into account: multiple records of the same height are counted separately. An empty square/another card gives 0. This is not the number of the equipment layer, not the number of floors, not the number of unique heights, or bool.

Behavior

  • The command reads the local map and does not trigger movement or target. A cell outside the size of the map is not replaced by a cell in an adjacent column.
  • Z height, graphic/type, hue color, flags and equipment layer have different meanings. Null graphic or Z=0 may be valid data; check the result form.
  • The composition corresponds to ReadStaticsXY, not GetLayer or ObjAtLayer. This client includes dynamic items and Multi parts.

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

1. Count records under a character - direct script

Parameters and execution flow:

  • count — number of cell records; 1 means one entry, not a logical success.
var count = UO.GetLayerCount(UO.GetX(), UO.GetY(), UO.WorldNum());
UO.Print("Tile records: " + Convert.ToString(count));

2. Check adjacent cell - script function

Parameters and execution flow:

  • The absence of records does not prove the passage of land. The presence of a recording also does not prove that it is a wall.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX() + 1;
    var y = UO.GetY();
    var count = UO.GetLayerCount(x, y, UO.WorldNum());
    if (Truth(count > 0))
    {
        UO.Print("Non-land geometry exists: " + Convert.ToString(count));
    }
    else
    {
        UO.Print("No loaded non-land records");
    }

    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 contents of two map layers - script class

Parameters and execution flow:

  • The current and neighboring cells in the same world are checked. The number of layers is not their height or graphic.
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 x = UO.GetX();
        int y = UO.GetY();
        int world = UO.WorldNum();
        int land = UO.GetLayerCount(x, y, world);
        int nearby = UO.GetLayerCount(x + 1, y, world);
        UO.Print($"Layers here: {land}; adjacent tile: {nearby}");
        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.GetLayerCount(x, y, worldNum) — UO.GetLayerCount(Any,Any,Any)

Parameters: x (Any), y (Any), worldNum (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getlayercount":

                    // Stealth's deprecated GetLayerCount(X,Y,WorldNum) is the

                    // number of static records at a map cell.  The portable

                    // bridge returns each record as Graphic/Z/Hue triples.

                    return new InjectionValue(bridge.GetStaticTiles(Arg(0), Arg(1), Arg(2)).Length / 3);

UO.GetMapCell

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

C# signatures

dynamic UO.GetMapCell(object? x, object? y, object? worldNum);

Reads graphic, height and land flags in one map cell.

Parameters

  • x — World coordinate X of the cell of the current map, not the position in the gump.
  • y — World Y coordinate of the current map cell.
  • worldNum — Card/facet number; use UO.WorldNum(). Only the currently loaded card is read.

Return value

Array of three int: [0] graphic/type lands, [1] world Z bases land, [2] minor 32 bits of tiledata flags. An inaccessible cell or other card results in an empty Array. This is not a serial, bool or Pascal record; do not use .Tile/.Z fields. For the number of fields, call ArrayLength(cell).

Behavior

  • The command reads the local map and does not trigger movement or target. A cell outside the size of the map is not replaced by a cell in an adjacent column.
  • Z height, graphic/type, hue color, flags and equipment layer have different meanings. Null graphic or Z=0 may be valid data; check the result form.

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

1. Read the ground under the character - direct script

Parameters and execution flow:

  • X/Y is taken from self, WorldNum is the current card. cell stores all fields of one call.
  • The indices start with 0. cell[1] is the height, not a sign of a successful search; an empty array is checked before indexing.
var cell = UO.GetMapCell(UO.GetX(), UO.GetY(), UO.WorldNum());
if (Truth(ArrayLength(cell) == 3))
{
    UO.Print("Type: " + Convert.ToString(cell[0]));
    UO.Print("Land Z: " + Convert.ToString(cell[1]));
    UO.Print("Flags: " + Convert.ToString(cell[2]));
}
else
{
    UO.Print("Map cell unavailable");
}

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. Compare two adjacent cells - script function

Parameters and execution flow:

  • The second call reads the square to the east, both using the same card.
  • The difference in ground heights does not prove passability: walls, statics and other objects are checked separately.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX();
    var y = UO.GetY();
    var map = UO.WorldNum();
    var here = UO.GetMapCell(x, y, map);
    var east = UO.GetMapCell(x + 1, y, map);
    if (Truth(ArrayLength(here) == 3) && Truth(ArrayLength(east) == 3))
    {
        UO.Print("Land difference: " + Convert.ToString(east[1] - here[1]));
    }

    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. Compare Earth's Base to Average Surface - Script Class

Parameters and execution flow:

  • GetMapCell reads Land.Z; GetSurfaceZ reads Land.AverageZ.
  • Both values ​​are height. On sloping ground they may vary; This is not the height of the floor of the house.
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 x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var cell = UO.GetMapCell(x, y, map);
        if (Truth(ArrayLength(cell) == 3))
        {
            var average = UO.GetSurfaceZ(x, y, map);
            UO.Print("Base: " + Convert.ToString(cell[1]) + ", average: " + Convert.ToString(average));
        }

        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.GetMapCell(x, y, worldNum) — UO.GetMapCell(Any,Any,Any)

Parameters: x (Any), y (Any), worldNum (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getmapcell":

                    return new InjectionValue(bridge.GetLandscapeTile(Arg(0), Arg(1), Arg(2))

                        .Select(value => new InjectionValue(value)).ToArray());

UO.GetNextStepZ

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

C# signatures

int UO.GetNextStepZ(object? currX, object? currY, object? destX, object? destY, object? worldNum, object? currZ);

Calculates the estimated height of the next step in the specified direction.

Parameters

  • currX — Initial world X, usually UO.GetX().
  • currY — Initial world Y, usually UO.GetY().
  • destX — X destination. To check one specific step, pass an adjacent cell.
  • destY — Y destination; together with DestX, it sets the direction of one step, rather than the full route.
  • worldNum — Card/facet number; use UO.WorldNum(). Only the currently loaded card is read.
  • currZ — Initial height Z, usually UO.GetZ(); geometric calculation uses the range -128..127.

Return value

int — calculated Z of the next step; 0 and negative numbers are valid heights. When a character or other card 0 is disabled. The method returns the Z component of the check even if it fails; the number itself is not confirmation of passage. For flag and height together, use IsWorldCellPassable and read [0]/[1].

Behavior

  • The command reads the local map and does not trigger movement or target. A cell outside the size of the map is not replaced by a cell in an adjacent column.
  • Z height, graphic/type, hue color, flags and equipment layer have different meanings. Null graphic or Z=0 may be valid data; check the result form.
  • The calculation does not take a step and does not open the door. It checks the local geometry; the server may reject the actual movement. If bridge does not return Z, CurrZ is used.

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.GetNextStepZ(UO.GetX(), UO.GetY(), UO.GetX() + 1, UO.GetY(), UO.WorldNum(), UO.GetZ());
UO.Print("GetNextStepZ: " + Convert.ToString(result));

1. Find out the estimated height of the eastern step - direct script

Parameters and execution flow:

  • Six parameters: original X/Y, neighboring X/Y, map and original Z. nextZ - height, not true/false.
var x = UO.GetX();
var y = UO.GetY();
var z = UO.GetZ();
var nextZ = UO.GetNextStepZ(x, y, x + 1, y, UO.WorldNum(), z);
UO.Print("Candidate Z: " + Convert.ToString(nextZ));

2. Separate trip from true altitude 0 - script function

Parameters and execution flow:

  • The call is made only when there is a known connection. Between checking and reading, the connection may be lost; Z=0 is still not a success code.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(Truth(UO.Connected()) == true))
    {
        var x = UO.GetX();
        var y = UO.GetY();
        var z = UO.GetNextStepZ(x, y, x, y + 1, UO.WorldNum(), UO.GetZ());
        UO.Print("South candidate Z: " + Convert.ToString(z));
    }
    else
    {
        UO.Print("Character disconnected");
    }

    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 next step from current height - script class

Parameters and execution flow:

  • The coordinates of the source and target cells are transmitted separately. The result is the expected height, even with obstruction; the pass flag separately gives IsWorldCellPassable.
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 x = UO.GetX();
        int y = UO.GetY();
        int z = UO.GetZ();
        int nextZ = UO.GetNextStepZ(x, y, x + 1, y, UO.WorldNum(), z);
        UO.Print($"Current height: {z}; next-step result: {nextZ}");
        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.GetNextStepZ(currX, currY, destX, destY, worldNum, currZ) — UO.GetNextStepZ(Any,Any,Any,Any,Any,Any)

Parameters: currX (Any), currY (Any), destX (Any), destY (Any), worldNum (Any), currZ (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

case "getnextstepz":

                {

                    if (bridge.IsOnline() == 0 || Arg(4) != bridge.WorldNumber)

                        return new InjectionValue(0);

                    int[] step = bridge.CheckWorldStep(Arg(0), Arg(1), Arg(5), Arg(2), Arg(3), Arg(4));

                    return new InjectionValue(step.Length > 1 ? step[1] : Arg(5));

                }

UO.GetStaticArt

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

C# signatures

dynamic UO.GetStaticArt(object? objType, object? hue);

Gets a single Graphic image from the installed Ultima Online graphics files and returns it in memory in BMP format. Useful for checking your game resources, icon sizes, reading pixel color and comparing colored versions of an item. The command itself does not open a window, save a file, or search for items in the world.

Parameters

  • objType — Mandatory Graphic/type from the static art section: integer 0..65535, string with the same number, or saved name AddType. For example, 0x0EED is an art for a stack of gold. This is not the serial of the item, not the map/tile coordinate, and not the animation number of the body. To get the art of a loaded item, pass UO.GetType(item), where item is its serial. If the numeric type is out of range, the result is an empty array; an unknown string name causes a conversion error.
  • hue — Mandatory integer color value: 0 — original colors of the art; a positive value is hue from the client files. Numeric strings are acceptable, including the result UO.GetColor(item). The value is limited to the range 0..65535: negative becomes 0, too large becomes 65535. Here -1 does NOT mean any color. The PartialHue flag art uses partial coloring; for others - complete. The result of a particular hue depends on the loaded color table.

Return value

Array is a one-dimensional int array, each element 0..255 represents one byte of the complete BMP file, starting with the header. Indexing with 0. It is not a bool, not ID, not a path, not a Bitmap object, and not a color array RGB. An empty array means the numeric type is not valid, the art is missing, or the required game files are not loaded. Before reading the title, check ArrayLength; the empty array is not equal to the number 0.

Behavior

  • Exactly two arguments are required. Reading is performed from the client's local resources, without a request to the server. The existence of an object in the world is not required. For mobile, the number from GetType means body; here the same number addresses a different resource section and does not provide an image of the character animation.
  • Result format: uncompressed 24-bit BMP. Bytes [0]=66 and [1]=77 - BM; [2..5] - size of the entire file; [10..13] - the beginning of the pixels, now 54; [14..17] - size of DIB-header, now 40; [18..21] - width; [22..25] - positive height; [26..27] - 1 plane; [28..29] - 24 bit. Multibyte numbers are written little-endian.
  • Each pixel occupies three bytes in the order B, G, R. The lines go from bottom to top and are padded with zero bytes up to a multiple of 4. String length = Int((width * 3 + 3) / 4) * 4. For x,y coordinates from the top left corner, offset = 54 + (height - 1 - y) * stride + x * 3. Check the bounds and size of the array before accessing.
  • The transparency of the original art is not preserved: BMP does not contain alpha here. The transparent background becomes black, and it is impossible to distinguish it from the original black pixel by the result. Screenshot, game window scaling, light, visibility range and object coordinates are not involved.
  • For each call, an image array is generated. If you need art many times, save the result to a variable and process it again. Don't call loading/coloring for every pixel inside the loop. The same parameters and unchanged files give the same result; different hue are not required to change every pixel, especially with PartialHue.
  • A real .bmp needs binary output of the exact bytes without text encoding. A regular File.WriteLine or JsonSave does not create BMP. The examples below process the array in memory and do not promise the presence of a non-existent File.WriteBytes.

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

1. Check icon size before processing it yourself - direct script

Parameters and execution flow:

  • ObjType=0x0EED selects the resource, Hue=0 leaves the original colors. The array is checked before reading offsets 18 and 22. 64 is the example's own limit, not a command limit.
  • ArtSizeField is a user-defined function C#, not a UO command. Adds four bytes with weights 1, 256, 65536, 16777216. The script helps you choose the size of your cell; Doesn't create a gump automatically.
var bmp = UO.GetStaticArt(0x0EED, 0);
if (Truth(ArrayLength(bmp) < 54))
{
    UO.Print("Gold art is unavailable");
    return null;
}
var width = ArtSizeField(bmp, 18);
var height = ArtSizeField(bmp, 22);
if (Truth(width > 64) || Truth(height > 64))
{
    UO.Print("Use a larger cell for this icon");
    return null;
}
UO.Print("Icon fits: " + Convert.ToString(width) + " x " + Convert.ToString(height));

dynamic ArtSizeField(dynamic bytes, dynamic offset)
{
    return bytes[offset] + bytes[offset+1]*256 + bytes[offset+2]*65536 + bytes[offset+3]*16777216;
}

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. Calculate RGB of a pixel taking into account the inverted lines BMP - script function

Parameters and execution flow:

  • GetStaticArt returns BMP; ArtPixelRGB is a separate example function for this format. x=0,y=0 means the top left pixel of the image, not the world coordinates. The replacement height-1-y is required due to the order of the lines from bottom to top.
  • The function returns RGB int 0..16777215, and uses -1 only as its indicator of the absence of a pixel. Black 0 is a valid color, not false and not an error. Therefore, the test for if rgb < 0 is separate from if rgb = 0.
return  RunScenario();
 object? RunScenario()
{
    var bmp = UO.GetStaticArt(0x0EED, 0);
    var rgb = ArtPixelRGB(bmp, 0, 0);
    if (Truth(rgb < 0))
    {
        UO.Print("No pixel at this position");
        return null;
    }

    if (Truth(rgb == 0))
    {
        UO.Print("Black pixel: may also be the original transparent background");
    }

    return null;
}

dynamic ArtPixelRGB(dynamic bmp, dynamic x, dynamic y)
{
    if (Truth(ArrayLength(bmp) < 54))
    {
        return -1;
    }

    var width = bmp[18] + bmp[19] * 256 + bmp[20] * 65536 + bmp[21] * 16777216;
    var height = bmp[22] + bmp[23] * 256 + bmp[24] * 65536 + bmp[25] * 16777216;
    if (Truth(x < 0) || Truth(y < 0) || Truth(x >= width) || Truth(y >= height))
    {
        return -1;
    }

    var stride = Math.Floor((width * 3 + 3) / 4) * 4;
    var offset = 54 + (height - 1 - y) * stride + x * 3;
    if (Truth(offset + 2 >= ArrayLength(bmp)))
    {
        return -1;
    }

    return bmp[offset + 2] * 65536 + bmp[offset + 1] * 256 + bmp[offset];
}

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. Compare original and colored versions of the same art - script class

Parameters and execution flow:

  • 0x1F03 — Graphic robes; 0 and 0x0044 are the original and selected hue. The same Graphic gives the same dimensions. If the result is empty, the comparison does not begin.
  • changed counts different bytes of color channels, not objects or number of pixels. One pixel can change up to three bytes. PartialHue, color table and original colors may leave part or all of the image the same; this is not evidence of a team error.
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 original = UO.GetStaticArt(0x1F03, 0);
        var colored = UO.GetStaticArt(0x1F03, 0x0044);
        var size = ArrayLength(original);
        if (Truth(size < 54) || Truth(size != ArrayLength(colored)))
        {
            UO.Print("Cannot compare these art resources");
            return null;
        }

        var changed = 0;
        for (int offset = (int)(54); offset <= size - 1; offset += (int)(1))
        {
            if (Truth(original[offset] != colored[offset]))
            {
                changed = changed + 1;
            }
        }

        if (Truth(changed == 0))
        {
            UO.Print("This hue did not change the exported bytes");
        }
        else
        {
            UO.Print("Changed color bytes: " + Convert.ToString(changed));
        }

        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.GetStaticArt(objType, hue) — UO.GetStaticArt(Any,Any)

Parameters: objType (Any), hue (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getstaticart":

                    return new InjectionValue(bridge.GetStaticArt(ResolveType(arguments[0]), Arg(1)).Select(value => new InjectionValue(value)).ToArray());

UO.GetStaticTileAt

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

C# signatures

dynamic UO.GetStaticTileAt(object? x, object? y, object? index);
dynamic UO.GetStaticTileAt(object? x, object? y, object? map, object? index);

Returns an extended record of one record above the ground of the selected cell.

Parameters

  • x — X cell of the currently loaded map; world coordinate, not position inside the gump.
  • y — Y cell of the currently loaded map; world coordinate, not position inside the gump.
  • map — Card number. If this argument is not present in the selected form, the current map is used. The real client only reads tiles from the currently loaded map.
  • index — The sequence number of the record in the results GetStaticTiles, starting with 0. This is not a graphic, not a Z, and not an equipment layer. In the form of 3 arguments, index comes third; in the form of 4 arguments map third, index fourth.

Return value

Array of 11 fields of one record; indices start with 0:

  • [0] kind — string: "land", "static", or "object".
  • [1] serial — int: serial of a dynamic item; for land/static is 0.
  • [2] graphic — int: graphics type.
  • [3] x, [4] y - int: world coordinates of the cell.
  • [5] z - int: the height of the base in the world.
  • [6] hue - int: color, near the ground 0.
  • [7] flags - int: low 32 bits of tiledata flags.
  • [8] name — string: name from tiledata.
  • [9] layer - int: layer of equipment from tiledata, near the ground 0; not a static index.
  • [10] height - int: graphic height from tiledata, near the ground 0; not the Z coordinate.

An empty array [] means no entry or an inaccessible card/cell. For GetStaticTileAt, a negative/too large index also produces []; index overflow does not select someone else's entry.

Behavior

  • The data refers to the currently loaded map. Another card or unreachable cell results in an empty array. Direct tile queries may additionally report map mismatches; GetWorldCell and GetWorldTilesArray immediately return an empty array without such a message.
  • Array indices start with 0. Check ArrayLength before reading the field. Z stands for world altitude; layer is the equipment property from tiledata, and index is the serial number of the cell entry.

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

1. Read type, Z and layer separately - direct script

Parameters and execution flow:

  • x/y — character position; the card is lowered and selected automatically. For GetStaticTileAt index=0 means the first entry.
  • The fields [2], [5], [9] have different meanings; all are read only after checking the length of 11.
var tile = UO.GetStaticTileAt(UO.GetX(), UO.GetY(), 0);
if (Truth(ArrayLength(tile) == 11))
{
    UO.Print("Type: " + Convert.ToString(tile[2]));
    UO.Print("World Z: " + Convert.ToString(tile[5]));
    UO.Print("Equipment layer: " + Convert.ToString(tile[9]));
}
else
{
    UO.Print("Tile is unavailable");
}

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. Get graphic name and height - script function

Parameters and execution flow:

  • The same coordinates are used; GetStaticTileAt reads index=0.
  • tile[8] is the title string, tile[10] is the height dimension from tiledata, not the Z base.
return  RunScenario();
 object? RunScenario()
{
    var tile = UO.GetStaticTileAt(UO.GetX(), UO.GetY(), 0);
    if (Truth(ArrayLength(tile) == 11))
    {
        UO.Print(tile[8]);
        UO.Print("Graphic height: " + Convert.ToString(tile[10]));
    }

    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. Prepare target by type and coordinates - script class

Parameters and execution flow:

  • WaitTargetTile gets graphic, x, y, z from fields 2…5.
  • This is just preparation for the next target. The example does not trigger a tool or spell. serial=0 for statics should not be passed as ID of the item.
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 tile = UO.GetStaticTileAt(UO.GetX(), UO.GetY(), 0);
        if (Truth(ArrayLength(tile) == 11))
        {
            UO.WaitTargetTile(tile[2], tile[3], tile[4], tile[5]);
        }

        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.GetStaticTileAt(x, y, index) — UO.GetStaticTileAt(Any,Any,Any)

Parameters: x (Any), y (Any), index (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetStaticTileAt(InjectionValue x, InjectionValue y, InjectionValue index)

            => GetStaticTileAt(x, y, new InjectionValue(bridge.WorldNumber), index);

UO.GetStaticTileAt(x, y, map, index) — UO.GetStaticTileAt(Any,Any,Any,Any)

Parameters: x (Any), y (Any), map (Any), index (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetStaticTileAt(InjectionValue x, InjectionValue y, InjectionValue map, InjectionValue index)

        {

            int cellX = NumberConversions.ToInt(x);

            int cellY = NumberConversions.ToInt(y);

            int[] statics = bridge.GetStaticTiles(cellX, cellY, NumberConversions.ToInt(map)) ?? Array.Empty<int>();

            int tileIndex = NumberConversions.ToInt(index);

            if (tileIndex < 0 || tileIndex >= statics.Length / 3)

                return new InjectionValue(Array.Empty<InjectionValue>());

            int offset = tileIndex * 3;

            return offset + 2 < statics.Length

                ? BuildWorldTileRecord("static", 0, statics[offset], cellX, cellY, statics[offset + 1], statics[offset + 2], 1)

                : new InjectionValue(Array.Empty<InjectionValue>());

        }

UO.GetStaticTileData

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

C# signatures

dynamic UO.GetStaticTileData(object? tile);

Reads the static graphic extended help entry from tiledata.

Parameters

  • tile — Graphic/type of record, not serial and not an index inside the cell. The static table is selected by the command name itself.

Return value

Array of 17 fields for a valid graphic. All fields are int except name (string):

  • [0] graphic — graphic/type of entry.
  • [1] flags — low-order 32 flag bits.
  • [2] name — name from tiledata (string).
  • [3] weight — weight from tiledata.
  • [4] layer — equipment layer number.
  • [5] count is the Count field from tiledata, not the number of items in the world.
  • [6] animId - ID animations.
  • [7] hue - hue from tiledata.
  • [8] lightIndex — index of the light source.
  • [9] height — graphic height, not world Z.
  • [10] wet — 1 if wet is installed, otherwise 0.
  • [11] impassable — 1 if impassable, otherwise 0.
  • [12] surface — 1 if surface, otherwise 0.
  • [13] foliage — 1 if foliage, otherwise 0.
  • [14] door — 1 if door, otherwise 0.
  • [15] wall — 1 if wall, otherwise 0.
  • [16] container — 1 if container, otherwise 0.

For an invalid graphic, there are no reference properties: the short array [переданный graphic, 0, ""] is returned. Check the full length before reading the properties. This is not a Pascal record or a list of objects.

Behavior

  • The command reads tiledata and does not require an item with this graphic in the world. Flags describe the resource; the result does not replace a full route check.

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

1. Read entry name - direct script

Parameters and execution flow:

  • Tile — numeric graphic of the selected table.
  • data[2] contains the name. Length check separates a full entry from a short entry of invalid graphic.
var data = UO.GetStaticTileData(0x0CCA);
if (Truth(ArrayLength(data) == 17))
{
    UO.Print(data[2]);
}
else
{
    UO.Print("Tiledata entry is unavailable");
}

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. Check Individual Boolean Flag - Script Function

Parameters and execution flow:

  • data[11] is a separate impassable field: 1 (condition met), 0 (condition not met).
  • This check does not take into account other objects in the cell or the character's abilities.
return  RunScenario();
 object? RunScenario()
{
    var data = UO.GetStaticTileData(0x0CCA);
    if (Truth(ArrayLength(data) == 17))
    {
        if (Truth(data[11]))
        {
            UO.Print("Impassable flag is set");
        }
        else
        {
            UO.Print("Impassable flag is not set");
        }
    }

    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. Output graphic and general flag mask - script class

Parameters and execution flow:

  • data[0] repeats the transmitted graphic, data[1] is a general flag mask.
  • The mask can contain several bits at the same time; its numeric value is not serial.
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 data = UO.GetStaticTileData(0x0CCA);
        if (Truth(ArrayLength(data) == 17))
        {
            UO.Print("Graphic: " + Convert.ToString(data[0]));
            UO.Print("Flags: " + Convert.ToString(data[1]));
        }

        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.GetStaticTileData(tile) — UO.GetStaticTileData(Any)

Parameters: tile (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getstatictiledata":

                    return BuildTileData(1, Arg(0));

UO.GetStaticTiles

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

C# signatures

dynamic UO.GetStaticTiles(object? x, object? y, object? map);

Reads entries above the ground in one cell of the current map.

Parameters

  • x — X cell of the currently loaded map; world coordinate, not position inside the gump.
  • y — Y cell of the currently loaded map; world coordinate, not position inside the gump.
  • map — Card number. If this argument is not present in the selected form, the current map is used. The real client only reads tiles from the currently loaded map.

Return value

Array is a flat sequence of int-triples [graphic0, z0, hue0, graphic1, z1, hue1, …]. The number of entries is equal to the length of the array / 3. For writing, i graphic is in [i*3], Z is in [i*3+1], hue is in [i*3+2]. An empty array means no entries or an inaccessible card/cell. Serial and layer number are not returned here.

Behavior

  • The data refers to the currently loaded map. Another card or unreachable cell results in an empty array. Direct tile queries may additionally report map mismatches; GetWorldCell and GetWorldTilesArray immediately return an empty array without such a message.
  • Array indices start with 0. Check ArrayLength before reading the field. Z stands for world altitude; layer is the equipment property from tiledata, and index is the serial number of the cell entry.
  • The current bridge lists Static, Multi and world Items in the cell chain. The name of the command does not limit the result solely to statics.mul entries. The chain order does not guarantee Z sort.

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

1. Count cell records - direct script

Parameters and execution flow:

  • x/y/map selects the current cell.
  • The length of the array is the number of fields. Dividing by 3 gives the number of entries.
var tiles = UO.GetStaticTiles(UO.GetX(), UO.GetY(), UO.WorldNum());
var count = ArrayLength(tiles) / 3;
UO.Print("Tile records: " + Convert.ToString(count));

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

2. Iterate through the graphic and height of all posts - script function

Parameters and execution flow:

  • offset is the index of the first field of the next triple, increased by 3.
  • The offset+2 check protects the entire record from being read.
return  RunScenario();
 object? RunScenario()
{
    var tiles = UO.GetStaticTiles(UO.GetX(), UO.GetY(), UO.WorldNum());
    var offset = 0;
    while (Truth(offset + 2 < ArrayLength(tiles)))
    {
        UO.Print("Type: " + Convert.ToString(tiles[offset]) + ", Z: " + Convert.ToString(tiles[offset + 1]));
        offset = offset + 3;
    }

    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. Read hue of first entry - script class

Parameters and execution flow:

  • x+1 selects an adjacent cell.
  • tiles[2] — color of the first entry; This is not the third tile.
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 tiles = UO.GetStaticTiles(UO.GetX() + 1, UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(tiles) >= 3))
        {
            var hue = tiles[2];
            UO.Print("First tile hue: " + Convert.ToString(hue));
        }
        else
        {
            UO.Print("No tile records");
        }

        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.GetStaticTiles(x, y, map) — UO.GetStaticTiles(Any,Any,Any)

Parameters: x (Any), y (Any), map (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetStaticTiles(InjectionValue x, InjectionValue y, InjectionValue map)

            => ToArray(bridge.GetStaticTiles(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map)));

UO.GetStaticTilesArray

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

C# signatures

dynamic UO.GetStaticTilesArray(object? xmin, object? ymin, object? xmax, object? ymax, object? worldNum, object? tileType);

Searches for Static/Multi/Item entries by graphic/type in a rectangle.

Parameters

  • xmin — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • ymin — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • xmax — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • ymax — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • worldNum — Map/facet 0..255; use UO.WorldNum(). Another map gives an empty Array. If the map changes between chunks, the partial result is discarded.
  • tileType — One graphic/type of tile, usually 0..65535; this is not serial. 0 is the exact graphic 0, -1 does not mean any type. A mismatched type gives an empty result.

Return value

Array of entries [graphic, X, Y, Z, hue]; all fields are int. graphic - type, Z - base, hue - color. Multiple cell entries remain separate. No matches: empty Array. The quantity is ArrayLength(result), not the result itself. The indices start with 0. This is not a bool, serial or Pascal record; there is no seventh output parameter.

Behavior

  • Local data is read. Search does not change FindItem/FindCount and does not perform a move, target, or network command.
  • Order: X ascending, within X - Y ascending. Records of one cell preserve the order of bridge; it is not sorted by distance or height.
  • The search is processed in chunks of up to 32 cells with a soft budget of about 1 ms. Cancellation is checked between servings. A complex cell or cold read may go over budget. It is better to divide a large area; the world can change while reading.
  • The current client's Static branch includes Static, Multi and Item from the cell, including loaded items on the ground; Land and Mobile are not included. It is wider than the classic selection of only static files.

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

1. Search near a character - direct script

Parameters and execution flow:

  • x/y — position self, map — current map. The region 3×3 includes the boundaries. In Ex two type are transmitted, in normal form one. Change the samples to suit your resources; this is a graphic, not a ID object.
var x = UO.GetX();
var y = UO.GetY();
var map = UO.WorldNum();
var rows = UO.GetStaticTilesArray(x, y, x + 2, y + 2, map, 0x0CCA);
UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));

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

2. Rearranged angles and output of all fields - script function

Parameters and execution flow:

  • The region 2×2 is transferred from the larger angle to the smaller one. The algorithm itself normalizes the boundaries. row - one record; PrintTile is declared in its entirety and only formats numbers, without moving anything. graphic - type, x/y - coordinates, z - height, hue - color. For land, a conditional hue=0 is passed: there is no color field in the land record.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX();
    var y = UO.GetY();
    var map = UO.WorldNum();
    var rows = UO.GetStaticTilesArray(x + 1, y + 1, x, y, map, 0x0CCA);
    var i = 0;
    while (Truth(i < ArrayLength(rows)))
    {
        var row = rows[i];
        PrintTile(row[0], row[1], row[2], row[3], row[4]);
        i = i + 1;
    }

    return null;
}

void PrintTile(dynamic graphic, dynamic x, dynamic y, dynamic z, dynamic hue)
{
    UO.Print("Type=" + Convert.ToString(graphic) + " X=" + Convert.ToString(x) + " Y=" + Convert.ToString(y));
    UO.Print("Z=" + Convert.ToString(z) + " hue=" + Convert.ToString(hue));
}

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. Re-Poll with Retry Limit - Script Class

Parameters and execution flow:

  • No more than three searches for one cell; between attempts WaitAsync(250). Each call creates a new result. Zero length means there are no matches now, rather than the object being permanently missing from the server.
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 x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var attempt = 0;
        while (Truth(attempt < 3))
        {
            var rows = UO.GetStaticTilesArray(x, y, x, y, map, 0x0CCA);
            UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));
            attempt = attempt + 1;
            await Delay(250);
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    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.GetStaticTilesArray(xmin, ymin, xmax, ymax, worldNum, tileType) — UO.GetStaticTilesArray(Any,Any,Any,Any,Any,Any)

Parameters: xmin (Any), ymin (Any), xmax (Any), ymax (Any), worldNum (Any), tileType (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getstatictilesarray":

                    return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), new[] { Arg(5) }, true);

UO.GetStaticTilesArrayEx

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

C# signatures

dynamic UO.GetStaticTilesArrayEx(object? xmin, object? ymin, object? xmax, object? ymax, object? worldNum, object? tileTypes);

Searches for Static/Multi/Item entries by graphic/type in a rectangle.

Parameters

  • xmin — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • ymin — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • xmax — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • ymax — World coordinates of two angles, inclusive; 0..65535. The rearranged angles are normalized. Area no more than 1 000 000 cells; invalid boundaries cause a script error before the map is read.
  • worldNum — Map/facet 0..255; use UO.WorldNum(). Another map gives an empty Array. If the map changes between chunks, the partial result is discarded.
  • tileTypes — Array of numeric graphic/type; every matching type is included. Repeating type does not duplicate entries. A scalar is also accepted as one type. An empty Array means all type; an array of one 0 searches only 0.

Return value

Array of entries [graphic, X, Y, Z, hue]; all fields are int. graphic - type, Z - base, hue - color. Multiple cell entries remain separate. No matches: empty Array. The quantity is ArrayLength(result), not the result itself. The indices start with 0. This is not a bool, serial or Pascal record; there is no seventh output parameter.

Behavior

  • Local data is read. Search does not change FindItem/FindCount and does not perform a move, target, or network command.
  • Order: X ascending, within X - Y ascending. Records of one cell preserve the order of bridge; it is not sorted by distance or height.
  • The search is processed in chunks of up to 32 cells with a soft budget of about 1 ms. Cancellation is checked between servings. A complex cell or cold read may go over budget. It is better to divide a large area; the world can change while reading.
  • The current client's Static branch includes Static, Multi and Item from the cell, including loaded items on the ground; Land and Mobile are not included. It is wider than the classic selection of only static files.

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.GetStaticTilesArrayEx(UO.X(), UO.Y(), UO.X() + 1, UO.Y() + 1, UO.WorldNum(), new[] { 0x0CCA });
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Search near a character - direct script

Parameters and execution flow:

  • x/y — position self, map — current map. The region 3×3 includes the boundaries. In Ex two type are transmitted, in normal form one. Change the samples to suit your resources; this is a graphic, not a ID object.
dynamic[] types = new dynamic[checked((int)(1) + 1)];
types[0] = 0x0CCA;
types[1] = 0x0CCB;
var x = UO.GetX();
var y = UO.GetY();
var map = UO.WorldNum();
var rows = UO.GetStaticTilesArrayEx(x, y, x + 2, y + 2, map, types);
UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));

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

2. Rearranged angles and output of all fields - script function

Parameters and execution flow:

  • The region 2×2 is transferred from the larger angle to the smaller one. The algorithm itself normalizes the boundaries. row - one record; PrintTile is declared in its entirety and only formats numbers, without moving anything. graphic - type, x/y - coordinates, z - height, hue - color. For land, a conditional hue=0 is passed: there is no color field in the land record.
return  RunScenario();
 object? RunScenario()
{
    dynamic[] types = new dynamic[checked((int)(1) + 1)];
    types[0] = 0x0CCA;
    types[1] = 0x0CCB;
    var x = UO.GetX();
    var y = UO.GetY();
    var map = UO.WorldNum();
    var rows = UO.GetStaticTilesArrayEx(x + 1, y + 1, x, y, map, types);
    var i = 0;
    while (Truth(i < ArrayLength(rows)))
    {
        var row = rows[i];
        PrintTile(row[0], row[1], row[2], row[3], row[4]);
        i = i + 1;
    }

    return null;
}

void PrintTile(dynamic graphic, dynamic x, dynamic y, dynamic z, dynamic hue)
{
    UO.Print("Type=" + Convert.ToString(graphic) + " X=" + Convert.ToString(x) + " Y=" + Convert.ToString(y));
    UO.Print("Z=" + Convert.ToString(z) + " hue=" + Convert.ToString(hue));
}

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. Re-Poll with Retry Limit - Script Class

Parameters and execution flow:

  • No more than three searches for one cell; between attempts WaitAsync(250). Each call creates a new result. Zero length means there are no matches now, rather than the object being permanently missing from the server.
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()
    {
        dynamic[] types = new dynamic[checked((int)(1) + 1)];
        types[0] = 0x0CCA;
        types[1] = 0x0CCB;
        var x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var attempt = 0;
        while (Truth(attempt < 3))
        {
            var rows = UO.GetStaticTilesArrayEx(x, y, x, y, map, types);
            UO.Print("Records: " + Convert.ToString(ArrayLength(rows)));
            attempt = attempt + 1;
            await Delay(250);
        }

        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    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.GetStaticTilesArrayEx(xmin, ymin, xmax, ymax, worldNum, tileTypes) — UO.GetStaticTilesArrayEx(Any,Any,Any,Any,Any,Any)

Parameters: xmin (Any), ymin (Any), xmax (Any), ymax (Any), worldNum (Any), tileTypes (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getstatictilesarrayex":

                    return FindPortableTiles(Arg(0), Arg(1), Arg(2), Arg(3), Arg(4), ArrayArg(5), true);

UO.GetSurfaceZ

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

C# signatures

dynamic UO.GetSurfaceZ(object? x, object? y, object? worldNum);

Reads the average height of the ground surface in a cell.

Parameters

  • x — World coordinate X of the cell of the current map, not the position in the gump.
  • y — World Y coordinate of the current map cell.
  • worldNum — Card/facet number; use UO.WorldNum(). Only the currently loaded card is read.

Return value

int — Land.AverageZ, including negative height and 0. If there is no map/ground or a map mismatch, 0 is returned, so this value does not distinguish missing data from the true height 0. This is not bool, the floor or the height of the nearest static.

Behavior

  • The command reads the local map and does not trigger movement or target. A cell outside the size of the map is not replaced by a cell in an adjacent column.
  • Z height, graphic/type, hue color, flags and equipment layer have different meanings. Null graphic or Z=0 may be valid data; check the result form.

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

1. Average height under character - direct script

Parameters and execution flow:

  • All three parameters relate to the current cell of the map. z is a numerical height, not the result of movement.
var x = UO.GetX();
var y = UO.GetY();
var map = UO.WorldNum();
var z = UO.GetSurfaceZ(x, y, map);
UO.Print("Average land Z: " + Convert.ToString(z));

2. Check ground availability before reading - script function

Parameters and execution flow:

  • GetMapCell is needed to distinguish missing data from height 0. The map may still change between two calls.
return  RunScenario();
 object? RunScenario()
{
    var x = UO.GetX() + 1;
    var y = UO.GetY();
    var map = UO.WorldNum();
    var cell = UO.GetMapCell(x, y, map);
    if (Truth(ArrayLength(cell) == 3))
    {
        UO.Print("Average: " + Convert.ToString(UO.GetSurfaceZ(x, y, map)));
    }
    else
    {
        UO.Print("No land data");
    }

    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. Show Change in Average Height to East - Scenario Class

Parameters and execution flow:

  • The difference shows the slope of the earth. This example does not move anything and does not calculate the route.
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 x = UO.GetX();
        var y = UO.GetY();
        var map = UO.WorldNum();
        var a = UO.GetMapCell(x, y, map);
        var b = UO.GetMapCell(x + 1, y, map);
        if (Truth(ArrayLength(a) == 3) && Truth(ArrayLength(b) == 3))
        {
            var difference = UO.GetSurfaceZ(x + 1, y, map) - UO.GetSurfaceZ(x, y, map);
            UO.Print("Average difference: " + Convert.ToString(difference));
        }

        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.GetSurfaceZ(x, y, worldNum) — UO.GetSurfaceZ(Any,Any,Any)

Parameters: x (Any), y (Any), worldNum (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getsurfacez":

                    return new InjectionValue(bridge.GetSurfaceZ(Arg(0), Arg(1), Arg(2)));

UO.GetTileFlags

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

C# signatures

dynamic UO.GetTileFlags(object? group, object? tileId);

Reads the bitmask of the graphic properties from the tiledata entry.

Parameters

  • group - 0 - land table; 1 - table of static graphic. The implementation considers any non-null group to be a second table; use 0 or 1.
  • tileId — Graphic/type of entry in tiledata, usually an integer 0…65535. This is not a serial of an object and not an index of statics inside a cell.

Return value

int — low 32 bits of tiledata flags. The most significant bit set results in a negative sign number. 0 means the absence of these flags or invalid tileId; This is not an independent sign of an error and is not a bool. Multiple properties can be set at the same time.

Behavior

  • This command reads the graphic help entry; world coordinates are not needed. group=0 and group=1 select different tables even if tileId is the same.
  • The property is read from the graphic data, not from the current state of a particular item.

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

1. Read the property of a known static graphic - direct script

Parameters and execution flow:

  • group=1 selects static tiledata; tileId=0x0CCA - graphic tree.
  • value contains the result described in the Returns section; its meaning does not coincide with serial.
var value = UO.GetTileFlags(1, 0x0CCA);
if (Truth((Convert.ToUInt64(value) & 0x40UL) != 0))
{
    UO.Print("Impassable flag is set");
}

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

2. Read the graphic property of the found item - script function

Parameters and execution flow:

  • FindType returns serial. GetType turns it into a numeric graphic.
  • group=1 is used for items; in tileId graphic is transmitted, not item.
return  RunScenario();
 object? RunScenario()
{
    var item = UO.FindType(0x0EED, -1, "backpack");
    if (Truth(item != ""))
    {
        var graphic = UO.GetType(item);
        var value = UO.GetTileFlags(1, graphic);
        UO.Print(Convert.ToString(value));
    }

    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 the property of the ground under the character - scenario class

Parameters and execution flow:

  • The first two arguments GetLandscapeTile are the current world X/Y; the third is the current map.
  • land[0] contains a graphic of land. group=0 selects land tiledata. For GetTileLayer/GetTileHeight the ground gives 0.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(land) >= 3))
        {
            var graphic = land[0];
            var value = UO.GetTileFlags(0, graphic);
            UO.Print(Convert.ToString(value));
        }

        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.GetTileFlags(group, tileId) — UO.GetTileFlags(Any,Any)

Parameters: group (Any), tileId (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetTileFlags(InjectionValue group, InjectionValue tileId)

            => new InjectionValue(unchecked((int)bridge.GetTileFlags(NumberConversions.ToInt(group), NumberConversions.ToInt(tileId))));

UO.GetTileHeight

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

C# signatures

int UO.GetTileHeight(object? group, object? tileId);

Reads the height of graphic from the tiledata entry.

Parameters

  • group - 0 - land table; 1 - table of static graphic. The implementation considers any non-null group to be a second table; use 0 or 1.
  • tileId — Graphic/type of entry in tiledata, usually an integer 0…65535. This is not a serial of an object and not an index of statics inside a cell.

Return value

int is the height of the graphic in Z units from tiledata. This is the height size of the graphic, not the world coordinate of its base Z. For ground, missing entry, or zero height, 0 is returned. Height in itself does not prove cross-country ability.

Behavior

  • This command reads the graphic help entry; world coordinates are not needed. group=0 and group=1 select different tables even if tileId is the same.
  • The property is read from the graphic data, not from the current state of a particular item.

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.GetTileHeight(1, 0x0CCA);
UO.Print("GetTileHeight: " + Convert.ToString(result));

1. Read the property of a known static graphic - direct script

Parameters and execution flow:

  • group=1 selects static tiledata; tileId=0x0CCA - graphic tree.
  • value contains the result described in the Returns section; its meaning does not coincide with serial.
var value = UO.GetTileHeight(1, 0x0CCA);
UO.Print("Tiledata height: " + Convert.ToString(value));

2. Read the graphic property of the found item - script function

Parameters and execution flow:

  • FindType returns serial. GetType turns it into a numeric graphic.
  • group=1 is used for items; in tileId graphic is transmitted, not item.
return  RunScenario();
 object? RunScenario()
{
    var item = UO.FindType(0x0EED, -1, "backpack");
    if (Truth(item != ""))
    {
        var graphic = UO.GetType(item);
        var value = UO.GetTileHeight(1, graphic);
        UO.Print(Convert.ToString(value));
    }

    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 the property of the ground under the character - scenario class

Parameters and execution flow:

  • The first two arguments GetLandscapeTile are the current world X/Y; the third is the current map.
  • land[0] contains a graphic of land. group=0 selects land tiledata. For GetTileLayer/GetTileHeight the ground gives 0.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(land) >= 3))
        {
            var graphic = land[0];
            var value = UO.GetTileHeight(0, graphic);
            UO.Print(Convert.ToString(value));
        }

        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.GetTileHeight(group, tileId) — UO.GetTileHeight(Any,Any)

Parameters: group (Any), tileId (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetTileHeight(InjectionValue group, InjectionValue tileId)

        {

            int tileGroup = NumberConversions.ToInt(group);

            int[] properties = bridge.GetTileDataProperties(tileGroup, NumberConversions.ToInt(tileId)) ?? Array.Empty<int>();

            return tileGroup == 0 || properties.Length < 7 ? 0 : properties[6];

        }

UO.GetTileLayer

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

C# signatures

int UO.GetTileLayer(object? group, object? tileId);

Reads the equipment layer number from the tiledata entry.

Parameters

  • group - 0 - land table; 1 - table of static graphic. The implementation considers any non-null group to be a second table; use 0 or 1.
  • tileId — Graphic/type of entry in tiledata, usually an integer 0…65535. This is not a serial of an object and not an index of statics inside a cell.

Return value

int — graphic equipment layer number: for example 1=Rhand, 2=Lhand, 21=Backpack. For a ground, missing entry, or null layer, 0 is returned. This is not the order of statics in a cell, not a floor, and not Z.

Behavior

  • This command reads the graphic help entry; world coordinates are not needed. group=0 and group=1 select different tables even if tileId is the same.
  • The property is read from the graphic data, not from the current state of a particular item.

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.GetTileLayer(1, 0x0CCA);
UO.Print("GetTileLayer: " + Convert.ToString(result));

1. Read the property of a known static graphic - direct script

Parameters and execution flow:

  • group=1 selects static tiledata; tileId=0x0CCA - graphic tree.
  • value contains the result described in the Returns section; its meaning does not coincide with serial.
var value = UO.GetTileLayer(1, 0x0CCA);
if (Truth(value == 1))
{
    UO.Print("Right-hand graphic");
}

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

2. Read the graphic property of the found item - script function

Parameters and execution flow:

  • FindType returns serial. GetType turns it into a numeric graphic.
  • group=1 is used for items; in tileId graphic is transmitted, not item.
return  RunScenario();
 object? RunScenario()
{
    var item = UO.FindType(0x0EED, -1, "backpack");
    if (Truth(item != ""))
    {
        var graphic = UO.GetType(item);
        var value = UO.GetTileLayer(1, graphic);
        UO.Print(Convert.ToString(value));
    }

    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 the property of the ground under the character - scenario class

Parameters and execution flow:

  • The first two arguments GetLandscapeTile are the current world X/Y; the third is the current map.
  • land[0] contains a graphic of land. group=0 selects land tiledata. For GetTileLayer/GetTileHeight the ground gives 0.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(land) >= 3))
        {
            var graphic = land[0];
            var value = UO.GetTileLayer(0, graphic);
            UO.Print(Convert.ToString(value));
        }

        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.GetTileLayer(group, tileId) — UO.GetTileLayer(Any,Any)

Parameters: group (Any), tileId (Any)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetTileLayer(InjectionValue group, InjectionValue tileId)

        {

            int tileGroup = NumberConversions.ToInt(group);

            int[] properties = bridge.GetTileDataProperties(tileGroup, NumberConversions.ToInt(tileId)) ?? Array.Empty<int>();

            return tileGroup == 0 || properties.Length < 2 ? 0 : properties[1];

        }

UO.GetTileName

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

C# signatures

string UO.GetTileName(object? group, object? tileId);

Reads the title graphic from the tiledata entry.

Parameters

  • group - 0 - land table; 1 - table of static graphic. The implementation considers any non-null group to be a second table; use 0 or 1.
  • tileId — Graphic/type of entry in tiledata, usually an integer 0…65535. This is not a serial of an object and not an index of statics inside a cell.

Return value

string - name from game tiledata files. An empty string means an empty name or an invalid tileId. The name is taken from the game resources and is not automatically translated into the interface language IDE. This is not the name of a specific item from the server.

Behavior

  • This command reads the graphic help entry; world coordinates are not needed. group=0 and group=1 select different tables even if tileId is the same.
  • The property is read from the graphic data, not from the current state of a particular item.

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.GetTileName(1, 0x0CCA);
UO.Print("GetTileName: " + Convert.ToString(result));

1. Read the property of a known static graphic - direct script

Parameters and execution flow:

  • group=1 selects static tiledata; tileId=0x0CCA - graphic tree.
  • value contains the result described in the Returns section; its meaning does not coincide with serial.
var value = UO.GetTileName(1, 0x0CCA);
if (Truth(value != ""))
{
    UO.Print(value);
}
else
{
    UO.Print("No tiledata name");
}

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

2. Read the graphic property of the found item - script function

Parameters and execution flow:

  • FindType returns serial. GetType turns it into a numeric graphic.
  • group=1 is used for items; in tileId graphic is transmitted, not item.
return  RunScenario();
 object? RunScenario()
{
    var item = UO.FindType(0x0EED, -1, "backpack");
    if (Truth(item != ""))
    {
        var graphic = UO.GetType(item);
        var value = UO.GetTileName(1, graphic);
        UO.Print(Convert.ToString(value));
    }

    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 the property of the ground under the character - scenario class

Parameters and execution flow:

  • The first two arguments GetLandscapeTile are the current world X/Y; the third is the current map.
  • land[0] contains a graphic of land. group=0 selects land tiledata. For GetTileLayer/GetTileHeight the ground gives 0.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), UO.WorldNum());
        if (Truth(ArrayLength(land) >= 3))
        {
            var graphic = land[0];
            var value = UO.GetTileName(0, graphic);
            UO.Print(Convert.ToString(value));
        }

        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.GetTileName(group, tileId) — UO.GetTileName(Any,Any)

Parameters: group (Any), tileId (Any)

Result: string / String.

During a call:

Internal implementation code; this is not a standalone script.

public string GetTileName(InjectionValue group, InjectionValue tileId)

            => bridge.GetTileDataName(NumberConversions.ToInt(group), NumberConversions.ToInt(tileId));

UO.GetTileXYM

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

C# signatures

dynamic UO.GetTileXYM(object? x, object? y, object? map, object? tileStart, object? tileEnd, object? uoPath);

Reads the matching graphic ID from the object chain of the cell of the currently loaded game card.

Parameters

  • x — X cell coordinate, int.
  • y — Y cell coordinate, int.
  • map — Card number; must match World.MapIndex, and World.Map must exist.
  • tileStart — Lower enabled Graphic border.
  • tileEnd — The upper included border of the Graphic. The reverse range is not rearranged and does not produce matches.
  • uoPath - The compatibility parameter is converted to string, but the current bridge does not use it and does not load the other file folder UO.

Return value

Array int with flat quads [graphic,x,y,z,graphic,x,y,z,...]. The map error gives an empty array and a message; no matches also results in an empty array.

Behavior

  • Follows World.Map.GetTile(x,y).TNext and checks tileStart<=Graphic<=tileEnd. Object types are not filtered separately: it's a chain of cells, not just statics.
  • The command reads the client's loaded geometry. Data from another map/facet is not loaded. The uoPath parameter is not used to download files; the number of entries is equal to the length of the array/4.

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

1. All graphs of the current cell are a direct script

Parameters and execution flow:

  • Each entry takes up four int.
var tiles = UO.GetTileXYM(UO.GetX(),UO.GetY(),UO.WorldNum(),0,65535,"");
UO.Print(Convert.ToString(ArrayLength(tiles)/4));

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

2. Print graphic and height - script function

Parameters and execution flow:

  • The indices i and i+3 correspond to graphic and z of the same record.
return  RunScenario();
 object? RunScenario()
{
    var tiles = UO.GetTileXYM(UO.GetX(), UO.GetY(), UO.WorldNum(), 0, 65535, "");
    for (int i = (int)(0); i <= ArrayLength(tiles) - 1; i += (int)(4))
    {
        UO.Print(Convert.ToString(tiles[i]) + " " + Convert.ToString(tiles[i + 3]));
    }

    return null;
}

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

3. Reverse Range - Script Class

Parameters and execution flow:

  • The range 100..99 does not contain any graphic and gives an empty array.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var tiles = UO.GetTileXYM(UO.GetX(), UO.GetY(), UO.WorldNum(), 100, 99, "");
        UO.Print(Convert.ToString(ArrayLength(tiles)));
        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 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.GetTileXYM(x, y, map, tileStart, tileEnd, uoPath) — UO.GetTileXYM(Any,Any,Any,Any,Any,Any)

Parameters: x (Any), y (Any), map (Any), tileStart (Any), tileEnd (Any), uoPath (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetTileXYM(InjectionValue x, InjectionValue y, InjectionValue map, InjectionValue tileStart, InjectionValue tileEnd, InjectionValue uoPath)

            => ToArray(bridge.GetTileXYM(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map), NumberConversions.ToInt(tileStart), NumberConversions.ToInt(tileEnd), uoPath.ToString()));

UO.GetUserStatic

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

C# signatures

string UO.GetUserStatic(object? id);

Reads a saved user static record.

Parameters

  • id - int ID received by AddUserStatic; not graphic/type and not serial of the world.

Return value

string — saved serialized record; unknown ID gives an empty string.

Behavior

  • state.UserStatics.TryGetValue returns the string without parsing it. Geometric notation - "graphic|x|y|z|hue|map"; old text entries may be different text.
  • Reads the current local state. There is no package, target or automatic update; individual reads may see different states.
  • In a regular client host, this state data is taken from the GetPersistentState manager and is common to scripts/chat/macros of the same world/profile, and does not belong to one script. Another process or an apparently separate InjectionRuntimeState has a different state. Loading/clearing a profile can replace it; saved serial are still checked against the loaded world.

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

1. Direct call - direct script

Parameters and execution flow:

  • Reads a saved user static record.
UO.Print(UO.GetUserStatic(1));

2. Explicit option - script function

Parameters and execution flow:

  • state.UserStatics.TryGetValue returns the string without parsing it. Geometric notation - "graphic|x|y|z|hue|map"; old text entries may be different text.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.UserStaticExists(1)))
    {
        UO.Print(UO.GetUserStatic(1));
    }

    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:

  • Reads the current local state. There is no package, target or automatic update; individual reads may see different states.
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 records = UO.GetUserStatics();
        if (Truth(UO.GetArrayLength(records) > 0))
        {
            UO.Print(UO.GetUserStatic(records[0][0]));
        }

        return null;
    }

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

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.GetUserStatic(id) — UO.GetUserStatic(Any)

Parameters: id (Any)

Result: string / String.

During a call:

Internal implementation code; this is not a standalone script.

public string GetUserStatic(InjectionValue id)

            => state.UserStatics.TryGetValue(NumberConversions.ToInt(id), out string value) ? value : string.Empty;

UO.GetUserStatics

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

C# signatures

dynamic UO.GetUserStatics();

Reads state.UserStatics.

Parameters

There are no parameters.

Return value

Array of strings [id, serializedText], sorted by id. Each id is int, serializedText is string; an empty dictionary gives an empty array.

Behavior

  • Reads state.UserStatics. The geometric notation is stored as "graphic|x|y|z|hue|map"; older text entries AddUserStatic may have a different format. These are local user entries, not all static maps.
  • Reads the current local state. There is no package, target or automatic update; individual reads may see different states.
  • In a regular client host, this state data is taken from the GetPersistentState manager and is common to scripts/chat/macros of the same world/profile, and does not belong to one script. Another process or an apparently separate InjectionRuntimeState has a different state. Loading/clearing a profile can replace it; saved serial are still checked against the loaded world.

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

1. Direct call - direct script

Parameters and execution flow:

  • Reads state.UserStatics.
var records = UO.GetUserStatics();
UO.Print(UO.GetArrayLength(records));

2. Explicit option - script function

Parameters and execution flow:

  • Reads state.UserStatics. The geometric notation is stored as "graphic|x|y|z|hue|map"; older text entries AddUserStatic may have a different format. These are local user entries, not all static maps.
return  RunScenario();
 object? RunScenario()
{
    var records = UO.GetUserStatics();
    if (Truth(UO.GetArrayLength(records) > 0))
    {
        UO.Print(records[0][0]);
        UO.Print(records[0][1]);
    }

    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:

  • Reads the current local state. There is no package, target or automatic update; individual reads may see different states.
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 before = UO.GetUserStatics();
        UO.Wait(500);
        var after = UO.GetUserStatics();
        UO.Print(before);
        UO.Print(after);
        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.GetUserStatics() — UO.GetUserStatics()

Parameters: No parameters.

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetUserStatics()

            => new InjectionValue(state.UserStatics.OrderBy(pair => pair.Key)

                .Select(pair => new InjectionValue(new[] { new InjectionValue(pair.Key), new InjectionValue(pair.Value) }))

                .ToArray());

UO.GetWorldCell

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

C# signatures

dynamic UO.GetWorldCell(object? x, object? y);
dynamic UO.GetWorldCell(object? x, object? y, object? map);

Reads extended ground records, above ground records, and loaded world items in the selected area.

Parameters

  • x — X cell of the currently loaded map; world coordinate, not position inside the gump.
  • y — Y cell of the currently loaded map; world coordinate, not position inside the gump.
  • map — Card number. If this argument is not present in the selected form, the current map is used. The real client only reads tiles from the currently loaded map.

Return value

Array of records. Each result[i] element has the following format:

Array of 11 fields of one record; indices start with 0:

  • [0] kind — string: "land", "static", or "object".
  • [1] serial — int: serial of a dynamic item; for land/static is 0.
  • [2] graphic — int: graphics type.
  • [3] x, [4] y - int: world coordinates of the cell.
  • [5] z - int: the height of the base in the world.
  • [6] hue - int: color, near the ground 0.
  • [7] flags - int: low 32 bits of tiledata flags.
  • [8] name — string: name from tiledata.
  • [9] layer - int: layer of equipment from tiledata, near the ground 0; not a static index.
  • [10] height - int: graphic height from tiledata, near the ground 0; not the Z coordinate.

ArrayLength(result) - the number of records, not the number of cells and not the number of route steps. The result may be empty. One x/y can have several entries with different Z. The entry "object" has serial; the entry "static" does not have a usable serial.

Behavior

  • The data refers to the currently loaded map. Another card or unreachable cell results in an empty array. Direct tile queries may additionally report map mismatches; GetWorldCell and GetWorldTilesArray immediately return an empty array without such a message.
  • Array indices start with 0. Check ArrayLength before reading the field. Z stands for world altitude; layer is the equipment property from tiledata, and index is the serial number of the cell entry.
  • The static part uses GetStaticTiles: its current selection also includes Multi/Item. A World Item may additionally be present as an "object" with serial; Don't treat each entry as a unique item.
  • GetWorldTilesArray limits the region of 1 000 000 cells. Exceeding or coordinates outside 0…65535/map outside 0…255 causes a command error rather than a partial array. For frequent polling, choose a small area.

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

1. Count and list records - direct script

Parameters and execution flow:

  • GetWorldCell reads one cell; GetWorldTilesArray in this example reads the square 3×3 with borders enabled.
  • cells[i] is a nested array. tile[0] - category, [2] - graphic, [5] - Z.
var cells = UO.GetWorldCell(UO.GetX(), UO.GetY());
var i = 0;
while (Truth(i < ArrayLength(cells)))
{
    var tile = cells[i];
    UO.Print(tile[0] + ": " + Convert.ToString(tile[2]) + ", Z=" + Convert.ToString(tile[5]));
    i = i + 1;
}

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. Show only records with item serial - script function

Parameters and execution flow:

  • The area is selected by coordinates, not by container.
  • The kind="object" check separates serial items from ground/static; [1] contains serial.
return  RunScenario();
 object? RunScenario()
{
    var cells = UO.GetWorldCell(UO.GetX(), UO.GetY());
    var i = 0;
    while (Truth(i < ArrayLength(cells)))
    {
        var tile = cells[i];
        if (Truth(tile[0] == "object"))
        {
            UO.Print("Object serial: " + Convert.ToString(tile[1]));
        }

        i = i + 1;
    }

    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. Select Records at Character Height - Script Class

Parameters and execution flow:

  • tile[5] and GetZ() are compared in the same world height units.
  • Equality Z filters the base, but does not mean passability or matching of the entire floor.
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 cells = UO.GetWorldCell(UO.GetX(), UO.GetY());
        var i = 0;
        while (Truth(i < ArrayLength(cells)))
        {
            var tile = cells[i];
            if (Truth(tile[5] == UO.GetZ()))
            {
                UO.Print(tile[8]);
            }

            i = i + 1;
        }

        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.GetWorldCell(x, y) — UO.GetWorldCell(Any,Any)

Parameters: x (Any), y (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetWorldCell(InjectionValue x, InjectionValue y)

            => GetWorldCell(x, y, new InjectionValue(bridge.WorldNumber));

UO.GetWorldCell(x, y, map) — UO.GetWorldCell(Any,Any,Any)

Parameters: x (Any), y (Any), map (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetWorldCell(InjectionValue x, InjectionValue y, InjectionValue map)

            => BuildWorldCell(NumberConversions.ToInt(x), NumberConversions.ToInt(y), NumberConversions.ToInt(map), true);

UO.GetWorldNum

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

C# signatures

int UO.GetWorldNum();

Reads the current card number from the client model.

Parameters

There are no parameters.

Return value

int — index of the client's current card, usually 0=Felucca, 1=Trammel, 2=Ilshenar, 3=Malas, 4=Tokuno, 5=Ter Mur. The user server may use a different set of cards. 0 is a full-fledged map, not a sign of an error.

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.GetWorldNum();
UO.Print("GetWorldNum: " + 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 current card number is stored in value.
  • Convert.ToString converts the number to be output and does not change the meaning of the result.
var value = UO.GetWorldNum();
UO.Print("GetWorldNum: " + Convert.ToString(value));

2. Use Value in Application Validation - Script Function

Parameters and execution flow:

  • The value is read once without any arguments. The current card number 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.GetWorldNum();
    var land = UO.GetLandscapeTile(UO.GetX(), UO.GetY(), value);
    UO.Print("Land record length: " + Convert.ToString(ArrayLength(land)));
    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 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 compared is the number of the current card. 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.GetWorldNum();
        await Delay(1000);
        var after = UO.GetWorldNum();
        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.GetWorldNum() — UO.GetWorldNum()

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

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


UO.GetWorldTilesArray

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

C# signatures

dynamic UO.GetWorldTilesArray(object? minX, object? minY, object? maxX, object? maxY, object? map);

Reads extended ground records, above ground records, and loaded world items in the selected area.

Parameters

  • minX — The first X border of the rectangle, included; 0…65535.
  • minY — The first Y border of the rectangle, included; 0…65535.
  • maxX — Second included boundary X; the smaller/larger of the two X's is selected automatically.
  • maxY — Second included boundary Y; the smaller/larger of the two Y's is selected automatically.
  • map — Card number. If this argument is not present in the selected form, the current map is used. The real client only reads tiles from the currently loaded map.

Return value

Array of records. Each result[i] element has the following format:

Array of 11 fields of one record; indices start with 0:

  • [0] kind — string: "land", "static", or "object".
  • [1] serial — int: serial of a dynamic item; for land/static is 0.
  • [2] graphic — int: graphics type.
  • [3] x, [4] y - int: world coordinates of the cell.
  • [5] z - int: the height of the base in the world.
  • [6] hue - int: color, near the ground 0.
  • [7] flags - int: low 32 bits of tiledata flags.
  • [8] name — string: name from tiledata.
  • [9] layer - int: layer of equipment from tiledata, near the ground 0; not a static index.
  • [10] height - int: graphic height from tiledata, near the ground 0; not the Z coordinate.

ArrayLength(result) - the number of records, not the number of cells and not the number of route steps. The result may be empty. One x/y can have several entries with different Z. The entry "object" has serial; the entry "static" does not have a usable serial.

Behavior

  • The data refers to the currently loaded map. Another card or unreachable cell results in an empty array. Direct tile queries may additionally report map mismatches; GetWorldCell and GetWorldTilesArray immediately return an empty array without such a message.
  • Array indices start with 0. Check ArrayLength before reading the field. Z stands for world altitude; layer is the equipment property from tiledata, and index is the serial number of the cell entry.
  • The static part uses GetStaticTiles: its current selection also includes Multi/Item. A World Item may additionally be present as an "object" with serial; Don't treat each entry as a unique item.
  • GetWorldTilesArray limits the region of 1 000 000 cells. Exceeding or coordinates outside 0…65535/map outside 0…255 causes a command error rather than a partial array. For frequent polling, choose a small area.

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

1. Count and list records - direct script

Parameters and execution flow:

  • GetWorldCell reads one cell; GetWorldTilesArray in this example reads the square 3×3 with borders enabled.
  • cells[i] is a nested array. tile[0] - category, [2] - graphic, [5] - Z.
var cells = UO.GetWorldTilesArray(UO.GetX() - 1, UO.GetY() - 1, UO.GetX() + 1, UO.GetY() + 1, UO.WorldNum());
var i = 0;
while (Truth(i < ArrayLength(cells)))
{
    var tile = cells[i];
    UO.Print(tile[0] + ": " + Convert.ToString(tile[2]) + ", Z=" + Convert.ToString(tile[5]));
    i = i + 1;
}

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. Show only records with item serial - script function

Parameters and execution flow:

  • The area is selected by coordinates, not by container.
  • The kind="object" check separates serial items from ground/static; [1] contains serial.
return  RunScenario();
 object? RunScenario()
{
    var cells = UO.GetWorldTilesArray(UO.GetX() - 1, UO.GetY() - 1, UO.GetX() + 1, UO.GetY() + 1, UO.WorldNum());
    var i = 0;
    while (Truth(i < ArrayLength(cells)))
    {
        var tile = cells[i];
        if (Truth(tile[0] == "object"))
        {
            UO.Print("Object serial: " + Convert.ToString(tile[1]));
        }

        i = i + 1;
    }

    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. Select Records at Character Height - Script Class

Parameters and execution flow:

  • tile[5] and GetZ() are compared in the same world height units.
  • Equality Z filters the base, but does not mean passability or matching of the entire floor.
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 cells = UO.GetWorldTilesArray(UO.GetX() - 1, UO.GetY() - 1, UO.GetX() + 1, UO.GetY() + 1, UO.WorldNum());
        var i = 0;
        while (Truth(i < ArrayLength(cells)))
        {
            var tile = cells[i];
            if (Truth(tile[5] == UO.GetZ()))
            {
                UO.Print(tile[8]);
            }

            i = i + 1;
        }

        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.GetWorldTilesArray(minX, minY, maxX, maxY, map) — UO.GetWorldTilesArray(Any,Any,Any,Any,Any)

Parameters: minX (Any), minY (Any), maxX (Any), maxY (Any), map (Any)

Result: dynamic / Any.

During a call:

Internal implementation code; this is not a standalone script.

public InjectionValue GetWorldTilesArray(InjectionValue minX, InjectionValue minY, InjectionValue maxX, InjectionValue maxY, InjectionValue map)

        {

            int firstX = Math.Min(NumberConversions.ToInt(minX), NumberConversions.ToInt(maxX));

            int lastX = Math.Max(NumberConversions.ToInt(minX), NumberConversions.ToInt(maxX));

            int firstY = Math.Min(NumberConversions.ToInt(minY), NumberConversions.ToInt(maxY));

            int lastY = Math.Max(NumberConversions.ToInt(minY), NumberConversions.ToInt(maxY));

            int world = NumberConversions.ToInt(map);

            if (firstX < 0 || firstY < 0 || lastX > ushort.MaxValue || lastY > ushort.MaxValue

                || world < 0 || world > byte.MaxValue)

                throw new NativeSubrutineException("World tile coordinates must be 0..65535 and the map must be 0..255.");

            if (((long)lastX - firstX + 1) * ((long)lastY - firstY + 1) > 1_000_000L)

                throw new NativeSubrutineException("World tile array is limited to 1,000,000 cells per call.");

            // Live world items have no per-result map field. Never combine the

            // current world's items with a request for a different map, or scan

            // every cell only to report the same unloaded-map failure repeatedly.

            if (world != bridge.WorldNumber)

                return new InjectionValue(Array.Empty<InjectionValue>());



            var result = new List<InjectionValue>();

            for (int cellX = firstX; cellX <= lastX; cellX++)

            for (int cellY = firstY; cellY <= lastY; cellY++)

            {

                InjectionValue cell = BuildWorldCell(cellX, cellY, world, false);

                if (cell.Kind == InjectionValueKind.Array)

                    result.AddRange(cell.Array);

            }



            foreach (int serial in bridge.GetWorldItems() ?? Array.Empty<int>())

            {

                int objectX = bridge.GetX(serial);

                int objectY = bridge.GetY(serial);

                if (objectX >= firstX && objectX <= lastX && objectY >= firstY && objectY <= lastY)

                    result.Add(BuildWorldTileRecord("object", serial, bridge.GetGraphics(serial), objectX, objectY,

                        bridge.GetZ(serial), bridge.GetColor(serial), 1));

            }

            return new InjectionValue(result.ToArray());

        }

UO.GetX

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

C# signatures

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

Reads the X field of the loaded object or current character.

Parameters

  • id — Serial/ID of the object, not the graphic/type. A number, a hex string, the standard name self/backpack/lasttarget/lastobject/lastcontainer/laststatus/finditem/lastcorpse, or the name AddObject. The alias must be set; existence is checked by Exists. The registered form without arguments uses self.

Return value

int is the X coordinate. For an unknown object, 0 is returned. Zero is also a valid coordinate. Measured in cells for world objects; These are not screen pixels.

Behavior

  • The latest data already known to the client is read; the update request is not sent to the server.
  • An unknown object and a property that has not yet been retrieved can have a null/empty value. Check Exists and conditions for a specific action.
  • For a character or object on the ground, this is the world coordinate. The item inside the container has an X/Y position inside the gump; the command does not translate them into the owner's world coordinates.
  • The current coordinate of the object is read. Pending steps are not converted into route calculations by this command.

Example .csx

int x = UO.GetX();
UO.Print($"X = {x}");

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

1. Read your coordinate - direct script

Parameters and execution flow:

  • The form without an argument selects self, the current character.
  • position contains the X coordinate, not serial.
var position = UO.GetX();
UO.Print("X: " + Convert.ToString(position));

2. Compare with selected character - script function

Parameters and execution flow:

  • lasttarget should point to the loaded character or item on the ground.
  • delta — difference along one axis. It is not the length of the route; the value may be negative.
return  RunScenario();
 object? RunScenario()
{
    var other = UO.GetSerial("lasttarget");
    if (Truth(UO.Exists(other)))
    {
        var delta = UO.GetX(other) - UO.GetX();
        UO.Print("Difference: " + Convert.ToString(delta));
    }

    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. Remember point and compare later - script class

Parameters and execution flow:

  • id="self" is an explicit form of character selection. UO.Wait=500 milliseconds.
  • The comparison shows the change in the X axis only. Changes in the other axis or rotation are not taken into account here.
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.GetX("self");
        await Delay(500);
        var after = UO.GetX("self");
        if (Truth(before != after))
        {
            UO.Print("Coordinate changed");
        }

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

Parameters: No parameters.

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetX() => GetX("self");

UO.GetX(id) — UO.GetX(Any)

Parameters: id (Any/Integer/String)

Result: int / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "getx": return new InjectionValue(bridge.GetX(Arg(0, bridge.Self)));

UO.GetX(id) — UO.GetX(Integer)

Parameters: id (Any/Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

UO.GetX(id) — UO.GetX(String)

Parameters: id (Any/Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

UO.GetY

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

C# signatures

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

Reads the Y field of the loaded object or current character.

Parameters

  • id — Serial/ID of the object, not the graphic/type. A number, a hex string, the standard name self/backpack/lasttarget/lastobject/lastcontainer/laststatus/finditem/lastcorpse, or the name AddObject. The alias must be set; existence is checked by Exists. The registered form without arguments uses self.

Return value

int is the Y coordinate. For an unknown object, 0 is returned. Zero is also a valid coordinate. Measured in cells for world objects; These are not screen pixels.

Behavior

  • The latest data already known to the client is read; the update request is not sent to the server.
  • An unknown object and a property that has not yet been retrieved can have a null/empty value. Check Exists and conditions for a specific action.
  • For a character or object on the ground, this is the world coordinate. The item inside the container has an X/Y position inside the gump; the command does not translate them into the owner's world coordinates.
  • The current coordinate of the object is read. Pending steps are not converted into route calculations by this command.

Example .csx

int y = UO.GetY();
UO.Print($"Y = {y}");

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

1. Read your coordinate - direct script

Parameters and execution flow:

  • The form without an argument selects self, the current character.
  • position contains the Y coordinate, not serial.
var position = UO.GetY();
UO.Print("Y: " + Convert.ToString(position));

2. Compare with selected character - script function

Parameters and execution flow:

  • lasttarget should point to the loaded character or item on the ground.
  • delta — difference along one axis. It is not the length of the route; the value may be negative.
return  RunScenario();
 object? RunScenario()
{
    var other = UO.GetSerial("lasttarget");
    if (Truth(UO.Exists(other)))
    {
        var delta = UO.GetY(other) - UO.GetY();
        UO.Print("Difference: " + Convert.ToString(delta));
    }

    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. Remember point and compare later - script class

Parameters and execution flow:

  • id="self" is an explicit form of character selection. UO.Wait=500 milliseconds.
  • The comparison shows the change in the Y axis only. Changes in the other axis or rotation are not taken into account here.
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.GetY("self");
        await Delay(500);
        var after = UO.GetY("self");
        if (Truth(before != after))
        {
            UO.Print("Coordinate changed");
        }

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

Parameters: No parameters.

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

public int GetY() => GetY("self");

UO.GetY(id) — UO.GetY(Any)

Parameters: id (Any/Integer/String)

Result: int / Any.

During a call:

Internal implementation code; this is not a standalone script.

case "gety": return new InjectionValue(bridge.GetY(Arg(0, bridge.Self)));

UO.GetY(id) — UO.GetY(Integer)

Parameters: id (Any/Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

UO.GetY(id) — UO.GetY(String)

Parameters: id (Any/Integer/String)

Result: int / Integer.

During a call:

Internal implementation code; this is not a standalone script.

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

Clone this wiki locally